├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── docker ├── atmcorr-ee │ ├── .dockerignore │ ├── .gitattributes │ ├── Dockerfile │ ├── README.md │ └── images │ │ └── before_and_after.png ├── gcp_ai_deep_learning_platform │ ├── Dockerfile │ ├── README.md │ └── test_image_packages.ipynb ├── jupyter-scipy-notebook-ee │ ├── Dockerfile │ ├── README.md │ └── test_jupyter_scipy_notebook_ee.ipynb └── minimal-install-debian-python27-ee │ ├── .dockerignore │ ├── Dockerfile │ └── README.md ├── examples ├── best-available-pixel │ └── best-available-pixel-composite.ipynb ├── export │ └── export-image-gdrive.ipynb ├── geometry │ └── image_profile.ipynb └── getting-started │ ├── display-interactive-map.ipynb │ └── display-static-map.ipynb └── images └── JupyterLab_Example.png /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | '*.png' filter=lfs diff=lfs merge=lfs -text 3 | '*.jpg' filter=lfs diff=lfs merge=lfs -text 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Google Earth Engine Community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Earth Engine - Jupyter Contributions (ee-jupyter-contrib) 2 | 3 | This repository is intended for contributions related to using [Jupyter](http://jupyter.org/) 4 | as an development environment for the [Python API](https://github.com/google/earthengine-api/tree/master/python) 5 | of [Google Earth Engine](https://earthengine.google.com). 6 | 7 | # Discuss this Repository 8 | 9 | Have an idea for content additions? Join the Gitter chat channel for this repository: 10 | [![Join the chat at https://gitter.im/gee-community/ee-jupyter-contrib](https://badges.gitter.im/gee-community/ee-jupyter-contrib.svg)](https://gitter.im/gee-community/ee-jupyter-contrib?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 11 | 12 | # Basic Notebook Example 13 | 14 | Here is an example of using [JupyterLab](https://github.com/jupyterlab/jupyterlab) IDE to display an 15 | Earth Engine image asset. 16 | 17 | ![JupyterLab example](images/JupyterLab_Example.png) 18 | 19 | The script shown in the screenshot is available in `examples/Getting Started/Display Static Map.ipynb` 20 | -------------------------------------------------------------------------------- /docker/atmcorr-ee/.dockerignore: -------------------------------------------------------------------------------- 1 | *.md 2 | -------------------------------------------------------------------------------- /docker/atmcorr-ee/.gitattributes: -------------------------------------------------------------------------------- 1 | *.png filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /docker/atmcorr-ee/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | MAINTAINER Sam Murphy 4 | 5 | RUN apt-get update && \ 6 | \ 7 | apt-get install -y --no-install-recommends \ 8 | bzip2 \ 9 | build-essential \ 10 | git \ 11 | libssl-dev \ 12 | libffi-dev \ 13 | python3 \ 14 | python3-dev \ 15 | python3-pip \ 16 | wget \ 17 | && \ 18 | apt-get clean && \ 19 | rm -rf /var/lib/apt/lists/* 20 | 21 | RUN wget --quiet https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \ 22 | /bin/bash /Miniconda3-latest-Linux-x86_64.sh -b -p /miniconda && \ 23 | rm Miniconda3-latest-Linux-x86_64.sh 24 | 25 | ENV PATH=/miniconda/bin:${PATH} 26 | 27 | RUN conda update -y conda && \ 28 | conda config --add channels conda-forge && \ 29 | conda install -y py6s 30 | 31 | RUN conda install -c anaconda pip && \ 32 | pip install earthengine-api oauth2client 33 | 34 | RUN conda install -y jupyter 35 | 36 | EXPOSE 8888 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /docker/atmcorr-ee/README.md: -------------------------------------------------------------------------------- 1 | # Docker Image: Atmospheric Correction in Earth Engine 2 | 3 | This directory contains a Docker image configuration for atmospheric correction with [Py6S](http://py6s.readthedocs.io/en/latest/) and Earth Engine. 4 | 5 | # Building the Image 6 | 7 | The Docker image can be built by opening up a terminal, navigating to this 8 | directory, and running the `docker build` command: 9 | 10 | ``` 11 | docker build . -t atmcorr-ee 12 | ``` 13 | 14 | The `-t` parameter assigns the tag/name `atmcorr-ee` to the image. 15 | 16 | # Running the Image 17 | 18 | To create a Docker container with access to a web browser 19 | 20 | ``` 21 | docker run -i -t -p 8888:8888 atmcorr-ee 22 | ``` 23 | 24 | Once inside the container, authenticate Earth Engine 25 | 26 | `earthengine authenticate` 27 | 28 | get the source code from [this repo](https://github.com/samsammurphy/gee-atmcorr-S2) for an example application with Sentinel 2 using the following command: 29 | 30 | `git clone https://github.com/samsammurphy/gee-atmcorr-S2` 31 | 32 | then run the example jupyter notebook 33 | 34 | ``` 35 | cd gee-atmcorr-S2/jupyer_notebooks/ 36 | jupyter-notebook sentinel2_atmospheric_correction.ipynb --ip='*' --port=8888 --allow-root 37 | ``` 38 | 39 | this will print out a URL that you can use in your web browser to run the code. 40 | 41 | If the URL is *http://(something_in_parentheses)* then you will need to change the parentheses and its contents for *localhost*. A valid URL should look something like.. 42 | 43 | http://localhost:8888/?token=... 44 | 45 | 46 | # Result 47 | 48 | If all went well then you should be able to see a before and after set of images similar to this one 49 | 50 | ![](https://media.githubusercontent.com/media/gee-community/ee-jupyter-contrib/atmcorr-ee/docker/atmcorr-ee/images/before_and_after.png) 51 | -------------------------------------------------------------------------------- /docker/atmcorr-ee/images/before_and_after.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fd115cda2b338a0c17916ef973f3a77e017d7bbfe30f011ece58ad34414f10ac 3 | size 1108736 4 | -------------------------------------------------------------------------------- /docker/gcp_ai_deep_learning_platform/Dockerfile: -------------------------------------------------------------------------------- 1 | # If updating, look for new versions of the base image: 2 | # gcloud container images list --repository="gcr.io/deeplearning-platform-release" 3 | FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-3 4 | LABEL base-image="gcr.io/deeplearning-platform-release/tf2-cpu.2-3" 5 | LABEL maintainer="Tyler Erickson " 6 | 7 | # Altair - Declarative visualization in Python 8 | # docs: https://altair-viz.github.io 9 | # source: https://github.com/altair-viz/altair 10 | # pkgs: mamba repoquery search altair 11 | ARG ALTAIR_VERSION=4.1.0 12 | 13 | # Earth Engine Python API 14 | # home: https://earthengine.google.com 15 | # docs: https://developers.google.com/earth-engine 16 | # source: https://github.com/google/earthengine-api 17 | # pkgs: mamba repoquery search earthengine-api 18 | ARG EARTHENGINE_API_VERSION=0.1.238 19 | 20 | # geemap - Interactive mapping of Earth Engine data in Jupyter notebooks 21 | # docs: https://geemap.readthedocs.io 22 | # source: https://github.com/giswqs/geemap 23 | # pkgs: mamba repoquery search geemap 24 | ARG GEEMAP_VERSION=0.7.13 25 | 26 | # ipyvolume - 3d plotting in the Jupyter notebook 27 | # docs: https://ipyvolume.readthedocs.io/ 28 | # source: https://github.com/maartenbreddels/ipyvolume 29 | # pkgs: mamba repoquery search ipyvolume 30 | # npm search jupyter-threejs 31 | ARG IPYVOLUME_VERSION=0.5.2 32 | ARG THREEJS_VERSION=2.2.0 33 | 34 | # Palettable - color maps 35 | # docs: https://jiffyclub.github.io/palettable 36 | # source: https://github.com/jiffyclub/palettable 37 | # pkgs: mamba repoquery search palettable 38 | ARG PALETTABLE_VERSION=3.3.0 39 | 40 | # Vega Datasets - Collection of datasets used in Vega and Vega-Lite examples 41 | # docs: http://vega.github.io/vega-datasets 42 | # source: https://github.com/vega/vega-datasets 43 | # pkgs: mamba repoquery search vega_datasets 44 | ARG VEGA_DATASETS_VERSION=0.8.0 45 | 46 | RUN conda update -n base -c defaults --yes conda 47 | RUN conda install -c conda-forge --verbose mamba 48 | 49 | RUN mamba install -c conda-forge --yes \ 50 | altair=${ALTAIR_VERSION} \ 51 | earthengine-api=${EARTHENGINE_API_VERSION} \ 52 | geemap=${GEEMAP_VERSION} \ 53 | palettable=${PALETTABLE_VERSION} \ 54 | vega_datasets=${VEGA_DATASETS_VERSION} \ 55 | && mamba clean --all -f -y 56 | 57 | # Install and enable JupyterLab extensions 58 | RUN jupyter labextension update --no-build nbdime-jupyterlab \ 59 | && jupyter labextension install --no-build @jupyter-widgets/jupyterlab-manager \ 60 | jupyter-leaflet \ 61 | bqplot \ 62 | && jupyter lab build --dev-build=False --minimize=False \ 63 | # Clean up 64 | && npm cache clean --force 65 | -------------------------------------------------------------------------------- /docker/gcp_ai_deep_learning_platform/README.md: -------------------------------------------------------------------------------- 1 | # Docker Image: AI Platform Notebook Deep Learning + Earth Engine 2 | 3 | This directory contains a Docker image configuration for adding 4 | the Earth Engine Python API to an 5 | [AI Platform Deep Learning VM Image](https://cloud.google.com/deep-learning-vm). 6 | The configuration file also installs the [geemap](https://github.com/giswqs/geemap) and several other 7 | [Jupyter Widgets](http://jupyter.org/widgets) packages that are useful for working with 8 | geospatial data. 9 | 10 | ## Local development 11 | 12 | ### Setup 13 | 14 | * Install Docker: 15 | https://docs.docker.com/get-docker/ 16 | * Install mamba: 17 | https://github.com/TheSnakePit/mamba 18 | `conda install mamba -c conda-forge` 19 | * Install node.js: 20 | `conda install -c conda-forge nodejs` 21 | 22 | ### Build a container image 23 | 24 | Navigate to the directory containing the Dockerfile. 25 | Update the Dockerfile as needed. 26 | 27 | Build a Docker image, assiging a name/tag to the image. 28 | 29 | ```docker build . --tag gcp_ai_deep_learning_platform_ee``` 30 | 31 | Run the Docker image to create a container, using port 8080 and mapping your local home directory to the container's home directory for the default "jupyter" user: 32 | 33 | ```docker run -p 8080:8080 -v $HOME:/home/jupyter gcp_ai_deep_learning_platform_ee``` 34 | -------------------------------------------------------------------------------- /docker/gcp_ai_deep_learning_platform/test_image_packages.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Overview\n", 8 | "\n", 9 | "The purpose of this notebook is to run simple tests on the libraries provided by the Docker image [AI Deep Learning Platform + Earth Engine](https://github.com/gee-community/ee-jupyter-contrib/tree/master/docker/gcp_ai_deep_learning_platform)." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "# Earth Engine Packages\n", 17 | "\n", 18 | "## Earth Engine Python API\n", 19 | "\n", 20 | "\"The Earth Engine Python API is a client library that facilitates interacting with the Earth Engine servers using the Python programming language.\" \n", 21 | "\n", 22 | "* Homepage: https://earthengine.google.com/\n", 23 | "* Docs: https://developers.google.com/earth-engine/\n", 24 | "* Source code: https://github.com/google/earthengine-api" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "import ee\n", 34 | "print(ee.__version__)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "ee.Authenticate()" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "ee.Initialize()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "# Jupyter Project packages" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "## Jupyter Notebook\n", 67 | "\n", 68 | "The core library for Jupyter Interactive Notebooks.\n", 69 | "\n", 70 | "* Docs: https://jupyter-notebook.readthedocs.io/\n", 71 | "* Source code: https://github.com/jupyter/notebook" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "import notebook\n", 81 | "print(notebook.__version__)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "## JupyterLab\n", 89 | "\n", 90 | "\"JupyterLab computational environment.\"\n", 91 | "\n", 92 | "* Docs: http://jupyterlab.readthedocs.io\n", 93 | "* Source code: https://github.com/jupyterlab/jupyterlab" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "import jupyterlab\n", 103 | "print(jupyterlab.__version__)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "## Jupyter Notebook Widgets\n", 111 | "\n", 112 | "\"Widgets are eventful python objects that have a representation in the browser, often as a control like a slider, textbox, etc.\"\n", 113 | "\n", 114 | "* Homepage: http://jupyter.org/widgets\n", 115 | "* Docs: https://ipywidgets.readthedocs.io\n", 116 | "* Source code: https://github.com/jupyter-widgets/ipywidgets\n" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "import ipywidgets\n", 126 | "print(ipywidgets.__version__)" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "my_slider= ipywidgets.widgets.IntSlider()\n", 136 | "display(my_slider)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "my_slider.value" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "### ipyleaflet\n", 153 | "\n", 154 | "ipyleaflet is a Jupyter Widget for interactive mapping, based on the [Leaflet](https://leafletjs.com/) Javascript library.\n", 155 | "\n", 156 | "* Source code: https://github.com/jupyter-widgets/ipyleaflet" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "import ipyleaflet\n", 166 | "print(ipyleaflet.__version__)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "my_map = ipyleaflet.Map(center=(53.35, -6.2), zoom=11)\n", 176 | "my_map" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "### bqplot\n", 184 | "\n", 185 | "\"bqplot is a Grammar of Graphics-based interactive plotting framework for the Jupyter notebook.\" \n", 186 | "\n", 187 | "* Docs: https://bqplot.readthedocs.io/en/stable/\n", 188 | "* Source code: https://github.com/bloomberg/bqplot" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "import bqplot\n", 198 | "print(bqplot.__version__)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "import numpy as np\n", 208 | "size = 100\n", 209 | "x_data = range(size)\n", 210 | "np.random.seed(0)\n", 211 | "y_data = np.cumsum(np.random.randn(size) * 100.0)\n", 212 | "y_data_2 = np.cumsum(np.random.randn(size))\n", 213 | "y_data_3 = np.cumsum(np.random.randn(size) * 100.)\n", 214 | "\n", 215 | "sc_ord = bqplot.OrdinalScale()\n", 216 | "sc_y = bqplot.LinearScale()\n", 217 | "sc_y_2 = bqplot.LinearScale()\n", 218 | "\n", 219 | "ord_ax = bqplot.Axis(label='Test X', scale=sc_ord, tick_format='0.0f', grid_lines='none')\n", 220 | "y_ax = bqplot.Axis(label='Test Y', scale=sc_y, \n", 221 | " orientation='vertical', tick_format='0.2f', \n", 222 | " grid_lines='solid')\n", 223 | "y_ax_2 = bqplot.Axis(label='Test Y 2', scale=sc_y_2, \n", 224 | " orientation='vertical', side='right', \n", 225 | " tick_format='0.0f', grid_lines='solid')\n", 226 | "\n", 227 | "line_chart = bqplot.Lines(x=x_data[:10], y = [y_data[:10], y_data_2[:10] * 100, y_data_3[:10]],\n", 228 | " scales={'x': sc_ord, 'y': sc_y},\n", 229 | " labels=['Line1', 'Line2', 'Line3'], \n", 230 | " display_legend=True)\n", 231 | "\n", 232 | "bar_chart = bqplot.Bars(x=x_data[:10], \n", 233 | " y=[y_data[:10], y_data_2[:10] * 100, y_data_3[:10]], \n", 234 | " scales={'x': sc_ord, 'y': sc_y_2},\n", 235 | " labels=['Bar1', 'Bar2', 'Bar3'],\n", 236 | " display_legend=True)\n", 237 | "\n", 238 | "# the line does not have a Y value set. So only the bars will be displayed\n", 239 | "bqplot.Figure(axes=[ord_ax, y_ax], marks=[bar_chart, line_chart], legend_location = 'bottom-left')" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": {}, 245 | "source": [ 246 | "## nbdime\n", 247 | "\n", 248 | "\"Jupyter Notebook Diff & Merge tools\"\n", 249 | "\n", 250 | "* docs: https://nbdime.readthedocs.io\n", 251 | "* source: https://github.com/jupyter/nbdime" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": null, 257 | "metadata": {}, 258 | "outputs": [], 259 | "source": [ 260 | "import nbdime\n", 261 | "print(nbdime.__version__)" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "# geemap" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": null, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "import geemap\n", 278 | "print(geemap.__version__)" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": null, 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "Map = geemap.Map(center=[40,-100], zoom=4)\n", 288 | "Map" 289 | ] 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "metadata": {}, 294 | "source": [ 295 | "# Visualization packages" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "metadata": {}, 301 | "source": [ 302 | "## Palettable\n", 303 | "\n", 304 | "\"Palettable is a library of color palettes for Python.\" \n", 305 | "\n", 306 | "* Docs: https://jiffyclub.github.io/palettable/\n", 307 | "* Source code: https://github.com/jiffyclub/palettable" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": null, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "import palettable\n", 317 | "print(palettable.__version__)" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": null, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "import matplotlib.pyplot as plt\n", 327 | "import numpy as np\n", 328 | "from matplotlib.colors import LogNorm\n", 329 | "from palettable.colorbrewer.sequential import YlGnBu_9\n", 330 | "\n", 331 | "#normal distribution center at x=0 and y=5\n", 332 | "x = np.random.randn(100000)\n", 333 | "y = np.random.randn(100000)+5\n", 334 | "\n", 335 | "plt.hist2d(x, y, bins=40, norm=LogNorm(), cmap=YlGnBu_9.mpl_colormap)\n", 336 | "plt.colorbar()" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": {}, 342 | "source": [ 343 | "## Altair\n", 344 | "\n", 345 | "\"Altair is a declarative statistical visualization library for Python.\" \n", 346 | "\n", 347 | "* Docs: https://altair-viz.github.io/\n", 348 | "* Source code: https://github.com/altair-viz/altair\n", 349 | "* Tutorials: https://github.com/altair-viz/altair_notebooks" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [ 358 | "import altair as alt\n", 359 | "print(alt.__version__)" 360 | ] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": null, 365 | "metadata": {}, 366 | "outputs": [], 367 | "source": [ 368 | "# load a simple dataset as a pandas DataFrame\n", 369 | "from vega_datasets import data\n", 370 | "cars = data.cars()\n", 371 | "\n", 372 | "alt.Chart(cars).mark_point().encode(\n", 373 | " x='Horsepower',\n", 374 | " y='Miles_per_Gallon',\n", 375 | " color='Origin',\n", 376 | ")" 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "metadata": {}, 382 | "source": [ 383 | "## PILLOW\n", 384 | "\n", 385 | "\"Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.\"\n", 386 | "\n", 387 | "* Docs: http://pillow.readthedocs.io" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": null, 393 | "metadata": {}, 394 | "outputs": [], 395 | "source": [ 396 | "import PIL\n", 397 | "print(PIL.__version__)" 398 | ] 399 | }, 400 | { 401 | "cell_type": "markdown", 402 | "metadata": {}, 403 | "source": [ 404 | "## imageio\n", 405 | "\n", 406 | "\"Imageio is a Python library that provides an easy interface to read and write a wide range of image data, including animated images, video, volumetric data, and scientific formats.\"\n", 407 | "\n", 408 | "* Home: https://imageio.github.io/\n", 409 | "* Docs: http://imageio.readthedocs.io/\n", 410 | "* Source Code: https://github.com/imageio/imageio" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": null, 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [ 419 | "import imageio\n", 420 | "print(imageio.__version__)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "# Machine Learning\n", 428 | "\n", 429 | "## Tensorflow\n", 430 | "\n", 431 | "\"Computation using data flow graphs for scalable machine learning\"\n", 432 | "\n", 433 | "Homepage: https://www.tensorflow.org/\n", 434 | "Docs: https://www.tensorflow.org/api_docs/python/\n", 435 | "Source code: https://github.com/tensorflow/tensorflow\n", 436 | "Tutorials: https://www.tensorflow.org/tutorials/" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": null, 442 | "metadata": {}, 443 | "outputs": [], 444 | "source": [ 445 | "import tensorflow as tf\n", 446 | "print(tf.__version__)" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": {}, 453 | "outputs": [], 454 | "source": [ 455 | "# TF example copied from https://colab.sandbox.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/quickstart/beginner.ipynb\n", 456 | "\n", 457 | "mnist = tf.keras.datasets.mnist\n", 458 | "\n", 459 | "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", 460 | "x_train, x_test = x_train / 255.0, x_test / 255.0\n", 461 | "\n", 462 | "model = tf.keras.models.Sequential([\n", 463 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n", 464 | " tf.keras.layers.Dense(128, activation='relu'),\n", 465 | " tf.keras.layers.Dropout(0.2),\n", 466 | " tf.keras.layers.Dense(10)\n", 467 | "])\n", 468 | "\n", 469 | "predictions = model(x_train[:1]).numpy()\n", 470 | "predictions" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": null, 476 | "metadata": {}, 477 | "outputs": [], 478 | "source": [ 479 | "tf.nn.softmax(predictions).numpy()" 480 | ] 481 | }, 482 | { 483 | "cell_type": "code", 484 | "execution_count": null, 485 | "metadata": {}, 486 | "outputs": [], 487 | "source": [ 488 | "loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": {}, 495 | "outputs": [], 496 | "source": [ 497 | "loss_fn(y_train[:1], predictions).numpy()" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": null, 503 | "metadata": {}, 504 | "outputs": [], 505 | "source": [ 506 | "model.compile(optimizer='adam',\n", 507 | " loss=loss_fn,\n", 508 | " metrics=['accuracy'])" 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": null, 514 | "metadata": {}, 515 | "outputs": [], 516 | "source": [ 517 | "model.fit(x_train, y_train, epochs=5)" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": null, 523 | "metadata": {}, 524 | "outputs": [], 525 | "source": [ 526 | "model.evaluate(x_test, y_test, verbose=2)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "code", 531 | "execution_count": null, 532 | "metadata": {}, 533 | "outputs": [], 534 | "source": [ 535 | "probability_model = tf.keras.Sequential([\n", 536 | " model,\n", 537 | " tf.keras.layers.Softmax()\n", 538 | "])" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": null, 544 | "metadata": {}, 545 | "outputs": [], 546 | "source": [ 547 | "probability_model(x_test[:5])" 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": null, 553 | "metadata": {}, 554 | "outputs": [], 555 | "source": [] 556 | } 557 | ], 558 | "metadata": { 559 | "kernelspec": { 560 | "display_name": "Python 3", 561 | "language": "python", 562 | "name": "python3" 563 | }, 564 | "language_info": { 565 | "codemirror_mode": { 566 | "name": "ipython", 567 | "version": 3 568 | }, 569 | "file_extension": ".py", 570 | "mimetype": "text/x-python", 571 | "name": "python", 572 | "nbconvert_exporter": "python", 573 | "pygments_lexer": "ipython3", 574 | "version": "3.7.8" 575 | } 576 | }, 577 | "nbformat": 4, 578 | "nbformat_minor": 4 579 | } 580 | -------------------------------------------------------------------------------- /docker/jupyter-scipy-notebook-ee/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jupyter/scipy-notebook:75d7f5e4f76d 2 | LABEL base-image="jupyter/scipy-notebook:75d7f5e4f76d 2020-07-20" 3 | LABEL maintainer="Tyler Erickson " 4 | 5 | # Altair - Declarative visualization in Python 6 | # docs: https://altair-viz.github.io 7 | # source: https://github.com/altair-viz/altair 8 | # pkgs: conda search -c conda-forge altair 9 | ARG ALTAIR_VERSION=4.1.0 10 | 11 | # bqplot - Grammar of Graphics-based interactive plotting framework for the Jupyter notebook 12 | # docs: https://bqplot.readthedocs.io 13 | # source: https://github.com/bloomberg/bqplot 14 | # pkgs: conda search -c conda-forge bqplot 15 | # npm search bqplot 16 | ARG BQPLOT_VERSION=0.12.14 17 | ARG BQPLOT_NPM_VERSION=0.5.14 18 | 19 | # Earth Engine Python API 20 | # home: https://earthengine.google.com 21 | # docs: https://developers.google.com/earth-engine 22 | # source: https://github.com/google/earthengine-api 23 | # pkgs: conda search -c conda-forge earthengine-api 24 | ARG EARTHENGINE_API_VERSION=0.1.233 25 | 26 | # ipyleaflet - Leaflet-based interactiving mapping widget 27 | # docs: https://ipyleaflet.readthedocs.io 28 | # source: https://github.com/jupyter-widgets/ipyleaflet 29 | # pkgs: conda search -c conda-forge ipyleaflet 30 | ARG IPYLEAFLET_VERSION=0.13.1 31 | 32 | # ipyvolume - 3d plotting in the Jupyter notebook 33 | # docs: https://ipyvolume.readthedocs.io/ 34 | # source: https://github.com/maartenbreddels/ipyvolume 35 | # pkgs: conda search -c conda-forge ipyvolume 36 | # npm search jupyter-threejs 37 | ARG IPYVOLUME_VERSION=0.5.2 38 | ARG THREEJS_VERSION=2.1.1 39 | 40 | # jupyterlab-manager 41 | # source: https://github.com/jupyter-widgets/ipywidgets/tree/master/packages/jupyterlab-manager 42 | # pkgs: npm search @jupyter-widgets/jupyterlab-manager 43 | ARG WIDGETS_JUPYTERLAB_MANAGER_VERSION=2.0.0 44 | 45 | # nbdime - Notebook Diff & Merge tool 46 | # docs: https://nbdime.readthedocs.io 47 | # source: https://github.com/jupyter/nbdime 48 | # pkgs: conda search -c conda-forge nbdime 49 | ARG NBDIME_VERSION=2.0.0 50 | 51 | # Palettable - color maps 52 | # docs: https://jiffyclub.github.io/palettable 53 | # source: https://github.com/jiffyclub/palettable 54 | # pkgs: conda search -c conda-forge palettable 55 | ARG PALETTABLE_VERSION=3.3.0 56 | 57 | # PyDrive - Simplifies many Google Drive API tasks 58 | # home: https://pypi.org/project/PyDrive 59 | # docs: https://pythonhosted.org/PyDrive 60 | # source: https://github.com/gsuitedevs/PyDrive 61 | # pkgs: conda search -c conda-forge pydrive 62 | ARG PYDRIVE_VERSION=3.3.0 63 | 64 | # TensorFlow - Computation using data flow graphs for scalable machine learning 65 | # home: https://www.tensorflow.org 66 | # docs: https://www.tensorflow.org/api_docs 67 | # source: https://github.com/tensorflow/tensorflow 68 | # pkgs: conda search -c conda-forge tensorflow 69 | ARG TENSORFLOW_VERSION=2.0.0 70 | 71 | # Vega Datasets - Collection of datasets used in Vega and Vega-Lite examples 72 | # docs: http://vega.github.io/vega-datasets 73 | # source: https://github.com/vega/vega-datasets 74 | # pkgs: conda search -c conda-forge vega_datasets 75 | ARG VEGA_DATASETS_VERSION=0.8.0 76 | 77 | #### Other packages 78 | # 79 | # nbgitpuller - Notebook Git Puller 80 | # source: https://github.com/data-8/nbgitpuller 81 | # 82 | # Sidecar - A sidecar output widget for JupyterLab 83 | # source: https://github.com/jupyter-widgets/jupyterlab-sidecar 84 | # 85 | # ipythonblocks - colored grids 86 | # home: http://www.ipythonblocks.org/ 87 | 88 | RUN conda update -n base conda && \ 89 | conda install --quiet --yes \ 90 | conda-build \ 91 | altair=${ALTAIR_VERSION} \ 92 | bqplot=${BQPLOT_VERSION} \ 93 | earthengine-api=${EARTHENGINE_API_VERSION} \ 94 | ipyleaflet=${IPYLEAFLET_VERSION} \ 95 | ipyvolume=${IPYVOLUME_VERSION} \ 96 | nbdime=${NBDIME_VERSION} \ 97 | palettable=${PALETTABLE_VERSION} \ 98 | pydrive=${PYDRIVE_VERSION} \ 99 | tensorflow=${TENSORFLOW_VERSION} \ 100 | vega_datasets=${VEGA_DATASETS_VERSION} \ 101 | jupyterlab=${JUPYTERLAB_VERSION} \ 102 | numpy=${NUMPY_VERSION} \ 103 | && \ 104 | conda clean --all -f -y && \ 105 | jupyter nbextension enable --py widgetsnbextension --sys-prefix && \ 106 | # JupyterLab Extensions 107 | pip install sidecar && \ 108 | jupyter labextension install --no-build jupyter-leaflet@${IPYLEAFLET_VERSION} && \ 109 | jupyter labextension install --no-build ipyvolume@${IPYVOLUME_VERSION} && \ 110 | jupyter labextension install --no-build jupyter-threejs@${THREEJS_VERSION} && \ 111 | jupyter labextension install --no-build bqplot@${BQPLOT_NPM_VERSION} && \ 112 | jupyter labextension install --no-build @jupyter-widgets/jupyterlab-manager && \ 113 | jupyter labextension install --no-build @jupyter-widgets/jupyterlab-sidecar && \ 114 | pip install ipythonblocks && \ 115 | export NODE_OPTIONS=--max-old-space-size=16000 && \ 116 | jupyter lab build && \ 117 | # Clean up 118 | npm cache clean --force && \ 119 | rm -rf $CONDA_DIR/share/jupyter/lab/staging && \ 120 | rm -rf /home/$NB_USER/.cache/yarn && \ 121 | rm -rf /home/$NB_USER/.node-gyp && \ 122 | fix-permissions $CONDA_DIR && \ 123 | fix-permissions /home/$NB_USER 124 | -------------------------------------------------------------------------------- /docker/jupyter-scipy-notebook-ee/README.md: -------------------------------------------------------------------------------- 1 | # Docker Image: Jupyter Notebook Scientific Python Stack + Earth Engine 2 | 3 | This directory contains a Docker image configuration for adding 4 | the Earth Engine Python API to the 5 | [Jupyter Notebook Scientific Python Stack](https://github.com/jupyter/docker-stacks/tree/master/scipy-notebook). 6 | The configuration file also installs several other 7 | [Jupyter Widgets](http://jupyter.org/widgets) that are useful for working with 8 | geospatial data. 9 | 10 | # Building the Image 11 | 12 | The Docker image can be built by opening up a terminal, navigating to this 13 | directory, and running the `docker build` command: 14 | 15 | ``` 16 | docker build . -t jupyter-scipy-notebook-ee 17 | ``` 18 | 19 | The `-t` parameter assigns the tag/name `jupyter-scipy-notebook-ee` to the image. 20 | 21 | # Running the Image 22 | 23 | To create a Docker container and start up JupyterLab, execute the following 24 | command: 25 | 26 | ``` 27 | docker run -it --rm -p 8888:8888 --hostname localhost -e JUPYTER_LAB_ENABLE=yes -v "$PWD:/home/jovyan/mount" jupyter-scipy-notebook-ee start.sh jupyter lab 28 | ``` 29 | 30 | This command will launch the JupyterLab UI. 31 | 32 | The `-v` flag specifies a volume mount, which exposes the host's current 33 | directory as the path `/home/jovyan/mount` within the container. 34 | You may want to add additional volume mounts for commonly used directories 35 | (like where you clone git repositories). 36 | 37 | From within the JupyterLab UI, you can open up a terminal tab, and use the 38 | Earth Engine 39 | [Command Line Tool](https://developers.google.com/earth-engine/command_line) 40 | to authenticate the container's access to the Earth Engine servers. 41 | 42 | ``` 43 | jovyan@1234567890ab:~$ earthengine authenticate 44 | Opening the following address in a web browser: 45 | 46 | https://accounts.google.com/o/oauth2/auth? ... 47 | 48 | Please authorize access to your Earth Engine account, and paste the generated 49 | code below. If the web browser does not start, please manually browse the URL 50 | above. 51 | 52 | Please enter authorization code: XXXXXXXXXXXXXXXXXXXXXXXX 53 | 54 | Successfully saved authorization token. 55 | ``` 56 | 57 | Now that you have authencated the server, from within a Notebook you can import 58 | and initialize the Earth Engine Python API. 59 | -------------------------------------------------------------------------------- /docker/minimal-install-debian-python27-ee/.dockerignore: -------------------------------------------------------------------------------- 1 | *.md 2 | -------------------------------------------------------------------------------- /docker/minimal-install-debian-python27-ee/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stable 2 | 3 | LABEL maintainer="tylere@google.com" 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | python-pip 7 | 8 | RUN pip install google-api-python-client 9 | RUN pip install google-auth-oauthlib 10 | RUN pip install earthengine-api 11 | 12 | ENTRYPOINT ["/bin/bash"] 13 | -------------------------------------------------------------------------------- /docker/minimal-install-debian-python27-ee/README.md: -------------------------------------------------------------------------------- 1 | # Minimal Earth Engine Python API Image 2 | 3 | This directory contains a Docker image configuration for a minimal container containing the Earth Engine Python API. 4 | (No Jupyter libraries are included.) 5 | 6 | # Building the Image 7 | 8 | The Docker image can be built by opening up a terminal, navigating to this directory, and running 9 | the `docker build` command: 10 | 11 | ``` 12 | docker build . -t debian-python27-ee 13 | ``` 14 | 15 | The `-t` parameter assigns the tag/name `debian-python27-ee` to the image. 16 | 17 | # Running the Image 18 | 19 | To create a Docker container and run it, execute the following command: 20 | 21 | ``` 22 | docker run -it debian-python27-ee 23 | ``` 24 | 25 | This will provide a bash shell prompt for the container (because the [Dockerfile](Dockerfile) specifies an entry point of /bin/bash). 26 | 27 | Using the bash shell you can use the Earth Engine [Command Line Tool](https://developers.google.com/earth-engine/command_line) 28 | to authenticate the container's access to the Earth Engine servers. 29 | 30 | ``` 31 | $ docker run -it debian-python27-ee 32 | root@1f439fe712a0:/# earthengine authenticate 33 | Opening the following address in a web browser: 34 | 35 | https://accounts.google.com/o/oauth2/auth? ... 36 | 37 | Please authorize access to your Earth Engine account, and paste the generated code below. If the web browser does not start, please manually browse the URL above. 38 | 39 | Please enter authorization code: XXXXXXXXXXXXXXXXXXXXXXXX 40 | 41 | Successfully saved authorization token. 42 | ``` 43 | 44 | From within the bash shell you can also open a Python shell to import and initialize the Earth Engine Python API. 45 | 46 | ``` 47 | root@1f439fe712a0:/# python 48 | Python 2.7.13 (default, Nov 24 2017, 17:33:09) 49 | [GCC 6.3.0 20170516] on linux2 50 | Type "help", "copyright", "credits" or "license" for more information. 51 | >>> import ee 52 | >>> ee.Initialize() 53 | >>> 54 | ``` -------------------------------------------------------------------------------- /examples/best-available-pixel/best-available-pixel-composite.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BEST AVAILABLE PIXEL COMPOSITE (BAP) *in Google Earth Engine Python API*\n", 8 | "based on *Pixel-Based Image Compositing for Large-Area Dense\n", 9 | "Time Series Applications and Science (White, 2014)*\n", 10 | "https://goo.gl/Fi8fCY\n", 11 | "\n", 12 | "* **Author**: Rodrigo E. Principe\n", 13 | "* **email**: fitoprincipe82@gmail.com\n", 14 | "* **GitHub**: github.com/fitoprincipe\n", 15 | "* **Repository GeeBap**: github.com/fitoprincipe/geebap" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "## Install Packages" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": { 29 | "collapsed": false 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "import sys\n", 34 | "!{sys.executable} -m pip install --upgrade geebap" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "## Make imports" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 4, 47 | "metadata": { 48 | "codeCollapsed": false, 49 | "collapsed": false, 50 | "hiddenCell": false 51 | }, 52 | "outputs": [ 53 | { 54 | "name": "stdout", 55 | "output_type": "stream", 56 | "text": [ 57 | "('version', '0.0.9')\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "# Import Earth Engine and initialize\n", 63 | "import ee\n", 64 | "ee.Initialize()\n", 65 | "\n", 66 | "# Import packages\n", 67 | "import geebap\n", 68 | "from geebap import bap, season, filters, masks, \\\n", 69 | " scores, satcol, functions\n", 70 | "from geetools import tools\n", 71 | "import pprint\n", 72 | "\n", 73 | "print('version', geebap.__version__)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "## Season\n", 81 | "This object holds information of the growing season (start, end and doy *best day of year*). You can make your own, or use 2 pre-made: `Growing_South` and `Growing_North`. This object does not hold any year, just day and month. For example, the pre-made `Growing_South` starts on November 15 (11-15) and ends on March 15 (03-15). But it has a method to add a year, see the example in the code:" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "metadata": { 88 | "collapsed": false 89 | }, 90 | "outputs": [], 91 | "source": [ 92 | "a_season = season.Season.Growing_South()\n", 93 | "ini, end = a_season.add_year(2000)\n", 94 | "\n", 95 | "print ini, end" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "Note that when the season covers two years, start date is in the previous year." 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "## Collections\n", 110 | "The main method to create a BAP uses a `ColGroup` object, that is basically a group of `Collection` objects. You can see all groups:" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": { 117 | "codeCollapsed": false, 118 | "collapsed": false, 119 | "hiddenCell": false 120 | }, 121 | "outputs": [], 122 | "source": [ 123 | "satcol.ColGroup.options()" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": {}, 129 | "source": [ 130 | "You could also make your own `ColGroup`, but you have to keep in mind that it is composed by `satcol.Collection` objects.\n", 131 | "As the process is made to combine pixels from all collections, `Collection` object renames the bands of each collection to match across all, resulting in the following names: BLUE, GREEN, RED, NIR, SWIR, SWIR2, ATM_OP. Also, each collection has methods ready to map a vegetation index: `ndvi`, `evi` and `nbr`. " 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "## Masks\n", 139 | "There is *(by now)* one mask you can include in the process: clouds" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": { 146 | "collapsed": true 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "cld_mask = masks.Clouds()" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "## Filters\n", 158 | "There are *(by now)* two filters you can use in the process:\n", 159 | "\n", 160 | "**cloud percentage**: `filters.CloudsPercent`\n", 161 | "\n", 162 | "**masked pixel percentage**: `filters.MaskPercent`. This filter can be used **only** if maskpercent score is included in the process." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 8, 168 | "metadata": { 169 | "collapsed": true 170 | }, 171 | "outputs": [], 172 | "source": [ 173 | "filt_cld = filters.CloudsPercent()\n", 174 | "filt_mask = filters.MaskPercent()" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "## Scores\n", 182 | "This is what makes the difference. Every score has its own parameters, but all share two main params:\n", 183 | "\n", 184 | "**range_out**: the range of values the score will be, by default it is (0, 1)\n", 185 | "\n", 186 | "**sleep**: as the creaton of a BAP composite is a 'concatenated' process, it can make more requests that are allowed, so if you set this parameter, the process will wait those seconds until the next computing." 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "## White's scores" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "### DOY (best day of the year)\n", 201 | "Basically, pixels from images closer to that date will have higher score\n", 202 | "It takes 2 params:\n", 203 | "\n", 204 | "**season**: You can use the same as the one for the process, or not. Each `Season` object has its own *doy*. By default it is `Season.Growing_South`\n", 205 | "\n", 206 | "**formula**: distribution ecuation. There are two (by now) options: `Normal` (https://en.wikipedia.org/wiki/Normal_distribution) or `Exponential` (https://en.wikipedia.org/wiki/Exponential_distribution). Default is `Normal`" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": 9, 212 | "metadata": { 213 | "collapsed": true 214 | }, 215 | "outputs": [], 216 | "source": [ 217 | "doy = scores.Doy()" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "### Satellite\n", 225 | "It uses a list of available satellite for each year that you can check:" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": { 232 | "collapsed": false 233 | }, 234 | "outputs": [], 235 | "source": [ 236 | "# List of satellites for 2000\n", 237 | "season.SeasonPriority.relation[2000]" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "the score has one main param:\n", 245 | "\n", 246 | "**rate**: how much score will decrease for each satellite. For example, for 2000, if rate is 0.05 (default value):\n", 247 | "\n", 248 | "* 'LANDSAT/LE07/C01/T1_SR' --> 1\n", 249 | "* 'LANDSAT/LE7_L1T_TOA_FMASK' --> 0.95\n", 250 | "* 'LANDSAT/LT05/C01/T1_SR' --> 0.90\n", 251 | "* 'LANDSAT/LT5_L1T_TOA_FMASK' --> 0.85\n", 252 | "\n", 253 | "*NOTE: may be the correct name would be 'ratio', so I may change it in the future*" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 11, 259 | "metadata": { 260 | "collapsed": true 261 | }, 262 | "outputs": [], 263 | "source": [ 264 | "sat = scores.Satellite()" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "### Atmospheric Opacity\n", 272 | "It uses the atmospheric opacity band computed by Surface Reflectance, so only SR collections will have this score. If the process uses a non-SR collection, like TOA, the this score will be zero." 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 12, 278 | "metadata": { 279 | "collapsed": true 280 | }, 281 | "outputs": [], 282 | "source": [ 283 | "atm_op = scores.AtmosOpacity()" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "## Distance to mask\n", 291 | "This assigns a score regarding the distance of the pixel to the closest masked pixel. As the only mask is for clouds, it could be considered 'distance to cloud'. It has 3 main params:\n", 292 | "\n", 293 | "**unit**: unit to measure distance. Defaults to 'meters'\n", 294 | "\n", 295 | "**dmax**: max distance. Pixel further than this distance will have score 1. Defaults to 600\n", 296 | "\n", 297 | "**dmin**: min distance. Defaults to 0 (next pixel from the maks will have score 0)." 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 13, 303 | "metadata": { 304 | "collapsed": true 305 | }, 306 | "outputs": [], 307 | "source": [ 308 | "dist = scores.CloudDist()" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": {}, 314 | "source": [ 315 | "## Custom Scores *(not White's)*" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "### Outliers\n", 323 | "It computes an statistics over the whole collection (in the season) and assigns score regarding the *distance* of each pixel value to that statistic. It has 3 main parameters:\n", 324 | "\n", 325 | "**bands**: a list of bands to include in the process. The process splits the score in the number of given bands. For example, if 4 bands are given, the max score for each band will be 0.25\n", 326 | "\n", 327 | "**process**: one of 'mean' or 'median'. Defaults to 'mean'\n", 328 | "\n", 329 | "**dist**: distance from 'mean' or 'median'. Defaults to 0.7\n", 330 | "\n", 331 | "*NOTE: bands must be in the image, so if you use a vegetation index, be sure to include it in the process*" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 14, 337 | "metadata": { 338 | "collapsed": true 339 | }, 340 | "outputs": [], 341 | "source": [ 342 | "out = scores.Outliers((\"ndvi\",))" 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": {}, 348 | "source": [ 349 | "### Mask percentage\n", 350 | "It computes the precentage of masked pixels in the image (not the whole scene). It has one main parameter:\n", 351 | "\n", 352 | "**band**: the band that holds the mask." 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 15, 358 | "metadata": { 359 | "collapsed": true 360 | }, 361 | "outputs": [], 362 | "source": [ 363 | "maskper = scores.MaskPercent()" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "### Vegetation Index\n", 371 | "This scores is based on the absolute value of the given index, parametrized to `range_out`. The only parameter is **index**: the name of it (*ndvi*, *evi* or *nbr*). Defaults to *ndvi*." 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 16, 377 | "metadata": { 378 | "collapsed": true 379 | }, 380 | "outputs": [], 381 | "source": [ 382 | "ind = scores.Index(\"ndvi\")" 383 | ] 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "metadata": {}, 388 | "source": [ 389 | "### Multiple years (seasons)\n", 390 | "If you want to use images from a range of seasons, and not just only one, this scores prioritizes the main season. Take in count that a season may hold 2 years, but the main is the least (see `Season`). It has 3 main params:\n", 391 | "\n", 392 | "**main_year**: this is the central year. Images from this year (season) will have score 1\n", 393 | "\n", 394 | "**season**: a `Season` object.\n", 395 | "\n", 396 | "**ratio**: amount of score that will decrease as it goes further to the main year. Defaults to 0.05. It is similar to *rate* parameter in `Satellite`.\n", 397 | "\n" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 17, 403 | "metadata": { 404 | "collapsed": true 405 | }, 406 | "outputs": [], 407 | "source": [ 408 | "# Will not use it in the test\n", 409 | "# multi = scores.MultiYear()" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "## Making the composite (BAP)\n", 417 | "Next step is to create a `Bap` object. It has the following parameters:\n", 418 | "\n", 419 | "**year**: The main year. Remember that a season can have 2 years.\n", 420 | "\n", 421 | "**range**: for multiyear composites you can specify a 'range' as a tuple: (years before, years after). Defaults to (0, 0).\n", 422 | "For example, if `range=(1, 1)` and `year=2000`, will compute 1999, 2000 and 2001.\n", 423 | "\n", 424 | "**colgroup**: `ColGroup` object. If `None` it will use the list computed by `SeasonPriority`. Defaults to `None`.\n", 425 | "\n", 426 | "**season**: a `Season` object\n", 427 | "\n", 428 | "**scores**: a list of `Score` objects\n", 429 | "\n", 430 | "**masks**: a list of `Mask` objects\n", 431 | "\n", 432 | "**filters**: a list of `Filter` objects\n", 433 | "\n", 434 | "**fmap**: custom function to apply before computing scores. At this point bands have new names (NIR, SWIR, etc) and vegetation index is computed." 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": 18, 440 | "metadata": { 441 | "collapsed": false 442 | }, 443 | "outputs": [], 444 | "source": [ 445 | "bap = bap.Bap(year=2010, range=(0, 0),\n", 446 | " season=a_season,\n", 447 | " masks=(cld_mask,),\n", 448 | " scores=(doy, sat, atm_op, dist, out, maskper, ind),\n", 449 | " filters=(filt_cld, filt_mask))" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "metadata": {}, 455 | "source": [ 456 | "## Define a site" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": 19, 462 | "metadata": { 463 | "collapsed": true 464 | }, 465 | "outputs": [], 466 | "source": [ 467 | "site = ee.Geometry.Polygon([[-71,-42],\n", 468 | " [-71,-43],\n", 469 | " [-72,-43],\n", 470 | " [-72,-42]])" 471 | ] 472 | }, 473 | { 474 | "cell_type": "markdown", 475 | "metadata": {}, 476 | "source": [ 477 | "## Finally, compute the composite\n", 478 | "`Bap` object has a method named `bestpixel` that creates one image out of the pixels with higher score in the collection (which includes all collections given). It has the following parameters:\n", 479 | "\n", 480 | "**site**: The site where the composite will be computed\n", 481 | "\n", 482 | "**indices**: a list of vegetation indices. Defaults to `None`\n", 483 | "\n", 484 | "**name**: name for the band that holds the final score. Defaults to *score*\n", 485 | "\n", 486 | "**bands**: a list of bands that will be on the image (in case you don't need all). Defaults to `None` which means *include all bands*\n", 487 | "\n", 488 | "**normalize**: normalize the final score to be between 0 and 1. Defaults to `True`\n", 489 | "\n", 490 | "**bbox**: distance of the buffer around the site. Defaults to 0.\n", 491 | "\n", 492 | "**force**: if there are no images for the specified parameters, and this is set to `True`, an empty image will be created. Defaults to `True`\n", 493 | "\n", 494 | "This method return a `namedtuple`, so `.image` will be the composite and `.col` will be the collection" 495 | ] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": null, 500 | "metadata": { 501 | "collapsed": false 502 | }, 503 | "outputs": [], 504 | "source": [ 505 | "composite = bap.bestpixel(site=site, indices=(\"ndvi\",))" 506 | ] 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "### Get the composite from the results" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "execution_count": 21, 518 | "metadata": { 519 | "collapsed": true 520 | }, 521 | "outputs": [], 522 | "source": [ 523 | "image = composite.image" 524 | ] 525 | }, 526 | { 527 | "cell_type": "markdown", 528 | "metadata": {}, 529 | "source": [ 530 | "## Watch the resulting composite\n", 531 | "*it may take a while..*" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 22, 537 | "metadata": { 538 | "collapsed": false 539 | }, 540 | "outputs": [ 541 | { 542 | "data": { 543 | "text/html": [ 544 | "" 545 | ], 546 | "text/plain": [ 547 | "" 548 | ] 549 | }, 550 | "execution_count": 22, 551 | "metadata": {}, 552 | "output_type": "execute_result" 553 | } 554 | ], 555 | "source": [ 556 | "from IPython.display import Image\n", 557 | "url = image.getThumbUrl({'min':0, 'max':0.7, 'region':site.getInfo()['coordinates']})\n", 558 | "Image(url=url, format='png', embed=True)" 559 | ] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": null, 564 | "metadata": { 565 | "collapsed": true 566 | }, 567 | "outputs": [], 568 | "source": [] 569 | } 570 | ], 571 | "metadata": { 572 | "kernelspec": { 573 | "display_name": "Python 2", 574 | "language": "python", 575 | "name": "python2" 576 | }, 577 | "language_info": { 578 | "codemirror_mode": { 579 | "name": "ipython", 580 | "version": 2 581 | }, 582 | "file_extension": ".py", 583 | "mimetype": "text/x-python", 584 | "name": "python", 585 | "nbconvert_exporter": "python", 586 | "pygments_lexer": "ipython2", 587 | "version": "2.7.9" 588 | } 589 | }, 590 | "nbformat": 4, 591 | "nbformat_minor": 2 592 | } 593 | -------------------------------------------------------------------------------- /examples/export/export-image-gdrive.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 7, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "\n", 11 | "from IPython.display import Image\n", 12 | "\n", 13 | "import ee\n", 14 | "ee.Initialize()" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "### Exporting images, map tiles, features, and videos\n", 22 | "\n", 23 | "Shows how to export assets using Google Earth Engine API." 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 8, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "# use ALOS DEM\n", 33 | "dem = ee.Image(\"JAXA/ALOS/AW3D30_V1_1\").select('MED')\n", 34 | "\n", 35 | "# define export region\n", 36 | "region = ee.Geometry.LineString([[93.116, 28.709], [93.148, 28.673]]).bounds()" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 9, 42 | "metadata": {}, 43 | "outputs": [ 44 | { 45 | "data": { 46 | "image/png": "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\n", 47 | "text/plain": [ 48 | "" 49 | ] 50 | }, 51 | "execution_count": 9, 52 | "metadata": {}, 53 | "output_type": "execute_result" 54 | } 55 | ], 56 | "source": [ 57 | "# preview image to be exported\n", 58 | "image = dem.visualize(**{ 'min': 3800, 'max': 5260 })\n", 59 | "\n", 60 | "# generate url to image thumbnail\n", 61 | "url = image.getThumbUrl({'region': region.getInfo(), 'dimensions': 256})\n", 62 | "\n", 63 | "# display image\n", 64 | "Image(url=url, embed=True, format='png')" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 14, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "VYTWJRXR4XMLMGBBUBCYOLA4\n" 77 | ] 78 | } 79 | ], 80 | "source": [ 81 | "# schedule a new export image task, here we will export to Google Drive\n", 82 | "file_name = 'dem'\n", 83 | "export_region = region.getInfo()['coordinates'] # BUG: it should just accept region as-is\n", 84 | "task = ee.batch.Export.image.toDrive(dem, description=file_name, fileNamePrefix=file_name, region=export_region, scale=30)\n", 85 | "task.start()\n", 86 | "\n", 87 | "# remember task id and use it to check tasks status later\n", 88 | "task_id = task.id\n", 89 | "print(task_id)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 15, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "# create a new task using id\n", 99 | "task = ee.batch.Task(task_id)" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 22, 105 | "metadata": {}, 106 | "outputs": [ 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "{'creation_timestamp_ms': 1516613914847,\n", 111 | " 'description': 'dem',\n", 112 | " 'id': 'VYTWJRXR4XMLMGBBUBCYOLA4',\n", 113 | " 'output_url': ['https://drive.google.com/'],\n", 114 | " 'start_timestamp_ms': 1516613923048,\n", 115 | " 'state': 'COMPLETED',\n", 116 | " 'task_type': 'EXPORT_IMAGE',\n", 117 | " 'update_timestamp_ms': 1516613929922}" 118 | ] 119 | }, 120 | "execution_count": 22, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "# query task status, it should go from READY -> RUNNING -> COMPLETED\n", 127 | "task.status()" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "Tasks state can be one of: \n", 135 | "\n", 136 | "* __READY__\n", 137 | "* __RUNNING__\n", 138 | "* __COMPLETED__\n", 139 | "* __CANCELLED__\n", 140 | "* __CANCEL_REQUESTED__\n", 141 | "* __FAILED__\n", 142 | "\n", 143 | "TODO: embed state diagram here\n", 144 | "\n", 145 | "TODO: show how to fetch results from Google Drive" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 10, 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "name": "stdout", 155 | "output_type": "stream", 156 | "text": [ 157 | "177\n", 158 | "\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "# query current user tasks\n", 164 | "tasks = ee.batch.Task.list()\n", 165 | "\n", 166 | "print(len(tasks))\n", 167 | "print(tasks[0])" 168 | ] 169 | } 170 | ], 171 | "metadata": { 172 | "anaconda-cloud": {}, 173 | "kernelspec": { 174 | "display_name": "Python [default]", 175 | "language": "python", 176 | "name": "python3" 177 | }, 178 | "language_info": { 179 | "codemirror_mode": { 180 | "name": "ipython", 181 | "version": 3 182 | }, 183 | "file_extension": ".py", 184 | "mimetype": "text/x-python", 185 | "name": "python", 186 | "nbconvert_exporter": "python", 187 | "pygments_lexer": "ipython3", 188 | "version": "3.5.2" 189 | } 190 | }, 191 | "nbformat": 4, 192 | "nbformat_minor": 1 193 | } 194 | -------------------------------------------------------------------------------- /examples/geometry/image_profile.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "\n", 11 | "import matplotlib.pyplot as plt\n", 12 | "\n", 13 | "import ee; ee.Initialize()" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "This notebook demonstrates how image values can be reduced along polyline. \n", 21 | "\n", 22 | "The _reduceImageProfile()_ function defined below reduces values along given line (_ee.Geometry.LineString_). Input line first gets split into a number of shorter line segments using _ee.Geometry.cutLines()_, which are then used to actually reduce image values." 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "def reduceImageProfile(image, line, reducer, scale):\n", 32 | " \"\"\"Returns image values reduced along given line.\n", 33 | "\n", 34 | " Args:\n", 35 | " image: Image to be reduced.\n", 36 | " line: The line string used to query image values. The function splits\n", 37 | " the line into smaller segments with the length equal to scale.\n", 38 | " These smaller segments are then used to reduce image values with\n", 39 | " the reducer.\n", 40 | " reducer: Used used to reduce image values along line segments.\n", 41 | " scale: Indicates scale used to cut line into shorter line segment.\n", 42 | "\n", 43 | " Returns:\n", 44 | " An ee.FeatureCollection containing distance and iamge value properties. \n", 45 | " \"\"\"\n", 46 | "\n", 47 | " length = line.length()\n", 48 | " distances = ee.List.sequence(0, length, scale)\n", 49 | " lines = line.cutLines(distances).geometries()\n", 50 | "\n", 51 | " def generate_line_segment(l):\n", 52 | " l = ee.List(l)\n", 53 | " geom = ee.Geometry(l.get(0))\n", 54 | " distance = ee.Geometry(l.get(1))\n", 55 | "\n", 56 | " geom = ee.Algorithms.GeometryConstructors.LineString(geom.coordinates())\n", 57 | "\n", 58 | " return ee.Feature(geom, {'distance': distance})\n", 59 | "\n", 60 | " lines = lines.zip(distances).map(generate_line_segment)\n", 61 | " lines = ee.FeatureCollection(lines)\n", 62 | "\n", 63 | " # reduce image for every segment\n", 64 | " band_names = image.bandNames()\n", 65 | "\n", 66 | " return image.reduceRegions(lines, reducer.setOutputs(band_names), scale)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 3, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "# image to be queried\n", 76 | "image = ee.Image('USGS/NED')\n", 77 | "\n", 78 | "# a line string used to qeury image values\n", 79 | "line = ee.Geometry.LineString(\n", 80 | " [[-114.3843, 36.4257],\n", 81 | " [-114.3616, 36.4220],\n", 82 | " [-114.3514, 36.4203],\n", 83 | " [-114.3419, 36.4199],\n", 84 | " [-114.3116, 36.4228]])" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 4, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "[]" 96 | ] 97 | }, 98 | "execution_count": 4, 99 | "metadata": {}, 100 | "output_type": "execute_result" 101 | }, 102 | { 103 | "data": { 104 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwEAAAHVCAYAAACpL/cFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmUpNdZ5/nfjX3LyK0ya99UKskqLZatsmwj25K3tsFqq2FY3DOmzQxgYHzAA0zTo8E9faBbp7uhB9ychmE8xoMx7jEGgzGmjS1LFiBvskqbVSpJVapSZa25Z0Zm7MudP96IyMyqiMiIzNjj+znHh6w33oi4Jaqk+MXzPPcaa60AAAAADA5XpxcAAAAAoL0IAQAAAMCAIQQAAAAAA4YQAAAAAAwYQgAAAAAwYAgBAAAAwIAhBAAAAAADhhAAAAAADBhCAAAAADBgPJ1egCTt2LHDHjp0qNPLAAAAAHraiRMn5qy1E5vd1xUh4NChQ3ryySc7vQwAAACgpxljztdzH+1AAAAAwIAhBAAAAAADhhAAAAAADBhCAAAAADBgCAEAAADAgCEEAAAAAAOGEAAAAAAMGEIAAAAAMGAIAQAAAMCAIQQAAAAAA4YQAAAAAAwYQgAAAAAwYAgBAAAAwIAhBAAAAAADhhAAAAAADBhCAAAAADBgCAFoC2ttp5cAAACAIkIAWm4hntEdv/E1fe3k1U4vBQAAACIEoA2eubColVROf/Lt851eCgAAAEQIQBu8cDkmSfrmK3O6tJTs8GoAAABACEDLnbwc02jIKyPpj795rtPLAQAAGHiEALTcC1dievORcf2z1+3Vn3z7vGZiqU4vCQAAYKARAtBSK6mszs8ndOueYf3P9x1ROlfQ10/NdHpZAAAAA40QgJY6NxeXJN04GdGh8bCMkaapBAAAAHQUIQAtNbWQkCQdGAvJ43ZpPOzTzEq6w6sCAAAYbIQAtFQpBOwfC0mSJoYCml2hEgAAANBJhAC01IWFhMbDPkX8HknS5JCfSgAAAECHEQLQUlMLiXIVQCqGgBghAAAAoJMIAWipqYWEDqwPAVG/5lbTKhRsB1cFAAAw2AgBaJlLS0ldXkptDAFDAeUKVguJTAdXBgAAMNgIAWiJudW03vofH1W+YHXDRLh8fXLIL0m0BAEAAHQQIQAtMb+aUcFKP3rXPt1/x57y9cloMQSwQxAAAEDHEALQEqlsXpL0Q7fvks+z9sdsciggSewQBAAA0EGEALREKQQEPO4N1yeK7UCzhAAAAICOIQSgJZKlEODbGAICXreiAY9mYrQDAQAAdErdIcAY4zbGPG2M+fK6a79ojHnRGHPSGPNb664/aIw5Y4x5yRjznmYvGt0vlS1Iur4SIEmT0QDtQAAAAB3kaeDej0o6JSkqScaYt0t6QNJrrbVpY8xk8foxSR+QdKukPZK+boy5yVqbb+rK0dXSuWIlwHt9zuTUYAAAgM6qqxJgjNkn6X2SPrnu8i9I+g/W2rQkWWtnitcfkPQ5a23aWntO0hlJdzdvyegFyUwpBFSoBAz52R0IAACgg+ptB/q4pF+TVFh37SZJbzXGfNcY8/fGmDcUr++VdGHdfReL1zBASoPBwUohIBrQTCwtazk1GAAAoBM2DQHGmPslzVhrT1zzkEfSmKQ3SfqXkj5vjDH1vrEx5sPGmCeNMU/Ozs42smb0gFSuOBNQpRKQzhUUS+XavSwAAACovkrAPZLeb4x5VdLnJL3DGPOncr7h/0vreEJOlWCHpEuS9q97/r7itQ2stZ+w1h631h6fmJjY5m8D3abUDuT3XP9HbG2bUFqCAAAAOmHTEGCtfdBau89ae0jOwO+j1toPSvqipLdLkjHmJkk+SXOSviTpA8YYvzHmsKSjkp5o0frRpVK5vPwel1yu64tD5QPDYgwHAwAAdEIjuwNd61OSPmWMeV5SRtKHrNPkfdIY83lJL0jKSfoIOwMNnnS2ULEVSJImo04lYJpKAAAAQEc0FAKstY9Jeqz4c0bSB6vc95Ckh7a5NvSwZCZfcXtQSRoL+SRJS4lsO5cEAACAIk4MRkukcvmKOwNJUiTgZM8VBoMBAAA6ghCAlkhl81Xbgbxul4Jet2JJKgEAAACdQAhASySzBfmrhABJigY9VAIAAAA6hBCAlkhl8wpWmQmQpKGAV7EUlQAAAIBOIASgJdI12oEkKRqgEgAAANAphAC0RDKbV8BTPQQMBbxaoRIAAADQEYQAtEQqW1DQVysEeBSjEgAAANARhAC0hLM7UPU/XtEglQAAAIBOIQSgqVbTOf38Z05oZiUtf812II9iSSoBAAAAnUAIaMBMLKXf+rsX9UePn5O1ttPLaauLiwm98/98TKenV2re9/UXpvV3J69KUs12oGjAq0y+oFQ239R1AgAAYHOEgAZ84alL+oPHXtG//fILmllJd3o5bfX733hFr8zG9ZXnr264HktlNwSiv1v3eK3B4CinBgMAAHQMIaABr87Fyz8vD9hpt//w8qwkKbhu288Xr8Z01799WN96ZV7ZfEH/5q+f1zdemik/XmsmYCjglSTOCgAAAOgAQkADzs2vhYDYAIWAF6/GdGkpKUlaTGTK1z/7nSll81YXFxN68cqKPv3t80rnCnrTDWOSpGy+UPU1o0EqAQAAAJ1CCGjA+fm4jk5GJA3Wh9e/fuay3C4jY6TFhBN+kpm8vvj0JUnOP4ursZRz70fu0QN37pUknV1XOblWuRIwQGEKAACgWxAC6pTI5DQdS+v2fcOSBqeNpVCw+tIzl/XWozt0ZCKipWIl4MvPXdZK2glC8XS+HAJ2DQf0g7ft0s07h/Qzb7mh6utGiyFgkMIUAABAtyAE1OnVuYQk6Y69xRAwIN9gn5ha1KWlpB64c49GQ14tFSsBn/veBd0wEZbf41I8k9P0ckpul9GOiF8jIZ+++stv07E90aqvW2oHGrTZCgAAgG5ACKjT+eI8wO37RiRpYE67/etnLingdemfHNulkZBPi4mMzs6u6sT5Rf3zNxxQxO/RatppB5qI+OV2mbpedzzslyTNDtguSwAAAN2AEFCnqQWnEnB0Z0R+j2sg2oGy+YL+9rkrevexXQr7PeVKwGMvOTsFvfc253o8ndN0LKWdw4G6X9vncWk05NXMSqpVywcAAEAVhIA6XV5KaijgUTTgVTToHYjTbp86v6jFRFbvu323JGm0WAn4h9OzumFHWPvHQuUQcHU5pV1Rf0OvPzkUGLjzFgAAALoBIaBOl5ZS2jsSlCQNBTwDUQk4MbUoSXrjYWfLz5GQT+lcQY+9NKu3Ht0hSRoqtQMtp7QrWn8lQJImo35CAAAAQAcQAup0eSmpPcUQEA14B2Iw+KnzS7phIqzRsE+SNBrylh+79+YJSVLY79ZMLK2VdK6hdiDJqQTMxmgHAgAAaDdCQJ2uLCe1Z8T5kBsNevt+a0trrZ6aWtTrD4yWr42EfOWf77nRqQSE/Z7yvMRWKgGzq2lZa5uwYgAAANSLEFCHRCanxURWu4dLlYD+bwc6P5/QQjyzIQREA862npNDfvk9bklSxO9RruB8iN/VcCXAr2zelg8gAwAAQHsQAupweclpWVmbCej/weAT5515gLsOroWAgzvCkqSP3X+sfC3s95R/brgSMOTcP01LEAAAQFt5Nr8Fl5eSkrQ2ExDs/0rAU1OLGvJ7dHQyUr62dySoMw/9oDzutewYWR8CGqwE7CzuJjSzktYtu7e5YAAAANSNSkAdSgeF7S5+yI0GvMrkCkpl851cVks9NbWkOw+MyHXN4V/rA4C0FgKGAh6FfI1lylIlYIZKAAAAQFsRAjZhrdV/feKCjkyEy+1AExHnG+xnLix1cmkts5rO6aWrsQ3zANWU2oEabQWSpLGIM2i8xEwAAABAWxECNvH4mTmduhLTz997pPyt+Pvu2K09wwH9m78+qUKh/3a2efFKTAUrvXb/8Kb3hv3OgHCjrUCSFPa55XEZLSUzDT8XAAAAW0cI2MSzxW/7/+lr95Svhf0e/dy9R/TS9IouLyc7tbSWeXXe2fLz8I7IJnc6bUCStHMLlQBjjEZCXnYHAgAAaDNCwCZmVtIaDnoV8Lo3XC996F3uw0PDpubjcpm13ZBqCfu23g4kScNBr5YJAQAAAG1FCNjE7EpaE0P+664PB53Tc/vxA+z5hYT2jATl82z+x6M0E9DoacElIyEf7UAAAABtRgjYxMxKujwIvN5IqBgC+rAScH4+oYPjobruPTIR0btumdRbiycIN2ok6GUwGAAAoM0IAZuYXUlrMlq9ErDUhyFgaiGhA2Phuu4N+tz65IfeoEM76rv/WiMhHyEAAACgzQgBNVhrNbOSqlgJKLcD9VkIiKWyWohn6q4EbNdIyKulBO1AAAAA7UQIqGE1nVMqW6hYCQj53PK6Td+FgKnizkAHx9oUAoJexTN5ZXKFtrwfAAAACAE1za6kJaniYLAxRsN92M9+vhgCDrSxEiCJ4WAAAIA2IgTUMFMMAZNDlXe+GQ56FeuzSsD5hbgk6eD41nr8GzUcck4N7sddlgAAALoVIaCGWpUAqbjHfZ+FgKn5hHZEfIoUt/5stZE+HrAGAADoVoSAGuZWnRCwo8JgsOSEgH5rYzk/n9CBNs0DSNJosRLQb21VAAAA3YwQUMNKKidJGgpU/lZ8JOTrv0rAQqJtrUDS2kzAIjsEAQAAtA0hoIbVdE4Br0ted+V/TMNBb1/1sqdzeV1eTra1ElAKWKXABQAAgNYjBNSwksop4vdWfTwa9CqWyilfsG1cVetcXEzKWrXtjABJChdnD+JpQgAAAEC7EAJqWE3nqrYCSWtDrSup/qgGXF5KSpL2jgTb9p5et0s+j4sQAAAA0EaEgBri6VzNXXL67dTgq8spSdKu4cpborZKxO/RKiEAAACgbQgBNaymaoeA8kFXfTIXMB1zQsDOaHtDQNjvphIAAADQRoSAGlbSOUVqtAP1WyVgOpbWSMirgNfd1vcN+zxaTefb+p4AAACDjBBQw2o6q6E62oH65aCrq7GUdlY5HbmVIn4PlQAAAIA2IgTUsJrapBIQ6rdKQEo72zwPIDk7BMUzhAAAAIB2IQTUsJrOlbewrKRUCYi1IAQ8cmpa7/8vj+sz3znf9Neu5upySruilU9HbiUGgwEAANqLEFBFOpdXNm9rDgb7PW4FvC4tNfm02xPnF/Thz5zQ2dm4/vUXn9eLV2NNff1KcvmC5lbT2tXmoWCJwWAAAIB2IwRUsVo8wbbWOQGSNBL0Nb0d6FOPv6qhgEe//z+8XtLa1p2tNLeaUcGqc+1ADAYDAAC0DSGgilJ7Sq1KgOS0BDUzBMyspPTVk1f1Y3ft04Ex5+TexSZXGqq9ryRNdmowOJOTtf1x8jIAAEC3IwRUsZKqMwSEvE09J+Ar37+qXMHqJ96wX2MhnyRpfrX1IaD0+41uUvlohbDfI2ulRIZqAAAAQDsQAqooVwI2+VDcrEqAtVaL8Yz+/uVZHRwP6cbJIUWDHrldpi2VgFJPfq1B6FYpvSdzAQAAAO3R/k98PaI8E+D31rxvOOjVySaEgMdemtX/+MffkyT9izcflCQZYzQa8mkh3oYQkOlcCIj4ncPJVtM5Tbb93QEAAAYPlYAq6q0EjAS9TTks7B9Oz5Z/vvemifLPY2FvW0JA6cTesL+9pwVLzonBkhgOBgAAaBMqAVU0MhicyOSVzRfkdW89U528FNP+saD++7sP6m0bQoBPi/HWH0ZWbgfydaIS4LznSro/Dl0DAADodlQCqih9+146EKyaZpwanMsX9P1Ly3rna3bqF+47siFMjIV9mo+nt/za9UqkczJGCvk6UAnwUwkAAABoJ0JAFdOxlMbCPvk8tf8RhYrfnCe3sbPNy9OrSmbzunP/yHWPjYZ8Wmzi7kPVrKbzCvs8Msa0/L2uxWAwAABAexECqpiOpTU55N/0Pn8xJKSyWw8Bz15ckqSKIWA87NNiIqN8obV76MfTuY7MA0hrB7KtEAIAAADaghBQxexKSjujmx+cFfA6H5xT2cKW3+uZqSUNB706OB667rHRsE/WNt5u1GhoiGdyHZkHkKRowGmpijX55GUAAABURgioYjqW1s7o5pWAgLdYCchtrxLw2v0jFVtxxsLOgWFzq/XPBfzlUxd1529+Tc9fWq77OU4loDMhIOB1yed2EQIAAADahBBQQb5gNbua1uRQI5WArYWAeDqnl6dXKrYCSdKte4YlSX//0mzFx6/1nbPz+ldfeE4rqZz+6ulLDawj37F2IGOMok06dA0AAACbIwRUMB9PK1+w9VUCPM4H5/QW24G+f2lZBSvduX+44uM3Tkb0ugMj+vMTF2Rt7Raf6VhKP/eZEzowFtKbbhjTV75/Rbl8fetaTXeuHUiSRkKEAAAAgHYhBFQwE3NabybrmgnYXjvQi1dikqTb9lQOAZL0Y3ft18vTqzp5OVbztb71ypyWk1n97k/cqR+9a78uL6d07P/4qk5e3rwtKJHpXDuQ5GzFSggAAABoD0JABdOxlCS1ZTD4zOyqhgIeTdTYieg9t+6UMdIjp2ZqvtbL06vyuo1u2R3VP33tbv3r+49JRvqLExc3XcdqOk8IAAAAGBCEgAqmS5WANmwRemZmVTdORmruzz8e8evO/SN69MXpmq91enpFh3eE5XW75Pe49dNvOax33Dypv3n2yqa7BcXTOYU7cFBYCSEAAACgfQgBFVxZTsplVPPb+RL/NgeDz8ys6uhkZNP73vmaST17cVkzK6mq95yeWdXRnUMbrr3/zj2aW03re68uVH1evmCVzFIJAAAAGBSEgAouLSa1KxqQ1735P57STEA613g70FIio7nVjG6sIwTce9OkJOnbr8xXfDyZyWtqIXFdoLjnxh0yRvru2eohIJFxDumKdDAERINeraRyLT8UDQAAAISAii4uJrVv9PqDuyrxuV0yZmuVgDMzq5JUVwg4tieqIb9H3z1X+cP8K7Orsla66ZpKwHDQq5t3DtWsBMTTzto7XQmQpJUU1QAAAIBWIwRUcGkpqb2jwbruNcYo4HFvqRJwdi4uSbphx+YhwO0yOn5oVN85u7ESEE/n9HuPnNbXXnDmBe7Yd/0uQ3cfHtNTU4tVtwtdTTuVgE6dEyCthQBaggAAAFqPEHCNXL6gq7GU9o7UFwIkpyVoK5WAiwsJuYzqDhxvvGFcZ2fjG+YC/va5K/qdh1/W7z1yWrfvHa5YwXjDoTElMnmdurJS8XXjpRDQwXMCCAEAAADtU3cIMMa4jTFPG2O+fM31XzXGWGPMjnXXHjTGnDHGvGSMeU8zF9xqV5ZTyhds3R/MJWeb0K2EgAuLSe0eDtY1eyBJd+x1vuUvtRFJ0tXYWiB47227Kj6v1G50YTFR8fEry0lJ0q7hzbdEbZVSCFhKEAIAAABarZGvfj8q6ZSkaOmCMWa/pH8iaWrdtWOSPiDpVkl7JH3dGHOTtXZr2+e00XIyqz96/JwkNVgJcG/pnICLiwntayBs7C6u6crS2gf/c8WWomO7o3rgzj0Vn1c672A6VnlnoakFJxzsH6tvDqIVRkJUAgAAANqlrq+gjTH7JL1P0ieveeh3Jf2apPVbujwg6XPW2rS19pykM5LubsJaW+53H35Zf/ytVyWpoQ/nfs/W2oEuLCQb+uC9u/hN/fpv/8/OxXXPjeP6bx99a9Vh5tGQV163KZ9/UGkd0YCn/G18J0QDznvHGAwGAABouXrbgT4u58N++etuY8wDki5Za5+95t69ki6s+/XF4rUNjDEfNsY8aYx5cnZ2trFVt0AuX9CXn7usXdGAju2O1r07kOScFZBqcDA4nctreiXVUNgIeN0aDXnL7TvWWp2bXdXhHeGazzPGaHIoUPWMgamFhA6Md64KIK1ttZrZwoA1AAAAGrNpO5Ax5n5JM9baE8aY+4rXQpL+dzmtQFtirf2EpE9I0vHjxzu+Ofw3X5nX3GpGf/jBu6r21lcT2EIl4NJiUtZK+xsIG5K0ezhYbgdaTGQVS+V0uI7dhSaG/JqpWglI6DW7hyo+1i6luYhslR2MAAAA0Dz1VALukfR+Y8yrkj4n6R2SPiPpsKRni9f3SXrKGLNL0iVJ+9c9f1/xWlc78eqCXEa67+aJhp8b8LqVbjAEXFh0vs1vtA9/93BAV5ZTOj8f1wc+8W1J0g2bVAIkaWfUX7ESUChYXVxsrC2pFdZCQMfzIAAAQN/bNARYax+01u6z1h6SM/D7qLX2v7PWTlprDxWvX5T0emvtVUlfkvQBY4zfGHNY0lFJT7Tut9Ac5xcS2jMSVMDb+F75Aa+r4XMCLi6WhnHrbweSnB18rsZS+sJTl3RmZlU/fnyf7j48tunzdkYDFWcCpldSyuQLDVckms3rNpK2dvIyAAAAGtP0jeGttSeNMZ+X9IKknKSP9MLOQFMLCR3Y4rfhW9ki9MJCUj63SzuHGtuWc89IUAvxjP7m2cs6fmhMv/Wjr63reZNDfi0ns0pl8xuCTmm70UPjm1cTWskYI6/b0A4EAADQBg0dFmatfcxae3+F64estXPrfv2QtfaItfZma+1XmrHQVpuaT+jgFodjA57Gtwi9sJjQ3tGgXC7T0PN2Fbf7PDcX13turX92YbL4vNmVjdWAJ19dlDHSHfuvP2m43bxul7JUAgAAAFquc0fEdpHVdE7z8cyW++IDXpdSucYqARcXGjsjoOT1B0d142REHpfR/Xfsrvt5688KWP/7PHF+UTfvHCpv0dlJXreLSgAAAEAbEALkVAEk6eDY1lpi/FtpB1pM6j17Gv/2/fCOsL7+K/c2/LzJIb8kaWZdJSCXL+jpqUX98Ouv28G1I7xulzIMBgMAALRcQ+1A/WpqwTl1d8szAR6XUtmCrK3vA2w8ndNCPNPwUPB2VDo1+OXpVcUzeR0/uPlgcTv4PVQCAAAA2oEQIGcoWNKWD8zyFwdt693Z5mJpe9A27shTOjV4fSXg5OVlSdJtezs/DyCJwWAAAIA2oR1I0ntv3a3dw0ENB7fWFx9YFwLq2WL0wkJpe9D2hYDSqcHrKwGnrqwo4HVteuJwuzATAAAA0B6EADkVgK1WASRnMFiSUtl8XUFiIZ6R5Jzi206T0Y2nBr94Naabdw7J3eAORa3idbuUyTETAAAA0Gq0AzVBxO9kqXg6V9f9K8X7Ss9rl8mhtVODrbU6dSWmW3ZH27qGWrwelzJUAgAAAFqOENAEpQ/zq3WGgNVUZ0LA+lODp2NpLSayXRUCfG7DOQEAAABtQAhognIISNUZAtJZhXzutrfhrD81+MnzC5K6ZyhYYiYAAACgXQgBTRAJOCFgpd5KQDrX9iqAtPHU4EdPzWgk5NWd+0favo5qCAEAAADtQQhogiG/MwxcbyVgJZUrB4d2Kp0V8JdPXdI3XprR22+e7JqhYInDwgAAANqF3YGaoPSBvu6ZgA5VAt54eEw/cGRcv/v1lyVJ77xlsu1rqIXDwgAAANqDENAEYb9zNkAjg8GdCAEBr1uf/Zk36pkLS5qOpfXuYzvbvoZaOCwMAACgPQgBTeD3uOXzuLRS92BwTgfC7TsobD1jjF53YLQj770Zr9vF7kAAAABtwExAkwz5PVpJZeu6t1MzAd3OOSeAmQAAAIBWIwQ0yVDA09BMwFAH2oG6nc/tUiaX7/QyAAAA+h4hoEkiAU9duwNZa53BYCoB13FmAqgEAAAAtBohoEkifk9d5wSksgXlC1aR4raiWMM5AQAAAO1BCGiSiN9bVyVgJe3MDVAJuJ7X7VKuYFUoUA0AAABoJUJAk9Q7E1AKCswEXM/ncf44ZgtUAwAAAFqJENAkEX+dIaB4TyfOCeh2PncxBDAXAAAA0FKEgCaJBDyKJbM6Px+veV+pEkA70PW8biNJnBUAAADQYoSAJon4PcoVrO797cc0t5queM9yMqvf/tpL5fuxkbfUDsRwMAAAQEsRAprE2rUWlqvLqYr3fOX7V/T01JJGQ17tGw22a2k9w1tsB8oQAgAAAFqKENAkP3j7bh0cD0mSlhKVTw4+v5CQx2X05MferZGQr53L6wmlmYAM7UAAAAAtRQhokiMTEf0//+K4JGkxkal4z4WFhPaOBuV2mXYurWd4GQwGAABoC0JAE42EnAPAlqqFgMWk9o+G2rmknlIeDKYdCAAAoKUIAU00EnRafBartANdXEho/xizANWUBoOZCQAAAGgtQkAT+TwuRfyeijMB8XRO8/GM9lEJqKp8TgAzAQAAAC1FCGiy4aC3YjvQhcWEJGn/GCGgmvKJwcwEAAAAtBQhoMlGw96Kg8EXFpKSpAOEgKrWBoOpBAAAALQSIaDJRkO+ijMBJy8vyxjpyES4A6vqDaXBYGYCAAAAWosQ0GQjIV/FdqAT5xd1884hDQW8HVhVb/BRCQAAAGgLQkCTjYa811UCCgWrZ6aWdNfB0Q6tqjfQDgQAANAehIAmGwn5FEtllS+sDbeenlnVSjpHCNhEeYtQdgcCAABoKUJAk42GvLJWWk6uVQOeubAoSXrdAUJALaV2oDQhAAAAoKUIAU22Z8Q5DGxqIVG+durKikI+tw6yM1BNoyGv3C6j6Viq00sBAADoa4SAJju2OyrJ2Q2o5MWrMd28a0gul+nUsnqCx+3S7uGALi4mO70UAACAvkYIaLJ9o0FFAx69cDmmb7w4o5/9kyf1xLkFvWZXtNNL6wn7RoOEAAAAgBbzdHoB/cYYo2N7ovrsd6f0+ScvlE+/vWX3UIdX1hv2jYb0+Om5Ti8DAACgr1EJaIGDY86BYPtGQ/IUW4Bu2kkIqMfekaCmV1JK5/KdXgoAAEDfIgS0wDtumZQk/acfu0N/84tv0Xtv3aU79490eFW9Yd9oUNZKV5YYDgYAAGgV2oFa4D237tKp33yvgj63JOkPf/KuDq+od+wbdXZQuriY1KEd4Q6vBgAAoD9RCWiRUgBAY/aNOlusXlxMbHInAAAAtooQgK4yGfVLkmZW0h1eCQAAQP8iBKCr+D1ujYS8miUEAAAAtAwhAF1nIuInBAAAALQQIQBdZ2LIr5kVdgcCAABoFUIAus7kkF+zq1QCAAAAWoUQgK4zMeS0A1lrO70UAACAvkRJd5qaAAAgAElEQVQIQNeZGPIrlS1oNZ3r9FIAAAD6EiEAXWdiyNkmlOFgAACA1iAEoOtMRAKSOCsAAACgVQgB6DqlA8OoBAAAALQGIQBdZzzskyTNsUMQAABASxAC0HWiQa8kaSXFYDAAAEArEALQdbxul0I+t2LJbKeXAgAA0JcIAehK0YBXsRQhAAAAoBUIAehK0aBHsSTtQAAAAK1ACEBXohIAAADQOoQAdKVokBAAAADQKoQAdKVogHYgAACAViEEoCtRCQAAAGgdQgC60lDAo5VUTtbaTi8FAACg7xAC0JWiAa/yBatEJt/ppQAAAPQdQgC6UunUYFqCAAAAmo8QgK4UDRRDAMPBAAAATUcIQFeKBj2SqAQAAAC0AiEAXWmtEkAIAAAAaDZCALoSMwEAAACtQwhAVxoKOO1AKylmAgAAAJqt7hBgjHEbY542xny5+OvfNsa8aIx5zhjzV8aYkXX3PmiMOWOMeckY855WLBz9ze9x/mims4UOrwQAAKD/NFIJ+KikU+t+/bCk26y1d0h6WdKDkmSMOSbpA5JulfReSX9gjHE3Z7kYFL5iCMjkCQEAAADNVlcIMMbsk/Q+SZ8sXbPWfs1aW+rV+I6kfcWfH5D0OWtt2lp7TtIZSXc3b8kYBF5XMQTkCAEAAADNVm8l4OOSfk1StU9k/5OkrxR/3ivpwrrHLhavbWCM+bAx5kljzJOzs7N1LgODwuUy8roNlQAAAIAW2DQEGGPulzRjrT1R5fFfl5ST9NlG3tha+wlr7XFr7fGJiYlGnooB4XO7qAQAAAC0gKeOe+6R9H5jzA9JCkiKGmP+1Fr7QWPMT0m6X9I7rbW2eP8lSfvXPX9f8RrQEK/HpSyVAAAAgKbbtBJgrX3QWrvPWntIzsDvo8UA8F45LULvt9Ym1j3lS5I+YIzxG2MOSzoq6YkWrB19jkoAAABAa9RTCajmv0jyS3rYGCNJ37HW/ry19qQx5vOSXpDTJvQRa21++0vFoPF5XMwEAAAAtEBDIcBa+5ikx4o/31jjvockPbSdhQFUAgAAAFqDE4PRtXweQgAAAEArEALQtbxuBoMBAABagRCArsVMAAAAQGsQAtC1mAkAAABoDUIAupbX41Imbze/EQAAAA0hBKBrUQkAAABoDUIAupafE4MBAABaghCAruV1GyoBAAAALUAIQNfinAAAAIDWIASga/loBwIAAGgJQgC6lpfBYAAAgJYgBKBrcVgYAABAaxAC0LX8bicEWMtZAQAAAM1ECEDX8rpdslbKFQgBAAAAzUQIQNfyeZw/ngwHAwAANBchAF3L63b+eDIcDAAA0FyEAHStUiWAEAAAANBchAB0rXIIoB0IAACgqQgB6Fq+BtqBsvmCPvLZp/TtV+ZbvSwAAICe5+n0AoBq1gaDN98d6NEXZ/S3378il8vozUfGW700AACAnkYlAF2rkUrAn33vgiTp8dOzKrClKAAAQE2EAHQtb3kmIF/zvmQmr8demtHB8ZAWE1mdvBxrx/IAAAB6FiEAXWutElD7m/1LS0kVrPSTbzooSfrWK3MtXxsAAEAvIwSga9W7O9DlpaQk6Y59I9oZ9eul6ZWWrw0AAKCXEQLQtUqVgOwmMwGlELBnJKAbJyN6ZWa15WsDAADoZYQAdK1GKgEuI+2MBnR0ckhnZlZlLcPBAAAA1RAC0LXqPTH48nJKO6MBed0uHZmMKJ7J68pyqh1LBAAA6EmEAHQtr9tIqq8SsGckKEk6OhmRJJ1pYUvQv/vyC/rayaste30AAIBWIwSga9VdCVhKavdwQJJ0Y4tDQCZX0CcfP6cPf+aEUtnaW5cCAAB0K0IAulbI5xxovZrOVb2nULC6vJzS3mIlYDzsU8Tv0dRCoiVrulQcQpbWDigDAADoNYQAdK2I36OhgEdX1n3wvtZSMqtMrqCdUacSYIzRvtGgLi5Wf852nJ+Pl39+/tJyS94DAACg1QgB6Gp7R4K6tFR9yHduNS1J2jHkL19zQkBrKgEXihWGiSG/FuKZlrwHAABAqxEC0NX2jgTL5wBUUg4BEd+G51yq8ZztmFpIyO9x6TW7hjRPCAAAAD2KEICutmeTD/Rzq84H8YnI+kpASCupnJaT2aavZ2ohoQNjIY2HfVQCAABAzyIEoKvtGQlqOZmtOhw8X6wEjEc2tgNJaklL0Pl5JwSMhWkHAgAAvYsQgK62t/iBvtpw8NxqWm6X0UjQW762bzQkSU0fDrbWamohof1jIY1HfFpN55TOsU0oAADoPYQAdLW9I86uP9VaguZWMhoP++RymfK1tUpAc0PAleWUEpm8jkxGNBZ2ZhCoBgAAgF5ECEBXK50EfLnKDkHz8fSGViBJGgk5VYFYk2cCSgeQHV0XAuZXCQEAAKD3EALQ1aIB5wP9arryB/rZ1cyGnYEk56wAn8el9CYnDTeqFAJunIxonEoAAADoYYQAdDW/x/kjms5W/kA/t5LesDPQ+uc1u1//zOyqRkJejYd9tAMBAICeRghAV/O4XXK7TMVv9a21xXYg33WP+T3ullQCbpyIyBij8bATPDgrAAAA9CJCALpetW/1k9m8UtmCxsLXVwICXpdS2eZWAs7OxnVkIiJJigY9cruMFuLppr4HAABAOxAC0PX8Vfr742nnQ37E7677OVtlrdViIqOJISdwGGM0GvJpId78A8kAAABajRCAruf3uCvOBCQyzgFiIZ+n7udsVSKTV75gNRRYe6/RkFdLCdqBAABA7yEEoOv5vZXbgRIZ51rIV6ESUOU5W7WScgJHdN2hZCMhrxYJAQAAoAcRAtD1qrX2lCsB/kqVgOa2A8VSTtvP+krASMinpQTtQAAAoPcQAtD1qu30U7MS4HEr3cTB4JVyCFirBDjtQIQAAADQe67/ChXoMpV2B3r4henyzjyVQkDA2+xKgFN12DgT4KMdCAAA9CRCALpewOtWct23+leXU/rZP3my/Ouqg8FNDAHlmYB1IWA45FU6V1Ayk1ewQhABAADoVrQDoetdWwmYWkhseLxyO5CrDe1AziFlVAMAAECvIQSg6/m9rg3bfb46H9/wePXdgZpfCbh2i1BJzAUAAICeQwhA17u2tefVuWtDQOV2oGaeGLySysrtMgp61wLHcNCpBHBWAAAA6DWEAHS9a9uB1lcC/B6X3C5z3XOaPRi8ksppKOCRMWvvNRp2KgGLVAIAAECPIQSg61275/+5ubWZgEqtQM5z3MoVrHL55gSBUghYj5kAAADQqwgB6Hp+r7s8E2Ct1fl1lYBKrUCSExwkKdO0EJDVkN+74dpwsDQTQAgAAAC9hRCArldqB7LW6mosVT4kTKpVCXD+aK8fKN6OWIVKQMDrVtDrph0IAAD0HEIAup7f41LBSrmC1YtXViRJxw+OSqoRAooDvKlcc4aDY8nshu1BS4YCHsXTuaa8BwAAQLsQAtD1/B7nA306V9CLV50Q8IbDY5KqtwMFvM2tBKykcooGr3+vkM+teKZ5uxABAAC0AyEAXc9f/kCf14tXY9ozHND+0ZCk2oPBkpq2Q9BKKqtohUpAyOdRMkMlAAAA9BZCALpeub8/V9BLV1f0mt3R8rfyIX/tweB0E9qBrLVaTV8/EyAVKwFpKgEAAKC3EALQ9QLF/v54OqczM6u6eddQeWeekLd2JSDVhHageCavglXlEOD3KNHEQ8kAAADagRCArlf6Vn9qIaFcwerAWKjcmhOsOhjcvErASsrZ/afSYHDI61aCwWAAANBjCAHoeqVv9S8sOIeETQ75FS1WAsL+1m8RupJyPuRXrgS4N2xZCgAA0AsIAeh6pQ/0FxeTkqTJocBaO1DV3YGaNxhcsxLgcyvBYDAAAOgxhAB0vVJrTykETAz5NRry6mfecljvumVn5ec0cTA4VqMSEPZ5qAQAAICeU/lrVKCLlNqBLi457UDjEZ+MMfrY/cc2fU4zBoNL7UDRCiEg6HMrnSsoX7Byu8y23wsAAKAdqASg661vBxoL++R1b/7HtqmVgGT1dqBwsR2JliAAANBLCAHoeqVv9ZcSWU1E/PU9x7t2tsB21RoMLu1OlKQlCAAA9BBCALpe6QO95MwD1CPgad6H85VUVm6XUbDCmQSl3YnihAAAANBDCAHoeuvPApisMwS4ih/am9Gms5JyTgs25vqe/6CXdiAAANB7CAHoetGAV+94zaSkjVWBzYT9Hq2mm1MJiFaYB3Dewwko7BAEAAB6Sd2fqIwxbmPM08aYLxd/PWaMedgYc7r4f0fX3fugMeaMMeYlY8x7WrFwDJZfftdNkqS9I8G6nxP2uxVvwmm+pUpAJSEfIQAAAPSeRioBH5V0at2v/zdJj1hrj0p6pPhrGWOOSfqApFslvVfSHxhjKh/rCtTp9n3DeuRX79XPvu2Gup/j7OHf6hBQbAdqQtgAAABol7pCgDFmn6T3SfrkussPSPp08edPS/pn665/zlqbttaek3RG0t3NWS4G2ZGJSHmnoHpE/B6tNuHDeSyVrbg9qEQlAAAA9KZ6KwEfl/Rrktbvt7jTWnul+PNVSaWjW/dKurDuvovFaxsYYz5sjHnSGPPk7OxsY6sG6hDyuxVvykxAHZUABoMBAEAP2TQEGGPulzRjrT1R7R5rrZVkG3lja+0nrLXHrbXHJyYmGnkqUJew36N4U9qBqg8GUwkAAAC9qPLXmxvdI+n9xpgfkhSQFDXG/KmkaWPMbmvtFWPMbkkzxfsvSdq/7vn7iteAtor4PNseDM7lC4qlchoJVQ4BpbMDOCcAAAD0kk0rAdbaB621+6y1h+QM/D5qrf2gpC9J+lDxtg9J+uviz1+S9AFjjN8Yc1jSUUlPNH3lwCZCfrcS22wHWkpmJUljYV/Fx0vnESRpBwIAAD2knkpANf9B0ueNMT8t6bykH5cka+1JY8znJb0gKSfpI9ZaviZF20WK7UDW2ooHfdVjMZ6RJI2GKocAyTnMjHYgAADQSxoKAdbaxyQ9Vvx5XtI7q9z3kKSHtrk2YFvCfo8KVkpm8+UB3kYtFENAtUqAJPncLmVyhaqPAwAAdBtODEbfCheHdrezQ9BiYvNKgN/rUiZPCAAAAL2DEIC+FfY73/5vZzh4nkoAAADoQ4QA9K1yCNjG0G55JiBceXcgSfJ5CAEAAKC3EALQt8K+UiVg6+1AC/GsIn5PzZOKfR7agQAAQG8hBKBvhf2lmYBtVAISmZpVAMlpB0pTCQAAAD2EEIC+FWlCO9BCPKOxGkPBEu1AAACg9xAC0LdCTRgMdioBtUOAnxAAAAB6DCEAfSvSlJmAOisBzAQAAIAeQghA3yrNBMRS2S2/xmJ880oAW4QCAIBeQwhA3/K4XdoZ9evSYnJLz09l84pn8jXPCJCYCQAAAL2HEIC+dmAspKmFxJaeWzotuK4QQDsQAADoIYQA9LX9YyFd2GIIWCgdFLbZTIDbrXR263MHAAAA7UYIQF87MBbSlVhK6VzjH9IX484sAZUAAADQbwgB6GsHxkKyVluaC1gotwNtcliYx6Vs3qpQsFtaIwAAQLsRAtDXDoyFJEkXthACFutsB/J7nL9GVAMAAECvIASgr+0vhoCtDAcvxDMyRhoO1q4EEAIAAECvIQSgr01E/HIZaSaWavi5i4mMhoNeedy1/5r4SiGAbUIBAECPIASgr7lcRmGfZ0unBs/HM5sOBUvOYWESIQAAAPQOQgD6XsjvVjyda/h5i/GMxjaZB5CoBAAAgN5DCEDfC/s9Ws00HgIW4hmN1lMJYCYAAAD0GEIA+l7E79laJSBRZyWAdiAAANBjPJ1eANBqIZ9biS3MBCwlshoO1d4ZSFqrBKQJAQAANMW3zszp44+cVjTg1a17ovrZt92giJ+Prc3EP030vYjfo8tLje0OVChYpXMFhXzuTe9lJgAAgOZ5dS6un/zUE9oVDWjRl9HXT00rns7pY/cf6/TS+grtQOh7Yb9H8QZnApJZp3IQ9G4eAjgnAACA5nn8zJzyBas//Zk36uFfuVc/8rq9+ux3pzS3mu700voKIQB9L7yFmYBSCKirEuB27qESAADA9j1xbkGTQ34dGncO/Pz5+44omc3rK9+/0uGV9RdCAPpe2OfWaqMhIOOEgEAdlQDagQAAaA5rrZ44t6C7D4/JGCNJOjoZ0a5oQE+8utjh1fUXQgD6XtjvUSpbUL5g637OWiVg87GZtcHgxoePAQDAmouLSV2NpfTGw2Pla8YYveHwmL53bkHW1v/fctRGCEDfK+0m0MhcQKkSEPRt/leESgAAAM3x3XMLkqS7D49vuH73oVFdjaV0cTHZiWX1JUIA+l64FAIaaAlKNNIO5GYwGACAZnji3LxGQl4dnYxsuP76g6OSpGcuLHViWRs8PbWoWCrb6WVsG1uEou+VhnsbCQGpLbQDUQkAAGB7nji3oDccGpPLZTZcPzDmDAlfWe5cJSBfsPpXX3hOf3HiovYMB3R4IqxkJq89I0H9wn1HdOue4Y6tbSuoBKDvldqBVhs4MGwrW4RyWBgAAFs3E0vp1fnEhnmAkojfo5DPrelYZ7YJffbCkj72xe/rL05c1IfefFATQ36tpvMKeN365pk5fehTT+jUlVhH1rZVVALQ90rtQIkalYBXZle1ezhQ/ua/1A5UTwgotwMRAgAA2LKnppxWn9cdGL3uMWOMdkYDmo41dvjndqVzef3eI6f1+994RZL0k286qN944LYN95yZWdWP/uG39IP/+R/1K+++Sb/0zqNtXeNWEQLQ98K+UiWgcgj4womL+tU/f1a/9M6j+pV33yRpXSWgjnMCXC4jr9swEwAAwDY8d3FJHpfRrXuiFR+fHPJrpo2VgHQur/t/73GdnlnVTxzfr1+474gOFs8uWO/GyYge/dX79OlvvaofODJe4ZW6EyEAfS/sL84EVNgdyFqrj33xeUnS7Mrav1hSmfpDgORUA6gEAACwdc9dXNZNO4eqbsqxMxrQsxfbNxj8xLkFnZ5Z1b//kdv1z+8+UPPesbBPv1z8IrFXMBOAvldrJiCVLZS/9Xev+9vQSDuQ5ISFxXhmmysFAGAwWWv13MUlvXZ/9eHanVG/pmOptp0V8MipGQW8Lv3w6/a25f3ajRCAvldri9D1LULrv8lPZvPyeVxyX7M7QTX33Typvzt5VX9x4qLOzKxsc8UAAAyWV+cTiqVyumPfSNV7dkYDSmULiqXq3+1vq6y1evTFGd1zZEdd24X3IkIA+l7Q65bLSKsV/qURrxICUtl83VUASfqpHzikRCav//XPn9VPf/rJ8mFjAABgc88V23xeWyMETEYDkpxdhFrt8TNzmlpI6D237mr5e3UKIQB9z+UyGgp4tZy8/mCPDZWAdYO9iUyufL5APW7bO6yPvP2IfuoHDun8fEKf+ua57S0aAIAB8uyFZQW8Lt20M1L1np1Dfklq+Tah1lp9/OuntWc4oAdet6el79VJDAZjIAwH6wgBG9qBCg1VAiTpX77nNZKkh1+Y1tnZ+BZXCgDA4Hnu4pJu3TMsj7v699O7hp1KwOWl1h4Y9tWTV3Xi/KIe+uHb5Pf0ZyuQRCUAA6JaCCi1A7ldZsNhX8lMbss9gAGvq3ziMAAAqC2XL+j5y8u6Y1/tE3f3jgTldRudnWvdF225fEEP/bdTes2uIf3E8f0te59uQAjAQNisEjAa8l03GNxIO9B6IZ9HiQrbkQIAgOudm4srlS3o9r21Q4DH7dLB8bDOzq62bC3fe3VRFxaS+sV3HK1ZlegH/f27A4qGg17FaoSAsbB3w0xAMpOv+4yAawW97vK2owAAoLZLxfaeA2PXH8R1rRt2hPVKC0PAwy9My+dx6b6bJ1r2Ht2CEICBMByq3Q40Ft5YCUhk8ltvB/K5lcxycBgAAPWYLu72s7O4+08tRyYjmlpIKJdv/n9nrbV6+NRVveXGHeXtxfsZIQADodQOdO0BI6UDxEZDvg0zAanttAN53UrSDgQAQF2uLju7/dQTAm7YEVY2b3VhsfnDwWfn4rqwkNQ7XjPZ9NfuRoQADIThoFe5gi2fBFwST+cU9rnl97iumwlodHegkqCPdiAAAOp1NZbUeNgnn2fzj6U3TDhbiL4y0/yWoG+dmZMkvfXojqa/djciBGAgDAe9knRdS9BqKqew3yPfNSEgsY2ZgIDXrWSGdiAAAOpxdTlVVxVAkg7vCEuSXp1v/g5B3zwzr70jwbpmE/oBIQADoWoIyOQUCRRDQLG/0FqnYrD13YHcbBEKAECdrsbS5TMANjMa8mrI79HUQqKpa8gXrL59dl733DguY0xTX7tbEQIwEKqFgHg6p4jfI5/bXa4EJLN55QtWQwHvlt4r6HUrkcldN38AAACuNx2rvxJgjNGB8ZDOzzc3BDz56oKWk1m97ab+3xWohBCAgVArBIR9G9uBVlLOUO9QYGs7AwR9bhWsNmw5CgAArpfO5bUQz2hXnSFAkg6Oh5peCfi7k1fl87j09psHYyhYIgRgQFQLASvrZwLyBVlrtZJy7tlqJaC0tWiKuQAAAGqaiTk7A+0a9tf9nANjYV1cTChfaE7F3Vqrrz5/VW87OjEQW4OWEAIwEKLFEHDtgWHxTE4Rv7M7kOR8ex/bZiWgNEuQyLJNKAAAtVxYdL7R3ztS/zDuwfGQsnmrK8vONqEzKykVthEInr8U0+XllN57264tv0YvGpy4g4E2VEz214WAdF6RgKccAtK5QrkdKLrVdqBiJSCZYTgYAIBazs46u/zcMBGu+zkHi7v3fO3ktOLpnH7n6y/rLTfu0D037tAH3rBfIyFfQ2t4+IWrchkNzPkAJYQADASXy8jvcSl9TZ/+anqtHUiSMrlC09qBOCsAAIDazs7GFfS6G5oJuHnXkIJet37zyy9Iku4+PKYT5xf1j6fntBjP6MEfuqWhNTx8akbHD41pLNxYeOh1hAAMDL/HpXR2LQTk8gVlcgWFvB753OtDQHPagagEAABQ2yuzqzq8IyyXq/5tOccjfn3319+pFy7HFPF7dGx3VHlr9Uv/39P6sycv6JfffVP5C7nNXFhI6NSVmH69weDQD5gJwMDwe91K59Y+mKeKuwEFfa6KlYDIFoeDSoeMUQkAAKC2s3OrDbUClUQDXr3phnHdtndYLpeR1+3ST775oJYSWX315NW6X+eRU9OSpHcd29nwGnodIQAD49pKQOmb+qDXvRYC8k4lwBgp7GMmAACAVkll87q4mNSRiUhTXu9Nh8c1Hvbp0Rdn6n7Ow6emdeNkpHwS8SAhBGBgBLxupXNrIaB0qm/A676uHSji9zRUmlyPSgAAAJs7P5+QtY0NBdfichm99egO/ePpubp2C0pkcvru2QW985bBGgguIQRgYPg9rvIHf2ktBAR9bvmL396XdgeKbnEoWKISAABAPc7OrkpS0yoBknTvzRNaiGd08nJs03svLSaVK1gd2x1t2vv3EkIABobf49pQCSh9Ux/wXFsJyG55KFhaFwKoBAAAUNXZOWd70Ga24txzZIck6bvn5je998pySpK0ZyTYtPfvJYQADAy/Z+NgcHkmwHf9TMC2QgDtQAAAbOqVmVXtigaaekrvZDSg8bBPL11d2fTe0mFjjWxP2k8IARgYAW+VSoB37cTgdDavlXR2y2cESE7FwRjagQAAqOWVuXjT5gHWu3nXkF6aricEpGSMtJMQAPQ3v8e9YXeg8kxAhd2BtlMJMMYo6HUTAgAAqMJaq7OzW9sedDM37xrSy9Mrym8yHHxlKaUdEX/5M8CgGczfNQaS3+tSan070LrB4Gt3B9pOCJCcYJGgHQgAgOtYa/WXT13SSirX1KHgktfsGlIqW9CFhUTN+67EUtozPJhVAIkQgAFy7TkBqeLPGyoB5cHgrbcDld4rs671CAAAOL5zdkG/+ufPyudx6fjBsaa//s27nN1+XtxkLuDKUlK7CAFA/6s6GLxuJmA+nlE2bzUW8m3vva45kwAAADj+4fSsPC6j7/36u3T7vuGmv/6Nk0514ezcas37ri6ntHt4MHcGkqTmjWMDXa7qYLDPpUzOuTYdc7YLGw1vLwT43C5lcrQDAQBwrcdPz+n1B0Y1HNxe1b2aiN+j8bBPU/PV24GWk1mtpHPaTSUA6H9OJWDjYLAxzgf2UjvQ1eKewWPhbbYDXRM4AACAtBjP6PnLy3rL0R0tfZ8D4yGdrxECnp5alCTdtrf5lYheQQjAwPB7XMoXrLJ558N5MpNX0OuWMaY8GFyuBGyzHcipBBACAABY75kLS7JWeuPh5s8CrHdwLKSpGoPBT5xbkMdl9LoDIy1dRzcjBGBg+L3FswCKH86T2Xz5dF9jjAJely4uOgeHjG23HYjBYAAArnPy8rIk6dieaEvf58B4WJeXk1X/W/zEuQXdvm9YId/gdsYTAjAwAsUP/OniLEAqWyhfk6Tdw0HNxzOSpJHtDgZ7aAcCAOBaL1yJ6eB4aNu78G3m4FhI1koXF6+vBiQzeT17cUl3t7ga0e0IARgY5VOBix/OU9m8gr61ELBv1NkhwO0yim7znAAqAQAAXO+FyzHd2uIqgCQdHA9Jks5XaAn6ztl5ZfNW9xxp7VxCt9s0BBhjAsaYJ4wxzxpjThpjfqN4/U5jzHeMMc8YY540xty97jkPGmPOGGNeMsa8p5W/AaBefk+xElChHUiS9o85/8IYDflkjNnWe/mu2Y4UAIBBt5LK6tX5hI7tbn0IOLTDOYn4lZnrtwl97KUZBb3uga8E1PN1Z1rSO6y1q8YYr6THjTFfkfSbkn7DWvsVY8wPSfotSfcZY45J+oCkWyXtkfR1Y8xN1lo+EaGjSpWAVLEdqDQYXLJ/1AkB290ZqPReVAIAAFjzUvHwrlvaEAJ2RPzaOxLU01NL1z322MuzevOR8Q0twYNo00qAdZRilLf4P1v8X+n/i8OSLhd/fkDS56y1aWvtOUlnJN0toMMqDQYHfOsrAU470AUm+wkAAA6mSURBVHZ3BpKK7UB5QgAAACUvTzsfJ2/aOdSW93v9wdHyVqAl33hxRufnE3rnLZNtWUM3q2smwBjjNsY8I2lG0sPW2u9K+l8k/bYx5oKk/yTpweLteyVdWPf0i8Vr177mh4ttRE/Ozs5u5/cA1CXguXYwOK+AZ+2vQKkS0IwQ4Pe4lM4SAgAAKHl5ekUhn1t7R9pzSu/r9o/o8nKqfAbQciKrj33xeR2djOjH7trfljV0s7qmH4utPHcaY0Yk/ZUx5jZJH5b0y9baLxhjflzSH0l6V71vbK39hKRPSNLx48dtwysHGlRxi9AKg8HbPS1YcioBaSoBAACUnZ5Z0dHJiFyu7c3d1at0BsD//Q+v6MBYSH/73BXNrKT0Zz/35vIhoYOsoS1QrLVLxphvSHqvpA9J+mjxoT+X9Mniz5ckrY9X+4rXgI66djA4dc1g8FjYp6OTkabsWuAvHhZmrd32kDEAAP3g5elV3XvTRNve7/a9w/rB23bp//3mq5KkoNetf/8jd+j1B0bbtoZutmkIMMZMSMoWA0BQ0rsl/Uc5MwD3SnpM0jsknS4+5UuS/qsx5nfkDAYflfRE85cONKbSYPD6oSBjjB7+lXub817F183kC+XwAQDAoFpKZDS7ktbRyUjb3tPjdun/+uBdOj29ouGQVxMRP1/MrVNPJWC3pE8bY9xyZgg+b639sjFmSdJ/NsZ4JKXktAfJWnvSGPN5SS9Iykn6CDsDoRuUDwsrfkN/7WFhzeRzO4EjkyMEAABweqa9Q8HrHe3Ae/aCTUOAtfY5Sa+rcP1xSXdVec5Dkh7a9uqAJlo7LCyv1XROmXyhKduBVnyvdfMH/KsHADDoXp52tgc9urN9lQDUxlQEBkZ5JiBb0HQsLUnaGQ205L3WVwIAABh0p6dXFW7jzkDYHCEAA2P9t/PTMWe7sJaFAA8hAACA/7+9e4+tu6zjOP759nLana5bL9u60Y52C2xjctnGghgumyJyU0HESKKRRAT/8A8NGjNEUSMJERMUY9QYwLh4IYS7ICFcFoyCQAe7w7qVda7d1q5d27Vd19t5/OP8th0mZRf49fmdPu9X8kt/5zlt+t35Zqf99Hl+z++wpvY+nVFTzpr8BCEEIBipwgIVmDQwNBp7CDh2JyIAAELW1N6vBRN4UTCO76S2CAXyWUGBqb66TM37+pUuyf6SXjOtJJbvxUwAAABZ3QPD6uwf8nJRMMbHTACCsrCmXFvb+9RxYEjlpUVKp+LJwamci5ABAAjZu53ZnYHOYCYgUQgBCMqC2eVq6RzQzq6B2JYCSUd3ImImAAAQutbuQUlSXSUXBScJIQBBWTS7XBkn/bu5S7NjDAFHZgLGCAEAgLC19WRDwGnsDJQohAAE5fB6xOHRjGbFdD2AlHNPghFCAAAgbG3dg6pIF6ushEtRk4QQgKA0VKdVVZaSJNVVpmP7PkeWAzETAAAI3O6eQe4PkEBEMgSlqLBAL313hda39mrJ3IrYvk+qMLv7ENcEAABC19YzqPrqMt9l4BjMBCA4FemUViyYqelTimP7HkdvTMbuQACAcDnn1NbNTEASEQKAGKQK2R0IAIADg6MaGB4jBCQQIQCIwdH7BBACAADhau05KEmqZXvQxCEEADHgPgEAAEi79mdDwOlV8W3GgVNDCABiUFRYoAIjBAAAwrajMxsC6qsJAUlDCABiUlJUyIXBAICg7ewa0IypKZWXxrcZB04NIQCISaqogJkAAEDQWroG2B40oQgBQExKigo0OMJMAAAgXC2dB1kKlFCEACAm06cUq3dwxHcZAAB4MTg8pr0HDqmBmYBEIgQAMaksS6n7ICEAABCmnfsHJEkNMwgBSUQIAGJSmS5Wz8Fh32UAAODF9o5+SdJ8QkAiEQKAmFSVpbR/gJkAAECYmvb2qcCkM2ZN9V0K3gchAIhJRTqlnoPDcs75LgUAgAm3tb1PDTPKVFpc6LsUvA9CABCTqnRKoxmnvqFR36UAADDhmtr7tbCm3HcZGAchAIhJRTp7Y5QelgQBAAJzaGRMLV0DWkAISCxCABCTqrKUJKmbi4MBAIHZ1t4v50QISDBCABCTinQ2BOwnBAAAArOxrVeSdHbtNM+VYDyEACAmh2cC2CYUABCaDa09qkgX6/Qq7hacVIQAICaV0TUBbBMKAAjN+tZenVM7XWbmuxSMgxAAxGRaabEKjJkAAEBYBofH1NTep/PqKnyXgg9ACABiUlBgqkin1DVACAAAhOPRN1s1lnFaMpcQkGSEACBGp1WUqq170HcZAABMiHf39esnT23WJWfO0MqFM32Xgw9ACABiVF9dpp1dA77LAABgQjy3uV2jGad7bjhXRYX8mplkdAeIUUN1Wq3dgxoZy/guBQCA2L3c1KGz5kzTnOlTfJeC4yAEADGqry7TaMZpdw9LggAAk1vfoRE1tnRrxQKWAeUDQgAQo4bqMklSS9dBz5UAABCfgaFR3bp6rUYzTld8rMZ3OTgBhAAgRg3V2ZukcF0AAGCyymScbnt4nV7b0aVffvk8LT290ndJOAGEACBGM8tLNKW4UC2dzAQAACan+17cpuc2t+uOaxbrC0vrfJeDE0QIAGJkZqqvTjMTAACYlF5t7tJ9L27TDefX6esXNfguByeBEADErKG6TC2EAADAJJPJON31zBbVVkzRXdedLTPzXRJOAiEAiFn9jLR27R/UWMb5LgUAgI/Mb9Zs1+bdB/S9KxaotLjQdzk4SYQAIGYN1WUaHsuwTSgAYNJY/WqL7n2+SdcvrdV1S2p9l4NTQAgAYlZ/ZIcgLg4GAOS/Zzbs0Z1Pbtbli2t09xfPYRlQniIEADE7eq8ArgsAAOS3zv4h/eDxjTqvbrp++5VlKiliGVC+IgQAMZs9rVSpogLt6CQEAADy27Ob9qp3cER3X3+uigv5NTKf0T0gZgUFpuX1lfrHxj0aHs0cGd/be0iPvdmq5n39HqsDAODEvbx1n+oqp+isOeW+S8GHRAgAJsAtl8zXnt5DemRtq5xzevBfO7TiF2t028PrdcvqxveEAwAAkmh4NKNXmzu1YsFMrgOYBIp8FwCEYOXCmVp2eoV+9OQmPfTGf7WhtVeXLZqlTy6apR8+sUlf+v0rmp5O+S4TAIBxdfYNaWB4TCsXzvJdCj4ChABgApiZVt/8cf3s71u0tb1Pq65apG9eOl9mpt09g3qluUsHBkd8lwkAwLimlhbpx59brE+fRQiYDMw5/zcwWr58uWtsbPRdBgAAAJDXzGytc2758T6PawIAAACAwBACAAAAgMAQAgAAAIDAEAIAAACAwBACAAAAgMAQAgAAAIDAEAIAAACAwBACAAAAgMAQAgAAAIDAEAIAAACAwBACAAAAgMAQAgAAAIDAEAIAAACAwBACAAAAgMAQAgAAAIDAEAIAAACAwBACAAAAgMAQAgAAAIDAmHPOdw0ys32SdnouY4akTs814L3oSbLQj2ShH8lDT5KFfiQPPZkY9c65mcf7pESEgCQws0bn3HLfdeAoepIs9CNZ6Efy0JNkoR/JQ0+SheVAAAAAQGAIAQAAAEBgCAFH/cF3Afg/9CRZ6Eey0I/koSfJQj+Sh54kCNcEAAAAAIFhJgAAAAAIDCEAAAAACAwhQJKZXWlmW81su5mt8l3PZGVmD5pZh5ltyhmrMrPnzWxb9LEy57nbo55sNbMrcsbPN7ON0XO/NjOb6H/LZGBmc81sjZltMbPNZvbtaJyeeGBmpWb2upmtj/rx02icfnhkZoVm9paZPR09ph8emVlL9FquM7PGaIyeeGRmFWb2iJm9Y2Zvm9kn6EmecM4FfUgqlNQsab6klKT1khb7rmsyHpIulbRM0qacsXskrYrOV0n6eXS+OOpFiaR5UY8Ko+del3ShJJP0rKSrfP/b8vGQNEfSsui8XFJT9LrTEz/9MElTo/NiSa9Fryn98NuX2yT9VdLT0WP64bcfLZJmHDNGT/z25E+SvhGdpyRV0JP8OJgJkC6QtN05965zbljSQ5Ku9VzTpOSc+6ek/ccMX6vsG4iij9fljD/knBtyzu2QtF3SBWY2R9I059x/XPZdY3XO1+AkOOf2OOfejM77JL0tqVb0xAuX1R89LI4OJ/rhjZnVSbpG0v05w/QjeeiJJ2Y2Xdk/8D0gSc65Yedcj+hJXiAEZH/p2ZXzuDUaw8Socc7tic73SqqJzsfrS210fuw4PgQza5C0VNm/PtMTT6KlJ+skdUh63jlHP/z6laTvS8rkjNEPv5ykF8xsrZndGo3RE3/mSdon6Y/Rsrn7zaxM9CQvEAKQGFH6Z8/aCWZmUyU9Kuk7zrkDuc/Rk4nlnBtzzi2RVKfsX8fOPuZ5+jFBzOyzkjqcc2vH+xz64cXF0f+RqyR9y8wuzX2Snky4ImWX+f7OObdU0oCyy3+OoCfJRQiQ2iTNzXlcF41hYrRH04CKPnZE4+P1pS06P3Ycp8DMipUNAH9xzj0WDdMTz6Lp9DWSrhT98OUiSZ83sxZll4l+ysz+LPrhlXOuLfrYIelxZZf00hN/WiW1RrOWkvSIsqGAnuQBQoD0hqQzzWyemaUk3SjpKc81heQpSTdF5zdJejJn/EYzKzGzeZLOlPR6NL14wMwujHYO+FrO1+AkRK/fA5Leds7dm/MUPfHAzGaaWUV0PkXS5ZLeEf3wwjl3u3OuzjnXoOzPhZecc18V/fDGzMrMrPzwuaTPSNokeuKNc26vpF1mtjAaukzSFtGT/OD7yuQkHJKuVnZnlGZJd/iuZ7Iekv4maY+kEWX/enCzpGpJL0raJukFSVU5n39H1JOtytklQNJyZd/4myX9RtGdrzlOuh8XKztFu0HSuui4mp5468e5kt6K+rFJ0p3ROP3w35uVOro7EP3w14f5yu4ss17S5sM/r+mJ974skdQYvXc9IamSnuTHYdELDwAAACAQLAcCAAAAAkMIAAAAAAJDCAAAAAACQwgAAAAAAkMIAAAAAAJDCAAAAAACQwgAAAAAAvM//XftchNjuKgAAAAASUVORK5CYII=\n", 105 | "text/plain": [ 106 | "" 107 | ] 108 | }, 109 | "metadata": {}, 110 | "output_type": "display_data" 111 | } 112 | ], 113 | "source": [ 114 | "profile = reduceImageProfile(image, line, reducer=ee.Reducer.max(), scale=10)\n", 115 | "\n", 116 | "# fetch resulting features (line segments) to the client\n", 117 | "features = profile.getInfo()['features']\n", 118 | "\n", 119 | "# extract distance and elevation properties from the resulting feature collection\n", 120 | "x = [f['properties'].get('distance') for f in features]\n", 121 | "y = [f['properties'].get('elevation') for f in features]\n", 122 | "\n", 123 | "# plot\n", 124 | "fig, ax = plt.subplots(figsize=(13, 8))\n", 125 | "ax.plot(x, y)" 126 | ] 127 | } 128 | ], 129 | "metadata": { 130 | "anaconda-cloud": {}, 131 | "kernelspec": { 132 | "display_name": "Python [default]", 133 | "language": "python", 134 | "name": "python3" 135 | }, 136 | "language_info": { 137 | "codemirror_mode": { 138 | "name": "ipython", 139 | "version": 3 140 | }, 141 | "file_extension": ".py", 142 | "mimetype": "text/x-python", 143 | "name": "python", 144 | "nbconvert_exporter": "python", 145 | "pygments_lexer": "ipython3", 146 | "version": "3.5.2" 147 | } 148 | }, 149 | "nbformat": 4, 150 | "nbformat_minor": 2 151 | } 152 | -------------------------------------------------------------------------------- /examples/getting-started/display-interactive-map.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Overview\n", 8 | "\n", 9 | "This notebook demonstrates how to display Earth Engine generated tiles on an interactive map." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "# Import Python modules" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "import ee # the Earth Engine Python API library\n", 26 | "import ipyleaflet # an interactive mapping \"widget\" for the notebook" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "# Initialize Earth Engine\n", 34 | "\n", 35 | "The following command initializes the Earth Engine Python API. If the cell output displays an error about needing to authenticate, open up a JupyterLab terminal tab and run the command: `earthengine authenticate`" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "ee.Initialize()" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "# Display a Dynamic Map" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "To display an Earth Engine generated tiles on the interactive map, we will use ipyleaflet's TileLayer object. First we start by defining a function that can generate a tile layer URL from an Earth Engine image object." 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "def GetTileLayerUrl(ee_image_object):\n", 68 | " map_id = ee.Image(ee_image_object).getMapId()\n", 69 | " tile_url_template = \"https://earthengine.googleapis.com/map/{mapid}/{{z}}/{{x}}/{{y}}?token={token}\"\n", 70 | " return tile_url_template.format(**map_id)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "Next we define a collection of imagery that we want to display. The following creates a collection of imagery from the Sentinel-2 satellite, filtered to a single day." 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "s2 = ee.ImageCollection('COPERNICUS/S2').filterDate('2018-01-01', '2018-01-02')" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "Now we can create a map, add the Sentinel-2 tiles to it, and display it in the notebook." 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 5, 99 | "metadata": {}, 100 | "outputs": [ 101 | { 102 | "data": { 103 | "application/vnd.jupyter.widget-view+json": { 104 | "model_id": "28a5b4441bee49bd80d26f10392d6fff", 105 | "version_major": 2, 106 | "version_minor": 0 107 | }, 108 | "text/html": [ 109 | "

Failed to display Jupyter Widget of type Map.

\n", 110 | "

\n", 111 | " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", 112 | " that the widgets JavaScript is still loading. If this message persists, it\n", 113 | " likely means that the widgets JavaScript library is either not installed or\n", 114 | " not enabled. See the Jupyter\n", 115 | " Widgets Documentation for setup instructions.\n", 116 | "

\n", 117 | "

\n", 118 | " If you're reading this message in another frontend (for example, a static\n", 119 | " rendering on GitHub or NBViewer),\n", 120 | " it may mean that your frontend doesn't currently support widgets.\n", 121 | "

\n" 122 | ], 123 | "text/plain": [ 124 | "Map(basemap={'url': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'max_zoom': 19, 'attribution': 'Map data (c) OpenStreetMap contributors'}, center=[48.2082, 16.3779], layers=(TileLayer(base=True, max_zoom=19, min_zoom=1, options=['attribution', 'detect_retina', 'max_zoom', 'min_zoom', 'tile_size']), TileLayer(options=['attribution', 'detect_retina', 'max_zoom', 'min_zoom', 'tile_size'], url='https://earthengine.googleapis.com/map/327cfca2252a67a827e408d38fe16610/{z}/{x}/{y}?token=649b2a423ea02d3adb95ace3ddd4513a')), layout=Layout(height='400px'), options=['attribution_control', 'basemap', 'bounce_at_zoom_limits', 'box_zoom', 'center', 'close_popup_on_click', 'double_click_zoom', 'dragging', 'inertia', 'inertia_deceleration', 'inertia_max_speed', 'keyboard', 'keyboard_pan_offset', 'keyboard_zoom_offset', 'max_zoom', 'min_zoom', 'scroll_wheel_zoom', 'tap', 'tap_tolerance', 'touch_zoom', 'world_copy_jump', 'zoom', 'zoom_animation_threshold', 'zoom_control', 'zoom_start'], zoom=4)" 125 | ] 126 | }, 127 | "metadata": {}, 128 | "output_type": "display_data" 129 | } 130 | ], 131 | "source": [ 132 | "map1 = ipyleaflet.Map(\n", 133 | " center=(48.2082, 16.3779), zoom=4,\n", 134 | " layout={'height':'400px'}\n", 135 | ")\n", 136 | "map1.add_layer(\n", 137 | " ipyleaflet.TileLayer(url=GetTileLayerUrl(\n", 138 | " s2.mosaic().visualize(min=0, max=3000, gamma=1.5, bands= ['B4', 'B3', 'B2'])\n", 139 | " )\n", 140 | "))\n", 141 | "map1" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [] 150 | } 151 | ], 152 | "metadata": { 153 | "kernelspec": { 154 | "display_name": "Python 3", 155 | "language": "python", 156 | "name": "python3" 157 | }, 158 | "language_info": { 159 | "codemirror_mode": { 160 | "name": "ipython", 161 | "version": 3 162 | }, 163 | "file_extension": ".py", 164 | "mimetype": "text/x-python", 165 | "name": "python", 166 | "nbconvert_exporter": "python", 167 | "pygments_lexer": "ipython3", 168 | "version": "3.6.3" 169 | } 170 | }, 171 | "nbformat": 4, 172 | "nbformat_minor": 2 173 | } 174 | -------------------------------------------------------------------------------- /examples/getting-started/display-static-map.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Import Python modules" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import ee\n", 17 | "from IPython.display import Image" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "# Initialize Earth Engine" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 2, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "ee.Initialize()" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "If the preceding command fails, you likely need to authentiate your server to access Earth Engine by running the command\n", 41 | "\n", 42 | "`earthengine authenticate`\n", 43 | "\n", 44 | "at a command line prompt." 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "# Display a Static Map" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 5, 57 | "metadata": {}, 58 | "outputs": [ 59 | { 60 | "data": { 61 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgAAAAClCAQAAACAP40FAACAAElEQVR42ux9B5xU1fX/nbJ1Zvvu7GzvvbC7LL333nuVpgLSiwoqKoIiKqBB7GiMvSRq1FiIMYY0Y0xiiJqiyS9RY4wxxhjN3yj3/z3fe9/sLLvAIsiC8t5ndmZn3rx5795zvvf0o1Tbt9uVNnu0DuoSXajjtA+v4/GcoPN1Nv5TOlN30/U6Sru0Bw8cvVetd5nvNSodgWOy9XA9SM/WS/RivUgv1dPwPEOPxat1ep4eqkfoPrq/HoUjanDWCl2ta3WVrsRzg+6i63QO9lp+lqnTdSr2oM7CWfN0Ea6qRJfhIa+KcYWFODYTexYeAZ2EK42WK6lu0/1+4txvlI7Vftxnok7RydhT8DrKfKbUbHmWa/FodZ86sm2NfDdSu15Sx2d7y7kju9/V7NMdCvcQr6fr0/R4PUznYrx8uOcEzq/ceZT2YrfzesDusu+6cVQ0j5M9EuOWhHPE4bzxeO3nOCZYmknAORP4uexJ3BP5SOAYm99OxujWYMbjMQsxOHskH7J7Q3sE/4/iJ9F8juYehU/kU/k/lrPoxxnN1cThtbyXgLkrBF1VgtYqdDnopkQXYM/UGaCbXOw5eOTj3Qpdik/zeUQxjsjn+5Wg9+56gB6MT4tAhfn4lnxaBoqV6xbqlTOX8byFOCIHRwR0Gs6fweO7g6676166n+6L66jAWaNxXBaOD2AcYjgusZiLdFxrNr4Th3tya3WbnbdMM/71+LUc0rfbPD4Kzez+Y0M+56nn1E/lx3x2GCM4CRF4lYUBjSQBxO33PqfC92vVLPuq3HnP978svREk1ls36gX6PD1Fn64n6GV6rV6jFwIIRun5eiUAoAc+r8BgluvOYP4yDHUhBqcAQzoSw90btyvDmMK/qfgbJKsLGORykopwbC7+l4EO4pgQAJymemNvIwC4MQU+ko4hU4GcZJxHhhln2SyDX40rLdDeZzAZR7JNtSNy63Fg/gpc67tN7Kr+i9/d0OyIpeo517+9YP4RIMcKS2ZCeMJEMgZeCwA8xxv4vj2bl8wXQ4AwzBZp2V+YOJ4LhZzHR4b2kfUSCAMJHNMEPpxdxljm1Bzhw6t8jG8pvmUAIIYMLr8SYa/I/BdlWV6eY+wrAwkRpFT5Zqzd/bwaP6FAnjPJ4LKolWIes0Ez6VxWMi0E5OGTDmCxclChWVzKycqy6AzXU/VMPQv03BVUUIb3i/hXvtEJTFmFY8sJBHV8PxdnDoB2BRQK8btlOKovKLw79t44YxBX5PoX5gKU4XnO+1wM/kYIlXziwsgEdPYrvuf82NU6zFkpZnW8LCIBLJoVuBsBYPUaqeqp0Mw++3kIJqDOx155wLuJalNo3y6T78FQBzBoHk43QODiNkEJvh+NwZU1NYj1f6NegWE8HQCwGo9LsZ+H/XrAwBggYy8MYx0ki14gBFnTBWdlkvJ1RwxtAOydi2GWvZoSgMgLRZb9BadzCAJB7CkgKlkVSMTn2/1g28UOgcfizmTlTyPzB+yZkkE4MVwj03EdXTHduTrmUZwvoNp/y8B1DAr7v6N6SVEuSyeBAbz+hSPGtfjeYrVVWMUTtrLLGpnKEfDZ97nW78DR2oHICLJaDJhRmE9WYw/fS+Jaa2SIOMtywsYOKPjD/sZZKEi0EJBov5uMuRMGFdiNp8wZvro3rf7yy00sbl6bv9EWOswxDuM7e0LoOQEzLNQivxfk3yyu/8WUP6v4qCKDy/JSg3W7N6TVHvg7CIvWdCxdA/HfeKzkQ/mqP1i6K/4KPIzUo3HMYhw1Bt8ZjE87EBRKcdZiHNcHsNsPVK7uIG+d0cqcrrd818H+30Gd7/q5wF88aLIf7onSpMYRPY4FCdVycicfEiLIHAmYBIXpKcJQReoj+AV8V8SZFDD2Oj0R6/9CfbHeqjfh78X6AqgHV+odgIOpGLr+GNDBePTFoBcD6TrgUY/vdcerDExJhWV/wdtaPIvckEfRLc+yfzrlhGSQlp+kEybGHuIKzR5pSTKd0kUOVY9kvJdGGMjAO3WUUSqMfFF7AgAA1C21rRljU0iPBsGl47qDRoW5q5Vv+ptY362dGU7B/KbhlbsZAIia5+YiEEUW83G9jSGTRpHNUwm5iWEKQKxde83xcVa28oWe/SGFI4G0kYKRD3LURd1LsgBi1vcIy/zhe5T9hea7AwWR9r94CwFG3kgm3KTwOchZzsLvyW+KuF9kRf4q0FoNKasMK/0oyKwjQI8DwPzj9GQ8TwAArMcCNhcq1Jmg2uGgaYGBMXg9EY/5WOiG4f++2Cfg035g+nrKAY34dh8scJnCSf3bPMdzRKUWNS0Z9DfCwqhbHysSilOD1c5WAWAAhAvsrme9mJIE+clFaqxMhvtmfKft22D3s34MdQzO0QuDMhdDtEqfgyHcpC/UlwMCVutLIBvMBQD0xhGD9Fg81wONu4LJZc1twOtSsHgFxawyPFcSV2vwXz7ez6VlIpOTGiThJ1s1QGQAL1cQXD3vRk1rcX2PN7GCWf/FmpBNwsizgly6XZ2qMAWiRSbibtSP1DfbHQDiMRNlYf/nQAwkq+bYlSzi7ziiNajy4P3B6p6QDQfPPrs+Rss75+PT3+OxTj0VQY3bjSPMmh7DldnHI+MoLaXR8hIfJnIbNo+xD19o1W6SEfw8l+xJBB6Rt3KoWQdoGXAYOppgY1jbAI55jgwxvS8MWIxcEE04M2pIPO0PSZTpMjC/wvJpnFN5ZFPMl72aYn8F2V/E+EKw6ww9D2w+A6x/JtXWs/D/mViuNuhpkGUXgfF7QwqYCDV2vB4CCJipz+AxC/BqDKFBwKAXWL8eVDwYC1yujvwlRz6Zs1Cp5h9Wxtvn4TgXY1Hsi9ER1STyGAKAbEtaBYCZQhZJGJZ0rv3Y61Q8ieXsIzz/PYoCo5g5yjEMqzhgMzFUK/RFGMzpGLB1gIURuifwUUwlvbDSdgDrd8RzFwyeGAgb8becJpZSiv81YMQyalcCAkb/l0cqV+0ECu6yfvgsKUaYdW19SxuAswaKFcCI/tkElUIMejFeBWgsKsDQl1vzkc+MyPvqxNvuMdp6kGtprOjwh9q2eDguLsJfFFnHKgbD8emLeKxQVuuOpPoXY1d0P0V5v11ZjYyUGBLsE8nAhhUNXMRY0d1nmd7HldlnzXViQ8jmmiyzacCkCQAc5SHG/hcTeuXsTRDQBAJJ1riYZAFKQL0AV5kF+smx1GLeK6F4Xgp6kkWlG3T1nlipa0GhS0Gr68HQfUGjF+gpoNDeoN/zILluxuK1liJ/XyxYswEO0/Qk7BPwmKiX4dhxWNCEsscAAoaBjgdAmsiQkX4mbPy7qy2Hmc9CmRdh/yH4fhZ+LZkjGaG/COKJVp1ld3cWE0MqCQOs8T/1PC5zNf4+r773uc/9mPpVDMhESKgcAtJgIKsg5xgw/mzg5AQM2TK8Nxm42QfD1QsT0QfiU38LAZ0AB91oLqwiABSHWD+HmJ5JCSBg7ffJFC2NFbpJWzQkIwTvtkQP6OuM+7Pkn2xX+gLqf0XUCavseiBqRw3tvAJGxRidWJrA8N1rOGrtvTXwKrZG0hgm9vkUCrxpoq492er1JeLdrxsVwBWmKmHGv27oQHbXNjnCa7V/X0jTjw+ZS5P5S2lWwE60Jj1nbY6zUkW8XfNjOW4xFM8d7d/H88pcigAuwJViNXaRNvwh5aG5oB++x4YZ+4wlJ4k0kEk5sg8Wk2JSSynopxN2sdyLOteN8qQsLKL9d6CdvxfW9eGgu97Q5Gsgj56PfbM+G4vVKlDoJKz4I8Hc08H2fQEUfSnVDsCjK/ZOoI16nrk/GHYCaHsWQaMey0gixpEq6Qsc2XjMQKcWtrdWACASo1EP5s/EGToAVNLkHO/xsxXq+YgP1X95vsxjQUSlxhnmsyui3d85RiRabAEFODYSN9Rdn07EHIehGoYhH4L/1mCgF2DQhuOdAXhMAgR0xsB2hizQCZPXQGFKVuE6WgBqyfxZdOUEqT0acjTrkeNwcsjPWVGMwajJPuCicCvCbDrXBMf8U0qmF/ZvwO9X0v5QSRAownFmXUmkyU3pdgeA98y9GP072jrs4nClfvznae36hjsM72rF2eex3h63tfOLNOXneppABkuwjr0ky2wGbpLs/3FW6PfZFT+B7B5H1SkqZApM5fgl2dkpA9D3BMTn0vRqfscxJIZDQGwrAGAgwG/nOhHUIG60VIr4olJ2w1waV/NgUNwc0NhU/B1G03M9aakKM9wBdNYP1zAITNsfxw3ANc3Ff+dBYV2DZWomvjECtDkKryYDCAZgH4hzDAb798GrnrQPFVB6LAKldMOR3XCmDhiTOMJyRNMYiw3gU9ePDg8AXtBZDyyPlTQhFoDavQ4AyPaCnb/1R0M89WqN7NGXR7zkudJ1pWq+X3SsAEDWEAGAeAx5PzD0XAzjRAzgCBr+xD86T1+qr9aX6OV4NQ03PZBKQTdKAZ3B/I2cLhHUOhLDxSMqjC/6XIAAkGJ10jT7bB7JIQ21SWiMDiN8F22sQryii+ZhmIu5Noj9tgN+R6CnhitFBS0QlVynMknqfjOta9TE9gUAF/Vio/9GUaeX+zLe5Ai5vhR7ZD8z2+pmBwA8ViZyVAGvjYfwkGidddwR1h3TXUKYyO9IXc4rxxTot45AAwup/F6UFeoTLGyk8wwJGOVegPpKqgLJIViItZJAXOj/2GaKQBP7x1toSramzCzMosxRA1bNGTh3Kee1ApQzDOv3FfpaPFaAxvrjiFpalSpxDf3B2LKyD8TCVAGaWwLR/2Ks/IsBCKNAq7LyTwYYTMDfYTi6F5izmu4/Yzxs4N9yygMdQUUBXE8hjq/l1RiHq9ydul6tcX0W8afDuqkL3bifwfjtrvidRJkx4cmNoc9XWC4dELICrfk8NgC6diK16+YvkESLPbiVCFrbhdF6QQKYpc/CQJ4GZhfMnapX63P1lfo2fQ2mZh7W/xG0m8q60JVyQCcaBbvT71rJgA0x1lVQ+A9QdEwOOfDS+TfDfpZmV5W4kBwQFSbnGD3LOCszaRMuxSTKlHbE3oDf60IgqKQNooxe5BR6DSrxC0KYLh3mj20nAIi2TrkojrKs4hLwk2Jt+CFxc0fz1d7D3auN8uCmMdCst5GUi+KtDm4YMMl68419vcnGnhhi8lTKAn7LskYcT+GspNPNGB0yCcbxU2HSBIxiA4C+mv7zdGvHkbU81oJMqoV3kTp81qoQDgB+a15MsIFHafyGBNlUQQQfg4Ujh5BQBjqbTLa+Ve/W1+vLQXGr8XkNAV4UBtHqh+rxmON6HDsOq/8CLFUzQI3TsfJPoGY/lau/sHgtXdKiNBbQaR2gHaOQFCSGvzrQ7ii9CK8zeDcxVEojLDxjXtpgA4jHyHQBH6Qbn86ht76HO+Ji9Ujz3fWI5yUhAXWaGq3qvkAS9alrvJgas8r4MVhTMLSn6YV6rT4TQzwRw36O3q5vAgTsBgjsxtRMAN6OZjBQD7C9DEMjGLEBQ1/Flbic2ptEAgS4GxXACRXKDEUHZtI3YEjTQEC08aWGpIAIXJGAh8QaFGJKy7km1OMXjQTSif/VUMczYl4RHqX0P2Tje+0PAIo6pmHeOK7sYtHwWXcoGPsZdUc4ALhIgAYyHG+J8etHhkJuHAu+47aLD8X3xVnB3B9iuiSrfJl13rHyJ9BKYGZFWDjKnj/auukSyKhioqvDGBdbv0uaVeGE2QVYgmTeQkZ7pDNSIeoAAIiltSAxJO8FCP6FPKv46zuBmfuCFedByVwI3XwBdfoL9YP6Tn2D3gb2MhaeevqhBhH8x0NNOAP7DEDGNLD9PDyLfWAoztibtCgRAt0pmcpiZOgtQAVELFL5OFsPqruL8NupDKRL5SIYRSWNQL3lsFxzdQS+V6cj/qFGu0eDRw8DAAAVh7eVGt/0+n31fsT7rve9/wOr/9yVpFru7i+cSCPxK3eB+N7E8+kK+DkB4v4m6Fgr9FIM9AQg7EIIW0sAATv1LfpxvQvC13Sg8FDs/THsvQgDnTEc9VQAaqkQmPCNdAsCRqzMZPClMeeZYM4sGyfoGJdM5JjjBPOCqBwbgMR91VHa6GJF/x6M/hIppAt+rwGTLXaIPFqsZcLTTgAAiCDTca2vUA0ehuemg9D8ZBHe536hAvVfs/Z4SYYJdHtKhGeMDbuJsXYSXyiOr8lh5zB+XMjXb+AmwQb3JFkjrPETOGqDMRRGhSL1IvgrxjPgCx1ThLnKIABnU6kTmU0kjnR6NLIsmEvIVwY9+EGravisRyHByh/pmBVRJ/pQ/56uN+ub9e36RiwtK8D2M8DKAgNb9VWgsZv0Y/pJ/V39LVDcYixGEzDrDaCxkaS3QXTlTQJVTscnA/UQvNOb6sFg2q16MJh9GOhzMD7pyusPWPiS6yigObsbjpgKKhKnaRZgJcgoy0hGa0QdHgCUmuMFpaVr9Vab6MAbxtFKne1yJA31Uth+VzsS6iX4/WdVrTpXYYK7YTpOhyB2i74DYr+4AldDX5oPZL4B7+0APl8IYJiEaRA7az/ibVd6BBpoBajHKzHhVFvrsWMHCNCWX0BbfiFf5TOwJ4Ohp/Fc1Uwsm5ear4S4JFpXUQ5FuBJGJYrloYa+4Y74rY6UCEQOyGbwUQ6m2ksAYeBs+wLAD8LmN6CKjVPT8Z+b+2xa+T1k/yDus5xBT2m0uyfbFTTV6u5Gow/QOuKYUw0kmLh/f8ieEmcVAccT4NjkfSG7QWJIsjDM76V9wYQRGejIYARAgMwepBUnhVeRSjgQmS6Ho55LA1sFQ3mDNpLQYX6x39SBQVdBplyBxURE/Nv1o3oPaOo0sPiVkCqXUdpcBmlzGz5/EEBwP57vBhhci9fr9BpIpn1BaeMgfU4k80/H8yTAxhBKor0hGYzBfwNAjyNwlORTDOGyVEL5JN0GVAVxJV1xlTWgcVk2MnE3ufibS9eyek295NufdDgAqACnXBClk//iekl993NQxdwQTZxQW7YTdpNG18xCTMxVeiNkgdlE6NFg+3P01ZiYe/V9ejnwcxjtrOJy6UlnYE9G5BnrfD3Ys5r+ARP9lkanVBaZPp+x2k64sHEXJtHxFMuVMZLhJH6K/2kUNI3/38QZ1NErXG0dRSVWPw3Y6DUh+0irRWe3vwTQwuMSS6bzkOFdVs2JJNT5rMcjheJ2If3gZYTTEsbGVdPNmUh5SFgxwYbRpFizXbI1A8Zb9ncSb8Jj/f3W/Rcb8vwbJSMiZHI0JkazessZs+lbCZL9A9YKYCz7mQQFE7cnEkA5Z7yCgWGFlOySKHsE6UisBWNeps/HYwckyNux/j+kn4c0+RjemQ9GnqHP0hv0A6Cs7VhkHtHPQgnYiXe2QhJdCXV0LBcbYXNZ++cBNs6g0iCLUHcGqo8Aw8vaLuu/mOckwr+W8SEVTK2KoxEykxJqIz4dBhWgH14VYTSKGGdQQS9A8NPswwHAG8rYl+apL9WWqHbKnoSBkDDJAgzomcDeszFQC2iSORuTcQnYf5f+BiZmLu2togIMAroPZQS2GAZFQO9MHb2B9vlCamAy+OmWlQsIAMalF2Qwr8gJjivLRKAHQsqDEwBUYjMNamjblfiwUpChx2rNbstSrrtdchd4lWtyBF9RS7BnngDjO1dd7HlZ7TTX56z7Xit0J3GVLaXfPZ0BOJn8X5SdIora2Xgl+ng6P0vj2CQTANIZbJ0eMqo2yQBG53dMg3Eh0TzWGui8ZHlP0+hZC4RJJEqk9aWATG5SvhJtMLCfWXz5VoYzDrYq+uwbaJ/pTENcDudW5DKR+nqBYc/RV0CKfFq/rJ/TT+jf6Iexb+fKLRCwCBLnk2D9PXi+C8ftxJKzGqCxARAwCtQ1ABQ5A7LpYn0B3pNY1Wl8vzfGpRvX/m5gaOMwHA9KrON4lnAEE2h4TeY4ii9JzIAdeYUSaVJBt3YRASD70zTtfwo0k3ewiXQBANyvYBa7qS/lNhn7fC8ms4ikkY7hvxqC2UiaXZZjmlZiYrZCOVikZ2GfQi+sRFZJUoYEVookICRQw2TNahoF02iEyWEgbx4lDBO/J4JuNgXeApqasuglCIbSQTKZC2YMgOV4Nx7Hd8GZM6m1plCzzNTe9+WqPXLlicqn7vNL3hZ+y9gVIiTO6z7laudxHaWWqT+q+1z3ee4TVcCI835rOhPmTLNidRLuuZQB1pIAK7Hqwk55FKdzQaiDQd49KSWIPp1nzakZhAHDpolWEjCivT8s3sJvvQd+2hbcB4QbNeUhRDPRKonXVEBbeQINlyZwWFZ2sch0YDh4GR1u9RTEB2OtnkDRfAQlxI7MtOvJtXkcmPkW/XX9ff2G/pv+JbT8J/WtYPbLIM4v1usBDg+A8e/R34QE8A0sM9tBZxfqiyH+L8Udjwf9SaraFhy3nmG9s0F7ktwuy1AfXk1nBqoNx2+PwrgV0h3txI8WEFrjCJ/p1ufhZayJ2BHEGAmN/lnPfVn7k35Lm9jwVmdxmbrP/ZHrbydAkNkXuqUq5hlKdHM8pIBLMKl9wOSjMbgSgb0awtdlmJZZmOpxGO7JZPzenIoeRFMTH1hGNi8lAAQt8+dRCShmgnEx133ZC3BUoV1RssN8BVk29Ffi/2oAA2IyLMYR4ls36UYCCu63m0kyrJAgZisTCBNjSNzV7qNaLIqJn2FKEXZtTqTSE2uF6jywfRbjyzvRhlLJ6EoZwwaqSSIfCSCavPRY3F0lGK6KAVBJNvzXhPYk2fXeBP4YfTzBpgHF2rQhJ6iotfoC0bw+c8ZsWnDiQhl9fsoGEoVZhj2fYbsVFMP7gQ6G4dGHbNkX1DKcDNmDXiEJ+BmMhWQT2P7XWP9f1/+H9X4tqWk5WPtKQMNeqAV7AA1P4Pl+qKAbcLSw+zxQ20ow/2046kp8Yx4kgfmgu0G0QYkKKmpnN7waStfgINBTlk0XCzJWv5TOYllYYmyStalskEO7Qn+McizvPV57fiS2sNYBwHUXR+h19SXf3CojAkM6k0GrKzGgfRmL3RMDNRaTtQTvXA4IEPvtRKLzeOCoWGMlcag3cwca6aSrYjGGUkYA5FoDoAj/YjDKJ7k2uatySVDGP5BHO76RDIq5/pcRHEqZ+htHc46xS/uEvT9Tb4f2vykbAptiPeWRJo6+/QHAq1a6Qlp3JN2DPht+k4q7yccd14OZe2LsOtKmPQh/hzKVdRTeTePxKRYIjIifpadCGeuJbyeENP5Ya2aMtgY+J0PA5AGayAKT2d9acRGzx1hjYSrtDWJIjLW5ByZgKJUsbUK+C5iOJVb4foCuHozS6MpnUQi6cqXuzVCcEltYZhgWkWvA7H/WvwebrwEzL8VKfwXW/cf0HyEd/AHw8H1IAlvB/OdAOpiDI5ZBBd2EpWiz3giKPB2UN4WGv2FM/DVRqT1xBbPx2RjQa6YNak6l+pJNw3MtXvtDoy+WpgxaJySULUKCefYqCev5RF2mMlRUKzM42/UxRqdBpamvwMYknEiQ1AIMdAcMXz2GeSDw9QLGCGyDkLZSr8CErGNEluRdDcJ0DMVk92UUtpgEG5g8XEqxKw9sXGT3PLv2O/FrsqcTGMqYBFpIFcDol/m0MZdRF5ZCDxKgYvLTcmgHaKU2zu+4f+xhaHGkCdVwnQBjOtFcmcvW7jERfWLzKKGJL0jTlaxjc/WN2K+GJnwl1r21+L+MAmw6QcBY6lM4Pg000TbwU2PeayrDYRJ24xk+5CX0eFg/INJm9auD7t5QHR8D0SZyIcoW9hAZwFSFyKJ/pgxsJKJ+g80MrWLGaAPLwpRhyZgP9j4PTL4B7H4NjqzGYyjW8b/pd/S7+iHcoWj0YnR+Cqz/Gh6v6Df1PkgK28HyF+BxFiHiIgYILdNncP2fD2CYSFVjMJ3BUgNgBKh1Pli6nh5+P5OaE23UgkiYvtDYxFI2KIGCNR7XGPMR5mUpVEVQVVxLI2Cp2T0Xqr/iuKD6SmysdCKxgSLGyYrcAK1fogLOpinnAeC1OAl3QasTb+0UTPQI7hKXNZQBmXVMGKpjKEkmizvk2TpBRmysZAR/NusFJdvMNROgkkSJIc/ano1NIIoaWwYtAuI+lPUuxibFGsaPcjICzXaeujlsd51AY3u3MQCK2F/OwGaBvSBI+Gr9HX03hNL1kK8WYVwrcfcCvFWMlfBbhSGaDtJM2ljk+zJHFTY8CCvZf3C3z7jCPA1OdGFEqEqPySRQh9jN0bFko6hQ8Q+Ts5HAd00sYQYhoIiyXkHIKZjHmS6zpsF8MNmZuJ/+jM+T0FyxFozB/Z0Dpr5Ov6x/CuZfCnh4QD9K199OMP/dgIN7AQsb9YUYj/NAa2sBBIvA/JLPN50ZfvOZATAFFCf5K+PwdyRX9IJQ8lN8KDDKOEqFngyEJmPs+oFqA/tdNzNUt0G9IhIaZMgJIVV4gezipVH/JBV1UV+ZDVNdhEcB023KwchzIPqfBwXgBn07JucBPN+BaboXJLuceQLTsRbNwhRMY6hGf9ph60iihTZBKI+MawJ782khKKemZmLYnZRhs+ZkcvUosMRmDDbROCbLViZycgiibMEpH8HAdbgyIyeMy1UAIAl3U4NxGgeGqMHodITguwXsLtKR2EwSrVbaABaPJ8sFQqW2EvENydwcy1DYYRhJr5NcLcEpU11c6dxhWr6HDOyz1X98TmXFg+xuW+jLTxXKEwKAaBvj52fFwFRbviufibtF1i6TT8uAhPAOBLv+mlr818GwlZx7kRd6s5jXOqb1LseC8rh+BDT1ff26fgYQsBUsvw7QcA0tAGdj1ZeCdSvB/PMhC03D/U7EmE0B6y/Uq7CfwTTf4UwJGorxK8PvxIXVQUikn6kzjarZVkZKYKJxD4yt61M7KxdZyGxKBmowQMhF5WX1FduoaScw0GIYBn0+pmkhpuU86GkPApsf1N+i0ebHENV24d1d+mag/OmY0PmcBvEGmNjAUgJAhbX2Z9j03hwK+pkU0UyceB6DMp2EllQaxXLxvrFYBzFp6TSTVRPDI2midDHXzgQRk9DPUwtPDgBw0yCYhBHpAkKexNCpMzCqHXDHcbxbd1ikgKymxlnqt1GBWfheFQtbFjBuP4qh3PzGJPxCvpodQSuLV7tnq+/EMOsthl6ULJ4pwTm6VSOgU98ngelHTZkJDgD4QvUHkkPVGiTCv8DGekpY0BT9pP6v1hDgh1ONy7QhXXKc6OwDcd+rITsuBXufB0Z/Bv9twOLyrP623g3A2Aap4BzAw0LAx1LQ1kIsQbMAedMgT0jaz0z8vxzfXYpXowAJkrw+CyJ9B/xKko2LdHIiUnDXjTQo19AOIsk/nRlq7NNqlp2VDu6XJU/D/Y663e6PQk56Us3mPuYrBwBimsrB0I7HMEu9QLH7TwZuP6x/AgD4IYDgTqz/P9W/xTsboZnt0Stw3ApM2hkhFaCGxp8ipnVUWJdVNsNEjI0/jfbrBBKyqAbGIpBKxjeebh/tztlAaj8ho4a1WqNDlfNElA1Lnq0VL8DJAACmlFciWKcSY1WPUagDCT8ACO2Ge5cMuDqMSpNO3gurnIS91BE2xV6SZwt9+m1UYYS16zs/Iquc/X+bjFMehW8J06ogi8SHVR90KjDHMB8z3poM48MAoLkEIOwvyliaLdRm/P2FDKcpYyWfgWDqq/RmfTlY+UaI7rtos+9ifQcdGMM5CMC3BIvKSCwWg8HOl4CdxcO/i6lnG7D2X4r1/TSMiciYZwEIzmSRukEAgRlg+9MBB/LpXCavzQNETMUvF9jskjgbRympTVJJKAe/XU8A8DMmpSPejWkuLz4TRXg0sGtqMrD+4ldxc3MFHswagediMs/FRC0lYq+iOWYj/r8aBPuMfhWSgKD1HXhcyRyC2YzYGs+qbJ2ZiGmqu5VaR2AuJQHjvw5YljfZZqmhAFSf1T9jWXYxn5JDOWO6MCnvqj9jV9DV/sz956HLftJ+cqJs1YrFVmpA4iNAun2w+pWQdURkLqHUk487hIb5Z8+f0/7i+hhX/y+zCksOmyQ/gUgL1ThZlSWq7iwQ/GlQskqwog2n10Bq9cj4xB4YnZZrd2f7s/sdqQR9j34Dq+w4FnnPMuFSYXusNSaaekIxNj/DqfkXb9OBnHrCKbi+YZzhRuZpNDChZzEWi5+CFi7EArEXNHIZ6ONBLBRm+wwCvzDrFaCgaVgqFuhb9NP69/hvASBgNVf0WfjOdXoH/r8IIHADFKN1oLt5WI6mgboW0OY0lRmAM5m6toqegREAmALGkqTyHiS2IofRomKilOA2qS/gYSnyGu2RsV5sxyYa47RdbEoVOEeWk5X6uPrqbrGM6OoHhr4Cw78ZU7EOq/xGTMo8YLWEA23X1+uH9M+wv62/CbK6nxFcm6G3LbHJmrJi9WDZsBKbApTLPdOWC8+wU5XAeLZ0KgeJzBsTqSDABN90WwUgwRYZk5w6NfOkGcZqWXtroQ2PAYFOBSxKqQpxkA4Co1yF/XIQMHT9FTzaT5Lb4rUxeQGM2CwwlTtMNB+Cd9bR8z0FzDOMobA1NCHyqHAAaFl4daixKawDS/0Q8/YwBO6L9NgD5IBoWxnIgK/f1vs3FoF0Bl6n23AjmSeJGF0GmrgObPwdrNz3QjV8Xv8C8uH3QRf/1r/TzvYe//5NfwwRfxIgI4qxDhU4Wxf6BKTKzzk410LssxnvfxZF/yWQBVbb0ZvJ6pVzWTpkAR7y32J8ZxWhYrbuS7NyAasvR1NKyaXnSHwrdaDCRFuWhQpjOHv3V6x/5MWYd2+SJ7/KmweMK0WWVmH4L9c7McFXg1y34/UN1PdvITA8Aux+GhP/GIjpUSD70/prIC8x15wBohjNuiwSE1DJZItC6zoydYJN9R4DAAEbb54cqk9fwjj4RpYZKwULJeL7CVQJMD3XAQJ8J8UwZqs7PM/3AKPOZTy7hKmK86qEYnBvMM9EjFG8AwDRaq0AQLx27Vd3qKel+uMYiLfdwurWxDyehDGdim8PwTdXgnlyCaABY9S7CSPD3T0zwJYWLu28g32rOUdvtn6ZA7a6Q/8Bs+dupv/L6meSh6Ks0zCSKkG0rerXlFsnv9oZjPcGGPuP+uf6Lf2O/n/47x2w/Vshxv9Y/whUcROo5noojZvwu6vA2pJPOhP7NC4TI7BcrNV3g66ugNwggv44FvmYy5j/s/CdKazytwxK5lp+X+oCrgKtrQNoyGMljpzKOhXFoK8UWiwSAQUd8I4EEa+AglUpo/hnjKzZ14YDgFhQWA/gzvgn1D57xFd6A4nOhOa1HsO7CRN4A15tBgDs0veBbK7H67V4/ykw/TeB6I8DAPZg2vcAEq7GxCzE1M1mmEY/RmmV03Jv1vBAqEpgkt2TSVTptrREMpWDMmpsdUz4KaFbJ8nWo7f4nHeyDKRrcVf6ySU6YiBYT1ayQVipJBK9mhERbgcAzLYFd/ipWZUiwGrVzK70OSza4ML/Z0KyqmJO/VyctZRprUkhYV7KjlUyWHYYINR1gIGvBIx2HWZtHmQLKWv5I1zbgebANOYbJlgAiLKav59uNFN6LUAXrfSi2gnx/aeAgQf0j7EI/EK/EmL9N0E1t9JDJKU7xtqQpnMZzisBvhJMLr2Q5oOhz4fW/x3Q1k0AgEW48sksTTeRzr7h+O4M0N8WfGsVO1dswYp/DdSEs0GF6/CNTVA4h+NMfTAWaaw9LXmXOYxXlPC18RinJQYiW68a3V+ZRGCtItpQFPSrAQBFQN2lWGUuAvtfiyE/h7r/NkzR1zHpKzGxF4Ld/6z/o78HCLhfP6NfAwQ8CAA4G2LZXFYUkrDQLnQFFtBQZEqFB2xFGgcEkq0skMoY/mwbX1bOnjSpDAZKdaoE/FWdYXf/STOSizsyHmIgDapnsojFLEZXpuioC3kv16kfqRsdbd21BTAnAJCJT2xgrkhQmaYM/DddGKHJGNsKxgKksm5SLNcvcVlJ0ksNWG0u10lJtOkAJpWQnIEYzy6Yvx2A62+D1a4H8xdg9Esh1fVu4QRMorW8qbFXrA2rKaD4n2ELswcATZeC/XoD5EfhPO/opu01wMEFuNPJtNCPZyj5KGYJjOPKP4u5I1KYYxnNfVuxvIjeL/H/ywEBUzFOS0B1K3AfCxkILGv8DMgt63AX5+Oo7fjeErwrlYBNKZDOANR4SjQ+pvhKPkVHnOd8HFOvY/+NER18MABwG5NghEr/skf6txEA/JjWuRjIVWD/q5mTtVnvhq7/ANj+Xhr8doHpfwKx/xuQBL4Hoe8DTPs9+OQChndOZyW3LvQFlDAOK5vrv1N20qlLYwpRmnISpkBIJjsQdqMbK4kuP6xty1U59sLjPg6Pqx/asKJXsb9whN8uUa963y6y/ROrWcasO33Y40CcjCp/1fOq7w2uwA2OBBClExzfdLndp9VhlBz2TGQRlDKMoFM/KZYW+RqWuZC2GVIXfyIr4Er7twvBPNcBtu+E7PY4Z+8RsNsqzN0PwVxprTgCi+lXiApzByZay4xp0mKSlCRb9Bv6RagRb4Zp+o9yZT4fjDmbQv4MGuumhIBgJGP3JId0JD5ZxGjSi0E1T0N5eF3/ST8BFj8bNHQ2vU+bQHmr8EqMf+eCBs/Bmc+mY/ASvF4LAFiGK0mkW5XVfFZhtN6JsOFhknMh2a0sqTsSs3GwjdKW1JbGHN99ivlle8f9USGHtiOQ9k4QjKQCSwTAI2D7bzEn61b9K30bPt0JUW8vBEGt9+tf4rOtmKSl0NtGMDq8jgpAAW3OpqZMivX+G2tyvK37l0qRMsAMtByIbSIeJ9ItxfCM9irv+UO3CQG5hqzxwefxAiRaa381mL8vgK0fddUEw7yfYaTfUbI7rUK2JGqPAwABu49IxAoaZepBv6P+nQL2EVkpImS7j8VaN5wxcvMhMI9i7qY00FiEeZMEmssB46KJPwSIvl4/B9b/BhjrETBiLUa/ZRiQZBY0if9N5UUSbV2/gWC/X0C/l+2TZuv+RQCVM2iqm8PHaWBdyRudwTIeU3F1w2j7WKx/Bvp5HRRz4PY2wOpifTMeG8DiK7EvBCCci3uR9PRVgIwZeGxiDuEUrPphjuCP1GkYrbcxfjJOHyum+3QADITVX2yho+Eb4xW9T7kyvo+dYn6z7Uigbz4R0/hdsP6VzNf+nr4RMsA9TOT8HvTHXVhf7tHf17frV2nj/SXWmgswSUsw8cOYE2By2osZvx9eDDQ+VFU23taOSaN9Wco2lGCF7IhvxduMf6Xbub6vcl8jJjHPEQOARPwZ1UZ6GEnOXH8Qv3S1qzUA8G6L72xRxgYQZskXE1WgyTK9wgsoGciEZ5e1answurV4T/ziZ4JBJE1LROg1+hbA80a8L1705WDPy/HOdXoPIGAN1t1dzOVwtcgFCLD3bnRYTz+nm08Kw34mYs4fBhXcBWp49wAGvo4QYPYzAQXzGB5mHqfRuv+dsKM/1v/QLbffg6ruBNNLtqCw/NUM+xH2F9vBDMg01wJMJuA6m8WB7JImLPjvDxyn2wQA0pi6XHpwAPCaO8437VciTjF+CAAUw06lNsDXIJ5JbNa1WDduwN97wP579K/1zzHZWxgV+DYm7QP9fwCAy+nKMW7AfvQB1NCQl2vLS5nawAE2+PSHasen2GZfQRxXyQyvKrxnOuJhQn/f7uUX5qkHsH9DZURMdE9sMxzl4jsviveijHUSS1igYi5GNCB3Jme8tRkpypm/pUQukFcTI1m9Pohv58ko7MXxBIAYkGsnAqkJfxb9tZYKxljGa4pXfAoYZjPE8atZiec8MJ5p/j4eQvoP9Sv6BwDqzYDzb0DvTm0hAUimXH8wbLW1MMSHOgyY2k6SxNsdgvk4nOPA7UPIh0vB5tKCXpx6EsW3CPtZZOHm26dYNP7ezHbQtL0C6roYC8z5AAKpRHEeIGsxm9Ys0JdCApmL1T/eFpCzEPCkZPQpsRU1CgC46MCMw2jViqGVY9pMEajB/1Mi2V+zxpzjFACEtt5qmfpLlHROAzn0BNGsAllJ7PUMiKMLsXpcj4m5CuSzHZBwB0DgQwiF/4KScA3ePxPEMYjhFyZ2P5fifzZ7BxUwBDgubGUxVgBJCJb+Q9K5zQSrRjsuqmtOmFEZCUB6GCPTdtlhcYQtsyElzHuAfPNML5pluCvu7msSr8nG3+jrTEizjzqrtenv9C6L+ixbq6dxfL49ZZ1a5qe/2yklKs+p+H8kRl6SXFYChkX0L8D5xA3WjfV1SxlTIelD4wEHy8FY61jg7VpAdjesp00AIAbgs1mt92pCSK6t6l9Bc2S2jeiU2gSDwKI/bJV9P4NaeCPUwXNZQOZ6ffDtQ/1X/Sb2/+qPmqkTn3BR2ccYg428Emlat4zeqek0/40KRSqaZiku258AI7Ib4zQIY8ZP4kGBZVp9iP+XqY0c9SsgEVyjXvBgXDrpwaDsWu3ZiU/dpxg/fHtR0RovhqBXMPyDQUzrmB9wDib1HtZwfVA/BgnhdmiXP8b+pr4NoLAWkzPNqgDVtq6cRPrlEgBMEeloWwkvkWUvc0maJWCSMZAbSmzOe5Qj3p1QAHCEfRgXO6tqcnjU3V1KRTNGPQ/ygDS/GsLSGfWsoyjJLO6wbjWqZYoqyd7V1DGYFoIYrPIuBvNMw0iaUOAs27YtjynVeazDJGVHJoClrsT8PY4Zu4t2+LvBzI1smbEbq+1C9txdCglvK85azDpFosB0Y93HERDLl0ARuFX/Wx9626vbvv1H/zPsv79C7vw2ru4W0NhtUFY246rWMifgDNCWVAXqRGb3MrpPfEdxdFxy3HY74+RiyLXUpLLq1g6O2IemC1Mx7nwy7idLQoT6n2L4A7cy1V2wMw3kdS0GfDiGag6rvKxiIvAlUAt262egBz4ACWCPfk1/F9N1LkhjLsuG9mHUWynNf+I+ymcGYF4ou9xJJ8lkMmkWyH8kvpHH8FYf69S6TjQAiMf6Gziib6TiG3XqnQPSbd+L+mUKxmIQFSVpXD0ehDgSu9gH8pviHUCUrk/VL1vUNZRzjm8mtj/C98x+bpNWX2Y7KmdaH0uQRtgsrHxLAdzfhgpwPeQA6chzB1S63+qnAQezIa5LZ+i1AHpRFObjuqTlhuQozNTrAfcS8feiflj/SX+R24eAp0dxRXfg927G74pNYyaudBQkxekYsXqGSAkExFGtTDCwORgjkNsEAJGMJEluDgCfeV+TwmzdqJpMMAFmpwCglc3v+igTumUQ5DIMGuYgaGEDQRrLIfg/AhlARLP7IPY/i2m6HURxE0DBxAHOgLzQjS07Shj0kmZTMyTBxDiYohl3Lt7kYqoFHQkwJs7Mb1tj0E7+gdp60o/jW27cn7kzqWuQxTJa0r9+EAtediAYLGDG21iMQYxJQv1A9VHSYOTpVs9Z6WHRKynehlG6LuyTqTGhNmuljKqUbjnZjL0I0AMjqciDMIu3YNa+zvoOVzGfXuz3oiD0ZxX/mbiic7DurmbJl36Yn0sBGT+F1m6s9R9hzZbtI2jy//1CIGC//rX+AUDqWsCSZAOs5YjVsAdANbNAIwgBcTZzgaCXFS4puRlGziDgfwC+49WuBFYqNp0Kk9khuE7O8l+O9amtxTbcJK9KS4Xp0JXEpx/EFMxmM/EbgMw/gpj3A/0kZIG7AQdroKWdqU/DRBnxP5dJP6mW7EwTKYPa0Sw9ZfrYmvr/AfoGTBCqFf6fOIFW/0NvxVAPWpMN8vH+yIh/xLMrzXAI2VNY5GomI9ql+cpkrGdFGIMIbbIE/U5e3+Gi0XPVo6H95gPsN+bdJxUgerweyjJjlQzGzmbpdGGcAr2Shd/v09/E4xtgrkm4otGsvy81niVsZ7W+HJAvVf6mAxq+rX+i/6j/Abb/TH9KE97bAH7JJ5BAo/P1c3z3WG9/gbR5GeSQzVyAJoLqJNWsC8Yz2rK/h6bAkDcgHAD2QIZ8EyPxf05ydQptWpk4uhiwC5h9zKpRF51i9YMCgNFhE8HQM7CiJDMvXwot9gMhr4MksBf7PZggKfkkzqYF7NsizcKK6QMPcPWPs51uTCV6jy1tJWbAdDaUSLNFrWNYysJOZsJJM07rcbVDW7MBRODOCyDbbGDt21n0jEsi6xIIs+K1H8yW2AHetynblexk6x/tlpxEpaInH11ZoK0wVCIsGquflH0XE+4TkN6+B2VAJBCR32S9n4GZXIpr3saqUJMB7E+DxV/Wf4a89zJZc5/+HVN4JrLoZw+oDd//AgDgX7iCM/A757FQyOmULeX6smx1I4/ta+BqDQCyY3WENN253pRkTWGgcx2oTZn6Sdq4AdUpADjoVqjOll0GNwHk6mJEeAor+dYwuHUDEPpxvRXE8iiIaQFjuSdST5NE0Xwm8Zp2VsavHGnDVmM4BdEsMplq2b+pM5B6lr8bddjrW6suOAFGqSDhuVYAIKi2up4KYBx6Y+2SfArRoNeA9ZezBetIELK0vKjBKCXZUh8iFwUAm4xl2+rGrmQfZs+Yxf+2pm4NOp/UH/SaVrmuCYBRxBTbk78j3XBK8UuRFmhiAEsTGVX3Pf0alIFdWOOvx+yNZHNYcSVOB3tfj2vth5meCXngPv0zwMUu/Vf9T6gC39HfhWAu3RpKWdOoBNLCj485APwP13caoEna1Y/E3940kybShNwEAE1GUbVLnRMagzjQ0CgBANOpuYTRgZCw/p+hauxuPG6EDHAKAA6zsfxGN67O8Syx1IiHEMViIPNF9D5L3daV7BYgaa89aAIUCEixVWZjbKVa0wYrlj1ZTe05v83+j2pa/duq9/9OvX0CjE5PXvOBAFCt2HlGKuRM1Q9BQZJk6XkU/Kewjq6MUWf6SZJCVYLj6RKNp3SUytoIniYvQINJ6a0EACeacZp+0GvaJzM1BKw7iPUIBoB1pF1LwBb6ctOJKOVF66EKvKLvxEq7mXH2lzCEZxaLbp6Bd9aw+HYPrL1nM1tvk34YEt9DkAjux+d5LNdqmsDm6u4AhWO7/ZI5g5KGLnEHo3R/qDNJtuB5pAUAr+2jbH0if2gxFtebTMeOjnL1YbNP+5+SANq29Y8EURhTSwmIYgrYfyPWiEsZoSUC43kQFGVV60/BtpFrQ5Ft/BVta8sLasfQFhDJiXPq3EXR7k877icn4dh4VCT3ZgCQC516Ixti3AjyHQJtfAxbaEhHRSlP0YHmuUxbGdHp5iduumpmQ1bRau9z6tNo1cUAsc92/km0XX99LSr8SyS8tEkfzOaa0l57EAGgmF78NJ7TpZ1GlSmQ4/ayHPd1YP9rMY+b9IOsB9mTBbi6MwagL+Z1CO5jpr4c0t6zkPu2YdaTQz2Hk2jPyQfY3X/M2P9ZPYxZ/qJyShi16Q1YSwkggnkK0jTea5ubhUqh7j5gdnaq/Yp01yzz0tn6geI+PeUFaAMAKAiGWSSwBECANBJdAxLYqi+GaLsCUsBZkACkX4B0Z+tJn7FEscWF6sp7rfDpta889tlrC1lbAIg6CcdmfSuGu+pyrL9X6u0YlaVsniICeYMtml7DBqoVbFiRbFt9JtEtKnXsTaOtevY/iLf9fWJChUGMqhDDCD2TVRlPhSrCsoCXsZW1YMcxgGPp3TzMAkA5C3dms+i7YziT48v0I/pF/Qv9PNb2BwFXF+tbwWoZuJI+AHUxIVbhVS8I4bMww1fre/VPoBxsgjwQDGs3msKA7irQxL5jZADsi1HKZ1eJEtZQOI25f4lWVRSjaSqgwWNDyryOGrC7xfy8bMvGrzjI/F10CgAOvQ3Ao17tqQQxyCAH6BUeSnK4HfuFrNyyijlcC0BsjewTJ1pnIUnXEe4PKFj9rtqj9rj+6bYCqdcEyww7CcdnutwJ9ng1UJXynT5qQQSY/XwQrbSr6sVg3S7sb1jDDoclbHtSSCdpGiskprH9Zy4LqXbk2l1FF2m6TaKOsCud15bqiLFrb7Qt5hFLYJCyqUUs1j2ApcgG4Ey9mYjUiZkZ+WyzkkRgjgxVV5wMDf9eCPbfZQ9oSfH+Jq4xGyB0Hq69kpaM0WwDM5VhYJLztxKCeZJV4UxfR+cezgDsvXOU7P8KrqmakSMyJuWQZhZBAliA64gPaf6mw0IaI0xrqF4yhqI1APgkdo9rjxp/CgA+32YTVGJZz0aE9Sz26O0FotgBbfAhNm06B2rBDPZna2D7r1KG9cQyp6B55Rn76gmedG9TPXrPsbF/t9/WiKvfxlfvRWEUFrMMZzXg0oj8HVhmvYQO0jw2Qym3PZKDTIWWbnZV7GHbmXaWWipREs+XQVkg2pJ+JCHVa6v3m/h9qQ0klfuqWPW2N4N+h+vZAJ/erM0knZw7sRBXCcutiTE3PjQn5fpc/Q2s7Tv1XZAA7tZ/0L/C1VcApK7CJ/1xLXMg461glYFbAPjpbE1WYxuQOQCQQghIw7fGQvlZrT89bKzgwbf78MuNbPIpgFXJuv/Sg0h6+sooxLEigsSMJFBGyKTckyGg1hoAvHvIeWsXAMhXG7EXnxQqbihDzcWCoV7a8dNZfuI8sP9j+iaIuQtBMuP0JBZ8DDJdJZEmJytsbmi2v4nHDJ5zrvOem8R90gHAxdEblbPfBBnmx/LK+1E2m2MVsxRHJwr8pllqIZOjc9j0vJbJUqaboemlW8JvdWVVxkZAiHQJzGUIdRKTp0xjyyjbACyKgr+yPX2T8TqZBdiGAYgL9XwwzHRW0h1GK4D00uvMDI1iXkPQJALtxdj/NhP6/WVg/6tY8uU2RuHdgm/V6M2Y25nsAe3U6XkMyp4kOteyGpHJ6kiwDV5SbMPyZPx+nV4CIGnL9lQr7/1KPwzQqaZRtAZQNhQLSz1+M9MaMSUAuIIlQKIJnpkEntTWJIBR6u/qP5iVqQedwz6q4PgTTqLqiz0Zr6474Yncxkm5iL1RFB1dROH+EMoe0T+DyCd2gPXM+lqLVSLfev99Zk1/BnfafOvY8kdcjhNQqWnqWewnR+2//caeIczpOtMY4IT8y2k6K7ItTovY6djURpLQqHxqtRWUD8qZrFNiv1FDNaGWeRg1LKVdA1ZqZAnNVBtOFWN73pjm335rPZAMiiATjz3MBYhmEu5Udu2dzEoBo6DJd2fHYSdFm5XynsX6iLOWA3wGMeBmBCSHnqxoPADzuxar+cXs9NCI+V4JgJ9gm2wZb0486wRkspdjjo02NE3JfaxRJO26pgFY3m6FzW+F3Cj5H730Puj8z4Xef1W/BAi4i77/aYCdKexR0YGJz/ksEZfMIvGi9pTj2zW4r3LTDPZNVR42OwNxd2/i3fdBgdUHncM5LMnyXbWzfUjo+ZPHHeiizlduU1tcmPjREP+/ra/F+rFObwDmSwHx8azz7+dEUcS8py0ndzmyglJnn0SBQPvD7O+NigUpUym0VrEoeiHF/QJasouZjBNkMG4ei6Rls0i46cAkeyVbq1fbguoF7KZcC8YcAgLPYDHOJNv4NMFW6XHiLNLpcE2iVz7JXk+dXgXNWWryTGOQ7xzIBL1om6lgclAGM+qbVLNc+gwa2HytCmwr6VuNYPd1jFwYpWfhfFL0rRfNt2KOjGc8ZzpX4BJecxoLvcTZhG8T35CA++2OK5Ckox/o3+jP8Hha79WvA1q6kI17goqk4rSxHLwPKHgOMsgT+kG9FVRlnJLSbyqfPSbEgiE9EgR8CtkPII81Ab0t3YDTQ/amw6sAn4Z1Bjqum6QhrgYhjT4J3F3PiMZZiYlgoSWPH9MwQe+CEHefvgLqwBl6mZ7LXK0sEmqUtKvytDHR0jER7rdMtV+9eBIAgBv35+yQBkyFgww2VpPi5qZjTinX9xJW4w/SXp7CeojSuKIKIn9/sF09HYPyXM82FlW0EZQziVc8Bxm2oEpCSN9OZZUFU8TTKa4qCVx11s6SCHY+DWv6HOwzWY1whC3UUmevLtGUwpD9l7j+5RFgLtM7uCvmUdq8zWJ1XintOQKvZ2IdlpqEpmNgFCsFm35P2VaVCdjmnKaBW4x1AJsmbtmUdxIYH5LHGBExYaZABhCv0UwA1dv6/+nfYu3/mn4GKsB39JP6analOBO/OoidFMvZFj6azcji2WtCgs6l1x9NmjlhtJZtKAmUWn0YCnSxf2S7AYCi0LtX9VRdw2K7urQmJrf7djWuc6+Hq5Frreop6RZdIBa+Aby+DWgtZalWAQiGgISTTUnrt9p87r3qn82bWoIoT6ot0nb8yWMabimF/0KCQAmVADFVZVj7SJxl2jKSvxTLmshQFzHVNdIOUMN+u2UUxWtpCMwIFVZLoyyRSRki27ZQzeH/Aj+VYhr8n5mnYQCPKWy5Ia1bJUuzK300JlAryPQsjvnvQX/nOCZZKZJVRYlFOjyJLFKB74kr0bR5SaHaE8mGYwms6iRdHzLYOSBglb/YEACYtJ2m3YTu+FmxJwhYuozxkNIp8SX9GiSDxyEPPAoZQFqFrWaRGWn90ZttwOvwC6X4jfH4boCB5NVUakqlpt9eNRx34ewBoVUXHraaQkqLvMqmrQbHP6eub28K2hBWbuJt9bsT0N+d76zVvlBJSQ8m/Ov655isW9jDfbO+GdO3EQSZBhI4AgBYD/GteUjLW3hvfTOd7sTdpqr18VyVc8mamexyJB2RpSRKgNbxgK2oG2SpUDmuDFAppTwnQeuWJtrLsdYNYyhVb67U1VQHKug0LGQhkDx+N9/2Xaxmh+ECwoH4CYppK5A2qpkfYeQudf20HgAziLX4peL+SD1GD6UiMADnb2QitgjUVgr4kUQ0eAhP+O8RdansLu4qtLtYeMNNb0QsrfAZYM1aen3S2Y/HVIBMtsXfEiwMRFNpMLH7HlaESAIUzcV9ZxMak6Ei7AQNfUPfDwp6AOrCvXo3Ph/GKhQSdBzEfQssdsc95zLRWeQjyXNgvYV7MAMfJDRRz9IDZmj8QeMAlEi2h6kINAZjE388CepEBAAnb5omwISQ/uiG7v8DoPc3MWXX62sxdbfg0RGkkHAkAHCwfrUTTwoAeMLN6gYB+vQDXAuDdGKZgmhBCsrm3QzW1JEeyJ2wIg+j9jufQVQTIU1NZ7fb/uyqUEOloIp990ppKyijPFHGVumdrc+gmHn/2ezWU8Y1WBpgRbI3oA+v+wMCBgFoJtEcOApA0IsAU0UASAmbSeNSlFiEQ3Rh0sr2LzKOWzF5NvKaiujJqKSsk08bRw4rEaQwrDmLQbxNMXtSwKMrV/I0uvSkmtGVkAakSfg2fQdA4Hp9CdSOvmysls/vp7AWUR1lkwrba7LUGP/YLHYbPgm5mt84pgBwFxWM47j1g1ogF7zG+sv747m9g2SGQowyz9gjnk8Tk8tQibWuwaS9BNHtGf2gvgtAcKu+XV/AQNE2AkAt7q6J5e/HWX8a+u8X+CzxBF/9n3D9PZaMHSQApFqPeA4JP5OrdhZ91Rm2Q3Ie+x5JteBhrHi/gW3VpNn1NDDqMAsAHUDsXWkRqOSxXSgROCW+ulMj70Y2zqarMJutwkQcr8CvYNzWq6Gu340AsIzEmcfizJPxG5PB/gOwV+EqggSACLJzpE3QCuJzsOmv8P0nWqWC1x2zoYtm4SRGF5az+lAJTZnFNF8W4pWpSFSJPRtnjggDANH+p+NuA1Zx6QXp50J9OfR/6R24g01AtgIa++M6CxkQFM/xTWHAdA5tItJKHfD1J1zTToXXl+rItwx1Yj/Q85QeKqzWcuuM412HnOMOOCL6+JJVKTO9b7ee8Zl4PuOEIvvHscaImW6FFKUaoG+E4P8T/R1WCNrJfgJSDbeNANDXxKVblpdkoEebSQHpJzQArFc0iAWphwetwJ/KYlSZto5epm2pkWXF/zybU9mNxUDuoKHtdKzQA1i8cxzbq3Zj4HBXyAl1kAR6steS9PmtpElRXg2ASN+AXzUGQAkGkrW0iPb4ZBm3Vbi6FwpxXln7p1DZGMkUXwkNkmBjp0yLl1kGfmruUr9pOCU4V+tRGS+xVRljN10WNBLpxKzglZXS8VmBa5ZOwPW4F+lwlMlvNMWDigVhPpSdDEZDFtsqExcBBKRT8AY8XwmGPh13OBxnFpNpvK0kmcIIwFjcaYbpm7RPsfzaWBzdSjLQl2i7MUZHvKca7R7b7gbBF0Jd1DANKRj+W2i7fQpgMA/kJk0bWgDAC+pcXPvLobvwK7dqiuNmcytrlupLJ87f1Hv85E+s9noibn51rZfusNQQg5u22VnWSJdl26Ik0yKQw9CeQhrTKsG+PZjq2g8MadJ3pdduF+bvdWUz7dH0zA/WZ0Af7sokqxq+Xw9I6MV4wWxrHswgSxTw/NX4fqZ2bZexjgG7z2LDkNHYp+O5B37LGAFNk/ZYm18QS60+mqXIA5RYDnLPceoFCcHxMS/RzdiHNCofGTirlDarYdaiaQcvLF7GADInBcnMdoxeBYArx1lycIdSNF0cjauZ8jMWbD8R0JHJb5oqyNHMRU1neBmXi7dBTS+E3MX3+FrPBvwyAYAKFYHEXnfiXJiLADBM38syU0/q+/V5WMdKRA9tKQFsa7a29xQAaF6Y2kVxVDlVgR9QJ3bP1p4SwiS++WRWzs/hClhIV1ceLQAZNlbNSAPZNOIVUliutR2DujPyrws7KndgqlBP7DVsEj5an0bmvxBM0p0yQAcLAMYGUB0yO4ocUECLunRX7A5w8diuvyVMQ15AtpKa+v1x9gZ6Fky3RsdnH2tzNqNoxxfJ4FBz7mVUiJugnUn7g8g1jWyEnmvlkiCBIZ2uY1eLbsTS8CuHqc9DsGDM0nOgBpzOPkKjmfx7OuMfJdU4KmR1iGjKJ9nW7ILuUV96AJiMW5b921JTz32VWnLCXNk29VE6pm8T1v47AQEPAQKuAuEWade/IIaOsEdF4/Uq9awR923YT0/oXtua7TbrLcJUvv+B+hUn9r0DpvsEAgDFWn8+puaIeF9Cx1kBISDXrs/pBIEs+gZy6EyrYNafFNyUoF9h6kb6+6spSDdwFZUowf5QqL6G0Vyvh4KpO9EsaFyF3RgyXEMNOYcMl0dQycU5OjN6gJ1/7nTjGtZCnHYKkZjGrbUs2Rq0WQEGAmJD2YYm20DddKg5d70QQxFcfEJlNhY/lzb9DGr2mbzjADV8n9Pk9Iammfb8qxxML7JLAcBpMWWURWB9k8Q0HDDQmxKGR7xJ9+Eb+7Hq/zSMUsbQOu9o5rPwzofq72pIm2atF9WjlraAVdxP8G2iYk7UEber+gI3z7t92YZK6sDfBEngMYDA3foSs5I7kYDJ4Yk/bqPz9zyYNyCCrsYsZ7149YSdjZ4mANgE6OazG4KwfyGddrmhZB/jBzAWgGIwdgNX/k5czWu51ndm2GyFDQyuogmtEqw6Duv3uXohKy3X8fhOeFd6DvcAfDSw7UieBYAirr6lNB/2koLYNj6xAKy1mYqAlNTqylCgEpsTYKL3TOxeNAV7n1OW/dCdmK90ZLY8XEkZnZaFTDUSC0jQqjlpuKM0jI51NWaEff9P8RgBgc1CrPyLbAvRerD9WJxvjJ6tJ2G0vOZ7YtITALj0gGt4yBqmzfZWq+nArW1bWpUozz2hZc2w7RqFyeyh1aPtaQRsNlDvujHl84Dea/Uu6HGv6A/0H/Vv9fMgtGY5fmzGFGdruKj1zc6452BGwBjalnOcuLUT0AjoZqW9aIanZlmffT4F4WxCQAYF4gwCQCG71zdSxy+zQUIiEXRkW7QKKhDFzBssZXBwLVm+I3MHKvC97oCCvozqFzjoRJu7cUCaMuDSjl2McEPxHFaOHMddqlfo5RC7B4LJujDEJz/UuDWF1gCT2Sdttg/qBmwB2B78ch/mL5RQthErRAKrDTUQhqocJp58wDf/JN8toewkKdM9eFcVBMLJej4UgHG2BZraoJ51U1ZR+iD1F41a8parrQDQVro+su0F9dHxITmfSnH9Wv1bxR1nUn8YoriXlv/3XJ80G6gk1U2BJJdiIuswlZfoHXoDRNfHQA7sdfOe3RkEEm8bWx0AAPFAc9nPxXGfNEkCxjfdFeuCqS4UOpezn97+AGBKa0Rx/Sxm1l+eFcxzQgAQZAhQHrPyy6mnV1igME7BjhDQexAAiuhXLyfDyyt5zrdReBL51gNA24W+AUkUKqcH3pjtsvi7+SxFNhRsSZhNUZPkCpMhm+3QG8FawyFi92CJkCLKKFm8wnQaKpOdwqRtBgA3IxpEKmlgydg8hicnUoLpA3ZO0Oo3nNfIA76ZKKNWwKyRGtzPQDJ/OcGwBJBQjTMmhABA1IxcrbbjPK177G92v+f+rJ0BIIHpfcdpe0D95LiT+i1qHwFgAZ730f3StBWpfdH7St+v4io1VU+HjLJQbwMgRITcP46wnOa0v1gfArTwXK15rn1JH6SZdePd4L64fan7qn7XoGP2ufCbeIDJ0p3qubJvxre/eB9tHH6lutWcsvXK2sIjaQsosut9wPr/syyDNWX959BVV04feR799mJC6wghuJHvFjOYuIIBQPncC5kYKxl3lSwY0p3xAR3Yq6faruQmxrCUAFPIOIEhYMMYiYWfgbl6J1bfxtTts6hj97SlW4sJPqWM5DMGy1T5zj41so3jss/zp3xIFDW0OjRSncm1UFKAXyrU6mX1zYN9V/0lmb79REJINUOJyvn9DIBIptPge6e6T+2L2Ofep5Yf9Drukebl0e0LAKc2iZjyQg3YhvX/UuwP6+tAFr6QtziCun3Q0QgdAOh74KC7HlXNewOWu/WBVoJme+0XfmcjD6ofrle21Jmxn2cyWj+VYnW6dYM5EkDQqgEFdu3PCUUFlICtp1LQLwlJAGU2gShAX3kmpYceYN6RrI4v+n8DjXmFNhVHXIxFlD4EKhoIMJOc4iuXKrxznb5ZL6FrsS/rAzTQFNmTQUbGEpF7xFqwe7BUIDaJzR14xjzeu2QlcKaTDvHlmZE0OXpoKyhnF4k63EeyrZRYhnP6HRvAobd7crDYBL8EAFBzcpQJOcg2V+1Su6JY72Yy1pr79b36KuqbHfUwvQZ/k1mjPcus3w+rxWqRkqCnXQecZ7GcB7ujNwbDjtjVbH/yeAGAx1Tm8+DaRrdmAzApsjEMVcmgTp1CKaCJ+Y03IMgyV/lc7bKotxfQc1DLCn7lVgUoZcmwXOrnSTbIRwCgG8b1ND2REQONDLQpZxGwMioeUonAeCAK2ReoQs+Ra/4NrvkJMQau1nfq7UyvlRIbQ7APwisJPh6J+RmA78Rq9c8Ws3HobbCPV1NLwBIQSacVwTR4A0MdKmJlphMZ6GEfH+lcIDaSgC0xJlGG5SILbscdSKxeRzzLfuBWrV7oi3uIPTYAMKk9Wagk1N3s5N2mOnuQjcJ9Wk31/0VKiF0GEhGruNfmk0maqPceZfYag+TcG9r0O4k48irPk+7jAQCZuJ9HQBz3gaj3hL1frn7lChU7FRCIA+kmMEsuzSbLZlrmz7QKQTBMOchlrYAq2tCrrSGtxLoQc2yuX5ApPnlk6kY26hrEJJ/RYF7xHJTSd9BICJAqRCYTsYoKwrKmmAqwWbW+HYrAVCYFDSHT96X2niOC9hN21oYf4cgMduGaO7OWcRHhLMepNPAozpZ1yO/OdJmIxTPF2jOA3oIYjFkiTZES9xdkx+IE4026mPaWy1qp7rNYSpA0iLRwLABgiDq1HaOtKYhnnwskuld/Ta+EACsx4tKcuQ8mLdYJAh4Y9o22aaBBYUi1M/J4AIBsW+3V7WnuBvRYBSCSf+MIAal2tQ8yOy7dauiZNq03aK0CkhdQTF2/wur8pbSjG8tALh11xo3oSAqSPDyE3vyxDJiZBNarAOtJaHAFpYZSCuPlLN3aD+v8sFCQtQtHPKx/xC6EQ1knQFq+TcUveo6mEetgCU7rZKsYllJlscFqVx72uzN5XLkKSDJPT+b1RVMBiGNNgTjc/wBQSZU5496Dd2HKAnAEtTplAzjBtiy7K0xxldLXYv1ZDRF0Kkh3IJC9Gws7WPfeQLqGzPFtM+p5cGSy2gkB/B31yhd/M66tMdr1CX4zNRwAPFYBMDYA0/rUaPtBK/6b1b8yZAUIMJElaEHBtO8u4TpeToHecSDmhOIIMkIJRIMBnyOwdk9iTN9IVvytoUfAWA8KrK9AvAwjcMQyfQdUMFtvEbC0GQCwWS/Q0/QKzMRYyCkQsMs45p+3BlOUyorY0UBnZS2zEFJM663Dn/EtdQt/2SsAEM06g+JNCdocBdNCXsZjpslQ3KviDkIbvuiHIzFS+N3/4KxvHUEW6rEGgH5H+ftf4i1R/SECk9QfIuxYvZxrT2dMbgbzxNUfoHkVf67GIDuZAPrBcbCdnIOrPBBoGtU/XBYCTKU8P8NgJMYul1lrBgByQ7FxmQyVCYRgIJNauzH8lbFSTx6980Y+cIyIuQSAcrD8FDxGgIWnsvJ/LzoE61g/0BQgKaImLg5CKTNysX5Sr2E7Fy9TZhdCCrsTEDAPn+br6H/ijv5wDNzJmzqxYIfYJPJx5VFtMSTm0wpUTJgIiB0lmyG/LhpK4xj7n8CQ5AIsFpUCYXsPZQSMYihTpJMO/Hm2JFXsuvsow4l7c0T/cIrdW992m921O/JJMfsMBonHmoLg86SBg7qt1W9Nx6dNewsAAGk8pHa7d7fTPa1320YnEcypS2JiTjbZOseK/dlke8clmG7rBqTYMiEZjB0opyvOJAw1RQ5khACggEd1w5gNBOufzyy7TnQGNrDrQKXNQii1TsRhWDev1a/qb+HYfFxZFluzSpKxS/R9MxOOkTUlNLoxnw8AgjQkDmTGQqZpUX647U+M3d/NorMBkU+kmoFJCEsiTbhYUCyWDdFyxZJ0cACoUD+Nw/fd/A4dyFM+x10Mx9UcK2Vy7ilmP/Q2VCL8xGWV4IQFHbwz0DsqPJWkFQngONkADgIARgKIoEkzkZX5TDRevq0IkMMWIE42QKaNEkijpTtgvffVLBKeF6b5Z4SxfxYNgGLpbwQE9MbKPhaacUeu/NVMu+3ENKISSglltAKM1pdj9f+a/r5ezCoCEp4c6aTSDDzgHupkZGPls8+Xer0pRvfTQ9h/oBJ3F9lWAHDySQMyw+LqdNnsgiwysmkmn8OsidhDAcBi+RbLgtPAHNmyIMjx3vafYvHDWQfmSFqT3ylEOYe754CjBkEmuE197GaFYWvMuo17H7WFz4vdOylK7mo/ADCBQFEMam2kLb+UuXHOep7DjD2zG5XAVA1KsSk0eUzxqWW9n3xKDrkhg6H5Vh5DbUtZB0DShQeD0RrJ1hUMDaoH63UFC1awzGglLQBz9U0s1vYvAEBf5hV0EcZ4heMs9fFutiN5W+xtaqdrjsvMwJFKAOYcF7p+W4T1XzoRV5rgndOPHABipdDcBlzDdjcrHgXoXZHSIWMhXUSFA0CB/V3HW7TYY/MSlG2QdtwAYJO6ls/T7BWtVpKtc5s67RSLH367NJIT7D+4zrYshakpkZzc+Kb6dVotUL/j833WBvB+ewKAWbUk712CdCsYjpNvw3PyrVafaV2AaeyakEpjoNT0zwaxd7KFP8T7X0JtP8+CgGkakk8DYYmFgEaK/lV8r4y9AyTOoif7MRYwybgO8sFK/bB+TD+lf6O3Ah6q8e0KYaJnQ9f9iagE4oCMOpoCrGY2zlfPReoeLAmfYwA95kgBQJkEZElzH2kyRpJshEAMex2qcABotL87tkkCcELHrSxzvABgn3qPz9vCOl5d+lXxJHznaE8QtTcWa98oyfrLbrEPkcBhSaw5j6HDvbAmdKMIPIrlpb20O8cz0UW1JwDIdod6Q9pUiq2+LlQTuMjG6GVRh8/hmu+niyvb5synAwrELShxgL0gQndkME02S4V0YZ8fR4Io5EgUUxGoJNtW2B6D5peKQ0bAMozQmVgxL2AfvwehAjzI4iG92Wa7HmfrAHjoqc9lKzeJF3S9qZ783Hf+Bvfl6kH1hhcyyCjcIeejuA0A0LQFTNIXffBZTtRlSO37F38jF0c5W6393SGQZQYoJ9mYdSliaOvgNdx1aKcOaGwK6wqEK56peLdtW2yzIw0AfIzV/w31Acvan9rasO0VzXmk3h6a7EinRyAZOw7/i2lM3umh14Jsxbaezki7GDYgcerMtDMAcC304OpibLOPSq65pexvl003YA5Ffz8TZWSNN9Vwk+jyKmAa7DgAWhGTeTKs9ODEA+TTwVdoLfz1DLiVqsBlob5DhaHnUozn+QzEvl9fp+/Vr2N0B+gJzMy4TK+g/380i4RLOXKRDY5VExYXfr2zXYOVPnIAiNXWnzPygEDvDVarbs0G8J4KzwvhDMRqozIeBgC8ofOH9wZsuxtwarMjD5QATgFAm7YLMUl3ufYUgRDdZHnJRk/m9Bm7ugeMEU0mvw2k6qOhzWejxAI2r5AQ8B81vZ3v5QnFYtnl9Mp3J2sVWlNgJoOC01l+S9yExbbvbR5Do314R7IA69lULZ4Al8bq/0W2o0ApFQmTJiwpwMMBh5IOVMm4gcJmezHYfQvYf5u+VT+qX9LPgeGX6xv11/VGvLtGzwMYyPdF7eiDa807WgDIwMibJCnMS45lRmjh08P6XLQOANNV93AAiCYEAADqhSqwv9sMAO4EtVThO+E1BXqrD6XYKNRB841H/KQjqYDgbR0AvKG8ghn2Oy+FAKASZ9+Bd6Zj70jvk7Pn47+xB4SAd2t2fgcAfoWjN+KT/XgeeIrB27b1jcDKZgpVu6jHRdM2EEm9fwIYwadnMi0k2vaZibVd4X1MvwmViWrfrVHR/pzLdF/J2Kuh9p9Dy38qq9+aujt5tjlnJsEhyAr66ayk72edvWLa8UV1KGZ2X6E1DZaw1o/EUQzRQ1nWq5YNPAxIOFKA1AJYCRngev01fYd+Xu/QNwAM1gMEzsK+WM/Sg3GO/mz8Lb+UerQAMJg2ACsDZYUkucNGArawAUSZhqVNhW5+0gwAHHtLeCTgQ24j7Dsm4OII+gLSMI4HAQA/1nizOU1vm7oDS0GQ4dausUOFp51Np7Lz+iHuJrzU3Xr73WdPsfYRCNCmsqAZQgkOmo69DKzRUb+ql7I/bgzZ32v7E8ewSVamLWURa1xPa9oXAIwmm8o1P4+d7Ex9nHiyt/j141gxQJpvxNADErA1/bMJZ9JlR7oDTdHjsW7PtSJ6BU2DZbZCkNQLlsKbvfG3C6UAowg4uzB1Z32RvlvfrG/Buv+G/p6+XZ9NgX+MHoFHI4GjlH2Ho3SbE38PbQQM355yUUZzHS4UWLvvCPtvoqLfv02Vrl5wAMAK/wYA3vLYUuVSLrzb4QDgwK17M7XDAEAapAIHAJQqZJzKbnWoatdDLQC4jx0AZKiX1eVfegCoDN9dz0rQ6rewavn0bP17/RD7DDlNsUXAS2HSiKytCexQK0WjPVIp9mXuN7XDHcSYa3ezIaaI8EHm8qWRtRNsJ700RgrEhhpmmVJiXnwid1cM9h8DZjVlvGdjtR7GXMoKWhVqWTijM0FAagL2pBRQTUWgJGQQFDWhN/s0XqAv11fov+jX2bZtCHsN9GDefSlbbcSbdfoLAADFHMY2AsDFYCzZ4tUdwryRn3EG5x/ym/KN03DUB24HAK7Ef/8ziU/pdETGHjkA3BxGg8FWACCS7lMBgP9ZOmvt/JVqEz4RAPhPq0cc8ZYbJip9ebZIlXqIRNFH4/R2rGBnQ1S9Wr+pf0zjTgyTTKUDrzSLME04i1nbrjs+DxUak/17OLvZXcf9zt517Y9kUnCaTQr2U/CPsz19M0xF/f3QcN9VH7tsVmQ8gW0ohPcVTNCV0pjj2SSkB0t/dbCNwxuZvdeJsX/dWFWwjubASvoEDAxUQ8ifBwDYqHdBEdipz4QCNU73pYGxgpKEsH+ahGB/hGsYfMwB4H71box2vwvWPsxIgZlS1e3QpmWm4tVlrndd/0swZsSL8U7EIQx4qeoCURbjze/vVt9iRelPZVQT/1tvagk1BwAfvuPF34N1q+4cpmo415eiyjhPc/Bdp8XobvYbNruED6c2yw0Rut6OI9z49P1jo5Z+OQFgaIuSYM0AIEYvBOkuhvD6V/2uHkghP9ZCQCkE4050kjWCoGezYGY35qB5w1pPWTBwtcO9vSekGctmHfH0ZESyWlAMTZzR4S2rdygb8ioyQQpW6PP0VLBqP9xRfz1Sj9KD2NCzE8OLKvC3zkYBNBIERA6oY2GQOmYAmjoCZYCNkTjPAr1BXwdJaoWeRhipxWcFdClmslpvtHZtPXrVrRUAkO2/bfr2TNUE2g/IG+5firUkzth0uh5O3RJ3sCesq4SNwb/NZcKBmwMAxrqNaeYtt/DWYLubsfW+AzweQ8N8IH2PrV3qxpOkUebn3faEhQI/mgrxf49eot+GOCyW8fiwttP1DKIZCvboBrLvyRDUBmaDR7NVVSxTcnz0CIMonmuHe6l2qh+7wlNUW3dNvdjUL0daXnezmn53dv6rZ9nwWob7lLJyQKXtGdiJfYO64sgeAAkp7dGFCsI4VhYU0BgKxr8AqsQMqBX9GHlQiHcr2YrTb+wtXxwAHAFdF+hzTYNvaY77y2jGRrJkjAMAG5UpxRKuPOAOxuCe89mrGJ9ObXldhJaF9v/xPEfDFz7zh17YjmobqK6AdvHlB4ABwOrXh+gb9AtA+OtoH09k6ep4mtBi6API13P0ANbILSbLJ9JKIM/pzMj3MeCG5ajfOOISF0e/pagVYfsg+668btnhcbo9ao/ILZL+Kkwt+r20Bqti+k61tfEXcZWvYAJwR3YSEKjoBQAYwDoBfaE2zNez2GZEXJHSXGMO1InhrLeXyrahZRivJKol+M1eJwIAuHAv23G36lnM/DsSTSDzTQlgB/efuMMB4Ey1Q1zEpbjTIRIH8leOXlnL63L9HO/XhgDgW/gvcBTXeRGUjsNv+fiVzo5PgldfeuzI6lX1zlcAAM6WyTtHP6ovgx7cneWhkm2GeLzVpwUA+oG8O4AMUm09+2RG2SXy+CQLGT4TlnpywOaWDFyrH4zbg2zdw9bsq2NXYMksKCYAVNIvYGQAsQMY9h8KdpA6QcOg8a+HAiAVesowQr3ZbLwTW4GlsfBYEb0P0cfKbXoMAECE92kAKSeEKM8GfwMAwuMBHQB4QkJ/sgBl0jvYow8oTms394HS1qG6A7dtO7QbsLWtr2ot8eqoLOW1lASmfSkBoAQCmssAgEtvge6/VW8DERtTWhKZuqmHjfSvmwICL+bKL+FBcSzCmcL8umxWmhUZQJKNTxIAyFINLtxBJ9vzp5E1/8roBDSVgU0koKn3I/mDjZQV+oHFh2MsJOVnEp7n64VY93vgyG541LFUZwUjBDPxN0BrCoNuu5woAOCiuJ4BoDIQEE9bj1u7Xm2WBfoiVKl5rhdd/4rAKElC1ATcZax2fYxP1rU4699ATYvwyYvWx3D0AFDTak3oQ21xuAZ97MOBJlJXOjk3f4vq8C2POF86AdyrX9IXgZAzWTgjya7pZlU3feyysBb2BlkbUT+Ja38aM+xLGWibTgigTXkrzuo5ocfFa0bGDUY3Bj6p+duRCb7FLA6aw7jBfBvyU8pUoA5MAx4I9h+H1fBKvBoNfX8WIGAtoKAbRP8GllzJt2a/AOMPxI+iPlYfHnYm2rZ9iHMdHQB8zfWh+o9YTBZIMzmbzRdtZDdzdmf/kbrItCKVmZ9Ab4mtJnUTxs/sUi8oGs9v4jGPEYmVxwgAfNiPbPPgGg4JAJ0/l3ba84CQxJNpk6kafoi7HiqGswb9LCSAevrQ01heI4VNLJOsCiB7Fcg6AWyRYptbx+K/XNvwModFNbMZKhznVBsYfEKz/yL1uBTniLLV9WuY519H3T/Xdhk2fYVNz4BSVv4zTcK7sJPeJD1RzwXzzwQErNXP6T36AjyPwPlS2f0vxoZQef/hehy/VX/Mrn04mP/oAEC2gJcuvSpabdxNXYRF3rXs76WfJ5bhXwOxN+ghuPME+lbE2BvNToTupzzDI58u0OoZ+Y7EVaqFpLhNFgC8qtPnvMbbj7je4GFVgKe+cgUID5co8kkyiPoh/W/G0KXajPl0SgDiVPOH1v88knREKDIwlipAgKE3OYy1z6W1O8ZpTHUiA4DfbYNTvLjqKvbZM17/coYSO+xvev6UMiyohBBQw+7CI/RkvUiv0Euh/89jj93LMIY36EugWQ+wgUjGReo+9uGpR68CEAAUS6r0xp1HO41jDZ2EAMB0Lo5g3YWutiNSkqk9hD2XRVMkzqIBz3GSXUoASGqSH1ZYCfPx4zavhwWAKercIzjdeJV2svN/rJPPf1AASAG2/0l/ZDvWJTNbLtmG0MRTp4+2EYGR7DnkDQOAVGv+y2FlnDRmC4TyBO5RW7iPOGEBYKjaIu3FpMVXGQFAQnxzbAFxBwJMY3FTPlR6AUub0HF6k16jl+vFUJnmQQ44Q5+t79ff14/rr0NFEI+/j6Kyaz/o7VinTJ2rbjkGABCL89wploCeuL+IkBSA+dqET7i79ns443E25yHACMoIif48Vz3kCw/jvR/vxOEb99i0YNYaVns4/1ep1ywltL7NPegnh9+WqEv4PMSeI5dXvgn/eY/FUH8J4gAiOGkHBwDXJwl6m9b6F7ZwhnEAplCXlyiAOAbSRIWxv8dW44+1XgI5IpPJs0H6B9wMCnIak7WpVHV7WEYEALYo3lWObZFVxAzBbFtH0LECFITi/cuoAnTG+n+GvlpP1efoJWT/OXoh1v5v6Z/pGwEI/TEOCRYAvqAU1cHHAACMbQvzkwnVL8ppHdesBLtrv5tZE5IqLQHVUbwnt/ECLE6xoUCxAglzrAo+3W/Nii72HuprC6DbGsmtb8eiOWjzgiB7DlrqroUm6FFf9u1Tu7e2YaASMTW/BgAMJ/sm04wXb2vE+xgEFBNi/0gbT28AIIaegFjbkcY06nRz4ptiAz22IQmIS4JCw/f23H5maxlcqj71Mm2oFutgNS34FWD6DNvAM9u2/DLR/jW2GJg0TV2tbwXDnwMlQBSABZAFNuibAQtbAQX9aSWJMHf9yQlNGxM8+00kfyFn1m3BG+9dpL6PqwfdGM+OA/0pxpsh/SqXrMA4DAA0GOY2dSIUOw2Zxm0mVTsJoyZwEEMTozlGbSQFfAp4/JR/m9cieJmfuo/ivp7EWdsUdPW+ekl9lbc9JnbuYf0/PdE210pkUI/fMr/P9gd2EmkiQ68iqBiY/zxW2/XaspIeS0gGFiKagoSb9t+dKEMglZLFVi9uwA5g7i6M388NVQYspOAvycLVFgAaMFZX6p3Q+M/XywAA8wAAS/D6Rtb9nw2tOolQeFL0vb/GrPv9MeORttSLOzwOoKdR+NwWHOJM/QAy93qMQ43pIBSqDnjgbgqMuWy6cjLlqijHRiQ+BisBeMNK0oSlAx/N9snBASBe9bflk96HdtL/COKGvKrDlwoArlDPqP2nYf2/HYRvLABG8BcA8FPzd/IBo7gKRFgJIMKW5DbM7bHFpE3UYGTITBhJqYC6sAUKRz1Qf2mmXAUxC/0P2dHui9u+F4F7DoLFpdBnZ5YXK7RGwDyrFlTTQ1DLukNSH3CU3oz9ejD9Sn2mXqQX67X6cihSK/VGvD+AFgCQ32sY3bZsPQ8Rgf9Fb0vUM+5/K4jqDSZhykKAZWcAgAMJRqrLDYUOFevu+FuIUbGr9jPWi4DzJNtGZdGgqAibi+EGnKaw7XwAY5pi+hjs47z///a+BDzK6zr7zoxGu0b7jja0SyxCyCxmRyCQ2M1qFoEBg1nMZgwY4+ClJthZTBL/JPbfuq7rxO7jNH+an5D8+Ynrv+4f166L7cZxU2dpmsePk9qpk7ht2oeHcPue994ZzUijZcSANOI73yMxyzeDvvvd895zzj3nPU/is4HDdcll3JGH+d7Uq7ACXlQ7w781KeCX/oZ//OMD/lKfOjfSjADXpVP6h/oeTADj/acx8cek/iTz5pkIQIKFgLjAGu+2ym8CgkmklMxghkAwiUgySUZchBDBfvM/AOf/MOiP8LerGgqJkyy3fJKCCOmXafhRQvUvJwCYxl+NFgCaYCsshfJ/SZ/Vh+Hx74DRLyBwn75fH9Hb9Fq9AlM8XkeQn/6B+uGQToE3pZBqBjz2eAsBKsgCCF7PE/3sgyQTm48zV2LM+HyL0JPNAWxKaXYmG7W5CQZetmjJwHsP6dUskZbqzErSruWa/yt0i5qcRGn+//On1+KC/QAgjScjcwFGGgBckL5Bz+mv6g5M9jRb+JPM1T/ZwoDfEkgM7AN4AyAQZ5n5k21KkNk6FCBJtT1781mi67NdfKUSvxH/Yw2bldqJVj4MxmGuIk1IFTcEJwMMa+2mnwn7jWFpcDP7AYkLMEffojdjOm+Fwb8ZILAdMPAAbIDbcbQBALyGp65/2SdOgmuoAUDmtVVpUWDXhbDntASAIJvPbRAwzUQFtoSc+053V8BD+68CI7kTMPkyxriGW80COUJFoy7aT9qzG9mwJOQo4r5SlC7XuADj8O+kiPYEvjXCXIALLtyC8/pRvV4votoaAEgLcgPSbBTAv67HW0fA30IihWdk2wyCTJtE7GP0wEcq7hzW56facqEq5tXlWDDBxPje8ACAJHYCKiN/71QouXQAmGRTg0wPgUk2W/AmNvfeAXXZojfqTYCB27Hy36v3wQXYBuugRVbRCAAgQgvgLEzbR6N8/XGGaD0e1wan7qOAQe5WY9V27pa8SAB4gWb5N/nePzZYUvBkvwsg0op/l6jJakVXFAC/X+Xn5rpspCgbrtLnYHU+CPhcyCCs62O3+R9pLQp3El2AD9lRiZ8dBAD06gIM3lT6WKmRBgBufUg/AS/2G/ADffReRaV99iedipscxA3ktb6/17blMmdkM4kol4lBucR2H4OJGQywZdndBXl1PFNtc6yrIOVEwwMAEkkXXom/TxqAzMRozGQnIOEDnoAVS0jETbnwTXhnCVS/FS7AZgDAZqr+nTCH78Q4tmH6qogsgAgB4DV85jtRH4HFKrB77w51AU7h3W9DEVtI5y3ykb8fQICMtCvgud6WA+f41Z+NQ/yJQJY1wstYwA79Lf1d/Wl9EuOZQ4YGH/mmhGLFYzkBS7pa10UOADraQDnUm1fXBABcWPu/rV/QP4U5W0YA8LHCL93+9lkbINmG9+LthqCXG4FpVP8cS72VSzY+02Izk5/PZaMN06bT5BjeRNJNYewVwq5aqZG/rP5kqAMhyiuMQqXw8ltJfTJbt2Ntkpq+ZtYJSkfgubYPz0QAw3Ks+4uh8Lfr2zBud+m74QYshx21ERZDiekE2J+Mx3X/nmoT2bx6TXmvweY1RsAeNvuPyn1ZXXb93m7Uycba77ltl2famgX1jfLiDkom4GX1ZTx2q+/bbTg5JqmMAAAkKmsDyO5QJiDzWaj//9Rn9Rm4UF7mHqYYQHmS24DvYZZdsdvYroiv2/y9Q5KGdiiWEo7jsW59qP8FK98sIHA6jfZM5gNmEgZ8gcBggs0ISGBEwDTcSKPK5wfaapaxuZbh4RNegTIm1ZiG26ZsaCZ86GagvBCK1JsOBINlX3o9isOA6yuF4T8LRvxN7BmwXq/SC6j27WwPvhTe/RKs8EIcshoG7Keh/HvxaI8+DijYBLdgPdyEatN5uX8AECX6vH1cF9F8uRYWQPC3c8NuPO5gKcAwhzv73i6rYLm1AM5iPe56VWIA3UOIPVOBAxuDHtKymbTyeIDqKYkknAnz14xWNnvANdDeB8FypO/PrArb97y7JDO5sCViADg2yK6v118w7UV2Yf2q5K54HjvO54bUA6bYUGACA3rGIvDZjvLltq1mCX+queFjIsHZ3EkfTRbBCtoGtay3q6dpLQy7VXrw9GuuO6M4Cqc9/5yL1X0uVHkOVHwmVvYNWKPaofLLLFvgWvj9M6Hkq/Bsu34Uv4X9bxVWsYM4+zQ+W0aFcQ8EAIrgWftLzHIjSoY93Q9951WOgzncp104PM+W4I4VYBQm4t5KMo96Rv3OJ6b8K+otvx0A9XzBdyzBsAIGuwUGABICfXsDPEweu4PkekWddv0kWT+GsfX8tT8FmYepKMxS33TbiJMldjsWQXq+dLP8MT8TVr6hMgfwJeRPj7Ac+FBQtDQGAMCtjwEA3mEngGya5jlc0433nhmgBjNxgESG/sxh7IRi23ZrFPvUCQdeJim5ZcWvs5x5Js22hHH2ClJljoeaTZVwzzDhX3S9KPThM6Dabfg9A779Zr3OKv8qPNqIYzkTgXfjnfWk/TquHwEwHMazw/ozuMZRvP4B7wIMf5lulDaeprmpEhFu41wShDTRsktiJmgqHbv0cBZAiHXhBw1jBRD4ziuM6jO207Dqngi0xZ9XaDJL8U5kHAHnercBWtT/sn1GwweGzpNMKjwAxOHdU70DAC/l/6ovxsRN7lBPjaINsBtrWD4Dd/k023MDuYE+S/pl6gJT7C6B8f7lrHJSZowiBEg1XQY+V8RwoLTtlDi68OyYTnujuRNQQa6dsRID6GB7yqGW83G/Er90CiP77bACNsDPFzdgjb4V6i9lvythrM7Gmn8vIGGt3gKlf1Tfj99n9Qv6C3oHnKgqkoCmhAOAU+p8wBS+H48ej4m5kcXC3qDD9Uqqze0TYEjf5O4Q6s84hlBZ+Rh8dkWPmWaOLwcSjn6CkdilOuLgaN2DhUOZBCE53sQ7wv07yn7G2ho9ACDBlgP1Ji38bC/SVyqwJKfs6BUA4oOLJsJZAPxj344RnD/i1d8EAPwGK1oRu+cWMRk2j0a8IQj1U4SasJ95xXDx59uG25VQ/GI+ko48WbYzr+HNrYKq17HWrtHurxfa9SRuuERLtIfMPROg+BLbXwIV3w4l38B2Kato9i/G6r8Xz47BErhD79f3YdLuwyvSVOQJAIAwCU9mnpu7JwBcCFqJzqmr6Q48tPJ1v5FfLJZOMV7Z6oaDUKZV/70BVQAAg9d6dgZKwcg1YT64TV6BOUpCrQdxLQEcY7q56P1bW7r3SGx9yPPtOLUzgFZCblTeyycn4b2+13f59AsxclM3q4ve32hrBczGQJdzpS6hiZdrqcHSSP9ZQRtB6gZzqeCFzJorYv68AQCz6ZfN4F8lPP0ZWFUlmbYB1kA9b7Npw52m3T/DGBUNm1F4USbyfhj1d7DGb6e+C+p9O9f+TryyB8/uhvLvxPsb8UxyAO/EK5sABAIPa+A6TGWztSp2UmYmoEs1B6WaS2lQPl5JVy+r54L+5/JAIsz1koYAdWfPeTswu3U1Z/hF1w/cv3LxUTcLuRnHl6nGv+Pj5hB+4BdthsAfczQkDGq+46L3oqsrjag9aLX3mu+Iv5h8Uf2ltbMvuv7DVgMWdfv+7tc0QAsgGAD6lktqpMk5bWUXVsEKtrMoJ8VHvt0O9DFPwIQIc+jtl1HhC1g2W2JjAKNIJ5Zh9wYqYRZLT7wm5taJb90KFSlhWy7vQMf6ugFAPP7WI/ox/aD+BNT7EAFgBxS8E3CwVR+F6X9Mn4TSb9fbMErbAQDH4AC0ATQ7AHIdgI8mwKa0Hi8Ub5XtqrzBhCCXbGR68ZBfa/TIbqvCsvbkdJWEBx0hABDnTyvu6AFO1uN3BacCF6lw3Shfd3WVAw+i9PqTuB3BIqTIA6Mv+szIA4DTFgC2YVpP1cvIjTOKNCGZAYrwDJYLlZIGtIK8d4U09U1LbVNJX8JtRBNHKIdKzIfaT6AFMA/r5HSqh8TKXcMLAA6od5P1aij/I/oz+rQ+ACg4rA8SACQqsAvPjmC9P45/dwIQbgMA7MYrC6H6R3ULrnMGi4mrcN3CjmgtADcM2h/FC4l2KWfNAdc3RhwAvIqra+gJAC7LCuDR/uh/dwDAGP0tNK77ZwssNbkcXbTg6faVULlLfYq04A/gncd63FE5KpQjAwOAYv3vBICv6efh276OqV/I/L4ujgB/MDCHqt7AqLdR+3LG/kuo/qO4hZhrnYM6bp1NJ93WBPjP4/C+ZAkQ/YcTAOAvqoHP/yDU/wv6Iaj5Maj7ASh+JwBgC9b9XXAHdsNF2IdjN1Z/YQHagVV/Nh43AwJWATZr7Tjkin1jG1baddDQVJFWY4QBQM9aAGYCmmKxVMwfUwngCQEA2d1P0lfBBdQlvTUGMfZFt7EO4gT0fMPbWzHQz29ICPjYB+UPlbNYsycEyMFMEDCNW39i+jexfk4IsGvJm1eD6V9OYpF8/NuAd+fi/UV6jp6mx8D0b4cDUM3mYqmh1YDDQPLZ9eBu/SkcnwQM3A8QvIusf5v1BjL/boVtJP6/AIG0/b4b50+GVbOGJUANpMyeh6sTdqF82bU+HjIZBQAupQIwpsrKlz4C548/8/8O9Y4Y8NJGPg9wWMCcke4WgJu9pMK6AJHI6wNOu1ZT2VpweVAagc/9W3XZ5W86mB90btaA/4BfhRytSjK8fmU3Jn6kXo4tAMjElH67GwS8D4UoDLIA0m3BTw2dAFM5V0neXNnUq2IMIBe/K9lLZyneb4daTGVjjdk8exLOSB52AFAB9b2FZv6DVP+TUPD9VPRO2C234mc7jtvI/7eF5T87cFUr9Fq9HI/24lrn6ptxfY3sKSC74yEAkEtK8EvT9AmAYPzIAYC3YcSvN7PfxeTwZCEWv+yxLmMueaKT/AwDIRaA5P5zK/C3tmvjYAHgEj5/sP+o5yo2F54m91pJI6kGlQbv5Z3AMZD8Ijc9uZ5mhv9YiFeW4LsepV/zivqLmLqZr6mf5OsO3V3ewaQusG5AOsN7OVzjR8Pgb7ZcwiVQcKmWq6T/K+k/UjfXCp96NqmkZzH3bx6bcE7HOUnXFgDiI9xbSFENNVDkh2H279P3Yu0/ikeHoNbS8KOTeQC3QuW3WwJQYQGU7j8LABkrAQOdeL6CnQOleWgzU2Kw5h0PmX/Sgv1SM9yJdmHRSQ96J5YrTF7C+rvVzH6TQJbDnfw49kJKYw5JYlcz0YZgAPCSXSChT8bK/gHAMhT1y70Q3LDyNfwcxiuRc/335APoCQCSn34oRsnHm2SvtafMx9pWwECgKfAptkW+UuqTQ07gKjbJbCZ9llQEiCrMZNCvjXV1NzEZaKlejGcVNAqvKQBURcgnP1fhGmZi/b8bBv4+mP77YfzvxeM7oPSSCbAOP7fRAtiCxxvYDbAV1zgNP9IvqJ0VDrNwfTNwnQWY9nHdXQDms42CndAACyEIAHSI7RmLstXUEZZgSZDlwNDFJZIgJp31Igl+9ofLwQDgIWWM7Zk0aADINl0o+gOAKHWs9YVUOXf94Vd6sqHF7O3cJyQPE7HW/U0AAP5Tv6VfgDqb1J0cTGFJ75WUoWRWDybjRzYAa+H1tzDnbxpbZy6Byk+FaozH6j+dyjGB+wF5EiIbZgAwRq+Cgu+Egouvf3vg2Iq1fy38/LVQ+U1QfWEAXgAln4N1fxkUfy6utoCdAPIAbXlsCRLXtSq5zWwx7VLSAIftzHfr1QWIvehTld/fb2SVRy1mQjpHI5V2Yi4zRX2WGi6YLdBUBJbjU95QQpB3Ivr/k+P8W6495YiyrETSuPAD6QNzleKFv8PD1an8mU9i1tyqHggDAE+qR2IQAGp5hb/1QV1D5Rfc/stj3l8ps97zbM+gZBp8dVj3J8JWaIXKS/X8fCjKYqq8dNVtw+OpsAQkVdbXnRIs2pIWIcseAGAh8/m24NiMdX4bPX4h/NwMAFgDV2YNVv6VMOAl+Ue2/NpxzgGcvYSZDQWsjcwkARrV/y2MYaMyXe4xAWtpQU3B2dPERP4UZlJ4WR4Tc6QE1/UVy9dXFc/NvmQSqggIjOYuURFGI9c6BXm2vjQt4Ay4WA2YjNdrMT8qDQC04ztl7gUX8OYFmo33JnHQsvAA8BX1hr/uwCBLNBtWSiqwMV5m8/n0MADwUcykAveUD+QmHeoGAV/Ve6DCZbb0V3b+/fUBAgBS59eKYwFUfywm+0xW1Us9/RwAQAdelV0A4R5mb5nhFAQEACyFyb8DSr2ZHv1W0n1vweNNtACkDdhy+PliCawCWMzFtazQR/RBuAnrMSbSIScpiNs2EJnmZE8hsejNGJl2nOsZDtuAVydjeI3rDAAkkP47gQ3iqnClsjVcya1QP0+UYYowXSP8dQRxLCgXBobpAFQCwIEwdvPoACFI77LQ0+s2YCr+GtodIQDQpN7j4W9dtUUt6fbRV4OCHOFztl1AQXOYBgQJgef+KfCe+r26xP9nWQze4iK5lnT9rW4A8CRAoY4JwiWkzpSQXwqJQTKYDiTRgpuZ+juRPXelj65U0M+FMi3D67JLQBP5pxHstFwXAJgHxT6gd+Pv3EQIECtgK5+tg9pLqu8tDAV2ANhW4195/aA+qe/TJ9gAXKwgq/6LMHb+kHKpvJIOxV+M79oB+KiTs2IdALyc6cLi/HfqF4Y2Xjb1csmraKhUy+gYmUhRFqEgn41SvbYUWFiBsjCHpmCW1BkASA3J/fev7z3nyXepVUEAoGQn4b0wdsrDCSbhrBsAdO9Ws7dP52Bg5cDTA0HAliAr4O3Yvs9xMHiD5T/1n2La38xc/nyG/wxtqJQHFzAPbhx/pP5vAm7sPKyaojhTgfJLYA80wAHIN7fk3eF3rY1Q7k7YOBIB2Muc/x3s/Lea17CCEX+xBFZzS3AvoPAejM9ivF5OlgR3b3Gf2W589zzAy2N6snEQFoddrzaGPH9X/XKYWwBcySWWb5LEc8j/K85hNbdCi5kMnk96mGxCQJ7dQUokp4RPS+7FFMyK0V0FQL3L+0GPs7qf6ToVtgvTkUC0DobEt3oFgHl9UoMODABq8D88rQ7Bmqjgo6dHAgAoTPnvhUDAczCRZ/HmZrP9leEHkBCXhACb2CZc0oGqWe/fDMXfxA2zVijOHLIBNUn32D/rIwOsHGO4ZQjsg6fzfjGPKT/79V1Y1+8DFOyiU7ASyr8CUOY/VlL9hQVQsgLa9CJcf0K4PHVjKW5Rp11QhTZYCp8TurDvY26Elj+vUyukTXkoALhOq88Nu/nQyHuzRd1rfGvDCZ1Kb98QvhXZutBKNlUr5vMiNkrPtT+SLJ5BShkBAKkNacF8yrZtSfjtXXGQNWpl4PGZbgCwJXDMxyunXFJY1F06rC7SjZjZKwD0LZEQgnw7aBKMCADoYN9Av/xaP4jVcQYz3TIDAJBEa6CAvPkVLCAqhVFnmmjMwArZhm9ZDKN5GtR/GX7Ha1XYx//JfnVDwRDgebGenP93QFUfwPp+gFGBzVB48f5XkhpkCX6vYzqwOAcLmP8/CaZsYm8A4DZBwBJ8XpKLU8IRVZIUNLG7BTAc5VAX1aeXhLDZ1rgv4HpfREaIciwC5XQEykn9UsKMEakekR2kIvJHGe7pLLwjO0Rltro0RXfbBXivl74AWcoUk3XFW071v+82OAB4WD2htqqzFgCS1P4+z16Ac82/TwUA4CkeGbEJALOhBl3yM303vPwxzAJID7QNTYPfV8wOutXMhC9mS+06NtmYAgO5HQCwDBbAFDoHNIH7AoByjOHWIWFTelHYABboo1D/o/oIy372kPt/A5R+NdR/Ka5jBZ6thTovxcpvLJ5iWgBxvQKAhxuns/BNO8RN6AEAhR+UCyvwVlU5rOeCzOJX5WqSuH6nBxrJF1D1ixgRKue997dUqWOKeBV7LRWSITILnxB4SGdWqSSUV7DsPIu5JVVGoX9tdeYp9R/q4wD92WeD/pYEtdXFRiY22vaUOmk1L+oAYIomVlkAGGhjkENBMQDzqDg2AUDorrrkn/QpthDJZU2g2QFIIPGn1AOUWrOvhGwC4gRMxOq4lvkA8ruFG4eqPwAYOnnRhWk8A+v+J3Cc1g8BAg4SAjZyH2AluYFkV2ARC5wmk96snDveacx2DwcAkvKaD1toNkBkbfiGlUPfGGRAc8Gk+6Sw2HWKl18AABH1SURBVMmY+mWWEaKQNaGjGAIsYyvxKnZTkgKwMUyOHk2+yGzyRJRYqhnJKingN5XaAvPCMN0FA7sA73f/e1yYgzn+UquBdmFSz/X4osjlBL7jZ8QhSTjNwW9X2PPeUS/jvffhpRSpX6ofB16PmcyvJBitZ/SHAQD4HzDYypjsIlmBqQELwMdq/3IyBJSxk3wDg4DNOH8pvOjVUJkcNszGzfoII5I3bC/5cgHM+0f1k/qTuPYj8PMlKCjVAGsZ+++EC7QRVkIbsxzGYf3KpfJLmZQ3GADm4Cpl0XC7sQaOx/mr6Trh1RMxuRQoDz1+Mfvr9c2kTa0mZ0Q19/yFEaKcq3k1G8VXQ+3Hk/h1Epuu1tkiMZNNmm7ThE2SUK79hmImlsVrz7vQl6OWE7CvbcD7MZr+g2NtH183mUej7yU2UOg9WqosffKPgzybGJE8TPc/1f8aAIA/Ym1Xjq0OTA0EAdOp9mVcFarYXW8cVv8pzItvYz7A6C5EXzOcr9h1eRRM/DP6BEuB7oQ1sJuBQPH41wIANsAKWAGnZjnX8zqmRqUy9VWmbngXwIfpPQmfW4YpHrvhIDczGXNwh4twjyWzcyzvc41tojqaPn851/4a7gLdxC3hqQC+SXhFVv0M23rWcEpmciZlM39AqFSzuasUaEzSPwAMuYxlp5JP4HdvvcxLeMY+/H4+KIp5Fj9lNo3CRIFrh+cFVmKSP6d/EwCAOTB7jSGXbnsFGJpwaQ1WahkA5ZiFGz8JN34aIKCWt1X9FcdAjqnDep5fLtE79cNQ/z1s+rmTycBbyBDcyU6Aq+HQbNLb8f5+XKmkuyQxqTU51AIIAoAkqIy0FVkqScAxKy4m7haQ9r2CER7pmjQOK305jX45ymkRSAB4jE0AkzkwkWlBEgFIsdvG8jvd9pHMJQBUc2mRMzKYLwgA+AL0Ihm24i41ImV9yH7BgeH5R27SX9RvBMUAOjCNTQDQZ/sIGgBIwq0spC/XAJWfhtVhLdRkBiZGIFK7NEbuy+U8KPxxMgFt07eRHlQIQaTnz1bAQSf3BA7oQ+wZsAArWx4BwMtG6eEBIJ6BrzxAYkqMA0AuPfU6tkudoFsIAGNI+lpNPmQJ99Vy/6cBhzRSH0c3ochGjZJsV4kkbgJmkDs6lwxKjRihOlpT2XiU66+mKBmZyh8zLkBTyCbgqzDma23hS5rF8QTbICzPTo7xUHtJlOnAejemt62xYQ0AqQCv+/QnaO6vZRKQ1AGswTVJH+CDOPbpXQCAI/ohWAaTumLRH/X6nbNVVxlMbMq3TfJuGitBpeBnDEu+mtg6tZZWXw1jAoYAXhK/pkL9pcFqPTtB+hgw9hIq4zlnUllIJpuDsndQQyhpYH1pEXcL3CMYAKJj8L8cJbaBN9Tb6q5eQhgwc4M3AW+xGd4+3r4kZnR5mdOdS8ugnjV/a7BGSpisQG7hxFgDgDiA1xH4/ibr/xZ47itxSC3gDr0brsFJ/YD+JI/P4FkrFMIjTPVjuvFLB0sK3zdHbEq5GiMAIDV+o5jqVc+OyU10AWptMLCeq7+0U5/MRqrTSJBST5p0HxcL0wwkjh2FkxhQzGFq0CjSxtdyO1n2kMr8GfwxBQBJKovHtZWuMtIfqVei8o2/xNr1QLiwr8qar58MAoDfAucNRXh6oEuQ1zYJFcwuoWfYhnXxVtz6JpPemRRjU/0D9fEyfQ8M/sUsAl6iFzH3bx3cAekBfIRMQSf1KQDAp/DKTNa/qxtA4qC0WUz4ETWv4xbfWNK913P9N0cdg4BjWAM6nufUQJmzLCeA2zYEi6MTkMxNwWxmEpTZlKFiwkE94MQbcwBw/HoYea7rxx9fp4DkT1P1/1F/qL+n/5zGmaF6SrLevzHoZCtQdnSLsR5I8GcRAGACbAJX7AGAUjdPYRuwVij6Sr1Qt8MKkFYhe6Hu+wEBB/DzEADg0/pzeqeei+uOvyEAwM31Oh93tZoWQCPUXIz2cez2UMOezzUkRTXWQD0tAikNkjYxqawDdNORiGPxcCL3AjJsF0qTUJTPxGFJI6o3VYMlypEhEwDAcbv2/wVWvnaseyU29GdU3xtoE25KO3KI3S0w/8QKaDS+cQwCgCSYSAhL2oPPAhAsJSn4vbim3QCBQ/oojP8/AQDsweszyGt3Q8wHKK4AQAlTfWq56lfR+2/guj/a5gGW2ozAEm4LFzL8l0aD32Nr893MJkzmq+m2w1SaZZsyyUE1cCXz5fyBAEDygPswuuarzw7XDbfhCAAe/dcWAC7q52ENlOHmpLKQww8AcUwOiSe1g3QCMgnAtVj/bxK1eEIdikG+uyJ1zo1pLP2B58P8lxSe1dwSlF2AvSwU+qL+gX4D8NiO9cr9Bq7yRpDHpIF6HvP9KxgIlKi/bP6ZR6W26j+P63gBiWNyudOfQc6oZEb23dYRSLFRAZ/lmU61Deek8UwZ6zK9A7UABg4A6gRWpDZHswduAfwX1f8HWPFW2m4+xbjVXQDgoflvoro+mogF3MeVLZ8YHutjMtWnQPnXwPxfCvUXVkDZ+5c6wRP6Qf0d/br+B30GXi5WqedvkPnQIurr7/ZQwcqPSqb/VBEIShgHyma5bxb5f7L5O8MWC6fYOSNq7+Z+fzJ5A5PZZdo0nE1jp+mxcKxWm43AqAJAs3oIF+FzNHvgFsA/Qf1/rL8Eb3ga+/nkwr8vZO5fAtd/D5Xfy43AVN7IBBp3bq3+KIbHulC1eP9/NQBgKX9uYQrwRn2nPswNwpP6a/oZ/QRGJfNDXOXoGwcAPOT1Mdt21Sz0Gc3SnjKSwxrlzyb8+7imZzBn1KT/mn2jVOb+uxkB8KcEJVsQSGEWgBSQrYa1lTpQAHAH9V7sU2ZGlRLsBgCAPK7//wfe70asdULmfVA3w0QT3y2evpxxAxJ5qw0RZL6fgSXWx/q8G1N1Ftf+PfoIVv69UH4hDH9EP6ZP6duwStXo65l3PizkkAcqWsBIfQVTfypZ859HRU+zR2ogQyTehvrSbAKwJBOP5uKRYusCJCnIUM36WBsguZWNsDc7eiYCFamrtLbGqs2OVkcCAEm2AvCkTfcogwncgNufzpQOt13941gLkGJvsq2L/yjmx/q8EIWPhxOwSx+A4h+C/38f1vxtLBFeDjgsliv98o0GABIgzacVMJqBv1LGBLK5M+RX+zjtehlmOQ7Pzzw2QGwsAKmLrKFNIM5CKveShE8om+nlEv4znabmSdL0W/iG4F4d2Xh+j6OW1xEA4vS7AIAPsQoKw994vQSGcCNuYTotADdDgB7L7m6iuil+Aqa/ivmrBwCU6zm48juh7gtJBdKKdV9Yge+gHeSKZer3QQOAYtK3ZOsJB7BEAwpIDpPGKH+AEtXfAOSMeZ7E9V68fqkYlLJhM4dMWnAqcwEkYFiKWVZjqwZsMZAj11weont0StV1B4Bk/TwA4Hd6mR7LFN9dQGZJ6zTIHcdKbLf2l4lmmmYYpjZ700gAgGz4/kIAOhGqv1jPZ3MTaX5SpVP+Dtd4fOA16CNCijFHLihu9o5ixl4p08L9rP9k5vUfOfYz8/nsfgkSS3zfDdUfw74BCYEMEkMOlskAciNG+maAC/z/V0mq7si1F9cl/ITrWQ8AOAIA+C7M4DHM8p4BdC6kuW94YA0EeO3qn25oMeVwjYBhOS+trqYA8lrJbtwGG6ARqp9uiKuevgEnSouhAM2hBVDM6n2fDd4l920PpbqZ/JuNszLgSqbZDFJZOBJoA6QQRvJgHyzFSHMh+ZKjmUMrH8ThhvwAAPAVfZAFHZLskUtfLsX6el7u6ZLl/Yr7SuKVuCvqCmyJkSNXPFe8V1xyVcHHqBt0RrSY649nhD9RdxuXvmI+qeqKm4uDWIgFNP69QVmkiUwKFnKwejhdY6V4/Ir64iD/ytns0tWm3L2W6DsyMACQ2Oz3AQFH9X3kdCsnF1BXFUC8ZXgnJdMkZ8BuGPm6pdo+G8FnOvx0MF5W+/uzR7wWAJIIAJV6AVyukkhbg/WQNLYnvQEjNFGTRjU76dcSmX1L/299Rp/V45ngKbleGXb9T7CZAMYCGKmkDY6EkT9QL/E4GMFnpuD8f8ZyccXzknrTRWbBRB4Jlh0gG+o/Re8FAMRdNQAk+PeiZg9zmtVhK19VzN5qYgrwH+sjuoVhn1G0AMwurzkSuiK/jjjSt5y23YHnKmYCptr4QQojSFV6Itb/PbpRXIWrBAB/wnFYAlZH+hfXV2W1z9Hr9F16q16sFzHdo4BpoFkkcyxgmqfYCCkmZ3soAeDQDQ4/M2Ps+ufKgpGI+SP5BPVkVRxPilHZUEyKvDtwOLngMU3DAQM3TLFWNC0AoWmo1bv1Tqj/HOZ5F5EMNIfrfwY3gNJtMIh123uH8K8tVfMcAIghycL9esbD+hGxA9xkGmL6+NfwjhxXzxp5IQGztAwLVLWho3UkMgAQQ380a98WwjNr1BXs75bFSkCvpcCM95tZcjhBQAcAIpH7zbxxWzo1j5lJZ6L2/Rd8UP8WPRkz1+sAQOQAEAcDrUZ36qNsZ13Lpg55tqwz3s9vN1ElBA6XM2hDJm7bnzqWxGPnzSzOpGV4JP9KN+1oyKWcK/m6Sc+k+e9yACBSSYYLkKanwgVYqFfqbXqzngR7QFo7J5LYyTO0Jn94+SjirSlHhl5uDu4BFBVVne0KbDima5cTBByETMz5eynXaNN3kAlvpd6Cx3OAqEXaRT4393AEgAfUozhWOLcvpqRM/T+zI+BhOvlVAoBLHXF/aTo3qN2wWt3OLsCgZJ8EaHJ1q74dq/8O9sLrBAgs1NVdaL3XGSZHoiLHlM7XzbpUV8HpvMp4vVt6BkvHoiQof5KzDThYABA8TtOrcLTr1YCAw4CAqWzibPP+XlblzjA5EhWpUou9r9ezzCz/agHgXCpm6Qq9xIQWV6jF4ajav64+Vn/pjHtfACB9but0h14E019AYDp5XYXqCzfoX1S6SnYGyZEoynmPLjadlQYHAPOg0zjWwU6dZbpRLMMsDR+Ydn0Hk/g1Z8x7kSTVpB4RT3+Mnq83sLF3q+3/Kmw/6h/UBWeQHImyPK7edL2pzDEYw3+PUJW1wU5t1Cn/5pFvmdz76d9RDgD0Lk3i4UuqbyPpMGcABqQOvph9fwv1QNnXHHHkuklyDt3V9Xqy1BG81N/pu9Xne2uE5YgAgJA+FbK5x2ZWwk+DO1CmS7VPPCsHAKIjS1S8MwhRkXWewwu5WE2BneoaAAA40q8FkAp1v0nPhvnfzB7wRbrG3wDTAYDoyLmgFm+OXI28nocZOkm3AwDSZIY6AHB1ACC03qP0Tnj+nXqBnqAbdC0cgByTULndGaB+5bOegYSyzimzn/J5Z8CuFgAUK1IlMV1dcYYjKhbABL0D3v8SmFWtuk3P0+N1Jvu4eD926qv7lTR3vsrv96wMlc8jzRmwq5QsVc7F6RRGM6/Xsz5wBmrAAODRJXAAVun9eoNu0XNxjCPhd5KkADsuwFCJR9XhyHIGopuUq/Hqhzh29nnWD52BGiAAeNmbZTHW/g16NQBgCvcA0tjOyYkBDKFkMAZz2BmIHi7A75xBiCIAeODvj9Mn9Ew9Df5/Mds3+GTtf8YZnKEGgHShy3RKryOVc041YAQAIDnUrXoTDP9KAEG1LuK0c3UHgM3qWVXqDNd1tgA28shxBsPKBszCZ9VT/Zw1B2PmyMABIF6X6216hl6mp+oS2gA0PkMB4HG8Ms4ZrusMAI6EymdJNO64ANEEAKWFTGmKLoMFUM3of6Kof5nK7g4Arl+4fm4O9XN8zpFrK27cA0dCJRNjUjagDsKODBwAXDD5pU+bsABLFwASgHSXx5Wfa8UJTA2FtGHcTzjDYGWhcnh/oiRlMPVf8+osKH8ubAGXTiIPkOpU00PO68R5/qNjUP+TD9/R6eQVDEo61aMJDgB0yTg7Ex2JiuxzwwbIAwiUsIFDCtwAFf1dgBpaD53OcA9CjOXlAIAj10Qa1etupv6k4ScTUJAjvV9/pP4wcNwRDQCQ9M2ClzzyfddTmkcAifh2HhNusHn5aUc1r5cUYX2uEc9KGNvzcPhIBu65l6/XqMIo/B/x9rvkePc63txUlenc4JiU950huL5S5+dqdfk7AF6rYiCtnnWG25FrCQD/DWZFYB6YFO15AAAAAElFTkSuQmCC\n", 62 | "text/plain": [ 63 | "" 64 | ] 65 | }, 66 | "execution_count": 5, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "# Generate a URL that displays a global DEM\n", 73 | "url = ee.Image(\"USGS/SRTMGL1_003\").getThumbUrl({'min':0, 'max':3000})\n", 74 | "# Display the image in the notebook.\n", 75 | "Image(url=url, embed=True, format='png')" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [] 84 | } 85 | ], 86 | "metadata": { 87 | "anaconda-cloud": {}, 88 | "kernelspec": { 89 | "display_name": "Python [default]", 90 | "language": "python", 91 | "name": "python3" 92 | }, 93 | "language_info": { 94 | "codemirror_mode": { 95 | "name": "ipython", 96 | "version": 3 97 | }, 98 | "file_extension": ".py", 99 | "mimetype": "text/x-python", 100 | "name": "python", 101 | "nbconvert_exporter": "python", 102 | "pygments_lexer": "ipython3", 103 | "version": "3.5.2" 104 | } 105 | }, 106 | "nbformat": 4, 107 | "nbformat_minor": 2 108 | } 109 | -------------------------------------------------------------------------------- /images/JupyterLab_Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/ee-jupyter-contrib/8c88bae6d567000c10cd8814daada280a92e4328/images/JupyterLab_Example.png --------------------------------------------------------------------------------