From 80924f877e8e05501c2511ae2a41cb178725805a Mon Sep 17 00:00:00 2001
From: Veronica Andreo "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "See extra slides for details about [*computational region*](#region) and [*masks*](#mask) in GRASS GIS."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Create daily LST STRDS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Create time series \n",
+ "t.create type=strds temporaltype=absolute \\\n",
+ " output=lst_daily title=\"Average Daily LST\" \\\n",
+ " description=\"Average daily LST in degree C - 2014-2018\"\n",
+ "\n",
+ "# Get list of maps \n",
+ "g.list type=raster pattern=\"lst_201*\" output=list_lst.csv\n",
+ "\n",
+ "# Register maps in strds \n",
+ "t.register -i input=lst_daily file=list_lst.csv \\\n",
+ " increment=\"1 days\" start=\"2014-01-01\"\n",
+ "\n",
+ "# Get info about the strds\n",
+ "t.info input=lst_daily"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "\n",
+ "See [t.create](https://grass.osgeo.org/grass-stable/manuals/t.create.html) and [t.register](https://grass.osgeo.org/grass-stable/manuals/t.register.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Generate environmental variables from LST STRDS\n",
+ "\n",
+ "#### Long term monthly avg, min and max LST"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for i in $(seq -w 1 12) ; do \n",
+ " t.rast.series input=lst_daily method=average \\\n",
+ " where=\"strftime('%m', start_time)='${i}'\" \\\n",
+ " output=lst_average_${i}\n",
+ " t.rast.series input=lst_daily method=minimum \\\n",
+ " where=\"strftime('%m', start_time)='${i}'\" \\\n",
+ " output=lst_minimum_${i}\n",
+ " t.rast.series input=lst_daily method=maximum \\\n",
+ " where=\"strftime('%m', start_time)='${i}'\" \\\n",
+ " output=lst_maximum_${i} \n",
+ "done"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "See [t.rast.series](https://grass.osgeo.org/grass-stable/manuals/t.rast.series.html) manual for further details."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Bioclimatic variables\n",
+ "\n",
+ "::: {.panel-tabset}\n",
+ "\n",
+ "## GRASS code\n",
+ "\n",
+ "```bash\n",
+ "# Install extension\n",
+ "g.extension extension=r.bioclim\n",
+ " \n",
+ "# Estimate temperature related bioclimatic variables\n",
+ "r.bioclim \\\n",
+ " tmin=$(g.list type=raster pattern=\"lst_minimum_??\" separator=\",\") \\\n",
+ " tmax=$(g.list type=raster pattern=\"lst_maximum_??\" separator=\",\") \\\n",
+ " tavg=$(g.list type=raster pattern=\"lst_average_??\" separator=\",\") \\\n",
+ " output=worldclim_ \n",
+ "\n",
+ "# List output maps\n",
+ "g.list type=raster pattern=\"worldclim*\"\n",
+ "```\n",
+ "\n",
+ "## Output\n",
+ "
\n",
+ "\n",
+ "## Map\n",
+ "\n",
+ "
\n",
+ "\n",
+ ":::\n",
+ "\n",
+ "See [r.bioclim](https://grass.osgeo.org/grass-stable/manuals/addons/r.bioclim.html) manual for further details.\n",
+ "\n",
+ "\n",
+ "#### Spring warming\n",
+ "\n",
+ "::: {.panel-tabset}\n",
+ "\n",
+ "## GRASS code\n",
+ "\n",
+ "```bash\n",
+ "# Annual spring warming: slope(daily Tmean february-march-april)\n",
+ "t.rast.aggregate input=lst_daily output=annual_spring_warming \\\n",
+ " basename=spring_warming suffix=gran \\\n",
+ " method=slope granularity=\"1 years\" \\\n",
+ " where=\"strftime('%m',start_time)='02' or \\\n",
+ " strftime('%m',start_time)='03' or \\\n",
+ " strftime('%m', start_time)='04'\"\n",
+ "\n",
+ "# Average spring warming\n",
+ "t.rast.series input=annual_spring_warming \\\n",
+ " output=avg_spring_warming \\\n",
+ " method=average\n",
+ "```\n",
+ "\n",
+ "## Map\n",
+ "\n",
+ "
\n",
+ "\n",
+ ":::\n",
+ "\n",
+ "See [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html) manual.\n",
+ "\n",
+ "\n",
+ "#### Autumnal cooling\n",
+ "\n",
+ "::: {.panel-tabset}\n",
+ "\n",
+ "## GRASS code\n",
+ "\n",
+ "```bash\n",
+ "# Annual autumnal cooling: slope(daily Tmean august-september-october)\n",
+ "t.rast.aggregate input=lst_daily output=annual_autumnal_cooling \\\n",
+ " basename=autumnal_cooling suffix=gran \\\n",
+ " method=slope granularity=\"1 years\" \\\n",
+ " where=\"strftime('%m',start_time)='08' or \\\n",
+ " strftime('%m',start_time)='09' or \\\n",
+ " strftime('%m', start_time)='10'\"\n",
+ "\n",
+ "# Average autumnal cooling\n",
+ "t.rast.series input=annual_autumnal_cooling \\\n",
+ " output=avg_autumnal_cooling \\\n",
+ " method=average\n",
+ "```\n",
+ "\n",
+ "## Map\n",
+ "\n",
+ "
\n",
+ "\n",
+ ":::\n",
+ "\n",
+ "\n",
+ "#### Number of days with LSTmean >= 20 and <= 30\n",
+ "\n",
+ "::: {.panel-tabset}\n",
+ "\n",
+ "## GRASS code\n",
+ "\n",
+ "```bash\n",
+ "# Keep only pixels meeting the condition\n",
+ "t.rast.algebra -n \\\n",
+ " expression=\"tmean_higher20_lower30 = if(lst_daily >= 20.0 && lst_daily <= 30.0, 1, null())\" \\\n",
+ " basename=tmean_higher20_lower30 suffix=gran nproc=7\n",
+ "\n",
+ "# Count how many times per year the condition is met\n",
+ "t.rast.aggregate input=tmean_higher20_lower30 \\\n",
+ " output=count_tmean_higher20_lower30 \\\n",
+ " basename=tmean_higher20_lower30 suffix=gran \\\n",
+ " method=count granularity=\"1 years\"\n",
+ "\n",
+ "# Average number of days with LSTmean >= 20 and <= 30\n",
+ "t.rast.series input=count_tmean_higher20_lower30 \\\n",
+ " output=avg_count_tmean_higher20_lower30 method=average\n",
+ "```\n",
+ "\n",
+ "## Map\n",
+ "\n",
+ "
\n",
+ "\n",
+ ":::\n",
+ "\n",
+ "See [t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html) manual for further details.\n",
+ "\n",
+ "\n",
+ "#### Number of consecutive days with LSTmean <= -2.0\n",
+ "\n",
+ "\n",
+ "```bash\n",
+ "# Create annual mask\n",
+ "t.rast.aggregate input=lst_daily output=annual_mask \\\n",
+ " basename=annual_mask suffix=gran \\\n",
+ " granularity=\"1 year\" method=count\n",
+ "\n",
+ "# Replace values by zero\n",
+ "t.rast.mapcalc input=annual_mask output=annual_mask_0 \\\n",
+ " expression=\"if(annual_mask, 0)\" \\\n",
+ " basename=annual_mask_0\n",
+ "\n",
+ "# Calculate consecutive days with LST <= -2.0\n",
+ "t.rast.algebra \\\n",
+ " expression=\"lower_m2_consec_days = annual_mask_0 {+,contains,l} \\\n",
+ " if(lst_daily <= -2.0 && lst_daily[-1] <= -2.0 || \\\n",
+ " lst_daily[1] <= -2.0 && lst_daily <= -2.0, 1, 0)\" \\\n",
+ " basename=lower_m2_ suffix=gran nproc=7\n",
+ "```\n",
+ "\n",
+ "\n",
+ "```bash\n",
+ "# Inspect values\n",
+ "t.rast.list input=lower_m2_consec_days \\\n",
+ " columns=name,start_time,end_time,min,max\n",
+ "\n",
+ "# Median number of consecutive days with LST <= -2\n",
+ "t.rast.series input=lower_m2_consec_days \\\n",
+ " output=median_lower_m2_consec_days method=median\n",
+ "```\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "We have all these maps within GRASS, how do we connect with R now? Let's move to #part2"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/_freeze/index/execute-results/html.json b/_freeze/index/execute-results/html.json
index d6b657f..0eebc41 100644
--- a/_freeze/index/execute-results/html.json
+++ b/_freeze/index/execute-results/html.json
@@ -1,7 +1,7 @@
{
- "hash": "e098d82f93fc94c0b5cae61d69aad312",
+ "hash": "b088c4ce77a7b5065d57b176d2781ad9",
"result": {
- "markdown": "---\ntitle: \"Leveraging remote sensing for Public Health\"\nsubtitle: \"Visiting the Geospatial Analytics Center at NCSU\"\ndate: '2023-03-30'\nauthor: \"Verónica Andreo\"\ntoc: true\n---\n\n\n## Overview\n\nVector-borne and zoonotic diseases are responsible for one-sixth of disease \nand disability worldwide. Their distribution and spread is highly dependent \non the environment. In the face of the environmental changes brought about \nby the Earth system crisis, remote sensing has gained renewed relevance for\npublic health applications. For example, time series of remotely sensed \nvariables can be used to understand the spatio-temporal conditions that \nfavor mosquito populations and may pose a high risk of West Nile Fever \noutbreaks. In this talk I'll show how we use remote sensing data of different\nspatial and temporal resolutions to predict the risk of diseases such as \nhantavirus, dengue and leishmaniasis, to allocate sensors for mosquito \nsampling, and to quantify access to health care, among others. I will also \ndiscuss various limitations, challenges, and future directions in the use of\nremote sensing for operational early warning systems and applications to \nsupport timely decision making in the field of Public Health. \nSpoiler alert! GRASS GIS is one of the main characters in this journey.\n\n## Contents\n\n1. Lecture: \"**Environmental drivers of vector-borne and zoonotic diseases: Leveraging remote sensing for Public Health**\"\n 1. Motivation\n 2. Health Geography\n 3. Disease Ecology\n 4. Leveraging remote sensing for Disease Ecology\n - Resolution vs scale\n - How can we use RS?\n - Examples\n 5. Gaps, challenges and opportunities\n 6. Conclusion\n2. Studio: \"**Using satellite data for species distribution modeling with GRASS GIS and R**\"\n 1. GRASS GIS\n 2. Interface GRASS-R\n 3. Demo session\n\n\n",
+ "markdown": "---\ntitle: \"Leveraging remote sensing for Public Health\"\nsubtitle: \"Visiting the Geospatial Analytics Center at NCSU\"\ndate: '2023-03-31'\nauthor: \"Verónica Andreo\"\ntoc: true\n---\n\n\n## Overview\n\nVector-borne and zoonotic diseases are responsible for one-sixth of disease \nand disability worldwide. Their distribution and spread is highly dependent \non the environment. In the face of the environmental changes brought about \nby the Earth system crisis, remote sensing has gained renewed relevance for\npublic health applications. For example, time series of remotely sensed \nvariables can be used to understand the spatio-temporal conditions that \nfavor mosquito populations and may pose a high risk of West Nile Fever \noutbreaks. In this talk I'll show how we use remote sensing data of different\nspatial and temporal resolutions to predict the risk of diseases such as \nhantavirus, dengue and leishmaniasis, to allocate sensors for mosquito \nsampling, and to quantify access to health care, among others. I will also \ndiscuss various limitations, challenges, and future directions in the use of\nremote sensing for operational early warning systems and applications to \nsupport timely decision making in the field of Public Health. \nSpoiler alert! GRASS GIS is one of the main characters in this journey.\n\n## Contents\n\n1. Lecture: \"**Environmental drivers of vector-borne and zoonotic diseases: Leveraging remote sensing for Public Health**\"\n 1. Motivation\n 2. Health Geography\n 3. Disease Ecology\n 4. Leveraging remote sensing for Disease Ecology\n - Resolution vs scale\n - How can we use RS?\n - Examples\n 5. Gaps, challenges and opportunities\n 6. Conclusion\n2. Studio: \"**Using satellite data for species distribution modeling with GRASS GIS and R**\"\n 1. Intro to GRASS GIS\n 2. Processing data in GRASS\n 3. Modeling with R\n\n\n",
"supporting": [],
"filters": [
"rmarkdown/pagebreak.lua"
diff --git a/_freeze/notebook_ex_rs_grass/execute-results/html.json b/_freeze/notebook_ex_rs_grass/execute-results/html.json
index d1a3318..341065f 100644
--- a/_freeze/notebook_ex_rs_grass/execute-results/html.json
+++ b/_freeze/notebook_ex_rs_grass/execute-results/html.json
@@ -1,9 +1,9 @@
{
- "hash": "8852929d3bc208ced4a640515b56fc6f",
+ "hash": "32f80528cb35006ae4f55badf986d3c9",
"result": {
- "markdown": "---\ntitle: \"Part 1: Processing data in GRASS\"\nauthor: Verónica Andreo\nformat: \n html: \n code-tools: true\n code-copy: true\n code-fold: false\n---\n\nIn this notebook we'll go through the processing of MODIS LST daily time series\ndata to derive relevant predictor variables for modeling the distribution of\n*Aedes albopictus* in Northern Italy. Furthermore, we'll show how to obtain and\nprocess occurrence data and background points.\n\nLet's first go through some temporal concepts within GRASS GIS...\n\n\n## The TGRASS framework\n\nGRASS GIS was the first FOSS GIS that incorporated capabilities to \n*manage, analyze, process and visualize spatio-temporal data*, as well as \nthe temporal relationships among time series.\n\n- TGRASS is fully **based on metadata** and does not duplicate any dataset\n- **Snapshot** approach, i.e., adds time stamps to maps\n- A collection of time stamped maps (snapshots) of the same variable are called **space-time datasets** or STDS\n- Maps in a STDS can have different spatial and temporal extents\n- Space-time datasets can be composed of raster, raster 3D or vector maps, and so\nwe call them:\n - Space time raster datasets (**STRDS**)\n - Space time 3D raster datasets (**STR3DS**)\n - Space time vector datasets (**STVDS**)\n\n\n## Temporal modules\n\nGRASS temporal modules are named and organized following GRASS core naming\nscheme. In this way, we have:\n\n- **t.\\***: General modules to handle STDS of all types\n- **t.rast.\\***: Modules that deal with STRDS\n- **t.rast3d.\\***: Modules that deal with STR3DS\n- **t.vect.\\***: Modules that deal with STVDS\n\n\n### Other TGRASS notions\n\n- Time can be defined as **intervals** (start and end time) or **instances** \n(only start time)\n- Time can be **absolute** (e.g., 2017-04-06 22:39:49) or **relative** \n(e.g., 4 years, 90 days)\n- **Granularity** is the greatest common divisor of the temporal extents \n(and possible gaps) of all maps in the space-time cube\n\n
\n\n- **Topology** refers to temporal relations between time intervals in a STDS.\n\n
\n\n\n### TGRASS framework and workflow\n\n
\n\n## Hands-on, let's start\n\nSo let's start...\n\n::: {.cell execution_count=1}\n``` {.python .cell-code}\nimport os\nimport sys\n\n# data directory\nhomedir = os.path.join(os.path.expanduser('~'), \"grass_ncsu_2023\")\n\n# GRASS GIS database variables\ngrassbin = \"grass\"\ngrassdata = os.path.join(homedir, \"grassdata\")\nlocation = \"nc_spm_08_grass7\"\nmapset = \"PERMANENT\"\n\n# create directories if not already existing\nos.makedirs(grassdata, exist_ok=True)\n```\n:::\n\n\n::: {.cell execution_count=2}\n``` {.python .cell-code}\nimport subprocess\nprint(subprocess.check_output([grassbin, \"--config\", \"version\"], text=True))\n```\n\n::: {.cell-output .cell-output-stdout}\n```\n8.2.0\n\n```\n:::\n:::\n\n\n::: {.cell execution_count=3}\n``` {.python .cell-code}\n# Ask GRASS GIS where its Python packages are \nsys.path.append(\n subprocess.check_output([grassbin, \"--config\", \"python_path\"], text=True).strip()\n)\n```\n:::\n\n\n::: {.cell execution_count=4}\n``` {.python .cell-code}\n# Import the GRASS GIS packages we need\nimport grass.script as gs\nimport grass.jupyter as gj\n\n# Start the GRASS GIS Session\nsession = gj.init(grassdata, location, mapset)\n```\n:::\n\n\n::: {.cell execution_count=5}\n``` {.python .cell-code}\n# List vector elements in the PERMANENT mapset\ngs.list_grouped(type=\"vector\")\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n```\n{'PERMANENT': ['P079214',\n 'P079215',\n 'P079218',\n 'P079219',\n 'basins_10k',\n 'boundary_county',\n 'boundary_municp',\n 'boundary_wake',\n 'bridges',\n 'busroute1',\n 'busroute11',\n 'busroute6',\n 'busroute_a',\n 'busroutesall',\n 'busstopsall',\n 'census_wake2000',\n 'censusblk_swwake',\n 'comm_colleges',\n 'elev_lid792_bepts',\n 'elev_lid792_cont1m',\n 'elev_lid792_randpts',\n 'elev_lidrural_mrpts',\n 'elev_lidrural_mrptsft',\n 'elev_ned10m_cont10m',\n 'firestations',\n 'geodetic_pts',\n 'geodetic_swwake_pts',\n 'geology',\n 'geonames_NC',\n 'geonames_wake',\n 'hospitals',\n 'lakes',\n 'my_firestations',\n 'myrailroads',\n 'myzipcodes_wake',\n 'nc_limites',\n 'nc_state',\n 'ortho_tiles',\n 'output_points',\n 'overpasses',\n 'poi_names_wake',\n 'precip_30ynormals',\n 'precip_30ynormals_3d',\n 'puntos_escuelas',\n 'railroads',\n 'region_elevation',\n 'region_nc',\n 'roadsmajor',\n 'schools_wake',\n 'soils_general',\n 'soils_wake',\n 'streams',\n 'streets_wake',\n 'swwake_10m',\n 'tmp_current_point',\n 'tmp_points',\n 'uniform_com_colleges',\n 'urbanarea',\n 'usgsgages',\n 'zipcodes_wake']}\n```\n:::\n:::\n\n\n::: {.cell execution_count=6}\n``` {.python .cell-code}\nimport folium\n```\n:::\n\n\n::: {.cell execution_count=7}\n``` {.python .cell-code}\n# Display newly created vector\nmap1 = gj.Map(width=500, use_region=True)\nmap1.d_vect(map=\"railroads\")\nmap1.show()\n```\n\n::: {.cell-output .cell-output-display execution_count=7}\n{}\n:::\n:::\n\n\n#### Importing species records\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Import records\nv.import input=aedes_albopictus.gpkg \n output=aedes_albopictus\n\n# List raster maps\ng.list type=raster\nr.colors map=lst_2014.150_avg color=celsius\n\n# Display records\nd.mon wx0\nd.rast lst_2014.150_avg\nd.vect aedes_albopictus icon=basic/circle \\\n size=7 fill_color=black\n```\n\n\n## Map\n
\n\n:::\n\nYou can also get the occurrences directly from GBIF into GRASS\nby means of [v.in.pygbif](https://grass.osgeo.org/grass-stable/manuals/addons/v.in.pygbif.html).\n\n\n#### Creating random background points\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Create buffer around Aedes albopictus records\nv.buffer input=aedes_albopictus output=aedes_buffer distance=2000\n\n# Set computational region\ng.region -p raster=lst_2014.001_avg\n\n# Create a vector mask to limit background points\nr.mapcalc expression=\"MASK = if(lst_2014.001_avg, 1, null())\"\nr.to.vect input=MASK output=vect_mask type=area\n\n# Subtract buffers from vector mask\nv.overlay ainput=vect_mask binput=aedes_buffer operator=xor output=mask_bg\n\n# Generate random background points\nv.random output=background_points npoints=1000 restrict=mask_bg seed=3749\n```\n\n\n## Map\n\n
\n\n:::\n\nSee extra slides for details about [*computational region*](#region) and [*masks*](#mask) in GRASS GIS.\n\n\n#### Create daily LST STRDS\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Create time series \nt.create type=strds temporaltype=absolute \\\n output=lst_daily title=\"Average Daily LST\" \\\n description=\"Average daily LST in degree C - 2014-2018\"\n\n# Get list of maps \ng.list type=raster pattern=\"lst_201*\" output=list_lst.csv\n\n# Register maps in strds \nt.register -i input=lst_daily file=list_lst.csv \\\n increment=\"1 days\" start=\"2014-01-01\"\n\n# Get info about the strds\nt.info input=lst_daily\n```\n\n\n## Output\n\n
\n\n:::\n\nSee [t.create](https://grass.osgeo.org/grass-stable/manuals/t.create.html) and [t.register](https://grass.osgeo.org/grass-stable/manuals/t.register.html)\n\n\n### Generate environmental variables from LST STRDS\n\n#### Long term monthly avg, min and max LST\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\nfor i in $(seq -w 1 12) ; do \n t.rast.series input=lst_daily method=average \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_average_${i}\n t.rast.series input=lst_daily method=minimum \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_minimum_${i}\n t.rast.series input=lst_daily method=maximum \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_maximum_${i} \ndone\n```\n\n\n## Output\n\n
\n\n:::\n\nSee [t.rast.series](https://grass.osgeo.org/grass-stable/manuals/t.rast.series.html) manual for further details.\n\n\n#### Bioclimatic variables\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Install extension\ng.extension extension=r.bioclim\n \n# Estimate temperature related bioclimatic variables\nr.bioclim \\\n tmin=$(g.list type=raster pattern=\"lst_minimum_??\" separator=\",\") \\\n tmax=$(g.list type=raster pattern=\"lst_maximum_??\" separator=\",\") \\\n tavg=$(g.list type=raster pattern=\"lst_average_??\" separator=\",\") \\\n output=worldclim_ \n\n# List output maps\ng.list type=raster pattern=\"worldclim*\"\n```\n\n\n## Output\n
\n\n## Map\n\n
\n\n:::\n\nSee [r.bioclim](https://grass.osgeo.org/grass-stable/manuals/addons/r.bioclim.html) manual for further details.\n\n\n#### Spring warming\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Annual spring warming: slope(daily Tmean february-march-april)\nt.rast.aggregate input=lst_daily output=annual_spring_warming \\\n basename=spring_warming suffix=gran \\\n method=slope granularity=\"1 years\" \\\n where=\"strftime('%m',start_time)='02' or \\\n strftime('%m',start_time)='03' or \\\n strftime('%m', start_time)='04'\"\n\n# Average spring warming\nt.rast.series input=annual_spring_warming \\\n output=avg_spring_warming \\\n method=average\n```\n\n\n## Map\n\n
\n\n:::\n\nSee [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html) manual.\n\n\n#### Autumnal cooling\n\n::: {.panel-tabset}\n\n## GRASS code\n\n\n```{bash}\n# Annual autumnal cooling: slope(daily Tmean august-september-october)\nt.rast.aggregate input=lst_daily output=annual_autumnal_cooling \\\n basename=autumnal_cooling suffix=gran \\\n method=slope granularity=\"1 years\" \\\n where=\"strftime('%m',start_time)='08' or \\\n strftime('%m',start_time)='09' or \\\n strftime('%m', start_time)='10'\"\n\n# Average autumnal cooling\nt.rast.series input=annual_autumnal_cooling \\\n output=avg_autumnal_cooling \\\n method=average\n```\n\n\n## Map\n\n
\n\n:::\n\n\n#### Number of days with LSTmean >= 20 and <= 30\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Keep only pixels meeting the condition\nt.rast.algebra -n \\\n expression=\"tmean_higher20_lower30 = if(lst_daily >= 20.0 && lst_daily <= 30.0, 1, null())\" \\\n basename=tmean_higher20_lower30 suffix=gran nproc=7\n\n# Count how many times per year the condition is met\nt.rast.aggregate input=tmean_higher20_lower30 \\\n output=count_tmean_higher20_lower30 \\\n basename=tmean_higher20_lower30 suffix=gran \\\n method=count granularity=\"1 years\"\n\n# Average number of days with LSTmean >= 20 and <= 30\nt.rast.series input=count_tmean_higher20_lower30 \\\n output=avg_count_tmean_higher20_lower30 method=average\n```\n\n## Map\n\n
\n\n:::\n\nSee [t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html) manual for further details.\n\n\n#### Number of consecutive days with LSTmean <= -2.0\n\n\n```bash\n# Create annual mask\nt.rast.aggregate input=lst_daily output=annual_mask \\\n basename=annual_mask suffix=gran \\\n granularity=\"1 year\" method=count\n\n# Replace values by zero\nt.rast.mapcalc input=annual_mask output=annual_mask_0 \\\n expression=\"if(annual_mask, 0)\" \\\n basename=annual_mask_0\n\n# Calculate consecutive days with LST <= -2.0\nt.rast.algebra \\\n expression=\"lower_m2_consec_days = annual_mask_0 {+,contains,l} \\\n if(lst_daily <= -2.0 && lst_daily[-1] <= -2.0 || \\\n lst_daily[1] <= -2.0 && lst_daily <= -2.0, 1, 0)\" \\\n basename=lower_m2_ suffix=gran nproc=7\n```\n\n\n```bash\n# Inspect values\nt.rast.list input=lower_m2_consec_days \\\n columns=name,start_time,end_time,min,max\n\n# Median number of consecutive days with LST <= -2\nt.rast.series input=lower_m2_consec_days \\\n output=median_lower_m2_consec_days method=median\n```\n\n
\n\n\nWe have all these maps within GRASS, how do we connect with R now? Let's move to #part2\n\n",
+ "markdown": "---\ntitle: \"Part 2: Processing data in GRASS\"\nauthor: Verónica Andreo\ndate: '`r Sys.Date()`'\nformat: \n html: \n code-tools: true\n code-copy: true\n code-fold: false\nexecute: \n eval: false\n---\n\nIn this notebook we'll go through the processing of MODIS LST daily time series\ndata to derive relevant predictor variables for modeling the distribution of\n*Aedes albopictus* in Northern Italy. Furthermore, we'll show how to obtain and\nprocess occurrence data and background points.\n\nLet's first go through some temporal concepts within GRASS GIS...\n\n\n## The TGRASS framework\n\nGRASS GIS was the first FOSS GIS that incorporated capabilities to \n*manage, analyze, process and visualize spatio-temporal data*, as well as \nthe temporal relationships among time series.\n\n- TGRASS is fully **based on metadata** and does not duplicate any dataset\n- **Snapshot** approach, i.e., adds time stamps to maps\n- A collection of time stamped maps (snapshots) of the same variable are called\n**space-time datasets** or STDS\n- Maps in a STDS can have different spatial and temporal extents\n- Space-time datasets can be composed of raster, raster 3D or vector maps, and so\nwe call them:\n - Space time raster datasets (**STRDS**)\n - Space time 3D raster datasets (**STR3DS**)\n - Space time vector datasets (**STVDS**)\n\n\n## Temporal modules\n\nGRASS temporal modules are named and organized following GRASS core naming\nscheme. In this way, we have:\n\n- **t.\\***: General modules to handle STDS of all types\n- **t.rast.\\***: Modules that deal with STRDS\n- **t.rast3d.\\***: Modules that deal with STR3DS\n- **t.vect.\\***: Modules that deal with STVDS\n\n\n### Other TGRASS notions\n\n- Time can be defined as **intervals** (start and end time) or **instances** \n(only start time)\n- Time can be **absolute** (e.g., 2017-04-06 22:39:49) or **relative** \n(e.g., 4 years, 90 days)\n- **Granularity** is the greatest common divisor of the temporal extents \n(and possible gaps) of all maps in the space-time cube\n\n{width=\"50%\" fig-align=\"center\"}\n\n- **Topology** refers to temporal relations between time intervals in a STDS.\n\n{width=\"35%\" fig-align=\"center\"}\n\n### TGRASS framework and workflow\n\n{width=\"70%\" fig-align=\"center\"}\n\n\n## Hands-on, let's start\n\nSo let's start...\n\n::: {.cell execution_count=1}\n``` {.python .cell-code}\nimport os\nimport sys\nimport subprocess\n```\n:::\n\n\n::: {.cell execution_count=2}\n``` {.python .cell-code}\n# data directory\nhomedir = os.path.join(os.path.expanduser('~'), \"grass_ncsu_2023\")\n\n# GRASS GIS database variables\ngrassbin = \"grass\"\ngrassdata = os.path.join(homedir, \"grassdata\")\nlocation = \"nc_spm_08_grass7\"\nmapset = \"PERMANENT\"\n\n# create directories if not already existing\nos.makedirs(grassdata, exist_ok=True)\n```\n:::\n\n\n::: {.cell execution_count=3}\n``` {.python .cell-code}\nprint(subprocess.check_output([grassbin, \"--config\", \"version\"], text=True))\n```\n:::\n\n\n::: {.cell execution_count=4}\n``` {.python .cell-code}\n# Ask GRASS GIS where its Python packages are \nsys.path.append(\n subprocess.check_output([grassbin, \"--config\", \"python_path\"], text=True).strip()\n)\n```\n:::\n\n\n::: {.cell execution_count=5}\n``` {.python .cell-code}\n# Import the GRASS GIS packages we need\nimport grass.script as gs\nimport grass.jupyter as gj\n\n# Start the GRASS GIS Session\nsession = gj.init(grassdata, location, mapset)\n```\n:::\n\n\n::: {.cell execution_count=6}\n``` {.python .cell-code}\n# List vector elements in the PERMANENT mapset\ngs.list_grouped(type=\"vector\")\n```\n:::\n\n\n::: {.cell execution_count=7}\n``` {.python .cell-code}\nimport folium\n```\n:::\n\n\n::: {.cell execution_count=8}\n``` {.python .cell-code}\n# Display newly created vector\nmap1 = gj.Map(width=500, use_region=True)\nmap1.d_vect(map=\"railroads\")\nmap1.show()\n# python displays are not shown...\n```\n:::\n\n\n::: {.cell execution_count=9}\n``` {.python .cell-code}\nsession.finish\n```\n:::\n\n\n#### Importing species records\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Import records\nv.import input=aedes_albopictus.gpkg \n output=aedes_albopictus\n\n# List raster maps\ng.list type=raster\nr.colors map=lst_2014.150_avg color=celsius\n\n# Display records\nd.mon wx0\nd.rast lst_2014.150_avg\nd.vect aedes_albopictus icon=basic/circle \\\n size=7 fill_color=black\n```\n\n## Map\n
\n\n:::\n\nYou can also get the occurrences directly from GBIF into GRASS\nby means of [v.in.pygbif](https://grass.osgeo.org/grass-stable/manuals/addons/v.in.pygbif.html).\n\n\n#### Creating random background points\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Create buffer around Aedes albopictus records\nv.buffer input=aedes_albopictus output=aedes_buffer distance=2000\n\n# Set computational region\ng.region -p raster=lst_2014.001_avg\n\n# Create a vector mask to limit background points\nr.mapcalc expression=\"MASK = if(lst_2014.001_avg, 1, null())\"\nr.to.vect input=MASK output=vect_mask type=area\n\n# Subtract buffers from vector mask\nv.overlay ainput=vect_mask binput=aedes_buffer operator=xor output=mask_bg\n\n# Generate random background points\nv.random output=background_points npoints=1000 restrict=mask_bg seed=3749\n```\n\n## Map\n\n
\n\n:::\n\nSee extra slides for details about [*computational region*](#region) and [*masks*](#mask) in GRASS GIS.\n\n\n#### Create daily LST STRDS\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Create time series \nt.create type=strds temporaltype=absolute \\\n output=lst_daily title=\"Average Daily LST\" \\\n description=\"Average daily LST in degree C - 2014-2018\"\n\n# Get list of maps \ng.list type=raster pattern=\"lst_201*\" output=list_lst.csv\n\n# Register maps in strds \nt.register -i input=lst_daily file=list_lst.csv \\\n increment=\"1 days\" start=\"2014-01-01\"\n\n# Get info about the strds\nt.info input=lst_daily\n```\n\n## Output\n\n
\n\n:::\n\nSee [t.create](https://grass.osgeo.org/grass-stable/manuals/t.create.html) and [t.register](https://grass.osgeo.org/grass-stable/manuals/t.register.html)\n\n\n### Generate environmental variables from LST STRDS\n\n#### Long term monthly avg, min and max LST\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\nfor i in $(seq -w 1 12) ; do \n t.rast.series input=lst_daily method=average \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_average_${i}\n t.rast.series input=lst_daily method=minimum \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_minimum_${i}\n t.rast.series input=lst_daily method=maximum \\\n where=\"strftime('%m', start_time)='${i}'\" \\\n output=lst_maximum_${i} \ndone\n```\n\n## Output\n\n
\n\n:::\n\nSee [t.rast.series](https://grass.osgeo.org/grass-stable/manuals/t.rast.series.html) manual for further details.\n\n\n#### Bioclimatic variables\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Install extension\ng.extension extension=r.bioclim\n \n# Estimate temperature related bioclimatic variables\nr.bioclim \\\n tmin=$(g.list type=raster pattern=\"lst_minimum_??\" separator=\",\") \\\n tmax=$(g.list type=raster pattern=\"lst_maximum_??\" separator=\",\") \\\n tavg=$(g.list type=raster pattern=\"lst_average_??\" separator=\",\") \\\n output=worldclim_ \n\n# List output maps\ng.list type=raster pattern=\"worldclim*\"\n```\n\n## Output\n
\n\n## Map\n\n
\n\n:::\n\nSee [r.bioclim](https://grass.osgeo.org/grass-stable/manuals/addons/r.bioclim.html) manual for further details.\n\n\n#### Spring warming\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Annual spring warming: slope(daily Tmean february-march-april)\nt.rast.aggregate input=lst_daily output=annual_spring_warming \\\n basename=spring_warming suffix=gran \\\n method=slope granularity=\"1 years\" \\\n where=\"strftime('%m',start_time)='02' or \\\n strftime('%m',start_time)='03' or \\\n strftime('%m', start_time)='04'\"\n\n# Average spring warming\nt.rast.series input=annual_spring_warming \\\n output=avg_spring_warming \\\n method=average\n```\n\n## Map\n\n
\n\n:::\n\nSee [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html) manual.\n\n\n#### Autumnal cooling\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Annual autumnal cooling: slope(daily Tmean august-september-october)\nt.rast.aggregate input=lst_daily output=annual_autumnal_cooling \\\n basename=autumnal_cooling suffix=gran \\\n method=slope granularity=\"1 years\" \\\n where=\"strftime('%m',start_time)='08' or \\\n strftime('%m',start_time)='09' or \\\n strftime('%m', start_time)='10'\"\n\n# Average autumnal cooling\nt.rast.series input=annual_autumnal_cooling \\\n output=avg_autumnal_cooling \\\n method=average\n```\n\n## Map\n\n
\n\n:::\n\n\n#### Number of days with LSTmean >= 20 and <= 30\n\n::: {.panel-tabset}\n\n## GRASS code\n\n```bash\n# Keep only pixels meeting the condition\nt.rast.algebra -n \\\n expression=\"tmean_higher20_lower30 = if(lst_daily >= 20.0 && lst_daily <= 30.0, 1, null())\" \\\n basename=tmean_higher20_lower30 suffix=gran nproc=7\n\n# Count how many times per year the condition is met\nt.rast.aggregate input=tmean_higher20_lower30 \\\n output=count_tmean_higher20_lower30 \\\n basename=tmean_higher20_lower30 suffix=gran \\\n method=count granularity=\"1 years\"\n\n# Average number of days with LSTmean >= 20 and <= 30\nt.rast.series input=count_tmean_higher20_lower30 \\\n output=avg_count_tmean_higher20_lower30 method=average\n```\n\n## Map\n\n
\n\n:::\n\nSee [t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html) manual for further details.\n\n\n#### Number of consecutive days with LSTmean <= -2.0\n\n\n```bash\n# Create annual mask\nt.rast.aggregate input=lst_daily output=annual_mask \\\n basename=annual_mask suffix=gran \\\n granularity=\"1 year\" method=count\n\n# Replace values by zero\nt.rast.mapcalc input=annual_mask output=annual_mask_0 \\\n expression=\"if(annual_mask, 0)\" \\\n basename=annual_mask_0\n\n# Calculate consecutive days with LST <= -2.0\nt.rast.algebra \\\n expression=\"lower_m2_consec_days = annual_mask_0 {+,contains,l} \\\n if(lst_daily <= -2.0 && lst_daily[-1] <= -2.0 || \\\n lst_daily[1] <= -2.0 && lst_daily <= -2.0, 1, 0)\" \\\n basename=lower_m2_ suffix=gran nproc=7\n```\n\n\n```bash\n# Inspect values\nt.rast.list input=lower_m2_consec_days \\\n columns=name,start_time,end_time,min,max\n\n# Median number of consecutive days with LST <= -2\nt.rast.series input=lower_m2_consec_days \\\n output=median_lower_m2_consec_days method=median\n```\n\n
\n\n\nWe have all these maps within GRASS, how do we connect with R now? Let's move to #part2\n\n",
"supporting": [
- "notebook_ex_rs_grass_files/figure-html"
+ "notebook_ex_rs_grass_files"
],
"filters": [],
"includes": {}
diff --git a/_freeze/notebook_ex_sdm_r/execute-results/html.json b/_freeze/notebook_ex_sdm_r/execute-results/html.json
index c63aa66..b4ba5d4 100644
--- a/_freeze/notebook_ex_sdm_r/execute-results/html.json
+++ b/_freeze/notebook_ex_sdm_r/execute-results/html.json
@@ -1,8 +1,10 @@
{
- "hash": "822b0b6f2b0d0bbc9faf163251ad4a1c",
+ "hash": "008dd6f81b4468f31c4678ab69b78818",
"result": {
- "markdown": "---\ntitle: \"Part 2: Modelling with R\"\nauthor: Verónica Andreo\nformat: \n html: \n code-tools: true\n code-copy: true\n code-fold: false\n---\n\n\n\n\n# Using Satellite Data for Species Distribution Modeling with GRASS GIS and R\n\nIn this third part of the studio, we'll use R to model *Aedes albopictus*\ndistribution in Northern Italy. For that, we need to connect to GRASS via\nthe `rgrass` package in order to read occurrence data and predictors.\n\n## [**rgrass**](https://cran.r-project.org/web/packages/rgrass/index.html)\n\n- `initGRASS()`: starts a GRASS GIS session from R\n- `execGRASS()`: executes GRASS GIS commands \n- `gmeta()`: shows GRASS location metadata\n- `read_VECT()` and `read_RAST()`: read vector and raster maps from GRASS into *terra* objects \n- `write_VECT()` and `write_RAST()`: write *terra* objects into GRASS GIS database\n\n\n### GRASS GIS and R can be used together in two ways:\n\nA. Using [R within a GRASS GIS session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#R_within_GRASS), i.e. starting R (or RStudio) from GRASS terminal\n
\n\n- type `R` or `rstudio &` in the GRASS GIS terminal\n- load `rgrass` library\n- use `read_VECT()`, `read_RAST()` to read data from GRASS into R\n- access GRASS GIS modules and database through `execGRASS()`\n- write data (back) to GRASS database with `write_VECT()` and `write_RAST()`\n\n\n\n\nB. Using [GRASS GIS within an R session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#GRASS_within_R), i.e. we connect to GRASS GIS database from within R (or RStudio).\n
\n\n- we need to start GRASS GIS with `initGRASS()` from R\n- we access GRASS GIS modules through `execGRASS()`\n- use `read_VECT()`, `read_RAST()`, `write_VECT()` and `write_RAST()` to read data from and to GRASS database\n\n::: {.callout-note}\nOriginally intended to apply GRASS functions on data outside GRASS database; hence some prefer to create throw away locations\n:::\n\n\n\n\n# Let's move to R\n\n\n#### Option B: Close GRASS, open Rstudio and run:\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(rgrass7)\n\n# path to GRASS binaries (run `grass --config path`)\ngrassbin <- \"/usr/lib64/grass82\"\n# path to GRASS database\ngrassdata <- \"/home/veroandreo/grassdata/\"\n# path to location\nlocation <- \"eu_laea\"\n# path to mapset\nmapset <- \"italy_LST_daily\"\n\n# start GRASS GIS from R\ninitGRASS(gisBase = grassbin, \n home = tempdir(), \n gisDbase = grassdata, \n location = location, \n mapset = mapset, \n override = TRUE)\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n:::\n\n#### Load other packages needed\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(raster)\nlibrary(sf)\nlibrary(mapview)\nlibrary(biomod2)\n```\n:::\n\n\n#### Read vector data\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Use sf for vectors\nuse_sf()\n\n# Read vector layers\nAa_pres <- readVECT(\"aedes_albopictus\")\nbackground <- readVECT(\"background_points\")\n```\n:::\n\n::: {.cell}\n\n```{.r .cell-code}\n# Quick visualization in mapview\nmapview(Aa_pres) + \n mapview(background, col.regions=NA, cex=2)\n```\n:::\n\n\n## Map\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Read raster data\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Use sp for rasters\nuse_sp()\n\n# List rasters by pattern\nworldclim <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"worldclim*\"))\navg <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"avg*\"))\nmedian <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"median*\", exclude = \"*[1-5]\"))\n\n# Concatenate map lists\nto_import <- c(attributes(worldclim)$resOut, \n attributes(avg)$resOut, \n attributes(median)$resOut)\n\n# Read raster layers\npredictors <- list()\nfor (i in to_import){ predictors[i] <- raster(readRAST(i)) }\n```\n:::\n\n::: {.cell}\n\n```{.r .cell-code}\n# Quick visualization in mapview\nmapview(predictors[['worldclim_bio01']]) + Aa_pres\n```\n:::\n\n\n\n#### Data preparation and formatting\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Response variable\nn_pres <- dim(Aa_pres)[1]\nn_backg <- dim(background)[1]\nspp_name <- 'Aedes.albopictus'\n\npres <- rep(1, n_pres)\nbackg <- rep(0, n_backg)\nmyResp <- c(pres, backg)\n\nmyRespXY <- rbind(st_coordinates(Aa_pres),\n\t\t st_coordinates(background))\n\n# Explanatory variables\nmyExpl <- raster::stack(predictors)\nnames(myExpl)\n```\n:::\n\n\n#### Data preparation and formatting\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Format data as required by biomod\nmyBiomodData <- BIOMOD_FormatingData(resp.var = myResp,\n expl.var = myExpl,\n resp.xy = myRespXY,\n resp.name = spp_name)\n\n# Inspect data\nmyBiomodData\n\n# Plot data\nplot(myBiomodData)\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Set model(s) options\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Set model options\nmyBiomodOption <- BIOMOD_ModelingOptions(\n MAXENT.Phillips = \n list(path_to_maxent.jar = \"/home/veroandreo/software/maxent/maxent.jar\",\n maximumiterations = 200,\n lq2lqptthreshold = 100, \n l2lqthreshold = 100))\n\n# Inspect all configs for MaxEnt\nmyBiomodOption@MAXENT.Phillips\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Run model\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Run model\nmyBiomodModelOut <- BIOMOD_Modeling(\n myBiomodData,\n models = c('MAXENT.Phillips'), \n models.options = myBiomodOption,\n NbRunEval=5, \n DataSplit=80,\n VarImport=10,\n models.eval.meth = c('ROC','ACCURACY'),\n SaveObj = TRUE,\n rescal.all.models = FALSE,\n do.full.models = FALSE,\n modeling.id = paste(spp_name,\"Habitat_Suitability\",sep=\"_\"))\n\n# Inspect the model\nmyBiomodModelOut\n```\n:::\n\n\n\n#### Model evaluation\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Extract evaluation data\nmyBiomodModelEval <- get_evaluations(myBiomodModelOut)\n\n# Accuracy\nmyBiomodModelEval[\"ACCURACY\",\"Testing.data\",,,]\n\n# ROC: Receiver-operator curve\nmyBiomodModelEval[\"ROC\",\"Testing.data\",,,]\n\n# Save run with max ROC\nmax_roc <- which.max(myBiomodModelEval[\"ROC\",\"Testing.data\",,,])\n```\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n:::\n\n#### Variable importance\n\n:::{.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Variable importance\nvi <- get_variables_importance(myBiomodModelOut)\n\n# Let's see the first part\nhead(vi[1:13,1, ,], n = 10L) %>% \n knitr::kable(format = 'html')\n\n# ... and estimate the mean\nhead(apply(vi, c(1,2), mean)) %>% \n knitr::kable(format = 'html')\n```\n:::\n\n\n## Output 1\n\n\n::: {.cell}\n\n:::\n\n\n## Output 2\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Response curves\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Extract model of interest\nAa_maxent <- BIOMOD_LoadModels(myBiomodModelOut, models = \"MAXENT.Phillips\")\n\n# Plot response curves\nresp_curves <- biomod2::response.plot2(models = Aa_maxent, \n Data = get_formal_data(myBiomodModelOut, \n \"expl.var\"),\n show.variables = get_formal_data(myBiomodModelOut,\n \"expl.var.names\"),\n do.bivariate = FALSE, \n fixed.var.metric = \"median\")\n```\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Model predictions\n\n:::{.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Set parameters for model projection\nmyBiomodProj <- BIOMOD_Projection(\n modeling.output = myBiomodModelOut, \n new.env = myExpl, \n proj.name = \"current\", \n selected.models = \"all\", \n compress = FALSE, \n build.clamping.mask = FALSE)\n\n# Obtain predictions\nmod_proj <- get_predictions(myBiomodProj)\n\n# Plot predicted model with highest ROC\nmapview(mod_proj[[max_roc]]) \n```\n:::\n\n\n## Map\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Optionally, write data back to GRASS GIS\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Export only one layer\ng <- as(mod_proj[[max_roc]], 'SpatialGridDataFrame')\nwriteRAST(g, \"maxent_albopictus\", flags = \"overwrite\")\n\n# Export all MaxEnt runs\nfor(i in seq_along(1:length(mod_proj@layers))){\n writeRAST(as(mod_proj[[i]], 'SpatialGridDataFrame'), \n paste0(\"maxent_albopictus_\", i, sep=\"\"), \n flags = \"overwrite\")\n}\n\n# Check it's there\nexecGRASS(\"g.list\", parameters = list(type = \"raster\", \n pattern = \"maxent*\"))\n```\n:::\n\n\n## Output\n\n\n::: {.cell highlight.output='true'}\n\n:::\n\n\n:::\n\n### Disclaimer\n\nThis is only a toy example and only the beginning...\n\n- other models to test\n- hyper-parameter tuning\n- variable selection and model selection\n- ensemble modeling\n- model validation with independent data\n- uncertainty: where we can predict with confidence\n- many other relevant packages: \n - [*dismo*](https://cran.r-project.org/web/packages/dismo/index.html), [*sdm*](https://cran.r-project.org/web/packages/sdm/index.html), [*SDMtune*](https://cran.r-project.org/web/packages/SDMtune/index.html), [*kuenm*](https://github.com/marlonecobos/kuenm), [*caret*](https://cran.r-project.org/web/packages/caret/index.html), [*CAST*](https://cran.r-project.org/web/packages/CAST/index.html), etc.\n",
- "supporting": [],
+ "markdown": "---\ntitle: \"Part 3: Modelling with R\"\nauthor: Verónica Andreo\nformat: \n html: \n code-tools: true\n code-copy: true\n code-fold: false\n---\n\n\n\n\nIn this third part of the studio, we'll use R to model *Aedes albopictus*\ndistribution in Northern Italy. For that, we need to connect to GRASS via\nthe `rgrass` package in order to read occurrence data and predictors.\n\n## [**rgrass**](https://cran.r-project.org/web/packages/rgrass/index.html)\n\n- `initGRASS()`: starts a GRASS GIS session from R\n- `execGRASS()`: executes GRASS GIS commands \n- `gmeta()`: shows GRASS location metadata\n- `read_VECT()` and `read_RAST()`: read vector and raster maps from GRASS into *terra* objects \n- `write_VECT()` and `write_RAST()`: write *terra* objects into GRASS GIS database\n\n\n### GRASS GIS and R can be used together in two ways:\n\nA. Using [R within a GRASS GIS session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#R_within_GRASS), i.e. starting R (or RStudio) from GRASS terminal\n
\n\n- type `R` or `rstudio &` in the GRASS GIS terminal\n- load `rgrass` library\n- use `read_VECT()`, `read_RAST()` to read data from GRASS into R\n- access GRASS GIS modules and database through `execGRASS()`\n- write data (back) to GRASS database with `write_VECT()` and `write_RAST()`\n\n\n\n\nB. Using [GRASS GIS within an R session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#GRASS_within_R), i.e. we connect to GRASS GIS database from within R (or RStudio).\n
\n\n- we need to start GRASS GIS with `initGRASS()` from R\n- we access GRASS GIS modules through `execGRASS()`\n- use `read_VECT()`, `read_RAST()`, `write_VECT()` and `write_RAST()` to read data from and to GRASS database\n\n::: {.callout-note}\nOriginally intended to apply GRASS functions on data outside GRASS database; hence some prefer to create throw away locations\n:::\n\n\n\n\n# Let's move to R\n\n\n#### Option B: Close GRASS, open Rstudio and run:\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(rgrass7)\n\n# path to GRASS binaries (run `grass --config path`)\ngrassbin <- \"/usr/lib64/grass82\"\n# path to GRASS database\ngrassdata <- \"/home/veroandreo/grassdata/\"\n# path to location\nlocation <- \"eu_laea\"\n# path to mapset\nmapset <- \"italy_LST_daily\"\n\n# start GRASS GIS from R\ninitGRASS(gisBase = grassbin, \n home = tempdir(), \n gisDbase = grassdata, \n location = location, \n mapset = mapset, \n override = TRUE)\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n:::\n\n#### Load other packages needed\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(raster)\nlibrary(sf)\nlibrary(mapview)\nlibrary(biomod2)\n```\n:::\n\n\n#### Read vector data\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Use sf for vectors\nuse_sf()\n\n# Read vector layers\nAa_pres <- readVECT(\"aedes_albopictus\")\nbackground <- readVECT(\"background_points\")\n```\n:::\n\n::: {.cell}\n\n```{.r .cell-code}\n# Quick visualization in mapview\nmapview(Aa_pres) + \n mapview(background, col.regions=NA, cex=2)\n```\n:::\n\n\n## Map\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Read raster data\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Use sp for rasters\nuse_sp()\n\n# List rasters by pattern\nworldclim <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"worldclim*\"))\navg <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"avg*\"))\nmedian <- execGRASS(\"g.list\", parameters = list(type = \"raster\", pattern = \"median*\", exclude = \"*[1-5]\"))\n\n# Concatenate map lists\nto_import <- c(attributes(worldclim)$resOut, \n attributes(avg)$resOut, \n attributes(median)$resOut)\n\n# Read raster layers\npredictors <- list()\nfor (i in to_import){ predictors[i] <- raster(readRAST(i)) }\n```\n:::\n\n::: {.cell}\n\n```{.r .cell-code}\n# Quick visualization in mapview\nmapview(predictors[['worldclim_bio01']]) + Aa_pres\n```\n:::\n\n\n\n#### Data preparation and formatting\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Response variable\nn_pres <- dim(Aa_pres)[1]\nn_backg <- dim(background)[1]\nspp_name <- 'Aedes.albopictus'\n\npres <- rep(1, n_pres)\nbackg <- rep(0, n_backg)\nmyResp <- c(pres, backg)\n\nmyRespXY <- rbind(st_coordinates(Aa_pres),\n\t\t st_coordinates(background))\n\n# Explanatory variables\nmyExpl <- raster::stack(predictors)\nnames(myExpl)\n```\n:::\n\n\n#### Data preparation and formatting\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Format data as required by biomod\nmyBiomodData <- BIOMOD_FormatingData(resp.var = myResp,\n expl.var = myExpl,\n resp.xy = myRespXY,\n resp.name = spp_name)\n\n# Inspect data\nmyBiomodData\n\n# Plot data\nplot(myBiomodData)\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Set model(s) options\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Set model options\nmyBiomodOption <- BIOMOD_ModelingOptions(\n MAXENT.Phillips = \n list(path_to_maxent.jar = \"/home/veroandreo/software/maxent/maxent.jar\",\n maximumiterations = 200,\n lq2lqptthreshold = 100, \n l2lqthreshold = 100))\n\n# Inspect all configs for MaxEnt\nmyBiomodOption@MAXENT.Phillips\n```\n:::\n\n\n## Output\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Run model\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Run model\nmyBiomodModelOut <- BIOMOD_Modeling(\n myBiomodData,\n models = c('MAXENT.Phillips'), \n models.options = myBiomodOption,\n NbRunEval=5, \n DataSplit=80,\n VarImport=10,\n models.eval.meth = c('ROC','ACCURACY'),\n SaveObj = TRUE,\n rescal.all.models = FALSE,\n do.full.models = FALSE,\n modeling.id = paste(spp_name,\"Habitat_Suitability\",sep=\"_\"))\n\n# Inspect the model\nmyBiomodModelOut\n```\n:::\n\n\n\n#### Model evaluation\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Extract evaluation data\nmyBiomodModelEval <- get_evaluations(myBiomodModelOut)\n\n# Accuracy\nmyBiomodModelEval[\"ACCURACY\",\"Testing.data\",,,]\n\n# ROC: Receiver-operator curve\nmyBiomodModelEval[\"ROC\",\"Testing.data\",,,]\n\n# Save run with max ROC\nmax_roc <- which.max(myBiomodModelEval[\"ROC\",\"Testing.data\",,,])\n```\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n:::\n\n#### Variable importance\n\n:::{.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Variable importance\nvi <- get_variables_importance(myBiomodModelOut)\n\n# Let's see the first part\nhead(vi[1:13,1, ,], n = 10L) %>% \n knitr::kable(format = 'html')\n\n# ... and estimate the mean\nhead(apply(vi, c(1,2), mean)) %>% \n knitr::kable(format = 'html')\n```\n:::\n\n\n## Output 1\n\n\n::: {.cell}\n\n:::\n\n\n## Output 2\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Response curves\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Extract model of interest\nAa_maxent <- BIOMOD_LoadModels(myBiomodModelOut, models = \"MAXENT.Phillips\")\n\n# Plot response curves\nresp_curves <- biomod2::response.plot2(models = Aa_maxent, \n Data = get_formal_data(myBiomodModelOut, \n \"expl.var\"),\n show.variables = get_formal_data(myBiomodModelOut,\n \"expl.var.names\"),\n do.bivariate = FALSE, \n fixed.var.metric = \"median\")\n```\n:::\n\n\n## Plot\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Model predictions\n\n:::{.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Set parameters for model projection\nmyBiomodProj <- BIOMOD_Projection(\n modeling.output = myBiomodModelOut, \n new.env = myExpl, \n proj.name = \"current\", \n selected.models = \"all\", \n compress = FALSE, \n build.clamping.mask = FALSE)\n\n# Obtain predictions\nmod_proj <- get_predictions(myBiomodProj)\n\n# Plot predicted model with highest ROC\nmapview(mod_proj[[max_roc]]) \n```\n:::\n\n\n## Map\n\n\n::: {.cell}\n\n:::\n\n\n:::\n\n#### Optionally, write data back to GRASS GIS\n\n::: {.panel-tabset}\n\n## R code\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Export only one layer\ng <- as(mod_proj[[max_roc]], 'SpatialGridDataFrame')\nwriteRAST(g, \"maxent_albopictus\", flags = \"overwrite\")\n\n# Export all MaxEnt runs\nfor(i in seq_along(1:length(mod_proj@layers))){\n writeRAST(as(mod_proj[[i]], 'SpatialGridDataFrame'), \n paste0(\"maxent_albopictus_\", i, sep=\"\"), \n flags = \"overwrite\")\n}\n\n# Check it's there\nexecGRASS(\"g.list\", parameters = list(type = \"raster\", \n pattern = \"maxent*\"))\n```\n:::\n\n\n## Output\n\n\n::: {.cell highlight.output='true'}\n\n:::\n\n\n:::\n\n### Disclaimer\n\nThis is only a toy example and only the beginning...\n\n- other models to test\n- hyper-parameter tuning\n- variable selection and model selection\n- ensemble modeling\n- model validation with independent data\n- uncertainty: where we can predict with confidence\n- many other relevant packages: \n - [*dismo*](https://cran.r-project.org/web/packages/dismo/index.html), [*sdm*](https://cran.r-project.org/web/packages/sdm/index.html), [*SDMtune*](https://cran.r-project.org/web/packages/SDMtune/index.html), [*kuenm*](https://github.com/marlonecobos/kuenm), [*caret*](https://cran.r-project.org/web/packages/caret/index.html), [*CAST*](https://cran.r-project.org/web/packages/CAST/index.html), etc.\n",
+ "supporting": [
+ "notebook_ex_sdm_r_files"
+ ],
"filters": [
"rmarkdown/pagebreak.lua"
],
diff --git a/_freeze/notebook_intro/execute-results/html.json b/_freeze/notebook_intro/execute-results/html.json
index 1435f72..92e1fd6 100644
--- a/_freeze/notebook_intro/execute-results/html.json
+++ b/_freeze/notebook_intro/execute-results/html.json
@@ -1,10 +1,8 @@
{
- "hash": "b53a28fd11af82306467fe99f7123b9b",
+ "hash": "d200446eb198dd3c91749270f24ec892",
"result": {
- "markdown": "---\ntitle: \"Introduction to GRASS GIS\"\nsubtitle: \"Basic notions, interfaces and temporal framework\"\nauthor: \"Veronica Andreo\"\ndate: '2023-03-30'\neditor: \n markdown: \n wrap: 80\n---\n\n\n## GRASS GIS general stuff\n\n- **GRASS GIS** (Geographic Resources Analysis Support System), a FOSS suite\nused for geospatial data management and analysis, image processing, graphics\nand maps, spatial modeling, and visualization.\n- Originally developed by the U.S. Army Construction Engineering Research\nLaboratories for land management and environmental planning (1982-1995).\n- More history:
\n\n\n\n\nFrom the **Data** catalog tab you can manage several actions and if \nyou do not yet have imported data into the GRASS database, the \nsoftware creates the directory structure or database automatically.\n\n### Database\n\n- **GRASS database** (directory with projects): When running GRASS GIS for the\n first time, a folder named \"grassdata\" is automatically created. Depending\n on the operating system, it can be found in `$HOME` (\\*nix) or\n `My Documents` (MS Windows).\n- **Location** (a project): A location is defined by its coordinate reference\n system (CRS). The location that is automatically created is in WGS84\n (EPSG:4326). If you have data in another CRS, you should ideally create a\n new location.\n- **Mapset** (a subproject): Each location can have many mapsets to manage\n different aspects or sub-regions of a project. When creating a new location,\n GRASS GIS automatically creates a special mapset called *PERMANENT* where\n the central data of the project (e.g., base maps, road network, dem, etc.)\n can be stored.\n\n\n
\n\n\n::: callout-note\nMore info: https://grass.osgeo.org/grass-stable/manuals/grass_database.html.\n:::\n\n### Computational region\n\nAnother fundamental concept of GRASS GIS (and very useful when working with\nraster data) is that of the **computational region**. It refers to the boundary\nconfiguration of the analysis area and spatial resolution (raster). The\n**computational region** can be defined and modified with the command\n[g.region](https://grass.osgeo.org/grass-stable/manuals/g.region.html) to the\nextent of a vector map, a raster or manually to some area of interest. The\n*output raster maps will have an extent and spatial resolution equal to the\ncomputational region*, while vector maps are always processed at their original\nextent.\n\n\n
\n\n\n::: callout-note\nFor more details, see the wiki on [Computational Region]().\n:::\n\n### Modules and extensions\n\nGRASS has more than [500\nmodules](https://grass.osgeo.org/grass-stable/manuals/full_index.html) for the\nmost varied tasks:\n\n| Prefix | Function class | Type of command | Example |\n|------------------|:--------------|:--------------|:--------------------------------|\n| [g.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#g) | general | general data management | [g.rename](https://grass.osgeo.org/grass-stable/manuals/g.rename.html): renames map |\n| [d.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#d) | display | graphical output | [d.rast](https://grass.osgeo.org/grass-stable/manuals/d.rast.html): display raster map |\n| [r.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r) | raster | raster processing | [r.mapcalc](https://grass.osgeo.org/grass-stable/manuals/r.mapcalc.html): map algebra |\n| [v.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r) | vector | vector processing | [v.clean](https://grass.osgeo.org/grass-stable/manuals/v.clean.html): topological cleaning |\n| [i.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#i) | imagery | imagery processing | [i.pca](https://grass.osgeo.org/grass-stable/manuals/i.pca.html): Principal Components Analysis on imagery group |\n| [r3.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r3) | voxel | 3D raster processing | [r3.stats](https://grass.osgeo.org/grass-stable/manuals/r3.stats.html): voxel statistics |\n| [db.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#db) | database | database management | [db.select](https://grass.osgeo.org/grass-stable/manuals/db.select.html): select value(s) from table |\n| [ps.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#ps) | postscript | PostScript map creation | [ps.map](https://grass.osgeo.org/grass-stable/manuals/ps.map.html): PostScript map creation |\n| [t.\\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#t) | temporal | space-time datasets | [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html): raster time series aggregation |\n\nExtensions or **add-ons** can be installed from the [central GitHub\nrepository](https://grass.osgeo.org/grass-stable/manuals/addons/) or from *other\nusers' GitHub* (or similar repositories) using the command\n[g.extension](https://grass.osgeo.org/grass-stable/manuals/g.extension.html).\nFor example:\n\n``` bash\n # install an extension from the GRASS GIS repository\n g.extension extension=r.hants\n \n # install an extension from another GitHub repository\n g.extension extension=r.change.stats \\\n url=https://github.com/mundialis/r.change.stats\n```\n\n### Graphical User Interface (GUI)\n\n
\n\n### Data for the session\n\n- Records of *Aedes albopictus* (Asian tiger mosquito) in Northern Italy\n downloaded from [GBIF](https://www.gbif.org/)\n- Daily MODIS LST reconstructed by [mundialis](https://www.mundialis.de/en/)\n based on [Metz et al. 2017](https://www.mdpi.com/2072-4292/9/12/1333/htm)\n - 1 km spatial resolution\n - Converted to Celsius degrees\n\n
\n\n\n### Get sample location, mosquito records and code\n\n- Create a folder named `grassdata`\n- Download and unzip [eu_laea location with LST\n mapset](https://drive.google.com/file/d/1z1b2NLC4Z6yzz_57RddTdRRK_gUkd7fU/view?usp=sharing)\n and unzip within your `grassdata` folder\n- Download the asian tiger [mosquito\n occurrences](https://github.com/veroandreo/grass_opengeohub2021/raw/master/data/aedes_albopictus.gpkg)\n as `.gpkg` file\n\nThe `grassdata_ogh` folder's tree should look like this:\n\n``` \n grassdata_ogh/\n └── eu_laea\n ├── italy_LST_daily\n └── PERMANENT\n```\n\n## MASK\n\n- Masks are set with [r.mask](https://grass.osgeo.org/grass76/manuals/r.mask.html) or creating a raster map called `MASK`. \n- Masks are virtual masks, they are only actually applied when reading raster maps\n- All cells that are *NULL* in the MASK map will be ignored (also all areas outside the computational region).\n- Vector maps can be also used as masks\n\n
\n\na- Elevation raster and lakes vector maps. b- Only the raster data inside the masked area are used for further analysis. c- Inverse mask.\n\n\n### MASK examples\n\n```bash\n# use vector as mask\nr.mask vector=lakes\n\n# use vector as mask, set inverse mask\nr.mask -i vector=lakes\n\n# mask categories of a raster map\nr.mask raster=landclass96 maskcats=\"5 thru 7\"\n\n# create a raster named MASK\nr.mapcalc expression=\"MASK = if(elevation < 100, 1, null())\"\n\n# remove mask\nr.mask -r\n```\n\nMasks are only actually applied when reading a GRASS raster map, i.e., when used as input.\n\n# GRASS GIS HELP!!!\n\n- [g.manual](https://grass.osgeo.org/grass76/manuals/g.manual.html):\n in the main GUI under Help or just pressing *F1*\n- `--help` or `--h` flag after the module name in the terminal\n- [GRASS website](https://grass.osgeo.org/): rich [learn](https://grass.osgeo.org/learn/) section with links to videos, tutorials, courses, books, etc.\n- [GRASS wiki](https://grasswiki.osgeo.org/wiki/GRASS-Wiki): examples,\n explanations on particular modules or tasks,\n [tutorials](https://grasswiki.osgeo.org/wiki/Category:Tutorial),\n applications, etc.\n- grass-user mailing list: [subscribe](https://lists.osgeo.org/mailman/listinfo/grass-user) and post or check the [archives](https://lists.osgeo.org/pipermail/grass-user/)\n- Link to source code and history in each module manual page, eg., \n[t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html)\n\n
\n\n## Other (very) useful links\n\n- [GRASS intro workshop held at NCSU](https://ncsu-osgeorel.github.io/grass-intro-workshop/)\n- [Unleash the power of GRASS GIS at US-IALE 2017](https://grasswiki.osgeo.org/wiki/Unleash_the_power_of_GRASS_GIS_at_US-IALE_2017)\n- [Temporal data processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing)\n- [GRASS GIS and R for time series processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing/GRASS_R_raster_time_series_processing)\n- [GRASS GIS temporal workshop at NCSU](http://ncsu-geoforall-lab.github.io/grass-temporal-workshop/)\n- [GRASS GIS course in Jena](https://training.gismentors.eu/grass-gis-workshop-jena/index.html)\n- [GRASS GIS course IRSAE](http://training.gismentors.eu/grass-gis-irsae-winter-course-2018/index.html)\n- [GRASS GIS course in Argentina](https://gitlab.com/veroandreo/curso-grass-gis-rioiv)\n",
- "supporting": [
- "notebook_intro_files"
- ],
+ "markdown": "---\ntitle: \"Part 1: Intro to GRASS GIS\"\nsubtitle: \"Basic notions, interfaces and temporal framework\"\nauthor: \"Veronica Andreo\"\ndate: '2023-03-31'\neditor: \n markdown: \n wrap: 80\n---\n\n\n## GRASS GIS general stuff\n\n- **GRASS GIS** (Geographic Resources Analysis Support System), a FOSS suite\nused for geospatial data management and analysis, image processing, graphics\nand maps, spatial modeling, and visualization.\n- Originally developed by the U.S. Army Construction Engineering Research\nLaboratories for land management and environmental planning (1982-1995).\n- First *User Manual* published on July 29th, 1983... **GRASS is becoming 40 this year!**\n- More history:
\n\n- Records of *Aedes albopictus* (Asian tiger mosquito) in Northern Italy\n downloaded from [GBIF](https://www.gbif.org/)\n- Average daily MODIS LST reconstructed by \n [mundialis GmbH & Co. KG](https://www.mundialis.de/en/) based on @metz_new_2017:\n - 1 km spatial resolution\n - Converted to Celsius degrees\n\n
\n\n\n### Get the sample location\n\n- Create a folder named `grassdata`\n- Download and unzip [eu_laea location with LST mapset](https://drive.google.com/file/d/1z1b2NLC4Z6yzz_57RddTdRRK_gUkd7fU/view?usp=sharing)\nand unzip within your `grassdata` folder\n\nThe `grassdata` folder's tree should look like this:\n\n``` \n grassdata/\n └── eu_laea\n ├── italy_LST_daily\n └── PERMANENT\n```\n\n# GRASS GIS HELP!!!\n\n- [g.manual](https://grass.osgeo.org/grass76/manuals/g.manual.html):\n in the main GUI under Help or just pressing *F1*\n- `--help` or `--h` flag after the module name in the terminal\n- [GRASS website](https://grass.osgeo.org/): rich [learn](https://grass.osgeo.org/learn/) section with links to videos, tutorials, courses, books, etc.\n- [GRASS wiki](https://grasswiki.osgeo.org/wiki/GRASS-Wiki): examples,\n explanations on particular modules or tasks,\n [tutorials](https://grasswiki.osgeo.org/wiki/Category:Tutorial),\n applications, etc.\n- grass-user mailing list: [subscribe](https://lists.osgeo.org/mailman/listinfo/grass-user) and post or check the [archives](https://lists.osgeo.org/pipermail/grass-user/)\n- Link to source code and history in each module manual page, eg., \n[t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html)\n\n{width=\"650px\" fig-align=\"center\"}\n\n\n## Other (very) useful links\n\n- [GRASS intro workshop held at NCSU](https://ncsu-osgeorel.github.io/grass-intro-workshop/)\n- [Unleash the power of GRASS GIS at US-IALE 2017](https://grasswiki.osgeo.org/wiki/Unleash_the_power_of_GRASS_GIS_at_US-IALE_2017)\n- [Temporal data processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing)\n- [GRASS GIS and R for time series processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing/GRASS_R_raster_time_series_processing)\n- [GRASS GIS temporal workshop at NCSU](http://ncsu-geoforall-lab.github.io/grass-temporal-workshop/)\n- [GRASS GIS course in Jena](https://training.gismentors.eu/grass-gis-workshop-jena/index.html)\n- [GRASS GIS course IRSAE](http://training.gismentors.eu/grass-gis-irsae-winter-course-2018/index.html)\n- [GRASS GIS course in Argentina](https://gitlab.com/veroandreo/curso-grass-gis-rioiv)\n\n# References\n\n:::{#refs}\n\n:::",
+ "supporting": [],
"filters": [
"rmarkdown/pagebreak.lua"
],
diff --git a/_freeze/studio_index/execute-results/html.json b/_freeze/studio_index/execute-results/html.json
index 62fcdb6..cb2b6a6 100644
--- a/_freeze/studio_index/execute-results/html.json
+++ b/_freeze/studio_index/execute-results/html.json
@@ -1,8 +1,10 @@
{
- "hash": "95c981a19e0f59da42fbdf0265bd9606",
+ "hash": "a09dc091511db7ac6012ce6f70a25372",
"result": {
- "markdown": "---\ntitle: \"Using Satellite Data for Species Distribution Modeling with GRASS GIS and R\"\nauthor: \"Verónica Andreo\"\ndate: '2023-03-30'\n---\n\n\nTraditionally, species distribution models (SDM) use climatic data as predictors of habitat suitability for the target species. In this studio, we will explore the use of satellite data to derive relevant predictors. The satellite data processing, from download to analysis, will be performed using GRASS GIS software functionality. Then, we'll read our predictors within R and perform SDM, visualize and analyze results there, to then exemplify how to write the output distribution maps back into GRASS.\n\n# Getting ready\n\n## Software \n\n### GRASS GIS\n\nWe will use **GRASS GIS 8.2+**. It can be installed either \nthrough standalone installers/binaries or through\n[OSGeo-Live](https://live.osgeo.org/en/index.html) \n(a linux based virtual machine which includes all OSGeo software and packages).\n\n##### MS Windows\n\nThere are two different options:\n1. [Standalone installer 64-bit](https://grass.osgeo.org/grass78/binary/mswindows/native/x86_64/WinGRASS-7.8.5-2-Setup-x86_64.exe) \n2. [OSGeo4W 64-bit](http://download.osgeo.org/osgeo4w/v2/osgeo4w-setup.exe) \n\nFor Windows users, **we strongly recommend installing GRASS GIS through the OSGeo4W package** (second option), \nsince it allows to install all OSGeo software. See this \n[**installation guide**](https://gitlab.com/veroandreo/grass-gis-conae/-/blob/master/pdf/00_installation.pdf) \nfor details (Follow only the GRASS GIS part).\n\n##### Ubuntu Linux\n\nInstall GRASS GIS 8.2+ from the \"unstable\" package repository:\n\n```\nsudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable\nsudo apt-get update\nsudo apt-get install grass grass-gui grass-dev\n```\n\n##### Fedora, openSuSe Linux\n\nFor other Linux distributions including **Fedora** and **openSuSe**, simply install GRASS GIS with the respective package manager. See also [here](https://grass.osgeo.org/download/)\n\n##### Mac OS\n\nHave a look at: http://grassmac.wikidot.com/downloads\n\n#### GRASS GIS Add-on that will be used during the demo\n\n* [r.bioclim](https://grass.osgeo.org/grass7/manuals/addons/r.bioclim.html): Calculates bioclimatic indices as those in [WorldClim](https://www.worldclim.org/bioclim).\n\nInstall with `g.extension extension=name_of_addon`\n\n### R and R-Studio\n\nThe following packages should be installed beforehand:\n\n```r\n install.packages(c(\"rgrass\",\"terra\",\"raster\",\"sf\",\"mapview\",\"biomod2\"))\n```\n### Python\n\n## Other software\n\nWe will use the software **MaxEnt** to model habitat suitability. The software can be downloaded from: https://biodiversityinformatics.amnh.org/open_source/maxent/\n\n## Data\n\nPlease, create a folder in your `$HOME` directory, or under `Documents` if in Windows, and name it **grassdata_ogh**. Then, download the following ready to use *location* and unzip within `grassdata_ogh`:\n\n* [Northern Italy (1.7 Gb)](https://drive.google.com/file/d/1z1b2NLC4Z6yzz_57RddTdRRK_gUkd7fU/view?usp=sharing)\n\nIn the end, your `grassdata` folder should look like this:\n\n```\n grassdata/\n └── eu_laea\n ├── italy_LST_daily\n └── PERMANENT\n```\n\n\n## References\n\n- https://github.com/veroandreo/foss4g2022_grass4rs\n- https://github.com/veroandreo/grass_opengeohub2021\n\n\n\n\n\n",
- "supporting": [],
+ "markdown": "---\ntitle: \"Using Satellite Data for Species Distribution Modeling with GRASS GIS and R\"\nauthor: \"Verónica Andreo\"\ndate: '2023-03-31'\n---\n\n\nTraditionally, species distribution models (SDM) use climatic data as predictors of habitat suitability for the target species. In this studio, we will explore the use of satellite data to derive relevant predictors. The satellite data processing, from download to analysis, will be performed using GRASS GIS software functionality. Then, we'll read our predictors within R and perform SDM, visualize and analyze results there, to then exemplify how to write the output distribution maps back into GRASS.\n\n# Getting ready\n\nWe'll run this session online, however, if you want to run it locally \nafterwards, here are the requirements.\n\n## Software \n\n### GRASS GIS\n\nWe will use **GRASS GIS 8.2+**. It can be installed either \nthrough standalone installers/binaries or through\n[OSGeo-Live](https://live.osgeo.org/en/index.html) \n(a linux based virtual machine which includes all OSGeo software and packages).\n\n##### MS Windows\n\nThere are two different options to install GRASS GIS in MS Windows:\n\n1. [Standalone installer 64-bit](https://grass.osgeo.org/grass82/binary/mswindows/native/WinGRASS-8.2.1-1-Setup.exe) \n2. [OSGeo4W 64-bit](http://download.osgeo.org/osgeo4w/v2/osgeo4w-setup.exe) \n\nFor Windows users, **we strongly recommend installing GRASS GIS through the OSGeo4W package** (second option), \nsince it allows to install all OSGeo software and resolves dependencies. \n\n##### Ubuntu Linux\n\nInstall GRASS GIS 8.2+ from the \"unstable\" package repository:\n\n```bash\n sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable\n sudo apt-get update\n sudo apt-get install grass grass-gui grass-dev\n```\n\n##### Fedora, openSuSe Linux\n\nFor other Linux distributions including **Fedora** and **openSuSe**, simply \ninstall GRASS GIS with the respective package manager. See also [here](https://grass.osgeo.org/download/linux/)\n\n##### Mac OS\n\nFind GRASS GIS binaries on
3Vi zO>qni%-QqbyKNkBMYh|rXUvM7(kUn_>R3J)@meFTVx@4Z&3t_S`q|R1?B2rQv@>G) z_%LDqYQFKP&tC3wA?(b5Ep&5M-Y-2n`#TV<#9=LCpB?etW(@gdAR9!14SY6?Qd8GB zOaWtsN5|fX%18_@awz{OEo@)M7V2Mtn+3LtOgbUk`YzqjNxFa`osuF=ien zhh@fDwX$-U`zi7|gj)fzOW$&WSy^942rVGzSLh)?s;rC_ppfVO0DUd@Jmz~>s@pcb z*W8aD6mpvIlxG?%Azaw;I&mqiN@gmZ?~6FzI*UZKWV$47xXai%{8+Css_ld)yyO%X zrpQOB-2ddwJdbUou%I6xBqSXDGv>BTHm(g6%Pr?!IFL cu7h+ zO?O{-*h90A_uG`&L_ku{LHEAYbjNPSjOCH^8@|!)p=a~qv67CtLvoJB2)oSZg9nh? zq{7XYcN76IX*33;5AZq20UuPV>||hac9EJ-Y wRe+4!&GBUk&mOJ6) z0>r7b-IeXJadBFP4)D?VoT0}&kNxaq!Ey)B^i>VeIh*j3pK*^t!QqNSZzzJU4oonU zw6O1TLq~l5Lqqw^%^_`VPn49DY;AvN>X6o%e{U8_ s#rx%r#RkhKP z AD>hx%%bj&krXxH4{f*3 9mec$_+v!~#*Pp^7nj|{xYMVr_zh>5hDm9&P(0cs6{FrZdp1AYs62^0@k*2|fH z%>a6m8;BX`)jR!{eg+2JkktcU^p (XvV_n5}ZG&dHi zfSARn^i#`3C~XaFoVa_~ADvYdc-;>$a##nrmG9BL+L^}WjnhUey~M%loWI}*8(@-r zrK|e_bT5{$O2T>Og_V_6ap@hRrVW{AD}6Mi5#~=aZEcbv>le2p)op?e;bYi`A36$@ zP13at>c$m0IlqfZNQ}&bTk9a}w}`?%beI8D1Axo!?uZxDN+&+b)3`<_LEAv08<$Da zeXbNB$zQc}T-DE!JANoBKKDU*gX12#o9zmv@NskJGZqR?H7#8uBXwtIVU7F<|NfM+ zJtV`NFO~(T`S82&@YF~sV!3VAt T_ObrtW3XIAS+2TNcsWN0kFmNOw8Ro;oip{ zsEO0_p@39G3%2Fl aDL#Vvx7G|tK9)+4!nZ|mCxcyh DA+e>Dar1Yl+73BOc+%_ 0-{6K@8tLBL~GqOZu4 N%syaG0R_U`G5$mBNl~qhmrv2*GV<~2M zkZJI`v3KIZfe35h{*%FD*s{URnG~RH9OiyKcn#;43S4?PUE>7My}%=+XybLafy1mX zOP8Xe|0#AJD9Vv#0jvGDt&E!;7`)~JnZgwnX=olA8&1!bJ2E-9V1<<9SuMORp>xd& zPSYMF&W+Ww@8)dFL2v6i7GI^V^Lem_w908-E~ps$TzPmp&1(P_6WI5H0e}+|?~Ny( zvu@PJWv5AOEj_Qr{-S|z;*Z^3R>16;0CK};+H-eC 1jzR)|j_WumZ;MP=7 zS-0fQd@rF`8q)Eh!&*NZ5c3yUtOuF@pO2oED%VUeOC6H6laG#0@X8&x-u3mpJn)wL z@bp1nf8T3keysns?yR=%n|lp&6p 7B0?xeu1th3=68pVyP|r)Xn)bM1`{_q6j&gq2=JqpZxkrDN}jn*&^d{;y3 FLZvX1KhKC`zwMiG_vVRd>a(JAHC8CXiw~fuM?!iP6^1 z$@&I2*~ChbuzzY=D)8{(BIt8kn$}yr^h3k&rw_ H@>CrNB*^C{aG$$BsmL_Y1g3@a5qtD=_foi zU-!24#>$Mm=8n_m!E9Tx8<=zUaifp8@~|NoC5}GN+gZjG)u!Z9p_-zCQg~HS3>niH z=T(-C!L{1Cw_FZpaB^nG@ToFBRox>pvh>GePlu^gfMOo=s?fb1h!^Lq+Zr;Rq`n(a zph!L(o1vWL=ii<^*VAKASC327djC!Xz(z*%HUU4%J72zi`%ov%1~@xEYcdK5R1aU; z3faNgTSC)(O_tWWGt>9g_tn-#Kd+>eH@^?qJ_ihnxjEw*C;IQ-RqZdB5=nrW>c6~{ z18mPfMKS #yzw z()6-jr{!s&F{|IaAB;`@%ED>7ItIuobF2>#BA=Bu814(%lJ5Myy3DXh@`Dv^O(2_8 zjEn?p=RJ!Ap(%AUA&=#5+}HVxShJ0?FIOhlc?1Mjbb?mXdWZU#TSLN_ u7UtssOeY0j^%i{U&htgLHuetY8blBe5?zzcvs*Unq74`vq|)W#<$TzsPCe`mbQ zZo{cx3n&$!V?kZx;py33vnnHBG`$1=^$QwCOi}4LEm2sAlp(XQuwa(+{*; @ww(zH? -FQ)0h&S180?gvEN26)sL(2;J7T3z{O)LOo@5I8(6RWXrY04Q=Jmx6g5=~# zgICM{QEw1nx)pC)aRAB;bZacOQUw7{`SGKQ5~ACsVHS`TAA!;U7?)`Dj)jjOQ)v&+ z>2=7Hljc)atM68yQ&V5P)l)(A(E?2J`>Yd1vk6ip_;&kxy>Nqg(L2=q{1BiL_r2u+ z$SHSQeQA(aS>f7oF>xW0XJIYV$)TK3X@!D+pt_qW;b?g^RsCyLXfDu;0+8DICDr0J zbLuj{0_uyt)9TI&7=X7O?*a}3(2fCtq+S3i#-A$4agX$ogn|YzM-Qg=J{$HW?oOmu z*ShZSQw`?GDuZaueSI?yKHh$*ioEp$05<@QfPy_THy7W(+DxELyk^}GS1&fI`g_ga zv|soQQja4eC8L0B^k@n6FU>iQYwPLtZfx)frSTVOJVXzg)k7qtrPKe|ztPq0`MqE| zXoZxxahSt5sBy6Fs iAuYUh!>itzX@T8wzjsP>-Y83;$q_;J(7v;M_cx< z4V+zZ^@xc`_Z}UQ^6TV)+j*JE5%5M~o}T<)-#)wov3?NWt9TL`@_5k0{!PuX2E2Yk z!41-J;nCRO#YRldYCW(yYTszh7gTc|)$_;3-CaOJJ BLHv+0Va zjU9{|c{kPFcbJluBR3F|h|kOh9;};${7kD(UPp3d%%f5H=ldNL6V>+gPPGQ|^sCWc z*S6nr7R%AY$AHTP$PEm?$&C!_kb`->>8Hg-Dn5RGUI89J)C0BD2Xg9kiNQF`mgm5` zm7Jz3vVqJwxKtHBn8faNFpwT%Os=I @}bA@bWG~V0FUFp4iAM z^LT)at~Clbteg0LJbxUVJ?(6{d~u8%9Q;;Ht>AHLRKeEIt&y{KMWL_);MAJ7*KAkn z0MpR4rn-kXPzSQ)JTh9aSm)P(FtE4h4>|W?1OVxm89snM3D1<{-OhTb0D9#$??Zfk zetsKKch${= UiU zv7QTDH=4WI=O7{?Iv5&)U IVM2=TbG*q>@hJ6IFqx9m z$lmRgl~h(nywo?)heGe!tVXW_SSR-`ewkat_#Y*`wtl6j9;u_HH5kbj7}a4`5p;v7 zFdds~^0R0%?C 3N{&Fle> I9qAg9FzZr&++*qN=K@ z0(1t@QJJXs;OExJx(^0}$37*iNI8VQCy(S9v#15SLVz+wB(UWJy}pPDA~{?NpFugs z7$!ZFsvH|laQ{KYa_m6d!SHY8V&19F`e=3UCJ_AzNKPas4D?{0bT!=RePPiXu#pvA z;ClZbtHmw*%|cL!>8EFr2@CEr6LkRypYgs_EBGyb0fE+4H^7f;@EeF40ZbxD9Iz?w z_dW=b05kPKybNu-Zy@3LwX!n0w?L&E!F`XFVG)^L1+bU$LJO z?X=@licc_;;Gwh$)0~yJV#mJiTNc^1N{X&pR94@=1Li~JY164ogW+eLH bbrS)DHT?|ufuxhl76RtYZVTEu zF6|Q_CPKybow&TXNpR=smZRgEE(ytivj}V`aylE))AJ*}ueLd-yITnk=i(I*h#F{3 zE)Y`lB1bi`RR+Z2L?|n{30Vwt`cnXM9B?^%`b8bh z4`B_sv^2%iB z=!j;~#gaxxj{)!lfNcZaeO>^!AtEBa$H)o??gexi0FvCfvhuv$b$xyHnXy7@$Jg?5 zo~?RuzG+`>Z6gPhp|afEkdqpT`uYayvCc>5oXrU%Dd0^1q=Egf_9Th?CV=lt2`?;^ zImv7&EhSIu|7f);!H7;y+7VY43Vl-Lqzm{^fZzRSE7+$vHy1ZwwBfjeE-*p(mNlm_ z<*!*EKo}fsSAkcnU{}l`(KuZ`U7y!d4%1JD_B(sIUGz1a?3?2%>O?N!SY5s5q`^Ur z9KYSVp73<+*RS5}s)~Sj;BdW4ov)!~V$e}jVqo{9Y&}v_J`SMzL^VGe_8P->BxfE2 z&7!iV1FreAvD)*nAWXxVf8gAVBOHtIT|e7uxsuiJ%9wiwpxOHNBm}Spt9+J~fa(TW zL+TA4pJHZ6gxwZ?KTuF``4kznX7kAD)VGN~fYek74>GGW+OxsqchVebr6+e0t_;}K zi3RGfVfJO?hH5o6V%osUKI *xTICbX@S4M%Wbz<-C|1ipvV16ar8={0fV#RZet z=s2KtS!N*P+1mko^2Yw>R`vDut_`y@r)W(@#*pQ3fHQTjV-QLOO3KC7g)K-zx67Ns zQlaa`gFT@4(J|{ar($O2KP#Lt{!GPH %dnva`jyBXdrS3BYX zNUR_Dm=_0N`Z4{qCWxXRKW+g8-(6%kTmhRtw0~Gsw&>Y#o=&WwtmCEGe&W!VjW)FE zoawbV*P3viRz_k=RGdw2%`qi zE>>BO&4&X60}SJ`V(q{J%+jDISBAdoDb9RrX!zXOnF44|SR>+D-i+$FSZ?1c;@81k zFJNb8JtZ|^zEj0ms!|K(tL#xaiAVA_N>N1Z (v~% zY#7kj-#;*_pG(QX!6B7R4$ui+e!=D6iyW=z<9&dq1Xx>^=H{V;rA{YJrwU#(p8PScd~zD;vP=evu8*oa>-4)pr|Mh05x>F9nc|=a$S0Og^y24PF7)dbrCyF zZyaXQBNFTbUav0;A1l`HDnMob?TI *c zvDU5*Ec`mZr^gY)%ZLNzX4H7Ge)v3FOHOts1~(ngvp2yn7a(FMY*P2IEzQmGg@uKm z^Psa%l0e<#KaqKEy Pg7jI-kMDcW#k{|f6c!df@$>Y*Y#*}Fwy>CjP?BfPyV?xq z0A5Uu!{k%IT~mKM<+WCvo&%zjO5pDiHU(%M;I1kwu?=#@eiGe!FPI=dB=#<;TwZUs zexKR8(5tc}CXYEa4CpD2OpntWa0^V@e=4|~T&ddErK=H)>PacEeu4wAf$tfNRjg}W z{)0o=vYAH*aQKS7vDMb=guy#NV*}V^G!G8$Sp1fkhkyU%p01eKC~SOk<1zp?pV&t` zZ~L<5%QKoxNoRAwOwG^njW*b8N;%EmtIBgFZW!8yd)22EUh+9PH)lJuo^w@Us@y$2 z50RonfVS^~t7rZW4R@;sB>Pforsv^Brt`t Bl3|E-upijD z>5BX>sR4XtH4U{9uM_3dj(_(8tdXk6#m%@*m*4=TIYJtiAn$j2u({>DA0ElNvN~>T zF`FS?Y*?3dyfx;wvY|!JEc4vRh-DGfc-F_yTiY cE)AFo-&yOzqN2YdSrjGucc6eOOwY)W*^@$* zET-s7Js2oJ83CgEGf-#_|G=s}LZzn7PT z>+aQ -o{CI>tWdp%{XsHKwNExKjR<5;WTG4oS=}G#ns)PaCgJrn3|R z7|Vgd0SM)aQkNVaA4eP=iKV2xWx#x}&3hL0swbp_szg-)(4kN$bOq>pSRw{lvPg3B zTHij_cBO9ndVk1W;aN!0CuJrDbt6|2;~>g;|6tQwhKryNx#hn;&sE`nUP~CB(#^bT z>!ZEzfGygC6{+jl@j3$L*zwWf;&p;vt+jY~I3d!P&Ul@x`8w6Av>NE%qj$C}tUUqE zX~&fh2lkESaXg}R(9W}C-bL@My6e!}zbjdCU$=Yz{{0Ug;k+7nx4=CG&|^ClUSOvZ z;LY*YayJmQ04^^PK9DUr30i<6@yL|adj0yP$6HRDAufquv2h8aVscM`92<9@Wn}U& zuT*KA+m=Tut3s&p!{EzG5TLW**zRrx+(S)G&1Jh&1!yY+drJQHLFnun<1@04U%mRI zsj5ny`|93aRvMsn*Vd4>-wgXjBvQ{OHn-jbdt_FDVi2r1m0M9Ea`z!A3N?-B?0gs( zM>hH=XPz=u|M23+*TyVIgE9{AeC*Hn?;U`BS>IV$vbU#zS{WUB>CeT*&2aBt=c?Ny zV1E~C_1n*fn54S}gJ$s4j$%aSAA8F_-E0Vh@Uh?h^NW}335_c7%F4U7{aq`gG|Af9 z0J#^Tt6Pf!3;SHtLs$a>gQg%0n1SJOFQPK9LA8*{F*>X~SX8!u;!Fyt1WXDr;YDxt zFE)CXTu_&XtsCIItTTVe?YysaIeC^I_GV9T>qces0KU4l1R$1BPgQhH4V^}goch<9 zK9~Zm^JniNJwTw0jg2$5(q;sUm%qL)@kz;c>GK! ~ux^ dr*t`&~r}(qBVtCT0 z5b{C0Hy*PWbMqyo^&UZ|*MU4V|A(r#45%vFqJ>dF5D5wCl2p1oq&q|e>F(|>>F$yi z5s+?>Zjc7)&O>+Sw~qJT@4e>_17V-D*Pd(5ImZ}t9BJaupFfrxzHF?uG11l4?RXgW zQ<`OTDxbBC7r@~%5y;?j!uNf+yZnxVnC->HhSfH j-;mAXDa9~A2)pgd<0;#t>!DxLPvU!Pw lh|~>=B;`S+gtD%eQEpBkXFHnf|BZZf0)SgantQFE9>dGlpifRBbN{D#AhEr z-BM=9WkUW?Q>b>C%j1&nn9H$UncM63FPw)Lt 72@U3^j!2i?6dq%yc;m@7V(H^vB|avzx+myl4_`w;_`h-a|O`-WD9uPS|HPGCK; zSoM0P9U)+^qj0}~N-`?HusQAU8D0$sOfYPRqqI9cM=>ny`8?&J%HNpRtf|kW+BG3| zrliXv)`(jSNP(jA@*L)oK}l08g#LP+gV?WlGKLeWr?h+o`RF3bM-|oQ=Uf$4w(u9^ z -RSVqfJ9&!{hSGxT#tWHgk4KjDrKBuHN3*2Hj^IX;vK%hqo&& zQ|*VgvbUPKu@s@{`*e;xkUwQ(Zed^j{SjZi%3IdY*;Z#piA2f$<9UBGRWe^)TdSn1 zqhKfscO!!x9iqPyRSDEb1O!Y@E)(Fi?^w`8LOR_!s*6xVryF3gIyeA*)>~e}FN4_M zzkipMmHklYNvJcgLG<=*JMrF6r9w%0>9wf?UKsE`k%Mp@lT<%z$r*iSclXb%pZQYv zb_WO$%`9y4OG*|mTKRD8xj3lYBbqxqJ2i*tY*AYj7NSm5@=X;LNoUnkm8YjZ+OG$( zdS(gtH@Wp|Zw}&*1Z9>Ys5!e%io>)E3B^xsA6I%Fm5I42;}{la^j3L+AKckF0|da& z@&d%hMR^GmNcs8#5ib_itP5{PS1T;|TDR`-MAHIc0#e}K($wf^hzh|6Sy?uIeuD|b zFLV!I=+?`&=x7;%P )O^KID^Gxsh@h6#9I^hncQ&~;I&0zj z<+BX@7Oo5UA@-rB(?0{+5W3fhnG{Npp>>P0R_UDwgz7pMT^BB(;WZrV2<+ !fG&kQ1A&AH#0 _HdEKpTok= zwm7{?dVFSrizKB#9YypbKQFd{)F1RUwN|sTPrj1}k2x$49}#NQ4<;H6@l?t*+kc`E z0I+vLH)5}MI8tlAuEP63y|SuOu~2!K`vhbAVmQV*HZ~TjYB!R31@?5xke5MJXlN9f z&xt wxs5u!jGi#l_QuksNmBky4 *$6y*iERH&5aL*%rnrMYmDo|(6R%-Pwq^tbZ+ z(L_2&-p6k%>8iZ;u#^2i6)K-D9GXaGBnw+;5I8qx#H_p?hvcK<5cqeG3yN1!XE6IS z)>hIrT4Iop^m4XdQrT5hzzizLTola5mo&X!?}l8(rl$k&k}-}VHYus6d0gq-o!?hy zkMZ@O5gR@`YVhJ7*BH#pmnYRV+$Qrqy$bXZFkBA$iOI>)jU&rOx9ZNix}=ejatR4o z6Jujij*ituS$IT5a!yX{RG)A-(uNX8ItYT$kRyrtz&&GOZJa&ck=Smzm{ibJACsOw z)0< 0f+R2CP6~A!~V#W-qURpa2j^h^R LSV7EJMe;gF;Z z?NEj&0Vz)bf=@%v#5BsTW?9gRhlMNoxF!~WvSp6)3dQK7HnDLyyi}Z|lr$CPdpz5q z3gS!~s`u|hVIqTy2W2~iMM9&)b8QB9D`W8~r2K^6qT}MS;eMx!@`Z_{{jt`uK#2T; z96$0!?$`%QSvIOqoE(iA5$BG=A|j!PXe1w}LmiPB8Tkeqf9Fw9+T9In8LAlziT~as zf+2m+99z)$PAM+Fcc_d4_M0yZwxMCfj5QPPsA zEP zSx03onOCP$xce58aiZexJYeMI%k7 g>7$A{TalmdAxzL$DXTC19B|- ;eMp~Ong+LUSe&3l~Jy!LZ`v8+RQ~t>I?GrUz(bt!I%|Y?9ELwsW5b_l@f1- zP2aP+ns l=A(YW>-MYW+tbYf)oX~)Bek%-@J-Rt ajkNip+GP@PSm#$7npIBEpFdYDOovUW z+@~`E1z^#I-8NgGu%A4HaOP-lkCK!WCQz7}OfYuR+`-AQTKyp4?m-PfXT*pJ7v^PE zgN vp8Ti*!_xL}~t%f~lJ|4yI$Sr6% tqCkG-sBoQq0K^5uFcb!i&RK7q*><) zqiB*xxQs%|lnp;Y+T@Ol5VcsPsHi2EJ-RnWzG^n2li5D$n^K`@(Il8j(bO~G+qvvf z!A$&U|L}sDd5of~cfx3QtM%z%+2L-O=<$Z+G4nHR(%8hr`t fvBYXSf^Igw|IKh!xFlj!``ms>?yE4tkcj-mdG&D5VfckJ7 z{nGQNnRd3top-tUSnH7tV#DoTpZV7 A1mmFWm*`eV8=Rj0xhIq7!Y^==DnxE{R*;9H9-k9abqka2N#vO9;o7aSsM7B)@t zIy%cCF224nC9F^51s29!BGWUb#Z!JSGh`0GROnM)TwIhgMPOc>1YeB^by#QB%lV=Y z(@`5(ZTA~vHbWw7TN&{myig*%Rf#G$x38MV*f`kH!J%Sm`VJNru(sSX2A?n+vu4FS zHH-K7&6=*V3uneA8mk+xZpQD>B&DRNSjgfIt>gC^4-dn0PtF+*c9zUJ(x{!5$IP9y z7sH)+7E@T9cpg?h6z|(dcocy=9(`azIHvO4?*pmr2%66|<5I~WzW(N)H xVyXKcm7F)+8dIpYhb_> z-8J!ea-4_Sl4;>+V#SqwCyXDI0nRyv4u-xVg!D&A+4nk%As6is& zoSs%^jfqY?Oi ^>1Yzo7g9Aa57I(%gciqgw22|H zi7A3U0(VzO5Cp+%2Zm;!&_F*o3L4C@Uu=B8%yjjf@ud^LO+_)7o6nnBnZISAN$5M) zB^LPQ_Yz~|72MZ`NDwa3t#@gi0~bG*2~axmO1dX_1E`7O3pLc-;3MURww-v8PLs2h z-uH67yt|`!Wr?i2OhaBeKUusOv03 (SJ4|&%Ec?rE3omGD}YWlTolQ8yjg}7*dXPSZ>Z*Tmp>Hc&8OthW!_h!ZX7D&`d zd<>)QEi1QM7uWW>nA{nC_ZksSfe3GB2TI~vrE!9K_$pCNtNI-y(EbQ{NKotPt!^-? z2|vblo7Sk0h2nVTNlHqB&h=T^&=%5XniRFB<|8oHc6L$b6X~*agCcmhGa|W^E^J`S zeh``X_wTTYw>bt VyJo?{rrLwZb zZ|`puhIoDL26t&8((w&{>#oGs9kpQB%|fH1#N#M#?@Hj{5#ke4M1_S3F J>*$mkWEJbWlb5``%VKvCPDU&h4d(11o5?!Daah&W)xTTtu&~~} zFok>Wr;9amxUh;O$c#m`S|qHS9gDIzh4K2eFF4_n+E>db=I3dJX%JhKa3jSrFfq-n ztVHsZJcx)DRs@5}2EUmyeJq-+1d7*lci7hJZpL>4in8mI;+7?gK%|L@k0H79U_YlJ zH)F}MJIR8SmYN_*PM{j N`f5%K~$+PtQFbnLW q>Ux?=OY8nqq<7*Pl}UBZf(-hGoze ONVH_+ aL?tBR0wh>!vN`kX(Ef%SPmB5AMxBVSs(a+m-_D&uaTgObds)gn63$Z z1?ZQLM$Ky|C@4s!!e*0B6Ak#NlR%~{RF3k{6cTy{&=wdtczARIB6cl|f3fu6E4@Zu zOJtS#?>lAUf0rm77l&b@5%iyH{`b=D>0(?}|9gEM?(~~VLr^N4*MOWGD4i! tswVz_uJ=_)_9uff4ZC@b!{?;NL^Y6vu@hcy;fv?SKAq}368bJJ zEvc!HLl>caB7D+3!|Ek;9a9WKEZ6_Hp#Q!3|NQZlJKPqkAN_y6_@94m(UA>i|8KpH z;m8MAz&IBuiEOz*Ir>c=3khDm1iN|3mqLow-TL3p_lP7J(P6V1SK&1-3V=k7NqUO` zz1DG(nUgUQ$QS3;Y%Jpt1&A5+1&`rufmp@9vQknegL7U9E;prUWUt|u%(0`xfjaZ* zs@{*hyrEjGvYms2ys9c#7`4n<2N{f%A!EbYR0V11qy5_8+pYgIKOe!rooQYv6A?h) zpu W#d9#>+e1jiII1!TNLIzy~Lr)D`{`7%$~ zPng-mtp2wwRhUfa#KQR3&Q($tvag`+|DOB3iRW=NHrJ4$PxrArwf?Yn$eEwI^Y~Kf zeInco{QjZ-w@%t&I)7YDvQoDOA&^m1HZUS(KG?EOt$>b!F&Jhv;K|^_@E1MZ3XhPm z>ogC(>X$*O-tOVnZDbl78{6~On3zN3Up ifd zlKadUl>RmOT`_BUztxP^v&blgq2se&gQt9M$h7pZdt9;J)!SX^y4s $J zLxUS`q(T&HQCV4ZNXRyxi{UfLxaTD*5*8K{5m_4lp4G|r&JGnXuPRq%CJcxjA)$6Q z&hVB1Xn;`}kJ~hvjAZ22Z}3Rx>35N|4Ij*>WF_so#4g#dte9xlJHm(Of$>|RPoG!; zVRd$Uol7l$di*i3*Q!cuq@Ss&*-&ju$c?-8@u1Ps(fKyd)8#VN3?HAs?dkz-hXfb5 zV$qQ0WVrEYV%F%J(v3q-)QaVRMK@&?y}_{Eg*tPMlhe$;Gl05GM!ecjF!MF =$kz8s##AGoUhrvE?dp8A=rAx8CSQeGV z*IhF2Vk{K mHohN(^ z4(kskDid>a;yeC#+8Iv^$q+LO3rI)a02> AW z4G&(PjHovQNf &S^&0A7lja86_87FPbS^b{`L&mhCGxda zpOoUv%&ayW7Ds+NrpZzX-0U;mWzDZAFMHc6zCN264+)LxFt0fs^HaFqs1n& sb$l-atJ%;(9ks85I^;@N *o^?JmB=Bn^;S1%i+Tt-nvyRC?Z_AgUb+uN-Us)Lq zm3FpKcwvZ|QDA&^Df(e+dxs};76YMe_SHeLT2+6Uy7fZ6AKiecgap7w{M1V>Ep8^n zOzIpGbtSVATiN10-7k@hWm@OG>^|xhGxlX1Uo)02{%mPjJP^p>@P%-cq*RLgwGmM( z5cgU-%U}N8VY8gC?aa3yG-id2=zJ(tuC!YZqNWm#{FgMo=3} zE+Upr%L*--Cy zT3go#pzqoqrzu$VL>!&t0pD*F?{RU<$LHrIz%(@An7Vp;T%EiFg`bU=t6huaz)4s+ zsE&~L%D=`#mv>gduB3B-9P 97wKfwPzwp~3*{xp+3`^Q=T)%|wz?SAl zu;o`ckD3+q^`F0J_Pe}vE=|-lxl0=QR2$4oSZPo$AU(|in)Z780q)WJ{&o@E2=Vc) zyip^T$RZoQJ6CfE^fj^ZrRANmkpjDv(*y( u@x85@^W_K4K`30 BbFR%?Duno}>< z0yOYS@HXZ1Kyu@Yv@+~u+sg$U@^raRIix fWRKIVERlVR z?w(G&9Px+dTnS@^R8cKF6Yc|*qFS_e7(5=E62*#*$&_42N5}Tz;m_h?La {T{yjU2_XhXJaD1YdnvuL%YVKqA78O zxTLEnZ|1e9n=^^1G$62#zJ8k2+Vc{aUhNE?{axdI?2tY(TnzpG-2~QMK*jUCeEBk- z!9Z8ncWVp#b~nSS<9}L!J9;<-1Wasfs&xJTluDi*)FxBltn|Jaw$XaBnJbU_(be@b z3RGhPOLxcQnLgHx1k)t|D)I##^BKre)RxP?0|A$!^P?V=w@ugg0yM+|KT1kaBE{vD z4Y2^(ML|vJ&iC}2y~ypTGa4X%@bh)nc8Pn|^RAHPS|iN2?d=QoPHC-=jXo=aUVCXX zM5qFf8>Gv(w`rgrKq?yQksu+#HBQzpU2f{1UUto>{_9rl;;8uP6ECGkgmFRhzB2(D z$>&P9PIslClEazm_F1VUBT(ANKdwWbNFa=w6js`Q0&W*(2j`ttiY6_WD^o*4j^CrP z$;5Sm?0lUi_}B_IG9{>6e(jq7p`~%%BhWc3kjfo9ew1ikPtD++`R#`3o)PtH7hl;t zah}K7#pP_Z7r}M2`vE9rUaBQ=+wXIc+#ecnl &&vReH^1fBpKE%aH5O zi1*{G$F-5xk;<>nZxL>9idt`YrL7knQQ{Q-PW?QzMw{N 8-AzfKNo_ z!BeQzTf~oe;lI4EsQs}$P)3z0Z73lz`RsmakvJMO=RKAj6XWB%Q>pB~8R94!_OE|D zs!$n3hn6Ou942EDu?GBznE@ojs$LG?J6g!m(@wDEQh8L Ig>sSr1R>UDKOm%gw{G4}g>NY+G;(dF33adqFd}^tP9Q?=;OaaVFLkUbY z%uM5(Y$RV3&S!sp;bd@3ZnR{Sm9g+6gHlqysB36csF(bmoOF1&MFCoheuCORJ`AJd zOWl5~$!?0vFMKZsjWU;;>{STW0i?aq=n@SGdq-%uf|REeIBVH%xcjrVHVRDsS5{Uc zA|rd!RDZce5HB9zKRN=|4RJ#QI29a%y}3z$w_oFH_%qW|U|?Wq78N`L7@g;o(?%b9 z-EeW4J^{a!x&V)xUf0unUhI(wwfI3+80&z31rXE>-}U5(w3O+#0#6ztA))ijOC@FH zjd<3gmKMMka{!nWbnSXI>Y+pt`u{o*Xs_&PZ~Xp8tebEXp01U(S =qKDCyI-A!Afh3V z@;W?wcz6JC(kK}FkuagQm@XD4c a0()iz7xy6)RbA zWTgg7gXRXz6V0s6DBm;N1(4@d{`#ija;VGVWKcEBlq#F@yU}YLV#Nz#)D|@~3|QVx zNlp{VW{wF@E;|Nf47byz!&cspm?WO)Z*#w2vg0AU@9q*n!$ioRk#Xm&7mfb!-vwD2 z3)(ae%MWD^sDw64<(XLz_c#E+$(g2>l_6TJc*i*M#+csgSj=Pd)Tlt2=J|6rz>R_l z|FzpkQLDwj3w*0JyE5~?KGQf`E%*5OXPpd|5&@s2(}Kz{!TSfByGhizAGn%s-$lzf zM?udpWPJ9TT#J~``TlNto5K^|n|7Ub9D1_zHE~k`@(Q3bFn#^QWHdB!<99|In_IV* z%RAmJ5y5qkjQt}=GTt3Wo~%Q`mTHJH-l8f@jO)F}S V$;aB#X- zI#h;+g;DYG5dwlJYgX3Dh!Q&-Xp!t?sW3r@L8sGVDec}PqRChlEuX(yHA1GD^$hAd zq7dy67c^#Sc(xU4GpMDdrTqDGh35?m(Bss5TrmJKW2U3)R4^JzTxO;az;S^$0-viQ zRXP;^0R_BgM;Uh&RS&n~FO?z*Wb5X~KQaM9LDysk$RK}j%DjSsg!gnxB;I%HJh0bU zFB^H!@kK*O1o}7v8m$g-i8=J&1!MtFF=G0G;nuf7UL5$5O_!(P;JoS8uTWG|>%K_i z1c`Y0RHJe{=d$t(-46=tlfC7Z-XJH7FEO!xvzA*KF3aR(WQ6`pOt=EF-|On8X}t^% z*0p#EkPkcCZo;(l4bFlt(s>+`YQV_mV+Uo+ yH_=&Y_?{-4K@DwCcMicdHp6Z}Ymh z^N4WXYi2{KP5|5n^YG%i=(%H(ppFJqiMX)irG}*dk;z|+`(ikKeSJ;Z%D?6S8Tod6 z%mfr)l5!c4tFxOwrV>+%yub)!q+X<`u`vx4T|gSpH#9&l@b($F;m*}I>pFwcz0mM* zat@B9f&x?EA_a8e6kM)F%c>27NlB01CQEdY;v$C1SUT9tLL}L1-w^2WGh%mZiS_jj z#!T5t?LD2$QGB#fy^<*4!Ql)9)Rm@V`u1noaU8fU@^KV^h#6o2=X`dyE_AkohK7Qc z_N>q>x1rSN=WLZp9j(b!CjYR -AAh4h8cH zfTs!#4P9t*iw7YpUnwpRZWu6d0z`mD1#rVke=jsJ$!J*OfJ{Z-z~D=jIpvGyOrT1( zUThJul#PHq=Yxt+H#^8GS#dyxyQ{86x{h45F?4g`PIN#7{M%4fA;XKc{jZ7Mh=IV@ z(X8*gWiJA$DV_I;%kzVm2<*@hJso|YMA?KLs6LzSRwbbI<=s#!dw@!j(Zd|Or`_Xo z1c8SLl6w*#X$2cb9qszQ<%bI&13ha7Eh@~ $$e359rmjDIR%v1*?M{^@|!Sk+1%0;PyeUoKyV$>$1-seQUR*3m2iM+bWqG zH#aCJ_3P#V#vw0JNpLrRfa>n<{;sHC<$SivQnNKGJNraOIXL-*?LmcaHn*n4s^fRZ zj7Ki@9r8y_d*IBbib;&!^H9n1?VCp5U|&j{SN`1%3-N^8(#ihDz(enRZK|1P&9ZAP zI^unxpuO=8k0ht4v-4#_luK_St*WG)9MRy_L 6hhf z%=3k;bGxFX?i;zz*C3!nLTte?YieUd&dM6z9iFUPaqe()YNS%8&2N1;l)4eV)|gJ; zBn1L=Xh^O!Q4Rc#jQoXL!!`amhE#jzx4F6#c(A3~P?p93j4Z(g2k}tr%~*Omo<3)0 zW}dNfKAlLvIw&t^N}|{30mHZTzyObc!}8do)rOBAbmGGT*^7tiKei<30sQq_-NbbL zIsh(Nqyn-5kKv!NZoae4a&od0p1@umpPv48(K^5O=ZoNd+Zu?W+vTjuv+MmTk jW~J3ZfUJYfK|2`1T?KlqvgUiTX`7|*4Gr*t!q25n-8bW@DboEjoGvc< zP)$rqz%-87tFyj=q08NSK(9AA-J!M~x(w_303f4oo=OB9KaBexQQ^r9pENXr)pLL5 zR>9g12gMPwxX8#fI6)ZV;0}l~KovfI6jl6|4Ikz1>R^+^=UUKBQAHk5=0M5ha3hWG za+LU$0!UUNw=L9Ohx@D<2Yl#ub`=|&h7Q*=VDNrPR5HZDxHZ3)6BoJZc03#lTdUh} zSG+`pTxyt4Vtw)??_uPV{W{fw)d5!w&=hTL;#}quAm6d$jF~xM*4E@(IMKAO(x-8p z>O9T+P=6q3ixYeGph7JbS5Rb=U0aIUI25(0mtWWr2)W#+V%s?R6P2^TA4j2AH_z;p z)~8wS>*e9>aX@!!*h;-qx7H8N@7+=Xf~nFAS7a_6G$LL%q?bU FB(iCR)nu6v2b^GiU$tAF#pprAnaDe3bE{Ew{VG)17O1m-u+2ktNY z$3mp@I`rxcnA5mzcgbXuxjX-&a96eMFlp9W;z>jk=Ya3Mc75Waq#oC=QC}opN23Rm zI&_k@r5mj}T5|eI7#}~5Y0|$p-s8NAEXpftOb+Li?(ZK0$Tt|q>JLGKjO9vzYU0)s z!M5}_UWZE~9T;I@RS<&)H@Lphbg2m<2}iprP+)xqV_~=_Prz`6+NmX!%k!G42w_=d zc*fFlp1GltfPesuyBkjaO6=<55_z5kCfBvKLGI5y^{`P=8ea)x1Pbwvy+m7Ja`uVm zNOP^t57yAwI4*JX=|1LPox)f0PPI(?VcOya!a=i8j$#ZCV;~nNbJQCocmQt!e#Ys} z2gIYe|Fa?|7`)IB==P^4r7+xO)Q28A$4terDwZ6)G>Kv0EC#k4AI5d#loTM*VG*J) zRQvpH%nGgR8j4H+@rUjY0pAtazzqin7n6_>qMp}bT!n7RhCzbUJGq9j `cDIQN&?jgb*NGv3%5k z#ndj6&Krl+vg4z8I<8>WS}yecdNc4~j0s*A1tqVp3@vRkXepc8LFh#qN3lz@?t3gG zAYT0V4y$02=IirFAgD1o>$&La5slWk-2Uxaxg3A0aneJ)q)D5*7oU;1bAlTv+zu}J z@m(S~cL6mCZ6m!;cyM*$u2c}7a^P@tnJ8wOqG`?j3iUeMaGqpz+S?8C|4KCa7o zM0uCqbjlyzB7xBfP!5Mgg`LiMcRIOMMt)eK2YZ2nni?TbNlI7uHP}Eviklz}4|GA` z!7zbe`fUy@n30Ezv_`<27I;_6-j-EYJC4I@0JjI+NK7=isp)B;rR^UXp=M!;13ME` z =)P%@hK^i!ots;oG!pPEhYg0>rNBXr@V&d@FGAAhK7@IbHt@r zQ`nEkxgKrflnNb#7Wi=sZJCssK6K+te)EV{bEGzbuMp%ZCKl9k+m7z`4h~~`7m`Tu z57@6jh9bN@#kcbx>AbIwz4FMAmynTp1 5z6+ExztFqqt zaR8%RGZzwOU)x&d3`8!Dj*bE+R&2@D_jj#N2r5O1_4QxsP){s2QOF<53JSo^HZ@Ug z_gp6O$ntcLu>suocNK@q#x&rC=pkT=%W1O&?SPWC-9yjM9YHe=sGNmnk7V! PI1YF*!N*a!5xG0CjPy-SVFTM&KJPNnd4rUC0{C(JyGtvexetkq zbSk0Zb=-cPuaLF1J6QxZyiiw{c5q+?wR2~==0<#8Q`5r5e%34S93t-sv)%*bLEN;U zxR~N?d+U27C~0-P!F T?w>xIyxCX#+HjYn;u1i0pHDJj*&AfAq4Pt+uPp z8{`hKf_q#G7QDyN_P(Laui|6?^O!IG(VAg#aeJbo0nvEM>9W>^(SibPEnat? --YXYo8gtIrw6#xT*`wVT}&fBm9aa^EXqz5@v)nNjB_FpjIQ=fY;t1mdyugrJ{4 z-C0-{%ihHgWxXyG6aew5?p{Z}Lv8ZP2DrVTs;Q}cp~Gg-X^9vzHn}i|z_kLO6bxL` zE{eTvc8w;6iR_6=mkFe-bGAAcyOncF>%`BeHa;gA=yyx^Wlz$U=@Vvu6?J-fpVmFd zFP}~X?`=-UKe>7j(6p9KxnC__eW^A@Z)j-1_5bSnG=uX6;nt3eknpB*riO)<`MP4= zrZ qx9tZ1}U4MrZZCf}YngwYAPk^d6wf`$DJLsIs4) zg2n&%qirn0o67sNpBgX@J^6`h@owTtNlQit>LWRCd@if9-b!J_QH%j|gonGUSuhdL z>v9OU(zyJ<0JvrFBQIdmhQvKQcmdKqt>cs7cD5zo(p_l#c;8@`wazMLwzG(iFYt8l zpi-*I9UcY^Rwf)=cbunHv?rsj4rK2{(5Yy?r|Eb*0G=#9z=rKwZD0wXw>z>BP4AZZ z+!069(5kf>v%l|;PurybN0ZBb($W$GKvsgi@sJqknHp?Yzs`FBOA9CqZ#0kuR1d4u zo@y{U+NDNM*9Je=?bptvo%z;P-!s_T+ryY#cdx#E0nXhBK l34!J zqN~j`(=9ol)nGV@*&77VxU16LQq_$`!+F2aODD4qsM6 WWtot<+r!s^O!VhJ=C+g_51!sf(jTWx(+JE#G@kip3=- zLu+;Lr0%bK1-C%G!C->Tm4#>1e1Q!f*x{iyF`sLjg7+!rk{g8R@s#n&UUvHyydX3% zWf+?`=8RcVuMcc|1_*4Lplle4&pk8Pgr$kb;PeDg5WqhAf#)x1NuYKjAmIRP66#D+ zGp!AqU0xmo#4aa21U9d+utYz7!USeHYZ}Y9Nz13h{{#$7IOxO0c% ehln8W}BD~D~vza)hA8a01j4eKg%*!fsNRtdsH -}7?R8BZRDzHP0U!a|mX9H$F&bWnOA zAt7Cl`JFYDJ4H@!Hu>xiNM(7{lhZQ44+WN)OZ@hzFn~YvN>i=$c$j%ZoR!`XF}p@s zFjX)~K}GpdTkF6jIEg~4uQGy;*8!s!;EQOlu{k&-V(5U5p6VhW+vWO`jBU0bOpSd& zQfNAbh&-K-`9~U(t3rwSZjIofQM-v*@g;M=omOpQX_+ryw(IrMNci2^Rx5Hlo#X@M zG-@MeYxO$aTN9tym>10Q#!LY`+-2 (*x0{MLxBnV*x$choGm9P zmK+3vPd6j8%^sY7etuAEmw{x)_^hmvus5_&OA6rY %*y+ae1B&qG9%7}2`Ug6 zFjTe}FL3$zaOW_Unm1|Aj2{U^VlgQxA^nEmf!7QekDV&fkN~shI-V!+d(&lE$_!XG zGxaULA|}KY&PLDOGrnP(G~YFOibd%-$#%tv?18;tXk--G=i;z2Kqkw-WfzUYvg>NR zxZ&X8`+BE6Y~anfzudaK?t;UhDXF7F0+2|9%(U6rS@7U&L5jXSTnwih zAQbRSkxS!fKq;J=nCN8mxslQKd2oU{QGECS1L~#whvg@JkIVhHl$3!$=z6%^I?@sN z3Yr5!mk-@pz_v$GS-ERGPsYUYv;fGy=ceREay^1o938PhY0mmn0;*fkK?(T(HC3dz z8@rPh)(*z}D1fyE>P-ntOFH1{k_W7IfVo1g)qD?Fdv2%QztvpTe}5CcNO(vIh5d{C zu87Z@q3Pj0+<9z*k^(qR%xm1&;;)~9hF++BhLD{m52?oe{*47qo=utZ&rAV^rFWFn zoFg^r49q8Xl3S;zr*_db=V {{baxZf&D3x#GY%Ke%zOb;sp&V}gT~nTJ-Suu z&$#S1IaXI!Vd$iY_6C7tZrb17!a~!NE=LPI^#|5Z>Ocp0`Z=6JN+CmQ>lb!=e0zyT z-8B$H4uMqwvo1x`y$u@OIImx~fd-8mG-o3McXVJh3rs`?+xXngTMw98TK)iLUH~RO z9p*iPkq>sz&>#SQ$8>6y0fDb@fI+<^uzgl9NdilMT=sNZ287dL;o&!rSFJ}H-Ch(d zEMI}H6vlv1eQfL_-JbzU9vX9TcIa6KKGEj?)_fWBn5c+Y@KRpUXwv!|s@9AO;u>3r zkmhFI7qjV;_XgRgA%im$*!zIlaA@cIaC@=P>XQ{utsq|{G9ZMzH_eOi!m91|Vux5T z7*1kh?ohW)MP5yf8#HZweTd(4b6=uf>d3#dnQ3wFuTCJaWGiP74EA7;1YJY+#11fH z{qCd7B&gzRykJoC3}5vz0}Mm_*f0ddKk$bs9vH#HoEughpP1lw-hT%c0OX3Ondz~y zReR&epCu)cV53W+AS#Fri1I~3m;IX+eP^oVz_!Pt>EW`Eq`ojA9{s_mmgymOdXc8z z7HdpC&C$ef-(zjZ$3Hj^QzxFxnO?Jw>x_u|0-SHj=gBKBF3$C!W*QL;f4Ry^NxgjG z@3(DwrFYI@vozQU3|@03qU#-ZFhF&KDW4Ea@e(uyAKKPmH`=s5)b0s1f&)+B;rtWm z+n|jOIXQHI2s{`dvMkk%VGZRCPO>$GJ_cPL;DfTe cu5DVQkpE#!NT;xK!e&wu+>T$5*8V`xzQgF>g_81 zZX~cup%D=q_n>t<9Q{W3@#9Az*w;5$2d1rnQBl&-QIP6)0=fB1J(EpOwXAAN`^pE{ zJB||HD%E;bEiok}mN#g$u6ldsFxBBbB &!uG-1FHyb>dKrp^q$ z-S5%PSdGpY_$ln{v7U9jVvNA8UTon@R^)8(1DYC;SSh% okw5%_#|we9TyAaP1IYb19q{`ZvXtx&|!c459Gp&!jL@Df&M2#$36 z+;L*jyutIiNiJ9n_@4H1&SUO<31ePW*}%c$YcHl$yVL-@2grs)@3j?$-N}}h>Wrih zA3>RBLx%*3m#Dfrei@h@3mD-CQ*bUWoL7g7>)^9oEP)gD!b@zx#e;L%4$zcPOPy99 zL7K$7n+*{4AP>AIAOK!gX+U`dS~5jVO<7G%LKvV7{a2;z&sKRJSm*#UB0e^@-NyTj z0JOA-FJGp{5qTQ* P<{MfS|@FujC}-+X*f!lvs3GCF8Sr0nqI zU8w4>53*2~vVH006aD|R0LC{RH*1Ze5<#)CSR*|~4b|0Y<#U#OAD(;@lZLIo>~W zc$)lybp~%0Y=0J3R;`y15n S7fFMr#e$HQs;4!#J9+JV9H_5bbR9W5wBibFL0ZOkx4<+8 A0s7$y-j6)3n>Hsux``abWK>-k zfe+kYWr6dwq?|;xPZcsE{;XZwva?3p+BlYM_34;W6|oeeffEa3VmrC&zuny*?90x? z1|&_A{4)huaikA#i@P%>kg_-Q) <#7 z>I#id8CvIE4F;l)nU+Ph5gDW8234IuzRe_oKS=pGVAYb|+t78s `Mtp*pZ;HGZ&aP0kcjI_RU~by+LCEHj $72B!-dBvlo?Y z1C9}=6IqX7bj)waI2ZJ+pd5f2pVaBSXm1!d2k~{kEg{%pU03CNFlXlk)~e-Z$OdrQ zq6P-!aTMHTa)BM6y+JI2B%-XM5|<1~9|a_#z4v)8$;pt7_k;<-wLdsMu~AD$F{0?8 z$Ac_2`BD=&PIvbAk3C1Zs-%FT`+H4I;>BL~1r0bnCZsGZX#2_jMy}BI$U+8p5830{ z1w-6U#!T7G5BZ97su~g0UidTkZkNBdbVk@rbowNq3hHEVCsg$GD0!z94#s@JQ((7r z0dNJhPtyq_{A&L%^@RwiuT+37M3|?RGWm-jyO^S!M{1#5kM+NzK;9bvRZ?iYyp>3P z*()A&vlu%$HPw?kkzem{M^#f(12ruNB2r TGd_+I^2Ib9~EzlGJW%=#qEZ{%Pq3nwO{ISVK)rf!$xPOaA`FwIt&gArTLNLEg zMdz_Ip0__=7abGx8qiS^`yP)skbVF?KD0XRsdRL90!Y5Yk^>VT{|_j&wA2B02eJ>x z!NEbP6jhN*$#) h5(mO=0ny{H>kHY(_CsHQrVBe3ZuWdjTP&CPL z__%r(R7S^=DmNG| %CuPlGl}R$fFdz#dk<}H{t#UXMqO6G3+Za|5#>sxmN}1^p$oW%i zz&3aaN5|6-fLOMQR=@j)hqpi)Gp%_B@>?Y|G>gBqgMPW*c6BX+yZR^V;EF9s6JH2+ zkr!PKcdd5Q=3zz)CQFY@|C&R)Pv80iTMoJ*ql37L)kl!@@Lrpl>hF Y@9P%Gvuu%NVAB?GWJU_}VI zyk7dA2BG3>@JpoNDhzbL(ou?e!$jFg$nTy2$(-jkaK;;sA%C?p*NkN8uZL+O63%-* z2h;JD5AwyacNB@Pe?ekpZ24nUfRWxaC2N7x^5x1y_qV&Z=5x#UsI}X!s**xdIi!bq zIC$HpB%GcZocoK7CZZ|rtF#phUM^f_V`c%{5?eZd6#5aei^{?YqDvLj6@Z;DkO-}B zC7%We=jdK^z{8lrvi+d$`L6Vy+ivxj!sb7)fYg-*4DtP^qyvRsOzLpz r-$b&j z#j*+vYI=*Pmkh7X(R|QHh^AI%R;sk8@^!>Ep1mo*>#=V{M1-2mJG7W2jx4Ak=GW(W zVCAy5)*W88Hu~+5$^X!l^TPI6^DW?tehm2#p0ZeZ<0l_|9$Q%G8sMF}xkx9^cxII{ zZ+*5&&u=kRYI5=If`WoeHL|;_3+VILryT?%)qnr?DBRhHXv>jHN%aGu;KY_`UkmV0 z0KxK_T5~kypTfwB={j6&1f~VTIf|oGQ}V#L0iYK~{c+u(Nr3{%hYJk@iL`;Gr=Z*= z^;M9k*V$LnT88_OU)Z}jXnw@>adC!a=j=` E@6$?)d@qevqGFq3wG{Ay-wwHec;AoAB<8Y1)Vs2Q8@#7P!Dj#y`Qrw+8N ze%`JcTo%Dv1co`*v3UHUJI1y0^_3SGp?LN9C)MfdP^+xfBWD8@ufL*n#5^%fhVxLb z_T1q5Y1X5PlsD>Z=`2~zsrFFZ#x(mG25%cYjH=zUno%;j)E|Z#m0kx8Nz2BeybcCr z#$;6YEUakWzt3C^sPwmth^-e=Pc-M(%jx^E-}fhphKARF$gcOLz{Y?Pika~fXN07y zvq0XS75#De{ZfC&+VVnz@SOXznwn0j)9}^EQ!*@ywugsck9M>DsuD8~kGtF(wXdkGR!y#ZI5UkrJuSx$or-2yD)q}} zUL8C{N0*yT7*E;QdSp#DfAX%dbh}+8D%NoE5bBVKeOzd*QQvuvxXhSDk5iNktomV( z>jd3i`g$DB^oh*ZRYD&89ph r>*3w~x2{#@YM6-a z>M>}`!)9#Zis2o+nslWZ!NDCdLn*pg@_vOAyXe&9+NKv{)zPOqof*y}7Y{0dr>QfT z^xw8OT?T-$4kH7AZU6p0oxi_-vSUW|SOsQ&!%>vn{eyyzUiR#YLe>Ml_vNj|{RHDu zy`=^X9g4u+J{JP&zR5rmJ-`AF)zd!Z2nQm)vDVi-pWh>}*$2K@ma`mf+S0(rR7HL$ zjga$`Pl;kq$7JreD_Z3OTgopH{8i5TGu~=DXA8%jIxQcYIH@)#>jYOatq5*bMya7M z-9W}`{bGNi0n^vd?-{Yje#O^O_Z2^cBrAooO(a%a;mc7BGDGn3dA@sD^V4NpXqgK& zrXGgR?$-jd#`!N;y&)%3Tf_T|eZKigseHd@EmLs`wu;a!A>I5Q4G))2su#^0N|p_G zhmEbrWlc}*XpgZrUV9oc#sl5Qk2$&UIW>DNjWc(vz4!N#b!DOSUt@Eg9kyD$LOWXM z+4#d;xxmEE>M?sM`U#@;{}J_;L3K4v*KiU71b2rJ+#P~LaCbjgaCZm}!JXjlPH=a3 zcXvIwyM8;@{k--4VpE5r>df@?tlhnOt;-$npJ&k(Q)^y?lp^3aF>#xXA07pyzSVOU zMD$?9B_*lBQb1Xm`TO_&;rNl vTq z?pm0v5WL;i{JEZk{&n#p)lxNYulFl5v*Yc%NkM{`fc93{C4imd_}{Pj!3=NP3=a+O zcO6ah`^rV~z(%BEW4-SE Wo3w_@ID3Bg4$cdG)cw!(=lhT8urFj$%UgazwXd hpUqTg088~Z69g5GD4u^M`Aix85s2`M+Y;iplGJ<4ag5lU; zWpY;{$BB_3#>XVV$K*Qnn8wfF2L#yuVWGE)225G>{1>Iu;_d6p;vLg`aDEfM O6_+}3*0&s_>?O95c?O_~K8 z{hw9PiCdGR%6$CtG|Pf(tM>urIUyIwqdlhS%-qt<8Li$%XW;K8in+pQv4c_?pR*4O zRspB$K944QX&bHP2foMMZ{|H*Ct~gl&!FGu&f1M#K!@_5w@fwdPU?n70>EFR89ukK zvRI+l;eG%Kn7;0wW@dd-w9aGeF1Ko-r ls0IZp<#a52tJdk2F#t|xMlpArCU+ey*iGLr}HKy>^ka{faZ6;Un z^`?YWeT8P|JnH{aG9b2C Cx+t)H}P_*I1$m EH6RgMbq4Q`RPUM3TED8dxnTgcM0f@C+`6}II7~n#>r~&; zHXP1}3vRQXN$donLA24~G(9oCP%#u3MidpL*Pdc)Hb=m-$<(@eQ~ZCYtjccWBw1x^ zUu;g-2BFnq(}0iDE|5TTp~}vOFtgz=9XoM2Q(7Bik5 W<(ouI2lhYLqM-K})n% zQ*=}w6#x;Uu4ih}GL!RDaV--7&!^8MLUdo-z=%h6%XQx!zVf|X2>mOK1J{v6LjJ!F zg>g;a)9rD2o!P$y5dN3A7CwP2!kHE<1v=|mo&Oh1mB=}i#3Rhx4>{HqunRC(JQeLy z|2we^y&{=MNc=Cz_p1&Q7_kuiZ }0SG&5`ThXqK*AW`t%*=Tq-c0XlXD_Ou zQVYG2gNtttr-&4?nJv2(URT4K;iYSx{4XbLsu5gxa_N~{^<&ODm?%!XEB3jYvrSYw ztJhyMW$LDWR|PJ81{^7dABxQap*7QZxchdH&VJ54>{-#b&ARNxt2F{w)xQ!MnFOki z%N8V{E}$}B@xEhW1p>Z2CJG?F(G428xrsolZ=A!;nn})G!dL$#7R40!%RN%{c>ZZ! z !lEOT#=v3cAtB{ zPLVBrds4hW;(wiM<%NPuL3q0;W?)$2t*Gx%ZDhI_O*{wRHXv1c|4LZ;71X7A4Oan# zi$r~-G_sgN)zU9~5koUceC?*0bGPa}(H}7dFBg5f4sPUnVC@wSrzd!YHUZwDq3Se% z3oxzDHpDF^Yp1ur@UqnKwW9#Gtj*n>{Y*9{4zRI8B; ) z)&8Mv;b8qGjmzmOv^+JV{X^%;$tcF2UK!cM^-+uPe}VWQ=+Tv-VZ-?S`>#I!eeQI` ze?5sh5W+0j+m+E(HUpd(2L|XGel*oaO;y(!?m%hT!{y?eL=0fLpo$yOAG3aaGRw;U zHkT^xY|qEz7P_mev!&~~Ga?;M*U`Ln{ Q)(u~C%1M5Nv*B`uGA}3l!S<%t4AILY&B}ShU1`yt zWHY{jZ*#NI#O11_MSME^9_g#`P6C~2K8`NuI7Oz1Ai79thE|WypFbDV8TXH;+V|Ql z?)RrF6L+U%3bzkCf9@&20tywJfL0!ep;dkB^?svbuoOUnKRjM82LMX}W>(hT(b0(P zo3Gf|pV8N>p$$fX^|g@6oihBH1(MPJ7kRq=|0p(YZGh%0pM9B3)8UlmcLi8Lo`mc< z)!Il}TFbT39pmA7R>Z?QGl()28z2Ag|9`l#PLgk#fND+i5#e>6TN~JiyoA2A?kC+y zi plz)P9sa16s8fE7@#*)Xv*arop3t_cRVMmJ>=SW z1gMNin>sba=z5>%@o~Ch{$`zc?5p_2aL9|5+i^$3M2{7A*!aey`83oF0gb42^D<^W zQa^<8aud%R&dS t&zwE!LV`vm9M&&ABYV8`xaS zWjCx`A&Azyvyb~+1hw|NQS*RHp@1>i7;qIex!uLpdAQZdaM{hUK;_mRo_z0Vcy~xJ zf_vjwuQGr>?|6U9S+>tF`cemrL62lTL5o%YAWBpdrwADF0tQkpWirM8Fd!^emvhIn z$?C5atJb^al7;2C)UT3MDPx#p#>b#k`xygMQ^*f~enM&@p(_8wJ-Ys3ZeMzMgUg`= z4K=j1URfnV)nZ7KQZ3`9+jPKVyzVZ5PiIm_2Kfl{KS@J?_>-{fWiqb23EcbH2IxRu zus1hPaLXMEM8I3}KB4t~XXx0TT`DGPy6;04OUb2}u)EpijLdAR+`ZQfe`~hc@T!e0 zKd7_WcoU%=1FuvArLc^JY@r}Goma4ps^%}twch%OhRfW wp5)K6gCRlUz zQUOKPIg}~)TrL+sFLkKc&R^bM*=<%-i)?AKU^TV=%Yy%h^MJ#z<*h!=TeIH kD+zc0w3c_@U|_SvW` zBaL>D_BTi5 UHLaJD=aL7S6A_@y;*u-Ou-XatEp;tL%0PGFZhT@yR6=o7d xSHXe^+R-kNmACirl IH26|SkciQgP4Z!0B4gPex?eErJ zuj>LjPh;*puY1rR2P3wcu$-?uwKdD#82;kTB^-YQnoK*F1BB3GX<9!*L9!> z?z2Weu sEv_$FFMA3INQtdR8CR;l7_E=~D7-w7ZeX@z|f|EZMTXI-Re#{kw;!ESqpWqUivV zQ1ihplBGt^R)g+dSDA$kj3$((jMw||pR3FacOT#w^e%@m-4XEhQ&7lWQ^ jzbUCwAan01JGHSqhs>DMncec_ey7iYSd~UltQ3Jgk&(WPi?3l_@RkP6O0DHf^Xs z$POMIRwy0)gWo4~PLzJ#%-twFHE7trpW0JdLJ{G(A#z616fNXp2B9ysxRA4lsC}Hm zKh&a8vF?XL216=E$U>aTX`K{V1C!v(5K2331mQ=0m{P(Q6WP17LQ_7#!sUBF5zGp> zGBjmg)tUHm)r!FS8Z=YLSbqbwN!4|6kKb#4q&yq6BMG-7%^JukQ5 f!8pOmV4l{hU$_3{Q%4Q-J=Y6j# W@ZMR`n%wa2)|qCaUxh0 3d z21s}4Ev+3TpYK6i@AJMLP~v{=#?Lwh3>%Lsdr{A|R}Gh(W@Hmy+*s9XP??ap{OvD~ zvvW3*V+(i!-YSFsh8hRlTAT$IUN22K;;$Bl<&}MnitD7OHo8dtGUv|kO}&jiQBLBB zZCaz5O;w|0^e6SIzZLV6?L_LW*WpV>DTowd(fe9?)EB~$=7I-9hCG}!ZI%SvKp3x_ z#6r(}bY|g%eoV>d#Ra2snri17KjWZ|IzN=R?GWcyzc$BtN=I5`{-QLMLvZx )6dE46cU_~@^1cc3=&vM^)#wzSs9*w>NR25xS_R9;e+*n8g)TKH*)@ZBa+w= i#(>W+tdrk^f23p4%PDzmnf z+AwU q!)8s)9I;(6Z|#-NAO z_5A5R0e-((W!TS`mQ_rxO#t4XfimpIX7uxUwrUs_{A~kZ*S5}S56q7BgzOAF zE==&X7k$@~@m_1Nd3V}jEw|Lb#;Vyn8#`XC-};{6ZO86?S5|S|quV;Z&|d4OvXk3T zOE(h1P`#(`E|t8>$jv>{ACU^M9b*Uh_m&3EG*LfY=r_ha!N+Sz;TT`InXdo<-xy%D z1@ph{@Mo)*07`A4@_y{x?e86}zVo5h=1FI}X&Dk`6oJW+By~WVw5Bt<3J;)gL?f zAx$z5-#`o&p9}q^FV51_)D&)QoOFsCGa9oSxEhNsSxoGimyKyA%D&n&?tYd(bwE}F zu*Nx_wxBH|{#4~)aDKAN5-lq?t0z8+)~A$pPb+akB|b+$weN|>MUK^ >;;0XGJMADs$maq!v3ff+|CgC@>~X$rni_GT!I(urSP+tPU7aG{D~fRF~qwx6hLD zosNrj&~E%L9P}qvJ57cO2VxW@dL~auCjVeC79Gd-qqN#owg&Q7&Z>zSSNFbKTJHcJ zI3g#?NOz1`y`%Tg8UAbft5(|!b49$^z4Epmr?8BbZje+;oUAJx jjzqm1G~3CEf3tAdzD zZ|nALli!$dWR`n(XT^g(HfFFLM`AT(etdEaUNAufyP{6W! zwzJm^q$Frxb>Ea zbvGRC(4{klT1nKIE^0TpYC4?=;v=vtHyPizr0!OakkEd2+$kmHlwlIo_8xcVd9Yp$ zY|9rwy^#|0%IE8#kNB#uHVE&RBU56FbFUgfEQ$WJQX}!?0FSiE4h~jvWN9gmv<90$ zipxvShook>HN4I=e{wlm9n=&6)l(K+gfWw1sesh4JoaZ*$JyCTNm?{w7KM9vHto2w zhy)Uz5gd%pe-1(yJ@g%=7PqsKN06jwx}iX;t>OR&Y$6k8xu^s{{+`~!+v#5rl^kfw z! OB|ZMcQ{dU+_^PW%wu^zP zJZ<8yeL&IKTekS+>4(1ox&JQS{Q$3mL28tyxChSkm+*kW=IdhLKfg&jDc)>kIoTpV zS=i+zT<{7q!avu_{0xsFoq1c0?7gKZXnmczi3wn)f07VQhR9#_T1`@J3P3C%t=oP4 zmdtTA=ZW~7a4eQltJ;r|gMm(7(BM6&R#4q?&n&)$T>%}hgrqawPV~HBn tRSvAVsLY7`?{nP!{%;fcJ(^ z%x9WGS}m_({@>DLu{MH#T&{+mpkw>$Y9n|wF#XH~c}|0A!{r#l>DD8;9MxP`zPP2t z&ByIxa=3>Fl)^lIIKa-~Y_R=&eEM zeZj>1#*-2@~0_kjX zbe2`=G<+^LmQ^+Hdb(7zBjZ=gSTsq{zq-j~9W<8n2UU0DwdP6C^@$qc_QpHFW`AaA z9UpSQdSDM*?XVWsv?fjCb4ba~CaPxL8!cuzS*;BmIBPo&V`zoK28=xcl473O@WaCc zmhOMAW(!0G+!>|AX~aM2nH-grC?Ui9sH{U1$%f!T0@i>NVp?S&E4z;NrdLovZ$O{t z rMUVe`$vLnKggs^pbgQB}zpNp?_u0s0_Yyj~Ux-N{JBd19i5rrtq zW39sGy0c^C?N_Ru_x|tw=3s1=`oY?u#ZculK27jb9VW9y@(70O-(oRF<(l4TK}i0S zbSnt~0pSDR{m@`>GZ*^-*NNKuz!pse%%+=bIw+yUD&GfK6&hIx6b{lCh10b;g{kf6 zb0^$ ~uo6rKa};p0YO3 zb+)5cKk=NaKl$`7(Mc^UG0snYH!C|EaPXfg-+HDCP{?tv>XWgYK+s;pt^O@-JO0y; zjng&bF~ihT0b{;J&!GA%afz~mDb&$8B0Ey^PIRUP$VsM@?sWENIN9`X1zv51;PL 9>MxL5)ZEIG=`ve96PBw&h9bMB29pFrj{O`+ zU`n#$Zy9TP8)E*mF~*04+}Xrrw7->q7j?^SJzeTaR@h=m7ce%F*8rwy`(ERJcwH;1 z79FyPe=o=CKH`ssE9%mjFMan zO2PH(U;MK2F@Be_Sm| SBw)iRC+T1>=M+KgbVeSW;HbwTZ3kfdzWe4xXJ<;DU z8P=+zG#wXyI_zbXs6L9&KG>C_#5;CyNl`wy)(;5=$j8inSr7UZdTM8@BQ7#TgLHNF zInxtQ1V leC>)B;DzgSg*f1odTm#+>8J;`>ADD^!IM(^MPo(hYmqU zgw5r;KnppdBH>kvKKwr3{*A6^aiT;D4;_|4HCDDOf25!!< 0S=`v_4!ntm6 z0iV^_3YWCR1xy8<5O2XrkRqm;j)M8&rj3i&?{zk+u}$1!2Zd3QI3YL8K@91VS($UL zdw81x6!u{xt#phY C3y5`F$UR&%oEc8975lY=J|3$WK=LRQ*sHOt zwj7&-iCPe<1>{2-SX_?oy+1aJRMEN{@43oaKan|JN7w&hc78J1O_$?mAA3zj1b$bv zDC^L7Pe5Hu?n!&z<&0^P+fUb2TIorCB}8UhU~W7rKCXvX^9`xeYrpQLZ-2jDa5-JD zsnOdJ1t`#N(}2}WBtGY;c7xnSI)yV6)Atw7CT*Mq_leR8*-WDecS3u;ei{8|#LOH5 ze}&K3IJlcq-1T-VfBPI<-VfQmEvBxTL9~V=mownS>o)=V(b~rnFhIb#tv1#Vr;L=q z&1J 1vw4 zB{hapexW!%-!>^aTU1r(Y9n%3zi(YaQ*TV2;h2XO7bZkdBZq$<4sE0qyrHXbP(k6= zHUNyW-OBq`@+%JzbU&75Mc=xK!uP@mCu?dPeMv}4N^uSh?!gc&q~vw3^OyXnpc7ye zdldloe_=7TFF7b^BlwmFwQQzygS3+@yAwiZ>zOkZTqF_-Qs$Z=L(eOc)UWW0y$FjG zc9aZRjODJ W^rwZv zs!$8O<{`^+kl7u=Bm#xLq4ruipc{tgp0BdyGfO=th=*BNb$-&|8kZo>{#=tKzm0 z;8+wMeI*W`AEg}CkFgP|Tm^H5!4{Mjt1f!F`NSBmo|L#q6!~kYkl#>6`q1)T_L9S) z&d6-DXm#B-X?*k>k8xHfn&L{b+FdH;!KJmZVNx<$Z)V&1Op5QMZA~cE8PQ{$g9u|k z2K+1u^A6tvv1u=E0MStT4( TyPW&alB2mRmfz(-p$3wBt$`$eh$+V zy(idU1&qCMs r;!hYtar*%Zf(D7g zRDCm$tJ`0iOcpByxoY@JOO6Rqxs;K|^S7Suiy yLt0vF#}Rp(U;>J%_sDd2jM=87jfK_ON)pGRa`70IO_M`M=pB6%VGJYMIjMSQnA6 z*u;8pPr8E267LC)iUZ8w1(_M_z2l+c)!Fa!lPh$zmBX?;G7>g^hqmMNN27g`RL3kf zD6WYzM6`+@Hd7$hI{3Ds)>|YWku0?OTL6+xJMaOn2LYCfgy>C>DVZ{flzs+3KgF6L zU%pDF_zm@wWu)SxzZ^xcD!LZUniNm!*tZUhn>(0duE%AX&x-FL)WdH5KgcF*-qKHT zMRn*#lmf-;QCg@(7Wl1MX`({q>fJDbTg*c3iqrL!3%I*ox1owe nT75Hr#l zmJfV|TQtU4UD=O}8-~(OaVb|D!=Nq=)&|9M+shQ{gi@Bl8zl)fRm`?#f6-2ANc$@V z{&;EpJnV72os-esx6DE#5fk9Ob*J|f+hMrhi!}Kif*{v%^vLQRk^<=sx^$@1(8CA} zuO#*!6T vYV$AQ3m8)MpZlb0g2-E>CcLsp|gr4Qi z^?i3WCNRWp1Z302Dg$mnl+0m92Z6jl@Nqo0WfNRcbw8;0-EvhK8I?L=uE#2ezVl z^rIj&xJC8X(j4Vor-z*AxUpD&*(B*KwyRY=@j4d@cPcpyr?8bv VCCEC(5xjTUD97VVAw}aOIcnI@19p1pBzW6L=bmB}yH?9Kl;i;nk)z+j)^ebs>v z7bp7{IK9_E3hk*HXpFH#)pnz)g;HKUE1F?#OM(+v?KjpOb||5-&W2A +PO9C$)v4T59RXd+8!apz07 _sD~lZTd0SAi0W6F;MYo7DI7Y`c&wFGFY3m1vG&=_tk( zP4o_8nd3gka6opiRXv?j5-ih~2`F37EBU}G 6O#&7J^qqMiFsR-YleoLT6z>V_51& zld&=#)t$Zy`OVa%yoM9Z8rmBcN-pR2g#-#d9AWmlLW1e0$_oh@i<7Q6)U3M dyJ<(4W5S{aiAw3_3PxK+m? z$Uc%g1C|CM8$r^_5ed~4cd (+T{k@ROA`5Peg+G2xI9(Mv84G z)dW&wdQG xSYeSGq%}ivl Vt1flyxj7J+SDP8uGuNL}?{_@`f9g{A@&W%Hob zJJ)e1oN#A$)O?asEu$k?94KW+O}9jGOnDY< yofP *kLQ|*;@XyEOz7Nb#!_$HR~M0uMn zlc^b)=Xq-+9^;S1{}g<9h?7$G@kC@$(1Ok^<*Eys@Zzv=z-2$#1QY()o-HXoeeWRz zEj%*(>XgD+&-;zq9f?qXr(n#q?B96n%6#M{fPpW&)*Cpm2UeXoUQ5-PYE8e>?tisO z^i8~L9ax?NT+VTSSd0x$ez;$&3TZ&XH#Rp$G=Rr4-gmiNIH!Xnx;XMtb3LEA7nceA zI_r4-*@Eu*&-sA5kjy|D(8YEpe3_3~p3-FiQN_)x?`*f@86+hiUtFc0Gq|t9pl!1v-e~8P_bA9S#hG5X1P(@jRB_>r_04ARsoJ~ zY)m=hE@o}HL0opMQ(|jGIXd7b>+yQ5d(Jt(F@YLeZFfw*&UtrMotRzY&i?2Fu}G>H zHgEWR_wi@MM}xs5r>kPBz>K$avW9#hc`q<*55_`a0@dHFayTcM6i%>Z40m&%`inj^ zEHlk?+tx~{)3|h*?YMdwW0ON;-|{O*SY1wm_F`w1Y2ea$;b_JY;{v{bhE!UHiG@X= zQ&~7iD9(*}dRKG7SC}T^kDZeD87C<5C{shMO-^@|`QQGcxCi)Bf~r^bWrWW#1e+jB z$s%c!?LMngu!(3yQ2cC8CR1brwU7 ?!12h%OLwqw& zw{CG^9P$}OvlWlO W08ICsaHv}DCIlZxgBPHM}ejRqw^f;iz zwOpV!zRB>~KEy{x1;km{ms_SzA677tWz)#2U3Pw+vVpBgbA|`WZO64OHN}!PMY+s( zFi0>w>1^Lc`pyoc(YkIy{fWU(U$TE}a4CD5QzhymTW1LY21jwbGt=!oaa(uYsLpBC zOC}MHd7P{YmE-I=70Jl5BmLEtdD*F2n!`f|4I??!>Mx3l>4nK{??}cQWBRFJ6dKI6 z+#-;3CRe@>&&bht=HnIO$e`jvdV=ma3mc1xo|+r6cTh7bPG+n-N>u3tX?DPJ4N2dw zXg-lzno!*CIlq}W%N;-PTD08`7fY~oK&!E{%+>^}iwT2fL)%&c4|DDZd4LQr_yHF6 zNTi6*E?kV)h#JO3f&b%d%qR|ntbH^VtF6w_4~-yQQ{CRJm?{zkDm=81v}_rib4i|> zH!h3k_##DWB_4ieIjW{ol5G~8ORd0+%03QxTys~^GwrqPX31p*%95BI>LEEI9AaS_ zyssmN2y_Rqf5Y&tqQ4icRxyT3A3_FBhtb1_QErlc%|NDP5%3J7mf|_+9ux;ee-I$3 z{KYur#332^?K3IAyXmvQP?2XixxNH^bySE%sqGleBszr1w^y>nIB&kexLh6a+^dN? z-tv- Hd1{$(b=CUZDKHH%(rK4~WSRiT ESqxkBm0(#wQ>NRZj%! zFrGdjg8tRyw;~-@pkmxFWm!t4M1v{@H?0_s&vQn0Yk;h%53zP5WNAMNNN9Z*uAPqi zjaOhQZ&-wu7QeEnLs* zl$cmb=upWy?8}IYX@TM&-Ge@-M)fX7%i0shKO=`VweS&snGUFn92x096R2p3oE%>G zZPwJ7CSu{ye*Ui7EizQPx9&%Ip7C=ofj^(kp54J@Bd1EA FsVLIS9F^zs6{RF!+AsYAzyi(Dbc76Q>gF?G&rUmN}{3{VhKwqx)99Erzsh_-Y& z{?6}deC|7{fj^m>&ffQ$VFl=#XK!3A3&xg)kkRv{*rt~kk!1jpnLOndw`Jow%FO$% zbL$ZhuKd)3bZYG3LPnG7XPWQ2|7KD-Z=db{(Ey<)U1R;>AcD-fAm|oV(5xZ$qe8FR z*+%bK+cVbd`Z0xCwU@ooMAcf*uNrehHiL+&bvM_wIjO=GjTpDXhCR@{6o0}@!qSpP z$N3<5=b{Os6jwv0W=d=RJ4jlq#H${;*`{5>K>ri(_rU38I%f#Rew2jM@9FFtrT@_c z?Pd)`cta=G%~JLfe#ID+l8vz`7>YCZqzxxats)hzf`E!dUZChnoNBbHPfUM6c+KW4 z)TURe#(VCny7_!gd=5^REl&gy$$3U0CRJc6P6NWeFwjjBLXgSJ!i<;YwSxr*Sj-1G zRZouptWQmp{R}xvf-5Y%T+GJ|kvhnFFZq9EitCuxYF5W{^7i_X8PGKQMZ z*)Obq?sA%6(uq!w `#ITgpCfOXF(XQ0oBvfc5 z@d2jlr|;90I=Bc0`s_p7rC;|0ACV?`2FoQXEDq*b8wtY_iVlzVTapBZ#zKI0Ng>r= z>oviHR(v)h&P`FJ6Pd#@yZ|K|5p45f5;*<%TxLybd3&k2ly7nx?mGJvCbfj#1ssI+ z-o@uJ`;ISZWcd<;VT#2&<@A~Z0`A-F_y!6Jm*d%B&Y!iIWW^N47qh8O*Yv-c$hz`h z@Q&mE%s1OsNf?VeEO4Ms&-Jt6DkzUiZRu8(h+XbjC0sQ@9aKEKRK7oansXJ58&`;_n%9k0>V;Rrbd15erDHfWAY(c^c>FHI zE jv*f7#WRlXjO+5D9d`;Y4v0@U67c`x-iaI*u*%?(T17us5b?PC3qHy>` ;$)2F~lUS0tstziX4hYLo#H7JX|Ak}w z+1S{HQKIY>RFlc0Dab6P*VWim6gMD$2OTXUVO(7#5KNb>FT|{{%;C}QFRZcnRq*HE zZ-hH>uQc1tqw9=&I?9T?U{Cka?dAr57yPS3vhMPas*fx9IrxHXZea@3bYvCudHEiD zpyD(H)HC_u(nSYaYSJ2i^v~gE7?6?}5*sMplEH=aMrtr2=~4b@nmxf$PQz_2c`3)} z+SR6*$)AL+FsO%~Tn&bV3h;<_4AUH`a{VMV{5#U2_T%)ZGkQ|6l|ga3DVk?=+Tthh z9VzIsEpe+iVJt6xH3tN38>_=joh~u3!7FF2X1C*T)VYh-!?SB`To&I5?iPmmRC%$Q zP+=tE8}Ri4DJJuJj(clX^b6^@!{V3cBPT