diff --git a/.travis.yml b/.travis.yml index 12cad75b7..9b6f44ea2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: false dist: xenial language: python @@ -28,11 +27,10 @@ install: - pip install rasterio shapely pandas numpy pweave - wget -O - https://piccolo.link/sbt-1.2.8.tgz | tar xzf - -script: - - sbt/bin/sbt -java-home $JAVA_HOME -batch test - - sbt/bin/sbt -java-home $JAVA_HOME -batch it:test - # - sbt -Dfile.encoding=UTF8 clean coverage test coverageReport - # Tricks to avoid unnecessary cache updates - - find $HOME/.sbt -name "*.lock" | xargs rm - - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm +jobs: + include: + - stage: "Unit Tests" + script: sbt/bin/sbt -java-home $JAVA_HOME -batch test + - stage: "Integration Tests" + script: sbt/bin/sbt -java-home $JAVA_HOME -batch it:test diff --git a/README.md b/README.md index 2b3bcb43f..ac1cc786b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -® +® [![Join the chat at https://gitter.im/locationtech/rasterframes](https://badges.gitter.im/locationtech/rasterframes.svg)](https://gitter.im/locationtech/rasterframes?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -6,7 +6,7 @@ RasterFrames® brings together Earth-observation (EO) data access, cloud computi RasterFrames provides a DataFrame-centric view over arbitrary raster data, enabling spatiotemporal queries, map algebra raster operations, and compatibility with the ecosystem of Spark ML algorithms. By using DataFrames as the core cognitive and compute data model, it is able to deliver these features in a form that is both accessible to general analysts and scalable along with the rapidly growing data footprint. - + Please see the [Getting Started](http://rasterframes.io/getting-started.html) section of the Users' Manual to start using RasterFrames. diff --git a/bench/src/main/scala/org/locationtech/rasterframes/bench/TileExplodeBench.scala b/bench/src/main/scala/org/locationtech/rasterframes/bench/TileExplodeBench.scala index 4ece4cc98..7f3352f69 100644 --- a/bench/src/main/scala/org/locationtech/rasterframes/bench/TileExplodeBench.scala +++ b/bench/src/main/scala/org/locationtech/rasterframes/bench/TileExplodeBench.scala @@ -22,12 +22,11 @@ package org.locationtech.rasterframes.bench import java.util.concurrent.TimeUnit -import org.apache.spark.sql.catalyst.InternalRow -import org.apache.spark.sql.catalyst.expressions.BoundReference -import org.apache.spark.sql.rf.TileUDT import org.locationtech.rasterframes._ -import org.locationtech.rasterframes.expressions.generators.ExplodeTiles +import org.apache.spark.sql._ +import org.apache.spark.sql.functions._ import org.openjdk.jmh.annotations._ + /** * * @author sfitch @@ -37,32 +36,33 @@ import org.openjdk.jmh.annotations._ @State(Scope.Benchmark) @OutputTimeUnit(TimeUnit.MILLISECONDS) class TileExplodeBench extends SparkEnv { + import spark.implicits._ - //@Param(Array("uint8", "uint16ud255", "float32", "float64")) - @Param(Array("uint16ud255")) + @Param(Array("uint8", "uint16ud255", "float32", "float64")) var cellTypeName: String = _ @Param(Array("256")) var tileSize: Int = _ - @Param(Array("2000")) + @Param(Array("100")) var numTiles: Int = _ @transient - var tiles: Array[InternalRow] = _ - - var exploder: ExplodeTiles = _ + var tiles: DataFrame = _ @Setup(Level.Trial) def setupData(): Unit = { - tiles = Array.fill(numTiles)(randomTile(tileSize, tileSize, cellTypeName)) - .map(t => InternalRow(TileUDT.tileSerializer.toInternalRow(t))) - val expr = BoundReference(0, TileType, true) - exploder = new ExplodeTiles(1.0, None, Seq(expr)) + tiles = Seq.fill(numTiles)(randomTile(tileSize, tileSize, cellTypeName)) + .toDF("tile").repartition(10) + } + + @Benchmark + def arrayExplode() = { + tiles.select(posexplode(rf_tile_to_array_double($"tile"))).count() } + @Benchmark def tileExplode() = { - for(t <- tiles) - exploder.eval(t) + tiles.select(rf_explode_tiles($"tile")).count() } } diff --git a/build.sbt b/build.sbt index fa42d1192..f941ea060 100644 --- a/build.sbt +++ b/build.sbt @@ -32,7 +32,10 @@ lazy val root = project .withId("RasterFrames") .aggregate(core, datasource, pyrasterframes, experimental) .enablePlugins(RFReleasePlugin) - .settings(publish / skip := true) + .settings( + publish / skip := true, + clean := clean.dependsOn(`rf-notebook`/clean).value + ) lazy val `rf-notebook` = project .dependsOn(pyrasterframes) diff --git a/build/circleci/Dockerfile b/build/circleci/Dockerfile index a2356f7b6..4ea664a52 100644 --- a/build/circleci/Dockerfile +++ b/build/circleci/Dockerfile @@ -6,45 +6,40 @@ ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ # most of these libraries required for # python-pip pandoc && pip install setuptools => required for pyrasterframes testing -RUN sudo apt-get update && \ +RUN \ + sudo apt-get update && \ sudo apt remove \ python python-minimal python2.7 python2.7-minimal \ libpython-stdlib libpython2.7 libpython2.7-minimal libpython2.7-stdlib \ - && sudo apt-get install -y \ - pandoc \ - wget \ - gcc g++ build-essential \ + && \ + sudo apt-get install -y \ + pandoc wget \ + gcc g++ build-essential bash-completion cmake imagemagick \ libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev \ - libcurl4-gnutls-dev \ - libproj-dev \ - libgeos-dev \ - libhdf4-alt-dev \ - bash-completion \ - cmake \ - imagemagick \ - libpng-dev \ - libffi-dev \ - && sudo apt autoremove \ - && sudo apt-get clean all -# && sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1 -# todo s + liblzma-dev libcurl4-gnutls-dev libproj-dev libgeos-dev libhdf4-alt-dev libpng-dev libffi-dev \ + && \ + sudo apt autoremove && \ + sudo apt-get clean all -RUN cd /tmp && \ - wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ - tar xzf Python-3.7.4.tgz && \ - cd Python-3.7.4 && \ - ./configure --with-ensurepip=install --prefix=/usr/local --enable-optimization && \ - make && \ - sudo make altinstall && \ - rm -rf Python-3.7.4* +RUN \ + cd /tmp && \ + wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ + tar xzf Python-3.7.4.tgz && \ + cd Python-3.7.4 && \ + ./configure --with-ensurepip=install --prefix=/usr/local --enable-optimization && \ + make && \ + sudo make altinstall && \ + rm -rf Python-3.7.4* -RUN sudo ln -s /usr/local/bin/python3.7 /usr/local/bin/python && \ - sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ - sudo python get-pip.py && \ - sudo pip3 install setuptools ipython==6.2.1 +RUN \ + sudo ln -s /usr/local/bin/python3.7 /usr/local/bin/python && \ + sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ + sudo python get-pip.py && \ + sudo pip3 install setuptools ipython==6.2.1 # install OpenJPEG -RUN cd /tmp && \ +RUN \ + cd /tmp && \ wget https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz && \ tar -xf v${OPENJPEG_VERSION}.tar.gz && \ cd openjpeg-${OPENJPEG_VERSION}/ && \ @@ -56,7 +51,8 @@ RUN cd /tmp && \ cd /tmp && rm -Rf v${OPENJPEG_VERSION}.tar.gz openjpeg* # Compile and install GDAL with Java bindings -RUN cd /tmp && \ +RUN \ + cd /tmp && \ wget http://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz && \ tar -xf gdal-${GDAL_VERSION}.tar.gz && \ cd gdal-${GDAL_VERSION} && \ @@ -73,8 +69,7 @@ RUN cd /tmp && \ --with-threads \ --without-jp2mrsid \ --without-netcdf \ - --without-ecw \ - && \ + --without-ecw && \ make -j 8 && \ sudo make install && \ sudo ldconfig && \ diff --git a/core/src/main/scala/org/locationtech/rasterframes/RasterFunctions.scala b/core/src/main/scala/org/locationtech/rasterframes/RasterFunctions.scala index 213f0f77d..94dcef333 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/RasterFunctions.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/RasterFunctions.scala @@ -59,6 +59,22 @@ trait RasterFunctions { /** Extracts the bounding box from a RasterSource or ProjectedRasterTile */ def rf_extent(col: Column): TypedColumn[Any, Extent] = GetExtent(col) + /** Constructs a XZ2 index in WGS84 from either a Geometry, Extent, ProjectedRasterTile, or RasterSource and its CRS + * For details: https://www.geomesa.org/documentation/user/datastores/index_overview.html */ + def rf_spatial_index(targetExtent: Column, targetCRS: Column, indexResolution: Short) = XZ2Indexer(targetExtent, targetCRS, indexResolution) + + /** Constructs a XZ2 index in WGS84 from either a Geometry, Extent, ProjectedRasterTile, or RasterSource and its CRS + * For details: https://www.geomesa.org/documentation/user/datastores/index_overview.html */ + def rf_spatial_index(targetExtent: Column, targetCRS: Column) = XZ2Indexer(targetExtent, targetCRS, 18: Short) + + /** Constructs a XZ2 index with level 18 resolution in WGS84 from either a ProjectedRasterTile or RasterSource + * For details: https://www.geomesa.org/documentation/user/datastores/index_overview.html */ + def rf_spatial_index(targetExtent: Column, indexResolution: Short) = XZ2Indexer(targetExtent, indexResolution) + + /** Constructs a XZ2 index with level 18 resolution in WGS84 from either a ProjectedRasterTile or RasterSource + * For details: https://www.geomesa.org/documentation/user/datastores/index_overview.html */ + def rf_spatial_index(targetExtent: Column) = XZ2Indexer(targetExtent, 18: Short) + /** Extracts the CRS from a RasterSource or ProjectedRasterTile */ def rf_crs(col: Column): TypedColumn[Any, CRS] = GetCRS(col) @@ -276,12 +292,38 @@ trait RasterFunctions { } /** Where the rf_mask tile contains NODATA, replace values in the source tile with NODATA */ - def rf_mask(sourceTile: Column, maskTile: Column): TypedColumn[Any, Tile] = - Mask.MaskByDefined(sourceTile, maskTile) + def rf_mask(sourceTile: Column, maskTile: Column): TypedColumn[Any, Tile] = rf_mask(sourceTile, maskTile, false) + + /** Where the rf_mask tile contains NODATA, replace values in the source tile with NODATA */ + def rf_mask(sourceTile: Column, maskTile: Column, inverse: Boolean=false): TypedColumn[Any, Tile] = + if(!inverse) Mask.MaskByDefined(sourceTile, maskTile) + else Mask.InverseMaskByDefined(sourceTile, maskTile) + + /** Where the `maskTile` equals `maskValue`, replace values in the source tile with `NoData` */ + def rf_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Column, inverse: Boolean=false): TypedColumn[Any, Tile] = + if (!inverse) Mask.MaskByValue(sourceTile, maskTile, maskValue) + else Mask.InverseMaskByValue(sourceTile, maskTile, maskValue) /** Where the `maskTile` equals `maskValue`, replace values in the source tile with `NoData` */ - def rf_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Column): TypedColumn[Any, Tile] = - Mask.MaskByValue(sourceTile, maskTile, maskValue) + def rf_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Int, inverse: Boolean): TypedColumn[Any, Tile] = + rf_mask_by_value(sourceTile, maskTile, lit(maskValue), inverse) + + /** Where the `maskTile` equals `maskValue`, replace values in the source tile with `NoData` */ + def rf_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Int): TypedColumn[Any, Tile] = + rf_mask_by_value(sourceTile, maskTile, maskValue, false) + + /** Generate a tile with the values from `data_tile`, but where cells in the `mask_tile` are in the `mask_values` + list, replace the value with NODATA. */ + def rf_mask_by_values(sourceTile: Column, maskTile: Column, maskValues: Column): TypedColumn[Any, Tile] = + Mask.MaskByValues(sourceTile, maskTile, maskValues) + + /** Generate a tile with the values from `data_tile`, but where cells in the `mask_tile` are in the `mask_values` + list, replace the value with NODATA. */ + def rf_mask_by_values(sourceTile: Column, maskTile: Column, maskValues: Seq[Int]): TypedColumn[Any, Tile] = { + import org.apache.spark.sql.functions.array + val valuesCol: Column = array(maskValues.map(lit).toSeq: _*) + rf_mask_by_values(sourceTile, maskTile, valuesCol) + } /** Where the `maskTile` does **not** contain `NoData`, replace values in the source tile with `NoData` */ def rf_inverse_mask(sourceTile: Column, maskTile: Column): TypedColumn[Any, Tile] = @@ -291,6 +333,10 @@ trait RasterFunctions { def rf_inverse_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Column): TypedColumn[Any, Tile] = Mask.InverseMaskByValue(sourceTile, maskTile, maskValue) + /** Where the `maskTile` does **not** equal `maskValue`, replace values in the source tile with `NoData` */ + def rf_inverse_mask_by_value(sourceTile: Column, maskTile: Column, maskValue: Int): TypedColumn[Any, Tile] = + Mask.InverseMaskByValue(sourceTile, maskTile, lit(maskValue)) + /** Create a tile where cells in the grid defined by cols, rows, and bounds are filled with the given value. */ def rf_rasterize(geometry: Column, bounds: Column, value: Column, cols: Int, rows: Int): TypedColumn[Any, Tile] = withTypedAlias("rf_rasterize", geometry)( @@ -389,6 +435,12 @@ trait RasterFunctions { /** Cellwise inequality comparison between a tile and a scalar. */ def rf_local_unequal[T: Numeric](tileCol: Column, value: T): Column = Unequal(tileCol, value) + /** Test if each cell value is in provided array */ + def rf_local_is_in(tileCol: Column, arrayCol: Column) = IsIn(tileCol, arrayCol) + + /** Test if each cell value is in provided array */ + def rf_local_is_in(tileCol: Column, array: Array[Int]) = IsIn(tileCol, array) + /** Return a tile with ones where the input is NoData, otherwise zero */ def rf_local_no_data(tileCol: Column): Column = Undefined(tileCol) diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/DynamicExtractors.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/DynamicExtractors.scala index 834c3aac1..e72f158aa 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/DynamicExtractors.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/DynamicExtractors.scala @@ -23,11 +23,14 @@ package org.locationtech.rasterframes.expressions import geotrellis.proj4.CRS import geotrellis.raster.{CellGrid, Tile} +import geotrellis.vector.Extent import org.apache.spark.sql.Row import org.apache.spark.sql.catalyst.InternalRow +import org.apache.spark.sql.jts.JTSTypes import org.apache.spark.sql.rf.{RasterSourceUDT, TileUDT} import org.apache.spark.sql.types._ import org.apache.spark.unsafe.types.UTF8String +import org.locationtech.jts.geom.Envelope import org.locationtech.rasterframes.encoders.CatalystSerializer._ import org.locationtech.rasterframes.model.{LazyCRS, TileContext} import org.locationtech.rasterframes.ref.{ProjectedRasterLike, RasterRef, RasterSource} @@ -94,6 +97,15 @@ object DynamicExtractors { (v: Any) => v.asInstanceOf[InternalRow].to[CRS] } + lazy val extentLikeExtractor: PartialFunction[DataType, Any ⇒ Extent] = { + case t if org.apache.spark.sql.rf.WithTypeConformity(t).conformsTo(JTSTypes.GeometryTypeInstance) => + (input: Any) => JTSTypes.GeometryTypeInstance.deserialize(input).getEnvelopeInternal + case t if t.conformsTo[Extent] => + (input: Any) => input.asInstanceOf[InternalRow].to[Extent] + case t if t.conformsTo[Envelope] => + (input: Any) => Extent(input.asInstanceOf[InternalRow].to[Envelope]) + } + sealed trait TileOrNumberArg sealed trait NumberArg extends TileOrNumberArg case class TileArg(tile: Tile, ctx: Option[TileContext]) extends TileOrNumberArg diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/CellStatsAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/CellStatsAggregate.scala index 95c0bd837..c9acf4ed4 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/CellStatsAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/CellStatsAggregate.scala @@ -123,8 +123,8 @@ object CellStatsAggregate { import org.locationtech.rasterframes.encoders.StandardEncoders.cellStatsEncoder def apply(col: Column): TypedColumn[Any, CellStatistics] = - new Column(new CellStatsAggregateUDAF(col.expr)) - .as(s"rf_agg_stats($col)") // node renaming in class doesn't seem to propogate + new CellStatsAggregate()(ExtractTile(col)) + .as(s"rf_agg_stats($col)") .as[CellStatistics] /** Adapter hack to allow UserDefinedAggregateFunction to be referenced as an expression. */ diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/HistogramAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/HistogramAggregate.scala index 44cc1324b..5f7483b0c 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/HistogramAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/HistogramAggregate.scala @@ -98,8 +98,8 @@ object HistogramAggregate { import org.locationtech.rasterframes.encoders.StandardEncoders.cellHistEncoder def apply(col: Column): TypedColumn[Any, CellHistogram] = - new Column(new HistogramAggregateUDAF(col.expr)) - .as(s"rf_agg_approx_histogram($col)") // node renaming in class doesn't seem to propogate + new HistogramAggregate()(ExtractTile(col)) + .as(s"rf_agg_approx_histogram($col)") .as[CellHistogram] /** Adapter hack to allow UserDefinedAggregateFunction to be referenced as an expression. */ diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalCountAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalCountAggregate.scala index 256cd63dd..2fd65700d 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalCountAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalCountAggregate.scala @@ -92,7 +92,7 @@ object LocalCountAggregate { object LocalDataCellsUDAF { def apply(child: Expression): LocalDataCellsUDAF = new LocalDataCellsUDAF(child) def apply(tile: Column): TypedColumn[Any, Tile] = - new Column(new LocalDataCellsUDAF(tile.expr)) + new LocalCountAggregate(true)(ExtractTile(tile)) .as(s"rf_agg_local_data_cells($tile)") .as[Tile] } @@ -107,7 +107,7 @@ object LocalCountAggregate { object LocalNoDataCellsUDAF { def apply(child: Expression): LocalNoDataCellsUDAF = new LocalNoDataCellsUDAF(child) def apply(tile: Column): TypedColumn[Any, Tile] = - new Column(new LocalNoDataCellsUDAF(tile.expr)) + new LocalCountAggregate(false)(ExtractTile(tile)) .as(s"rf_agg_local_no_data_cells($tile)") .as[Tile] } diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalStatsAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalStatsAggregate.scala index 86b360dea..080579633 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalStatsAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalStatsAggregate.scala @@ -146,7 +146,7 @@ class LocalStatsAggregate() extends UserDefinedAggregateFunction { object LocalStatsAggregate { def apply(col: Column): TypedColumn[Any, LocalCellStatistics] = - new Column(LocalStatsAggregateUDAF(col.expr)) + new LocalStatsAggregate()(ExtractTile(col)) .as(s"rf_agg_local_stats($col)") .as[LocalCellStatistics] diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalTileOpAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalTileOpAggregate.scala index b739961c1..bd48f3981 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalTileOpAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/LocalTileOpAggregate.scala @@ -83,7 +83,10 @@ object LocalTileOpAggregate { } object LocalMinUDAF { def apply(child: Expression): LocalMinUDAF = new LocalMinUDAF(child) - def apply(tile: Column): TypedColumn[Any, Tile] = new Column(new LocalMinUDAF(tile.expr)).as[Tile] + def apply(tile: Column): TypedColumn[Any, Tile] = + new LocalTileOpAggregate(BiasedMin)(ExtractTile(tile)) + .as(s"rf_agg_local_min($tile)") + .as[Tile] } @ExpressionDescription( @@ -95,6 +98,9 @@ object LocalTileOpAggregate { } object LocalMaxUDAF { def apply(child: Expression): LocalMaxUDAF = new LocalMaxUDAF(child) - def apply(tile: Column): TypedColumn[Any, Tile] = new Column(new LocalMaxUDAF(tile.expr)).as[Tile] + def apply(tile: Column): TypedColumn[Any, Tile] = + new LocalTileOpAggregate(BiasedMax)(ExtractTile(tile)) + .as(s"rf_agg_local_max($tile)") + .as[Tile] } } diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/TileRasterizerAggregate.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/TileRasterizerAggregate.scala index 360ef93dd..6647f4258 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/TileRasterizerAggregate.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/TileRasterizerAggregate.scala @@ -138,7 +138,7 @@ object TileRasterizerAggregate { } } - // Scan table and constuct what the TileLayerMetadata would be in the specified destination CRS. + // Scan table and construct what the TileLayerMetadata would be in the specified destination CRS. val tlm: TileLayerMetadata[SpatialKey] = df .select( ProjectedLayerMetadataAggregate( diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/generators/ExplodeTiles.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/generators/ExplodeTiles.scala index 06c0c033e..2a70be585 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/generators/ExplodeTiles.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/generators/ExplodeTiles.scala @@ -24,8 +24,8 @@ package org.locationtech.rasterframes.expressions.generators import geotrellis.raster._ import org.apache.spark.sql._ import org.apache.spark.sql.catalyst.InternalRow -import org.apache.spark.sql.catalyst.expressions.codegen.{BufferHolder, CodegenFallback, UnsafeRowWriter} -import org.apache.spark.sql.catalyst.expressions.{Expression, Generator, UnsafeRow} +import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback +import org.apache.spark.sql.catalyst.expressions.{Expression, Generator, GenericInternalRow} import org.apache.spark.sql.types._ import org.locationtech.rasterframes._ import org.locationtech.rasterframes.expressions.DynamicExtractors @@ -87,17 +87,14 @@ case class ExplodeTiles( cfor(0)(_ < rows, _ + 1) { row => cfor(0)(_ < cols, _ + 1) { col => val rowIndex = row * cols + col - val outRow = new UnsafeRow(numOutCols) - val buffer = new BufferHolder(outRow) - val writer = new UnsafeRowWriter(buffer, numOutCols) - writer.write(0, col) - writer.write(1, row) + val outCols = Array.ofDim[Any](numOutCols) + outCols(0) = col + outCols(1) = row cfor(0)(_ < tiles.length, _ + 1) { index => val tile = tiles(index) - val cell: Double = if (tile == null) doubleNODATA else tile.getDouble(col, row) - writer.write(index + 2, cell) + outCols(index + 2) = if(tile == null) doubleNODATA else tile.getDouble(col, row) } - retval(rowIndex) = outRow + retval(rowIndex) = new GenericInternalRow(outCols) } } if(sampleFraction > 0.0 && sampleFraction < 1.0) sample(retval) diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/localops/IsIn.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/localops/IsIn.scala new file mode 100644 index 000000000..1707aff60 --- /dev/null +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/localops/IsIn.scala @@ -0,0 +1,96 @@ +/* + * This software is licensed under the Apache 2 license, quoted below. + * + * Copyright 2019 Astraea, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * [http://www.apache.org/licenses/LICENSE-2.0] + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.locationtech.rasterframes.expressions.localops + +import geotrellis.raster.Tile +import geotrellis.raster.mapalgebra.local.IfCell +import org.apache.spark.sql.Column +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult.{TypeCheckFailure, TypeCheckSuccess} +import org.apache.spark.sql.types.{ArrayType, DataType} +import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback +import org.apache.spark.sql.catalyst.expressions.{BinaryExpression, Expression, ExpressionDescription} +import org.apache.spark.sql.catalyst.util.ArrayData +import org.apache.spark.sql.rf.TileUDT +import org.locationtech.rasterframes.encoders.CatalystSerializer._ +import org.locationtech.rasterframes.expressions.DynamicExtractors._ +import org.locationtech.rasterframes.expressions._ + +@ExpressionDescription( + usage = "_FUNC_(tile, rhs) - In each cell of `tile`, return true if the value is in rhs.", + arguments = """ + Arguments: + * tile - tile column to apply abs + * rhs - array to test against + """, + examples = """ + Examples: + > SELECT _FUNC_(tile, array(lit(33), lit(66), lit(99))); + ...""" +) +case class IsIn(left: Expression, right: Expression) extends BinaryExpression with CodegenFallback { + override val nodeName: String = "rf_local_is_in" + + override def dataType: DataType = left.dataType + + @transient private lazy val elementType: DataType = right.dataType.asInstanceOf[ArrayType].elementType + + override def checkInputDataTypes(): TypeCheckResult = + if(!tileExtractor.isDefinedAt(left.dataType)) { + TypeCheckFailure(s"Input type '${left.dataType}' does not conform to a raster type.") + } else right.dataType match { + case _: ArrayType ⇒ TypeCheckSuccess + case _ ⇒ TypeCheckFailure(s"Input type '${right.dataType}' does not conform to ArrayType.") + } + + override protected def nullSafeEval(input1: Any, input2: Any): Any = { + implicit val tileSer = TileUDT.tileSerializer + val (childTile, childCtx) = tileExtractor(left.dataType)(row(input1)) + + val arr = input2.asInstanceOf[ArrayData].toArray[AnyRef](elementType) + + childCtx match { + case Some(ctx) => ctx.toProjectRasterTile(op(childTile, arr)).toInternalRow + case None => op(childTile, arr).toInternalRow + } + + } + + protected def op(left: Tile, right: IndexedSeq[AnyRef]): Tile = { + def fn(i: Int): Boolean = right.contains(i) + IfCell(left, fn(_), 1, 0) + } + +} + +object IsIn { + def apply(left: Column, right: Column): Column = + new Column(IsIn(left.expr, right.expr)) + + def apply(left: Column, right: Array[Int]): Column = { + import org.apache.spark.sql.functions.lit + import org.apache.spark.sql.functions.array + val arrayExpr = array(right.map(lit):_*).expr + new Column(IsIn(left.expr, arrayExpr)) + } + +} diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/package.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/package.scala index ef614a9a3..d2163f72b 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/package.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/package.scala @@ -36,7 +36,7 @@ import org.locationtech.rasterframes.expressions.tilestats._ import org.locationtech.rasterframes.expressions.transformers._ import scala.reflect.runtime.universe._ -import scala.util.Try + /** * Module of Catalyst expressions for efficiently working with tiles. * @@ -53,8 +53,7 @@ package object expressions { private[expressions] def udfexpr[RT: TypeTag, A1: TypeTag](name: String, f: A1 => RT): Expression => ScalaUDF = (child: Expression) => { val ScalaReflection.Schema(dataType, nullable) = ScalaReflection.schemaFor[RT] - val inputTypes = Try(ScalaReflection.schemaFor(typeTag[A1]).dataType :: Nil).toOption - ScalaUDF(f, dataType, Seq(child), inputTypes.getOrElse(Nil), nullable = nullable, udfName = Some(name)) + ScalaUDF(f, dataType, Seq(child), Seq(true), nullable = nullable, udfName = Some(name)) } def register(sqlContext: SQLContext): Unit = { @@ -87,6 +86,7 @@ package object expressions { registry.registerExpression[GreaterEqual]("rf_local_greater_equal") registry.registerExpression[Equal]("rf_local_equal") registry.registerExpression[Unequal]("rf_local_unequal") + registry.registerExpression[IsIn]("rf_local_is_in") registry.registerExpression[Undefined]("rf_local_no_data") registry.registerExpression[Defined]("rf_local_data") registry.registerExpression[Sum]("rf_tile_sum") @@ -125,15 +125,18 @@ package object expressions { registry.registerExpression[LocalMeanAggregate]("rf_agg_local_mean") registry.registerExpression[Mask.MaskByDefined]("rf_mask") + registry.registerExpression[Mask.InverseMaskByDefined]("rf_inverse_mask") registry.registerExpression[Mask.MaskByValue]("rf_mask_by_value") registry.registerExpression[Mask.InverseMaskByValue]("rf_inverse_mask_by_value") - registry.registerExpression[Mask.InverseMaskByDefined]("rf_inverse_mask") + registry.registerExpression[Mask.MaskByValues]("rf_mask_by_values") registry.registerExpression[DebugRender.RenderAscii]("rf_render_ascii") registry.registerExpression[DebugRender.RenderMatrix]("rf_render_matrix") registry.registerExpression[RenderPNG.RenderCompositePNG]("rf_render_png") registry.registerExpression[RGBComposite]("rf_rgb_composite") + registry.registerExpression[XZ2Indexer]("rf_spatial_index") + registry.registerExpression[transformers.ReprojectGeometry]("st_reproject") } } diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/Mask.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/Mask.scala index 69dac94c7..c6b9b75ec 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/Mask.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/Mask.scala @@ -34,52 +34,58 @@ import org.apache.spark.sql.types.DataType import org.apache.spark.sql.{Column, TypedColumn} import org.locationtech.rasterframes.encoders.CatalystSerializer._ import org.locationtech.rasterframes.expressions.DynamicExtractors._ +import org.locationtech.rasterframes.expressions.localops.IsIn import org.locationtech.rasterframes.expressions.row import org.slf4j.LoggerFactory abstract class Mask(val left: Expression, val middle: Expression, val right: Expression, inverse: Boolean) extends TernaryExpression with CodegenFallback with Serializable { + // aliases. + def targetExp = left + def maskExp = middle + def maskValueExp = right @transient protected lazy val logger = Logger(LoggerFactory.getLogger(getClass.getName)) - override def children: Seq[Expression] = Seq(left, middle, right) override def checkInputDataTypes(): TypeCheckResult = { - if (!tileExtractor.isDefinedAt(left.dataType)) { - TypeCheckFailure(s"Input type '${left.dataType}' does not conform to a raster type.") - } else if (!tileExtractor.isDefinedAt(middle.dataType)) { - TypeCheckFailure(s"Input type '${middle.dataType}' does not conform to a raster type.") - } else if (!intArgExtractor.isDefinedAt(right.dataType)) { - TypeCheckFailure(s"Input type '${right.dataType}' isn't an integral type.") + if (!tileExtractor.isDefinedAt(targetExp.dataType)) { + TypeCheckFailure(s"Input type '${targetExp.dataType}' does not conform to a raster type.") + } else if (!tileExtractor.isDefinedAt(maskExp.dataType)) { + TypeCheckFailure(s"Input type '${maskExp.dataType}' does not conform to a raster type.") + } else if (!intArgExtractor.isDefinedAt(maskValueExp.dataType)) { + TypeCheckFailure(s"Input type '${maskValueExp.dataType}' isn't an integral type.") } else TypeCheckSuccess } override def dataType: DataType = left.dataType - override protected def nullSafeEval(leftInput: Any, middleInput: Any, rightInput: Any): Any = { + override def makeCopy(newArgs: Array[AnyRef]): Expression = super.makeCopy(newArgs) + + override protected def nullSafeEval(targetInput: Any, maskInput: Any, maskValueInput: Any): Any = { implicit val tileSer = TileUDT.tileSerializer - val (leftTile, leftCtx) = tileExtractor(left.dataType)(row(leftInput)) - val (rightTile, rightCtx) = tileExtractor(middle.dataType)(row(middleInput)) + val (targetTile, targetCtx) = tileExtractor(targetExp.dataType)(row(targetInput)) + val (maskTile, maskCtx) = tileExtractor(maskExp.dataType)(row(maskInput)) - if (leftCtx.isEmpty && rightCtx.isDefined) + if (targetCtx.isEmpty && maskCtx.isDefined) logger.warn( s"Right-hand parameter '${middle}' provided an extent and CRS, but the left-hand parameter " + s"'${left}' didn't have any. Because the left-hand side defines output type, the right-hand context will be lost.") - if (leftCtx.isDefined && rightCtx.isDefined && leftCtx != rightCtx) + if (targetCtx.isDefined && maskCtx.isDefined && targetCtx != maskCtx) logger.warn(s"Both '${left}' and '${middle}' provided an extent and CRS, but they are different. Left-hand side will be used.") - val maskValue = intArgExtractor(right.dataType)(rightInput) + val maskValue = intArgExtractor(maskValueExp.dataType)(maskValueInput) - val masking = if (maskValue.value == 0) Defined(rightTile) - else rightTile + val masking = if (maskValue.value == 0) Defined(maskTile) + else maskTile val result = if (inverse) - gtInverseMask(leftTile, masking, maskValue.value, raster.NODATA) + gtInverseMask(targetTile, masking, maskValue.value, raster.NODATA) else - gtMask(leftTile, masking, maskValue.value, raster.NODATA) + gtMask(targetTile, masking, maskValue.value, raster.NODATA) - leftCtx match { + targetCtx match { case Some(ctx) => ctx.toProjectRasterTile(result).toInternalRow case None => result.toInternalRow } @@ -169,4 +175,28 @@ object Mask { def apply(srcTile: Column, maskingTile: Column, maskValue: Column): TypedColumn[Any, Tile] = new Column(InverseMaskByValue(srcTile.expr, maskingTile.expr, maskValue.expr)).as[Tile] } + + @ExpressionDescription( + usage = "_FUNC_(data, mask, maskValues) - Generate a tile with the values from `data` tile but where cells in the `mask` tile are in the `maskValues` list, replace the value with NODATA.", + arguments = """ + Arguments: + * target - tile to mask + * mask - masking definition + * maskValues - sequence of values to consider as masks candidates + """, + examples = """ + Examples: + > SELECT _FUNC_(data, mask, array(1, 2, 3)) + ...""" + ) + case class MaskByValues(dataTile: Expression, maskTile: Expression) + extends Mask(dataTile, maskTile, Literal(1), inverse = false) { + def this(dataTile: Expression, maskTile: Expression, maskValues: Expression) = + this(dataTile, IsIn(maskTile, maskValues)) + override def nodeName: String = "rf_mask_by_values" + } + object MaskByValues { + def apply(dataTile: Column, maskTile: Column, maskValues: Column): TypedColumn[Any, Tile] = + new Column(MaskByValues(dataTile.expr, IsIn(maskTile, maskValues).expr)).as[Tile] + } } diff --git a/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/XZ2Indexer.scala b/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/XZ2Indexer.scala new file mode 100644 index 000000000..7acbb3277 --- /dev/null +++ b/core/src/main/scala/org/locationtech/rasterframes/expressions/transformers/XZ2Indexer.scala @@ -0,0 +1,130 @@ +/* + * This software is licensed under the Apache 2 license, quoted below. + * + * Copyright 2019 Astraea, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * [http://www.apache.org/licenses/LICENSE-2.0] + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.locationtech.rasterframes.expressions.transformers + +import geotrellis.proj4.LatLng +import geotrellis.vector.Extent +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult.{TypeCheckFailure, TypeCheckSuccess} +import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback +import org.apache.spark.sql.catalyst.expressions.{BinaryExpression, Expression, ExpressionDescription} +import org.apache.spark.sql.jts.JTSTypes +import org.apache.spark.sql.rf.RasterSourceUDT +import org.apache.spark.sql.types.{DataType, LongType} +import org.apache.spark.sql.{Column, TypedColumn, rf} +import org.locationtech.geomesa.curve.XZ2SFC +import org.locationtech.jts.geom.{Envelope, Geometry} +import org.locationtech.rasterframes.encoders.CatalystSerializer._ +import org.locationtech.rasterframes.expressions.DynamicExtractors._ +import org.locationtech.rasterframes.expressions.accessors.GetCRS +import org.locationtech.rasterframes.expressions.row +import org.locationtech.rasterframes.jts.ReprojectionTransformer +import org.locationtech.rasterframes.ref.{RasterRef, RasterSource} +import org.locationtech.rasterframes.tiles.ProjectedRasterTile + +/** + * Constructs a XZ2 index in WGS84 from either a Geometry, Extent, ProjectedRasterTile, or RasterSource + * This function is useful for [range partitioning](http://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=registerjava#pyspark.sql.DataFrame.repartitionByRange). + * Also see: https://www.geomesa.org/documentation/user/datastores/index_overview.html + * + * @param left geometry-like column + * @param right CRS column + * @param indexResolution resolution level of the space filling curve - + * i.e. how many times the space will be recursively quartered + * 1-18 is typical. + */ +@ExpressionDescription( + usage = "_FUNC_(geom, crs) - Constructs a XZ2 index in WGS84/EPSG:4326", + arguments = """ + Arguments: + * geom - Geometry or item with Geometry: Extent, ProjectedRasterTile, or RasterSource + * crs - the native CRS of the `geom` column +""" +) +case class XZ2Indexer(left: Expression, right: Expression, indexResolution: Short) + extends BinaryExpression with CodegenFallback { + + override def nodeName: String = "rf_spatial_index" + + override def dataType: DataType = LongType + + override def checkInputDataTypes(): TypeCheckResult = { + if (!extentLikeExtractor.orElse(projectedRasterLikeExtractor).isDefinedAt(left.dataType)) + TypeCheckFailure(s"Input type '${left.dataType}' does not look like something with an Extent or something with one.") + else if(!crsExtractor.isDefinedAt(right.dataType)) + TypeCheckFailure(s"Input type '${right.dataType}' does not look like something with a CRS.") + else TypeCheckSuccess + } + + private lazy val indexer = XZ2SFC(indexResolution) + + override protected def nullSafeEval(leftInput: Any, rightInput: Any): Any = { + val crs = crsExtractor(right.dataType)(rightInput) + + val coords = left.dataType match { + case t if rf.WithTypeConformity(t).conformsTo(JTSTypes.GeometryTypeInstance) => + JTSTypes.GeometryTypeInstance.deserialize(leftInput) + case t if t.conformsTo[Extent] => + row(leftInput).to[Extent] + case t if t.conformsTo[Envelope] => + row(leftInput).to[Envelope] + case _: RasterSourceUDT ⇒ + row(leftInput).to[RasterSource](RasterSourceUDT.rasterSourceSerializer).extent + case t if t.conformsTo[ProjectedRasterTile] => + row(leftInput).to[ProjectedRasterTile].extent + case t if t.conformsTo[RasterRef] => + row(leftInput).to[RasterRef].extent + } + + // If no transformation is needed then just normalize to an Envelope + val env = if(crs == LatLng) coords match { + case e: Extent => e.jtsEnvelope + case g: Geometry => g.getEnvelopeInternal + case e: Envelope => e + } + // Otherwise convert to geometry, transform, and get envelope + else { + val trans = new ReprojectionTransformer(crs, LatLng) + coords match { + case e: Extent => trans(e).getEnvelopeInternal + case g: Geometry => trans(g).getEnvelopeInternal + case e: Envelope => trans(e).getEnvelopeInternal + } + } + + val index = indexer.index( + env.getMinX, env.getMinY, env.getMaxX, env.getMaxY, + lenient = false + ) + index + } +} + +object XZ2Indexer { + import org.locationtech.rasterframes.encoders.SparkBasicEncoders.longEnc + def apply(targetExtent: Column, targetCRS: Column, indexResolution: Short): TypedColumn[Any, Long] = + new Column(new XZ2Indexer(targetExtent.expr, targetCRS.expr, indexResolution)).as[Long] + def apply(targetExtent: Column, targetCRS: Column): TypedColumn[Any, Long] = + new Column(new XZ2Indexer(targetExtent.expr, targetCRS.expr, 18)).as[Long] + def apply(targetExtent: Column, indexResolution: Short = 18): TypedColumn[Any, Long] = + new Column(new XZ2Indexer(targetExtent.expr, GetCRS(targetExtent.expr), indexResolution)).as[Long] +} diff --git a/core/src/main/scala/org/locationtech/rasterframes/jts/ReprojectionTransformer.scala b/core/src/main/scala/org/locationtech/rasterframes/jts/ReprojectionTransformer.scala index c4751cb3c..54b45c034 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/jts/ReprojectionTransformer.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/jts/ReprojectionTransformer.scala @@ -21,9 +21,10 @@ package org.locationtech.rasterframes.jts -import org.locationtech.jts.geom.{CoordinateSequence, Geometry} +import org.locationtech.jts.geom.{CoordinateSequence, Envelope, Geometry, GeometryFactory} import org.locationtech.jts.geom.util.GeometryTransformer import geotrellis.proj4.CRS +import geotrellis.vector.Extent /** * JTS Geometry reprojection transformation routine. @@ -32,6 +33,12 @@ import geotrellis.proj4.CRS */ class ReprojectionTransformer(src: CRS, dst: CRS) extends GeometryTransformer { lazy val transform = geotrellis.proj4.Transform(src, dst) + @transient + private lazy val gf = new GeometryFactory() + def apply(geometry: Geometry): Geometry = transform(geometry) + def apply(extent: Extent): Geometry = transform(extent.jtsGeom) + def apply(env: Envelope): Geometry = transform(gf.toGeometry(env)) + override def transformCoordinates(coords: CoordinateSequence, parent: Geometry): CoordinateSequence = { val fact = parent.getFactory val retval = fact.getCoordinateSequenceFactory.create(coords) diff --git a/core/src/main/scala/org/locationtech/rasterframes/rasterframes.scala b/core/src/main/scala/org/locationtech/rasterframes/rasterframes.scala index f22753c1e..b1958d36b 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/rasterframes.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/rasterframes.scala @@ -31,7 +31,6 @@ import org.locationtech.geomesa.spark.jts.DataFrameFunctions import org.locationtech.rasterframes.encoders.StandardEncoders import org.locationtech.rasterframes.extensions.Implicits import org.locationtech.rasterframes.model.TileDimensions -import org.locationtech.rasterframes.util.ZeroSevenCompatibilityKit import org.slf4j.LoggerFactory import shapeless.tag.@@ @@ -39,7 +38,6 @@ import scala.reflect.runtime.universe._ package object rasterframes extends StandardColumns with RasterFunctions - with ZeroSevenCompatibilityKit.RasterFunctions with Implicits with rasterframes.jts.Implicits with StandardEncoders @@ -48,9 +46,8 @@ package object rasterframes extends StandardColumns // Don't make this a `lazy val`... breaks Spark assemblies for some reason. protected def logger: Logger = Logger(LoggerFactory.getLogger(getClass.getName)) - @transient private[rasterframes] - val rfConfig = ConfigFactory.load().getConfig("rasterframes") + def rfConfig = ConfigFactory.load().getConfig("rasterframes") /** The generally expected tile size, as defined by configuration property `rasterframes.nominal-tile-size`.*/ @transient @@ -81,7 +78,6 @@ package object rasterframes extends StandardColumns } rf.register(sqlContext) - ZeroSevenCompatibilityKit.register(sqlContext) rasterframes.functions.register(sqlContext) rasterframes.expressions.register(sqlContext) rasterframes.rules.register(sqlContext) diff --git a/core/src/main/scala/org/locationtech/rasterframes/util/DataFrameRenderers.scala b/core/src/main/scala/org/locationtech/rasterframes/util/DataFrameRenderers.scala index ae57edcf3..36872332f 100644 --- a/core/src/main/scala/org/locationtech/rasterframes/util/DataFrameRenderers.scala +++ b/core/src/main/scala/org/locationtech/rasterframes/util/DataFrameRenderers.scala @@ -24,12 +24,14 @@ package org.locationtech.rasterframes.util import geotrellis.raster.render.ColorRamps import org.apache.spark.sql.Dataset import org.apache.spark.sql.functions.{base64, concat, concat_ws, length, lit, substring, when} +import org.apache.spark.sql.jts.JTSTypes import org.apache.spark.sql.types.{StringType, StructField} import org.locationtech.rasterframes.expressions.DynamicExtractors import org.locationtech.rasterframes.{rfConfig, rf_render_png, rf_resample} +import org.apache.spark.sql.rf.WithTypeConformity /** - * DataFrame extensiosn for rendering sample content in a number of ways + * DataFrame extension for rendering sample content in a number of ways */ trait DataFrameRenderers { private val truncateWidth = rfConfig.getInt("max-truncate-row-element-length") @@ -47,8 +49,9 @@ trait DataFrameRenderers { lit("\">") ) else { + val isGeom = WithTypeConformity(c.dataType).conformsTo(JTSTypes.GeometryTypeInstance) val str = resolved.cast(StringType) - if (truncate) + if (truncate || isGeom) when(length(str) > lit(truncateWidth), concat(substring(str, 1, truncateWidth), lit("...")) ) diff --git a/core/src/main/scala/org/locationtech/rasterframes/util/ZeroSevenCompatibilityKit.scala b/core/src/main/scala/org/locationtech/rasterframes/util/ZeroSevenCompatibilityKit.scala deleted file mode 100644 index 3a78bcbaa..000000000 --- a/core/src/main/scala/org/locationtech/rasterframes/util/ZeroSevenCompatibilityKit.scala +++ /dev/null @@ -1,371 +0,0 @@ -/* - * This software is licensed under the Apache 2 license, quoted below. - * - * Copyright 2019 Astraea, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * [http://www.apache.org/licenses/LICENSE-2.0] - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -package org.locationtech.rasterframes.util - -import org.locationtech.rasterframes.expressions.TileAssembler -import org.locationtech.rasterframes.expressions.accessors._ -import org.locationtech.rasterframes.expressions.aggregates._ -import org.locationtech.rasterframes.expressions.generators._ -import org.locationtech.rasterframes.expressions.localops._ -import org.locationtech.rasterframes.expressions.tilestats._ -import org.locationtech.rasterframes.expressions.transformers._ -import org.locationtech.rasterframes.stats._ -import org.locationtech.rasterframes.{functions => F} -import org.locationtech.jts.geom.Geometry -import geotrellis.proj4.CRS -import geotrellis.raster.mapalgebra.local.LocalTileBinaryOp -import geotrellis.raster.{CellType, Tile} -import org.apache.spark.annotation.Experimental -import org.apache.spark.sql.catalyst.analysis.FunctionRegistry -import org.apache.spark.sql.functions.{lit, udf} -import org.apache.spark.sql.rf.VersionShims._ -import org.apache.spark.sql.{Column, SQLContext, TypedColumn, rf} - -/** - * UDFs for working with Tiles in Spark DataFrames. - * - * @since 4/3/17 - */ -object ZeroSevenCompatibilityKit { - import org.locationtech.rasterframes.encoders.StandardEncoders._ - - trait RasterFunctions { - private val delegate = new org.locationtech.rasterframes.RasterFunctions {} - // format: off - /** Create a row for each cell in Tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def explodeTiles(cols: Column*): Column = delegate.rf_explode_tiles(cols: _*) - - /** Create a row for each cell in Tile with random sampling and optional seed. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def explodeTilesSample(sampleFraction: Double, seed: Option[Long], cols: Column*): Column = - ExplodeTiles(sampleFraction, seed, cols) - - /** Create a row for each cell in Tile with random sampling (no seed). */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def explodeTilesSample(sampleFraction: Double, cols: Column*): Column = - ExplodeTiles(sampleFraction, None, cols) - - /** Query the number of (cols, rows) in a Tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileDimensions(col: Column): Column = GetDimensions(col) - - @Experimental - /** Convert array in `arrayCol` into a Tile of dimensions `cols` and `rows`*/ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def arrayToTile(arrayCol: Column, cols: Int, rows: Int) = withAlias("rf_array_to_tile", arrayCol)( - udf[Tile, AnyRef](F.arrayToTile(cols, rows)).apply(arrayCol) - ) - - /** Create a Tile from a column of cell data with location indexes and preform cell conversion. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def assembleTile(columnIndex: Column, rowIndex: Column, cellData: Column, tileCols: Int, tileRows: Int, ct: CellType): TypedColumn[Any, Tile] = - convertCellType(TileAssembler(columnIndex, rowIndex, cellData, lit(tileCols), lit(tileRows)), ct).as(cellData.columnName).as[Tile] - - /** Create a Tile from a column of cell data with location indexes. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def assembleTile(columnIndex: Column, rowIndex: Column, cellData: Column, tileCols: Column, tileRows: Column): TypedColumn[Any, Tile] = - TileAssembler(columnIndex, rowIndex, cellData, tileCols, tileRows) - - /** Extract the Tile's cell type */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def cellType(col: Column): TypedColumn[Any, CellType] = GetCellType(col) - - /** Change the Tile's cell type */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def convertCellType(col: Column, cellType: CellType): Column = - SetCellType(col, cellType) - - /** Change the Tile's cell type */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def convertCellType(col: Column, cellTypeName: String): Column = - SetCellType(col, cellTypeName) - - /** Convert a bounding box structure to a Geometry type. Intented to support multiple schemas. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def boundsGeometry(bounds: Column): TypedColumn[Any, Geometry] = ExtentToGeometry(bounds) - - /** Assign a `NoData` value to the Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def withNoData(col: Column, nodata: Double) = delegate.rf_with_no_data(col, nodata) - - /** Compute the full column aggregate floating point histogram. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def aggHistogram(col: Column): TypedColumn[Any, CellHistogram] = delegate.rf_agg_approx_histogram(col) - - /** Compute the full column aggregate floating point statistics. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def aggStats(col: Column): TypedColumn[Any, CellStatistics] = delegate.rf_agg_stats(col) - - /** Computes the column aggregate mean. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def aggMean(col: Column) = CellMeanAggregate(col) - - /** Computes the number of non-NoData cells in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def aggDataCells(col: Column): TypedColumn[Any, Long] = delegate.rf_agg_data_cells(col) - - /** Computes the number of NoData cells in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def aggNoDataCells(col: Column): TypedColumn[Any, Long] = delegate.rf_agg_no_data_cells(col) - - /** Compute the Tile-wise mean */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileMean(col: Column): TypedColumn[Any, Double] = delegate.rf_tile_mean(col) - - /** Compute the Tile-wise sum */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileSum(col: Column): TypedColumn[Any, Double] = delegate.rf_tile_sum(col) - - /** Compute the minimum cell value in tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileMin(col: Column): TypedColumn[Any, Double] = delegate.rf_tile_min(col) - - /** Compute the maximum cell value in tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileMax(col: Column): TypedColumn[Any, Double] = delegate.rf_tile_max(col) - - /** Compute TileHistogram of Tile values. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileHistogram(col: Column): TypedColumn[Any, CellHistogram] = delegate.rf_tile_histogram(col) - - /** Compute statistics of Tile values. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileStats(col: Column): TypedColumn[Any, CellStatistics] = delegate.rf_tile_stats(col) - - /** Counts the number of non-NoData cells per Tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def dataCells(tile: Column): TypedColumn[Any, Long] = delegate.rf_data_cells(tile) - - /** Counts the number of NoData cells per Tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def noDataCells(tile: Column): TypedColumn[Any, Long] = delegate.rf_no_data_cells(tile) - - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def isNoDataTile(tile: Column): TypedColumn[Any, Boolean] = delegate.rf_is_no_data_tile(tile) - - /** Compute cell-local aggregate descriptive statistics for a column of Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggStats(col: Column): Column = delegate.rf_agg_local_stats(col) - - /** Compute the cell-wise/local max operation between Tiles in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggMax(col: Column): TypedColumn[Any, Tile] = delegate.rf_agg_local_max(col) - - /** Compute the cellwise/local min operation between Tiles in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggMin(col: Column): TypedColumn[Any, Tile] = delegate.rf_agg_local_min(col) - - /** Compute the cellwise/local mean operation between Tiles in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggMean(col: Column): TypedColumn[Any, Tile] = delegate.rf_agg_local_mean(col) - - /** Compute the cellwise/local count of non-NoData cells for all Tiles in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggDataCells(col: Column): TypedColumn[Any, Tile] = delegate.rf_agg_local_data_cells(col) - - /** Compute the cellwise/local count of NoData cells for all Tiles in a column. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAggNoDataCells(col: Column): TypedColumn[Any, Tile] = delegate.rf_agg_local_no_data_cells(col) - - /** Cellwise addition between two Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAdd(left: Column, right: Column): Column = delegate.rf_local_add(left, right) - - /** Cellwise addition of a scalar to a tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAddScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_add(tileCol, value) - - /** Cellwise subtraction between two Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localSubtract(left: Column, right: Column): Column = delegate.rf_local_subtract(left, right) - - /** Cellwise subtraction of a scalar from a tile. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localSubtractScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_subtract(tileCol, value) - /** Cellwise multiplication between two Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localMultiply(left: Column, right: Column): Column = delegate.rf_local_multiply(left, right) - - /** Cellwise multiplication of a tile by a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localMultiplyScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_multiply(tileCol, value) - - /** Cellwise division between two Tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localDivide(left: Column, right: Column): Column = delegate.rf_local_divide(left, right) - - /** Cellwise division of a tile by a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localDivideScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_divide(tileCol, value) - /** Perform an arbitrary GeoTrellis `LocalTileBinaryOp` between two Tile columns. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localAlgebra(op: LocalTileBinaryOp, left: Column, right: Column): - TypedColumn[Any, Tile] = - withAlias(opName(op), left, right)( - udf[Tile, Tile, Tile](op.apply).apply(left, right) - ).as[Tile] - - /** Compute the normalized difference of two tile columns */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def normalizedDifference(left: Column, right: Column): TypedColumn[Any, Tile] = delegate.rf_normalized_difference(left, right) - - /** Constructor for constant tile column */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def makeConstantTile(value: Number, cols: Int, rows: Int, cellType: String): TypedColumn[Any, Tile] = - udf(() => F.makeConstantTile(value, cols, rows, cellType)).apply().as(s"constant_$cellType").as[Tile] - - /** Alias for column of constant tiles of zero */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileZeros(cols: Int, rows: Int, cellType: String = "float64"): TypedColumn[Any, Tile] = - udf(() => F.tileZeros(cols, rows, cellType)).apply().as(s"zeros_$cellType").as[Tile] - - /** Alias for column of constant tiles of one */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def tileOnes(cols: Int, rows: Int, cellType: String = "float64"): TypedColumn[Any, Tile] = - udf(() => F.tileOnes(cols, rows, cellType)).apply().as(s"ones_$cellType").as[Tile] - - /** Where the mask tile equals the mask value, replace values in the source tile with NODATA */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def maskByValue(sourceTile: Column, maskTile: Column, maskValue: Column): TypedColumn[Any, Tile] = - delegate.rf_mask_by_value(sourceTile, maskTile, maskValue) - - /** Where the mask tile DOES NOT contain NODATA, replace values in the source tile with NODATA */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def inverseMask(sourceTile: Column, maskTile: Column): TypedColumn[Any, Tile] = - delegate.rf_inverse_mask(sourceTile, maskTile) - - /** Reproject a column of geometry from one CRS to another. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def reprojectGeometry(sourceGeom: Column, srcCRS: CRS, dstCRS: CRS): TypedColumn[Any, Geometry] = - delegate.st_reproject(sourceGeom, srcCRS, dstCRS) - - /** Render Tile as ASCII string for debugging purposes. */ - @Experimental - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def renderAscii(col: Column): TypedColumn[Any, String] = delegate.rf_render_ascii(col) - - /** Cellwise less than value comparison between two tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localLess(left: Column, right: Column): Column = - delegate.rf_local_less(left, right) - - - /** Cellwise less than value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localLessScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_less(tileCol, value) - - /** Cellwise less than or equal to value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localLessEqual(left: Column, right: Column): Column = delegate.rf_local_less_equal(left, right) - - /** Cellwise less than or equal to value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localLessEqualScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_less_equal(tileCol, value) - - /** Cellwise greater than value comparison between two tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localGreater(left: Column, right: Column): Column = - delegate.rf_local_greater(left, right) - - /** Cellwise greater than value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localGreaterScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_greater(tileCol, value) - - /** Cellwise greater than or equal to value comparison between two tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localGreaterEqual(left: Column, right: Column): Column = delegate.rf_local_greater_equal(left, right) - - /** Cellwise greater than or equal to value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localGreaterEqualScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_greater_equal(tileCol, value) - - /** Cellwise equal to value comparison between two tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localEqual(left: Column, right: Column): Column = delegate.rf_local_equal(left, right) - - /** Cellwise equal to value comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localEqualScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_equal(tileCol, value) - - /** Cellwise inequality comparison between two tiles. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localUnequal(left: Column, right: Column): Column = delegate.rf_local_unequal(left, right) - - /** Cellwise inequality comparison between a tile and a scalar. */ - @deprecated("Part of 0.7.x compatibility kit, to be removed after 0.8.x. Please use \"snake_case\" variant instead.", "0.8.0") - def localUnequalScalar[T: Numeric](tileCol: Column, value: T): Column = delegate.rf_local_unequal(tileCol, value) - } - - def register(sqlContext: SQLContext): Unit = { - - /** Unary expression builder builder. */ - def ub[A, B](f: A => B)(a: Seq[A]): B = f(a.head) - /** Binary expression builder builder. */ - def bb[A, B](f: (A, A) => B)(a: Seq[A]): B = f(a.head, a.last) - /** Trinary expression builder builder. */ - def tb[A, B](f: (A, A, A) => B)(a: Seq[A]): B = f(a.head, a.tail.head, a.last) - - // Expression-oriented functions have a different registration scheme - // Currently have to register with the `builtin` registry due to Spark data hiding. - val registry: FunctionRegistry = rf.registry(sqlContext) - registry.registerFunc("rf_explodeTiles", ExplodeTiles.apply(1.0, None, _)) - registry.registerFunc("rf_cellType", ub(GetCellType.apply)) - registry.registerFunc("rf_convertCellType", bb(SetCellType.apply)) - registry.registerFunc("rf_tileDimensions", ub(GetDimensions.apply)) - registry.registerFunc("rf_boundsGeometry", ub(ExtentToGeometry.apply)) - registry.registerFunc("rf_localAdd", bb(Add.apply)) - registry.registerFunc("rf_localSubtract", bb(Subtract.apply)) - registry.registerFunc("rf_localMultiply", bb(Multiply.apply)) - registry.registerFunc("rf_localDivide", bb(Divide.apply)) - registry.registerFunc("rf_normalizedDifference", bb(NormalizedDifference.apply)) - registry.registerFunc("rf_localLess", bb(Less.apply)) - registry.registerFunc("rf_localLessEqual", bb(LessEqual.apply)) - registry.registerFunc("rf_localGreater", bb(Greater.apply)) - registry.registerFunc("rf_localGreaterEqual", bb(GreaterEqual.apply)) - registry.registerFunc("rf_localEqual", bb(Equal.apply)) - registry.registerFunc("rf_localUnequal", bb(Unequal.apply)) - registry.registerFunc("rf_tileSum", ub(Sum.apply)) - registry.registerFunc("rf_dataCells", ub(DataCells.apply)) - registry.registerFunc("rf_noDataCells", ub(NoDataCells.apply)) - registry.registerFunc("rf_isNoDataTile", ub(IsNoDataTile.apply)) - registry.registerFunc("rf_tileMin", ub(TileMin.apply)) - registry.registerFunc("rf_tileMax", ub(TileMax.apply)) - registry.registerFunc("rf_tileMean", ub(TileMean.apply)) - registry.registerFunc("rf_tileStats", ub(TileStats.apply)) - registry.registerFunc("rf_tileHistogram", ub(TileHistogram.apply)) - registry.registerFunc("rf_aggStats", ub(CellStatsAggregate.CellStatsAggregateUDAF.apply)) - registry.registerFunc("rf_aggHistogram", ub(HistogramAggregate.HistogramAggregateUDAF.apply)) - registry.registerFunc("rf_localAggStats", ub(LocalStatsAggregate.LocalStatsAggregateUDAF.apply)) - registry.registerFunc("rf_renderAscii", ub(DebugRender.RenderMatrix.apply)) - registry.registerFunc("rf_localAggMax", ub(LocalTileOpAggregate.LocalMaxUDAF.apply)) - registry.registerFunc("rf_localAggMin", ub(LocalTileOpAggregate.LocalMinUDAF.apply)) - registry.registerFunc("rf_localAggCount", ub(LocalCountAggregate.LocalDataCellsUDAF.apply)) - registry.registerFunc("rf_localAggMean", ub(LocalMeanAggregate.apply)) - registry.registerFunc("rf_reprojectGeometry", tb(ReprojectGeometry.apply)) - - sqlContext.udf.register("rf_makeConstantTile", F.makeConstantTile) - sqlContext.udf.register("rf_tileZeros", F.tileZeros) - sqlContext.udf.register("rf_tileOnes", F.tileOnes) - sqlContext.udf.register("rf_cellTypes", F.cellTypes) - } -} diff --git a/core/src/test/resources/MCD43A4.A2019111.h30v06.006.2019120033434_01.mrf.aux.xml b/core/src/test/resources/MCD43A4.A2019111.h30v06.006.2019120033434_01.mrf.aux.xml deleted file mode 100644 index 5a18f6944..000000000 --- a/core/src/test/resources/MCD43A4.A2019111.h30v06.006.2019120033434_01.mrf.aux.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - LERC - PIXEL - - - 06121997 - MODIS - MODIS - Terra - Aqua - MODIS - MODIS - Passed - Passed was set as a default value. More algorithm will be developed - 0 - AMBRALS_V4.0R1 - v1.0500m - 15.0 - 463.312716527778 - volume - 2400 - 2400 - Day - Mandatory QA: - 0 = processed, good quality (full BRDF inversions) - 1 = processed, see other QA (magnitude BRDF inversions) - - 6.1 - 150.120692476232 - N - False - 75.0 - 86400 - 43200 - 19.9448109058663, 30.0666177912155, 29.9990071837477, 19.8789125843729 - 127.31379517564, 138.161359988435, 150.130532080915, 138.321766284772 - 1, 2, 3, 4 - HDFEOS_V2.19 - 30 - 10.5067/MODIS/MCD43A4.006 - 10.5067/MODIS/MCD43A4.006 - http://dx.doi.org - http://dx.doi.org - MYD09GA.A2019113.h30v06.006.2019115025936.hdf, MYD09GA.A2019114.h30v06.006.2019117021858.hdf, MYD09GA.A2019115.h30v06.006.2019117044251.hdf, MYD09GA.A2019116.h30v06.006.2019118031111.hdf, MYD09GA.A2019117.h30v06.006.2019119025916.hdf, MYD09GA.A2019118.h30v06.006.2019120030848.hdf, MOD09GA.A2019113.h30v06.006.2019115032521.hdf, MOD09GA.A2019114.h30v06.006.2019116030646.hdf, MOD09GA.A2019115.h30v06.006.2019117050730.hdf, MOD09GA.A2019116.h30v06.006.2019118032616.hdf, MOD09GA.A2019117.h30v06.006.2019119032020.hdf, MOD09GA.A2019118.h30v06.006.2019120032257.hdf, MCD43DB.A2019110.6.h30v06.hdf - MCD43A4.A2019111.h30v06.006.2019120033434.hdf - 6.1.34 - MODIS/Terra+Aqua BRDF/Albedo Nadir BRDF-Adjusted Ref Daily L3 Global - 500m - BRDF_Albedo_Band_Mandatory_Quality_Band1 - 0 - 500m - 29.9999999973059 - 1 - NOT SET - 0 - 0 - 0 - 100 - 0 - 6.0.42 - MODAPS - Linux minion7043 3.10.0-957.5.1.el7.x86_64 #1 SMP Fri Feb 1 14:54:57 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux - 2019-04-30T03:34:48.000Z - 0 - 0 - 99 - 0 - 2019-04-13 - 00:00:00.000000 - 2019-04-28 - 23:59:59.999999 - processed once - further update is anticipated - Not Investigated - See http://landweb.nascom/nasa.gov/cgi-bin/QA_WWW/qaFlagPage.cgi?sat=aqua the product Science Quality status. - 06121997 - MCD43A4 - 19.9999999982039 - 2015 - 51030006 - concatenated flags - 0, 254 - 6 - 6 - 127.701332684185 - 255 - - - BRDF_Albedo_Band_Mandatory_Quality_Band1 - concatenated flags - - diff --git a/core/src/test/scala/org/locationtech/rasterframes/ExtensionMethodSpec.scala b/core/src/test/scala/org/locationtech/rasterframes/ExtensionMethodSpec.scala index 4f5fe3591..bb3894162 100644 --- a/core/src/test/scala/org/locationtech/rasterframes/ExtensionMethodSpec.scala +++ b/core/src/test/scala/org/locationtech/rasterframes/ExtensionMethodSpec.scala @@ -39,7 +39,7 @@ import scala.xml.parsing.XhtmlParser class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSupport { lazy val rf = sampleTileLayerRDD.toLayer - describe("DataFrame exention methods") { + describe("DataFrame extension methods") { it("should maintain original type") { val df = rf.withPrefixedColumnNames("_foo_") "val rf2: RasterFrameLayer = df" should compile @@ -49,7 +49,7 @@ class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSu "val Some(col) = df.spatialKeyColumn" should compile } } - describe("RasterFrameLayer exention methods") { + describe("RasterFrameLayer extension methods") { it("should provide spatial key column") { noException should be thrownBy { rf.spatialKeyColumn @@ -124,6 +124,10 @@ class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSu val md3 = rf.toMarkdown(truncate=true, renderTiles = false) md3 shouldNot include(" sfc.index(e.xmin, e.ymin, e.xmax, e.ymax)) + + def reproject(dst: CRS)(e: Extent): Extent = e.reproject(LatLng, dst) + + describe("Spatial index generation") { + import spark.implicits._ + it("should be SQL registered with docs") { + checkDocs("rf_spatial_index") + } + it("should create index from Extent") { + val crs: CRS = WebMercator + val df = testExtents.map(reproject(crs)).map(Tuple1.apply).toDF("extent") + val indexes = df.select(rf_spatial_index($"extent", serialized_literal(crs))).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + } + it("should create index from Geometry") { + val crs: CRS = LatLng + val df = testExtents.map(_.jtsGeom).map(Tuple1.apply).toDF("extent") + val indexes = df.select(rf_spatial_index($"extent", serialized_literal(crs))).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + } + it("should create index from ProjectedRasterTile") { + val crs: CRS = WebMercator + val tile = TestData.randomTile(2, 2, CellType.fromName("uint8")) + val prts = testExtents.map(reproject(crs)).map(ProjectedRasterTile(tile, _, crs)) + + implicit val enc = Encoders.tuple(ProjectedRasterTile.prtEncoder, Encoders.scalaInt) + // The `id` here is to deal with Spark auto projecting single columns dataframes and needing to provide an encoder + val df = prts.zipWithIndex.toDF("proj_raster", "id") + val indexes = df.select(rf_spatial_index($"proj_raster")).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + } + it("should create index from RasterSource") { + val crs: CRS = WebMercator + val tile = TestData.randomTile(2, 2, CellType.fromName("uint8")) + val srcs = testExtents.map(reproject(crs)).map(InMemoryRasterSource(tile, _, crs): RasterSource).toDF("src") + val indexes = srcs.select(rf_spatial_index($"src")).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + + } + it("should work when CRS is LatLng") { + val df = testExtents.map(Tuple1.apply).toDF("extent") + val crs: CRS = LatLng + val indexes = df.select(rf_spatial_index($"extent", serialized_literal(crs))).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + } + it("should support custom resolution") { + val sfc = XZ2SFC(3) + val expected = testExtents.map(e => sfc.index(e.xmin, e.ymin, e.xmax, e.ymax)) + val df = testExtents.map(Tuple1.apply).toDF("extent") + val crs: CRS = LatLng + val indexes = df.select(rf_spatial_index($"extent", serialized_literal(crs), 3)).collect() + + forEvery(indexes.zip(expected)) { case (i, e) => + i should be (e) + } + } + } +} diff --git a/core/src/test/scala/org/locationtech/rasterframes/ref/RasterRefSpec.scala b/core/src/test/scala/org/locationtech/rasterframes/ref/RasterRefSpec.scala index 80f0a7082..51e3338d2 100644 --- a/core/src/test/scala/org/locationtech/rasterframes/ref/RasterRefSpec.scala +++ b/core/src/test/scala/org/locationtech/rasterframes/ref/RasterRefSpec.scala @@ -253,14 +253,18 @@ class RasterRefSpec extends TestEnvironment with TestData { } } - it("should construct a RasterRefTile without I/O") { + it("should construct and inspect a RasterRefTile without I/O") { new Fixture { // SimpleRasterInfo is a proxy for header data requests. - val start = SimpleRasterInfo.cacheStats.hitCount() + val startStats = SimpleRasterInfo.cacheStats val t: ProjectedRasterTile = RasterRefTile(subRaster) - val result = Seq(t, subRaster.tile).toDF("tile").first() - val end = SimpleRasterInfo.cacheStats.hitCount() - end should be(start) + val df = Seq(t, subRaster.tile).toDF("tile") + val result = df.first() + SimpleRasterInfo.cacheStats.hitCount() should be(startStats.hitCount()) + SimpleRasterInfo.cacheStats.missCount() should be(startStats.missCount()) + val info = df.select(rf_dimensions($"tile"), rf_extent($"tile")).first() + SimpleRasterInfo.cacheStats.hitCount() should be(startStats.hitCount() + 2) + SimpleRasterInfo.cacheStats.missCount() should be(startStats.missCount()) } } } diff --git a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionRelation.scala b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionRelation.scala deleted file mode 100644 index 3148a67d0..000000000 --- a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionRelation.scala +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This software is licensed under the Apache 2 license, quoted below. - * - * Copyright 2018 Astraea, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * [http://www.apache.org/licenses/LICENSE-2.0] - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -package org.locationtech.rasterframes.datasource.geotiff - -import java.net.URI - -import geotrellis.proj4.CRS -import geotrellis.spark.io.hadoop.HadoopGeoTiffRDD -import geotrellis.vector.{Extent, ProjectedExtent} -import org.apache.hadoop.fs.Path -import org.apache.spark.rdd.RDD -import org.apache.spark.sql.rf.TileUDT -import org.apache.spark.sql.sources.{BaseRelation, PrunedScan} -import org.apache.spark.sql.types.{StringType, StructField, StructType} -import org.apache.spark.sql.{Row, SQLContext} -import org.locationtech.rasterframes._ -import org.locationtech.rasterframes.datasource.geotiff.GeoTiffCollectionRelation.Cols -import org.locationtech.rasterframes.encoders.CatalystSerializer._ -import org.locationtech.rasterframes.util._ - -private[geotiff] -case class GeoTiffCollectionRelation(sqlContext: SQLContext, uri: URI, bandCount: Int) extends BaseRelation with PrunedScan { - - override def schema: StructType = StructType(Seq( - StructField(Cols.PATH, StringType, false), - StructField(EXTENT_COLUMN.columnName, schemaOf[Extent], nullable = true), - StructField(CRS_COLUMN.columnName, schemaOf[CRS], false) - ) ++ ( - if(bandCount == 1) Seq(StructField(Cols.TL, new TileUDT, false)) - else for(b ← 1 to bandCount) yield StructField(Cols.TL + "_" + b, new TileUDT, nullable = true) - )) - - val keyer = (u: URI, e: ProjectedExtent) ⇒ (u.getPath, e) - - override def buildScan(requiredColumns: Array[String]): RDD[Row] = { - implicit val sc = sqlContext.sparkContext - - val columnIndexes = requiredColumns.map(schema.fieldIndex) - - HadoopGeoTiffRDD.multiband(new Path(uri.toASCIIString), keyer, HadoopGeoTiffRDD.Options.DEFAULT) - .map { case ((path, pe), mbt) ⇒ - val entries = columnIndexes.map { - case 0 ⇒ path - case 1 ⇒ pe.extent.toRow - case 2 ⇒ pe.crs.toRow - case i if i > 2 ⇒ { - if(bandCount == 1 && mbt.bandCount > 2) mbt.color() - else mbt.band(i - 3) - } - } - Row(entries: _*) - } - } -} - -object GeoTiffCollectionRelation { - object Cols { - lazy val PATH = "path" - lazy val CRS = "crs" - lazy val EX = GEOMETRY_COLUMN.columnName - lazy val TL = TILE_COLUMN.columnName - } -} diff --git a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala index 9e2d8dcb3..d236449ed 100644 --- a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala +++ b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala @@ -49,18 +49,16 @@ class GeoTiffDataSource def shortName() = GeoTiffDataSource.SHORT_NAME + /** Read single geotiff as a relation. */ def createRelation(sqlContext: SQLContext, parameters: Map[String, String]) = { require(parameters.path.isDefined, "Valid URI 'path' parameter required.") sqlContext.withRasterFrames val p = parameters.path.get - - if (p.getPath.contains("*")) { - val bandCount = parameters.get(GeoTiffDataSource.BAND_COUNT_PARAM).map(_.toInt).getOrElse(1) - GeoTiffCollectionRelation(sqlContext, p, bandCount) - } else GeoTiffRelation(sqlContext, p) + GeoTiffRelation(sqlContext, p) } + /** Write dataframe containing bands into a single geotiff. Note: performs a driver collect, and is not "big data" friendly. */ override def createRelation(sqlContext: SQLContext, mode: SaveMode, parameters: Map[String, String], df: DataFrame): BaseRelation = { require(parameters.path.isDefined, "Valid URI 'path' parameter required.") val path = parameters.path.get @@ -71,8 +69,6 @@ class GeoTiffDataSource require(tileCols.nonEmpty, "Could not find any tile columns.") - - val destCRS = parameters.crs.orElse(df.asLayerSafely.map(_.crs)).getOrElse( throw new IllegalArgumentException("A destination CRS must be provided") ) diff --git a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSource.scala b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSource.scala index 061e9fb56..03b2fd0da 100644 --- a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSource.scala +++ b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSource.scala @@ -37,7 +37,7 @@ class RasterSourceDataSource extends DataSourceRegister with RelationProvider { override def shortName(): String = SHORT_NAME override def createRelation(sqlContext: SQLContext, parameters: Map[String, String]): BaseRelation = { val bands = parameters.bandIndexes - val tiling = parameters.tileDims + val tiling = parameters.tileDims.orElse(Some(NOMINAL_TILE_DIMS)) val lazyTiles = parameters.lazyTiles val spec = parameters.pathSpec val catRef = spec.fold(_.registerAsTable(sqlContext), identity) diff --git a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceRelation.scala b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceRelation.scala index 6af519f56..9b381d3a6 100644 --- a/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceRelation.scala +++ b/datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceRelation.scala @@ -69,6 +69,9 @@ case class RasterSourceRelation( catalog.schema.fields.filter(f => !catalogTable.bandColumnNames.contains(f.name)) } + protected def defaultNumPartitions: Int = + sqlContext.sparkSession.sessionState.conf.numShufflePartitions + override def schema: StructType = { val tileSchema = schemaOf[ProjectedRasterTile] val paths = for { @@ -84,10 +87,11 @@ case class RasterSourceRelation( override def buildScan(): RDD[Row] = { import sqlContext.implicits._ - // The general transformaion is: + // The general transformation is: // input -> path -> src -> ref -> tile // Each step is broken down for readability val inputs: DataFrame = sqlContext.table(catalogTable.tableName) + .repartition(defaultNumPartitions) // Basically renames the input columns to have the '_path' suffix val pathsAliasing = for { @@ -112,7 +116,7 @@ case class RasterSourceRelation( val df = if (lazyTiles) { // Expand RasterSource into multiple columns per band, and multiple rows per tile - // There's some unintentional fragililty here in that the structure of the expression + // There's some unintentional fragility here in that the structure of the expression // is expected to line up with our column structure here. val refs = RasterSourceToRasterRefs(subtileDims, bandIndexes, srcs: _*) as refColNames diff --git a/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionDataSourceSpec.scala b/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionDataSourceSpec.scala deleted file mode 100644 index 9b69fd89e..000000000 --- a/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffCollectionDataSourceSpec.scala +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This software is licensed under the Apache 2 license, quoted below. - * - * Copyright 2018 Astraea, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * [http://www.apache.org/licenses/LICENSE-2.0] - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - * - * SPDX-License-Identifier: Apache-2.0 - * - */ -package org.locationtech.rasterframes.datasource.geotiff - -import java.io.{File, FilenameFilter} - -import org.locationtech.rasterframes._ -import org.locationtech.rasterframes.TestEnvironment - -/** - * @since 1/14/18 - */ -class GeoTiffCollectionDataSourceSpec - extends TestEnvironment with TestData { - - describe("GeoTiff directory reading") { - it("shiould read a directory of files") { - - val df = spark.read - .format("geotiff") - .load(geotiffDir.resolve("*.tiff").toString) - val expected = geotiffDir.toFile.list(new FilenameFilter { - override def accept(dir: File, name: String): Boolean = name.endsWith("tiff") - }).length - - assert(df.select("path").distinct().count() === expected) - - // df.show(false) - } - } -} diff --git a/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala b/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala index 817d7d5bf..c57737118 100644 --- a/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala +++ b/datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala @@ -192,29 +192,36 @@ class GeoTiffDataSourceSpec } it("should write GeoTIFF without layer") { - val pr = col("proj_raster_b0") - val rf = spark.read.raster.withBandIndexes(0, 1, 2).load(rgbCogSamplePath.toASCIIString) - val out = Paths.get("target", "example2-geotiff.tif") - logger.info(s"Writing to $out") + val sample = rgbCogSample + val expectedExtent = sample.extent + val (expCols, expRows) = sample.tile.dimensions - withClue("explicit extent/crs") { + val rf = spark.read.raster.withBandIndexes(0, 1, 2).load(rgbCogSamplePath.toASCIIString) + + withClue("extent/crs columns provided") { + val out = Paths.get("target", "example2a-geotiff.tif") noException shouldBe thrownBy { rf .withColumn("extent", rf_extent(pr)) .withColumn("crs", rf_crs(pr)) - .write.geotiff.withCRS(LatLng).save(out.toString) + .write.geotiff.withCRS(sample.crs).save(out.toString) + checkTiff(out, expCols, expRows, expectedExtent, Some(sample.cellType)) } } - withClue("without explicit extent/crs") { + withClue("without extent/crs columns") { + val out = Paths.get("target", "example2b-geotiff.tif") noException shouldBe thrownBy { rf - .write.geotiff.withCRS(LatLng).save(out.toString) + .write.geotiff.withCRS(sample.crs).save(out.toString) + checkTiff(out, expCols, expRows, expectedExtent, Some(sample.cellType)) } } + withClue("with downsampling") { + val out = Paths.get("target", "example2c-geotiff.tif") noException shouldBe thrownBy { rf .write.geotiff @@ -223,9 +230,6 @@ class GeoTiffDataSourceSpec .save(out.toString) } } - - checkTiff(out, 128, 128, - Extent(-76.52586750038186, 36.85907177863949, -76.17461216980891, 37.1303690755922)) } it("should produce the correct subregion from layer") { diff --git a/docs/src/main/paradox/RasterFramePipeline.png b/docs/src/main/paradox/RasterFramePipeline.png deleted file mode 100644 index 26900b8cf..000000000 Binary files a/docs/src/main/paradox/RasterFramePipeline.png and /dev/null differ diff --git a/docs/src/main/paradox/RasterFramePipeline.svg b/docs/src/main/paradox/RasterFramePipeline.svg deleted file mode 100644 index e9c08f831..000000000 --- a/docs/src/main/paradox/RasterFramePipeline.svg +++ /dev/null @@ -1,920 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Produced by OmniGraffle 7.7 - 2018-02-16 20:16:42 +0000 - - - Canvas 7 - - Layer 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GeoTrellis - Layers - - - - - - - - - - Map Algebra - - - - - - - Layer - Operations - - - - - - - - - - - - - - - - Statistical - Analysis - - - - - TileLayerRDD - - - - - - - - - - - - - Machine - Learning - - - - - - - - - - Visualization - - - - - - - - - - - - - - Your Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GeoTIFF - - - - - - - - - - RasterFrame - - - - - - - Spark - DataSource - - - - - - - - - - Spark - DataFrame - - - - - - - - join - - - - - diff --git a/pyrasterframes/src/main/python/docs/reference.pymd b/docs/src/main/paradox/reference.md similarity index 90% rename from pyrasterframes/src/main/python/docs/reference.pymd rename to docs/src/main/paradox/reference.md index 195b7e5e0..1121bbd36 100644 --- a/pyrasterframes/src/main/python/docs/reference.pymd +++ b/docs/src/main/paradox/reference.md @@ -66,6 +66,15 @@ See also GeoMesa [st_envelope](https://www.geomesa.org/documentation/user/spark/ Convert an extent to a Geometry. The extent likely comes from @ref:[`st_extent`](reference.md#st-extent) or @ref:[`rf_extent`](reference.md#rf-extent). + +### rf_spatial_index + + Long rf_spatial_index(Geometry geom, CRS crs) + Long rf_spatial_index(Extent extent, CRS crs) + Long rf_spatial_index(ProjectedRasterTile proj_raster, CRS crs) + +Constructs a XZ2 index in WGS84/EPSG:4326 from either a Geometry, Extent, ProjectedRasterTile and its CRS. This function is useful for [range partitioning](http://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=registerjava#pyspark.sql.DataFrame.repartitionByRange). + ## Tile Metadata and Mutation Functions to access and change the particulars of a `tile`: its shape and the data type of its cells. See section on @ref:["NoData" handling](nodata-handling.md) for additional discussion of cell types. @@ -183,7 +192,7 @@ Parameters `tile_columns` and `tile_rows` are literals, not column expressions. Tile rf_array_to_tile(Array arrayCol, Int numCols, Int numRows) -Python only. Create a `tile` from a Spark SQL [Array](http://spark.apache.org/docs/2.3.2/api/python/pyspark.sql.html#pyspark.sql.types.ArrayType), filling values in row-major order. +Python only. Create a `tile` from a Spark SQL [Array][Array], filling values in row-major order. ### rf_assemble_tile @@ -198,7 +207,7 @@ SQL implementation does not accept a cell_type argument. It returns a float64 ce ## Masking and NoData -See @ref:[NoData handling](nodata-handling.md) for conceptual discussion of cell types and NoData. +See the @ref:[masking](masking.md) page for conceptual discussion of masking operations. There are statistical functions of the count of data and NoData values per `tile` and aggregate over a `tile` column: @ref:[`rf_data_cells`](reference.md#rf-data-cells), @ref:[`rf_no_data_cells`](reference.md#rf-no-data-cells), @ref:[`rf_agg_data_cells`](reference.md#rf-agg-data-cells), and @ref:[`rf_agg_no_data_cells`](reference.md#rf-agg-no-data-cells). @@ -206,14 +215,30 @@ Masking is a raster operation that sets specific cells to NoData based on the va ### rf_mask - Tile rf_mask(Tile tile, Tile mask) + Tile rf_mask(Tile tile, Tile mask, bool inverse) Where the `mask` contains NoData, replace values in the `tile` with NoData. Returned `tile` cell type will be coerced to one supporting NoData if it does not already. +`inverse` is a literal not a Column. If `inverse` is true, return the `tile` with NoData in locations where the `mask` _does not_ contain NoData. Equivalent to @ref:[`rf_inverse_mask`](reference.md#rf-inverse-mask). + See also @ref:[`rf_rasterize`](reference.md#rf-rasterize). +### rf_mask_by_value + + Tile rf_mask_by_value(Tile data_tile, Tile mask_tile, Int mask_value, bool inverse) + +Generate a `tile` with the values from `data_tile`, with NoData in cells where the `mask_tile` is equal to `mask_value`. + +`inverse` is a literal not a Column. If `inverse` is true, return the `data_tile` with NoData in locations where the `mask_tile` value is _not equal_ to `mask_value`. Equivalent to @ref:[`rf_inverse_mask_by_value`](reference.md#rf-inverse-mask-by-value). + +### rf_mask_by_values + + Tile rf_mask_by_values(Tile data_tile, Tile mask_tile, Array mask_values) + Tile rf_mask_by_values(Tile data_tile, Tile mask_tile, seq mask_values) + +Generate a `tile` with the values from `data_tile`, with NoData in cells where the `mask_tile` is in the `mask_values` Array or list. `mask_values` can be a [`pyspark.sql.ArrayType`][Array] or a `list`. ### rf_inverse_mask @@ -221,12 +246,12 @@ See also @ref:[`rf_rasterize`](reference.md#rf-rasterize). Where the `mask` _does not_ contain NoData, replace values in `tile` with NoData. -### rf_mask_by_value - Tile rf_mask_by_value(Tile data_tile, Tile mask_tile, Int mask_value) +### rf_inverse_mask_by_value -Generate a `tile` with the values from `data_tile`, with NoData in cells where the `mask_tile` is equal to `mask_value`. + Tile rf_inverse_mask_by_value(Tile data_tile, Tile mask_tile, Int mask_value) +Generate a `tile` with the values from `data_tile`, with NoData in cells where the `mask_tile` is not equal to `mask_value`. In other words, only keep `data_tile` cells in locations where the `mask_tile` is equal to `mask_value`. ### rf_is_no_data_tile @@ -374,6 +399,13 @@ Returns a `tile` column containing the element-wise equality of `tile1` and `rhs Returns a `tile` column containing the element-wise inequality of `tile1` and `rhs`. +### rf_local_is_in + + Tile rf_local_is_in(Tile tile, Array array) + Tile rf_local_is_in(Tile tile, list l) + +Returns a `tile` column with cell values of 1 where the `tile` cell value is in the provided array or list. The `array` is a Spark SQL [Array][Array]. A python `list` of numeric values can also be passed. + ### rf_round Tile rf_round(Tile tile) @@ -621,13 +653,13 @@ Python only. As with @ref:[`rf_explode_tiles`](reference.md#rf-explode-tiles), b Array rf_tile_to_array_int(Tile tile) -Convert Tile column to Spark SQL [Array](http://spark.apache.org/docs/2.3.2/api/python/pyspark.sql.html#pyspark.sql.types.ArrayType), in row-major order. Float cell types will be coerced to integral type by flooring. +Convert Tile column to Spark SQL [Array][Array], in row-major order. Float cell types will be coerced to integral type by flooring. ### rf_tile_to_array_double Array rf_tile_to_arry_double(Tile tile) -Convert tile column to Spark [Array](http://spark.apache.org/docs/2.3.2/api/python/pyspark.sql.html#pyspark.sql.types.ArrayType), in row-major order. Integral cell types will be coerced to floats. +Convert tile column to Spark [Array][Array], in row-major order. Integral cell types will be coerced to floats. ### rf_render_ascii @@ -657,3 +689,4 @@ Runs [`rf_rgb_composite`](reference.md#rf-rgb-composite) on the given tile colum [RasterFunctions]: org.locationtech.rasterframes.RasterFunctions [scaladoc]: latest/api/index.html +[Array]: http://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.types.ArrayType diff --git a/docs/src/main/paradox/release-notes.md b/docs/src/main/paradox/release-notes.md index 0d7ed4c9c..c181d55da 100644 --- a/docs/src/main/paradox/release-notes.md +++ b/docs/src/main/paradox/release-notes.md @@ -2,11 +2,22 @@ ## 0.8.x +### 0.8.4 + +* Upgraded to Spark 2.4.4 +* Add `rf_mask_by_values` and `rf_local_is_in` raster functions; added optional `inverse` argument to `rf_mask` functions. ([#403](https://github.com/locationtech/rasterframes/pull/403), [#384](https://github.com/locationtech/rasterframes/issues/384)) +* Added forced truncation of WKT types in Markdown/HTML rendering. ([#408](https://github.com/locationtech/rasterframes/pull/408)) +* Add `rf_local_is_in` raster function. ([#400](https://github.com/locationtech/rasterframes/pull/400)) +* Added partitioning to catalogs before processing in RasterSourceDataSource ([#397](https://github.com/locationtech/rasterframes/pull/397)) +* Fixed bug where `rf_tile_dimensions` would cause unnecessary reading of tiles. ([#394](https://github.com/locationtech/rasterframes/pull/394)) +* _Breaking_ (potentially): removed `GeoTiffCollectionRelation` due to usage limitation and overlap with `RasterSourceDataSource` functionality. + ### 0.8.3 * Updated to GeoTrellis 2.3.3 and Proj4j 1.1.0. * Fixed issues with `LazyLogger` and shading assemblies ([#293](https://github.com/locationtech/rasterframes/issues/293)) * Updated `rf_crs` to accept string columns containing CRS specifications. ([#366](https://github.com/locationtech/rasterframes/issues/366)) +* Added `rf_spatial_index` function. ([#368](https://github.com/locationtech/rasterframes/issues/368)) * _Breaking_ (potentially): removed `pyrasterframes.create_spark_session` in lieu of `pyrasterframes.utils.create_rf_spark_session` ### 0.8.2 diff --git a/experimental/src/it/resources/log4j.properties b/experimental/src/it/resources/log4j.properties index 5cc16f4db..4a81f524a 100644 --- a/experimental/src/it/resources/log4j.properties +++ b/experimental/src/it/resources/log4j.properties @@ -35,7 +35,7 @@ log4j.logger.org.spark_project.jetty=WARN log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO -log4j.logger.org.locationtech.rasterframes=DEBUG +log4j.logger.org.locationtech.rasterframes=INFO log4j.logger.org.apache.parquet.hadoop.ParquetRecordReader=OFF # SPARK-9183: Settings to avoid annoying messages when looking up nonexistent UDFs in SparkSQL with Hive support diff --git a/experimental/src/it/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelationTest.scala b/experimental/src/it/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelationTest.scala index 3f777d322..8499bbe44 100644 --- a/experimental/src/it/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelationTest.scala +++ b/experimental/src/it/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelationTest.scala @@ -21,6 +21,7 @@ package org.locationtech.rasterframes.experimental.datasource.awspds import java.sql.Timestamp +import geotrellis.proj4.LatLng import org.apache.spark.sql.functions._ import org.locationtech.rasterframes._ import org.locationtech.rasterframes.datasource.raster._ @@ -75,5 +76,32 @@ class MODISCatalogRelationTest extends TestEnvironment { stats.data_cells shouldBe > (128L) stats.mean shouldBe > (1000.0) } + it("should compute aggregate statistics") { + // This is copied from the docs. + import spark.implicits._ + + val modis = spark.read.format("aws-pds-modis-catalog").load() + + val red_nir_monthly_2017 = modis + .select($"granule_id", month($"acquisition_date") as "month", $"B01" as "red", $"B02" as "nir") + .where(year($"acquisition_date") === 2017 && (dayofmonth($"acquisition_date") === 15) && $"granule_id" === "h21v09") + + val red_nir_tiles_monthly_2017 = spark.read.raster + .fromCatalog(red_nir_monthly_2017, "red", "nir") + .load() + .cache() + + val result = red_nir_tiles_monthly_2017 + .where(st_intersects( + st_reproject(rf_geometry($"red"), rf_crs($"red"), LatLng), + st_makePoint(34.870605, -4.729727) + )) + .groupBy("month") + .agg(rf_agg_stats(rf_normalized_difference($"nir", $"red")) as "ndvi_stats") + .orderBy("month") + .select("month", "ndvi_stats.*") + + result.show() + } } } diff --git a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/CachedDatasetRelation.scala b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/CachedDatasetRelation.scala index 1fac7699a..06947080d 100644 --- a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/CachedDatasetRelation.scala +++ b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/CachedDatasetRelation.scala @@ -33,6 +33,8 @@ import org.locationtech.rasterframes.util._ * @since 8/24/18 */ trait CachedDatasetRelation extends ResourceCacheSupport { self: BaseRelation ⇒ + protected def defaultNumPartitions: Int = + sqlContext.sparkSession.sessionState.conf.numShufflePartitions protected def cacheFile: HadoopPath protected def constructDataset: Dataset[Row] diff --git a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/L8CatalogRelation.scala b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/L8CatalogRelation.scala index 9a14c86f3..049617de6 100644 --- a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/L8CatalogRelation.scala +++ b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/L8CatalogRelation.scala @@ -68,7 +68,9 @@ case class L8CatalogRelation(sqlContext: SQLContext, sceneListPath: HadoopPath) .select(schema.map(f ⇒ col(f.name)): _*) .orderBy(ACQUISITION_DATE.name, PATH.name, ROW.name) .distinct() // The scene file contains duplicates. - .repartition(8, col(PATH.name), col(ROW.name)) + .repartition(defaultNumPartitions, col(PATH.name), col(ROW.name)) + + } } diff --git a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelation.scala b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelation.scala index 30b3ba234..6e76acc36 100644 --- a/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelation.scala +++ b/experimental/src/main/scala/org/locationtech/rasterframes/experimental/datasource/awspds/MODISCatalogRelation.scala @@ -64,7 +64,7 @@ case class MODISCatalogRelation(sqlContext: SQLContext, sceneList: HadoopPath) $"${GID.name}") ++ bandCols: _* ) .orderBy(ACQUISITION_DATE.name, GID.name) - .repartition(8, col(GRANULE_ID.name)) + .repartition(defaultNumPartitions, col(GRANULE_ID.name)) } } diff --git a/project/PythonBuildPlugin.scala b/project/PythonBuildPlugin.scala index 7cc33fda3..37404ddae 100644 --- a/project/PythonBuildPlugin.scala +++ b/project/PythonBuildPlugin.scala @@ -133,7 +133,7 @@ object PythonBuildPlugin extends AutoPlugin { val dest = (Compile / packageBin / artifactPath).value.getParentFile val art = (Python / packageBin / artifact).value val ver = version.value - dest / s"${art.name}-$ver-py2.py3-none-any.whl" + dest / s"${art.name}-$ver-py3-none-any.whl" }, testQuick := pySetup.toTask(" test").value, executeTests := Def.task { diff --git a/project/RFAssemblyPlugin.scala b/project/RFAssemblyPlugin.scala index 60a7badfe..cbde26437 100644 --- a/project/RFAssemblyPlugin.scala +++ b/project/RFAssemblyPlugin.scala @@ -55,7 +55,8 @@ object RFAssemblyPlugin extends AutoPlugin { "org.apache.avro", "org.apache.http", "com.google.guava", - "com.typesafe.scalalogging" + "com.typesafe.scalalogging", + "com.typesafe.config" ) shadePrefixes.map(p ⇒ ShadeRule.rename(s"$p.**" -> s"rf.shaded.$p.@1").inAll) }, diff --git a/project/RFDependenciesPlugin.scala b/project/RFDependenciesPlugin.scala index 5c161eadb..20cca567f 100644 --- a/project/RFDependenciesPlugin.scala +++ b/project/RFDependenciesPlugin.scala @@ -59,7 +59,7 @@ object RFDependenciesPlugin extends AutoPlugin { ), // NB: Make sure to update the Spark version in pyrasterframes/python/setup.py - rfSparkVersion := "2.3.4", + rfSparkVersion := "2.4.4", rfGeoTrellisVersion := "2.3.3", rfGeoMesaVersion := "2.2.1", ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 73943d4cb..f51b70fec 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -8,7 +8,7 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.2") addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.5.5") addSbtPlugin("io.github.jonas" % "sbt-paradox-material-theme" % "0.6.0") -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.3") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.6") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.1") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.1") @@ -16,5 +16,6 @@ addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.10") addSbtPlugin("com.github.gseitz" %% "sbt-release" % "1.0.9") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.19") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") diff --git a/pyrasterframes/src/main/python/README.md b/pyrasterframes/src/main/python/README.md index 22a6f30c7..00a915387 100644 --- a/pyrasterframes/src/main/python/README.md +++ b/pyrasterframes/src/main/python/README.md @@ -13,8 +13,8 @@ pip install pyrasterframes You can then access a [`pyspark SparkSession`](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.SparkSession) using the [`local[*]` master](https://spark.apache.org/docs/latest/submitting-applications.html#master-urls) in your python interpreter as follows. ```python -import pyrasterframes -spark = pyrasterframes.get_spark_session() +from pyrasterframes.utils import create_rf_spark_session +spark = create_rf_spark_session() ``` Then you can read a raster and do some work with it. diff --git a/pyrasterframes/src/main/python/docs/index.md b/pyrasterframes/src/main/python/docs/index.md index e3a37274b..f3be57721 100644 --- a/pyrasterframes/src/main/python/docs/index.md +++ b/pyrasterframes/src/main/python/docs/index.md @@ -2,15 +2,21 @@ RasterFrames® brings together Earth-observation (EO) data access, cloud computing, and DataFrame-based data science. The recent explosion of EO data from public and private satellite operators presents both a huge opportunity and a huge challenge to the data analysis community. It is _Big Data_ in the truest sense, and its footprint is rapidly getting bigger. -RasterFrames provides a DataFrame-centric view over arbitrary raster data, enabling spatiotemporal queries, map algebra raster operations, and compatibility with the ecosystem of Spark ML algorithms. By using DataFrames as the core cognitive and compute data model, it is able to deliver these features in a form that is both accessible to general analysts and scalable along with the rapidly growing data footprint. +RasterFrames provides a DataFrame-centric view over arbitrary geospatial raster data, enabling spatiotemporal queries, map algebra raster operations, and interoperability with Spark ML. By using the DataFrame as the core cognitive and compute data model, RasterFrames is able to deliver an extensive set of functionality in a form that is both horizontally scalable as well as familiar to general analysts and data scientists. It provides APIs for Python, SQL, and Scala. -To learn more, please see the @ref:[Getting Started](getting-started.md) section of this manual. +![RasterFrames](static/rasterframes-pipeline-nologo.png) -The source code can be found on GitHub at [locationtech/rasterframes](https://github.com/locationtech/rasterframes). +Through its custom [Spark DataSource](https://rasterframes.io/raster-read.html), RasterFrames can read various raster formats -- including GeoTIFF, JP2000, MRF, and HDF -- and from an [array of services](https://rasterframes.io/raster-read.html#uri-formats), such as HTTP, FTP, HDFS, S3 and WASB. It also supports reading the vector formats GeoJSON and WKT/WKB. RasterFrame contents can be filtered, transformed, summarized, resampled, and rasterized through [200+ raster and vector functions](https://rasterframes.io/reference.html). + +As part of the LocationTech family of projects, RasterFrames builds upon the strong foundations provided by GeoMesa (spatial operations) , GeoTrellis (raster operations), JTS (geometry modeling) and SFCurve (spatiotemporal indexing), integrating various aspects of these projects into a unified, DataFrame-centric analytics package. + +![](static/rasterframes-locationtech-stack.png) -RasterFrames is released under the [Apache 2.0 License](https://github.com/locationtech/rasterframes/blob/develop/LICENSE). +RasterFrames is released under the commercial-friendly [Apache 2.0](https://github.com/locationtech/rasterframes/blob/develop/LICENSE) open source license. -![RasterFrames](static/rasterframes-pipeline.png) +To learn more, please see the @ref:[Getting Started](getting-started.md) section of this manual. + +The source code can be found on GitHub at [locationtech/rasterframes](https://github.com/locationtech/rasterframes).
diff --git a/pyrasterframes/src/main/python/docs/masking.pymd b/pyrasterframes/src/main/python/docs/masking.pymd new file mode 100644 index 000000000..f3ab08826 --- /dev/null +++ b/pyrasterframes/src/main/python/docs/masking.pymd @@ -0,0 +1,135 @@ +# Masking + +```python setup, echo=False +import pyrasterframes +from pyrasterframes.utils import create_rf_spark_session +from pyrasterframes.rasterfunctions import * +import pyrasterframes.rf_ipython +from IPython.display import display +import pandas as pd +import numpy as np +from pyrasterframes.rf_types import Tile + +spark = create_rf_spark_session() +``` + +Masking is a common operation in raster processing. It is setting certain cells to the @ref:[NoData value](nodata-handling.md). This is usually done to remove low-quality observations from the raster processing. Another related use case is to @ref:["clip"](masking.md#clipping) a raster to a given polygon. + +## Masking Example + +Let's demonstrate masking with a pair of bands of Sentinel-2 data. The measurement bands we will use, blue and green, have no defined NoData. They share quality information from a separate file called the scene classification (SCL), which delineates areas of missing data and probable clouds. For more information on this, see the [Sentinel-2 algorithm overview](https://earth.esa.int/web/sentinel/technical-guides/sentinel-2-msi/level-2a/algorithm). Figure 3 tells us how to interpret the scene classification. For this example, we will exclude NoData, defective pixels, probable clouds, and cirrus clouds: values 0, 1, 8, 9, and 10. + +![Sentinel-2 Scene Classification Values](static/sentinel-2-scene-classification-labels.png) + +Credit: [Sentinel-2 algorithm overview](https://earth.esa.int/web/sentinel/technical-guides/sentinel-2-msi/level-2a/algorithm) + +The first step is to create a catalog with our band of interest and the SCL band. We read the data from the catalog, so all _tiles_ are aligned across rows. + +```python, blue_scl_cat +from pyspark.sql import Row + +blue_uri = 'https://s22s-test-geotiffs.s3.amazonaws.com/luray_snp/B02.tif' +green_uri = 'https://s22s-test-geotiffs.s3.amazonaws.com/luray_snp/B03.tif' +scl_uri = 'https://s22s-test-geotiffs.s3.amazonaws.com/luray_snp/SCL.tif' +cat = spark.createDataFrame([Row(blue=blue_uri, green=green_uri, scl=scl_uri),]) +unmasked = spark.read.raster(cat, catalog_col_names=['blue', 'green', 'scl']) +unmasked.printSchema() +``` + +```python, show_cell_types +unmasked.select(rf_cell_type('blue'), rf_cell_type('scl')).distinct() +``` + +## Define CellType for Masked Tile + +Because there is not a NoData already defined for the blue band, we must choose one. In this particular example, the minimum value is greater than zero, so we can use 0 as the NoData value. We will construct a new `CellType` object to represent this. + +```python, pick_nd +blue_min = unmasked.agg(rf_agg_stats('blue').min.alias('blue_min')) +print('Nonzero minimum value in the blue band:', blue_min.first()) + +blue_ct = unmasked.select(rf_cell_type('blue')).distinct().first()[0][0] +masked_blue_ct = CellType(blue_ct).with_no_data_value(0) +masked_blue_ct.cell_type_name +``` + +We next convert the blue band to this cell type. + +```python, convert_blue +converted = unmasked.select('scl', 'green', rf_convert_cell_type('blue', masked_blue_ct).alias('blue')) +``` + +## Apply Mask from Quality Band + +Now we set cells of our `blue` column to NoData for all locations where the `scl` tile is in our set of undesirable values. This is the actual _masking_ operation. + +```python, apply_mask_blue +from pyspark.sql.functions import lit + +masked = converted.withColumn('blue_masked', rf_mask_by_values('blue', 'scl', [0, 1, 8, 9, 10])) +masked +``` + +We can verify that the number of NoData cells in the resulting `blue_masked` column matches the total of the boolean `mask` _tile_ to ensure our logic is correct. + +```python, show_masked_counts +masked.select(rf_no_data_cells('blue_masked'), rf_tile_sum(rf_local_is_in('scl', [0, 1, 8, 9, 10]))) +``` + +It's also nice to view a sample. The white regions are areas of NoData. + +```python, display_blu, caption='Blue band masked against selected SCL values' +sample = masked.orderBy(-rf_no_data_cells('blue_masked')).select(rf_tile('blue_masked'), rf_tile('scl')).first() +display(sample[0]) +``` + +And the original SCL data. The bright yellow is a cloudy region in the original image. + +```python, display_scl, caption='SCL tile for above' +display(sample[1]) +``` + +## Transferring Mask + +We can now apply the same mask from the blue column to the green column. Note here we have supressed the step of explicitly checking what a "safe" NoData value for the green band should be. + +```python, mask_green +masked.withColumn('green_masked', rf_mask(rf_convert_cell_type('green', masked_blue_ct), 'blue_masked')) \ + .orderBy(-rf_no_data_cells('blue_masked')) +``` + +## Clipping + +Clipping is the use of a polygon to determine the areas to mask in a raster. Typically the areas inside a polygon are retained and the cells outside are set to NoData. Given a geometry column on our DataFrame, we have to carry out three basic steps. First we have to ensure the vector geometry is correctly projected to the same @ref:[CRS](concepts.md#coordinate-reference-system-crs) as the raster. We'll continue with our example creating a simple polygon. Buffering a point will create an approximate circle. + + +```python, reproject_geom +to_rasterize = masked.withColumn('geom_4326', + st_bufferPoint( + st_point(lit(-78.0783132), lit(38.3184340)), + lit(15000))) \ + .withColumn('geom_native', st_reproject('geom_4326', rf_mk_crs('epsg:4326'), rf_crs('blue_masked'))) +``` + +Second, we will rasterize the geometry, or burn-in the geometry into the same grid as the raster. + +```python, rasterize +to_clip = to_rasterize.withColumn('clip_raster', + rf_rasterize('geom_native', rf_geometry('blue_masked'), lit(1), rf_dimensions('blue_masked').cols, rf_dimensions('blue_masked').rows)) + +# visualize some of the edges of our circle +to_clip.select('clip_raster', 'blue_masked') \ + .filter(rf_data_cells('clip_raster') > 20) \ + .orderBy(rf_data_cells('clip_raster')) +``` + +Finally, we create a new _tile_ column with the blue band clipped to our circle. Again we will use the `rf_mask` function to pass the NoData regions along from the rasterized geometry. + +clipped = to_clip.select('blue_masked', + 'clip_raster', + rf_mask('blue_masked', 'clip_raster').alias('blue_clipped')) \ + .filter(rf_data_cells('clip_raster') > 20) \ + .orderBy(rf_data_cells('clip_raster')) + + +This kind of clipping technique is further used in @ref:[zonal statistics](zonal-algebra.md). \ No newline at end of file diff --git a/pyrasterframes/src/main/python/docs/nodata-handling.pymd b/pyrasterframes/src/main/python/docs/nodata-handling.pymd index c9fffe390..d9beea951 100644 --- a/pyrasterframes/src/main/python/docs/nodata-handling.pymd +++ b/pyrasterframes/src/main/python/docs/nodata-handling.pymd @@ -2,7 +2,7 @@ ## What is NoData? -In raster operations, the preservation and correct processing of missing observations is very important. In [most DataFrames and in scientific computing](https://www.oreilly.com/learning/handling-missing-data), the idea of missing data is expressed as a `null` or `NaN` value. However, a great deal of raster data is stored for space efficiency, which typically leads to use of integral values with a ["sentinel" value](https://en.wikipedia.org/wiki/Sentinel_value) designated to represent missing observations. This sentinel value varies across data products and is usually called the "NoData" value. +In raster operations, the preservation and correct processing of missing observations is very important. In [most DataFrames and in scientific computing](https://www.oreilly.com/learning/handling-missing-data), the idea of missing data is expressed as a `null` or `NaN` value. However, a great deal of raster data is stored for space efficiency, which typically leads to use of integral values with a ["sentinel" value](https://en.wikipedia.org/wiki/Sentinel_value) designated to represent missing observations. This sentinel value varies across data products and bands. In a generic sense, it is usually called the "NoData" value. RasterFrames provides a variety of functions to inspect and manage NoData within _tiles_. @@ -75,95 +75,6 @@ print(CellType.float32().no_data_value()) print(CellType.float32().with_no_data_value(-99.9).no_data_value()) ``` -## Masking - -Let's continue the example above with Sentinel-2 data. Band 2 is blue and has no defined NoData. The quality information is in a separate file called the scene classification (SCL), which delineates areas of missing data and probable clouds. For more information on this, see the [Sentinel-2 algorithm overview](https://earth.esa.int/web/sentinel/technical-guides/sentinel-2-msi/level-2a/algorithm). Figure 3 tells us how to interpret the scene classification. For this example, we will exclude NoData, defective pixels, probable clouds, and cirrus clouds: values 0, 1, 8, 9, and 10. - -![Sentinel-2 Scene Classification Values](static/sentinel-2-scene-classification-labels.png) - -Credit: [Sentinel-2 algorithm overview](https://earth.esa.int/web/sentinel/technical-guides/sentinel-2-msi/level-2a/algorithm) - -The first step is to create a catalog with our band of interest and the SCL band. We read the data from the catalog, so the blue band and SCL _tiles_ are aligned across rows. - -```python, blue_scl_cat -from pyspark.sql import Row - -blue_uri = 'https://s22s-test-geotiffs.s3.amazonaws.com/luray_snp/B02.tif' -scl_uri = 'https://s22s-test-geotiffs.s3.amazonaws.com/luray_snp/SCL.tif' -cat = spark.createDataFrame([Row(blue=blue_uri, scl=scl_uri),]) -unmasked = spark.read.raster(cat, catalog_col_names=['blue', 'scl']) -unmasked.printSchema() -``` - -```python, show_cell_types -cell_types = unmasked.select(rf_cell_type('blue'), rf_cell_type('scl')).distinct() -cell_types -``` - -Drawing on @ref:[local map algebra](local-algebra.md) techniques, we will create new _tile_ columns that are indicators of unwanted pixels, as defined above. Since the mask column is an integer type, the addition is equivalent to a logical or, so the boolean true values are 1. - -```python, def_mask -from pyspark.sql.functions import lit - -mask_part = unmasked.withColumn('nodata', rf_local_equal('scl', lit(0))) \ - .withColumn('defect', rf_local_equal('scl', lit(1))) \ - .withColumn('cloud8', rf_local_equal('scl', lit(8))) \ - .withColumn('cloud9', rf_local_equal('scl', lit(9))) \ - .withColumn('cirrus', rf_local_equal('scl', lit(10))) - -one_mask = mask_part.withColumn('mask', rf_local_add('nodata', 'defect')) \ - .withColumn('mask', rf_local_add('mask', 'cloud8')) \ - .withColumn('mask', rf_local_add('mask', 'cloud9')) \ - .withColumn('mask', rf_local_add('mask', 'cirrus')) - -cell_types = one_mask.select(rf_cell_type('mask')).distinct() -cell_types -``` - -Because there is not a NoData already defined, we will choose one. In this particular example, the minimum value is greater than zero, so we can use 0 as the NoData value. - -```python, pick_nd -blue_min = one_mask.agg(rf_agg_stats('blue').min.alias('blue_min')) -blue_min -``` - -We can now construct the cell type string for our blue band's cell type, designating 0 as NoData. - -```python, get_ct_string -blue_ct = one_mask.select(rf_cell_type('blue')).distinct().first()[0][0] -masked_blue_ct = CellType(blue_ct).with_no_data_value(0) -masked_blue_ct.cell_type_name -``` - -Now we will use the @ref:[`rf_mask_by_value`](reference.md#rf-mask-by-value) to designate the cloudy and other unwanted pixels as NoData in the blue column by converting the cell type and applying the mask. - -```python, mask_blu -with_nd = rf_convert_cell_type('blue', masked_blue_ct) -masked = one_mask.withColumn('blue_masked', - rf_mask_by_value(with_nd, 'mask', lit(1))) \ - .drop('nodata', 'defect', 'cloud8', 'cloud9', 'cirrus', 'blue') -``` - -We can verify that the number of NoData cells in the resulting `blue_masked` column matches the total of the boolean `mask` _tile_ to ensure our logic is correct. - -```python, show_masked -counts = masked.select(rf_no_data_cells('blue_masked'), rf_tile_sum('mask')) -counts -``` - -It's also nice to view a sample. The white regions are areas of NoData. - -```python, display_blu, caption='Blue band masked against selected SCL values' -sample = masked.orderBy(-rf_no_data_cells('blue_masked')).select(rf_tile('blue_masked'), rf_tile('scl')).first() -display(sample[0]) -``` - -And the original SCL data. The bright yellow is a cloudy region in the original image. - -```python, display_scl, caption='SCL tile for above' -display(sample[1]) -``` - ## NoData and Local Arithmetic Let's now explore how the presence of NoData affects @ref:[local map algebra](local-algebra.md) operations. To demonstrate the behavior, lets create two _tiles_. One _tile_ will have values of 0 and 1, and the other will have values of just 0. diff --git a/pyrasterframes/src/main/python/docs/raster-processing.md b/pyrasterframes/src/main/python/docs/raster-processing.md index fc6353e37..e112b2287 100644 --- a/pyrasterframes/src/main/python/docs/raster-processing.md +++ b/pyrasterframes/src/main/python/docs/raster-processing.md @@ -4,6 +4,7 @@ * @ref:[Local Map Algebra](local-algebra.md) * @ref:["NoData" Handling](nodata-handling.md) +* @ref:[Masking](masking.md) * @ref:[Zonal Map Algebra](zonal-algebra.md) * @ref:[Aggregation](aggregation.md) * @ref:[Time Series](time-series.md) diff --git a/pyrasterframes/src/main/python/docs/raster-read.pymd b/pyrasterframes/src/main/python/docs/raster-read.pymd index 53f3a96e6..443ee0d96 100644 --- a/pyrasterframes/src/main/python/docs/raster-read.pymd +++ b/pyrasterframes/src/main/python/docs/raster-read.pymd @@ -14,7 +14,7 @@ RasterFrames registers a DataSource named `raster` that enables reading of GeoTI RasterFrames can also read from @ref:[GeoTrellis catalogs and layers](raster-read.md#geotrellis). -## Single Raster +## Single Rasters The simplest way to use the `raster` reader is with a single raster from a single URI or file. In the examples that follow we'll be reading from a Sentinel-2 scene stored in an AWS S3 bucket. @@ -33,14 +33,12 @@ print("CRS", crs.value.crsProj4) ``` ```python, raster_parts -parts = rf.select( +rf.select( rf_extent("proj_raster").alias("extent"), rf_tile("proj_raster").alias("tile") ) -parts ``` - You can also see that the single raster has been broken out into many arbitrary non-overlapping regions. Doing so takes advantage of parallel in-memory reads from the cloud hosted data source and allows Spark to work on manageable amounts of data per task. The following code fragment shows us how many subtiles were created from a single source image. ```python, count_by_uri @@ -55,6 +53,69 @@ tile = rf.select(rf_tile("proj_raster")).first()[0] display(tile) ``` +## Multiple Singleband Rasters + +In this example, we show the reading @ref:[two bands](concepts.md#band) of [Landsat 8](https://landsat.gsfc.nasa.gov/landsat-8/) imagery (red and near-infrared), combining them with `rf_normalized_difference` to compute [NDVI](https://en.wikipedia.org/wiki/Normalized_difference_vegetation_index), a common measure of vegetation health. As described in the section on @ref:[catalogs](raster-catalogs.md), image URIs in a single row are assumed to be from the same scene/granule, and therefore compatible. This pattern is commonly used when multiple bands are stored in separate files. + +```python, multi_singleband +bands = [f'B{b}' for b in [4, 5]] +uris = [f'https://landsat-pds.s3.us-west-2.amazonaws.com/c1/L8/014/032/LC08_L1TP_014032_20190720_20190731_01_T1/LC08_L1TP_014032_20190720_20190731_01_T1_{b}.TIF' for b in bands] +catalog = ','.join(bands) + '\n' + ','.join(uris) + +rf = (spark.read.raster(catalog, bands) + # Adding semantic names + .withColumnRenamed('B4', 'red').withColumnRenamed('B5', 'NIR') + # Adding tile center point for reference + .withColumn('longitude_latitude', st_reproject(st_centroid(rf_geometry('red')), rf_crs('red'), lit('EPSG:4326'))) + # Compute NDVI + .withColumn('NDVI', rf_normalized_difference('NIR', 'red')) + # For the purposes of inspection, filter out rows where there's not much vegetation + .where(rf_tile_sum('NDVI') > 10000) + # Order output + .select('longitude_latitude', 'red', 'NIR', 'NDVI')) +display(rf) +``` + +## Multiband Rasters + +A multiband raster is represented by a three dimensional numeric array stored in a single file. The first two dimensions are spatial, and the third dimension is typically designated for different spectral @ref:[bands](concepts.md#band). The bands could represent intensity of different wavelengths of light (or other electromagnetic radiation), or they could measure other phenomena such as time, quality indications, or additional gas concentrations, etc. + +Multiband rasters files have a strictly ordered set of bands, which are typically indexed from 1. Some files have metadata tags associated with each band. Some files have a color interpetation metadata tag indicating how to interpret the bands. + +When reading a multiband raster or a @ref:[_catalog_](#raster-catalogs) describing multiband rasters, you will need to know ahead of time which bands you want to read. You will specify the bands to read, **indexed from zero**, as a list of integers into the `band_indexes` parameter of the `raster` reader. + +For example, we can read a four-band (red, green, blue, and near-infrared) image as follows. The individual rows of the resulting DataFrame still represent distinct spatial extents, with a projected raster column for each band specified by `band_indexes`. + +```python, multiband +mb = spark.read.raster( + 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif', + band_indexes=[0, 1, 2, 3], +) +display(mb) +``` + +If a band is passed into `band_indexes` that exceeds the number of bands in the raster, a projected raster column will still be generated in the schema but the column will be full of `null` values. + +You can also pass a _catalog_ and `band_indexes` together into the `raster` reader. This will create a projected raster column for the combination of all items in `catalog_col_names` and `band_indexes`. Again if a band in `band_indexes` exceeds the number of bands in a raster, it will have a `null` value for the corresponding column. + +Here is a trivial example with a _catalog_ over multiband rasters. We specify two columns containing URIs and two bands, resulting in four projected raster columns. + +```python, multiband_catalog +import pandas as pd +mb_cat = pd.DataFrame([ + {'foo': 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif', + 'bar': 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif' + }, +]) +mb2 = spark.read.raster( + spark.createDataFrame(mb_cat), + catalog_col_names=['foo', 'bar'], + band_indexes=[0, 1], + tile_dimensions=(64,64) +) +mb2.printSchema() +``` + ## URI Formats RasterFrames relies on three different I/O drivers, selected based on a combination of scheme, file extentions, and library availability. GDAL is used by default if a compatible version of GDAL (>= 2.4) is installed, and if GDAL supports the specified scheme. If GDAL is not available, either the _Java I/O_ or _Hadoop_ driver will be selected, depending on scheme. @@ -154,45 +215,6 @@ non_lazy In the initial examples on this page, you may have noticed that the realized (non-lazy) _tiles_ are shown, but we did not change `lazy_tiles`. Instead, we used @ref:[`rf_tile`](reference.md#rf-tile) to explicitly request the realized _tile_ from the lazy representation. -## Multiband Rasters - -A multiband raster represents a three dimensional numeric array. The first two dimensions are spatial, and the third dimension is typically designated for different spectral @ref:[bands](concepts.md#band). The bands could represent intensity of different wavelengths of light (or other electromagnetic radiation), or they could measure other phenomena such as time, quality indications, or additional gas concentrations, etc. - -Multiband rasters files have a strictly ordered set of bands, which are typically indexed from 1. Some files have metadata tags associated with each band. Some files have a color interpetation metadata tag indicating how to interpret the bands. - -When reading a multiband raster or a _catalog_ describing multiband rasters, you will need to know ahead of time which bands you want to read. You will specify the bands to read, **indexed from zero**, as a list of integers into the `band_indexes` parameter of the `raster` reader. - -For example, we can read a four-band (red, green, blue, and near-infrared) image as follows. The individual rows of the resulting DataFrame still represent distinct spatial extents, with a projected raster column for each band specified by `band_indexes`. - -```python, multiband -mb = spark.read.raster( - 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif', - band_indexes=[0, 1, 2, 3], -) -mb.printSchema() -``` - -If a band is passed into `band_indexes` that exceeds the number of bands in the raster, a projected raster column will still be generated in the schema but the column will be full of `null` values. - -You can also pass a _catalog_ and `band_indexes` together into the `raster` reader. This will create a projected raster column for the combination of all items in `catalog_col_names` and `band_indexes`. Again if a band in `band_indexes` exceeds the number of bands in a raster, it will have a `null` value for the corresponding column. - -Here is a trivial example with a _catalog_ over multiband rasters. We specify two columns containing URIs and two bands, resulting in four projected raster columns. - -```python, multiband_catalog -import pandas as pd -mb_cat = pd.DataFrame([ - {'foo': 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif', - 'bar': 's3://s22s-test-geotiffs/naip/m_3807863_nw_17_1_20160620.tif' - }, -]) -mb2 = spark.read.raster( - spark.createDataFrame(mb_cat), - catalog_col_names=['foo', 'bar'], - band_indexes=[0, 1], - tile_dimensions=(64,64) -) -mb2.printSchema() -``` ## GeoTrellis diff --git a/pyrasterframes/src/main/python/docs/static/rasterframes-pipeline-nologo.png b/pyrasterframes/src/main/python/docs/static/rasterframes-pipeline-nologo.png new file mode 100644 index 000000000..caa011d70 Binary files /dev/null and b/pyrasterframes/src/main/python/docs/static/rasterframes-pipeline-nologo.png differ diff --git a/pyrasterframes/src/main/python/docs/supervised-learning.pymd b/pyrasterframes/src/main/python/docs/supervised-learning.pymd index c66697032..81a81f634 100644 --- a/pyrasterframes/src/main/python/docs/supervised-learning.pymd +++ b/pyrasterframes/src/main/python/docs/supervised-learning.pymd @@ -32,7 +32,8 @@ catalog_df = pd.DataFrame([ {b: uri_base.format(b) for b in cols} ]) -df = spark.read.raster(catalog_df, catalog_col_names=cols, tile_dimensions=(128, 128)) \ +tile_size = 256 +df = spark.read.raster(catalog_df, catalog_col_names=cols, tile_dimensions=(tile_size, tile_size)) \ .repartition(100) df = df.select( @@ -91,23 +92,12 @@ To filter only for good quality pixels, we follow roughly the same procedure as ```python, make_mask from pyspark.sql.functions import lit -mask_part = df_labeled \ - .withColumn('nodata', rf_local_equal('scl', lit(0))) \ - .withColumn('defect', rf_local_equal('scl', lit(1))) \ - .withColumn('cloud8', rf_local_equal('scl', lit(8))) \ - .withColumn('cloud9', rf_local_equal('scl', lit(9))) \ - .withColumn('cirrus', rf_local_equal('scl', lit(10))) - -df_mask_inv = mask_part \ - .withColumn('mask', rf_local_add('nodata', 'defect')) \ - .withColumn('mask', rf_local_add('mask', 'cloud8')) \ - .withColumn('mask', rf_local_add('mask', 'cloud9')) \ - .withColumn('mask', rf_local_add('mask', 'cirrus')) \ - .drop('nodata', 'defect', 'cloud8', 'cloud9', 'cirrus') - +df_labeled = df_labeled \ + .withColumn('mask', rf_local_is_in('scl', [0, 1, 8, 9, 10])) + # at this point the mask contains 0 for good cells and 1 for defect, etc # convert cell type and set value 1 to NoData -df_mask = df_mask_inv.withColumn('mask', +df_mask = df_labeled.withColumn('mask', rf_with_no_data(rf_convert_cell_type('mask', 'uint8'), 1.0) ) @@ -204,29 +194,35 @@ scored = model.transform(df_mask.drop('label')) retiled = scored \ .groupBy('extent', 'crs') \ .agg( - rf_assemble_tile('column_index', 'row_index', 'prediction', 128, 128).alias('prediction'), - rf_assemble_tile('column_index', 'row_index', 'B04', 128, 128).alias('red'), - rf_assemble_tile('column_index', 'row_index', 'B03', 128, 128).alias('grn'), - rf_assemble_tile('column_index', 'row_index', 'B02', 128, 128).alias('blu') + rf_assemble_tile('column_index', 'row_index', 'prediction', tile_size, tile_size).alias('prediction'), + rf_assemble_tile('column_index', 'row_index', 'B04', tile_size, tile_size).alias('red'), + rf_assemble_tile('column_index', 'row_index', 'B03', tile_size, tile_size).alias('grn'), + rf_assemble_tile('column_index', 'row_index', 'B02', tile_size, tile_size).alias('blu') ) retiled.printSchema() ``` Take a look at a sample of the resulting output and the corresponding area's red-green-blue composite image. +Recall the label coding: 1 is forest (purple), 2 is cropland (green) and 3 is developed areas(yellow). ```python, display_rgb sample = retiled \ - .select('prediction', rf_rgb_composite('red', 'grn', 'blu').alias('rgb')) \ + .select('prediction', 'red', 'grn', 'blu') \ .sort(-rf_tile_sum(rf_local_equal('prediction', lit(3.0)))) \ .first() -sample_rgb = sample['rgb'] -mins = np.nanmin(sample_rgb.cells, axis=(0,1)) -plt.imshow((sample_rgb.cells - mins) / (np.nanmax(sample_rgb.cells, axis=(0,1)) - mins)) -``` +sample_rgb = np.concatenate([sample['red'].cells[:, :, None], + sample['grn'].cells[ :, :, None], + sample['blu'].cells[ :, :, None]], axis=2) +# plot scaled RGB +scaling_quantiles = np.nanpercentile(sample_rgb, [3.00, 97.00], axis=(0,1)) +scaled = np.clip(sample_rgb, scaling_quantiles[0, :], scaling_quantiles[1, :]) +scaled -= scaling_quantiles[0, :] +scaled /= (scaling_quantiles[1, : ] - scaling_quantiles[0, :]) -Recall the label coding: 1 is forest (purple), 2 is cropland (green) and 3 is developed areas(yellow). +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5)) +ax1.imshow(scaled) -```python, display_prediction -display(sample['prediction']) +# display prediction +ax2.imshow(sample['prediction'].cells) ``` diff --git a/pyrasterframes/src/main/python/docs/zonal-algebra.pymd b/pyrasterframes/src/main/python/docs/zonal-algebra.pymd index 9869e6b36..b3f4951eb 100644 --- a/pyrasterframes/src/main/python/docs/zonal-algebra.pymd +++ b/pyrasterframes/src/main/python/docs/zonal-algebra.pymd @@ -96,7 +96,7 @@ park_rf.printSchema() ## Define Zone Tiles -Now we have the vector representation of the park boundary alongside the _tiles_ of red and near infrared bands. Next, we need to create a _tile_ representation of the park to allow us to limit the raster analysis to pixels within the park _zone_. This is similar to the masking operation demonstrated in @ref:[NoData handling](nodata-handling.md#masking). We rasterize the geometries using @ref:[`rf_rasterize`](reference.md#rf-rasterize): this creates a new _tile_ column aligned with the imagery, and containing the park's OBJECTID attribute for cells intersecting the _zone_. Cells outside the park _zones_ have a NoData value. +Now we have the vector representation of the park boundary alongside the _tiles_ of red and near infrared bands. Next, we need to create a _tile_ representation of the park to allow us to limit the raster analysis to pixels within the park _zone_. This is similar to the masking operation demonstrated in @ref:[Masking](masking.md#masking). We rasterize the geometries using @ref:[`rf_rasterize`](reference.md#rf-rasterize): this creates a new _tile_ column aligned with the imagery, and containing the park's OBJECTID attribute for cells intersecting the _zone_. Cells outside the park _zones_ have a NoData value. ```python burn_in rf_park_tile = park_rf \ diff --git a/pyrasterframes/src/main/python/pyrasterframes/rasterfunctions.py b/pyrasterframes/src/main/python/pyrasterframes/rasterfunctions.py index 9c0e52f09..ae5977f51 100644 --- a/pyrasterframes/src/main/python/pyrasterframes/rasterfunctions.py +++ b/pyrasterframes/src/main/python/pyrasterframes/rasterfunctions.py @@ -25,6 +25,7 @@ """ from __future__ import absolute_import from pyspark.sql.column import Column, _to_java_column +from pyspark.sql.functions import lit from .rf_context import RFContext from .rf_types import CellType @@ -137,20 +138,6 @@ def rf_explode_tiles_sample(sample_frac, seed, *tile_cols): return Column(jfcn(sample_frac, seed, RFContext.active().list_to_seq(jcols))) -def rf_mask_by_value(data_tile, mask_tile, mask_value): - """Generate a tile with the values from the data tile, but where cells in the masking tile contain the masking - value, replace the data value with NODATA. """ - jfcn = RFContext.active().lookup('rf_mask_by_value') - return Column(jfcn(_to_java_column(data_tile), _to_java_column(mask_tile), _to_java_column(mask_value))) - - -def rf_inverse_mask_by_value(data_tile, mask_tile, mask_value): - """Generate a tile with the values from the data tile, but where cells in the masking tile do not contain the - masking value, replace the data value with NODATA. """ - jfcn = RFContext.active().lookup('rf_inverse_mask_by_value') - return Column(jfcn(_to_java_column(data_tile), _to_java_column(mask_tile), _to_java_column(mask_value))) - - def _apply_scalar_to_tile(name, tile_col, scalar): jfcn = RFContext.active().lookup(name) return Column(jfcn(_to_java_column(tile_col), scalar)) @@ -260,14 +247,26 @@ def rf_local_unequal_int(tile_col, scalar): """Return a Tile with values equal 1 if the cell is not equal to a scalar, otherwise 0""" return _apply_scalar_to_tile('rf_local_unequal_int', tile_col, scalar) + def rf_local_no_data(tile_col): """Return a tile with ones where the input is NoData, otherwise zero.""" return _apply_column_function('rf_local_no_data', tile_col) + def rf_local_data(tile_col): """Return a tile with zeros where the input is NoData, otherwise one.""" return _apply_column_function('rf_local_data', tile_col) + +def rf_local_is_in(tile_col, array): + """Return a tile with cell values of 1 where the `tile_col` cell is in the provided array.""" + from pyspark.sql.functions import array as sql_array + if isinstance(array, list): + array = sql_array([lit(v) for v in array]) + + return _apply_column_function('rf_local_is_in', tile_col, array) + + def _apply_column_function(name, *args): jfcn = RFContext.active().lookup(name) jcols = [_to_java_column(arg) for arg in args] @@ -449,16 +448,53 @@ def rf_agg_local_stats(tile_col): return _apply_column_function('rf_agg_local_stats', tile_col) -def rf_mask(src_tile_col, mask_tile_col): - """Where the rf_mask (second) tile contains NODATA, replace values in the source (first) tile with NODATA.""" - return _apply_column_function('rf_mask', src_tile_col, mask_tile_col) +def rf_mask(src_tile_col, mask_tile_col, inverse=False): + """Where the rf_mask (second) tile contains NODATA, replace values in the source (first) tile with NODATA. + If `inverse` is true, replaces values in the source tile with NODATA where the mask tile contains valid data. + """ + if not inverse: + return _apply_column_function('rf_mask', src_tile_col, mask_tile_col) + else: + rf_inverse_mask(src_tile_col, mask_tile_col) def rf_inverse_mask(src_tile_col, mask_tile_col): - """Where the rf_mask (second) tile DOES NOT contain NODATA, replace values in the source (first) tile with NODATA.""" + """Where the rf_mask (second) tile DOES NOT contain NODATA, replace values in the source + (first) tile with NODATA.""" return _apply_column_function('rf_inverse_mask', src_tile_col, mask_tile_col) +def rf_mask_by_value(data_tile, mask_tile, mask_value, inverse=False): + """Generate a tile with the values from the data tile, but where cells in the masking tile contain the masking + value, replace the data value with NODATA. """ + if isinstance(mask_value, (int, float)): + mask_value = lit(mask_value) + jfcn = RFContext.active().lookup('rf_mask_by_value') + + return Column(jfcn(_to_java_column(data_tile), _to_java_column(mask_tile), _to_java_column(mask_value), inverse)) + + +def rf_mask_by_values(data_tile, mask_tile, mask_values): + """Generate a tile with the values from `data_tile`, but where cells in the `mask_tile` are in the `mask_values` + list, replace the value with NODATA. + """ + from pyspark.sql.functions import array as sql_array + if isinstance(mask_values, list): + mask_values = sql_array([lit(v) for v in mask_values]) + + jfcn = RFContext.active().lookup('rf_mask_by_values') + col_args = [_to_java_column(c) for c in [data_tile, mask_tile, mask_values]] + return Column(jfcn(*col_args)) + + +def rf_inverse_mask_by_value(data_tile, mask_tile, mask_value): + """Generate a tile with the values from the data tile, but where cells in the masking tile do not contain the + masking value, replace the data value with NODATA. """ + if isinstance(mask_value, (int, float)): + mask_value = lit(mask_value) + return _apply_column_function('rf_inverse_mask_by_value', data_tile, mask_tile, mask_value) + + def rf_local_less(left_tile_col, right_tile_col): """Cellwise less than comparison between two tiles""" return _apply_column_function('rf_local_less', left_tile_col, right_tile_col) @@ -585,6 +621,18 @@ def rf_geometry(proj_raster_col): """Get the extent of a RasterSource or ProjectdRasterTile as a Geometry""" return _apply_column_function('rf_geometry', proj_raster_col) + +def rf_spatial_index(geom_col, crs_col=None, index_resolution = 18): + """Constructs a XZ2 index in WGS84 from either a Geometry, Extent, ProjectedRasterTile, or RasterSource and its CRS. + For details: https://www.geomesa.org/documentation/user/datastores/index_overview.html """ + + jfcn = RFContext.active().lookup('rf_spatial_index') + + if crs_col is not None: + return Column(jfcn(_to_java_column(geom_col), _to_java_column(crs_col), index_resolution)) + else: + return Column(jfcn(_to_java_column(geom_col), index_resolution)) + # ------ GeoMesa Functions ------ def st_geomFromGeoHash(*args): diff --git a/pyrasterframes/src/main/python/pyrasterframes/rf_ipython.py b/pyrasterframes/src/main/python/pyrasterframes/rf_ipython.py index 0066e7dd7..0ae23d4ab 100644 --- a/pyrasterframes/src/main/python/pyrasterframes/rf_ipython.py +++ b/pyrasterframes/src/main/python/pyrasterframes/rf_ipython.py @@ -19,6 +19,8 @@ # import pyrasterframes.rf_types +from shapely.geometry.base import BaseGeometry + import numpy as np @@ -120,13 +122,18 @@ def pandas_df_to_html(df): if not pd.get_option("display.notebook_repr_html"): return None + default_max_colwidth = pd.get_option('display.max_colwidth') # we'll try to politely put it back + if len(df) == 0: return df._repr_html_() tile_cols = [] + geom_cols = [] for c in df.columns: if isinstance(df.iloc[0][c], pyrasterframes.rf_types.Tile): # if the first is a Tile try formatting tile_cols.append(c) + elif isinstance(df.iloc[0][c], BaseGeometry): # if the first is a Geometry try formatting + geom_cols.append(c) def _safe_tile_to_html(t): if isinstance(t, pyrasterframes.rf_types.Tile): @@ -135,11 +142,21 @@ def _safe_tile_to_html(t): # handles case where objects in a column are not all Tile type return t.__repr__() + def _safe_geom_to_html(g): + if isinstance(g, BaseGeometry): + wkt = g.wkt + if len(wkt) > default_max_colwidth: + return wkt[:default_max_colwidth-3] + '...' + else: + wkt + else: + return g.__repr__() + # dict keyed by column with custom rendering function formatter = {c: _safe_tile_to_html for c in tile_cols} + formatter.update({c: _safe_geom_to_html for c in geom_cols}) # This is needed to avoid our tile being rendered as `=1.6.0 -pyspark==2.3.4 # See issue # 154 +pyspark==2.4.4 numpy>=1.7 -pandas>=0.25.0 +pandas>=0.24.2 matplotlib<3.0.0 # no python 2.7 support after v2.x.x ipython==6.2.1 rasterio>=1.0.0 diff --git a/pyrasterframes/src/main/python/setup.cfg b/pyrasterframes/src/main/python/setup.cfg index 8088676c6..4d9369ec4 100644 --- a/pyrasterframes/src/main/python/setup.cfg +++ b/pyrasterframes/src/main/python/setup.cfg @@ -2,10 +2,10 @@ license_files = LICENSE.txt [bdist_wheel] -universal=1 +universal = 0 [aliases] -test=pytest +test = pytest [tool:pytest] addopts = --verbose diff --git a/pyrasterframes/src/main/python/setup.py b/pyrasterframes/src/main/python/setup.py index 611950c9c..70f4b2dcc 100644 --- a/pyrasterframes/src/main/python/setup.py +++ b/pyrasterframes/src/main/python/setup.py @@ -130,6 +130,26 @@ def initialize_options(self): def dest_file(self, src_file): return path.splitext(src_file)[0] + '.ipynb' +pytz = 'pytz' +shapely = 'Shapely>=1.6.0' +pyspark ='pyspark==2.4.4' +numpy = 'numpy>=1.12.0' +matplotlib ='matplotlib' +pandas = 'pandas>=0.24.2' +geopandas = 'geopandas' +requests = 'requests' +pytest_runner = 'pytest-runner' +setuptools = 'setuptools>=0.8' +ipython = 'ipython==6.2.1' +ipykernel = 'ipykernel==4.8.0' +pweave = 'Pweave==0.30.3' +fiona = 'fiona==1.8.6' +rasterio = 'rasterio>=1.0.0' +folium = 'folium' +pytest = 'pytest>=4.0.0,<5.0.0' +pypandoc = 'pypandoc' +boto3 = 'boto3' + setup( name='pyrasterframes', description='Access and process geospatial raster data in PySpark DataFrames', @@ -144,40 +164,41 @@ def dest_file(self, src_file): 'Bug Reports': 'https://github.com/locationtech/rasterframes/issues', 'Source': 'https://github.com/locationtech/rasterframes', }, + python_requires=">=3.5", install_requires=[ - 'pytz', - 'Shapely>=1.6.0', - 'pyspark<2.4', - 'numpy>=1.7', - 'pandas>=0.25.0', + pytz, + shapely, + pyspark, + numpy, + pandas ], setup_requires=[ - 'pytz', - 'Shapely>=1.6.0', - 'pyspark<2.4', - 'numpy>=1.7', - 'matplotlib<3.0.0', - 'pandas>=0.25.0', - 'geopandas', - 'requests', - 'pytest-runner', - 'setuptools>=0.8', - 'ipython==6.2.1', - 'ipykernel==4.8.0', - 'Pweave==0.30.3', - 'fiona==1.8.6', - 'rasterio>=1.0.0', # for docs - 'folium', + pytz, + shapely, + pyspark, + numpy, + matplotlib, + pandas, + geopandas, + requests, + pytest_runner, + setuptools, + ipython, + ipykernel, + pweave, + fiona, + rasterio, + folium ], tests_require=[ - 'pytest==3.4.2', - 'pypandoc', - 'numpy>=1.7', - 'Shapely>=1.6.0', - 'pandas>=0.25.0', - 'rasterio>=1.0.0', - 'boto3', - 'Pweave==0.30.3', + pytest, + pypandoc, + numpy, + shapely, + pandas, + rasterio, + boto3, + pweave ], packages=[ 'pyrasterframes', diff --git a/pyrasterframes/src/main/python/tests/PyRasterFramesTests.py b/pyrasterframes/src/main/python/tests/PyRasterFramesTests.py index 7cda3b997..3bb2ce491 100644 --- a/pyrasterframes/src/main/python/tests/PyRasterFramesTests.py +++ b/pyrasterframes/src/main/python/tests/PyRasterFramesTests.py @@ -131,7 +131,7 @@ def test_tile_udt_serialization(self): cells[1][1] = nd a_tile = Tile(cells, ct.with_no_data_value(nd)) round_trip = udt.fromInternal(udt.toInternal(a_tile)) - self.assertEquals(a_tile, round_trip, "round-trip serialization for " + str(ct)) + self.assertEqual(a_tile, round_trip, "round-trip serialization for " + str(ct)) schema = StructType([StructField("tile", TileUDT(), False)]) df = self.spark.createDataFrame([{"tile": a_tile}], schema) diff --git a/pyrasterframes/src/main/python/tests/RasterFunctionsTests.py b/pyrasterframes/src/main/python/tests/RasterFunctionsTests.py index ca17dc325..6c82f867c 100644 --- a/pyrasterframes/src/main/python/tests/RasterFunctionsTests.py +++ b/pyrasterframes/src/main/python/tests/RasterFunctionsTests.py @@ -24,6 +24,8 @@ from pyspark import Row from pyspark.sql.functions import * +import numpy as np +from numpy.testing import assert_equal from . import TestEnvironment @@ -103,7 +105,6 @@ def test_agg_mean(self): def test_agg_local_mean(self): from pyspark.sql import Row from pyrasterframes.rf_types import Tile - import numpy as np # this is really testing the nodata propagation in the agg local summation ct = CellType.int8().with_no_data_value(4) @@ -221,20 +222,43 @@ def test_mask_by_value(self): rf_local_greater_int(self.rf.tile, 25000), "uint8"), lit(mask_value)).alias('mask')) - rf2 = rf1.select(rf1.tile, rf_mask_by_value(rf1.tile, rf1.mask, lit(mask_value)).alias('masked')) + rf2 = rf1.select(rf1.tile, rf_mask_by_value(rf1.tile, rf1.mask, lit(mask_value), False).alias('masked')) result = rf2.agg(rf_agg_no_data_cells(rf2.tile) < rf_agg_no_data_cells(rf2.masked)) \ .collect()[0][0] self.assertTrue(result) - rf3 = rf1.select(rf1.tile, rf_inverse_mask_by_value(rf1.tile, rf1.mask, lit(mask_value)).alias('masked')) - result = rf3.agg(rf_agg_no_data_cells(rf3.tile) < rf_agg_no_data_cells(rf3.masked)) \ - .collect()[0][0] - self.assertTrue(result) + # note supplying a `int` here, not a column to mask value + rf3 = rf1.select( + rf1.tile, + rf_inverse_mask_by_value(rf1.tile, rf1.mask, mask_value).alias('masked'), + rf_mask_by_value(rf1.tile, rf1.mask, mask_value, True).alias('masked2'), + ) + result = rf3.agg( + rf_agg_no_data_cells(rf3.tile) < rf_agg_no_data_cells(rf3.masked), + rf_agg_no_data_cells(rf3.tile) < rf_agg_no_data_cells(rf3.masked2), + ) \ + .first() + self.assertTrue(result[0]) + self.assertTrue(result[1]) # inverse mask arg gives equivalent result + + result_equiv_tiles = rf3.select(rf_for_all(rf_local_equal(rf3.masked, rf3.masked2))).first()[0] + self.assertTrue(result_equiv_tiles) # inverse fn and inverse arg produce same Tile + + def test_mask_by_values(self): + + tile = Tile(np.random.randint(1, 100, (5, 5)), CellType.uint8()) + mask_tile = Tile(np.array(range(1, 26), 'uint8').reshape(5, 5)) + expected_diag_nd = Tile(np.ma.masked_array(tile.cells, mask=np.eye(5))) + + df = self.spark.createDataFrame([Row(t=tile, m=mask_tile)]) \ + .select(rf_mask_by_values('t', 'm', [0, 6, 12, 18, 24])) # values on the diagonal + result0 = df.first() + # assert_equal(result0[0].cells, expected_diag_nd) + self.assertTrue(result0[0] == expected_diag_nd) def test_mask(self): from pyspark.sql import Row from pyrasterframes.rf_types import Tile, CellType - import numpy as np np.random.seed(999) ma = np.ma.array(np.random.randint(0, 10, (5, 5), dtype='int8'), mask=np.random.rand(5, 5) > 0.7) @@ -323,13 +347,9 @@ def test_render_composite(self): # Look for the PNG magic cookie self.assertEqual(png_bytes[0:8], bytearray([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) - - - def test_rf_interpret_cell_type_as(self): from pyspark.sql import Row from pyrasterframes.rf_types import Tile - import numpy as np df = self.spark.createDataFrame([ Row(t=Tile(np.array([[1, 3, 4], [5, 0, 3]]), CellType.uint8().with_no_data_value(5))) @@ -344,11 +364,12 @@ def test_rf_interpret_cell_type_as(self): def test_rf_local_data_and_no_data(self): from pyspark.sql import Row from pyrasterframes.rf_types import Tile - import numpy as np - from numpy.testing import assert_equal - t = Tile(np.array([[1, 3, 4], [5, 0, 3]]), CellType.uint8().with_no_data_value(5)) - #note the convert is due to issue #188 + nd = 5 + t = Tile( + np.array([[1, 3, 4], [nd, 0, 3]]), + CellType.uint8().with_no_data_value(nd)) + # note the convert is due to issue #188 df = self.spark.createDataFrame([Row(t=t)])\ .withColumn('lnd', rf_convert_cell_type(rf_local_no_data('t'), 'uint8')) \ .withColumn('ld', rf_convert_cell_type(rf_local_data('t'), 'uint8')) @@ -359,3 +380,44 @@ def test_rf_local_data_and_no_data(self): result_d = result['ld'] assert_equal(result_d.cells, np.invert(t.cells.mask)) + + def test_rf_local_is_in(self): + from pyspark.sql.functions import lit, array, col + from pyspark.sql import Row + + nd = 5 + t = Tile( + np.array([[1, 3, 4], [nd, 0, 3]]), + CellType.uint8().with_no_data_value(nd)) + # note the convert is due to issue #188 + df = self.spark.createDataFrame([Row(t=t)]) \ + .withColumn('a', array(lit(3), lit(4))) \ + .withColumn('in2', rf_convert_cell_type( + rf_local_is_in(col('t'), array(lit(0), lit(4))), + 'uint8')) \ + .withColumn('in3', rf_convert_cell_type(rf_local_is_in('t', 'a'), 'uint8')) \ + .withColumn('in4', rf_convert_cell_type( + rf_local_is_in('t', array(lit(0), lit(4), lit(3))), + 'uint8')) \ + .withColumn('in_list', rf_convert_cell_type(rf_local_is_in(col('t'), [4, 1]), 'uint8')) + + result = df.first() + self.assertEqual(result['in2'].cells.sum(), 2) + assert_equal(result['in2'].cells, np.isin(t.cells, np.array([0, 4]))) + self.assertEqual(result['in3'].cells.sum(), 3) + self.assertEqual(result['in4'].cells.sum(), 4) + self.assertEqual(result['in_list'].cells.sum(), 2, + "Tile value {} should contain two 1s as: [[1, 0, 1],[0, 0, 0]]" + .format(result['in_list'].cells)) + + def test_rf_spatial_index(self): + from pyspark.sql.functions import min as F_min + result_one_arg = self.df.select(rf_spatial_index('tile').alias('ix')) \ + .agg(F_min('ix')).first()[0] + print(result_one_arg) + + result_two_arg = self.df.select(rf_spatial_index(rf_extent('tile'), rf_crs('tile')).alias('ix')) \ + .agg(F_min('ix')).first()[0] + + self.assertEqual(result_two_arg, result_one_arg) + self.assertEqual(result_one_arg, 55179438768) # this is a bit more fragile but less important diff --git a/pyrasterframes/src/main/python/tests/VectorTypesTests.py b/pyrasterframes/src/main/python/tests/VectorTypesTests.py index e31f26b43..70e94af72 100644 --- a/pyrasterframes/src/main/python/tests/VectorTypesTests.py +++ b/pyrasterframes/src/main/python/tests/VectorTypesTests.py @@ -156,3 +156,16 @@ def test_geojson(self): geo = self.spark.read.geojson(sample) geo.show() self.assertEqual(geo.select('geometry').count(), 8) + + def test_spatial_index(self): + df = self.df.select(rf_spatial_index(self.df.poly_geom, rf_crs(lit("EPSG:4326"))).alias('index')) + expected = {22858201775, 38132946267, 38166922588, 38180072113} + indexes = {x[0] for x in df.collect()} + self.assertSetEqual(indexes, expected) + + # Custom resolution + df = self.df.select(rf_spatial_index(self.df.poly_geom, rf_crs(lit("EPSG:4326")), 3).alias('index')) + expected = {21, 36} + indexes = {x[0] for x in df.collect()} + self.assertSetEqual(indexes, expected) + diff --git a/pyrasterframes/src/main/python/tests/__init__.py b/pyrasterframes/src/main/python/tests/__init__.py index bea51f58b..b09b5f6f3 100644 --- a/pyrasterframes/src/main/python/tests/__init__.py +++ b/pyrasterframes/src/main/python/tests/__init__.py @@ -94,3 +94,7 @@ def create_layer(self): self.rf = rf.withColumn('tile2', rf_convert_cell_type('tile', 'float32')) \ .drop('tile') \ .withColumnRenamed('tile2', 'tile').as_layer() + + df = self.spark.read.raster(self.img_uri) + self.df = df.withColumn('tile', rf_convert_cell_type('proj_raster', 'float32')) \ + .drop('proj_raster') diff --git a/rf-notebook/build.sbt b/rf-notebook/build.sbt index b7e7b6213..7e406b411 100644 --- a/rf-notebook/build.sbt +++ b/rf-notebook/build.sbt @@ -1,5 +1,6 @@ import scala.sys.process.Process import PythonBuildPlugin.autoImport.pyWhl +import com.typesafe.sbt.git.DefaultReadableGit lazy val includeNotebooks = settingKey[Boolean]("Whether to build documentation into notebooks and include them") includeNotebooks := true @@ -8,6 +9,11 @@ Docker / packageName := "s22s/rasterframes-notebook" Docker / version := version.value +dockerAliases += dockerAlias.value.withTag({ + val sha = new DefaultReadableGit(file(".")).withGit(_.headCommitSha) + sha.map(_.take(7)) +}) + Docker / maintainer := organization.value Docker / sourceDirectory := baseDirectory.value / "src"/ "main" / "docker" @@ -44,6 +50,7 @@ Docker / dockerGenerateConfig := (Docker / sourceDirectory).value / "Dockerfile" // Save a bit of typing... publishLocal := (Docker / publishLocal).value +publish := (Docker / publish).value // -----== Conveniences ==----- diff --git a/rf-notebook/src/main/docker/Dockerfile b/rf-notebook/src/main/docker/Dockerfile index 6c7e514dd..d4271e370 100644 --- a/rf-notebook/src/main/docker/Dockerfile +++ b/rf-notebook/src/main/docker/Dockerfile @@ -1,30 +1,58 @@ -FROM s22s/pyspark-notebook:spark-2.3.4-hadoop-2.7 +# jupyter/scipy-notebook isn't semantically versioned. +# We pick this arbitrary one from Sept 2019 because it's what latest was on Oct 17 2019. +FROM jupyter/scipy-notebook:1386e2046833 -MAINTAINER Astraea, Inc. +LABEL maintainer="Astraea, Inc. " -ENV RF_LIB_LOC=/usr/local/rasterframes \ - LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/conda/lib" +EXPOSE 4040 4041 4042 4043 4044 USER root +RUN \ + apt-get -y update && \ + apt-get install --no-install-recommends -y openjdk-8-jre-headless ca-certificates-java && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Spark dependencies +ENV APACHE_SPARK_VERSION 2.4.4 +ENV HADOOP_VERSION 2.7 +ENV APACHE_SPARK_CHECKSUM 2E3A5C853B9F28C7D4525C0ADCB0D971B73AD47D5CCE138C85335B9F53A6519540D3923CB0B5CEE41E386E49AE8A409A51AB7194BA11A254E037A848D0C4A9E5 +ENV APACHE_SPARK_FILENAME spark-${APACHE_SPARK_VERSION}-bin-hadoop${HADOOP_VERSION}.tgz +ENV APACHE_SPARK_REMOTE_PATH spark-${APACHE_SPARK_VERSION}/${APACHE_SPARK_FILENAME} + +RUN \ + cd /tmp && \ + wget --quiet http://apache.mirrors.pair.com/spark/${APACHE_SPARK_REMOTE_PATH} && \ + echo "${APACHE_SPARK_CHECKSUM} *${APACHE_SPARK_FILENAME}" | sha512sum -c - && \ + tar xzf ${APACHE_SPARK_FILENAME} -C /usr/local --owner root --group root --no-same-owner && \ + rm ${APACHE_SPARK_FILENAME} + +RUN cd /usr/local && ln -s spark-${APACHE_SPARK_VERSION}-bin-hadoop${HADOOP_VERSION} spark + +# Spark config +ENV SPARK_HOME /usr/local/spark +ENV PYTHONPATH $SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.7-src.zip +ENV SPARK_OPTS --driver-java-options=-Xms1024M --driver-java-options=-Xmx4096M --driver-java-options=-Dlog4j.logLevel=info + +COPY conda_cleanup.sh . +RUN chmod u+x conda_cleanup.sh + +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/conda/lib" +# Sphinx (for Notebook->html) and pyarrow (from pyspark build) +RUN \ + conda install --quiet --yes pyarrow \ + anaconda sphinx nbsphinx shapely numpy folium geopandas geojsonio rasterio descartes && \ + ./conda_cleanup.sh $NB_USER $CONDA_DIR + +ENV RF_LIB_LOC=/usr/local/rasterframes RUN mkdir $RF_LIB_LOC -EXPOSE 4040 4041 4042 4043 4044 - -# Sphinx (for Notebook->html) -RUN conda install --quiet --yes \ - anaconda sphinx nbsphinx shapely numpy folium geopandas geojsonio rasterio descartes - -# Cleanup pip residuals -RUN rm -rf /home/$NB_USER/.local && \ - fix-permissions /home/$NB_USER && \ - fix-permissions $CONDA_DIR - COPY *.whl $RF_LIB_LOC COPY jupyter_notebook_config.py $HOME/.jupyter COPY examples $HOME/examples -RUN ls -1 $RF_LIB_LOC/*.whl | xargs pip install +RUN ls -1 $RF_LIB_LOC/*.whl | xargs pip install --no-cache-dir RUN chmod -R +w $HOME/examples && chown -R $NB_UID:$NB_GID $HOME -USER $NB_UID \ No newline at end of file +USER $NB_UID diff --git a/rf-notebook/src/main/docker/conda_cleanup.sh b/rf-notebook/src/main/docker/conda_cleanup.sh new file mode 100644 index 000000000..a48622d6d --- /dev/null +++ b/rf-notebook/src/main/docker/conda_cleanup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +NB_USER=$1 +CONDA_DIR=$2 +conda clean --all --force-pkgs-dirs --yes && \ + rm -rf /home/$NB_USER/.local && \ + find /opt/conda/ -type f,l -name '*.a' -delete && \ + find /opt/conda/ -type f,l -name '*.pyc' -delete && \ + find /opt/conda/ -type f,l -name '*.js.map' -delete && \ + find /opt/conda/lib/python*/site-packages/bokeh/server/static -type f,l -name '*.js' -not -name '*.min.js' -delete && \ + rm -rf /opt/conda/pkgs && \ + fix-permissions $CONDA_DIR && \ + fix-permissions /home/$NB_USER \ No newline at end of file diff --git a/rf-notebook/src/main/notebooks/Getting Started.ipynb b/rf-notebook/src/main/notebooks/Getting Started.ipynb index 1c0355774..2bcc5b3ec 100644 --- a/rf-notebook/src/main/notebooks/Getting Started.ipynb +++ b/rf-notebook/src/main/notebooks/Getting Started.ipynb @@ -21,9 +21,9 @@ "outputs": [], "source": [ "import pyrasterframes\n", + "from pyrasterframes.utils import create_rf_spark_session\n", "import pyrasterframes.rf_ipython # enables nicer visualizations of pandas DF\n", - "from pyrasterframes.rasterfunctions import (rf_local_add, rf_dimensions, rf_extent, rf_crs, rf_mk_crs,\n", - " st_geometry, st_reproject, rf_tile)\n", + "from pyrasterframes.rasterfunctions import *\n", "import pyspark.sql.functions as F" ] }, @@ -35,7 +35,7 @@ }, "outputs": [], "source": [ - "spark = pyrasterframes.get_spark_session()" + "spark = create_rf_spark_session()" ] }, { @@ -100,25 +100,45 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "|rf_local_add(proj_raster, 3) |\n", - "+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "|[[[-7783653.637667, 993342.4642358534, -7665045.582235852, 1111950.519667], [+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ]], [int16ud32767, (256,255), [3408,3471,3110,2875,2798,2973,3255,3169,-2147483648,3217,...,-2147483648,-2147483648,-2147483648,-2147483648,-2147483648,-2147483648,-2147483648,2841,3226,-2147483648]]]|\n", - "|[[[-7665045.582235853, 993342.4642358534, -7546437.526804706, 1111950.519667], [+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ]], [int16ud32767, (256,255), [2337,2346,2581,2751,2575,2364,2223,2384,2618,2296,...,-2147483648,-2147483648,2608,2701,2713,3050,2983,2953,3252,2682]]] |\n", - "|[[[-7546437.526804707, 993342.4642358534, -7427829.471373559, 1111950.519667], [+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ]], [int16ud32767, (256,255), [2728,2784,2781,2567,2539,2254,2327,2436,2888,2589,...,2741,2515,2843,2934,2801,3044,2899,2430,2471,2645]]] |\n", - "|[[[-7427829.47137356, 993342.4642358534, -7309221.415942413, 1111950.519667], [+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ]], [int16ud32767, (256,255), [3058,3163,3036,3228,2877,3310,2885,2932,2931,2940,...,2634,2531,2122,1911,2229,2507,2239,2272,2499,2966]]] |\n", - "|[[[-7309221.415942414, 993342.4642358534, -7190613.360511266, 1111950.519667], [+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ]], [int16ud32767, (256,255), [3355,3502,3055,3343,3334,-2147483648,-2147483648,-2147483648,-2147483648,3058,...,2537,2851,2905,2449,2605,3025,2719,3054,3226,3052]]] |\n", - "+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "only showing top 5 rows\n", - "\n" - ] + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Showing only top 5 rows
rf_local_add(proj_raster, 3)
" + ], + "text/markdown": [ + "\n", + "_Showing only top 5 rows_.\n", + "\n", + "| rf_local_add(proj_raster, 3) |\n", + "|---|\n", + "| |\n", + "| |\n", + "| |\n", + "| |\n", + "| |" + ], + "text/plain": [ + "DataFrame[rf_local_add(proj_raster, 3): struct,crs:struct>,tile:udt>]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "df.select(rf_local_add(df.proj_raster, F.lit(3))).show(5, False)" + "df.select(rf_local_add(df.proj_raster, F.lit(3)))" ] }, { @@ -166,24 +186,45 @@ "name": "stdout", "output_type": "stream", "text": [ - "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs \n", - "+--------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "|proj_raster_path |footprint |\n", - "+--------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-70.85954815687087 8.933333332533772, -71.07986282542622 9.999999999104968, -69.99674110618135 9.999999999104968, -69.7797836135278 8.933333332533772, -70.85954815687087 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-69.77978361352781 8.933333332533772, -69.99674110618135 9.999999999104968, -68.91361938693649 9.999999999104968, -68.70001907018472 8.933333332533772, -69.77978361352781 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-68.70001907018474 8.933333332533772, -68.9136193869365 9.999999999104968, -67.8304976676916 9.999999999104968, -67.62025452684163 8.933333332533772, -68.70001907018474 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-67.62025452684165 8.933333332533772, -67.83049766769162 9.999999999104968, -66.74737594844675 9.999999999104968, -66.54048998349857 8.933333332533772, -67.62025452684165 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-66.54048998349859 8.933333332533772, -66.74737594844676 9.999999999104968, -65.66425422920187 9.999999999104968, -65.4607254401555 8.933333332533772, -66.54048998349859 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-65.4607254401555 8.933333332533772, -65.66425422920187 9.999999999104968, -64.58113250995702 9.999999999104968, -64.38096089681244 8.933333332533772, -65.4607254401555 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-64.38096089681244 8.933333332533772, -64.58113250995702 9.999999999104968, -63.498010790712144 9.999999999104968, -63.30119635346936 8.933333332533772, -64.38096089681244 8.933333332533772))|\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-63.30119635346937 8.933333332533772, -63.49801079071215 9.999999999104968, -62.41488907146726 9.999999999104968, -62.221431810126276 8.933333332533772, -63.30119635346937 8.933333332533772))|\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-62.22143181012629 8.933333332533772, -62.41488907146727 9.999999999104968, -61.33176735222239 9.999999999104968, -61.14166726678321 8.933333332533772, -62.22143181012629 8.933333332533772)) |\n", - "|https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF|POLYGON ((-61.14166726678322 8.933333332533772, -61.3317673522224 9.999999999104968, -60.92559670750556 9.999999999104968, -60.736755563029554 8.933333332533772, -61.14166726678322 8.933333332533772)) |\n", - "+--------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n", - "only showing top 10 rows\n", - "\n" + "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs \n" ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
Showing only top 5 rows
proj_raster_pathfootprint
https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIFPOLYGON ((-70.85954815687087 8.933333332533772, -71.07986282542622 9.999999999104968, -69.99674110618135 9.999999999104968, -69.77978361352781 8.933333332533772, -70.85954815687087 8.933333332533772))
https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIFPOLYGON ((-69.77978361352781 8.933333332533772, -69.99674110618135 9.999999999104968, -68.91361938693649 9.999999999104968, -68.70001907018472 8.933333332533772, -69.77978361352781 8.933333332533772))
https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIFPOLYGON ((-68.70001907018474 8.933333332533772, -68.9136193869365 9.999999999104968, -67.83049766769162 9.999999999104968, -67.62025452684165 8.933333332533772, -68.70001907018474 8.933333332533772))
https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIFPOLYGON ((-67.62025452684165 8.933333332533772, -67.83049766769162 9.999999999104968, -66.74737594844675 9.999999999104968, -66.54048998349857 8.933333332533772, -67.62025452684165 8.933333332533772))
https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIFPOLYGON ((-66.54048998349859 8.933333332533772, -66.74737594844676 9.999999999104968, -65.66425422920187 9.999999999104968, -65.4607254401555 8.933333332533772, -66.54048998349859 8.933333332533772))
" + ], + "text/markdown": [ + "\n", + "_Showing only top 5 rows_.\n", + "\n", + "| proj_raster_path | footprint |\n", + "|---|---|\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF | POLYGON ((-70.85954815687087 8.933333332533772, -71.07986282542622 9.999999999104968, -69.99674110618135 9.999999999104968, -69.77978361352781 8.933333332533772, -70.85954815687087 8.933333332533772)) |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF | POLYGON ((-69.77978361352781 8.933333332533772, -69.99674110618135 9.999999999104968, -68.91361938693649 9.999999999104968, -68.70001907018472 8.933333332533772, -69.77978361352781 8.933333332533772)) |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF | POLYGON ((-68.70001907018474 8.933333332533772, -68.9136193869365 9.999999999104968, -67.83049766769162 9.999999999104968, -67.62025452684165 8.933333332533772, -68.70001907018474 8.933333332533772)) |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF | POLYGON ((-67.62025452684165 8.933333332533772, -67.83049766769162 9.999999999104968, -66.74737594844675 9.999999999104968, -66.54048998349857 8.933333332533772, -67.62025452684165 8.933333332533772)) |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF | POLYGON ((-66.54048998349859 8.933333332533772, -66.74737594844676 9.999999999104968, -65.66425422920187 9.999999999104968, -65.4607254401555 8.933333332533772, -66.54048998349859 8.933333332533772)) |" + ], + "text/plain": [ + "DataFrame[proj_raster_path: string, footprint: udt]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -196,7 +237,7 @@ " rf_mk_crs(crs), \n", " rf_mk_crs('EPSG:4326')).alias('footprint')\n", " )\n", - "coverage_area.show(10, False)" + "coverage_area" ] }, { @@ -231,23 +272,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "folium.Map((5, -65), zoom_start=6) \\\n", " .add_child(folium.GeoJson(gdf.__geo_interface__))" @@ -290,6 +317,7 @@ " \n", " proj_raster_path\n", " extent\n", + " geo\n", " tile\n", " \n", " \n", @@ -297,32 +325,37 @@ " \n", " 0\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF\n", - " (-7783653.637667, 993342.4642358534, -7665045.582235852, 1111950.519667)\n", - " \n", + " (-7783653.637667, 993342.4642358534, -7665045.582235853, 1111950.519667)\n", + " POLYGON ((-7783653.637667 993342.4642358534, -7...\n", + " \n", " \n", " \n", " 1\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF\n", " (-7665045.582235853, 993342.4642358534, -7546437.526804706, 1111950.519667)\n", - " \n", + " POLYGON ((-7665045.582235853 993342.4642358534,...\n", + " \n", " \n", " \n", " 2\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF\n", - " (-7546437.526804707, 993342.4642358534, -7427829.471373559, 1111950.519667)\n", - " \n", + " (-7546437.526804707, 993342.4642358534, -7427829.47137356, 1111950.519667)\n", + " POLYGON ((-7546437.526804707 993342.4642358534,...\n", + " \n", " \n", " \n", " 3\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF\n", " (-7427829.47137356, 993342.4642358534, -7309221.415942413, 1111950.519667)\n", - " \n", + " POLYGON ((-7427829.47137356 993342.4642358534, ...\n", + " \n", " \n", " \n", " 4\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/11/08/2019059/MCD43A4.A2019059.h11v08.006.2019072203257_B02.TIF\n", - " (-7309221.415942414, 993342.4642358534, -7190613.360511266, 1111950.519667)\n", - " \n", + " (-7309221.415942414, 993342.4642358534, -7190613.360511267, 1111950.519667)\n", + " POLYGON ((-7309221.415942414 993342.4642358534,...\n", + " \n", " \n", " \n", "\n", @@ -343,12 +376,19 @@ "3 (-7427829.47137356, 993342.4642358534, -730922... \n", "4 (-7309221.415942414, 993342.4642358534, -71906... \n", "\n", + " geo \\\n", + "0 POLYGON ((-7783653.637667 993342.4642358534, -... \n", + "1 POLYGON ((-7665045.582235853 993342.4642358534... \n", + "2 POLYGON ((-7546437.526804707 993342.4642358534... \n", + "3 POLYGON ((-7427829.47137356 993342.4642358534,... \n", + "4 POLYGON ((-7309221.415942414 993342.4642358534... \n", + "\n", " tile \n", - "0 Tile(dimensions=[256, 255], cell_type=CellType... \n", - "1 Tile(dimensions=[256, 255], cell_type=CellType... \n", - "2 Tile(dimensions=[256, 255], cell_type=CellType... \n", - "3 Tile(dimensions=[256, 255], cell_type=CellType... \n", - "4 Tile(dimensions=[256, 255], cell_type=CellType... " + "0 Tile(dimensions=[256, 256], cell_type=CellType... \n", + "1 Tile(dimensions=[256, 256], cell_type=CellType... \n", + "2 Tile(dimensions=[256, 256], cell_type=CellType... \n", + "3 Tile(dimensions=[256, 256], cell_type=CellType... \n", + "4 Tile(dimensions=[256, 256], cell_type=CellType... " ] }, "execution_count": 11, @@ -361,6 +401,7 @@ "pandas_df = df.select(\n", " df.proj_raster_path,\n", " rf_extent(df.proj_raster).alias('extent'),\n", + " rf_geometry(df.proj_raster).alias('geo'),\n", " rf_tile(df.proj_raster).alias('tile'),\n", ").limit(5).toPandas()\n", "pandas_df" @@ -390,7 +431,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.5" } }, "nbformat": 4, diff --git a/rf-notebook/src/main/notebooks/pretty_rendering_in_rf.ipynb b/rf-notebook/src/main/notebooks/pretty_rendering_in_rf.ipynb index 722a12c76..fe0d373ec 100644 --- a/rf-notebook/src/main/notebooks/pretty_rendering_in_rf.ipynb +++ b/rf-notebook/src/main/notebooks/pretty_rendering_in_rf.ipynb @@ -24,10 +24,18 @@ "source": [ "import pyrasterframes\n", "import pyrasterframes.rf_ipython\n", + "from pyrasterframes.utils import create_rf_spark_session\n", "from pyrasterframes.rasterfunctions import rf_crs, rf_extent, rf_tile\n", - "from pyspark.sql.functions import col\n", - "\n", - "spark = pyrasterframes.get_spark_session()" + "from pyspark.sql.functions import col" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "spark = create_rf_spark_session()" ] }, { @@ -39,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -94,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -103,12 +111,12 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOy9ebgcVZ34/Tm1V6+379p3y73ZQ0IgCYIREQIKKDhoxlFwGAVBxtEH3xn1HfRB5ye4jDIo6sxvZhx2t1GBd0RRFgkBAQnKDoHsyd33vn177+pazvtHJXe43BBAHUmc/jxP/9GnT536nqpT33O+y6kWUkpJnTp16hwBKK+3AHXq1KnzaqkrrDp16hwx1BVWnTp1jhjqCqtOnTpHDHWFVadOnSOGusKqU6fOEUNdYdWpU+eIoa6w6tSpc8RQV1h16tQ5YqgrrDp16hwx1BVWnTp1jhjqCqtOnTpHDHWFVadOnSOGusKqU6fOEUNdYdWpU+eI4YhWWBdeeCFCCIQQHH300bPl+XyeL3/5y2zYsIF0Ok0sFmP16tVcddVVVKvVOW309fXNtvHSz49+9KN555RSctNNN3HCCScQjUZJJBKsW7eOn/70p79THzZv3sxFF13EihUriEajdHZ28q53vYsnnnjikP198WfFihUHbbu/v5+LLrqIjo4OTNOks7OTjRs3zqnzzW9+c05bU1NTr7kPDzzwAEIIHnjggdd8bLlc5oorrjjosYVCgcsuu4wzzjiDlpYWhBBcccUVL9uW67pcc801rF69Gtu2aWho4MQTT+SRRx55zXIdig0bNrBhw4bZ76VSifPOO4/ly5cTj8eJRqOsWrWKL33pS5RKpTnH/td//Rfvf//7WbJkCbZt09vby/nnn8+uXbvm1DvUuBRC8Pa3v32eXFu3buW9730vLS0tmKZJb28vH/vYx+bU6e3tfdk2Lcv6w12k/yG011uA35d0Os1PfvITIpHIbNnAwADf/OY3+cAHPsAnP/lJYrEYDz30EFdccQX33nsv9957L0KIOe18/OMf5y//8i/nlC1dunTe+T760Y9y880384lPfIKvfOUreJ7Hc889R7lc/p3k//d//3cymQx/+7d/y8qVK5mcnOTrX/8669ev55577uG0006bU9+2bTZv3jyv7KVs3bqVDRs2sGjRIr72ta/R1dXF6Ogo99xzz5x65513HuvXr+f666/nhhtu+J36sG7dOrZs2cLKlStf87Hlcpkrr7wSYI4SAMhkMlx77bUce+yxvPvd7+b6669/2XZ832fjxo08/PDDXHbZZZx44omUSiWeeOKJeUrjD43rukgp+eQnP8nChQtRFIUHH3yQL3zhCzzwwANs2rRptu5VV11FOp3ms5/9LIsWLWJwcJB//Md/ZN26dTz66KOsWrUKgPb2drZs2TLvXLfffjtXXXXVvInn/vvv5+yzz+Ytb3kL3/72t2lubmZgYICnnnpqTr2f/OQnOI4zp2xgYIBzzz13XpuHJfII5oILLpA9PT3zyovFoiwWi/PKr776agnIhx56aLZs3759EpBXX331K57vJz/5iQTkj3/8499L7hczPj4+r6xQKMi2tjb51re+dU75BRdcIKPR6Cu2GQSBXLNmjVyzZo2sVquvSo7Pf/7zEpCTk5OvTvA/EJOTkxKQn//85+f9FgSBDILgFetJKeU3vvENqSiK3LJly/+gtCGnnHKKPOWUU16x3mWXXSYBuWfPntmyg93v4eFhqeu6vPjii1+xzQ0bNshIJCJzudxsWalUku3t7fLss8+evV6vhSuuuEICctOmTa/52D82R7RJ+HJEo1Gi0ei88hNOOAGAwcHB36ndb33rW/T29vK+973v95LvxbS2ts4ri8VirFy58neW88EHH+Tpp5/m7/7u7zBN8/cV8RU5mEl44YUXEovF2L17N2eddRaxWIzu7m4+9alPzc7wfX19tLS0AHDllVfOmiYXXnghwOz3V8O3vvUtTj75ZNavX3/IejfffDNCCPr6+l6xD1JK/umf/omenh4sy2LdunXcddddr0oeYLZvmvbfhszB7ndHRwddXV2veL/37NnDr371K973vveRSCRmy2+99VZGR0f5+7//+1d9vQ4g97s4Fi1aNG81fzjyJ6mwXo4DptSBZfeL+epXv4phGEQiEU466SR+9rOfzfnd8zy2bNnC2rVrueaaa+jp6UFV1VmTS/4BX42fy+V48sknDypnpVIhnU6jqipdXV1ceumlTE9Pz6nz4IMPAhCPxznrrLOwLItYLMY73/lOtm/f/geT85VwXZdzzjmHt771rfz0pz/loosu4hvf+AZXXXUVEJo9d999NwAXX3wxW7ZsYcuWLfzDP/zDazrP4OAgfX19rF69mssvv5y2tjY0TWPVqlV85zvf+Z3lv/LKK/n0pz/N6aefzu23385HP/pRLrnkEnbs2HHQ+lJKPM8jn89z99138/Wvf533v//9LFiw4JDn2bt3L/39/Qe93y/mxhtvRErJhz/84TnlB+637/ucdNJJGIZBKpXi/e9/PyMjI4dsc9OmTbO+zteq7F4XXtf13e/Jy5mEB+OZZ56Rtm3LjRs3zikfGRmRl1xyibzlllvkQw89JH/wgx/I9evXS0Bed911s/VGR0clIBOJhOzq6pLf+c535H333Sf/5m/+RgLy8ssv/4P16/zzz5eapsnHH398Tvk111wjr7nmGvnLX/5S/vKXv5Sf/exnZSQSkStWrJCFQmG23kc+8pFZWS+++GK5adMm+b3vfU/29PTI5uZmOTIyMu+cv49JeP/990tA3n///bNlF1xwgQTkLbfcMqfuWWedJZcvXz77/ZVMvVdTb8uWLbP9XblypbzlllvkPffcI//iL/5CAvLaa6+drXvTTTdJQO7bt++Qfchms9KyrHnj5de//rUEDmoS/vCHP5TA7OdDH/qQdF33kP1yXVdu2LBBJhIJOTAw8LL1PM+TnZ2dcsWKFfN+O/PMMyUgGxoa5GWXXSY3b94sv/3tb8umpia5ZMkSWSqVXrbdc889V6qqKoeGhg4p5+HC/wqFtW/fPtnd3S2XLVsmM5nMK9av1Wpy7dq1sqmpaXbADQ8Pzw7El/pJ3v3ud0vLsuYojd+Vz33ucxKQ//Iv//Kq6t92220SkNdcc81s2SWXXCIBeeaZZ86p+9RTT0lAfvazn53Xzv+EwhJCyEqlMqfuZz7zGWlZ1uz3P4TCOqBEDMOQfX19s+VBEMh169bJrq6u2bJXq7DuvPNOCcjbbrtt3vl6enoOqrCmp6flY489Jjdv3iy//OUvy0QiIc855xzp+/5B+xQEgfzgBz8oVVWVt99++yH7//Of//xlfa2nn366BORHPvKROeW33377vIn3xWQyGWmapjz77LMPee7DiT95k7C/v59TTz0VTdO47777aGxsfMVjdF3n3HPPJZPJzIabU6kUQggSicQ8P8k73vEOqtUqL7zwwu8l65VXXsmXvvQlvvzlL3PppZe+qmM2btxINBrl0UcfnS1ramoC4Mwzz5xTd82aNbS3t/Pkk0/+XnK+WiKRyLxQuWma81JLfl8O9HfFihX09PTMlgshOPPMMxkaGmJiYuI1tZnJZIAwCv1SDlYG4Rh5wxvewKmnnsrll1/Otddey89+9rODprzI/abd97//fW6++Wbe9a53HVKeG264AV3X+eAHPzjvt5e732eeeSZCiJe939///vdxHGeeiXk48yetsPr7+9mwYQNSSu6//366urpe9bFyv09KUcJLZNv2QdMcDlb3d+HKK6/kiiuu4IorruDyyy9/TcdKKeec+5hjjnnVdf8UWLx48Zy0lhfz0ntzQIG+NLT/0vyzA0pgbGxsXpsHKzsYB4I8O3funCfThz/8YW666Sauv/56/uqv/uqQ7UxMTPDzn/+cc84556BO+0Pdb3j5cXnDDTfQ1tbGO9/5zkMefzjxpzVyX8TAwAAbNmzA9302b948Z+Z9JVzX5cc//jHNzc0sWbJktvw973kP+Xx+XiLinXfeSSwWe0Wn6cvxxS9+kSuuuILPfe5zfP7zn39Nx952222Uy+U5q753vOMdRCKReRGtJ598krGxsVeMpP0xORDFrFQqv3Mbmqbxrne9i23bts2J/kkpufvuu1m8eDHNzc1AmDgJ8Oyzz85p46VBlvXr12NZFj/4wQ/mlD/yyCP09/e/Krnuv/9+gDljSErJJZdcwk033cR//Md/8KEPfegV2/nud7+L67pcfPHFB/1948aNCCHm3e+77roLKeVB7/fjjz/Os88+ywUXXDAninnY8zqZon8QXs6HNT4+LhctWiRN05Tf//735ZYtW+Z8BgcHZ+t+4hOfkJdeeqn84Q9/KO+//3753e9+Vx5//PESkDfddNOcdjOZjFywYIHs6OiQN9xwg7znnntm/UVf+9rX5snGQXwlL+VrX/uaBOTb3/72eXK+2FfW19cnTzzxRPnP//zP8s4775R33XXXrD9o1apV8/LODrR7wQUXyLvvvlvefPPNsru7Wy5YsOCgfryD+bAOlL3YN3UwXs6HdbCcsQNtvpienh65fPlyec8998jHHntszjW788475a233ipvvPFGCcj3vve98tZbb5W33nrrHGfy7t27ZUNDg1y+fLn84Q9/KH/xi1/IjRs3SiGEvPXWW2freZ4nly9fLhcsWCD/8z//U951113yr//6r+XChQvn9eGAP/Hiiy+Wd999t7zuuutkZ2enTKfTc3xY3/72t+X5558vv/Od78jNmzfLO+64Q1522WXStm154oknznG8X3rppRKQF1100bx7/eSTTx70+q5YsUJ2d3e/rC/sQLuKoshPfvKT8t5775X/+q//KlOplFy7dq10HGde/QPBoh07drxsm4cjf5IK68AD9HKfFztub7jhBnnCCSfIxsZGqWmaTKVS8swzz5T33HPPQc85MDAgzzvvPJlKpaRhGPKYY46RN95447x673nPe6Rt2zKbzR6yD6eccsohZT3A9PS03Lhxo+zt7ZW2bUvDMOTSpUvlZZddJmdmZg7a9nXXXSePPvpoaRiGbGpqkueff/4cZf1iDqawPvWpT0khhNy2bdsh+/D7KqxNmzbJtWvXStM0Z5XsAXp6el722rx0Mnjuuefk2WefLePxuLQsS65fv17ecccd82TYuXOnPOOMM2QikZAtLS3y4x//uPzFL34xrw9BEMivfOUrsru7e/Ze33HHHfMSR3/961/Ld77znbKjo0MahiEjkYg89thj5Re/+MV5EbpD9edgY/lAQOH//J//M//CvwjP8+RXv/pVuWTJEqnrumxvb5cf/ehHDzr+yuWyTCaT8uSTTz5km4cjQso/YALRH5kLL7yQBx54gN27dyOEQFXV11ukWdLpNB/4wAe4+uqrX29RDomUEt/3+cIXvsAXv/hFJicnZ82nE044gZ6eHm699dbXWco6dUKOIOP14PT396PrOqtWrWLr1q2vtzgAPP/885TLZT796U+/3qK8It/61rf4xCc+Ma88n8/zzDPP/F6Jl3Xq/KE5oldYfX19s9Ed27Z/Z6f3/2YmJiYYGBiY/b5mzZojywlb538VR7TCqlOnzv8u/mTTGurUqfOnR11h1alT54ihrrDq1KlzxHBYeleDIGBkZIR4PH5kvPKiTp3/JUgpKRQKdHR0vC5bvA5LhTUyMkJ3d/frLUadOnVehsHBwde0N/cPxWGpsOLxOABvPu7/RdNMFNfHixromQpiZAwME1IJCCTBvgGk581rQ+tsp7SqHTeqYBR8cosNtLKklhAUlrnoCQexK4aZhchEgG8K8otBLC1yRu92HptaQGYmxnELBjmv+VGu3vd28pvSREd8Cj0q5aOq9LRnGNzajhRgTSjEhwLitz6GME3E4h7E+BRISdCTxrc0cottSu0CPyoJdEnzU5B6eACvu5nCwgjlJgW9LFEdqLQIios81IqCMa3Q+asi6u5hEAJ/OosSjaA0pUBVCaIWKAqDpyfx4pKeO4o4zRbVlIYXARFA9kQHVQ0wbZeORI5dg22IokZkWKW8soqme3iTNl33BiCgllSpxQT2VICR99DKLpnVUeIDHp6toBc9jGkHaSi4MR2pClQnwI1qCF+S79VBQO4oj+X/Ok12XTNT66DjVwGxZ0fY/pl2zGQVz1UJPIWGVImZgQbsEZXoqMTXAQGeLai0S6wJgVSg1OOjFRX8zipWxCVuVZnIJGi918DM+oy/QSewJMaMIL2lhD48jTQNpG0gdRV1PAt+gJQSoSjIVIJqOopW8lCLNaSt4UV0hC9RHI9Ku43wIbZ9EmnozKxupLBAwYtI4n3gRQXCk5h5ifAkQoJR8LFGivjb/vuPJZwz1lFt1FB8ia8Lqk2Chl0esa2jeEMjqIt7qXUm8Q0FtRZQi2voJR9zKIdwXaRt4aRjZFaatD+YJTA1Sl0RrKyL9sjzKBEbd1UvbkxHc3zcqEagC2pxhUK3wMhBfNgntjuPMp3Db2tEGRxDdrUhKjVQFQpLG0CAXvDQKj5q2aXYG8OzBU5CITHgomSK/Prxq2ef0T82h6XCOmAG2tMOqqFS60gSJDWUh19AbW5CRCLgSLz+QVQECH1eG+7RvYiYil0NqDWraIrAbRegglk20SbjpPYE6CWfUqsJf57h6hV3ohCwKbeK2kycx864kZQa4arMUsr399K8zyW73MKsQUWoeGaVxn02mRNdqikFM9DQj19LYGq4MQ25sBknqeJGBLERj9adVZTflnAWpMisNIlnHdREA0LqFFZGEB44zSAV0CrQ/kSoSN2ooLjShKOa0CsBsT1F1NEp8AS1RWl8U8WNqbT0QXx7lmpXMux7DdRCQP+7oKmjRDYbo+pDIplHzVgoZZ3qMomeNdEqgmgeNMNFdQLsyQBlyKfUZePGBFUjvH7mvip2xkcaBqoKSq6CiMVQKj5KRRKZriIVhUhZYfyNURKjUDw+Qutvx2jZnMfPTKN1dRIbjVP1oxh5Ba0CclsD2gkVPGmSbwNzWmDMSIgL9ABkA1TSPlrNILo2hyIkuWwS5YlWunb6WNMuga6RnNAp9ghad7uIeAz3qBj23gyBMMED8lWUlib80XGqbz2GYqeGnQmwhicRVRcZqGiKgm/rVNMGo28PaHlEQ91doLy0Ga9VI2gEKy8QUYmqC6QFEomZDbCmHPTJKiJfRWvtwJ+cBEWl0hhFRAQN28to+QqBHY5ZkWpCLO1GyTmohoVR9pCqhjXp45s6SmOKQFOYWhOhlhCoVVAjMbwmi2gxQN/yPFJqKIsXUU3H8KIK0oVaVODGBbU4dD/q4KQ0MHVqS0wqjWmcRkH7QxaBqTFxagStLNEqksi4iyJUZFTgNikYUmAWJdEioKrU0mLOM/rH5rBUWAcIohYyEUNxA+LPjiMbkshKFT8zDYdIH1OXL8ENJFrJJzAUNCcgOi4oqipuDBJ7QK1JFE9SbtEoLIS/6N7GqfYkO1yNpzNdFEoW35w+njdHw1eDSAVmlujoRcnMUZLOngyZR9OIdjBGdZAQGQ8od0VQq5JCp4YIQGqQ3FPDHJhGjk6AYWBELVI7BW5CxTR0qq0RIqOSQBMgQHXCVVapQ6G0wEepCfIamFmF+D4FqSv4XS1U22ychIrqSowZD3vPFP7IGFrqqHDWH5ph6sRW9AxM+w2kF2aYyCTwpIoypWMtKtAcKzH4QhpREig1UGoBes7Bixtkl0dxo4LACPvfviV8j5XTZCKkxGnQscdVtJJLYKigKbBvHNHSROboFJ4NtYSk65c5vL19s/fHWdKGXoTAVKglAhL7BIEOdsShrJkonsBJSUAQaOBbElERRAdViktcCjkba5dF11YPa6KEWqohDQ2nycKLCNKPuqiODxKMmSpSVVDKVahUobUZvzmB391EsUMj0e9iTpSRpgGaih+3KPZGKXYq1JJgN5XQqjGGzmmn2iKxpgSxQUlkyse1BZ4NkSkfY8ZDK7k4TRbl9ibsqQRm/zRq4ENz46yyyR4VQavaRMZdzJE8+AH6VBk/aWFMlvASFl5Mp9piEmgQ6y9T7rSITAbYGUHymSnc1jjWUAExOoFoaaa2pJ18t0ktHiqRmgDVgeQ+D2uyun+16CM1hanVFnpJYuQkCMHUMeE/LikuSFXgJjREIKnFFEppBRGAkZP4tsCeDIg9Pvd13H9sDmuFVWmPYTsKarmGm25ADwL8/vkv6lebm8DzCBZ34TZYuKoIB2xVomY8ao0WE2sNnKZQycWGJbW4INCVcLmbdtlZbOVLwYnEVIeJXIx1Cwb50fbj+OGekzGnw1nUN0E9I4M/liR3XxoNUGoQ7wMhJZmjBWpVQ/FhyTv2MJhPMj2eoPWBLKJUQS5ZgAT8qMHMYgM7E1BalKTcrCIV8C2IjoarqqkzqghVwrSJbweIqIeYsqglBENvi1NrkNhjgsZtLoovKXUYzCztINHfijFTI9AFbmscJyWQvWWWtU2xb7IRVQ0YyiWho0ppIkrwZBLNlMT7JGbBRyt5SE3Bs1Syq0ArQcfDDqW0zsxiE+GHcrpRgV6SeFYEe8pFn6mi7B1B9nRQa4pQWARqBZqfkcjn5/7nnrG1n0atl9wiAz2vEOiS/CKIbmogVZW4sdAMrLQFCE8gNYlYnqeYsxEVldgzOtHRAGuyhj6YAUXgtafI9WoEOlSaVYyiIDJUBi9AmgZipgCA1DWUbBGvO0XDbgd9uow0NKShUulIMH6ciheV0FohKGl0fy9CoEnK7RI/6pPcpRId9UCAVBTsKQ+pivDaBCZaNZx4fFNFqgqyO83oWxrIL/WxR0NzV61JAl0hd3QjvinQy5LIUBknHSO3UKfSLIiMS/SSpNwVwR5zkJqyX7HZlDpMkrkKaBqltd0gQXElXkShlgC9COlNo4hiGWwLp7eJYqdBbrFCdEQSaGAUJaWuCFoZ1FqA4kmiQ1WkpjC90mJmhUStSLxEgJFR6d5UwRjO4r3kPWJ/bA5rhRXZl0Uve2BbKKUy3nj41kixdhWFpXG0SkCgC3wjnImdhEKpW2JOCxJ9PuUWFTcODXt8vAioVXBafJz35pkZTrBk+Shva93OlBvDVDzuH1vK2AutWJMKqd4y977p37iy5+3smGnl5LbdJLUK//HAaSi+YOmf7eJNjXv50b7jmN7WhB+V2OkCb+3ZyXPZDsauXUj64WGa+3fiH+jQ6BhqSwss66RpW5XsMpPR0yRoLqnHdHwTyufmsA2XYDiF3aeT6A8wZySldpO2O/vwhkdQVy6j3JvEsxWqTSrlNgWnQaKXBMZMDS+iMfpmHfvYIksbh6j6OhVPx3dVgpJObtRG8QQtL0Bk3EWtBSDBTahkV0RAQKEXjMV5/OcTjJxkUmsIsMcE9oTEmpY07Kqh52vhgzSYQdomez65gsAIfWbRQYE1HfrD1LZWpOfhT0zinbaO6R4D1ZE0PV+h0moiVYg8KplZoqE6IPfvYQ80sGYEbhTcXQk6nghI7Crg2zqKFyAcl6ApgdtgUeowKJ1aord5mqH7FhAfACNmoD29Hel5BIBiWYh4FK8lQWalBRISgxq+KSi1qcyscTl7Tfh2zkevXUfTM0WGT4vjmyDbKyiTJrERD98S5BeEK2g1qWBPB0THfYycixvTEBLsgRzSNJham8S3wMiq+HaoLAJVkFuooVYhtb2MNpnH6Wmk2KFjTwU0vlADKSl1hS8bDEwVpRZQXJbEMwWJHz8GRy9FRGwiuzIEyQjl1jiKC61PejhJBa8tyfiftVNcV4GMQfoRSO4JqDYqaBWJkxShG2MmIDpWQwpBodcm0AVSQGxAQalB5GmBXnIpdZhkjm5HnarALX9UNTCHw1phAaCqeH2DEPhoPd1k13diZVxifSXUokOtLUZuoYlnCdSaJLkTAl1SblEpt0ukDoVOFcWDde/Yxur4MDdsPZG3rN3OAjuLLxVW2KOcHt1NlzHNNx47h0o64LK2e/lx/lgA0tE8i60JVluD3L9qGYWayfaJNp7e103DFhOzQVA2Babuccdzx2AMGTT5Em9w7j+WKNEo+VMWgYRCt0phYYDdVEHXfNwzBR2JAic27+XRqYVMZzSaXvAJNFCrPvGBAHlgdpvIoLXFMLI1Cr025bREpqtILWDwuIDqlIrVXKTmqQwVGjBUH1UJHe6VskZgBQQKZN7qMpU10IoaqW0Q6FCLC6rNErfHQduVwG3xQQ9ofkSnYWcZfccwtaO7mVlkEugG8SGfaksHmZUaIBE+WBlBfMhDKgK1FiAb4uDUGD1/CVKB5udqGFkHp8lC8SSlZhXPEsSGA8otoSnmNoQmXaApxPvBzkgSuwoIx0Xb7yQOTB2nLYIUMP5GiOg+OwfaaBkJ/TH6dJlgf0BGiUYJVi1C+AFqwcFpjKKVwknOs0NTSo87PDS8iPKOBhodyBwbwzfBsyXRp2wSfT5uTGH6KBXfkvgG+FGfnjskkYE8ftyk2GkRHfcpLW6g2qBS7BF4EUl0UCA1gRcBvSxpeqGKPlGEQOKmk7hxlci4hwgkasXFabYRAeh5D61Qo9QdodCl0rjDRWtvo9wRx4skEYEkt1BDqUFyr0uxQ6PUIVBrFvmlHpEXbFI7faQCtbiCVpK48dAEb37OxZwsIxwfZaaAWm2m3G4hfEG+RaC4UDQUrIzASQq0yn63xevIYa2wRK2GzFdRFy0AXSO/opGGJycgX8Qfn8AXAjPfQes+lVpPE8UOM1xxmVBaIPG7qgRlDdB4w1u284ZkHzftehO64dFolHECjclajIjq8E/jb+W+vmW4yYD4gjwf230e+ZrJlmP/PwAGvCK73CQNZoWya+C5KtZOi0obeFGJNAMKLzTStAeMvKThvl34Qbi2Kr73jUg1jHIZhQDhS2pJldPf9Ay6CKj4OnvyzUyXbW7ZuQ5nJIpVCGfA6KhHoCtEnxvBmwrfM+5PZTC3abgL02iOJGiroWkBXk3FLeksWjrG6EyCIFCYKYY+CidnIRyFtkUZSo5BeV8CUTQxigr2uMS3oNQuCPRQyWsjJj0/r+DGdfSijzE0SZCI4K7sotRuEB/2mD5KJ9AFajVAL4E9CXYmIL5zBrnfKasUy0l+rSMAACAASURBVATJKLs/mMZrcFn5xRFQFSY3dKG6Eich8CKC6FjA6Ns8UCUNjSXe3DbE05MdFKea8A2B4gU4rRGsviwIAUIweUICoyAptykkd0L0wRhWKvS76KUAUXbQehcgcwX8XB4efwFh6MhVizFmQKuELgLhg1GQlPZFccsCuwzVRggMSP/GxcxUceMGU6tNqi0SN+GjlcMcpOQ2DXt0BlEs46Vj+IagmlIxCgGKLzFyAs+CYk+AMaOgl8DM+mgzVYKoidNkUWrf74APwJ70EDUPc7xMoEURARR7IhQ7VOJDPpGt4SRo750miFrUWmxS2130govTbFBLCJJ7QsXfsDWU0bMEjb8Zx+pppNqoYRYEsb4SgalR7I2hF30sQAQSERCu2FMBRl4hMhpeo9YnSgSGiitr/8NP/aE5rBVWkIgiF3QgXB+1VCPxaD9BdgYAoRsgA4JcHtHdTqXFQC8HuBGFYq/ANyWRZ2ykCl5E8ttHl7MlsQRRU/j2mTfyYHEFt/3sJLSy4N7uYzhx7Q7OWvQ8iWVV8p7F7Q+eQGKPwsqHP4Z3dIm3LdnBx1s2szw2zr7/WE7XSI197/GwRsPZTZ9WadgBDbvKlLpsRDwGUxm09jSJXQW8uInihDNoqTtKtbvGU5NdnNG5nRm3iemyTXEgQXyfiiFBK0taHs0gDQ3huHhDw3OujTc2jtLejD1aJfVwJPTFNUKtIcAPFBKRKkmzykg+QXE8hhJz2bB6FxknytbnF9GwCwqLwFlUhVUuCxqzZHa3I2wffcCk/REPIUGr+mgFh8lTOvAsiE4ENG7ehzc2TseDEXJ/dgwiELT/KkulI4biS6QQKKUKBAGy6tB3QRdeyqXzlwpeVxNSEWjVMMVEqgIRQDWl0NBSZGnTJJ/v+jnfHH8b01NxGkYFRlGiVgLMsSIAbkuMve+xEL6k6RlBZDwgOlqj3GaEY8OX4cqh4uB3NCEmM7B/8giqPmrVQ3Uk1kyAVgowsw5j62Ohc7oWmqLxkYB4XwX1qR0oDUlypy2kkpaYWYHUFLSiQHXAzIX9rS5ppZTWQQkDFJUmheTeGk7SQC8ItIrAt8LfVCcAX1JeGCHfrREb9fHM0EIw8i5+zKSWMjByLvleC98KU28SL0zjtzeizJRACAJbw8hUUHJlgoYoTtwmMh6g1kI/mdMg0CqQ2FfBa03gxlVK7SoNu120iRxuZ/iHLOU2neyyRmoJwntegtigguJCZNLDmqigzJQQgUSpK6xDsH+WVmfKBP1D4PtIz0No2mzuldLeSq01hupI3IhC5hiBm/RpelLFzAXUYoJSu0AYoGU0Fp8wwL8Nn8bOyRZa3zjGSCYJGZPhUpLdM81MPd+C1CX2mEL73aOIUoXtV7dzRsNWrs+cxJ13rKct45JfaKDlIToiKXUInMVVpjqh8YIpprYsQHHT2OkGGJlG9A1jRKOgawTJKHrBI7HVpNKk88DYUhxPozAdJbVNIT4U5jklduZhaIwgn0eJRBCahhKJEDjOrGmojmXwF6exMwHjb1QIjHClN5JJouk+4+NJlKwOMZ/jegfYlWthcF8LsQlBpRXWnBT+IegLE2l29qfRchqND2vYmdCpXOy2MHI+lWUJ4oM1rL1TyHLlv32J3R1MrREkdqsEWoLcIhVrSmLvrhJMTSNMA/wgfAB26xgzDtpEHr8xhtj/ns1aAgITnGafszr28Zm2+/iXzEk8/ItjaZgOV0HRkRpaycOPW1QWJ4n/P4Mw1EbjJovoaA0hoZbQKLcqpLcUKCyMEhga3rI0erZKUCrNGVZeg03T8xW06RJua4zx42M4jRJk+MACBJpAmy5BdweZE1qZPlpgTQq8KKjV0CkuBRjFgPE3JyEA1ZXohf2BndFwfKpOuAL3YqA6gsbtPuZonnJvA9PLNaSy32XhQ2pnDTVXxU+YGDMu2eU2XkSglSXJnQVEsYIiBGRzeMu6cBpNAt1CrUVwEiqBDtVGBTMXmuapnR5aJUB4AYGt4doKelES2bKboFJBlxKlpZ3CgnCCjw2Cul8fKV7Yj8iebBiRNw3kxDSymP2fedZfJYe1wpKGijGUCQe/phHsf1APKCutswOpa2E4uVGn2KnQffwQg5MpMseZGFMqiivQyrDsTXu5fek9s23nFlc4/ZkPkngwdDTObO9E+JJIVCCFILXbo9adYviUdv5q9a+4K7uaNyd2Edvo8JuTe+nf1YGW08i8wSfSUmJd6zjPjXSwe7QVv9GnlFaJv1DC6x8MlU0gEckEUlHI9xq4UZBPN5AB4n0SbVX4kEwv10jt9sLVieeBEnqgxcolFBYnUasBvqVgzriIootWrJE9OUJkWZZiwULkDE5dvJOt0+1UZkKnbby1SNE1WZyc4jvv+B4L9Rifn1zFjmIbg4UGgqeSqMkgXAk4AcZMDbVUQ0vZCF9iTZQhAGkZkC9QedcJTB+l4cYkWknQ8sRMuAp2klgTFfB9gkIBSirq4h6cZkl8LwSGst9fo+NGQj9KbFgyvQq05gqnJrfx4d3nsuvpbuIzUIuDkxJExxVcVafcpvPnf7+J54vtjD3SQ7Kvij48g7OgEd9U6Ng0xdTxTUye4qJNRNALAiNv0e6tINga/uP1zAfeRKBDdNwDojgNOoER+u/scYFUw9Wt6kqChM3oSXHyyzyMjEq5M0AtC+L90LDbodag4SRUtHLoz1KdMCXFyriobsDIiTbVtoDIcLhaSfT72GNVKguSVBtVAi1Mewk8aHmsihdRKSxPopUDfFtBrUmi4x7RFyaQhSJYFkiJ7GrDtzS8iIJUwElqyP2uJd8ENyKID/lIVaDnawg/QNQCkrtLyCdegGQCkUzgtadwIwrxAYkIJJ4dRiyFLzEKPkamgsgXQdOQk9P42SyBdP84D//LcFgrLPH8HqQdR3S0ITyfYF8JtakRWXVQ4jG84RE0OpDRJpSaxJ6UDD/Sib8wzBdyFzhIRyXeUqQ3luEXZYvNuZXcvu1YmDBJ7FGITvrYEzWM4SyVJc0UOnWKCwTB30whdJe1VpGf9a3mtK6d/LawmABBo1nGaqxSFRbfOvUH7HDa+dG+48KsbUdF1BRioz5M5wBQIhFoa6aWTpJbbBFoYei52iKRGng2tP/aD3OqahKt6IfZxxEbZckC/KhJqdsGKak1a+jlAOEGCNen3B2j0umTUn0iMYcgUuOZqU7Gh1PgC8wFRVY0T3Bu62OsMMa5eeaN/NfeY0nYVVxfZXKogUQRUtslRj5crUhVwUtYaDmHIKKTWxan2KmQ2u3hrmkitzhczRk5QanXZ+CsBtKPOtjDJeTTL+AJBSUapfbGFYysM1ErYE/7SEUwdWyEUhdoJYGZlWRWh47rdLLED8dPYMfedmjwyK0SqHkNe1JQ6NYodoG3/74+fevRdG6ZASmZXt9Gw44SlVadgXOaqaQDEo0lCkoE1TGRGrjNEczeBRTWpMktESAkRkGh1GaTWwaBHpDaKkj2VaklNYrtKrWooNQdIb/cQ9QEUgtlTm0PHfqlDmN2nDZuLeI0WbhxFaSk0qJT7AqVVOMzgoa9FRTHR6l6VNNRZpboVBv355f54YpNcXxyKy2sbICRC1CdAM/UQ1+glIhEHD8VRbg+lY4oCCi3KHiR0GdqZSWKK7GnJUbOo9xqYOZ8hBegjs+glMr42WzoSgGEojC9MopvgJmXBKogOhqazWrVx5hxEK4PtgU1FwwdxbKgUldYh8Y0EYUSwUwOdeUyGBpDqGr4MB+zAi9i4CYMtLKPJcAbVikHNk6vg6yoRJrLtMWLDJRSXFc8ha2PLyTep1BpkyDAyHnkFltEEi1kVumU0wFqe5k/73qacTdBs17g7OZnaVKLvFDt5OHpxZzT+gwDhRTRxiy/nFnNA7cdR9PzHrYpKLWr6IVw+4W/MI2aSlA8qgm94KO4AWYuQKsIMqvBi0lafwOppzPU0nGkIih2qFQbDZzj01iZNlofySL8ACPnYWQdtKkCcmoaP58nEAJbrMQeSpJPRfAcFVHW8LIJSLvYzRUWNGZ54vGlbBtajuIDAThpyWSvjpexEAJqSYg85qBWw5w1faoIw+MUT1vB4DsDEs05iuMxUHSsSYlegpoWBje0xipuLoIXUTF+0xf+D6CA8mmryHdrOE2S5mckWiVgYo2OF5fE+sLE3UqrQHElvoCpbJyJHS3YmXDVEOj720kH8KY85y16BlN4fOfHp9P5RIXc8gSeJWh5cASvLUmhW6Hc6WOmy5TKJuqYgVaB6EiAF1HJnNXFzNEeqa4MuXyEKWERmBBokobtgpZfT1DrSFJuUcNIZy5g/HgFu7mAuydO41a5f6uSR6AKCl06vg3mtGR6VQw3LhBeaMI6jQIrI4kPhQmsSiX0XeaXxsn3qvgWIEJnv+KF12B8fTQ0/bYXwl0MmoY5HguDNbaJ1xBBLThUO2PUEmqYFJuXKF6YriMFGHkPL6JSbdTRywFaJbREpB0m+qoyQFgWaBp+eyOeJXDjoJdC09aLKPt3ZQRU2iOYGSfczjSVR/gKcvlC1GIBdr9+6uCwVlhKMgmArFZROtLIzAwiGqG0rhvPUjByHl5MDZWDISgsUAhMcKMSbczAbXGpVgx2T6fRYzU03Ue4gvySAKXZobrco++oCM2/hdE3adQ6HTTTZ0XHOLcMrGNV4xhnJ5+mUy3yb1Mn85Pn1hJNVrh68nS6GnJ0RWe47+fH0fVIBadJJ7dYhQCsTOhPyy+OojkRogMllJKDKJRRfj2GYuikft2ErFbxpzL4QuAuPh4z6xLblWNsQ2OYYpAUTK5PUWkRVLp84rvjIOMoXgfxIQ8nrlJtCjPRg0CAo6LlFbyYpOFpg1KHzm49jl4BxYP4oE+1QcGpCZStURQjXOlZGYnUFZyohVQEwe5+pFtj5M0qQvcob2/AKguan3Uptmv4RuiYbdrqkn1DDXUwgl70EHo4nEob30CgCVI7HRr2KggvYPqoMN/KnArNrmJXGAzRqgKZV1GmbRL9oUnlNAo8O1SIUpWUSyaPTC1CV3yMHIwdb2POSJqu34KvGwy/r5PG00aJBQoTmQRBSUOXUO7wUWoqjdt8jKLEHtWoTDShWBJ7InT8a2VI7ipS60gyfryFGwNzBoqmipv0CPbFadgNZi6gYXuZwFCZXhVBq0iEL6i0CiKjcr9ZGPbNnpD4Jsws1olMqFgZQXa5GSbxKmFCbWBAdCSMZuZ7FHxbYk2B22ihThvhtrNiEno6qHYm0MoeTjpKYYFOot/FmKwgTZVqi0WgC6IDYdRPqgJzykWpeggp8aMGylQWknFEqgEqVcqr2skuM5Aq6IUw6TnQwmBFZMLHN5Uwt9FQ0UdnCKamURJxRNUNk1FfRw7LVyTn83mSySTrzv0SRG0ikz6RgTy5lQ2oNUl82zSiWqN4dBuFLpVCL3gtLngCJPQumqDmq8yUbHoas+x4ZgGLb62iPrUT0dHGjo+1YU0p2BOS6LhP52d2cVnH3azZ/6ee6x4/l/yORsysoNLp8/YTnuGXu1aQutfGaRRop2RYlMrwxNZFtD4S+ph8C8ptoV/GnAa9JGncFv45qPbcXjB0/CWdCNdHGZqERAyEQA4MIxZ2k13bRGTcxfjtTkTEJuhoIXt0gkqLQC9KpBrOyHpZYk96ZFYZBEY4w+tluT/KBDPLwjwoezLAKAXhKicVHhsYkNoRoDoS3wxza6QQNG2romfKoCgEhkqxN0q+VyE+EAYtRAC1hKDUFaC4gsSe0OcjfGh7YIJg3yDC0MmfvZrs0vDhi4wI2m/ZAW3NDJ/ehFILV1V6SZLcXULZNUBl/TJmFuto5TCcXm0WtP22glqskV8WR+6PuGlViV70Eb7ETWioTkBkd5ap9S1MnRBgZBSSu2BmRZgzFRtQaH2qgjGYhXIFv72Z6WPCa1nuCMP11a4a5rCBWgXFh+JSl6OWDDOaT+AFCs2xEplSBPFAitiwj+KFsiDAMwW1hMC3wntj5mToVhjJwdgkpZNXkDlaI7EvTG2oJhWclNifHR+OlWq7h/AFWk7BHg8jhGZO0vjQEDIRpbQwSXTvDGRmyJ+0kHyvSmpnuGIqtaq48XBjupX1scYrFHuiYVJoWRIdc1ErXrjxO5fHnwldE+7bjsNJaWEmvhEqbDcisLN+uI81qRDoAjMf7iLQCg6iPDez3VUDNr9wNblcjkQi8cdRCC/isF5hCR/iAzXM0QLTaxv3z4gBbnOMUqdJsUMhPugTHQMnoeOkBMbbpugbaoZquGwe/E2SxQ+V0MdzOG9cweQxFi1PBhgFD3PGpf9Mi0KmleuNk/m/nb/hwSqUn24kfmyWmakYb1qxh8cnuun8T4PojnEGN6ZJxwv05xpp2KrhmxK1FioorRyuCqqtkvhTAUrZBQUqJy5Hq3hoj+1A+j7B6qVITYFHn0Vb1EtxSYrUUxmYnEa0hGF/4foEejjAjWI4e+eWAFKQOUZHcSVKLZzRkWFUqtKk0fxsgG8IrBkfz1Yod0i8WIBI1QgqGpMRjdYn9mejjwdE+4uo00WoufjpFCiCyEgVa0qlnNaZPiZArSgoNUl0KLzebkSh5bdZlMkZvNExEILyWWvILQxzoFqeDoje9htEe5qZlQ2oVYlePtCXADVTwFu2AHswj1QSZFbq6Cdn8B9tQs+EIfvomEMtruMkQxOx2KEjFUgMuni2wthpLTgNgvYHwJqukVlpohcgsRtSO8toU0Vwani9beQXRih1CtyYJIj66Ity1PYmCUyJm5CsXrcPTyrsmWzGc1W8fOjnqVQMLCtMLrVyAdWkEvr4lHBsRsbCLS32pIu5bzIMsBy3ilK7Svo3VZSqT+aYyP68MEk5Lailwr2hSlkhuVOgl6HaBOW0oPWxAkEqxsipjZQ7JJ1+EsvW97suJJlVYQpNot8n0e+h52sEpsb0qlC5mzMBblQhv8Cg5TcFEAIRj6MGEm/1IsppHcUDvRwQG3EZe6MNAdjTYORcQMeLKFiTNdRiDVHz8Bsi4VgFlIqHMjL6eqkD4DBXWEY+3LFeWtyAXpZEh8oQBJR6YriR0GlrT7n4hkK0r0hxcYypJ5pJZMGLhFs82h8qgSLIrWtDBND22xIzy8JEvPETVLyOGtet/h7HmQbv3nUmO+5fTLxfUjtGoJg+T/3yKJq2+tjjZWbWtVJeXcEPFCLfbgARpiBolQDFlVgZj2qThpn1MfIuyr4hhG1j7xqE9lbKp64i0AXWuIO6dS9Eo+B6RB/dhz85GWZj5woIy0QYOvGBKMm9EiEltYROLaGh1CSRyXC/YaE7NJ3UarhxNTruUuzQsbI+etGj1GqhOgK3zceyXGrjJgvuqaG6AcUOE3vcwY8ZBEYD2nSJwNJxGg1EILHGymRON4h253EcDd9X0QYtzBmPxPYijE/hTWVQLIvqKUdTSqtExiWJPgf1gSdRly6iuLwZxQ+jZ9NHg54P0wEmTmknPuyi7hkm+7YmymsqBGMJjrp2x//P3pvFWpqd53nPWuuf97z3mcc6Vae6hq6eJ7I5iaRIkaGs2BI12kISBTES2M4II4hiwAkQKDAMOw4CKwoQIKIsOgoUWKAN2ZBEihSVZrPnsaq7hlPTmcc9739eKxfrdDEMpdyF7Av+QN8UUI1T++z/W9/6vvd9XkStStmpkUcOKilp3R1QNAPUlEfpCoy0wszKvmb2K++gJxPUwxcQF23BquwXFukT+RTzdSazHicPC/KVhCDKmKtZiUPRbZFMl8iplBuH0wCEfsbSTJ9rZp7RfhX/QFG/q2l+/SaUGv/Js6ikxDkcks/WSaZOB9jGoA+PEU89TP9CjfBIIzNNfz0ir1oFf+nabbWREoTtgr2hpog+MHqDOh5y/Pw8o6djdOxw8KSLO2kQTxvyqQL32EHm4LynCV67jWjWSc5OER0V5JEtKtFhgTj1ghnPhb1DzNoipa+I9uz2UqYlk/mQyram9W4f4yrKwMGZlIT7MSLNkccD9PEJxccetv/mXgz7R+TD3g+5Cnz/86EuWJUbh6hxDq0G6UoLOYhJFxsUwSlPaKPEf28bk+fs/PWL9C8WtN42OAnWFpJCPBfgjkt7yo8K8obH4ccLvvzUq/y77e/wWrLMf/DOr+L/7y0a7w+Znc85etQl2Wgw912DO84RpeHo8SrZl3q0nRLxXzYJXn0ZdWEdpEBXA44erYI8HYA6AlFqzNI8aE16aZGs4eD1CypXDy3Tan3Figzv7VGeKtj1eIxqNmBhlrIeoF2J9ixBQWaa+W+dYFxFvFChCGzBlrl9Sd1xQekrKrs50Y1DMIbOpIGTVhgPPGqbCr9foD1J2nKobqUUoSJtOYSHOUWnghpnVA6HFJ0qh0/VcUaC+j+vWRpEv0AUCU4/tlsrx8GZmyW9tEgZSGr3C8LtIea928iHL5DOVUmbktbbPbb+dg2kwT/x6K+5qMyyo46/dIF43jD/Bx6V7RjdH6KCwHYG2hDePMB4LnmtxvElB1lA/S60r44wr11DA+qhc4zXGqjUEJ5ogsMEI2CyUqF3zmF0puSzz73Dz3Ve5X7e4fpkjrd7i2QNjX+skHsRaUfjrY4YjQOuDiLkdkAwETRvaGq/911KQDx9hazuEA0zJufa9M5b76dKoAh83M9fIdqaUNnJQMB4MSBrCGqbmmgnYXA2JDwwOLHtiqvb1vHgjTT1OyXBm3fpfXqd/U+WMHEIt6yPNI8EZv5Ux9Y31O8V+McJIvBBCPydAelCHSMFwWFC2vYpQom5fR+dJIgnHsb4CpUUlIHDcNknadmiWd0uKSPP2pXiHHevD1JiPBfdqcN00wpTu0P758060gV2/j9e2v+fnw91wTKjGLSkbFVImw7uIARhB8jagaQhqc60uPFrTdTsGPduxOx3unQfbeJ3wY0N2hXEHWtIRTiMFhSqb/jajUd4fWqZipvR22xy8bVDhg9PMVxSxLOa1T/M8Y4Tsk6ALG1hKF9q4d8oEUkftboMkwRTr9BftxYKUUB4UuBMygdIE3PSJZgkeHsHiEqE0QazPEv/Yg2/V+K/YU8sVa9jVhYYnm/g93LUOMdJSkRh8DaPraRhZYqiYvEfQa/EHwjC3QlymEBvgFuWiEqEblTsSx/n1O7EtF6xX7h8rsZ4NiDo2XW3dATuSGOUIO346NmAyn3BZCFgMic484/essWpVqVcm7NX1SS3WqAkQQQB43kPv1cS3eujN+4hPJfxWoPBikN0pBmtNxAp1DYUo1VNPAvRtuTkko/f06z/ow30YGDFsI5DubePKkucYJ7uRxYZrkpGZwvcrkEU1tok7+zA+hlM5HP0WIPJvKCxUaJizdZnaghtlwKjxxO+cOkav7n4XQBys8k/yOtsbE3jLk/IdiKMY1g4f0g7nLDZa5J9t01RMVQ3DbW7dgaZf/5pRvMu03++i/FdiuUIUfK9/4zdNmdNn9Gih3Z4IPgUpWG0HCBzKx3AQP1uiUr0g+ulE5eIaoXRoqJ6SzHzWorb7VPWPYwUNO5KSl8yWHHorzl0xg5iMITR2Ipz5+u4wwJ1PKJydx+A9COXyWsORp1uwtd8soZAJQa/Z3Vj9bcOoDdAOA4EPsZRoKTtaNOSeC4k2I8plzqgDc7JGBP4P5Ja8MHzoS5YGI0+t8zJlSpCQ+nbudRkStLc0NQ2hux/rIWOCkzqEPUFW59vW4bPwBAe5LZdV4KDp3zStmU+lRVN/VsVtpYqZJ2S6Vckk/NteusKZwwzL0MZKkuEmGj8+wMauaZ1rcTZPMTkOdSqlNvbDD/6NKUn8MYGb2ALgdAG1U8gL8D3MeMYsbaMjjyKms9kzrOO/s0hotWAvGD0mYvsP6NwRoLptzWlrwh2R8j9E3BdTC0invUs3sUXpHVB/V6OnGSU1+2e2VldJj4/Q7DZR9cC8o5P6UuydgdnbO8JrfeGiKRAaA1HBU6zQtawVxu/m1sjbGmYeaNAzkxhHEW+YJXc3nYXypLiFPEjH1tAlNgCfXfLKvHPLtBbd8jqkDUk1S1DsCcYPzvBFJLGS1Zr5PdL/D985XskC0DWaohqBRMFxDMe+8+BzAzesUJNBPW7dlU//MQ6fjend95ncM5u3dKGZDJj0TClD/rRhN/66O/y+cjqhjbyES/EZ/j63kUWZntU3IyiYw+LvFTc67ZI32ohHXsYjhcE2o2Y21piXFe0rw4ZX5hGewIn0Uy/mZLXXMZzDlpB6dn5lj/UpHWJcewwXxgIjwucYY4OFO5JjBxMIEkpl6aRgxiztQvtFpU9TXUzsdfzaoDTjUFDvFLj6IqDOwK/Z2wn5DqIMCS9sIBxBP7mgPLWHWS1CquL9NYtCkiWMFh28IaG2maJM9E4cYl7OEFog16aZXCuxmRaEh1p/JOCYOOAcqaJiksG5ypEBznB7SPQGpH/2Jrzlz76zBwHH62TdmD2pZzxYsBwWeKOrZp4eLZK/4Lh0vltApXz1sk55l8wVDYnOPs9TH/A+BMXiNuKvGqtFx//3Dt886UrIKBxE8ZjhyI0bH5WUd205t28IhiuODgxTL+R2qLoCOZeHKAHQ/sid3vIVgtnotFKktYFSdPBnRhqdxNEmoEUMNWid6VFdSthtBwwWpS037PygP6VJq1JAqUlE7SuGdxYE+xMmKxWyNsh3naBADvYnpaUgUArqOxZxTu7h6hL59n80jTu2G7/6rUOsrDqZbdvr7QfrLnRGtkb2q1lp4Z2JM7Ebp9KX1IuVnFGVjhYTtktkNM9fckAk5zagtbX6D9Up/nmESIv0OsrsLlPMhsxWTDI1P7Mw1XBymfucWt3hqV/4RBtD8kaHsG97vcXqyBATyaYbhd1YZ39ZyX+saB231CE0NxIcXsJRd2SOYoFj8peiSgUSccuERq3cyp7ku4FxcyTJ+wVDX7jqMOUO+Qgt/8WfSoJ3+o18N2CVhSzc9zAvR6hA0MR2Q6+iAxpS5AvdajccvO43AAAIABJREFUn1BUPSYzDnlFnHoQSwu6q1njNlhZwHBRWTFn3xAdFAS7EytViHOcq3fsz7CyQHp+mmBr8OCwwRjqGy0oNOQFateC8pKH5uifdfEGlnmVVwSjh6eQecdKaA5j5MY2KIl4/DJ507e0W2VlMUaC3zVUtzJUag9T53BoRbfPzTFekPZwPzGEeynedhczGiM9FxU51O9McO4dYPIc4fuY9MfC0b/02X2+RjltFdX9Ndeug6cMfheKUDFYVRihee/mIuF9l+oIajdP0G+/TwHoTzzB4eMOjQ1NtpTz8NoO3cwyusNjw3BJkrYNshQ0btpiNVySVLc1U692kQddtn7xHONnY9SdAHlvH53loLVdFQuBLM5gpJUbGHHKT78UMvhSSD5V4O05RLuCIggZL9orQfe8a+cYewWjyzPIwq7to/tjVG9EMV2n9vYBxe27iNVlTDWiaIZgIDzQeCO7CUzrivSvXCRpW5Or3zdkNahsjlHHQ7LFFsaR5DWFLF2MAGdc4OalHaxOMtRognEdVCXASIkOHNydE8uKjwLkOMZEAfliG9VPEJUQVa8yWe/YK83mDjovkGGAWVng+LJLWSkpA6jdUaQfHXL9+iLnfzdDvfY2yaeukDUc3K/f/r7ftU6sit2Zm+Xuz87QvG6o3U+JZ1ziaclg3WPmVctaNwpqdxPKQKEy220LbVCZJq8pSh/uXZ/j79/6WRbXjni4vUumHfpZgO8U3DtoI5WmWs24u9uh+mpIMmUI9y1S5QOrTrRnr0H9x6ZIG4LxomWj+92StO0yWLGSFic21lazpJCF/X5Gh5pwe/SAjFuGLvrJdbKGQ+lLwoOM8pql2SIEwveRRwMrdXEdUJJkfYbJrEvjTo5MNWWgqL6xRbY2A0rgHMfI7gAz1aLsVCkDxyrqffUAmRPtG/y+7ZqdfozsjzGea39/Ghq3S2vJGZd2ttqsQruKSEvc3QEcHGEcB5SyVrFGFY5+OO//X/R8qAtWEYA3PMWUFIb2mxnxtEs8Je21o2UsNvh126aPF6T1tF1YZ/BIh+GyIp4vuPJTG8hRgxu7M7QbY1Ye2eX+dBsOfdrv2vCE8bwknha039dUNmNEadj52XMMn0qovRqy8I0TmGlTXl5CXbdTx/yzT9I759q5wNAwmpeMVjXuCDvUvO7Sfr/g5KJDXrNf9iK0KJPqdk5WVzTeskEVZnMHnSSYqQ5y/5BiYjsaXauQzlVwBxmtG5nVJjmSPJJ2VhLaU7T9XorbT1AnI/Y+v0DQreKf2K2Q9YlJvEGBSkt04JGuNvGPE2SWWyJnXiLjCbLbw2gDYYAIfXQtxLgKIwVFJ8Q9mjA532Hyt3ocHdW4+M4C6XKDeMbl+Iq1vchmhtwM8D57xEwYs/leDeekC7Ua0Y1DvDv3fuB3rZoNWJzj9pc7eAOY/oP3rXfti8+QPg3N6/alGi5ZyN94McCdaPyBJtyzi4CsHZA2BO7QAuiMA3uTGXZnGkhlaNYnJLmD3gkxpeBwVKNzz5DXLDU2r53+3rZKnMQwnlH0nphitCDJmoa8qol2BGlLkVdscXPHdosbtxVObAf/RWC3t+l0hFGCoqKonCSoSYYzUlay8tZ73/vHG0PZ7cKpdUYtzlG26+RVRbSfE9w5xigJh8cUvT5ydx813bF6vakGZdXOlZxRhto+grVZROnidw0qtS4Db38EO/uYxbkHM8bpN62EpAgVTlza4ipBDmJEnEJR2O9CliMqrp1n5j/aDutDLRz91LP/Na7wHiBZjh5TZA2NrpYEmy7VTYsIySMrhGveTvDuHpEvdTh4KqL/SE5zZkjg5UxSjzj2qFYS4tc7NG5qnNSw/6ykvmFPRBVroheuw0yH+z83j1GWxjD1yglFMySru6jUGlM/kFKYN64++LllFIHWD7qFB89HHkUdDU+7Fh/x3gY6SXDmZjG1CsV0jZNLkTXlHmiqN/qIskRXA/K6h1ECmWl2PxqQtawo89O/+jJPVu7y9//sr7H6LyF64QZlr4/qtBk/vw4GgqOEvO7ZhcXYDnox1oSsHcFw2dpQGrczgrtWjGsqIbrqw2nmnFECURrKyOHoSkj/2YTPXXoPJQzfurdOkSvU9QqVLUPQ1aQNSe8nY37x8mt89bsfpX7dYe5/+M6Dj0I4dvaihxZZ7KwuU8402f6JGvGs5vxv99Dvvo987BKbX2jhjmH+j/bQjYjRmQp5JFGpobKTktecBzYVlRsmU5K8JqjsaPKqoPuw9eqVrYKFhRMOuzWi71QQBiq7JXlFkkdQBtaO4o5KEHYeNZ6V5FVhmfqppPM2OImmd16RTGmm3hS03htRVF2K0HZW7iBDFJq8YQuI3cBmuLsDhg9PoV2BE2uCf/WyLdCz09ZvWhSwMAObu3AqXtbdLiIMMesrZJ2A8N0tCHwoyh9ADSEVzvwsxc4u4ukrDM9EaEdYzVtcMpl1Ga5YPHJes4P36Kgk2rQSD3XQB8cinXEdykaIUdLSKkptC5kxFNN1dDrhm6/99z8Wjv5FTxk5xIsVyxealpYYIME9cmhdt53DYNXODIIjQx45iMU2u89HyAxELHlydot/u/M678bLbEym+bPb6zz0+8eIOKX31Cwzr2gq2wl5zSW6eYTOMqgENG/ZL2/17phkvmpTR05xN143w72zj8kyTBAg52Y4/IlFSh9mv3mAOumRPLnG3jMeWdMw/6ImcKRVDuclcm6GcrFN5gicXoLMNSqHyn6Jf5KCI+lfbhJ/cNUbaBwByeUY0/WY/5ktfr71Mr9z9DFkpUDmivTJdfKaQrtWme53rT3DEcL+WWlpENqT9gCYVxglaF1P8fdHoBTlXAvtKoQxiLx8oM/pPmRtJZPlEi/M+eY3HscdChZeTEjaLrWNHqOzNY4vKRY/s8lz9QNeOV5FlBZV/f98TFliTovV/f/medKzCWbkgJtz6e/dQy/PUH76SQ4uB9Tua1qvHyGSjHylRVaReCNNtJeCNgxW7ZzRSWyxkvmpLapikUL+kSA4Mpgvjqh5KYd3ZsmrVhemHcFkToC2EgNvUKKSEpmVJNM+eVXYcUFqVfTJlCCZkjhjOPsHKWWo6F2oULqCzjtDtO8wWQiJdmLck4RkPqK6MUJoTbbYIG1ISg/mXtiiAMzSPNlshXLdEhMqWwlyMsEMh6hGHbm2wuShDqIE/3CCqUa268FulJmdst9HrRGjCfr4BDU1xXApQmWG6CCjCBT9c56NoTv9XCq7JVlVYoRABy7OrR2MNohaxR5YH6ThGEPRruAcDBDDMaYa0b0UIYYCXvuhlYAfeD7UBSurOwTHBWVgTZlJGypbkuatkrQhiackRdVaYbQjiKcdtn5Sob0SUQhaa13Gpcfb8QqbSYvcSMrEYXS+QbQdW/qntj46r5tCnCBWl8jaIUbaDYtxJJNZl6PHBc5EUN0STP3JG5i1FcYXVog7iqwuyKvQullSNiOk55I2FNUtg3PLULkzAgnJfJVgb4xuVJBpgTYK4zkkMwG1zRSZljgHA7s6NgZ3Ih4Mz+/+PAQ3Q8Knj/nC7FVeic8Sly5i30c7JeHBBJnZ7aNMcrTvUEYuZeDgDgqypktWVUzmpFXQC8u69w7GkGZ2pqUk+C46dDh5rM5k1tpJwkOD3zUYpWh+u0JlyyrJRV4g0ybJXIW4JQmeO0ZieGFnjd5+jfbbkugPXvz+X6oxOGfP8N5/Mke03KfpFCQ3Oix9c4KZn2L/uToImPv2ib3qHHcpe33cqQZm1SNpSsAO3kvPQvH0CKq7VoGf1exVrf1eiSzh5IIikJob15YwzRIjFQsvlIxnFGnTUNmxn3ERSuKOoog+sN1A3iqZellZXdWCzRycfjNHu5LRvEvWEDZRJnBwTybUt08gL4gfXqD0JXkrQHvSBk2MNc0bCcnFebJnl0ma1hWgPYuzyZoeYRii2k2M52J8D3dU4O4OMIELroPpDdC9PsJxKKdqaF/h9FPiS9NoR1B/fQd3WJA1HYrARr85sT3kZW4Ijy2P3hudZk1eu4eJY0SthhkMbefbrGCUJK9aCxRSkp+dY7IQ2Dlt/KO9kH2oC5bMrdiziHwatzNq25K44zCZloxWIdwHd9/QfaREGIF/oJALE3SmmJvtsXfU4PVxQLEo6aYRgyQgasT4Ry5oTbA7QmSFbbOna5hqBLsHeEcnjD//ENFeivbVqUhTEB4apv/ZG4iHznLyRBt3YvVQbixp/LHdlhW37yLPrFC74zBcq9C41mOyUmc851D6EN7LYfcAMdWGRmTlAr0c8cKbiKceJl1to5ISd6yZTCvGK/CJn7jGTB6wu1Tn47O3yY3i1mSG79w+RxlZfhVa422dhoYGLtmcRxFIguMcmZeI0iFpS0QBElCJJUqY0EXsH0OtwmS1QdJRHD9iT9nO21ZRX0SC0rMhBsFxThE5jB+bwp1oVKJJG4qTxzW/snKNS+EO/+v9j1PcbDP1v3zvKigrFSuMvbDOjX9/mspKn3qYMPjGHHNv2M5z/yMNsrpd3U9W61Tf2Ca/sMxo+TyjRfmgOyp9O+xWmWU4eUOrt8sr1supXRBG2pf0wJB9cwqzXiAzSfuqRQFPFgRgSDqglbKYn8AuTRCQ1wzekT2MJvOGslYy922Jf5QwPFuxVNIt2z06vQQxScAYhk8vkTbUaTKOQObahjl0E/oXa6TND2ayUJ5ihrKaIDyGyacu4Z+kOBu7MBzh3AbRbj24kiVPrlF6Er+bkbatFCWvOXiDHO/6Dvm5eXsTAJKOY5dLRzbqS7s2Hk47LtXtCXKcWhhmJToFLZaYKEA7kv65EH9Q4vUzjO9Qhg6lJxjPS6rv/7hg/aVP5foRbiFxTkKbOzcd0b0MzUeOKN/rEB5ZqcL0S4p42s4byBRhNWUQB5xfOOBs7Zh3T+bZvD8FuSCcmeAeDBHj2G5FppsMLtQID3PcvLBXQmOo7qSMF3xLkYwN7W9NcK5vYtbPcPJY0xaxgSarSpzEkKw2CW8coM6fZeun5xitaNa+lsHBCftf7pDMF6x/Ncfc2ST/6GWMFGR1B7+bU0SKqNNm61ONUy9eQulLxiuGxad2SLXDG3eX+dKld1nyutxP2/zprQtUXwppX0vJWh5BagsvkWS8VsMIQfX+BCMgawcMVh2b3jIweEND3JFkNeyM65NnGS4r8oo98afe1LTe7nL0TPs0NMLynEReksxGeP2ceNolOEjY+WQN8YkuH5neYz3Y5w+PHuX+O/Nc/L37FIBqtRCBT7G7h7O2yq1fnaasaNLUoffyHM17mv5Zj9GKRzZd4HYdvKFguKjonVtleL7E+AXevmuBfP3v5TdqYbup4bIknrHiXr9rHQ7upESUMFy12Bl8jRgrnNTYQn763UFY+UIyo/EP7dxOJeCdyh8mCzYjsvamwkjDcK1iqQZH1keY1RTGVehmleF6jaRpZTd5JCgCl/C4JNwak7cDnMQgj8HvFWQ1RV6RyMIQdCGv2I7LOR5TnhJdAWs9eugcvadmiKck1e2SgycjZG4sOjo1jGcCxLmzFIH9mZ3YGuKFNtYBETnE09baFB7mlhySWN6acBxbEAMfE7jIpCA6KGwS9jAFbeeeGJh5PUHu9H/IVeD7nw91wcJzGV2ZRbuC8azd4qENR7fbTL0r6K8JysgOoY0CZyRZf2SPyMno+GMKrXhlf4Xxi1O4FUNRMaiX6uQzDu6JYnixRR4KWu/2Kas+xvfQSYLyPPLIOc2M09T2Uxtl1W5SNAOiw4KsrqhcP2bn12Z45PkN3tufo9hYtN69uqbzlsC/e4RpVGm9r5HvCnafD8n/9kNkXYfovkPzpoXaRRtdxh9dRxhY+to2uhYymW2y/tw9Hmnu8PWth3hq7T5bkyYv7q0xeLND4w70LmuKyGfp6wPQoDv1U954aZcDgUMZnr4YOQ++eEZAPGuQqWC04p3m2tnuJTgxOIlh/+Nt0pZg6esD1NGAfKFF3gmpvH9IvD5FZTejDBySp8d8bG6L905m+W/f+qsE+w4XfusW5cos/U8uEU9JFn/nPQ7/w4+S/1Sfpdo2d99dwH+1ijc0HD0iHuCSha8JDm1HExxZvpQRBjFRaAVp2zA+VzC72GUwCcg3akR71qPnn9iikwL1O5apnjVsx6UmksIxVLYF4WF6qp+yGY+lD1nT4J1I3JH1oCZTBpVZCUq4f0rLkKdZjCNr/fogpNcbliQLEWlDkdYFTmKJn63rMd69I0yWIYSgrC5QBILJrCSruDRvxlSTgrzh0z/rgRFU9kvMvS0AnLNnIC8oZxpsf7yB9qGyrancHeH3fNKmS1aVnFyyMEVR2mJVvW9ovzemDByMtGBAoyThfmY1WPt9zP4RolGHqRaMY8rpBtqR6EAxWLFD/8Zdm7cochul5400bjeh/Ate0x/m86EuWDuf7uAqh3gG8pqmuikI7sDhc9D/4phs7OEcuFT2Svxuwclln0DlbJxM8drhGUSiqN9Q0IAyMpYwuqcZnA0pL9k0mfbVCfFClWjjBHN/G9VqwcIMsjTEU3Yulkwr/JMV/GPDzO9fRQ4GuMD+3/wo55+7x0lSIUsc8E7nHK9C++sbdiUsrS/u8ElJNp/BcUC47bDw7QkyKylqHroWEBzEzHYVuhbSfaRJ/ksn7A1rjLI1Hp3epTSCN//FFSq7mmoNjp8r8A4dlv6kT1HzyRqOPfGr6gGtQaVW0OiOSqvC7oN2heV+n9hk4A9y6GQJKrbXy/75iO4VzdLXDdpTSN+jiBy0K0hX25SexBlbX+KTK5u8fTjP+I0OC+8aGu8cEj++wu7HrG5u6RsZu79yifTTAxpByk63gQ40o/MllekJLjDZrGGiEhJFPG0oF1JkHpCeSS2JojUhe6uF9gzuscN+2aYyMz4lgObEUxaZomsFcrYg6duNa7xY2CLtaVTPoblRoMY5edO3SGFjBZ7JNGQt+2LKQuD3BM7I4ovdkR1WO4ntTI206nXtSoKDGFFodj/ZtGyp08JW3S1w3tqgGE+QlQh8j+7FgO5li4puvT/BublF9sgqWz/hUbtnD4zq61swN8Ph5xbtNfHQ5gXkNRt+IQygBN7+iNFCm+GqOLUF2cJbhoaiIpgshFbSEhdoR1IGVrag+gkiLxD1GqZegSzHuA4iK8g7VbrnXZvjefMUOrh/AkWB166gfUVZ8SD50fKwPtQFq4jAySE4gtpdQf1eys4nfUQhyLoBzkDhDQT9NUXyrKScTXnj2hrV2w4Ld0oOn5AMHrIq8nBXWbOnLzh+zBAcyFNUcUjrj28gXBfOrpC3I2Sh6Z73HqT9VubGjI4i0pbDjBQgFXv/8XMMH0+Jv36G6pah5fIgjjyrQ3plGX93CKWmfmOAymvIVOAOM7x7O5jQJ1lpnsaD+6i44ORiyMzfOODp6h2+s3uGVhQzGw650Zum/605hILjR+0WcPVroN2S21+uo9ZHpPsui98QVHZSjq8ECCMJuuaBlcdIGC0p0iY4E5h7OSFtucRt2315I0393V3GV+bpr4MJ7GkuhzH5bIPRooc/0Da8tSlBeGx+QXD79fNU7iumb1leOaWme8Ejr2kaN4QVVJ4xLNVHnExCkuMQEZRUGjGjXgixwplO+Mz6dV753x6n805M90LI8UdyWu0R3d06o606ZjlDTBROJ+GJxR22hk2GEoqKtAp+KfB2XapbLu5Y070owNeQSdwjl5lXrTE6r3tMph2MA0FXU4QCmWLZVBOBO7YQQZVan+Bk3nZa3tDC9mRuZzjeidW8HX1snubNHG9gw0adxKASzfDzl63vNTekdcVkVlDfEMy+NEQd9NBz0yRtl/Y1+/+ThSE9P8fJRR93DHPXJuw/HVGGtnBmdWzXmZfsf7yDUafG6wokHYMODNGWlXw4E43MStQ4RQeuTbuJC4yvSKeniadcEIL6v7mKWJqzyw1jcEeG5sb3UnI+eJzdLrpZRRSaovjR9lgf6oLVulEiI01aFzTupCRTLs7EbgRNojArMbUrI8aph3i/gTx2KaslyZQhfTLGuVqlvmG3NDbCXNJ/yCrSx2dzvAOH5tUe+sw8R0/UOflEiskU4T0X49gv7PK5Qy40D/jm7UdY+69etM79Zx5B5iCPXZq3bBcT1ySihHjOMpaM8Jntp9Yr5kj8bo53a98GNMx1GJ6rEe0kyKxATjK2f2qaL/w732HJ6/LueIEr07vsThp89/WHqNxXD5hb0T50Xtzn1r83y6OfuImfhez260SbCpnbiXplzw7DVaYZz7kIbbPpLF/LgBCcXPCp7pYEXY3KDcF+aj18Uw4qFsx820HkJdlCk7TjoTJr+8lPh9y9dYepVwyyMNQ2LXRPnViVvtAQ7kuMgOPLirKRs/nuHPXbEnfJ4J4fs9zsQbPHz8y+hRSG37n3EVo3MvKay/HzOW6UMxiFyKhAOZqykGhHsjzdZXPQIisU2rUc82hQojKH8MA6Do4eUeTNEjFRqLHNLHQm2q7yXfmggKvUFovKtrDhoqcdVeO2JVnE047t0LCD8WjfxofJpECHLt1n59AORDePKKbreIMSd5BTRg5OYu07adu6GtyxTcURWUE50ySveaR1u7FFQPuaPWjcsUXEZA2XoGvQvgAE/gkE/ZJ4ocpkzoazIk4Lq4bahqRzLUUldtY4WYrQyoprgx3bFZWhS16xdA7//W3M8jw68pBpATWXyn6BzDR53cctDbI/gtOtZRl5NoF6c/yDL+oP8flQC0fP/vpvMH3Ho37d6nYOn63jjg39s5KVT91nlHvsvTdDcCBxEpjMGYJDQee9HHdQUPp2iJrXHZKGpHfBXn3ypibcUiTTGh1qqnM2D2+c+9w5bFPuRMhC8KXPvsLXXn+C8J5L55rNjisCQVERVLdLwoMU52TM/ienrAF6aOivQ7RnxXnxtGD5j/uY164+wHzsfLKK1zd03o1xejFlzWfrM1Ue+dL7/Pz0q/wfB8/wztcv4HXttsxJDX63wB0VbH8qYrKW8/D5LXaHNfrDiHo1ZjgKqbwYEXQ14VGJM8qJZ30bWR5+0CEYS6c8iCkrLmnTxesX+JtdTCUgmY0IN44RRWlN21IyemwBlWlEYRgue8Sz9vrojmD2O3104KADK9wsQoU7zMlaHknLDvCL8IMUGh68+EbZUM4icjh42ucnfu41LkR77Od1vvr6czx34TZfOfNH+MLlqBzz5ff+OjPRkOdbG7wzXOKlnVUmIx/paMxeQHBktVHewFDbttfDPLJK88m8tXXNvZzgnlg1fLxYI6sr0oYgOtQPkpONshSF2saQouEzWvTpr1mxZf1edkoJsZ9FMu2RVSStd6x5Ol6u4fZzEAL3aMTkTJO9j7hkqzZXwO0rlv84Q2Ylec3F76ZkTZ+0oajspBhHkHRc6te6doDvO/QuVhnPCxp37HAfA8FhyuBsSNoUxLMGZyQeuCrsbM0a/p24JJ71yaoSv28tX6K0nZHsjiDPwfes3UYKdKsKhaZo+jiDFDlMEHGKbtcYr9WItmP794ZjismAbwx+98fC0b/oqW3aX9T+8w2K0JI8xcqE9dkjRpnPybCCDi0EbbJSIjJJtA9xx7Ffht2MrO5w+LgkXcgRE0V4T9F+8oif/dSbvD+a58/vniW52WDjW00L9O9AfccWm3/17adxE5slFxxbIZ47zMlrLuY0snvwcJusYYWZx49aoqXMXWZeK5l6bYx54yrO0iImKxgvVajdsx3NaDmglpfc/VIFdWnA7639Kf/45CzvfP0ClU2LDBbGkgO0J9l/NuLZn3mHtHR4fXuJLHZ5dv0uDTfmW3fO079UkB44Fr+SKcazCu3Zrswb2k6k9AXJbIjMNLWr1hKEY5Neomt7jB5fYDKlqG1mpG2bRuz17RZztHLalSTQvJWBEuQND5lrsrpDVpUMzjjU79otkzVpn7L2V21RmXl1TFFxmMwHxFP2Sv5H33iSfz2X8fT6Xb78+Gv8nak/xxdVAJ5/4T8iH3mki4pJ3eeZ+h3+9PXLAMiBevA9UZmhtmltW0nbHlJZ3abSMLA/h9g5wixMkdcUWdUWUpkbtGc3j9WdHP8gJpmrUAaCwhfIAioHBSq2A+gyUJQ1myHQessWq8mZOnFHoeccwhNNXmvSP+MiDKg9j+BYUL+nbaDGQkBtY4g6GWFUi/BeD9EbQuDj3yzQzRpF00azFYE9sEbzEiQ0bhcUVUtdHa3q0yWT3ZYWkT0UguMC7zghbwUYYSkRXi9HlKVFHQsBeY4pCsysDVE1UkKhkZOUYi7CyAB/lJKdmaZ/LrDxZUlAsRyhUo1/dQsGP4SX/y95PtQFS2U2Hbh/oaR5pkfLz7jS3uXt4wUO3pylDAyt64LeFY3TV8y+qhnP2jbbiWG4HBDPa3RQEm3YFJUihL+x+jKByNkaN/Ffq1K7b69Pw2VFtGdO8+VsrJPQkEcSp+LgdS2BIW05uGNNVncpfPuFn8wL3KEkrZa0rmsq37Y5eMzOMHhmiXA/oX/GQbs2O87vGfo/WUNcGHLt+d/lH56c45//1k9RG1k8ijzNuCt9QdJUJB3DcVrh9nGHn1y7wU+33uQL0Slve+lFfn3/Ub72+x+nf8ahdcswddWiSbRrle2I732uziCl6FSRWYE6HiKGE8aPLXD8sOWQdx/y0T64A4M7dOhedKlsGaq7hQ1D3euRLXcIdkdMVmo4Extu4Y5gPO8gNFR3ctKGondBMvtyTuX1+xQrM8QzLqUnLAf9yFpdYt+l4mScZBW+myzyuij5z775y8iRQnQyilKRG8VrwzOoRk67OWKceMRbNcJdweyfdylrPrLlkHTA61kdlQ41opT4L75vFfZyBpVpVKboXB0zPBMBFoDon6SM16rWunSKlykqhnBrhOyNyBfb5DUHYQyNq10oSgaPTGGUjQcThaG3HpJXFGnb8rjqG5A2rXBzMusS7VvDuVES5/omNG2HYrr/uAQPAAAgAElEQVQ9ysEIx3OhGdBfD1GnCdRWuHt6xU814bHA7VuY4QdF1x2I0y2vRpQ2nemDXMGsFZDVayBqeP0c56SHqNfg1Mkg0xzyAhPaw8c9SSjaFQZrASefS2h+MzhFJllXQNmuwp0fYhH4fz0f6oJ19Dg8/Pxd3DiiPw55Ymab1w+XGLwwgyNh+jXNYE0iY8HCCyXVd/bY+c/ncUaSvFOAY1BdK2Go7NoBdO8CBCLntzY+SfYnU0Rdu9npXlCoGFo3UkaLHvEcFO0cESt65yXeUBLPBTZuq1/SP+tS2bdO9+EaYAwqFaz9n4bg9j6TT1ygd9YlmYLVfzMinguobVtbxPEjkDyc8IsPv8ZvzL4NwP/8+qdoFoakbQf3zU07R8lqitHnR/zape+ynTb5Z+f+gIYMf+Cz2k/rlI8PWej0SP7pAka6qLjEP4opQ6uvwZHkdY9kJsI/TjBKUrZqTFYqHD3qoBIehBPI4al3bt2115GeJnp3B93tUT50xtqMtvaRcxVLHN3MOH7EPw0MLRisuoyWBEYZVKrZ/vlz1LZL6rfG6NBBjXMG56o2THWtTzeNGBce/2Pvs+zcncI/sEnGeCVPzmxyN+7wZ+8/RFhLODyoI13N1BuC9rsDstkK4znrlzPKUAaCsqKp3nGYfSVBrCwg0pzxXETl9oBqoek/3EI7pwEX44KTy1WKyIL3wB5YzVsGcX+P/OIKJ5cjjILp14bknQrDFR83NkTbll8VrzRIpqwVaHQGvE1B0rbBpI33B7brkYKj56bQLrTfraPevY2OLSQQXUKcMFgLyasCUZzODCvgDgUnl73TA8gexs7YoplLTyBLqN9P8TcOMLUI4wi8kwQduBhHktUV3rDE3TrGOI71DAJyGEOa2c5LSsLbx6QrbfafDRhdSgm8gvBYM5lzGaxK8oah+Wrlx9acv+y5/Pg97nXnmdyr48xPuNmf5uStaXRbE+1Ia60pFLMvGcK9mN0vLoLS5PMWMuYGBaVfUvQ90pYi2te4Q8n/9Js/awWU6nsbmvpdOyvIqw4qs1l1Wd2jCC1mZDItT4WJhqRjryODFcVk3nZk2oNwz4oaTz4yy2BNksyV1BYHDN5vkNVttzaZFbAQ858+/qf8ndb3qAWd9ojeJzVCGMq9kPGyxy988f/iSrjFZt7mX+9e4Qtz1/inJ4/z1ZtP47sFo4nPf/fk17jo7fO51lVe2Vvm1r1Z6suKyp4d+madEFloyAWlb5HI/kmBcSTxbEDvnLJEz74VaMUzAm9gGM4LZl7X1LYg3EuQr79PkaZWCLp1QHl4iLO0SHTjEDOaUDy0SHVbk9YEWU3i9zThMfgnOcmUS227pHqjj/EVTjdmvFZnPC+Z/eQ2i5U+n269zz9853PMNEYEnRh9VEWlgl+4/CqjwueV7hwfv3CT1/7lFZpDq9SP9gsQdv4zXLVEBRXb4XnjuqJz9VSAe65FGQiSpuTw8TbOxKrUJzPShjtcCUlWU2TPpfWu9W4KbUmdZnmW0WqI39fU7li6QV5zcBK7vHGORujI5+gx70FnNvWGprqT4O4NMTv7mItnMEJw5686GK8guueSzPiEl86QTgVEL9+mPD5h/MQy8cyp7zMUZE1D9T6MVgFjI7lUareGZQB53W44Z19JcY8nmGpIOl8ja1hrjjfICe/38X0X1RthBiP0mQVLZJhkGN9F5AXGd23uwROz9NcUkzmNdDTJUWi36lcEtcvHJL0KvQviB97TH+bzoS5YN/9sjfyCRM0k+H7O5sY0jgQMTL1lDahz3x2jxhn7H23Se1ijWilCGPKRR5E6MHSYflnS2BjTvRihHajsWae+dqz+BcAdabRnjcJGWZtH0jG449MN44zFwyQdG/JgpKC7DF5PnH6BNGlLcthyadzRRHuGeFkz3Kxj5iXJjEEldgD+6fUbzLo9/kn3DL9Sv8pX+o/y21e+wrEO0UYiheaTAaQm58XE55dqXf5ue4NfuvMZVqMTHpnb5aVr5wjvufz69i8jF2L+2sW3+OnVq7xSW2Xn5jJ5RWCUi1bWGzf9uiad8mxYxp0j8oUWgxVbrPxDh2jP2j+atzIGZzxm3swZLTioDGq9CcZxkL6PaNTQ1Yji0RVMUiJeeJP0i8/QW3cZPJUy/acewUlpTeqDHONK6m8fYUIPEzikUyHd8y6Dh0pu/9xvft/v+x+UEikM1TClL6vUnjnknf4CHX/CSq1LoRXLn7tH25/w0ssXKH2X3nmX8ZJBL8ToXKI2PcoAgtvmAQU0q1lFeXhsmVLagYNnJOEejFYEZWBwDj2iHYGTatyR3fwGm32S1SbuSFO5cQxKki7UrbpdQnSQI8YxIvRwTpdnZQC1uzHOIMEELuahFQ6frDL5yREqLzE7AWlbc3LRIWpW6bzWRff6diHQcfAGdm6bTAncgaAI7dzQiW2RVgmMl2wX3ripbTRcL7XdVzUg6ViiiDvMQRt77RtOrAtibop0NiLYGiJGMflSB1kNUJsHmHaDIhQUFVDzMWUpqd52GJyBqcf2aQUxo7GVEv0onw91wWrc1hwveIStCfO1IaO8QVErEZWC3Y8FLH1jgsw1t365SdEpaM/1Gcc+aTcAYzP33KGkfj9hMh8wXhTEKzm1TTuD8vt2DjBYUbSv5/hdS97MKw6jp0GHBmdiCQjVTYM/tFFPWVUymRMEhzZZuHtJIDNhwwy61oCbNgUzf27X2zufthl02hXUz3f5bPMav1DtA32gwt9tbwD2mvftRPOVg4/zVVny8u4qveMqD63uceP6An/l2Tf4L6Ze4LCU/GP1OdaeO+IPtx/m4LjOn2xeoHe3SfNMz57M21C6gqwhaNwpGK2GlJ6gfiehbFbZfzpCe9B4z0HmhsqBnZPE0y5FKMgrivGSYOrtkvL9W6iL6+x9aooiEtS2LIrF+cZryEcv0r3oEj83wnQDsppgsObi9aG2Ze0maXOK4m8e8SePfJWqDL7vd/z3Dh7hb7VfZN6pcuNTX+G7SclvbH6J6jMpj7W3+bcab3FY1vntrefxVcF67Yjv7J4h2pVEByUnlxVFO4dMQSLJGobWVYHKLdCv9JWd9STgDgsadzS9sy75bEYZuDhDQWXLKtiL0H5mo0WHxu0MkeU4wxx/mGJCj7wVouKC8AicYUbW8innWpSBQ+NOTv+MS/1uabHcnkO8VGHn4wqxOiZwC9K9CNMsUF2XaM/QvjpEv/s+qtOGuWnGizZYxHoQ7edTRDaYVWirtM9moLJlTqkVGc4ggdLeFNK2jzOx2jLjWh5Y2qmhvTqVeyOreN8cIMYx5VTD4mMOjjFGQ1E9tSpB3vPB02R16w4Ric/BcR0hDfOf3eT6P/nhvP9/0fOhLlhHT4BwDKO9Kjf2qiz9mUElhiJy8U9SZKG58asRleU+T8xtsT+p03+/g1PaQlRWrNju8NGQeNaQzWfU3/FobEzQrqSIFN0LVifTX3Op7FoZwMEz4M2PSU9CytDg7NvB6dEVhcwh7WhUbLd4opCEB/83e28abNl1nuc9a8/77DPfee6+PaMxNwEC4DyJo2hatGRLsqJIjhW5SnZJSpTBVUpFkZ2ybJcjKU7sSHYqcVRlSZRkk5FIxgQhUASIiQC60Wj03H373r7zmYc977XyYx00Jduq/AqJH9p/ugoF9LnnYu9vf+v73vd5AQVJXdC8WjBYNSlvS5ov7JItNjDHPl5L8Pkf+Qa/MPXqvYf2ifN/hU8uvcWl4QKvXFoHpfPqlKtQQlG5aVGPoffsCrMKnl08zn2lHdadAyyj4PdvP0x/ow6motdzsEKDwfUG1Y3vgAKbVzLCGX3MBUHrQZ888Ml9naqclbWxO6kYiLLB4Ki2uvSOGxSuonp+j8JxOHxymtEaBHeh/vwm+baGGG59qknSVFS+EVC5W9A+q48tU2+ldE47hE+N+P4Tb7KfVPlyODcp1Nz7/llhcGU4x7w35L+ff4YnvACApaDPry58m98fVfnvvvKDSFfSWOpTtWPGF5uUe4r+uuZ5VS85ZAFkZYXXFpRaBU5fR8rnE36WmUjMuCCtWwzXJSK0MENBaVcQHGjSgzIhnyBYvFuHKMvEyCVFzdMbQseAkknuG/SOa/OxNatTgJK6wB4r/FaKEWW0Hq3Tel+GV4moBRGDb83CQoHhFghl64K63UIGAXJ9idbDZZSA4RFQayHVSkhnp8bUty3cgS5IXm9CFzE0dNIMU+1yqDukVYO0LO4N6ysbGWZrQH5mFntQkNU8hFSITIJTQUipj6txguF7ZLMVDj+RMDs9oDsskR6UMFOBnGROnFneoxUGbLdr341H/8+93tEFS0hQjkSkBu6hSeXSAdlshXDWo3/EJVy0KS0PSVOL528ew3ZyZEknAadN3dZLW9svajeg8seKwtNseGlpMWXu6Ta+tK+wx5LCMXG7BgkBXtcgrUmGawaL30zwuya7T5r4B5rNFS1IzEgQ7OobqrahO7Spt6Se7XgO3VM+0pf8+I89zaLd41YOW7nHz/7eT1C7AV9OP8DgqKC5p1OR04pg9P6IDx27xsp7uzy9d5rt8wtUbsFwr8IbSyvYouDvLzzNc405fq7zV/E2XOR9I1LTo37RYryot4L1q7pTkrYgmjWQptahaYif9mDG07oYD48Kcl+nvDgDfTRY+FYBcUL7Rx+l/ZBi4Xmov3T3njnXnGpij2D6Db1l23lfmfGJlLlnLDb+kslvf+rXeCVa56X+UZ6s3+S3dp/kH48q5IXB4FoD6Sr8xRHtOKCblPivi4/zt+e+zpnqHp+svsG1bMzr4QMwnXB8ocWRcoc/efpBvAONfyk8/T3iOYk1NKhsaOGoKPQsMW5aeJ18EpcmSKYcspLB1AUYrRjYA+7Notx+QbCjWfZcvI5aWyafKjNe8UkDHTLiH6YoQ2cjjpbByAVeC8xJLoOR6/vg7vc1GB3LEZFJ1i5zaAY4BlDOMC2JUlC7rOUMhuswntYyhLdlLCszXZQSDHqW1ldF2mGgOVbgtwvsgdbKJdP6O2nDszbj+22JuXUApknpOZ31mC9NYaQFxl6bYmkaoxeiTAMR+IhyWRMargg6noe0wS70i9ldHuE7GZduL0JuIJPou1kC/oPrHV2wilpOabuk/WSbisEDU4TTBtGsIJkpqK32EUKRxDZyYGPs+phlpfVHPYO0WSAkVO+kjBcd2md1kkheQht+c6jf0HYdIwcryvGUwgodzNjACqF5SVG+MyRcKtE/ajLzuiTzYXhEYCSaDJDUdNT4eNaidFiQNAzu/NwcytYf0pgf8EJnnbvDOv3z01RvwHxP6iTkYUHjrZis6hLO2XQfyXnP2h0+23wdm4J/efe9GLZWp589vUUnLbFkd5k2Az4XjPhvghTjwZianzA8X8aKFFldohxJ17SYPi+0RmnWpbDBGOkXgT3QxaqYpB8XvgRXUrrhYEYKNxcE1zvsfu4og2OKY1+ItT/ubVLokVVkLcA/lPibQ1qPN+CpHqLv622dm/Lrux/j23dX+PSxS/zWncdpdSs0amNyaaDmE1RiUvET9vsVADYuLvKNueP8lw9/jZ+/9IOEscODizs4bs7NS4tsRMusPpMynre1EXmoFeoim6j4LYGQEiNVJHWL3JsUl0WTwhPUb2Y4Q8l43iDYVpQONLQPQLqTMI6L1ymeuI+4ZFF4BtGUoLxb6EShXCFtg/66nu2ZsU5bTmq6YCBg86MexXqEbRbkqYUYuZT2NLzPu+7htRXNKwmyZKPsKkXJpn/Mpn9Cd+0AmxcX8A4N6nuKaFpv9IQCd1AQTpm6yzIFWVULWO1IUbnWQ3T64NiaCe865Jt3Ndb41BpFycba6ZDv7SNabXKpMMsBMkko7j+K1yvonTGx+4JgRzFYF8iqPpe2bjfBUgivgKHx3S0C/971ji5YGMDZIYYhaS2W8HZtspMha7MdXDMnkyYLpT5vskBfCiLgkftvs+gP+Ob2OvntGqV9xfYHHLKapHHJoHZTCwyFhGAvIff05kyaMFx2NZ0zh6z+djZdSFZx6K+bDE9lJO9OyFMT1XFRQY7bc3RR3MzpnrSp/ugev3T0D3kpPMY3WifIpEn0zxbphFUaX32N5qMue09VGS+aJDOS5vEBo8jFec4lWlCcPXmXDzWu8H/tP4VUgidP3WRz2CC8Nselyyt88JHL2CK/9yuarY1oj0qEX59l9s2UwZqNkQhEaGGNBYMjgu5pl7w00esUEM4o0qWU952+zsZgirv7DewdF39XHx01Rhdu/egMR3+3y8w/05oyaZgkn36MnfdYHP3SmHjaY/zDfbx/GoCCym9XaSQSa5SQv2XygnuUv/7gywC8d+4Wz+QnONxqgKuLhIhN9rcbmAMTMxbMPHJImpv8yjc/hcgMTpzZxhKS+fqAjYGLGBnc/ZBD/ZouuoUH8VqKd0cTJ9IKIPURMAv04iSa1rd4WoHDh2yCHaUFwokuMNIxKN3uwV4LLAv5wAnipkP/qEnuw/KzoabEJjmj9SqdMybhiYTSNRf/QM+bRmuK0p5ebiAURd+GuoKhjVqOGc0ZTP+xvk9qN0OiOR3um9Q9whldAKZfE8x8fRNMg2Kmxt6TVeIpXYiNTFC9k2NF+qgbzjmTJB2FM5SUtkOyZgnTtzHCFA7a91K5ZRyjXrmICeQAQmAuL6L6Q4pTK0jXxD4YYV/dplE9TuucJFpQKEdhOAXRwANLgaGtQN/r6x1dsGZn+6R2mSS1MMYm8XLKYnNAklsEdkrViQlzB9fOUbmBUclYDbrcGM4w7PvMvQzRtEDaGq4/PApZ4DL9ZooZ5liDGNO17w1n/c0+Ik7Z//DCPb/Z4FhAGghK+5IssEkSA39xRFQYEJnkjw3xvlFhPGeRleBzCxd4LTrCtDXEMzMuX1vC+FyKseNx8vUZVD9k+g0Hq5/QOlel3ShTec3TjKoFKFkpf3T4AFIZTLljtsMai+U+r76nRqUcc7kzx1Z9Cj04g6+e/R1+5Ob3c9OsYSaS2q2UcMElPRGRKJBDGzMy8PcNyluSaMZg4fFdpv0Ro8xlr1MleNPDHioNvpMQ7EqsWLH0pR3yO1sYQYA4sszuB6YYPBnhvWWz+Ku3+Z+Xv8aHfvHnuP1XCvzpIepiFbdroIRFVoFzR2/Sz30eKN3l650zjCMXhML2cirliG6njOg594zoJxsHxIXNK4cVjKFg69lV/I/e5BPzb7FVb3Im2OHX/+Az+Ic5o0WL8EgGqUEyUxBsmJT2dSBEWtEdjZkoRiuCtKaQjsQ7MHRXO1CEcwbSFgS7md6gmQb5iUWSKZfRkok9UgS7injawYwlWVl32PGZCMZaye6MJOnEQxrOKaxYUL0J+Z5FNGORLGYUQxu7YxLN6dlg574SZvodCmhlO8c7SMjLNoPHlxmsaluTMXknWSHYIYSzlrbv3CkYzxnYoY7ussIM6ZiYYYrZGqDCmKLVRtgOolKBP5UvYK2tIGsBKtOLAWuvhxqNEb7PnZ88wfhIjt03sYYGha9IAbujiatZo0ClJkYqv/uF4E9d7+iCdXC3gVFy8bdsLE9x9OFd2mGAb2fUHW3ovNWbYzD2EJbE81NeOVyl8+I881d0Ek48pSgqErtjYEWCZEoRzlo0zmve9vioz2jRxAohmm5S2HpwGexqtIcz0AEVtdf2qV2rsPV9FUKnxCNnNvjs7AX+3qufJogU9ZsxWeDzm9ef4rNH3mTNafHZ2QvMeCOev7uOuetz+2+sE62n1F53qG5aDD465vRci2LZ4EilzWebrzMsfL7UepiXbh9BGIpibHPm+DZ/99xX+B9f/STxVp2XZ9Y54ezxHs/gt4ZHuPjaUcoZbH3UpbSnjbKpAtV3cLqTMAkD+p8f4do5m1fn4KszdE/YWGUYHcsQiUF5w6SyJQlntY6qmK5iiVW6715k98MFH334Ak+/fpaf/ut/xKfKl3jsN/8rzDnwpiKKyxXMAvr3Z7h7FslsgSUkw8zj5eFRLh3OIwRYlYyTCwfk0qDbruAd6iISn0gYpD6X9+YQlkTNJ0QlG0NIGtaYWhASKxv7vgHDzaoWeEqB8HPKFzz8Q/32V0LgTDAvo0WD3FfktQJvV9/q4wWBkILCVxP6p42Z1MlOTRNN6cJSvV0gLfEd8sKyTVYRxNMKDl3KuwbVO1qrJW3tiADIK4r2IxLRTOHAxRyYFM2MfDkH4Wq+2khQupWTlQy8boF/p8f4WIP+ulbpi0JLbd7mk5UOCuKGQVoX+PuK3NNi1OYljalWvoMBGL0RxfaujuICVJZSHB7qDaRh0v7EcXonwe0JarcKyreHcOUWHD/C7gebRPMSp2Vi5Nq2JB0wIkOzxWYEZqylL4nxF7SGP/8SitIdm2RKUtRztvs1PDsnkwaX2/MkuYmUBllq4XoZR6c6bP/eUTwJB+cExvKYojCovuxjxorOEylmW6/tRydqKIN7c45oVlMggl1FaT9jvGDfc8L7e5r3XpSa1G9I6jdMdr55jP/9x8qw51JqFaRVm9ERiQhdzvg77OU1zrrbPDBzl9cOVug8GuF4OfQ8RquK0RGDkpdx+eoyVjVl65lVhp/y2Bw22Lk+w4n7tjkcB1Sne0S5zT+6+DH8N3Wm4s3BNHu1Outf+BH8PYP6Uy06fh0j1OLW3hkFLRcjF+RlhZEK/Eda9Ic+nK+yfDFnuGwxuD9lbrGHldoULzVw+oqDc4amB1zJuPafllFeiSNHdnl3acj5wyVEKvi1L3+KLzz/cWbznM1Pg3NNe//y+0dYmwGiEAiv4NLh/NueZ0abVYxU0DzTpumOudKZw7/mYsYwPJnj+Blv3F7G2nNQUzmVmRHpNZ8LyTHeWpon6XuIyODofbu0/JruQByJ6Dra87efIW1B4RpETUNjnV2QLvjbFkaqAYBOT+C1Ff2TCqerWet5oHP8ollBZVPqYtIvKN0Zs/uBGsrUEWBFILEHOrcymhJkZYOsokmn0ZEUwy2g6+C95SMdSGYKiEyUgJnXJLln6CN3Sb9E3HZMUfGQjjbTJw394rTHOk7eivUMq3AFlTu6szFT/c9RgG1hdIao0ZgiDFFSYVariGrlXrJO8tBRNr/PQbqKqQsCZSgGqyZJtUb0sUfxDzS1tHZVo3XCBb1tNTJw2wa5D+W7mgef+wbYf4FI/nMvb9smPJqzdvyAQeyS5haFFICJY+UMQ5c0snH8jGY55NruLK4Po+MZS2tttncbNF90KO/kHDxiQSFweuJegm7haFW0KBRuB+aevkt8fJa0ZuF1C+yxJo7GMy7j5SOIQmmUci+m9WiVgxuzGIrJ21FhLIb8vXP/lv2sfm/OdD5eZaEyoO5H9GOP967eopv6bA4ahH8yg2+B3zIZrSpeeukUylYsnzzgRPWQD89e5Y8PT3Lj1VUqtwWFD+MlyWq5yxcO34XyC85++joHYYV8fsigExBNO0hv8hY0FP4dmzxQDEOXoJTQn/WIpnSuHsDBYZXgkkd5V3HwQW0Qn39e0D3uYUxFOE7OzouL7JwcU3k6QJ0rMMZowoGA4I6+wauPtOl0A8yVkKnGkCiz6OxXmVvsMU4crNkI180xDcmbhwsMrjVwDEhrYIQGxaiEKTUNgkwgvt5g7kbG3hM2Sc3FGJtUj/bY6dagAcl6jGEonK6DFSmdUNSUKAGNS+C1JUamRcBWpDsW665AOpP4+D0Nc1SmYDxnUTj6+KUEkzDUjMPHqpR3JO2zBllVYo0MvJbeLMPbQ3foPFBAZuDVI8LIIq0Z2ANB+ZZJdaPA30/onvE1T7+AtCy0VCGXmHFK+WZO+5E6pV1F6VAzt5QFma+30VaksBKJd6jXkYVrYqQ5ojdEdnsYczMYs1PIkou0jHup0UYQ0F93sGLB2u8MULaBOUqIl6tEUxZC6m4qK0/IqzXd1QXb+rsJpZAmeN1C/0wlmH7u34sY+y5f7+iClcwWTK2MaI9LZJnJQmPAIHb58NI1osLmq70zOH5GvRyxe1gjeN0nfmzMSnPA3RuzlO7qQjBcM5GOZOpFC3eoc9bSitZcSQsq2wW15zbA0nOCuKHfePZI4rZj0oZLWrZJm/ptl550sEJY/pqisGH3AwUPP3iLn158lp4sMWf36ORlvjE6TTsLeKJxm//z8rsxTYlr5NzpNzH/dZOZdoaQitGijRkLsuWE+4/s8Eh9C4DnO8e4dmmZyo7Ww8TTClmSPPeVh/AOoGbCm3dO8dG//AofPnqZf3LrY2zFM4hUEKwMyc/XKTzF/Lk9tu5O4bsZJ85uc81doLRhUz/v0Hwr4fBh+In/9kv8youf5MgXc8J5m2hW0HjaJ60Kgr6i8k2H8TxMv2QiFPROaxtMVlY8/tQVNocNnjx2mwcq2+ymNb62cQo7yHDMgv3DAOEV5InFaL+MNTAJdnSnI5TCb+mA1O4HY1QhKF3xKO8UHJyzydYjzAMXZcBSrc/tdhN/W+F0PQpf443bT2Ygwb/taJFoobVKhacNzIUH5U09w5SOIlyE+W9J3G5O/5iDFWrEsJnpPMPZb3UYnahhJtA/qouVLBWYkaU/p1NgJIqsbJBWDKhnLM72aHgRlzcrFCWJFZrUbhUEW2NEVjD7fEh4pEZ/3UZOxOLDExXqL9yFaoAodMybkSsdZ2fpBQmGTvTOPYPxkofbyfS/Yxgo38VwZghPzhDO2TpwYj8kX2wiZurEcyWqGylzX9lFdnsIKRH1Glbdx3ENrNuKpGJgDxWlfUV5Wy+h/NtdvV2MNLXB2WqT39nCBnL1F1H1f+5VW+ljGjZR6FIpR2SFyQcXb/BTzef4B3sf5+hMh27ss7/RpPGGJluuz7bZGVTxdk0912hpbYszAK+jI8MQevaQNKByR1F78S7YNtnyFP5BijQd4qZJ+e6Egx0W+C1BeVtSuAZGbmLF+o134z83+OV3f5GKEfFvu+f4a1Mv8u1wnfPDZWacER+vX+QX34sTJ6IAACAASURBVPpL1MoR/ZHP1//oHDPnc/y9kPGST/eUjmKStmJtsU3ZSvjy1lmi56Zxu4pmDoWvf1YjFTRfN3H7EmnqTiF5/5ifmXmWrbyKb2WUF0Z4dk57o8GDH77JG3eW6H5tgWoBvbNlertV/C2L6oakdmPM3Q9X+Jkf/yKn3V3EyMQaxxiZzdRbOcMVC2VA7XYyiYVXxPMG0ZxC5OC1Qd435vzuErUg4kRwQCxtUmlhmRJpSbZ2mpAL/CAhPAwo3bGwYjBSLe61xnrTllYFQTlmtF0laSp6x02yisK0JFlFZ0Re25shP/BRc4LyXUVnGfzjfbL9MtMvm1iRJJo2SBoCe6Co3imQlrbRRHMgHYmzNiKJbazIIp7WeO20bOitoiGo3cyIF8qEUya907rQKVP7LIXUOq9wRlcckU8os5Zk77DGoVVBWYrGm1rmYIUFFAoRaqV896RNXpoM1GMtwFVxjACm/yRk8OgiSL0g6q1rDdbbGq/yVozVGoFpMLivQXmUogIPpb5zf5qJJJ7VBIqDR22CXYW0oPCWUday9kYaYkI11TAAdyjx2inS1N1c6dohqjdApSlFGOI4NiQpRqWCKPngGbDxPSkHwDu8YIWRw2Bcxasm1EsRDzR2eCjY5Dc672VrXEci6F2YxksFg2OKYirjcBwQhS71XUXh6yOGKHR7G0+ZjBc0fiZcT7FaNl5PJ+kapRJiqcnhIx4ih/kXBnDxOuLEUbJZn+DyJMkkL/B7fYRjQ6PG48f6vBGu8PvPPIH0FH988ChpQ3LuXdf5eO0iANGrU1TuKEplwczrIaKQjFZLdE9M1NU+2A/0mfLGXO3MEL46jSF0q64EWDHMvpbhHsbkZYe8ZOLvhew/UeUjR66xk1e4nsyzHPQ419zkpL/Ho/dv8nM3fghzzyVcktSPdwien6ZxrcCMMg4etfnc332RkpESK5u/v/FpatfMiWpa0HrERK5E2Nd9wjlNHI0bgsF9GUiBOTaIpwV5ZmLbBQvBgFe6a2SFycGozHDgY+y7CFfSONqls1sj2LDwWtrTZyYSe5CRl23GcxZJU5G2A/AKxNhgfCSnujBktjLirlUn7npkAxdKBfbYnAzPFfmFOksXC5QhGayZGDlIE8wMtj8Iiyf3CFObfr+EMBVFYaA6DkLqSPn+UYusorDGUNnU3KrRskP/lD5GjtYkblsr6v3DSeLQRBtVaPkY1Wd9zbtvgGlCOI+2Jm1qzhTA7geaxDMTc7YJ9espqlZGODbRiRlEobCHOVnVYv9xzdzXG1vN6RJFQXi8obsvAcoQYJtI20Q6xkT5ntM9WaL/nhjzrkVrNcccmmRla2LtsYhWM7wd/d1KLW2QF6nE7QwRoxBV8hDlAHWogYf5rQ2MIMCoVsB1UL32d7sM/JnrHU0cXf61X8Iouywtd3hwagffSLk8mKcTlRjFLvGtCl5L39wi0w9RXi9w2ibWSM8r7KEOqqxu5QxWLe3HaihK24L6zRT/ZhtaHdSRJbY+riF+i8/oqHixfQDTTUScIPcPdYab76NKHpgGh09O4/7QPjs3ZjjzD+5CUfDW31umMTOk6iVs7TdY/l2b3jGL3IeFF2KkJdj6qINRaGxIFiiylRTTKShyAzWycFsmYjIwr96A5uUYc6RfteOjZYxUEU2b/MgvfIUn/Jt8ofsYDwWbnHZ3+UL3cXpZiW/vrdDfqkE5x/Iyql8PKO/kWvluwVP/xct0soDnn72frFZgVDJsJycZuojYRNT054k9F7etN3nRSg6GojQVYpqS8EYN6SuOnd4hK0xmS0N2RjX2OlXEXV+LU+cLnNmQZOhSvehQ2SooHEHpQIck7L87YHiswIgF3vqQKHSQscn6kQOOVw/5+o1TGJs+eUWi3AL70MYe6PlbaV+hTN3pAKR1zWyKpxXpbM70Up+ZYKS78MMaqhCQmNTesigdSC17WDInf1eBMvULIp4yiJuAgGBHdyJZoImypcOcpKqzKnXwg6B2K6d7wmK0rpFG5Rs2s68m2J1Yo3vut0jr2jYU7CgqmwlmmKEsg70nAqI57TooHUq6pwwduLJp0Lia6eOt0DmDSU1nRNZuTfyKlsBMFG5H00yv/rSLGJu4bZP4SEJQizENyWCvgn/Xurd99Ftav2UP9S/OHqRYhwOUbaE8W/OvxhFqHFK0/myBylXGs3zxe0YcfUcXrLV/8Ys05gtMQ/+IvQvTOrVkLcRxc0puyjD0EG9UsEcakVwEEpEKnIH2wsm1iGJkU7liU96W9NeNe9je2ddizD+5gHjkNGnDw79xSL6xCYB530mUZYAQiCglnyqTNhyUIUhqhs67O5pRf91G2lA60Fl+0rFoPVplvCIQGcSLBU7LJC9L7nvXBhdvLWHvO4gMzFhvJd9Ojs4qmqiaxRbulkN5S2+MhITBmqGNu8cMZs5nbH7K4A8+8+sctSX/qn+aTh7wf7zyFPaBTV6ReAtj4t0At2XSfHIPxyzY2JzB2bFZeCHn4JyNtBWFo1fdhQfJVIE1NPDauiB4Le0ayD29qFCm0AkzxyJUYaBCk8rikCh0MUyJ52ZEsY3aCKhfg9JhQTht0j+pPZ1eS4MOs0BhjwThfTG2l1MrR3x+9Tz//JUPYDgFpSBhKgjZvDaH3TUmiduaAmuPFGlN/2nGk5AI9CbLDiXjWa0b6p8qUJUce9/B6epCYaZKx3I1TJKGFpiWt3VGYH9dY7ardzQKu3AFSU3LYIxE//deTxJNTVhSmWav+89cxKjXkMMRKs0wjq8xPK3zHI1csf+YNl/Xr+puyb/VQW3vEb//LAeP2ExfzBFS0b7fJqkrjExv66YvaE5VXjIQhZZXWHFBYesUnKRm4IwkveMWItdH1awsdEe4PMK2Coa9ErafUf56gDPS22+7E2P2x8iSB5aOrC8CrSuzDiYoUctEmSYiSSmu3/ozz+b3umC9o4+ER+dazDVzXrhwgrU/UmQ/1eUHj77OXlrl1miaS9eXWf6KQXC7z9YnaxQlid3TBSleSSnVI8K+T2lD434P3qVvBqcLjWsZ5rOvYU41SWoe7t4Y2e4CYHgeFBIhBCKKidanCOf13yEtjfxQBpAJkg8PiIYu5S9bDE7XyQIdrFq/qhgvGNQum/Tuz3nygeu8/MIpDBPUakSeG2QDG3ukQXXSUUhXIXZ8Fl7R9EgrkoSzFofvlthdxWjJYOpyTnDlAPMDi/zY+Z/gE2uXOd9d5tbONPXXNZNpMFsQ9Ty9BTo7JM0tdvfrWgC4mpC+6VDaVYyXBIUvGc9kWsmsBPaOiTXWKvDxkmaGex29Uk/LEM8WiL6DNZhE3ivB8kyXtDDJCpPBfplyWzDzYotopUpas1BCz1LiKcH4ZEpQj6iVIurA2eYuj1dus5vVqV5wGJzKIUi4szmNkelC6vS1SDOcMzETzSQzU/TvB5PCU2QliJu6OEhbp/6IgU3llk67ERKsRDJa0sz3rAqrXx1h3j0ke++a7jwOJaN5EwwmIbNK+xPHEmVonpYydQqRkSlKN7sUcYxorKCWZzDClHi5qj1/ptYvKUvhtgRKKPKSiayVGD/wALtPiUkOooEVSWo3dcpTaVeHtEpbFyrQx7+kYZFgUbk1RkiH4YpJ94yJM9BzwKSu07llNWep0SfKbIaGz/p/dhujWSc5OkM45zBcdvDbAUaucDox0aKmhDg9TR0VkVbKCyEQlTLW/BzF289F4JN3W9+9AvAfud7RBWuzU+fWdgNzbGL//F2aSvBaf4W9cZXtjWkq1yyipgLKGBl4eybGuT6fPnoJqQT/z+Zp7H17srJVGAUEW/phLF1vwfGj9B+ZpfZGG/YPkWmKOTMDShKv1HRUd8XVA+dEzy6SukaANK8UcEWw/SkPCsFgzWT6YorfSjl42MeKFdNvpjjtiOj9Brthlbn79RwszS2kAntaEpxOWQp6vPbF+zEjgX+gsEd6W/Q2AtfdNwm2FaNVSCom6uF56ldhcNTi3zzzbvw9A9fVkU+FrS0v7lyINzOiUILB2ENlBphaZb77IYupV7XmJ6tCkemBq9PRxXO0qud+bhfsoT4SAfRPKvAkKhdkCzleOSVwU3wrY8Yfcb09g3AlhQcHT07d0wtJVxHNK71pcwuisUM48Hh4fZO6HXEtnud3X3kMvwzudEQ4chGRiSwVOIcWlbuSw4dNlKlw+3q2Jyabs/KWVuhbsWJY1+6E6GQCUoCpN3luXwtJwz8l51j9cl8nGlUCct9AOrqLTWYkYiahGFnULtlEs5BkgtKeRroIpR9u7/wGxcT+ghDEMz55SReC+tURrYfLGoXdEsy+njBe0P7HrObSP2pqv2YHvFaGNUppP1imsgFuX28vzbjQEg/0izILTO2DXC2x8wFASMyxQRZo4ao9UoQnFe87c43NYZOd/Tr+VY/s3AmsUUo45+AMCtKqxXjexG9L+ucmz01XIpQir3pYEp1dWKuifBcBiAmhFKmw1pbhDt+z6x1dsD5y5DqnZ3rc527zlDfkgf/77yCkoHzT5MhbGU5PM36s1ggzanDwLpu/dfpPMJH8w6c/g9s2qd5V5AGMVhWFp2i/p+DkT34bFQR0fuBBpv/kLvkdLSOwFubB95Alj+GKA6s6i88/TBms+oxXFW4b5p7rIvYOYW6aaKpJ5+GCZEqx96RDsK0LTeEItj5qU8xJSlbCxsYsxtBENTMYWyi/4KFjW3xi5k0qZsyL1bOIAjoPSdolydSLGsFcuAKvA5W7GeNPJJSeGnDnrQVO/OsxzrjEzgclo1MFwiko1yL+1olvsZvWeHrnFGHiYBiSbK/E7LcF8bQgfiJjfq1NdGmOvKS3k3bXJA8k6vgYZSjkZoA1NjBTrRtyRtrga2QCBhbSk8zN9am4CTffWqTVrLA43cMwpD7S7SrmntkhWZvi8JzDytk9XDNnOejxzBtnEI7kI2eu0HTGJNLiy9fO0nhda6EGHR8UVG+apDVTG3HXDNK6xOkZjJa1Rsgegh1KClfgtwqMQjFadEhmFaJro3w9GjAyHdFlj/X2DaWLtMgKVOAxPFah9bBCmQrlSNypCHW9zPzrkriuGJyUlG+ZWLHCa+e4232UZ8PsFObcNCiF2tqllGYka00dbfZAmawiJmRTyXDZ4fDdBdVrFt3Tji68XYHXkcRTFqMHXeIZnYLTuJ5ib/e0wdnXbJe0rkcRwyWdCRBs6ReKmejvY48Vw1Xt/3zx2bP4ewKxJrEiODjnkVW8SWisFhY3riaMFx3KuwWDVYuxY5L7GgxQckyM+rp+HkYptHuoQqKyFJIEAvt7VA309Y4uWD/cfJFX1X2sWH2uZhZ2PaHY9ynvSLy9MVndY/v9HvGiw/RyjwCQyuB/+sqnWXlWYo9i3NuHFDM1+q0ye+9XmG2b7KPn2H/MZfmPR98pVkdWiY7P6Nw632BwHKbPS9xOTut+H2VC4y3wDzOy6RK2OQtojczyvxMoUx8b6t/cANdh/6NLKEOx8nsWw2UXL59YLnKttB8vmVzIV/nby0/TKwLEsTFp36XxmkX9Ro7b6hMulxmuCSobenV9bKbFRqeJd2jQOxGg/lqLh8oD3rizhGlJfmj9ddbdfV7qH8U2C440O1x74QhT12C0LCi9p8V75ja53Jvj4PEIGVnYHW2SzmqK+xd3OX9hHVMKxH1D0tcqmBEkNQNlCLyWnmEpU9DpB4w9BxUULM90EULR6wUE533cgWT/w4sYOXiHgvlgwChzudqbZe3IIfc3dln3D7kRzfLc9lGKwqD37hT3tguWxNm1JwZl6B8H7xDcjoG0FM5Qq76dUUE0ZeG3ckrXW6QrDZyhQijB8JROxa5swHhBD8bNRAswk5rA7QJCkDZ9cl8w9YYgnhKEC1D0y5QOBON5k2hWUb1qUtnWVp32/S7Fo7NU7xRUrw1AKYxBRDEcYs7PMFp0SCtaM6eJGIq4rsGN5dsW4eMhpVLCYK8CwsRIjXvyDjMUrHy1jxEmZEt1hisu0hQYuea2Z2U9YC987Y2sX4GpV9skCxXaZ12kowi2BbVbGWnVJJ7WnWRlS062itBfNzAK6J52qV9P2X+XQ1HS6n+3rwWihW8QzeigEDPzaPTHqAlOCKWQw9F3vQ786esdXbAOigqfqV3kYrLAP775MbLQpnlZYKaSg1/Oed/iGzxhJvxw/WWeGZ8mlA6//oefYvVrKf6VPVStrN3p7SFppYLTNjFDQeshl8VvhvDiG/c+S5ZL7D/moiyIFnKWnpFULxwyPjVN6aAgnDM5fEzidGzmvi0YLWlOe/NKgpFK8sDCe/k6ea+PWa+R+8tUb0Dwwk3iT57UyOBwwugyNa3Ubdv8zehvUjvSY7o2Iv/DgMpWopOM0fMNkUPSEOw94eMMK7h2RndGMv2+fZ6cvc0fXH4Y77pHtJzx1nABgE5S4r1zt/h2e5WsmRMu2NgjKP1vdb5x/zQf+oFX+bUTv8PnvvizzLymOHgXPHB2k51Rjcotk9GjEeeWtnjl2hnMu1Day2ifdRkd16JBq28xVR/x6aVLfHHzQTqhj3q+wfLlnKSm5QJvx5Qh4MLOEp8/cR6A5w6OsRdXSKRFN/WxDMnCdJ+qG3O5WMTfcHC7EE9BvJTh7Fu6MxKaWmBGkzQZCV6nwN8eIRtl4qZN42rCzns8zKHeEicNrXkyJlqmtxcYtZsZ0VKZpKYzFbNAzyWdnnEv+XlwQh9nm1czhks28YzASGH+xRDr21dI33OW3nGHqTdc5JFp9h/0COf1IsA/1EQIDJCO0N/lSMLZxX0GicfACigcA6+D7iqPK8qbBuZhDxX4KCHw2gVZ2ZjYjXTSUlrXAapvJ1Ln751itKbDccubMPdNLXgdLWk00vzzExTQQZ98vg6UCOf1bGy4alPZnBxzpcLf1WybvScrjFc06qa8JSAvsObnkL2+Jj/E6f+vz/z/1/WOLlgfLyW4lsOLkUOSWVQvOgzXFMnHR/z40Vc55e5yNVngV3Y/zn5Y5TPzF5n9ttb47H9yVSefXBsTzXv0TilkNad0y6H5Vobx3Pl7n2MtL7H94SZ5oLc05dsW1W9cp/eRY3RPGaQNiTVSWCMDfx9a91sUvsJriQl/W7PSmZnCajbY/IFFjAJmXxgiqhXsUGKFkqyst47SAb8tCXYTZt6Ag4eb7B2VBLMCoRycoSSt2Ow9Cccf3OTzi6/xUn+du+M6d3s1EIrVSpftqI644zP9Ro79vOQFjrO51qDuRfzhrbMUxcT7pXRO3+ZnFH/jyWeYtQc86HhQy9h9r4U9FzLjjrjTbVD6vn0W3JirnVm8Q82X6p1wGB4vqM8PGY58fvZ9X+Wsu81v7H2AufKQS1dWqMUQzmhxae5D75TCWRkT9zzKVkHFjLk4XKLpjZn3hsy7fQKrzOnKPrYoOEwr3N46QnB3srSeEpDrbiWx9EMqbR0pbyaC0qHCOQj1Brfq4QwLxgsOVgzJJCdBFDDxyIOAqGnQuJbj7YXE8yVyXxfWPNDJzPbEND08ArWrgvJOQRaYGIUuLNKE3feU4L2PEs1KFp6XWJc3GH7oNHkJ7JHu/nSAre6ypKUTboJazKVrywhHv7SaFwVetyCumzTemhBFHBtZ9fVRDAcMGC1Y5IEgaSryirYHGZkunllZENxVeB2FMyrY+2CTtKLlHklDMDgWkHuC0qyP14ppXOhQu2bTeUCjaxp7OaXbA5RrEi4H9Ncthg8lIBTuFY9gP0e2OxjVCqIcYDqOPhLufNdKwH9wvaML1hdHFb7WOceVzhy9O3XcKiw9tsM/PfHbVIyCv3P781z/6jGieUl5rc9vDp8iP23SPa19W7XbkrTmMFy2sEKFs6e3Y+5XXgHAePA0+081GBzTN2zljqY5Vq722PqJE4xXC5SfYvYsgm2dZNw/rVXXSL2V8Q8d3F5BXjJIVhtYw5TGjRx7UJBXHHqn5vE6BWlVP8zKUDhDcLs5RqJjxRvXLQZnBElTMPWmTnlWlkDWTP7ywuuMCo+rvVkO+2WKwuDk/XdpOmM2x03ctsAeFrTvd8HI2L4zxY5XsLrQIcxsOpsBSVMvHKyexZf+yYeIZgQ/9XP/K7e+71/yG/1F/l3rPp6q3aBuhzy7c5yr2ws4uzZmGaxQEM4LrJmIlXqPLz322wDczUfcGTaI/80cVU9v84I9eY/GOXO6hWflbI4dHpjd5cJgmV7qc6a6x2FaJiqm8c2MpjvmW911rrVn8A4hntGD83glBakfZL+jcTE6tUh3LYVrkDY8kvUygyMaXe32dAfltg3Kd/UwPq3o6pUFeq6YxAZu10Y62kc3WAeENohbod4Cz7xWUP3ym1AUtH74EYZHBNLRqeLlbUn12pBoOaBwBGp5gWhKI2bsoY4Jy4PJDTzpMNO6orhZhaDAajssPF9QvrCFGg7xj68gHfM7M6tcgimwRilC2YQLtrYDHQjEnmZ0Na4X+LsaGyNdLeOwOxFZqYqRGkQzennTO2ngHeqfQVoGqu4TzXuEc5qz1T5rYQ9LGJl2cAzuyzCdAvdiiZk3Mkov3YKVRZLFKvYLbyHjmCL8i9ScP/f6H974NML3KJcSFk8csvxoj++fvkBb+rwaT3Nlfxb18IiHF3Z5/doawXWHeLlg9iV93k8rBv11B7erqN6EqfN9isnQ0Hj4Pq79J1U9aNwTjI4WeIcm3kFC+9EmozMJ5AbWoY3X0g/R8HSmYWaJgVlLKFKTbuKy+M0MZ6iwB6nG7XYzct9C2gJnJCk8nd4ilEIJgSgUWdlEWRoYKC0BTkH5jol/s00+W2XnqRJGX/IrL32CxtSIMHZYne6y1a4DcLk/z407c0z1FVsfc1g8t8MRN+J6a5qw51P88zmiYyY8HFGthLh2zt7dJkZmMlov+IW9R/hH86/zU7UdfqqmX5mf2D3H6I0ppjYgbmoKa++04j1PXuLdtdt8uHSVlxOb32o/xTObJ8nequL5Grvi7wuSukHcFGQrCaPYpRWXMQ8cXuyfYvn0Pp9efJNlp0MsbQIj4Uuth3l+53F6u1WC2xbxkiIvS0QjpVRKCQ8C3I7GAiP00a6yk0/CQ3OGay5ZIO4RDnJfH50a1wrNWZ+8JKwIPXQeSNyBZLjq6WNrobVwhacIdhSNa7F+ibx+FVUUyMfO4vUkzpta2mDGEqOQtB+p0npXQfm2idcpYY/VPX5V4ehOrfAmwaMelHZ0EZMdHYAazpqUpUSUy1AojCgnnfImthyBtd9ndP8c7fssnJ7uxv1WruGSBbgtfXyTroU1zhBpTl7VjmxRQHVDajR4TydDj2dNRoua9JFWdYevDMgdxe5TeiCvLLBbAv+SzdzLY+xdPWznoI1jGhQTrpbKvrdHwne0cHTlH/4yXhyQLKXUJyv6zx+9wGeq58mUyWbe5A/bD/Hct89Qv6SLghXp1t3rS5yevovMSSdjhBn5lM/tz7o4PYP8vjFrsx1uvrnEyX81pPVwlfaTGfaBzcK3tMCwcxaUrc2x+cTThiMhMQg2LEr7SttEFJS3JEah6Q869AGMyZ/KEkRNU+fdjfSxNa2ajBaNe34xJSArQ3xfhDCgVh0TpzYzlTHHqi36mceFrWXMGz7JQk51RvOt2p0yqjB41/ENZt0Rf/Tm/QS1GKUgSWzUvoe/r5nuaUMiZ1N+5tFn+fnmLfoyomb4FEqyXYSsWmV+d1Tjly5+hsBLaXfLyNBibrnLmeY+3aTEhaurOAcTkueCnmuJsYk1EzPbGBLYKdv9GuY3avhtSf0nt/jIrKaW2qKgn5e4OFjktVurlGsR46EHLVd79qo5SgpEaGL3NfUgL00QJy1JOGOQT2ZO9lCLM6NZQTyXU96wqN/QISBZeaKVmxS7YHsS82VPcNZzBtVN7S0dzZvYY0V5N6NwtIYqnDbJqoLFr2nywehEDa+l/0flgUU24atLS/994azBaEV/pnQ1sVOZCqtn4gx0kfAOJ+Egk1AJM4XKZop38wBlWyRrTZz9MdFKRYejGOC1FVaiue5GphisWbg9Rekgw8gluW8xWLVI64LylrYWGTnULrQQcULRrDI+UsY/SEDp8cDwiE9S04npdl/fF8G2oH4jI3h9k3xvX9+QTzyIEWXIC5f1vVwqIacrPH3nf/kL4eh/7Fp+WrL/EUVw3WHYr/OjH/0mH628yUY2DcBhXuWx6h2ez+6jdCgp3xnTeqSigfyjQjO+c0VWsUFZmIFN3LTx9wzGD8R84vhVnv76Ixz/Ukg8WyKeFvh3HGo3JFmgo7zyeo5ZySgyA6Nna03S0MQ/ELg9xXBNv6HrV8HrFYznLPy2xpYoQ4v+rEgiUomZfadbUKYgDfSbN/e1XaJ3RjFzsoWROAihCGOXZK/EHTOA4+BZGX4pISx5GH6OZRaU7IwwSDENydnKLi+0jzI/36NkZyS5xX5iI03F+EiOtzNBimQG/+LKU7y8cIRztTvMWX0uRcuc9e/yVyu73EmnmamM4VdnOPyMwG4kpLnJpfY8AG49JvVsLLuAnguu1MSCqT6zpSEnywdcv/IUgQ3hnMHBxRWu1eZhYGFOJxQtF+VLFlfahImjC9RMgmkoityA0MTbNykcTVrwWrq7Gi3o448Vau9fWhP/L3tvFmtpdt33/fbe33zmc+d769ZcPVTPzWZzEkVRpGJLgpTYGqIkQGIb9kucPASBAgTIQ14SIA+BEQQIDDgyEhiOHdmQQySKhpCiSJFsskk2u5s91Dzf+d5zz/zNe+dhnSpKgvlK9gP3SwFd1XVvnft9a6/1X/+BtAvJLjQfGPrvT9BFzc7n2nipxHfVAeQ9wXRw4rYx3XZ0bstSo4rEsz0YVdShgNxlQ5EvKYqW4+Gv9inbglcWrYhgIhhU8+4U5xvmGzFZTzPfED5UvmxxnkP3cmxhxNIlV3TuiJf8425Qorwc83WfOl7Hm9ecXA3xLgbM18TJon2vIt6bUSzFZEs+szVFOHJ00DPpAAAAIABJREFUPxjhfEPd8LG+SHqW3stQlUXnFVy/S12UmH4Xe2aJrKuZbiXER5ZgXNPYL4iPFLOtgGKzRE88kkNH+Mffo3rcvyglOkVP47fb1OMxqtWkXmr9jIf148581SMYKfSnTrnaO+Vvtd9i06vo64zfH73G7996hSwNWHpHAY69z7QJR47mToEuLP7OgHKjB3j4pxl4mtg68r87o84Cvvl/vMrFr4/I1hIOPu5jPUfzIYRDwZzyngPjntjcoqCOpP1/zLWynmP9OzXJIxEjVxHo0jwZqbq3S3QpzOVgYkXkOl5s2+YGf+5z+qxi8HrJ8tqYaRailEMBnleTxTVUmvt3V4iXUqqbLfAgjEqMdlxqH/O5tZtcn67xreOLrCVjNpIxee1x83SFahxALMnPZdsSHWv8SQAu4M3dBjcviNB6u33K/Xmf//HaL/GZrbtcaJ/w9vlNkrURvUbKZnNEwyvo+CnHeZNBnmCdYt4P2D9tUaY+O8ddZu2A73/vCsmeJjyVuPXGI011EtK+55ivJ6Qvz+m05hSVRxSUzIKachLgdXJ4IJFodSxjCpV0nboU0N36i2LfdZRrBcpYRs2A5R8ItnL0WofwVBGeyEVgPTC5bBeVhWxZNJxVDGWmCRajnrISBVZHQpJ8bAGjrPCe4oEVJw9Pkp/N7gl2tUcVJYwuQx077GYJlSbspyRRQWU19Y2eGAZe0AQTnoRV4IQu0jgU4D19ygcnOGnntqX/7T3c6RDWVoBYmOlTeTZVUaHSAj0vCO6luEZMvt7C+or4XopaX8Uttxk83WS2IVQGXQpD33mSlD3dNJRtS3wn4MxXZ6hvvYNpt3FnN8Eo0k0xZUxuD7DzOTqKUElMHf50S8ZHumCdPufwL05Jhwm6N2C/bvNymKOZ8Y3jS5SFB4ch1oOyoWnuWfxZTXjnCKqaanuZsu2jS4cuKqooYnw2ov5/ItZvFQQnI7KNhNEFH38CoCg6MLUe6aqi7FcCyM4NZV/o3tGeh6pFizjfkHVy4+6EfCVhui3k1OllS/zQY+XdiirRxHsFRkHRCfDSGjMrqRs+urCMLmnKiymkHsePuk+A2tb6BKUc3ol4Zb32Sx/wnb94lrptoVlSFB5+c04/mLHqjykTw57pMKsCTvOEaRFwOmqgmyW2MJhGiVmyzBoRZq45+ycVo/M+2f4y6VM5w3HCP3zpz/k7a9/ktXDAZ//J72I3HButGb+++S6/3HyPv0gv8yBf4ka+yrUH6zD1oYbODUPehfyZlONHXfofKsKRpYxly+cM9K+JjnN2vuK5zQO2kiF3JstoHEXT0FoasXfaRiFbO5NB/654NHnTkuHTDSY94VNVDSk6TvlU7RoCS9nwePg3WhRdS+89efGnV3PUzKNxX0a+6VkJGEkOFsGkTXBa0xxXmHlJ0QtJ+5q8L19HGOyOKlFEQ8dsI2B4RegIzZUu46eF2pLsiyhZ7QXkfUc9ajLaytCPIgIH4dgyuqwxhZA7rZMx0mUwPice7t4c+tcr4kczzPEIN53B6jLzyz2cElG2P5eRL99oEz4YoCY59XKH6cUm81Xhyk22V/AyR/tOSnxSM3hePXFZbT4qsIFGLzIM/Kli49s53ocPqLVBtVuMnu0QTCQFfXzWI7lp0d0O1JZqpY03+hkP68eepXcU3G1w+vMZkVdyWLUY2SFz5zDKUuUejX2N8xxlILdXcusUqhrXbZH3Q5QFXdbyQzeSCFyqhTar16RMxL+8ShSzLbGQBUXZWtjQWoXtlVBq/IFHdCK41OQi+CP581Ur5OSFkDqpcYEl2vVZfavEBgqTWqbnYqpQHlJ/UqKzgnwtYXjJJ1uxMAgIJpqiV+NNDcFQoa735MZ9sWBpfcib989RNyzOs5Ab6kpT1oZvHFzk7eAMO6cdoqDk5zbvMC4imkHBJC5IZwFUCpyiKgyN+94i6kx8o7JVi7OKj5+7zy8k13k5DPnd/Z/Dn8L0nCPySkpn+N17v8HDYZdmlHP8/TXcWgmepXVHsBb30oTgvRbRorMZXRHPrPgIkj1H2lfw+oi1KCfxCq4P1ziaNFhtT7nSP+b68SrFSURnR5Kq/WklWOC0IFtPmGzrJ9FawUhwnaynmQQat1wwuajBKrH1bcDw+QoTWPSBprFrma9pdC6FoWgrgpGIuXUtAav5slgVV4ladDpQNRxVp6JuaA66AnjXjYr8UoUueoCMpXXAYhtowUHdqWHm0X6kCMaCl1UNcWvwUocpoYxlS4kTX7HGfk3jujgjlGeXyXubBMMCVcPokoczkBxYsnXF+tdPUFkhFslZgTe3Ap4pIduaArzTOWZe0rnRIZjWhKNaAjiGOafPNCjajnN/OMd77y6qkWCWz/HoV9bJlh3R8V+KozcGihJ7ZZs68VHpz2K+fuyZrymKs44Xzu4Sm5JHxRL/w9Em9+ZLjPIIRj5LPyypI03eXoQthB4u6lD2Y6pY409r/L0htpMwvBIzfAZ6HwJKMV/WizBOIefpQkzygrEj70N46GFDR5XIzaYq6aqCkaL/njiXth7lAsIm8v+Seay8U1HHgleVDfnVlA5TOrKVEOdpsr4Aw95MifG/hvDY0LoH8UnFbN0w/+KU7faUg2ELlCNYnWNvNQkHiuLjUwJTU9SG3WGb5daMT6zcw1c1W8kIi6KympEXcVq0UI8ivExeRn/qOHzFo2pamuclifk3Vr7PU77iT+c+B3mLq79xjTdvnedo1uD3Dj4N9xPqyGEunnLp0/d5OOwyHSSEp47jT1RE77coehZlNVXiMJnCm8vodfSpmouX95mXPs4pdqcdrnSP2GyMqJzmw6M1JsOEpbcM/Q9meMOUqisSnaoTcviaT9l0rLzlSFc0dSzM7zoWsW+cFOSrDu9ehD+B8SVhraqHEfGBYnRZUXQsy2/L9jjvKIqOFK1oIB2vqh2zM5Hgkmdl5Iwvj6hGMeGej/fSkN999k/5bHyPL3zpv0TZReEbOkafy7CngWBXjRJyQ+8H/hMH0azvEQ4U/kSWMUVTi998oEgOrciGgMOfXyVbUqx/JyO5N6ZaiqkjRXxi6bw3BKNohR5qngnB1JfXN96bPSkyZSvAm5dQVtT9Bt2bKbqy2IXzSLoeUSaKs19O8R+eQL9Lfn6Z4xciih5EJ8I/M4WjcXcMnoEz6+i0JJgX1PPZT7wO/OXzkS5Yr/z6+0RNn+eauzzI+3zl8GlmRcByMuPg5jJn/7h+wqcxhTwMo6tdkoMCb1LQnBSYkwlunuL6TfKeonkfvMw+KVb5kqNsW3Su8Cf6CY4QHQt3p1wuUYFFnQRUicNGlmTPI5hYRuc9OrdrPKBOHHViWXrLUPuKMtFCGE2lE3AL3KJuKnTpwSLmzRkoz2aEH8ZEJ9LVJTtzGncrbl3q8Wg1YGl5woXuCe8frFMFji/8B9+laXIepD0GeYMb41WOJw02tkZoZbkxXeWdh2eoS43ZC2meLMDnJYvJxRq6/doRtVU4pwj9in9054v8XpjxOxtv8p+tfwXrNH939+9wetLCHARUKyXnzx6Rlj4f3t5E5QZdKrzfOiSexfTPnbCz2yftOJRxhHFJq5HSCnNGWcTRtMHVlQNebO1wWLb4cLjOveM+SVQwPmiiKtG5VU0fXUqn4oxieCXEKejcEOvjvCe4lC6huDrH1xbPqyl3W4RDWWJ4U0XjhidbxTUjEfZHWjqN0xKUmBQ+KSjrCemyR72Q1OTPpvzqM+8xKBrc+L+eZfCipZiGrHoTfvuHf49kV8TwAMOfz7C5weSKWjvcIGT7q5bGvRHOKKbnm08smP2ZI13SZEviGpIcWoqmYrItOFN44lh5pyTYk0IhFBgIRjXFaoNwb4x3IFtL5Rz5GYmN94cZ2XJE1jdEwxqTa4YfW0PXjsajFD0vUIFH0Y+oA033dkHZ8Che2iQYlSjnaO2Ia2nn2gT39gd4mxvYXpv6/esAmF4PVvo472cY1o89ga7wtKZGUVnDzqDDVn/Eh4/WWf+WIt6doiqLDTyy9URSR1KHf5oxvtLClI7W8Viy16xj5Z0cZxRVrOlfLxk8Gy5imjT+SFG2HVUimz1dQ5U4GQUPBEcSW2C1YKJrih6MLyYL3++aaN/DaUfe1ovsOUXZQDhAc4c/s/h7FdmSjFFmwQ/qdmbUk5ho6Gjs5ZIvNxhy8b+6hnnuaa7//T4nXg/nOf6jL36T/7j3bf758HX25h0G85gy81jtTXhzdJ6GKfjBvW3cOAArK+75lqXxUOM/EP/u8WVIlGNWBOR3W2LQZ+Bv/84f83L0iH968nM8E+9RZB5RM8d0UrRypKXPvBAem+nlbC0P2TttU5WGoY7Z3joh8Qs2kjEtL2NWhXi65tzKgIvhId+fnecPd59j98ESeI64nTEaiqWvKoWzZo1CpSXG0xy/0mF0RcY45SDrShed7DnSdSXYXGyZ7LaIZuqJtcyZrxZS9IB0OSIYipWLP63l0vAVyaEjXTLUoSHviUg6XXesvnjAf779FtM64muPLjP+dEXUz1jvjvlvb/wa0zeXCTLp/tN1i387Jj9TyEXz0GP1ByXetKRqBky3I3GNNRBMHNMzmiqBYCj2RsG4ZHI2Yr6hSB44urcyqsSQneuS9T3qQBGfVOja4U8KyU/0PPA9yo0uyjrUwt+9SjTpimw927mlbCi6NzJUuaD0jGaYyCOqHLq2lE2P5KvvY2czzNOXcbpNnMmf5dWrDJ5q4Qx03pN30W2tofICNZ3/9df0J3o+0gXramOfN7Kr/ODojBj1Kbhze43Vb3jEhwUnL3fp3krx3r9LpM9giojo9hHp5RXSZc3aGyPcLKV+8TI6q9CVJW/6BKOKsulhPQFvdQnB0OHPBHR3HlALFqBGhrJlCUaGeCF5MLkAqcFI1va6huSRYXa+ouhq+u8qomG9oFQYIR3m8gLl/R/5agVjR7asOL3fo2Nhclaz9ws+0d4ZOrc2CWaW8VkPtTbHTn1UWOOrmn89epV3hmf4eP8+R80W367OsXNnmR1/ibiX4pwiONHoXNH77D57+z2yeUAwFl1bHTmOri3jTxWNgaJ7q+LoJY9vDC7x7eEFLjRO+Aedh3z5/EPe3dnEGMtWZ0Q/nLMz6zAdxXh+TeSVVLsJtlPRXZaidnt/hbtmCaUcReaTNHO+528T+RXHoya+X+O3c1qNjMksws08TKppPNKUDYmcUnXN0es9pmdlu5csXD+zvoy040tQ9wu8gwAzDekOpCA8zhSrIxGw14HEfdkFvjnZ8rGBjHKPyZ1OwpopOrD18h4X2idM64hfbr3Lf/P6NX5vtM61dIMfDjfZ+d4myXARBuJDdKzJuw4z9AhPNPGxZF4WF306d0vKRFG0pGA5DY1duyCyOry0JlsJ8FPL2neF31clhqphqAOhwnTfOkFNZriyRMUxGBnrXODj/AWWtPil/d4JzfsRs+0Gg2dDurdKTFah7+3hzqxRd3o4T+PNS7KVSDbcMxnvbDOk6HjkZ0KGTycEY4k7i/dLvK1NbK+Nsla6vlYD9n+SVeCvno80cfS5f/Dfo+MI5aB9r+LBrzl6G2Oywqe83WLjjZrGvamESC63Kboh93/VJzrStO/KwxEfFqjKUvQCKRoO6lALYXBTmNAmg3hQkS55jC8onBGcqmzI6OEMtB44ksOKvCMZdnYRNumMjFvTSzXeWLP8tqN1f04de6QrgcRHZZJO4oyMM4/xl2zZEm2JOyR/3kMX0ur70wXomwhTeXK5Jlqb8fz6Hh8crqOU442P/1OaOqJ0Nf/po5/na3cu0+/MaAQFe187Qx04OrfATx2TM0KqNalsx6pYMflYhvco5NwfZWQrAaPzhsnlClVqXGhRucb5lnA5ZXtpSGgqru+u4XYj7HLJxvopRjkeXVvDn8rogpMlhDdfbPNiGUPVeoZWjir3CO+GhKfCyC468vtYxdp3He1rQ0ZXu5w+pakTh5lLRFey7+TF98QfrEqkkD2WwPgTRzR0RMclg6shszMOb6bwZotA0kJcSlUt2YTlSkm4E9C7JqGx2aen2FpTzT1++aX3+NXe2zwslnhvdoY//fKrMmLuim2QLGYgX61QlaLxwBAOJTYuOnH0f3CKqmuoamwzpuqETzzxZ+uaoq3o3q5pPEpJ1yOKheGjN7cEwwJvMENlOe50hKtrdL+HazdQw4mEpPY7VN0EXVnM3gAXBbimmPDZwOAdDJ84kJh2m+qFi4zPR+IQsimfgbLQ3HH0fjgWr/hzbU6viK++9cUddeVL13FZLl9/NAatUFFEpWu+vPOPf0Yc/bcdZ1iA3Y69nzPgaibTmKXulMOkwf4nDN1uBy9tM7qoSbdq9MIjaLaphWA497ChWjCYFcGwZHQpYHQFsA5/Iiz1+YZP0XY4z2F9CQvQlfBroiMZV5wR8PzkeRHg+hPxi6pDiB8ZejdqokFJvhRSxaJ/c0oKmr+wNjE5TM5LGjEKtnojJnlImYqNiEOu/McPVh2B18/IM5/DeQujLf/1s3/M3NXcKTL+i1u/zd0PNlC14vR2wsFyzS/86g/52rWnyIYhbiCbNZOL3XG6JpIRdRwQHypGlyLqUD7n9k2P1kPZqFaxomh7jJ5KOAgqJvstwkND0bOEjYLIqzieNtCFoujLOCw/qwV5UoHzHC6ydBsZszTABDX5xYxs7mHmmvBYs/I9wRR16Th6vUe6+lh+snB8sAsdYCSE0bIpOrg6hHRTvOBVreFUaAdFRzy+dLEQDDct/kSLAHnHgVJ4c3GEGJ/XzM9WPLd2xO2jZX7rY2/xevMOb0yv8G9uv0g6idC+Q1nheKUrcoHkZwootRgeetK9NXcrGu8f4JKI0fN9ksMCf3+Cp6F394hie4nJdkKyL13kdDumbOgnWFi64gnEMZr8yOGz3ZRQiPEMV5SoJMJpjc4qzGgGRqOsg1kGvofZORLpjFKo156nDA13/72IeqkkuRmKwNoHfya2NcVKLLyyRNN6WNN6JB1n990TVKeNigrsyUACV5TGzVOq0U83hOIjXbCyT07RO2L5onPFxcv7ZJXH4dtrNA8X5mxtKBPBKMwdQ7a6EPrOJT3XhooylhAFU0C6GjDbUPhjiA+dOEr2LMouXpASXADpRr0QxC50iU0NTc10S4SwdWLRpYZMcKJgJOx6VTm8mXC2nNIUTUXWF4Dfnwn3x59CeOqRrVgG85jBXod2oggHsjiYr4kDpjWw+cWHnG8O+M7eWT69cgetHIUz/J/jq/xP73ye8L2EViobzLIJ/tUZX3/jOfrvKfrX5uS9QKx2FQwv+4SnkHchPNUUHfleZLXu6NxKKds+6bKHso5gBJ1rhuphj6AjHQYaspOYu4cJVApjYftPACqqUDoIfV9GoTqG6UXHs8sHxKbk7aNNhrf6+FNFMBYhsa4hXdLSeS7GJ6z4jMlnKIRHVcvlYH0IJpCugM4UjR1Nsi8M7nTZIzyFxiPF5IKjPpuhDkPCE0X/mmyTJ4E4rc62FgRO45gWIV84f4NL0SH/8vB1TrIGrThHKcgPAqKBI1uRAmjXcvRxIPSJpgSe1r5itupRhxsEo4rWrSk6L6k7Mbqosa0GuqhZ+/aE+ZmEg9c8Kaqlov+ho3lvKpdIWuDyAhWFYC0s92UMa8YQBVBWqJMhuiwhCLBLXep2iJkVqN1j6pMBptcR2+92wMNfCqg7FWawSDGv5cI0mXSspjDkLenwGrsFRdcXXatSkGYQ+OilvkR+HRxilpfgY1fh+1/66RQEPuIFK4kLnvv8Na40D/nK3tMMf3+LbElRb9RMXy7xH4Qku7J9KTqCCW1+VRJuD19rcfwSRAMPfyJjRDWWFbENHf54IZ3xwJ9qnJZuy/rCv3FJjRn76FxRtGUUMYUjGCvKDmz8hWW+oqgiKTRL7wse4JSA867pPRHEli3hx3gzET8bJZ2DqhS+sajA0tizFC21WNtLIMWnPvs+Ta/gjd3zRH7Fl3efZpYFKPUi870myUODPxY8rYoU8y2wd1usfwe6392lXm4vvr6RTVQh/w4vVczXZU1ZNjTRwBGOa2xgOL3i488d8YljdF4vpEPSqehcExwbnOcoejXBRLP+nRp/WlElBhfzxE45HDnmoULViu/cOU/v6xHRyLE9ralD2VQ6DfNV/WTMsx6LxYaM6SjprpyRDnG2oQgmUrQkDUm62GhQET+aEB35ZKsxRy/5FEs13oOI3ofQf2fA5EqH4RUjP++Jw5+Ip1T/zCnP9/a4N+vzrb3zNMOCh7t9tGd54ewu7+w3OP10BcMAf6qI342IThxFW2gJNhTlgz+Xn0HjboaezHFRiI09qlaALqxoSZd95qvy+VUty8bXofvmroieq0q0fp2WjITt5iIMQqHHqRSw+nGit6F4aoNsKcCkFt/XePUSZrmLGs9Aa+78pkG3MrxdoXY4I8+criAeiDZx/xNmoVfUWD8SfC2z2NBHrfZQjw5AG7A1yvOYv36Rqsp+wlXgr56PdMEa3evyZt1DX3BMspDqb4xZac040xxya7jMwaxPdOIRHAr/x08tu7/YQVWQrTqq1ZJZ7NG6q2k9qOWhijW6kHHPeYJzPDaHUzVPjNzKtZpiRZHc92k9tFhPwNqiA6vfFX+roiVC1OZuRR17qFKkN2UnYHzOI++y0L5BY8/iZY461JRNRTRwVDPF66v3uRGtctg9y+nLNX4nxw8qLvWGVNbwZ//vq9Sh4x/+2h/xv3zplwmHgp/5TQGZZ2cd5VBLWMSRmNH5s5JqpS0ZhotsxmAoL9bkgqT5BEPpckwuARHWV8zXfPypw59LtNTkaoGaebioBt+R3Dc4BbOzlnjPEzuVWDPdDKkDsZix/sLCeOowOfgDTXQzxilH3pJROj7IGF+Ima3rhR+7wps7TK6EMd9TxCc11leky4uIsXVwiJuBKqGx556Im8PDFDXPqFYaOLNw/CwV4VDRvT7BJgHpksafSDEcXQIvVWRbJb++cYvff/tjdN4K0aVjZkG9YPnYK7e4N+qLh31uiE40K+9WWCNjYbZsqGOBDrrXJzhPYwMDnmZ+ZZmyqWns5oSHY1zgMbvQYrolrPZ4X7H8NjR2c1wjRqU5bjKBzTUJP9Fa+E9VjR5nuCwHW+PSDIxh/DevCjCfOapEUzYD7GZI9/0h9c4uyg/A20Dth+gCqgTqUC7k/oc5/ijn+JUW4alEhkXHBVVimK/6tG/JFlA9OsClGXY+xzz3NIe//TT+DKJ79qdZEj7aBSs+0GSrmh8ebpBmPq+ffcC88pmWIcNpDL6lDiDrieJ8vmaomkIXaD6AWe0Tnip610uqhma+LEnGJpdx0BSCK2XLIplIV+Sl8WeQnwQQOMqWxHCJbhDCgSM+Lija/hNP7b1P+ejSp3tL5ChOC8HUpALEmly2RMMrhjqE5gPBYs7/4j3ORyf80Y3nsM84wn7KxZUTpkWIc4qb/+sz+Mtw+XP3+NcPX6V3DbrXROCbbjTY+zmPcqmi7CrMVONPxUZY5xYzkZvQtMQRoo7k+8+Xa3SvwNyLqGohYPpT8HIp2K1HonMcXA1Qfonq56ijkOZDGdusB63bi8BSX6LcnRGXjMfF2Wm5zZ2G5EAKbNlUNHct4bAkWwll2ZHLnwtPBeytfAlANelC96bE42p8Qbq8eF9T9BzhQJGu/uj363aAqmOqxKAqR3amIDjwaT6y1InP8HJIuiLAedWQf68zYCaGf/XDV9n6Qw+nLervHfJs74CuP+fLD5+m/lofdc4Snoq/VtGQ5UXeVqRrFufBxrdqzKzARt6CmBnLCGvB+prZJWHEB8OKtTdz6shDOYfOa3RePcn/A6g/vIl3/qwQQotSWOZlicukaOlOi+zl80y2Df5U2P7BsCJ6OKLuxDjf4J3bZvDpLbA11pelAxZ6137k8OC0onNHrJCi3QlVL8Hklva9DD3L4WiAK0rsfE79+VdJOx7dm4XYJ52MfgqV4EfnI12w+NiY7ZWa0moCryarPTpBxqiIeHXrEe+YTZwJsEa6pca+ZbYpxcsacWNMV+D4JR9dsIguV9Qj2RzlXcXkvLxkeW/RHUhQL8GpoegKeFxFsqGyBlo7YumhS0dyZBmf15RtUeiPaomd91JH6y7i2BgoioYm72q8qRQ8G8Do4znPBinfGFxCKYdt1CgF1+5vwMSjc83QPq4IpooP3jmHi2qefn8M795ExRHTjz9HFTtMUlEXmtrK99+6Ky+V8w1VM5CbeP4YCwIX19QTn/hUPYkrD6aS6adqmK/5ZH3pdMK7EY0dETBnfSjblt4Hi42gEp/4omvxF5FfqpLikxxXqMqhHMzWfIqOogpguqVxOsSfPSZ0Cq5YtGUU9+aOcF+8p6KTkrLlcfSSh/MdaEfRk9zJ3GqCkaQXde6WBA8GFFs9/HHJ5HwEtkaXiviwEPqKL9SFYGqJhtC7VgmVoe1hCsPRi4bf/J2v4aua3/vOZ0nu+DR3HNMtiI40/WuPE2wgb2uKrqJ1TxGe2id5jXXs4zyNSWvytk80qKliQ9HWhKMaG2i8WSlR9QuxtY18DIBzqE4bfX6LKvLEdWFeoAYjqv0DlOehO23s9jpF1yMYLWLO5pZoZwx1Tb4SMbzoM7raQLdyzF6EyaD1ALo3xeeraniYeYWeZniHI1wSUTdD0lXpLhs3B7B3SD2WfELz3NOMtgLBOA9zsVp21U+hEPzofKQL1nwYseN8nFW4WvPxtQdshkPeKrb5we4ZqttNuouti7CHJRjUmwsvJ1sSDk7tyfi0e07x+U+8xw/+txeYbGuyFRkrqsRRLkuqsdyUGm9xyysL4ys1wVDTvgPezOKlFdbTxIc1TgdUschRqqbQIVoPK0xmKboeZayEmFjISKYrWRK03gl568Ez5FsleuyhAe9mC+WLQ2XVEMvh0y9kfOHyDa4PVxk9vSa+X8t9TAbNiyOaUc7ubh80JLua5NBSNg3rK9abAAAgAElEQVR11BL7klVDlUgHlK5Zmv05eeaD8si7is5diz8TIqz1FOmKGPJVGwXJh6E4cl4QwWv7zxuEI/Gkmm/I8sF5Qk2wYyk6szOOUerRf99x/JLCS9WCte5o32ExBgp5qEocTitsx1E2Hc37mvi4JhxWmKzi4S+FFL0KNKhC6CY0KpgGxEeO9oOSaGdCdmEZZR1Fx2O6pdFz6F636Mqh0prOXYe6aaljg0lrvHmFdzTB7yQcv9KC10bcnq3w3a88y/lvVgyehsHzYANL44HGZA5dOeYr4i+//G6Jl9aMzodgIV9vYo3C5Jay5eFlThxjfdEOOqXwh5lItLJ6EcgLzWsD3Gwuo5422I0e5nQuY+/pGDuZopMEFUfMPn2ZwdMe2bKjd00WLGXDY3hphdm2PN9VqyJaTskPE7q3IDmyWCOLpmBUER6n2NCjXm3inUj+4vRcQjCuCf7keywQMnFmOHeG6eUO8fHivyqFCwOqVgT3ftKV4EfnI12wqBR24qNzjWtXtLyM47LJ7rSDMZbSQPt+QRUbgqnFm9X4U4M/kQ1QOHR4cxheddhWxebWgEkVMnzBYqaaOrZizLdSSo5dobFxTdFe4Fn9SuxnjzxJ5J1bGh/sU5xdJl3xiQYV4/OaoiN/j6oUaBahFObJKGRy9yQdxS6oGu4x7y+sMZlP5wZkKxIHr0pF0dJ8/re/xy92PuR7sws8u7XHHz38HOUnr5L3fE6vgsp9xodNkns+jV0BUoNpTdEyRMclVVOY/8mRY76ssS25HcvTELsmcei6dJSJbDNtoEgOxHveux2Kfu+VA6ZZSPF2T6Qly4LBmUwWFq5X4O2ElH2LKhU6U3gzxeFrDtuocMaw+j1o7OVMt0LC4YJi4SuqMYyesjhfzO6SI8HSDl4LmW95uKB+QgZVlcLMFf44pPlQcMPo4Qg1TWGtSRUb6lA+VG8mKTjJgSJ8NML5HsVaA38ittTzrYiGdXiHY3o3fMqkw/0HTS6/vcvR5zZJ10X0nCzPcTsd8o78vUVLsfRBhpmXlN2Q7p2MouVThdJFxyfQuDfFnE5IL6+Q9YInsfQ6r3CBR9nyCcYlwY09iELwfVQvpLi4hn8whtFEwHXfR68sMXx9k8FVTbZd4B86eh9CtixUmfm5it7mCDUPqY5iGusz5ntNwkPByuZomrs14SDHjDKcb9Bphdmf4YxmfnmJ+EgChQGU51H84stUiUbn8lzkHUXtgzMezb2AXOfw3Z9oFfgr5yNdsFSlUb7CJjXRw4Bvbl3kfHvAs/0D3tw5S/sO1IHGFFbSRSIZM3SlmK/zZKP0OEF3b7/HvtfBzGRj1nhkmFyyuNSgCi3gsiexR86DynNgxUY3PnB0/vRD6HYYXolIVxRFwxdXByVYgZey6KQc4d0x2ZkW0zOSpKysjKFZX4uw+lTGNDv1aR4qjj9V4jVLmm8lTK+URC9IW/7m9CLDKiGtfXY/G2N92PhmTudmwLhqkKQyGqXLivgInDYkhyVl06BLR+tBIa6cSyHewCc97aBCSzDShEP53utAUbZEyGtyIa56M8fwqmX37jLhobhUTM4q8iW7oEJIUY+vRRQdhzfS+BMB3ovuQvycerTuIKzufkB8WBK+cU0Y1p98kUefb2JDucHb1z2CScVky1B0HOHAkK1WJGszysLDjRIpQKd2kZNo8PsN/PGMcH+CjX3G59s4A8V6SXQYYAO9ePk9/EGGzoSj1EpL9MmYaqPHyVXZjrXeOyK7sMx0S1FHFowjzwJCD2YbIqnxZ3D0SkQ4CMX6elk2wdNNoaF0r0/RD/Yon95meDmQDsdTaE+jJhVVN8JLa7xTCXDNzveoQ+FSBcNSRsM4olrtUHZDJls+07MKaxyt9wN0CdNtyC7nuEqhxx75G0t4BtzVOen9Ft5CQtZ+UBMfFOiFNMeFhjoJpHDO5ri1PuFpjsprqs+/iiotp8/EhCNL+w9/iApDpn/7GYbPyDjdviXQiDf8Gej+Y0//B5rTz0qEus7hD577Z/R0xD8eXuTGv7xK5wf7lFtdDl+JsR6sfzfFn3rkHaEFZBsW08+JopK61mRHMfHDkKLjKFZqyoXDQzAQpXsRA5Vk9FUrBf5+gC7kxfQyGP3SM1SR8FZW3i7J+h6qlo4CJd2Tl8LoYkj6iYi856iWSpa/5RFMLVUsY6vJJbY9GClsYBg/V9D7vk/e9fnkb73DWjjmrdNt/r+7z7DeHfObW2+xk/fIe+J8WUeG1oMCZQNmGzDbgrJdk/c17dtKsJOmJu8I/ytdl5HBmyrhoq3JQz1fVwtfJHGqqBqK0+cU4dkx02nIM+f2+PDWFvlmSdHTmFQTDjSNHfFPN7kQadUDR2O/pOh4zFekAwOhD0wuwMnrjpVvGZo3Z6jNNbh5B779LmffTZh/4XmqSDabJ8/5hEPH5X+6j5qlnPzieQ4/2cSbaVbfcgTjCmUdurTEeyXm5iOq01P0aYJ66jzOiB40ehAAEB7NwfdQWU7V63L8apvxF+dUheHSPwkoOz6NfRmHH/6761RNwMnGOHgQiFXylYKolVPfbLL95TlV4jHbCBifN0JvaIousHHtCBeHuI1VbGBYe2OIqixqlkJtmT2/IcGwOzkoRbXSgoVpoDcVk8fhq6sULeEXPqYgBI+Trh20H1TEeynjOw3KRJjr820ZmbvfTKgagpG2HhYk18Tm2DUT6lYodJqsog4N9pktVOUYXokpGzLK2wCmz+Y8e36P2795Ge/tJtHAsfSuXPrRqSxMCvezgvVjz+Ss4B/4lvz5lFXTIHcl//s/+hVak4rRK6skeznd2xW6sMxXA7IVR7Eum65GL6XfmLN73EU/iIjni2LUr2QE1JL2W3ZrXGbAc6i5wZsr6oknGI2CYLRYIS/cKIPJwl/7gqboCmPdH2sau9JdFS3hUtUNi/ItSz+cUEcewyvxQp6zoDUkSrqSpqFsKrKrKadFzDcfXqAsPJS2bCRj/mD3FY6nDVa/72jfnqJnOTYJmL8WCt61MBp0c7F19jLNbEPA9zpgkforD2bRcSS7mtm5WjzHR0YuhAqKtsNszklPYuKllA/vbAJgRoa6XVN3S3AhgxccyZ7Chgqmwtna+1T4ZM0fnbgnARbJpRHlwzajK1AlPdbeGGHWVimf2ULN5eemPUPRFr/7aGBRac7kE2c5+GKJMo7gkXQmOEdwlIrt8P0D6lNhhJefeIbjFyLSFemI/SlEp47phaa4MXQMs035fJVTtN6OCO4/wFtqc/iJDlUiYvf2bcE0rSfM+ioBmjn6rRYX/uAQFweMLidMzikaO7KwGF+ElbdSbCumboZgHeG1HVxe4NIU1etil7rMNjzCsaXo+LIICBZk2NJipjku8ChaYs/svMXPDbkAGztShLy0pmwHTM9IRH2+UaIyTbxnSA5r/KmljkVvWK90KNsh062AsinFTtWgKsHyHp86FO6cNwU/qrj71fOsvVsRnqRPtI3haYn1NeNzIZMe8NWfUAH4t5yPdMFKDhz+kSFd8Zifq3i/SPn33/r7xBZm67Kpy5dkE1Ys+6LRiyxqZjCZJh157G94sBdKmEHTUXZr/FZBOQ5Q3RJXGvRhiMnkITX5wkXBgJ4rvIms460nuFM4kTZ/eCUgfSaDkY8/0uLiMK2FjxSLmZvqFqiDED065fTZNQmgGEmHUCaPQVlhbGevzHGF4fr//RRl37H04hHLyYx39jfJHrRo39TM1mCy3cKfNLG+EgtnB2ouD6A/U/hzWRZUDZGoVA2hahQdGUu9uXoSRBqeSFFONytUUtPopGRpQLTrk88NvUunjKcxauCh5wZXaKKnR9KtrntEbyXUoSLtaTbeyIW7tR0sdGvgVjOmO22wohhwGo4+3iHvdEkOHP13hyQ3xpx8ZoPRJY31HTvPV0y3zpP3Qc0U4aERWoiB+PYJtpNg7u5THx0B4K2vkTWE86ZrBQv76qKtyLtCjKxD6VaiD2OW3q9oXjvk+PPbxCcVrUcV422PvK8YPA/+WNG7UeNmisOLcOF/9vD397HdBifPNyXO7JEjGgmgvfFth55k2CQUmsIHd6jmQlPQrRbV9grZakzjoMIfV/jHU6puggs01mh0UVP2E8qmuDNEAymaeU+61PjYkuyXElrS9Un7HkVLaCDhvtB0wqEjPK0ITjN0KqPl8evLmEKoDOaRxRvnVK1wgfUpqlAxOacWHeUCOrmV0L7rBL9qe2Rdw+SsRpdGQnGBjW/MufGTLgR/6XykC1a6osiaAI7gyPDf7fwKs2GMn4gerrlnBRsqhek+OyN6v+DUUEfiXRVcb3DuKymTcyGHrzv8jvAWgiOPOjaoQFwadC7Sj2Ak45ELLNVmSXUaMJtpgoVUZLaqMTkMXq7xgwo3C0VoOxct4GxTk66KJtHNfOJTzfTqMtGwxpvVDJ4NKdqC8+hCRjxVKex+RGNXM9+y2G5J9W9WKD5ocv7OPs4ewVKXu7+9TNmyTxKhdSERZU7Lwy0FyTE7o8iXa0yq8aYyrtZNh1rNyPcj/KlCF4qqaWEjIw4qnFOkd9qsvgmTc+ITNvmgT92t0VsZ5kEESpHnHp85f5fVcMLvz1+jeSNgvgbDZ328mcZkML9U0FudkO21nxTzKoHhCxXxIw9/JiLv4XMdyqRL0REC7+zFnMtbR5x5dgjAd3fPkuUtujcheTgjP9tn8GzImgU9n6P7PcqzC5LmjqNsKdI1KdC1xDTiTx3BWKgbrbszVFpi2zFVDLNV6XpQMhIFQ3EpAOGX9X/o8G/sQKdF0QtpPygEG6wcJrXC6SstdS9B5TV6OKNeFCvz1CWmzy4xXzaYAtoPMkxWUS41KHpyyQaTGj231J5GOcfy+ynW08zXfHkOKwmsyPs+RUMxOyOjfNWw2G5FVSq67/i0HlYEowJzOoO8wDViwoklHJRPtLhojT/MyHstvLnl9IqP9R3Fco03NoQDRTRQeJkkThdNgT5MAfnrU9S1Jqs/qDDj/CdbBP7a+UgXrF/4m29z325y/6RH+ajB23tbUGiyJbCew0s1wdRy+pQheyrDWYU5DlBXJ9SzgKW/CFh+Z8xsu8HxyxBuzInDguGgCR0rAtzRj2K2Go9EdT/bdkTdDGMs87HgHP7UMtuQ2wkcOtVUZUw0XWAAnpKNSiBdWt21mLGhf60mHJSUbY/TpwJmW45yvSRq5WSTkMauT+ORYvRczXxL2vONPxELnKLrc/QbF1l6P6MODcnHjuknKXf2lgluxWz/WY6qHPmSpPnMV2S0rBJH46GhDiDdrCCQ0bSR5BSThKJr0SuZpLrMfAqncIchrfua0UURfHeuGey/c8qVpSMejHukjZzV1pSVeEpsSr55cJHe6oTZXp+qKaNgHUlH5x37TI/6NAfiOJquyKWw+RWFrmr2PqMoPj3DOSj2E+K9xYhyGnBrvsGjpS5JlDM7StAKpmc087UO8ZFltu0YPdOi80Nhh/t7Hq26TbYcMTXmCeaoaoiPpPiUTSWpOJFH3QkwWY0uhSfnTyqa90vKtmRE1rFmdM5Dl9C+n8NSl/SsGOWVDcN0y9C7UeCfZlTdkMEzEet/+ACMxo2nKD/AnNlg+vQSw0seZRuiQzh6Kcabix5z+Ix0u91rQjj2Z5bwtMIpuXi89Ec6yqIlppJe5kj2pQDbUJO1Yfk7Hu37OeGjkch44pBys0sdCYZZJsKhMoUjmHj44wJlHXWkWf9Ozt2/5aEquazFF86J7dHUYj3HbFOMJ8M3mzR3LPFuijs4/onWgL9+PtIF60+vP4NyTfAtZi3nP3zqe3wpepFj02Flc0hxtEK2YnA+uFqDcnzhc2/z1TtXOPuvNMHpnKoVkHU1dauC0lCWMYw9GflKIUNmTYuei3eSLqBcK9AO5pOQeNeIXYgCrLhE1guX0+hQRg5dikZPqAqKYqtAe5b4hk84zCm6PuNzHlUCNrSQabIyonnbl26r40juewQTWHovI9gbc/SZFabbiqJnmW6HxIeKyVGbeSvEjn3679eUTY90SRwDVC0dadWQ4pH3HP2XjvjM0h5/9s0XsK2a+SxChw7XqGh/PSY6dRy+plCNkvBQujZ/BvGxbDtNWBDomk+u3cM6jadrJmXEuyebHLy7RrKjME0Bqb2UBSajCCbC5PdmTsiqRkaP6RkjCoDtGfncRw0CtBX7GOeBl2pwmmy5yfQpxfb5Y/YHbcppQueWED83v+5Ivn+fuqqohyOM5+E2umR9Q7a0AKxreem9TLrexl6Nl9WkawHtd49xgY8pJEC0bHsMr0ToCsJRzWxBaO3esqjKMXi1T3xc480qsn7I0vsZqnKcPt/m8DM13gjW0hTWV6CZYDsRx1clXDU5tLhjRXJQohwcfCwg3arxh5rmA9nOFm2oIo0/k01jHWnmK5JxWLYc0aGisecIx5Zw6AjGJRChPvQIxpVIkZIQgPRMg+mmEQlZ2xEfiWFjc7dAlZbJ+RhTONrvD0jPdVHVgtum5WfQuz7HTHPS7RZVrIiP5DNMlxTJfoG5vfOjGLCf0vlIF6zgboR6NWOzP2LnpMM/+9LnSfYUT//mfV7tPWT+n9zlO4fnaAYFn16+Q6gq/vm/+ALnvpWiyoIq8ShbHlWsUJWmTj0oNdHGnGwcUiUK1y/p9mZMpjGFF0C7QnuWIKjIR9EixUahrKVztyDvexx+HMKBJtl3pCvCJH9sBucMqIlH845h/VsTvN0Bg89uS+iBUjQeaPz5j6Q+dST2yv5E0dj//9l7s1jL0vM87/n/Ne+15zOfU+fUXNXV3UUWu5tkcxIlUzYl0xoCyHJgIIgQOA4Q50q5DBDEdhDf5cJIDAhBDAOJkxh2EmuwrVAyRYpUk+xms9lDsbuqazzzsM+e917z/+fi2110AutW7Auuq6q6OXX2Xutb//d97/u8leBxrWX5zSGd932ypYDppkN8UhIMPJzMpVOKALNoyFu4sSfF0ptJoMF0xxI/P+DLGw+4O9rAnStab7skq4LQ6b7uMd9QJF+ZEnsl+VsSReUmUhSCQcHR50J+a/tH3J+t805/i9NxHftek8ZjS/v+nCt2RtH0Obvjk4eWUkmYqSoVNjQ4I5foRDHbNpIUs5WiFHRaMxxtOCsahKeyxEhXZOhrHdksVldSGmHOYB5RjAJ8JfC+4Q2H7l1LtL4EJ6cAqCBgthU+m1Pp+U9sQWlb4xRyqqkCB39csfdra1QhNB8Z0q5DGSqivixR0o5DMLJ07yY4SUGyGdN4kuIdjyjXWrTfG1J0axx+MSK5lVJvpAQ/aKGaDczjPfRSl/GdDsFY+FZFrClDBMrnifzETcRW40/EfG7VQu7SkXmRP4Z0CbBiRQKYbiumOy7eGMJzFy8RgfTwupBrg4G3sIMJi95qsQ2NVip2/kB0gc4opeY7KGMZv9Blsu1Q34W8Ib7M+FgG+uMrsjn0F/z55vtDWtZitcbsbDBf0vBHP6WCwMe8YBUdw+31U5LSozqu0d4T8sEkD/i7q2/hKQc2fsDX5x6/N3iJ/XmbrW/O0EVFthSSLLvM1zVZ12KDCjUTdW9VKTCK2uUxq40pu6ddTN/HBgbHM1gDs2mISjTNp4ZgWGIVpEsuRU1T3xV5AkqsKLqCYGiYbjqk2wXttzw2/u0pap6S3pDwUWUsYX+he/IUDpZkDYq6xRstUlV6BZPnl0RX5irih2PCyhCeIvoZp0le15TeTxYEyiChCk0IRou5ze0RX7t4l0ezZe4+3GLtfctkZ4FtdqUl+fnPv8s33r6F+9AjHsgDFAzkjX3+Qkh2e84/+s5XqD2VdOtGAcoYsdtsR4LSMeDOBPXiDKG5OeELW4+5U98F4B8//jzVa6t4M5h6AXY1Y5b6WKvgLEBXEPYWboNIUdRhetngOhWVVcx2mzglFC1DvmZwhy5nr0DeaLN2vCqs/maMP65I2674Slek3Wo8lt91sq5ZebtC54bTl0O8qaX7gcwTlbGoyqKMZb4u2qpgWGB8h2Q9oPIU9R8IXlPndbLVmKLpsvZGhv/1DJUZePQ25XzO9DdfFT3VVDSBWVs+73BYLdJ5LLWepfHBCD1PmT6/Stp18OYCmpzsOMIrW4X40JJ2pfigYP17kp1Y1KXonrzikXUN7szS2BUhadYWoobtFLS7U4bDmM3f94jfeEx1cgqfvMX4kk/tVDj2Yc8yuSTts5OKxmpyQ7IG/InFHxviR0PULGH24rpYuPop8bsHP7V6AB/zgrVx45QHZ8tk+3WhRf7SGP+PmvS/t84v8Nf5Ly7/Cf/d+79EI8z469s/ZDvs87999irpsiVfqsCtUKklWJ/DJMCdaarQYo3m2pVjjscNdk+7lEMfN5G20Zz7YBXuaoIphOsErmz4xhW10xx9ryJZC5luiAnYyaXtmW9a9MyhcVhiQw/TCJlu+RhXFPnD675gVDyZ6ygL/khT1OWYffxqyM7vn5Nu1InfPye9vETadYnOCpKNiPFFB1XB5LLBBBVBz0GVirAPwVC2YcW6oiwc/s8P75AlHu65eAOVgfZfOeIr6/douXP+0e/+Mms/tihjCEYV3qigqrkcv+LhvzTAPmnR2NMLWw34Q9mKOYUl6OWoSjx0xveEOGph9qDF1x/e4U8mLxHvWwbPW9xosdQohEaaTgNs4hCONPV9WZrksaJoyBLBnWgKP6Doh9AosV6FLRyU/smCogqAbgvValC1IrBWTL5aBufxgcVLROO09HaCMpajL4qotP2wkCWFgip0qEJ5aL1phbJQRo5sXo0gY2y7gfUcioYvhfCePMS2P6Qaj9GNBpO/8Sp5U1Hfr/DmJSo3uOOUKvbJuyHh/hg9GFNtLlE1A9It2fK66QLmtyGm+LxlMM2SbAsoNNGhS31XTNeuq4gPUoynSXYAo/CPRHOYrlrJZwSCWo7rGGo/Dmk8mVCdnOKurzG82cKbCxa6qInfNjgXNBFA1pb2cb6hJMquMKjBGBwHbyzzVGeSPrPv/LSujzUi+c6/+G0IQwbnDbwDnzK26ExR31OsfW+MffMuyvfRjTqqHlNsdHj4m9FP5kqlQl2ekZ+HbH1DMb7oMF+3VE1BAXsDTdE2NLbHJKlHVTqYzAGj0FGJ7fsEPYewBx9FpNd61QJytsD1RprplibsWaKeWF+qUCLRi5oiGBuikxyspYxdyljakKylmF5ciDkz8fnpQrH0jqX97pBsXVApduFRq0LN/s+7XPzUASvRlO/fv0z4OMBNZAZWtAy0ChrNhJvLp/zg0UW2/7nL4IbL5PkcKoXXdzHbKdZA509D6vslecvh9FdTOs05jjY0goxHh8sEH0TUThY3eB3qe4awXxEdzaA0z9KBg/OUvBOQtd1F4cvZ+8sLdrGC/HqC+ySkuJBTb89xtWH0oIM/0s+M5u4cYbVfr9DLGWvdMSvRjMNpk16vgS01/qFHY1fCH+r7ls6Pp+i0YHKjReUrJjtahLqNiujI5cIfz7C+5vFfCzG+pflAUz8SE3PYL8naLoObYlavnRiCoXC6PkLt1PcynFQ8o+44hZMeKooYf3qLwXVJ4qnvw9K7c7ynZ2CM8M4djZqnVMtN0rXaIlatZHAjlHuhV+AkJVYr8pbPyWc9/OFHui+LujWlKBziN2o09ioJAS4EIzO47jDfKfEGDkWnwmtni+glRTEK0IutsD9S7PyzXWyjxsmXlsTnWFgZ+mtF3lTMN+yClqrwx6AzqPUEmxQdzdBpSb4Ss/+XAuJ9WH19hNo7Jrmxxp++9vd/hkj+913tIOEgacHYxV6Z4wDVSSQr3ydHpH/5ZbK2S+0oQ2clecdHZ4qqLl5Bd6qw79RZPrRMthST67Ixi9sJs+OY6mpC6JdMdpvYSDZpeuIKJtlxqB05IvAMpUDFxyVObqh8YcKXoWK2psXSkluML9soZSy61DiZkjimJQ+dL/xzgVqgWRRW2UX4AHSe6zOZB4TfCqkaAf55SlUXe4k3TMl36ugCDr99gd2aJbwypXiuIjsLsbWKWnfOy5t79LOY9/7NTVZ2Le4s58Lv9bB/HDC53uTw5wwUGmYSpjq64jH6TEqnMWcwivm1597mLK/z6GwL60H/izm2VCy/5tHYz1CFoWwEDK+HRP2K81suxvNo7IqIMm869G7H1PflxNN72WIKLTOl1GGlPqM3jbGepYqstOphBY7FP/KwnuXFrSNKq3lwvkyy25Bw0FKEr97M4I9lkzbbqZHHUmDytgyZUdB5x2HttT7q6Jz+V6/Svgfh0KJLIaJWvmKyLarMsCcFGaCoO9SfzMiWw4U2qcI5PEc3Yzg4gSgkv7iMPyzZ/E6G++AQKgHb2TTFXNvGeA66qCD0qWr+s4SmyY4rboSBbJndxMOfVFhXsfx2RRkqhtc1+ZKh8Z0GK09KykgShIyrcLTl/AWHdKNExwVlVEGpKM9D3AUpg26BMRA+cVn9YYLpNnjyax3KusWdQe1YZnyTbcX0Vo4ey33eeKLxFkggNzH4owLrOWTtkCrQuHNJiVL7J8xfvcpwpYTXfkoFgY95wXqwv0owrONfm0p+3f0OYV/jzyp6X7vBdEdR37V4/Tnzi02mW4IiUaW0DtHZoiDEivHzBZ2NMav1KR++s41TQeV6JMZHtQq0tujDUBjiyxXBnk/7oWFwQ6MqaD0SamTpSAjFZMf5d8zMinAkdABgoTAXYWjlaaLzxckrkJOXqQRn4w+FvTX5dMJLq3t8/Z0XGFyX1GhVVUIpMJZspUZRUzipkmK6lXJ99Yz7JytkYYWOStK5zxv7F0knAfpWQhmHROeacrXJ8Foky4GZJdgL8KYS254tV9QaGTe7Z3zy0luMyohv372Bci3pxQwsLH3PIz4qma/JJurks2A8AfhVn5pQlQ4jP6L1AM5fkEVE80nOfM0jONMk/iK/sJmzf96mzB3clYSy4RG3ElpRSn9agyc+4XLCKA9xtUEpMUQ7c01VF5SyLslnzasAACAASURBVCy1E9FNleGCGOv8RBUenilqZxU8PmD287eE3hrIKSLul5Sr+hlVM+3INs1NEXxKr0DPC6LdAj0YY9MUGnVGt5fgxS7BqMKdFHjjDKc/lUAIY6m2l0nXa5Q1LVicoyn6fAxuF/CYr2qyFoBsTLFSHJIlV154myIH8cfQ/SZAxeSCbJTbDyqcVE7X/hCyVYVyLJx5+NOFAHiB/tZnHstvWYJRgf/hIQ/+zhUufG6frHQ5+vEq9V317Pftvi5jgsaukfsisdQPxR5UNFzmKyG6kpeOKiEcVIx//hr9mw5V9tNtCj/WBav7fZ/sgiIZhORljaivhcO+pKk8hT+Exl7O6IUOSVfmKNGx3KTRqYD36geG2brCGbvMOz73jjZpPtGUEcxrhu6FIdYqBqcNwpEowvXMITqD3m05DblzyOsK62jyhjC0omNoPxSVtJPJ4BaziGqKNMZTqMoSjSqKhkPWlBvMyaEMofHEMl9XjD6Zc3vniE/Vd8lfdHn4B7dw+zPKbsx81QelqJ1k9O64VMsZ25t92mHCe29fxEk1rIiI7Nb2MUnpQQcG84hB12P/LzmoSuZvQV9Y5/5EWtf5L6R8cfspTTfjrfMt3jtbx3yvQ3sqmpzxdUt04KIqia7K2orxzRLdLFhqz7j5yin3BytYqzi/4DC7lWI/aBIOfoJWyVYMBEaEuEcheatEhxXtRsLUNVSVZp57pAd1lg4t/W7MbuYS11NWG1MO1x2K3IWBLwZyC/NlTdQTAzQWkq4Mq925SDmG1x10dYvjVx0sgrQJRobpBZ8yBG9uSSOH+Zp6JqpsPE1wz2eoLMecDzALFLGq1YhOcxmaZxVufwbWYj2X8rkdklUhrcYHKfG9IcwTbL22oIgW5PUYXQhWOz4W4qxxldwrStBH8ZFo/z4K3E1WxCa0dLek9nRMVQ+Y1UPQEkZSTH0cA9m62Mt0onFn8jLL62Adh9GvX6F+55xhEtI/bhFMNNaRFrDyxcnRvVeRx4Ijig9zCaOIXfKmJuoL7XV8UbamybJEj6Eg6v1M1vDnXsNbFldLAfEmC1TuqvTcwdAQHxY4WYU30ZSBSzisGPmy6ZhviiCuqMkMRheQnUeERy5FHeJXe3yyc8ZGOGIv6fDDe91nDCzrWKY7kp7zEbkh6yrObxZE7ZTirIZ7fc7eCxF6JpgWGdSKl9AfCU4EoIo85msuRUNUyk5mWX57LnKFCy7bF845mjT5neGX4I+6rJzNMfUQVRl6n9DEh1D8x1Muhz0ePFljb3+JPWQ+F50o1v9lyfhyxEH7MmVNtDt51xCeCsJX3pLSMrkzGVjv/c2SK0tDnoyXODhts/z1kEjJOr2sCSa6+aGLcSQDMF+ucBoFjrK8cnGXn+/c45uDm6zXJ2xEI85bMXePN8iXKgY3XMrYo+yW1LpzQr9gUouoxj5urcQPCsazkGI/lg2nhpUfKer7OfO1gGKzIk18nkxD4npKNpccxzJSJF2NLuUBj3oVujSMLrvP0D3BULHxZ3NOX66hSkvrIc9izYJxhZsKLqWoCf+/cy8n+OEDWFnCtGP07hgzmcjNpx1UmlHUXSEsTHNRtJeGsu4TPD1HVS2yToA7TMm3OxS1FQDctGJwI6D/Ukl7fcKoV8f/toeycgqvArmXPzKJR2cypxrekPso3rWkbYfZWgd/asljxeRTKY5VqFxjVnKc00CWBPWKqnRwZxLioSwSDTcLKaY+Xs8l7Ek76GQyh60fFeSNBZIpMShrRf7haqJTAScOrwo1I+xJt+DNLK1HliT4i64C/9/rY12wvva5N/lXjz5D9DCgsWsZXxKBoj+2RL0Kb5BiA4fxRVdSTUZymlBWBpimaakiScjRpcIfuTgpbP36Ez7YXae336a+NsXVQgydr0vIqJMq/KGETZSRJd0p+NT1p+TGJatcbl78kLY3p+vO+DcnLzC8HnHaXiY+EApp8/4J1VqbvBsy3fTEgZ9B536Gkxl0WpK1IpLtEmMVs9Qn+EaT5XfmMovrhjz5m5bllR79K3Uuhyk78YAn5xcITxWrb2XoMuP0pYiDL8cil7AS1Bn1SgY3fIwPKMXSe+JvDAfVgr/usPqvAg4vbeNNYe3MoCqRKxQ1Td6SVtE6ms/85bsM8xpLwYxBVqMTzMkql39++DItP8HXJfeGazx9vCJR862c7IoYyZVfsdqcMkpCnA9iCC2FAj8oyAYhXioPq3WlQE63fIqWpUg8tGuIGykKhKd+5uDN5YQweKmk/qFH8wmUkftMfxXvGqLzCmeaUcQ1Vn5kmK05TLctutA4ufoJ0seHpbs54b0j7Ooy1vfQD/afmal1HMPVbco4oH73RFJkqgrle6iixOoWphWDsbhpxeRmSwqRr8iamvF1l2orxT0KyZ908RoSoDEJHKGyDiUj0puIBCNvqoUoFNoPSmZr0q4qKy/Q2bZFOwv1u2/Q2uJfnhB4JfN3O3gTRe1E5qhpW5MuQ9EP8fsOzUeCV6oCyVTUORjfE5FwIsk9ReyiSzn92dBhtiYWq6Vdmd/KyVBOp7Xhz1rCP/ealCGObwgGclPrYrH6ThctGFBFLmUs7VayYll/vWK+vPjCfZ59mcPn5Dhs1jK0snS6QtGcpwHTQQyhIb48IZkHqN1ICKI1g17O+NzFpxIEWjhMc58nsy5fXTnmpGjyq+vvcFI0+Y5/lb2767QflGRXV8m6nnCmarKRWXrPYjyNOy+pmr4M8l3D6BvrtPYMTlEx3QlJO5r5umVz/YRmkHJ21CIpPN443sb4lumViulVB90wKJVQjTyCz42YTCPSezUmF33mOyW1lRm+YzjYqtN+26OoKZI10faMnrN037ZkXcVsXbPyoxT/bMboa0usfO6I82mN25864q923+V706s4GDaCEZlxcQND5BQ8mXbZ67UxBzWCqaa8loCyOMf+ggrgsn+0SeMp2A2LuZiw3JyTLKLudSnRbWHfLk62wKUZzbDAAo0wY575+Gcu0amldlbRe8HFP3Vxp5C3XMY7P0FSA6Qdh7NPdgiGljKQk7VisQkb/iTnMjy3RO/tk1/fJOt6RCcpDMW/qBsN1PoKJvDQpQFjML0+ynGwO5vYOMSZZpSdGrPNgLSj6dzPqEKHk1ccEQI3KvzdkM6PLSCtbP95yJcqgjNHZpu+yFt0KS1aGSk69wux5ywEyEUNspUKdznBlg7V3INCocYBuQ2wE03tDKJziTmbr7kSaz9TeA9dGnuG8Y7oEP3xQtWOEpKuY3EzFnMrhzzW1I8Kpssebgrtt2eY0KHyhRDrJhWqsoxX9F9oDfj/Xx/rgjWvfMxQwjGrUCLLdSFCSV04GKeGdeWt4SYAiuhwRhk1JFMwUbQfVAyvOVhlqVolv/L8u/zR4+dYaU5JCo/iSR29nsox+qyOExeUrYr6+pS/df37XA9O+OPhC9wbr3I8blCWDpebfebG58VoH09VdN0pB802u/4a0wsLymRqGF/0mL6coLSluh9R2x2TbtSZbPvMthXBoYc/FPvD8auapdtnXG8O8HWFpytee3oZjOLszTVa9+G5//Q+P9zdlg/nIMKbKqqdnDT3MINAWqwlgzdwyMdNnGNF3YXxVUlfriYeulbiHkhUuT+yNPakdX3/v2xw6/ITRllI4JX85xvf4B8e/CKjPOK3LrzGV2u7vJau8H+fv8yslCl3VTqYyFDFhvidSEzNlZw0TADeYjDsziGoZTjaMDur4Q5dkai4kBlFOJDTkalltKKUzy0/ZlxG/PHjG4A8zGnLwZstBugnFcmSxJOly+IwMJ5isiNLibAv/sOiLtvLsCcnmaIug3os9P7KFYoYKZgnIyrHwXz6BebLAcF5Rln3SLsu7cEUFYVUvXP04wp1YYPxi0vMNhz8kSUcGJJVn+mmYLWbjyy6cnATQ9bWJMsiW/GHkkXppAtDc0dmWGqhc7MVeKOC+UZAsqwoGpZyM6fWlBBdO/TxJhonkZOXNwVvbIn6Rk5h6y7uguQ6eT4neuzTv6Upbs7hIMI4Ypuyjrz86/uLNG3l4s/MgiaRUzeW6P0j8mtrFLFLWdP4Y5GDTC4GVMXPYr7+3OsHj3dw5pLKghWJwEcRWdaRtNwihqwrp69gYOndaXL+eUEeB4ceZ58SumgwUKirGe8OhPFUWUXvpImKjAgTHYMbF9RqGblX0akltJyE16dX6Oc1TiZ1AC4u9Wn7CYEuqOkMX1WE5Hy18x6DF2vsvX0Fd5RRBRGTKxX/zSu/z99781doPsmYX2py9HkxnGZrJRhZyY8KRRVXXGv3uB6fMi5D6m7GD/xtdv6pg9UVD/8jjTNpUw19oiOXbMmQXckgc0hPYqyyJFslOtH4Q0Xnw0qSeq45mNDgPYmITxW68HBSy+iGJTpRnH7Kw3llxsvLp7z1dJvG6xFXfuND9oolbtRP+SvN92jolO+ka3xjdIuztM4gjTjc70KhUUbhnzmUsWV2qULFJYw84l1HZjOlZdTVzE7rVA892lNI1iymUnBlxnwcoIxHdKrYaQ35+eV7rLgTvjG4RTNO6bVruFM5uYR9y3xVcfAViyos3XeFkloFckLzR9JuJatKxLgLIakuF9mBJ4a0o5lclsWC8Szja2CdDewXNjCOwp8ZpjsRRW2xcZzMUGGI8/wNYVZ1QoqaoKWrQIi3RV2cBsrK96kLiT/Dil1K57KtFq+lLF3KUE5WtRNZggTnKeefqDPdgWy1xO+khI7BWgjCgjmBkBrqltUfWFnieDDdcmDB1LMOjH4hYa09pfj+CllXUe1GWCSNKI9EToLSzBcbU29uCc9EJ6jnOdH+ObZeo4xcirqYn6eb7gKyKLOun+b1sS5YduILL6pYxBVZSJct801wMo2q5Kjvj6UdLGvgjxXtN32ic8NsU3x1KzfPuNTqPxsWP723zsiR9bhOFZ1LY+6sHHBvuMrBaRs78Ll04Slf7z3Pvd4q82mASVx0VPKk6PLweIU/q13m9uoRr7SeUNM5g1LEkoMvZAxvNbj2iX2uA3/3X/8Gm9+xZB1JOC7ahqWLA17qnLFdG2CsYljUuBEfczvc56Wgz6u/+9tc+r2K+rLLycuS0Ly+cYKnDW47J60UjUcOZj8k2TAElyZYqygeNlAGmk8Nw2sO801D7RCW3nSIBhL06WSW+tMZ42sNqlDkGpOyzVu3A7723HvcXd/AWM2kCvnV1ltoZfj7u7/CO48vwFQWGtazNNYnlKVDlnqotZKq1HhPa0T3XIwvnkCrIFnRNJ5YdOEx3zT4I0W2UvHLr7yDqyrqTsZ3Ll7l8L01Plsb8sPxDm/sX6R4UsdJoXWiqB9UhP2c0aWQYGQJ35CBsTcVLVOyJFu/2onMWtJlOYm7U/m3IhbBaRUJmsUbaepHlqwj4tXZupja60cF4eM+VSdGv/cQk2bMv/oSZSxb6dFVTd4xBD1Z/OAssDQjSRgvI8hbHxUimflUntiiop5FlVA7E/Gt059iHZGdFA2P2U6NwfMW0ylQcxfzNKaIhKlmZh7NDx1aT8Q6lXQ1ulhElS0sYv1PCD6Io5DGP4KjLyiKWLIEqgBmFxa4oZm4HtxUTtc6l9gvJymZXW4y/0wHN7UEw4/CRqRAOZkEsDZeP/6p1QP4mBeslYt9Urcgf6+FP1HMLohROOhJH51sVFShJjhXxIeKZAWmN3Lq932ySnRHplny5Y0HlEbzv+5+lsEsAmC+18BNFOVaTjtKiD5izJwF2MjQdDOGeY2q0tiF8l1pyGY+2jUs12c0vZRLfo/Kah6mq/SSGHXuY5dy7j/coP2ORyeTBGVdiA+SuEQpS+zmHKVNfnCwQ/GowZvPXeD+2jp/589uc+X3c2brPr07ivbzPQLg5OEyK69rakvCAnNyi5+CdTWzeg1n6hD1FLVjy3xFBJXhifxcp4C8rqkf5HjDVEicBRRNy/ltRRkbrm+ccSU6Y1hE7EQDvlz7kA+LZb41fo7PdJ5gUNzd28BMPVa2B8R+jlaWrHQ5eLLM0g8k8CJZlRZ96X0JaIhPrITKdizOSorarFiLE77W+RGFdfnj4QscnbfwRpphEXEwa+F7Jc7VMfaNljCncsPwSkj/E5bmQ004NZShtCrupGK+4uCPxZNYNBUmMLhzTXwkJ7x0SaNfGlGmHmovona8eFgfilMh7EmQSXA8w0Y+bm/C7BdeWCCDnGeBIcEAvJl8pt7MEozkpTfdEGKGP5ZTlD+2kpO5rOk8yPESByczhKcpzvkEG/qYVkwV+6LlijTHn9WYVoGauDhzTdkSJXtVafFznhrStoObyuzRnUpB1KVlcFNR29fEPwhZ+vYB51/cknbYyHehc/AmzjPvqc7FL5g3HKx2QMF8LZJ7JfuI0ODgT8TvioWN7+b433oXc2HlL7wO/LvXx7pg1YOMzNRFQFktjMJT6f2z5YpwY0Z6UMdJRD9VhVB75OOkEB9X5HWN8gzfOromthM/Y5SEMoltFSxdHxH7OSvhlD/88Hm0Y2hf7/MfXHyHa8EJ3+EGp7U6V5bPqXsZg7TG4bjJdnvIcjil6804Llp8c3CTrj8n8grUeoqZeCy97uLNDUUsHPUihmS9ImqkONrw/aMd5vOA2ps1TBMutft8/599kjCE3b9dsb1yyNc6h9wdbnD8/2zTGYpuC2Qm5GQyk5lfEKW4kyghHYQy77Na5ln+UNDNrbtDdG+AbTUYX2xRXk145dJT7p+v8PLaPp9uPsZYxZ3GPqnx+Mb8Jr9Wfx+nZfgXvU/z7qMtgj1fWFrK4mrDZ5ee8LuPb3Ph66IBmlyUdOWluxkql/QdZWC2KUp1RjWCT/f5rUvfpbKav/f+13C0pZy7VGsVP+6tMU99trojnp4sUW2XxLsuSddlvq4wodhn8qai+aQgejxgdmOJIlYSabYmCOzagSYYSAEb3tDY5yfEfsF8r0H3vqz/R1c9Vt6a458VKGNwJhY9T8kudhm/1JECNFmYoytIlvUz6qZV8mBbLbOzxkFJ2dOUi0i3vKHwppb4tMI4Cm9cEr71GDotqm6dvB1gPI11FaPLLuorfZ5rjXj/hxcJ+pqiYXEnDnZSIz5etH7bApFs7BfU9yt0Lgb/ybZL931LMCoJj+dMPrWxMHG7ZF1L6YPO5UTopICSE6E/NmK7CjSzDZF5hAOLNzPPQluKmqbxGFbeGGDff4SzvUn/k2148NOpB/AxL1hF5TB/2MLLFJOrJdGhS9GwVKGRYnUSC/tppcK6oop258I/SroOvc9WMHU5KdpsXzjHd2Q2NW8FbCyPuLN0gFaGR9NlGvWEsnJoBDl1J+W/euPX0Qch0aniw7Zl5dMn3Gyfcqt9zIY/YsMb4CjLsKpxLT6jX8Q8Pe0SBAXVhzWsY5mvasYvFNTve8yu59SX5tjvtWGvweSLBt0smF0wXLp9yDtvXOW3fusb7KUdAl2yFQz5Jx+8SvDtBloJINCdIrMQYxcPB1htcUbus4enjCHrWNy5IjjXbLyW4X7jTVS7xeTLNxlec5m/PMdxDL4u+ZWL79FxZ9ybr3OUtjAoztOYwCn5tfr7xCrnFzs/5rvxJbILiu2tc663zvjTR9fY77fxvttgcAPmWxXxnpyyjj4XoEyAdaWwlg1DvlxJDFjl8D/e+zKuNmhtiLxFxFoFg/M6tWbK8aiB6fs4qTykzccJbhYyv1GRLjtYRxEeTcFzcXKDmwhlNV0rhZ2W+GIG9yWivTyK6duYYCihHCCCUWeaoYdTqAym3eD0yxsY8b5LGs7WYn6K/D1tI/dZIoZzlPDfz+64GNfSeiBhvU5iCAYZGIsqDCZyqa5uyZ89B+NrdG7oXwuYXbBEVvH+/jqsZKSejzPX6AycTMSw1v3ImiSGc1UZ8k5A2pWTZXQmASBnLzcpY4FIVpFIdHQhQ/90WTIzux+UuPOPDM8uRQ0ae/J3NzFkzUWMWybb1867E1RaoC5vM7q9TN7M/+ILwb9zfawL1tE766gY0gsFqtBy8zUq4vUZO50BzY1DXn9wieBRiJvIg1rWwGrF8CaoWkm7PeNCa4SrKnLjsn9/FW+kOez7VNcVv7L1HuvdMd9Tlzn5ny8TvQ1/6H+J5057jF/aFPsDDoM/Xedb3VXiayP+1vXX+D+OPsMH722zef2MgyfL1B+6OBEkSwYnkmFutZpBppl/MiEMS7SyTLYqioYmPHHJCnlr772+Rev2Of/L7/4CnZdl3vav779A/EaN8bWK4Nyh9UCU0mlbU0WyGVMGlt8QjdLoinqWdxj0RS1dPzB4gxTz+U9y+kKN2ZbCuzOg6sfUujM2wjEb3pCv957nR4+3YepBvWBpaUo3mvM/DT4LyLa205jTXBrwl1bv8fsHt1G7EYUD5ZrFvzYmArJll+xxTQzZDUu1maH6Ps5aQhzloqsCmmHG9fYZSeVRGs2eXZZ0Z6NIZgHuQUD3kbRdbiKm8emWhkL8oRt/NkclOflWm/PnRUaRtw26UeDfj6gvyLGjOzmXds54en8dt69x5yKMbT+scDKDmqXYWsj8UpvJtgRD6EL8haUjn1+ypBfDdWn5PiKalqFifEXoH94Y6qdQ389xZyXuOEWNpmAteC46DbCOoI3KOKSoO6Rtl+mOxb04ZdKPUYkjkgdXZlL+eMFbL2Wb66SW5qMEnZRkazWytiPq9Bb07vgSSlsr8Y8lQ7OsWfyhLJyMC9GxovW0xB+WlLGD1erZEiBrKWpn5lmit+B+RC7hDKfY8wGTX7zF8asa70D91OoBfMwLlnUtdrlAOwYiyAMHJ6pYrs+41jjjNGtwY/uE4UpE/0crcnTfrHATB3Vpyp3NI+peRi+t83TUofhBh9ZAvhB9c87znRNOiwZ/8MFtVv4goPPBGLV/gtIO1ELiJ6LVivdd8o7P6IrH2Gnx3x9+ldqeSyOF8946rYEMmctFsIQyEjRaJQHZSsnq8pjBpMZkv0n9qUPQtySrcrP4I016PaX4k2XymwX9UUz/Rys4FiZ3UrRr8Z5GOIUojp0cjG9J1xThmViTJjs+JoAC+d2iM/sMItf/RJP5hkAGy8hSzEIoFJPzmD/xrvMvp5/APorRnsWuZfzGi2/hYMiMS03n3AoP+G/vf43xLGTqBfzO3s/hHvmUdYPq5PhhgTEaa6HbmjG8ZjAf1IkPFN69gNpZxfHnakxWfVY2h3x54wFfaHzIe8kFJlXIt46uoWMhY7hD79mGMzpOmVyMQEHalW1w457H+ndn6KTEtGokK6Lpmlw2ktL8XsTy2wWjqx7TSwa/nvPk0Sp+X+NPhBvf+TBH5+KZG76yRv95JTihuXxuRayIzgxOAdMNST8qYmmRgqE8rGUNJlctZikn/DCg/bCi+e45ph6QrtYoWj61JMM6GrTGxAF6NCe50mW+6uHkgnFZu33M2aCBmgomKDiXE2neUouiLwETTgrxaYkqDUU3ZLop7K/BnYq1nT5B5lPNArzH0hEUDahqBuNLiEr7QwEz6twy2/RxcqE2ZG35OUHPUH84BQ3JUhNdyHLAnVeUj5+iP3mL3m0B/vmHP4v5+nMvf2dKXrWI4px2LWEwi0jnPqMk5Hsnl3hh6Zj/cPt1airjf4i/wnvvXhTmUtcSvl7ncXpdNimZxS/BU5ZkTZFsVLy0fsSFaMD7k3XchyHzVUXeaKJeblI7q2i8vouezDHtGFUZyY+bWdrvK5bu5mAyrK85f17c/ZI76DwTKVah+AaLqwXPdU759uAqrQ+kv+h9ukItNn18eUA3zDjaXiXa93AyT3AxDQNDn+BE486kvYyPKvKGiA7DU/HI9Z8PSJctVWBRPtT3JENRVZbJBYd0RVb8upDkmmzgE/RlNpE1V2DFYkJL45HGezfkX939PNXLE66u9HBbhn98+CWK0hEC63ttdABFq2J5Z8hgXKNZS/nM6lO+e3yZ00dLWG2J5/L2DiYGZSwbr5Xs/pLGdyp+vf0m35re4g8Pn+dKq4erDdF7ItRdfsfgzgz+uKCK3IV4UmEcRWPX4s0NqjToacLs5jLTTYfpRYNplQR7PvU9w2THxSrAKOyjmOaJwkktWRfB3TQdvAn0b7nMdqpFmrTID6zzkUZKPyOBlrHCn0iblXUtZc2Kxm+qqT0QIF7zj95HNRvYVkTeciRuq1uXOLZ6KKy0G0tMtlyMqxg9Z6hdGDHPfMrzEG+k0ZX4CYuGzKyqSkJRPkoOP/ySi/FiVt+Q097kMuAbTk5aqJmLO9ELc7y4PIIzh/BcuPbKykjB1AUYmNe1UCBSAQzW7/ZQRcn4pQ2qUJYG/qjEPxiiNtY5f7FF2JNswvjR9KdZEj7eBassNF5cEPkFSeFSlrLRSHOPtcYEX5f8ONliP+vw44N1ogOH7MWEMtU0H0tmnPGhdqTwxqLLyZsW61l++M5V3nSuUH/gEuY8s/T4U0vtMAHHwYYBJnDRaYE7yalCn+jc4g7mcHSGmUxIf+4zYMCfiKk17ElIahVZ8osZX7l+n0EeCbMolgej9b5L3obVv7ZH4JS8/9ZFgnNNulFBhVhRxovorqnAAZ1EWgVvbvFmlvElzWxHUSwVeOcu7kysJ8YFNzVMLzhYBbUjiYSSOY/gXOp74mWbXJe5UvOBxptZhrcguDmkG6UcTRoYq5jmAS+sHPP67g7Kgt6e8cr2Pm8fblGNfT5z4ymvn15kMIrBgC71s6F05SvK0GF8UXPxuQP+wdX/i1CVZNblC2uP+HCywuG9VdojS3woixVlYb4RMF/WFA1F534p6S+A8TUmcCl3Ohy/6pAvlaiowt/3iQ+l0MRHFYObEksV9hRRz1AGauEphNEV2YxVAfh9TdG0FA0oY4m4D3vSfgkCSLR9xlNkXUuxWuCdeMR7Ulz8qdBCq+cu4vYmWM8h3k/xD4dQVdh6jawbgFL0bktKuL0yY609ZTwPGT9uE56JANadW9xMWmCngMajKcObdWabmt5nKnS9oP2nIUUNFsib1gAAIABJREFUBp8qJUPTNYS1HP2BiIaN95EebfF7FCLzUEYKli4tyYYYmYORRJWFZzmmHpFciMljTXRuaL15jB1PMNMZe7/9MsaDzj1D88EEez75aZaEj3fBKlIPv2lIF8UqHwbgG1ZWpqxGE3Lj8i+e3GHYr6M9Q3IzY+N3A1rvnnP26jL5ZoFXy5mEEe5cKItqK4G5i9fzCM/Usxuz8pGNztRShS6OtahCECLz7Rh3WrH+jTM4PQetqAYDnOtXaD0UsF3akQKTLokSOTxTGC/gweYy15o9rIXmE0PvjuLaq0+pexmb0YjvnVwiOJe1O9MA1fOfKfetIxgaVYETKIKJvG3TjiZdF11N7bEnAaQ90R4VdcXwmogWW48M3kzSfvovgH9hhlKW+ZoPd8aoRBTUySqMX03ZWe9TGc0wCQncCq0sdT/jJGmgFPgvjnhlY4/3+2uUhcPNGwf8wfdfIlqfcnm9h1633H+0gT+R2VwRy1q9+sSUwCn5h0e/yJW4x6PZMu/31pj9uEPrQNF8WuDNSoq6y3TDJW+JrcYfIxtdK8ZcnRuG10JGNyTZx5lrVr6tqe+lOPMcE3qkyz7pisGdS2vUX1GUNZE5GFcEx8JBlwG8O5VipguFPxKt0UdhqlgRgU7WQBXQ+pGPP7Y4uTDglRW5SHxvDtbi3n2MzQtsHGN2Vkk2Yowv1IP8kzOsVYRhwdl7q+gKlGsJRjJzTVag86Hgi72pJPx4ifxfVl9zmG263PlP3mEjHPFnZ1do+Sk1N+ed37tFdCqD+aKuKEPAkcJVxot4OiU+w/masLOcBLDQ/NEJ1nWY3loCoPVgjnt/j/K8D0D5lZdJbmboc2HG62lG9nT/p1EKnl0fa+Lo9u/819RXFfUwYziNyMYByjfYSuHXCspCcLZm6hEeu/hjWPv+jMMvxSRrBtOoCA498m6FaufUGymtKCX939efvXlUJWvuvCEtXPNJhT8qyTouaVdjHLGO5E1F+0GO+2/fBMDdWGd2Z1tAfpGif0tRdIyctgYOxrNU2ykbKyPyyiH2c558uEZjc8JvXnmLf3rv0xRPY6wDtUtjmlHKSjSjn9YYJSFp5pGPA1QuIqD2u5pgbBdQN54xoZQRg3eyailaku6j4hI7ddG5xkQVzbUp416Me+7ReCIbr9bfOCArXYbziPk4hKmL7uQ8t3XMMI04n8ToHzZItiqu3zogcgsu1Ia8dnSJwXETJy6pJh6qVqIdS7MxZ3BeJ9jzWXpPMgCzbsDuV12+8Lkfc7e3zqBfh6FP656m1jP0bitaD6D9IMEdzOm/1CVvyDzJeFDrySzLeA5l7JJ2HMaXZZBcO7F03xpQNQLGV6MFE16RLllUJYWmikQPVTUWc5dGgXYN4ds14kPBD3206SsjQRIVDTkJm8Au5CGW+lNN534uqd5NV1rLWJTi4bnQDaLjFJ2XqKIiX4lJuy5nL2nK2OCkmrJZ4TRzPK8iO6qx9JakNBV1mZ1ZR4bcky2H0ScKqBQbf6JJljXDVzLiDwKaTw2D5zTpVkG451HVxKhfNAyqUIuEcpmnejO7iKSTe1ycIbL9a+xXNH90wuzmCtZRxI9H2Cf76G6H8ae3SLqaqC+tY2NPuGjuKKOKPcx8xjff/Ac/I47++65We86Xto8YlwFvzC6iModgzyfdKijOIgkgrVV4AwfjW8YvFBgvxmoIexr3qaZogioUrdaca90ee5O2iC6nlsmW8H7KSIpVfGSoHWd4T88wtzfx5maBqDV4c1fwMZ+8hTo+p7y4Shlrjr6o8LdmBF5J3otpLM+oXSvwnYrjN9dJ/zTk8//ZD/jeySXcds6VTp+H8xWyoxr1Q02ybpme1MlaHkXlUJQOZSVDbK+RCVjw3QatJwXepCDr+EwuOBTNRQZiKutub6xwUld8e30Hp4Dh12Z0mzPO+k30VNpGN5G37ePDZeJGynwc4pz62AsJX77ygKOkyfCb6ygP5tdzmt0ZWeUSuQXvj9ZIMp8rV05ENLrsMkxCPKdiNI4Jnwa07xkaH07A1Ywveqw8d8bd3jr9sybuqUd8IHOW/nOytfNnFUXDw+0L39xTYo+pPEUZarJuQBVq8lijK2lv/REE44r0QoO86YgnTkshL+MF313JRq+qW3SqMJ5FnwS0P4D2w5TzF0PK2uLhTuWENduSB7yqWYq1HDKHjW9q4iPZzk0v1lAW3Lkhnlb4g4zZdg0nFUSLTkvKdkTWdjl9WWM9S3jqEPRhdsGhzANyo4hOJJIu7Buau3KPTbZdnMTQ2IfoXNr5xt/e5/R4Bf9RSPOpIW8oVAHRrtAWSBTZUoWtVURPxBXSuVdQ2x1TdGtMLwTM1xboIysvqsZeRbw7peqIMyP6wx9SlSXO2irZ1VUxQR+UGF/RfXvI9EoTFGRdj/A8Rxc/G7r/uVfs5/zZ4WWG/Rjn3MPWDelmAVpwKiY0uAOXoK/Y+qtP2Y6HvP2dT1DE4u1KVy21AyEtAhxMW4xmEReepjKYJaCItGyH6orKU+ispPcLO4yvKnHR1yS1Jehp/JGLmwTooo2ycH4bTFSSjgIuXz1ne/MJAK8fXWT83VX8AtJfHvFv7r9AOfYhqKi5ORqLXspJkhCdgX/u4K2WzDOf+X6doOdQrlVQL7CJy6U3CvKGRhkxozo5pL7cgMpC1hZTb3xoJenlsOT0JY+ycDje7RLtejgLemTeUCirCD8MKdyQsIB0vaJdT/iTD26y9C0fP7QMPpNz69IR3WDOO6cbHPabLLVmfOXSfb7YvI+nKioU/+TgC3x4tApAeAbtu0I9mO3EzC6Al/lMz2vosYs3kQToMpYC29w1hL2CKtDMrnUWFA6DVbJq/4hqgBXhbRVKkYuP5SQpfj2LLhX924I9cVI5kRoXrL94Uo3CH2ihftRgeDWgdlIRDEqSFY/Zpqaoi2bLOiILaT70JV18L8EZpSTbDdFAFRZ/kGNCh7LuEZ4KmF4nBWUrJOv6lJGcHMOBBVWJzOZFQ3Dm4o+g9biSApdZ0q5DOKxoPcwZ3PCJ+vb/Ze/NgzXLz/q+z+939nPe9e5bd9/ep6dnH0kz2gUaQALsAJIwq4OTuMCACSYpcGI7VXE55SRUUkkcQxljikoAgw0UAgkkIwkhaUYjaUaz9Ezvy+3l9t3f/X3Pfn7543m7xTauSlWC5g+dqqnquTXTffu95zzn+T3P9/v5ktUUybcNmLNKqgOX6EAxXJNuMFksiW5ZOGNJO7fmUrRVUQYOy89luF+6CK6Lk7Xxo1mStp4WeZmRRRsjdJIxPtEmev4Gam4W06hRNUMmSy6NjQRVVmIbqntYmcgdnH6Gzkv6R2rw6l9fDfiL15u6YO2+sog5CbrvYCzQUY7e8jFa3rTWWGGPFfpdXd4yc4tP3jlDeFBSOdZ0kGqkRR4pxrHHcBRQ7vlkzZK0JW/mZEYG5OlijtOxGR1qkCyXWCM91WBBbUMEhOJ0V2hbtDrOEKr5iqdPXieyM26OZrj5p0fIa4bqeIox4OYWwYshRQjZmYwbgxl6o5DqwEVbhmxBHrTyep3mFYVfyfyh8jRF7tK6pDBWQXQnoYiEAGqUzF2YHuaVEbvFeFkCGu6+16b0KqqBQ3jbFnyLD9msFIrSh8YN8dgNj4A9m9DdblC/5LD/zozFlR4zpWY17DMuXBRCZugOQz7ZPcPnwmMs14fc6TWJhz6mUgQ3XKKdknQhwu1nxLMW6UJJNvCxejbhlgS1okUQiYLBusZKbYwWzM3ClwdMDkUMV+xpWrHEXRWBHBF1DrPnC5xhKWlEomqge9ZM1Z7yIrsX6GolMoAuIpkJ5jX5HO7NjQ4e8uQoPZej3Ap7y6VxHfyOFBllwN4bkq02Kf17hVChiwqrK7mFVdPGO8jJZwLGyy5ev6R1YSjyhrpFdDumdyrEPbCo3Tb4PTlqWZkBT/DDbjcja7nUtkqSlkXwPTucrPd44bnT2CUMThWEt22sDIJtC52L9CFtG4qxA6Xi6J9kWGmJOXMUvblPceU6zlwdcLBSQ7hXENwZYlyb+EiL8PaIcm+P8pueIK/ZePsprZf2UaMJ5fIMo3VBHTWvZ7g7Y4xnEa9EWGn811kC/tL1pi5YRa1CpQ56LsX1CoobNYwCe6xJFwoaR/t8y6FLHPd3+Z9f+lbCF0JqP7XJH5z+dW6XHn/rUz9O1nREtftiDZ3KG/buD8cEQcZqs09Zaa7cXoSJRbGckccWqlQUzRL3wMLfl6NG5cpNL3BARTJnKOoVJtM8//IpwtuyeUoWCwhKtF1hJjb6fO0+0oTNgD2jOL60x0alyLo+KpEbsL4hb0JnZCgdYSc5PYtoR8ypg+OBYHRntBh5fekG8tkCa2ARbYp3LpkRNLMzEEyzO5B1dB4pwi2YLMnaO9zJyesWdqyJDyLK1Yrw/bscDsdoZbi0vcCnL55mbm7IeOJR5RrjKBnaX21y56BNOldhwgr3wMKKYTKvGS96WJlL2lJYQwuTaJkHeeDGoEuBwiVzBv9AMVyTW7AIIV6OiNsWRQjhvpA2i3AKVYyn5NeGxWhFFhxGydfcrgglK2caomqBjiGdq8gbQmYtArF2uX1FVlNUs4J8ft9jF9gYznD3Syvys3ZEzuB1MtzbB2RrMzgHE+yRQ7LgUzkKa68v6dFJQP+YUBTcYU79ZoLRislaROUovE5O58GQ4Tq0L0r0mCqFomulkl84PGTDmo03MLS/uEn3I4fY22qzfdAULV9oaFwWMKXkLlZ4WksmZkdRu+XQvJ7j7U1Q4wT6I6rxGABVVjRv5EQXdjD9IebIMumsj9tJUHEGTz9C6VnUXtshX26RrjUBKc5GQW2zwD2IGZxpksxoZl6PMZNv4GXe8HIXJnzTGdlK/IdXHkKvJFRjG//4hLct3+a/X/lDWlrzw9c+RLXvsfwdt/iJw5/hO1/5zxiOfY4c2eN20Ma67aOOjcm3Q0xU8NV3/SJtKwTgcwn8bPphdvcb2G6BDsV6kHYCMJA1ZHhbeqK/cQaKMjQUq6Li9ncl1HJyqBTMhwZKhTrwsEslx4zp21pVUKvF3O62yPoe9sDCWIZgR4pVHoq9Rufgb9s4QwldTVqatK3uY1R0JiGzs0e6jBOXaqtBvGAYHRJQm5UIjrnymHK8ZdhqNKCmIaOWwusUDNc8RscKPvzUV3h/4zxv8TrslYqfzL+P61eX2LvTQkcFrZkx/ZtNGlcsou2SwjfEywZ/WxC8kxX5d29f4YxkCVA2JKWIRHC7qhRGWRnIw+YMJIQ2j4TTlDU0xpaBuj2RoIjSl5RjnYG/J4LLIpSGKtibFqdcjsd2rFG5UEzTtsxamldkcG70lPSZGvJQxKbzh7rcGbfY/+NVGvuCKQ72C6KLu5AXGN/F6cYYx6IMJWmo/somJs2gP8QzhvmkLhu9zR5VMwStCW9lDE/U6J7yyJpQvyXHMSuusLKK2pUeajjh7t84TDIv3a6/n9N5xyqj0zm2V2LZpei9JmLBytolbtf6GqZGMGbMXExxegllzZPNtmPDcIh68ixp2yO81sEEHvnaDCiFtysdkhrHTM7OoipDtjYDxuBtj6h8G7eo8F0ba7cHWU4UOjRfm2A8h8z+htL9Da9n1i+TmxpfuHWM1sKQ/+ns7/ArO+/mp5f/mKd9CxBG1cdO/RGvrid8cnSWf3Hr/Xzv+kt8sH6O5+NjtNbHPPbuu/x2/wn+df891OfGXCkcfnHz3Xz++nH0RkDtNgQtRXI2JqrHeE7Be0+e45HwNp/pnuEgjTh3e4Vi6FC0DSrTOLc8KQgPD6kGHmoi1gs90Tgj6749QuiRBnskadO9zQZ4FVSK0q/wOnITxvOGcFtEjr0H5azn70osVT71h+UNQ+ka5h/YZ0ZXbN6cRSUWZr7A6Vly7CpFU5Q3DE5f8LZGTmA444r2JemEtp9yWP/YEP/AZVgqQivjA2FKv9L8avft7I8iwnl5UxujGE88ETgWhsm8RRFB/YY13bLKz0sVarpel1AItEXla4wSPv49O0hlQbpgGB82eHsaa4oOMupe8THkNT3tFqfeycjQej5j520eyZrEVN3TfGWtCp1JoTeO/D7uQBNtSjdX+oiGbWRI2oqsBfZ8wvAr84wzsDMpAMGBFKsqCiQhvO5jDROKpkcR2ISXdsGxJcZrTgrVZNGl9ekr5GcPowqD3RkzPt5mvCQLnfrdEq+bM172qDyFLhVV5DF6sI2qxPNZBBBc2qH2Twr+6+XnGFcuv3jjvew1alReRbBlUduwyJrgHQgSx1iCxHZ3xqitXaxahHEdVJJRJglV6BLcHogkxLJwLm2iQh8T+hIMe2Se6NaYouai0wKrN6FqBGQtD7efoQfSTRUnVkApjGVRBg7qxYt/7XXgz15v6oL1rvplTrQH/Mj853mnr/mpu2/lZ1Y+yU+8/oOs1vu8c/Yqn9o5Q2DnvH3mOi8NhMa5lTX537efYXPSBOD9Cxd5b+0CvzH3FswX2nzf7Z+ERo7jF5RHEvJewOqfjhluBJQ/NOJwo8tPz36B//LWf8LupI5jlVSZhb9ty0MQKgZPpDiB8Mn12MI7kHy3e3OlvP61WYrk3E3V72MLNbRkq5dJgGpyqECNbCbLUxDhvgyXrdyQ16TLi1cLnnr0KoeCLs/tHmXz+hxOb5o8HdvTWZ0hnpuqzLvCkXdGchRJmpruKYv4UAF2TnjNRcU5M7/7Ku3z69x5S5t/018iNxavdFcZj33qzwYUEcSPTyj7Li7SAcYLMuguQoO/NyVlBIaqVmAlLuGeofdghbMYY+6G0C4wtYJEuehcyJx5AyFMjKQjQotbIG1apC1FvKCo7GlArIb6VYt4wWGynkMmmY/JfCkJ3T0fK7GoLIMup6wqI4N7VYndpfSEVjBekVCN2gvR/cDdYK+iflMEn8bSGN+mcqxpsQqw+ynO1oB0fZa8Jkywe8fS+RcHZA8dYftpn2DHkDVC2ldyFr46ofQsVGWYLEhqtBVX6LwiWfBJ65rKFZb7/Jd7xGeW+MGFj7Fk9ziXHGL7bhs3gdotCysVbI/RBu9AQlH9boV/kKNHE8xUL5ivNAU9NNfE2eqhKkPVCCXkdXEWkhRz4zbqyBrlnIW9P6Ka8UlnQuKHawSdCrdfUHoWVpZj0pSi7mClJaossV69Spmmf+114M9eb+qC9bi3w8fGj/PswQn+myQkKWz+8PJZACxd0W+GfO/KC/xx50F+784j7F6YJzw6YL3W4dpgjoaXkBY2u1mDR1sZv/b4r3DwaMi55BBfHRzmh+a/yHGny28/8ji/9va34n08ZPTiHC/5c7zj8k/jb7j3tVp6vuLvfuQTdIqI33z9LUSvBKQzLpZtmHlNSay5gmRmGn4Zf63jqBxD2gIrU0R3FI3bJaMli97DBVYzoxUlTLba6Ezaba8jgLW0pUhnDVm7oLU64Extm8/tnSD+6CJRQ5EsVBQRBLEYZEeHJEBi/ssiiqzdKXCGOd0zAZNvG/LM+iX+6PJZnlrf4KVrDxIfqRON5xgcrvGlu0f45vYFbiWz3Oq0qT8bkM5OnQGlAq8in1HkMxKEoLwS1XHF8uFKxFn9vEu4U9E/rjG2obwVERwoJrZYR4pIwlO9rsIZSmFR0mxiLEhaFvGizAx1dq9T07hdRftKLsSKrk21mmBGMmusbkdE+5LvOF4xZFFF45ro0+5JHUpPjo/dM1A0SlQqWqt7XKxwowedPiiF8j30OEVZFmXDwzkYQ14welCsQLWtEn8nJboyJltpYCzN8JAnxa+EpS8OKUOHvO6QNiU4VReGaCujcjRZw6bwtQQ7ODB7bsx4vU72ox0+XL/B1dziUwdnCFsxxZZDXoPxGthjqN8UK03a0NhjsT0VG7fkeViaJw9t8rpFsKuwX7uCPrIK1RQXU5SUV2/Ig3X5Gn5+hMmpeblX0wq/J+ODdMZGlTZO14euwr/dh61dyl7/61ID/uL1phaOfubcGu+d8+9//ed2HuOFg8N4VsFmv8ngbh2Va0xQcuzYDrP+mO+Z/yrbRZPne8foJiHjXLyHo90IHENjZsz3HH2F0/4Wl5Jlvrv5VR5xv/ZnvJ7FfGz4CDeTWda8Lj8x8zJNHXA5H3PKEe3Kky9+L9Un5oi2S/JI+ExqGjx5T/OCkc6hsqAMBLoXbVcSVzWv7j+Q6WyFcQxWLEklzkCKXNY05O2SYye2ef/CJY55u/zq5ju4/qXDhFvSOSQzMpAOt6fO+2mQqzsQO0keQffhkicfvs6Vg3meWLpDaRSv7KxS+w3pPmsbY8rQ4eYHPMzhmCqzqLUmjAYBescThhKQzYtvJtyQkAI9PZaUAcSPxjQbY/qDiCOLB2x2mmRbEeGWvp9SU7nTDV4lLgBnJD69tAnpfIXb1RLf1jFUrngI7cTgDsTiU/rQPVsx+9LUVnRUCpGxZDbmjBXuY11mogm9j64yWRJRZf2WYXBUkbUr0az1hWSx9NwEZ3cIu/so38fkOSoISE8uogqDTguKmoszkI5C5SUqzjCuQ9nwSBY8SkfRPW0RbUoQaeXINtnfTUEr4gWPeFYT7ZTUXtshPTJL2nYoAvl5Db9vwGirhioVP/q+z/BocIv/4/b7uf75IzgDJXSHECrbYKWK9iXpqqxJgbOxQ7El9E+r1cSsr5IuhFhxif3yVfK3nMS93UXlBcViC3u3D2mGqYVUjQCVl4yPNSg8TbiTSXF3FMZSjBdtWlcT3DsdMIbqoItanCM9PEOZxXz+8//0G8LRv+p60FX8y94hXh4eZitucBCHjBKPyVi2VngVupXRrE+wlYDlfmHjfYxSCUlQytDdaEMjR3kVes9lkNT5v0ZPobY9HnzrBt/ZeJnPJTCrY0oUHxs8xsXxIk81b/C+8DJ3CvCd/H6xAujebHPqSwPi5ZCszvShkgdYldxnbN8/Cnrc93qlbRkau/fEjbmiiEqqUhFuauxY9DX5Ys6JIzsMU4/zo2We7x7l5p8eoWxWjA4b3K7GGQuKt5pKLsTQaugfF1/iwtEDTnkJm6MmT69ssDlpsTWsM77SQi8oWldzippL1rRZ/1hMOuey86RFFmaYXLPwoqF/TPx24U2byplGmk/9jKoUaYLnZ4wmPo8cusNT7Q1+L3+E4hM1RmtMKZbCVleVFHFdyLG6CGUL5nZF8iA2EojnFI0NwelYaUURaPrzFno2I5mbEkNvwmRBOlCUIZ2rKCYecezihYJliTYN8dT8rXIlm0YtHZ0V56g0g5rMQavVOQ4eaZA1JfTU6wqCRfs2VpxjtKZYqGNsjZUIUypedfC6MPP6iHTWv4+nKeoOo2VHcgJLsdpkq23ieYfSU+y8p+T73/olro7nefFmg9bxDs/UXqelM+705UVyj2oqIwX5ntx+gdNLRKC6sweA1WhQPLhOsuARbsZYt3cxnotzMJHZk+9R1Fzi5SU57vkWeaRF/Loxooxc8rpD0rbIa4q0qZh9Xbybo7OLRJf20Y06ZTOk9DSTWfev5dl/o+tNXbC+/8p3cFDN0QyE0rmz28RyKpqNyf3/RimD7xS8d/4Ko9JjlEvSYz/2Gd1oYqcKby1hMvZkoNtOKTo+ulS8trHCRzZ+DKUN7HlYKxN+8MwLPFaXNJyzbvCXvqdfH85y4tcT1KWb6NnTGGVh7K9tboz6M5urcpq0mxqiacR6UnKfs20lkgJT9hzxNHqQ24rxWoWyK65eXUJPLMbrrnDllwsaSyIzKNOAoiYbQHsi87F4qSLYkQJjlOHh2S3e3bxEYlz28zqv7K/SPajDfEb0vM32Uw7JSo7KIbwT0tiocAeKUSdA+SXdD40pr9bwDqbFJZABvjOa5tuFQjAo9yIOHd3juxZe4oXRUaxfngPXYCdSLMK7UrSs3ExJnYrhkWnKdi6zKjuTTeF4RVG/KSk3g8MWecOSv58HfpBhxwHJnHjmdAH1G5pk3pB5hrLQ6D2XaFP49cmsYrxeQiPH2vaI7pj7gLui4aGHLqooqRohw2M13LEh3BesSulpnHGB3UswjkW6GE5ZYymVZxHP2tIBjkRk6UwK7EQxXnLJlyQYorZZUrvWRw8mbH1wlcpWJPOGH3v7Z/nuxsv8F7s/ROVXnJ7ZY8XK+PD5v01yoQUOoi5vSbftdUUO4e3HqKKiunQNqhJ7aRHTbmDvj6j1YrizDbNtiuUWRWiT15vC/SrNlMjq4g5K9JQo2nuwQR5J9x8vyIiheUnu8yKUOLKqFWFma6QzHlndIneL/9+f+//Y9aYuWNe25rFrHuOJR5HJkLOqFKOJR1lYaG0IwpTF2ojnOsfwrZxjtX12nTp3tmawcsXCYzscrne5eLBAcirHsirsrYi51wom8xKplCxWWCsTPnDiAhWKzx6c4vzmEv88tTiyesCHVl/i77dvAnAjnSdruYSLcxJLHyqszNw/OqGn3Y4j/2RNRbArx5qkrYjnhbUdbt1Tfd5Lm5buZXJG4uj3BjXKTY/SM4z2I1SsCVbGnJ7b5cLeIg+/7ya2Lvn8q6eJbjhMVoW6ms5IAXj8oRt8aPYFTjoHbJY1rrDE04sbfHJ8hnTsEv9Il3SjjXNgUx5KGDs28YJF7ViXf3z6T/jy8CifuvQA1UyBFYv5VeWgK0XWhMpTjA+X1K5bJGsp37P2EreyOT710bfSdCsmS9I16VShS5EVqFI0TmlD/IB5XQbz2djFvuIyWVDMXCgJdjOypgNaT8Wf8pmpzzZxRobxinRPlSvhElm7wgQlTGyCbY2dlvRPaNKjKSaxmHnWwx2KJakaKcLdDJ2WYFsYS5MsRdPhfCXFKtC43Qzn1j7F2ix5TYTLqjBkLY/BYRudw8yFMfbuAGNbGNchXakJAseIIdu5uYcZjUieOCEPvyM5g3+6f5JfeuVdBOcCVr9pm04a8vdufIjdVxZxxnJcHK9ON8X7imi7JLoxQHdHkOcURQF6qkWzLJRSsHuAajepGiFFaGMfzHoaAAAgAElEQVTlFWYiIR3GUsRzNu6wwhkV6IOC/smIeEHjjERaArKVjnZFVK0qiLZT0hmPtG3j9kuC/Rz8bwSpvuHlBTmVdqQ4ORXl0JHhb2JJjNdMjDGKC9dXUJZhYaHPrUGb4cTHpBrvxIBJ5nBz2GahNmKYedzdmGP5SkXp6vtkBberKdKIP7zzJJVrsMcapYC5nI+svUikU36pv8I7g2vcmMyBhtHZefJQfHyqkg6Hqai0CGGyUqLnUsrUYrJiU78mGz2dS1TTeA2CHSEK6EIe5njR4EUZ+8MIy6qwTg94aHELgC9fW+cHTr3A4+EG33EsYb8c81O3vpPZF2zSNtgjLeJJ1/D4k1d578wVBpXPP9v6IACXe/P0xgFZarOw0GfwxQXaO5LrZ10NqN0yjFcVDz+9xb/fepJh5vHM6Yu81llmK5/H37JwBxIKW0WGbAaiWxbm3T2eWbvOC/11nn39JO19SRAOdyrGy2IjMhqivZLSUeShFu9manCGmmLGwt10qG0a2ucG5G2fZM6ld9KidKb5eU3pOmfOSYK1O1QUviJr3qMPaEyqqF/XLH6pT+9Mnbxm8K95NK9VVJZIOnQmRSBtO2AcAiBrTscHU8Fp1rJxRiX2/ghchzKwJYHZ1eRtWYr43YrobopOCvLl1n3rTtawMJYsTPQkB9chedtJBoccKhvGj8dEYcaVLx+hcVOG8VsXFrBiJbq0QKgbpa8wfYXXA/+gItoYojtDTOjDRE4X1smjFE05AVjDhOroNL7Os8jrNtZeKsSMQJM2RO5Seoqs6aAL4XJVDoIEyg1z50rcfk4R2VS2RXg3wdgaZ1Tgb43IZ0Lpuqxv6LDe8Epv19C+j7EN9kBjIQ877QxlGeL9EGukUb7BmY9p+TE3vnhY3ub1ivFuxNgy9DLNfkcGomolY+tbhUYZBSnd3TrhdRevOxUkThXVZVTx+KmbjEqf//XFZ/gnb/04nxk/wHOfeIQ5tySrC64ma03d/a4hXSrw2wlLrQGdcUgcu1RDG9XOGJ50xaxdK1Cp5OzpXJJM/H2JMi+DCpPbBGFKzU/5gcMv8N7oEpVRsAKPeXLcvZGP+Nedd/D6vzuDl8uG7p6g8ORjtzlV22Ura/Kbt5+kPwlIrtcpWwWHDh1QRjFb1+axQ4EZ1jemWXNGjNTPb6wTBBlx7LK918SUGn9L3ub9h3Khgx542BPFeLVi0U/5wuZRjrU7oAz90wa3o6fscWhsGOq3UoylMA2bwboma4kItwgrrFs+M+cN9VsJ+u4elr9M1E9whj7e9pjJ0Qbu9+9jEo/8Rpu5P9qgOrTA3pP16VFJ0Xsix91yWP6dq5Q7u/T/xjtQxhBuTYNUh6UgWzyLtGmR1RRzr45QeYmrFOMVDys32HGFziqspCBfbFC5mrwmOrnSVTgTg5VU+LsxRivKwEFnJfHhOpN54erbqaSS61FMvtRk9wmXZNYQnexyOJpwc2uWaeo87tAw86pisiTH43BbTU3bssGsbRVYSUUZuhh3Bj2IUY6DffQIZc1jfCgk3E6ly4pzVJJSrLXxOxlZW9LFs5rGHcmR0I4r3F5K6dsYbWOPIdqVI3Bes0jmXMKtGG+/Im94WHGBs9XFBHLfpU2L1P5G8vMbXvZQg6XQY1FIp7MVVaNAGUU1Nbnq1Zi12b6wwbstebPuii2lms+hL0rCyoWiWXJsbY+nZjfYSRt8eeswzq4jRmgluiAQ64o1m9J2Yz5/cIJnTl/kU50H2U8i0nbF/sMWzkjeynkklo9iLodCk45dNvYX0bWcauhgJ5py4KKaGSdXdxllHpPMkbTmJYX6Sl3kEIslxjGUE5vMLvmBU89Oj6H+X/pc/s/99/B75x+lPRHpQxEBFailhLPNLTYmsxwkETudBvpWgDZQORW3785AbOH0pXgHOwZ3LN62yZKgWarMYtSvEWzaJCcTtFvyD3/43xHpjJ/7yoeoOi7OkrzlH1jY5+LtJbwgp+1NOH1si7S0ubU9A/sebk+6WGfiCEs8EMW9v6cYHa6wUlHFJ21FsGdRPHpYYHmNgHhO0/8BxY+/7dPUdcJnOg9wLWtRHl3CGiQsfm4flOLij7VRI5v6BpQ7u3JPpLD+qRh7IJ2PTqv7nYGqDOF+RV53KSKLwleiAD8Qc69RSryoDRtVGKJPvkrx1jOUyx7BToqe5BhHU0YOKq8YHooYrWoGD+Q0LjhElwuic1vEZ5a4+QGbahra0AwSzra2ub3Xxu0r3KGMCcZromcLdmS0YE8Mfq8gDzWlJ/e4t51QuTZoRbG9g3rLQ8TLIf5BjrOxS7nQRk9SOOhht2tkTSlWINo2ZUQ/Z+/lUBmSWYciUsy+lmCPc2F5DRXprE8668mWNDfovKRq1VCxHKGLQAmH++t4vakLlnENVjYdTHsQHe+jlSEvLVy7wNKGwMlJCpu81Dy+vMlXLpzBHUKybDBjG10qahuaaLui+4DNjXKZw092OR7u0Z0NqN55QFLa9FOf0MnRytCLAxZrQ567fZQ8s7l2+Sg6g/h0ypEHt7i9O0MydKSzcSvWj+wx64/51rnzfGVwlE+9dFaK1cDCGctK3rrtc+e1IxTRND9vys5SoRiqa4cHxJdaFPWS4wv7fHznIb45uvjnBv8XsglfStb53NYJ/AsBeTgtmHVRepexzee3j9P0E65vzcGeR94oscYWek+izr2uHAEmS3IkSJqarKnIGoZyOUXvukSbmsKHVnvMtx8+j6tKfu4rH0Lf9NFHJ2QHPrqRsz2s88TRW2yNG3zuygmqVNT+lldir45JgoBkzVB6Do0NEdB6XdmoNq8oggND54zwxtx+RtZ06TzgMj5UwWzM40dk+bGTN3ntE6fxtSFe9PEtjZ7k7D7dwBnKBnL2l58DwHrwFGv/XH5tPA/fOUFZcykCm7RpkUeKxkZGMudQeApvUOLvJtj9GJSijFySBU+w2p98gfLtj5I1Hfz9XKQNxpDXXdy9sSjIhw7DdVCJBJ16+wmDt64yXLOoajn+HZe8XpGvarSqsG0hTZQ+jFcVeU0WJc7YEG2X2OOSrGmLJqys8Lcn5DMh8YJLbWOEdfY0Ji/xd2KhnDYi1OUNyvF4+v0fpYgswt0MVRhGh3yMgXA3wx5lUFS4wxIrNfSOe5SBT7RdCka6KQUy2srxtgYU7ZB8LsCoiP5x5/52+Ot5vakLFkYsHmUgA9bxxCMIMubrI7QybGzNoizDg6vbPN2+Qb8MeKWnSGfAhCUkknQ7PF4yPAHeATgdzeXePMfDPd4+c51DTodx5fHiaB1blXSyiBs7s1S/P8uh1yYUNYukXbH7NlhY6HN7r81ce8h3PvwaC86AX7nxDm5eXmK83uFf9d5FrxeBNlhDG3cgkP90RlHfECBd3NZMlhV0REhZOYZ8LYOX2ngJVI7m0uYiX3jPv2DZrv25j2OvCrmTzXBwbYYok5s+nZcAhjKEqB0zF465tLmIezWgCAzegU18LENZFVXsUfr3IpxgsmTID2VYbonn52Q7EVYinZZ9ZoBrl7zWX+HXv/oU4RWXyaEC92qIY8FDD92gMhpbV3SGEXrTx53IxjJersi1h9JgnEq8kZ2CtGkxWdRYqdz0e48r5r9aYmWGvSdqU+icYHDMgUd2yKZbRPzu9UdJlkuSUznJZZ/WVY0du2Bg/R998c99RuX5y/d/ba0uU1ZI7HqkyeoKv1ehsxJwCDoFOq3QeUlZ8zCWRpUVteduUO7tYTUamHFKUFRQVVS+Qx46eLe64DqosiCZsbBSResi1M4foIZjnNYaOtfUrjhUT/dRqcMkdbk8WOCx1U2+nKzjDH3cPtRuTpcSSob+ZaCxkkoY/HFJGTjkDXlM07kAtytdnp7kGN9FjWMpVoC9tMhkxsGeVFijjP6pOrqUINrSs3DTHBWn+Bs5yWHZJPrdSjaHeUUROFS2QhlDFbpkbZfKUSQt4XOpcupK+Dpeb+qCpXJF5QFGUXoVpuMx0i5zJ8c83L7Lw+273Bq3aboJ50fLwiA/meN0bex9RzZMPYU7kA88bRvKsGLvq4v8ym6Ld5y4zmVrCU8XDHKfThqileGBlR0uvW+R8VpIsKPony6pHR7g2wV/9+Fn0apiP69zN20x/pMF6jkMd+dJlguwhL+kShFBFqHkA9qxwT/IsMcWaIfRIfA64rrPxzZ5vSJrg7UY80+f+H0Wpubse9e1fMR/+sf/ALtnU98W31w8D2o+RRtw3ALPyRmkPu5lCXWI7ggXTFkVbpCTHzVkmYXu2+gMOBTzyOoWO5MaOzst5p8X4kTn7RmOgvcuX+UPNx4kvOKS1w3BpgygnRGce+4ElWsIdjXtjYpgNyOdsUlamtExidxame/TGYXM/EGAlZbk0VS+YYsBevWzGc6oYPupkPSpEe84coPnPv0QjWuK7tsyXr94iEuDdWq3FM6iIbjo07hVYKWG4PaA4KOX3vDeMe98jHHDwd+dYMcF40VfHs6hbLm8XkERakBjbI1KS+y9AcWNmxjfxz60RnxmCSsuyeu2zLbyCqcbky82sAcJ2VzEZEkzc84w+/wOnbctsPNMC7+W8ujKdR6pb3I3bXFr0qYThzzRvs35wTLtZz3cgQD5jAWFK0e2vi+8nOaNHHuQkzUcklmH0YqW7q0zZW+NY7HcGCWb1FYT1W7Rf2JJaBIpUqwKQ1bT2LbG7WcY16YKXfKWT7zgyFwrMXJMnJFiVb8p5ujKd2RbuSYbQ79bCYPr66wzf1Mr3Y/9o/+B4pADbsXico93L11jJ61zsbPIKPZYbokNZ9nv83JvjY3ODNVLTUp3ugY3kCwVtM7Z95N6QYadaVNhbElLniwpvHfts9oYcKy2z4PhXc56d/iV3fdwsbfAwUC2dvHQx+Qaq2/RvCLZgL0zBpo5tp9TlRbc9Yk2xdCazlZYseLwpxKscU6yGFAEmvGChd+t0CV0HtSkcyWf+5v/Cy1tc7csOZcuM6x8WtaEF8ZH+eL+UTrjkHHsUlUa7vo4A03erCjbBfWZMUnsYl2M0BlMTqXYXokBvHMhybxowNy1MVpXJBNhcc22RixEIy7vzFPeqMngfiqzCfZE6zQ5nol3b6IpaxV4JWps43Y0wa5Cf9s+Z+e2+eKNY3AnoKiVWK0M51JI44Z8tjqH2dclsw+4HyS69faQcz/zC/d/7k/807/H6IjMEI1fUr/kSDBpZvB3YqxxxsZ3z07DIZAI9WcHcO4K5i943PRDD2Aci/HRGllNk0cQHMitXln35o+ybfR7FcFuLjYUSwqYcSxUaRicrJO2hAvldBKq0GG05rP7Nlg6u0tnFFK93sB7tAvAsBdy6vA2e+OIXj+iVks4PbfLY407/M7NR+lutJl5WTNelTBWewris2OJGIu2KoK9nCKSRUceaRpXx9g7PYxjo0YTRm85gtvLcC5tUu6JgHT0vU/TOy6BFtFOSe+Y8LMqR5Y69dspla0oIgudGfK6vMSjTbk3lTH38c7GUlSOzIH3H7KpbcrixN0aUE4GfOrWL3xD6f5XXdl8ydzamLqXcbK5x43xLP0sQCtDuzah6cZoZdhJG2wN62SXGwQjsJUYdM3hGOdmQDUF9Kup8jxryUxM5xI8YWUQf3mO8w9EzB4f84HoMueyOd7dukxuNG0/ZtEf8plXzxBdd2SrtzrF03oV2q6kWG17qBJGhyvsWNF+XRHulei0lBCFtKJoW8xcSnE6CftPNsiaFY88vEFL29S0zykNd4sRF5IVLpdL/Mn2SQ56NRFFWka4VK2CcgaUXaEGDuNeU0gNFQwfyAmue9JBMZUU3NFMViuy1Mb0XYw22DMJeanZHdeoSo1zfEi8F2IPLZy+FPLxmiG64lJE9zjpiqKmxMPnQuHDaKvJF260paBFFbXlEaOtGl4uvkqA9sUce5hjbE3esPF3E6zdHvGSLBQ+G2t+9IUfwq0rFl4o2X/EEjuTgoOHLNw+hLWIpF1n5QsJ7maPqhXBSxcwxV8tZIwP1xkv2cTz0s3JhyERaIXPVK8myJnCUzijXI59oUc26wsgUcF4yWL2fIqVlIyP1hgvaEbrYB8acTCMaH40Iv1Ih95ejfbCkH/w1k/x2niFtLQ5PbPHQ/W7nPa3+FBtQIXi35ePMxi2aFwXQGFWE11bHilqmwa/U1AGokaXrxVYoxSTpNDtU04mpK2jlL6HqlZwooCqGTFZ0LhD8DvVVO8GXq/CmRi8Tk4RWjgDmZhnLZvhIc3iCzGqlEKlD3qUS7PYo4yi5tI/aVOEiuiuYfb5XdRwjMlzTPENHtYbXo+d2eBif53+MCQtLXYPGphS0WqPWW+JGfOV/RUmqUtyrUHrmrjxk7Wc2pwkxPiPjNlrtaldt9GF0AsmS9I23+sm3L7B7QMEbCzM8I83v533ti4zbw8A6CUBLTeGQm7yzsMGU8/FNJhrTM/FGmh0gUQ5OYaFzxv8TobKKsnY0wr01+LG04WAziMV/+MHfpPvrfX5s9vAGWvCKX+LX918JzU3I40SBqNAMMt2hfZLGXB3XdkA1UrSJye06jFl4hJ+sSFWIS0spXjJUEYV/tWAdLbEX4hZafcZZy4rtT4rtT6vba6AW1E5mvhERt50cXtCVrDSKYsrAGsix1idStFSucb4FcHhAcfaHc7fXaJ5waa2VRLPapx9+fvqrCBph9jjUvxqZ5doXVI8/L/9ODMXCmZDzda3ZPjvHfDM4k1ePlhlr18j3w7JmoJDvjdMfyPpon1snfTwjEgoLAmlKH3ZGrr9aWfdljbbGUkxLz0Id+VYlK22qGyFM8ioXEEgt6/kpC2btOHef9FZMVRXauShgR/Y52xrnw8+cI6n/Zv82/5buNRb5MH2NoHOOOGL3+/ZpOKF7hHyQjonnUuRGq/J3M+OxT+5/4jM5koPirphsuiwYJoEWgtGZnWZeF7ScGo3K0wUkLcDom3RuXndQrojG/l9XEU87xDs5Ti7Q5yqQq+1sRJDPOdixxV+UVGuzlHUXJJZB2Ug3K+wEoFEpmstnL6PSktKt4QX/798yv/fXW/qgnXuxWM4VUB1JOVQvcfO1TmMW2FbFdc6cwx7IV6UkQw8iEoGxy1KrwLLcHSmw4+ufpaNbJ7/Wz1F/tK8DMBbkt9nTUMrjdw/97lKWWnx+v4SAMv+gJd3VkkutNjPlmC+IFkosSeaQgt8T/5nxEqxUBLetJl/ebr7raDyLCpHjkCl/zXscueMy9NPXuAx7y6fjhu8Pyj5N/0lXhyt86GZr7BgDfmR1We5EK/y8eQsVaHBrWjNjiTworBImjLzMEax2BySV5p4q0ZgSSchycGgS4W/Z0tm4VijdcXG9ixhlPJaf4W86wl4EKi8Ct1zCLcUbs/gjoWAWjnCgs+aBp1KV5q2DLXVAe9avYGtSv7ghcepX7GJdirsScXMXoY1ytCTjPHxNu4wxxpkjNdr94/ntdsVaVMzWtP84Fu+RG4szvVW2Npv8p8/8hz/7bsv8UMb7+PF//DgG94n9qE1Ou9ao7JFWBpsjdl/qMnwREl4RyQoMgaQz1+VUqys1FC7a2SeVXdJWzI6mCxFTBY19sTg9QzdMwLSi+6KRab7oOJD3/4sb6tdpzSaWWvEV+N1/llXRLofWXuR/bzOo+Et/uWtb+LvH/40P3/7g1zcWcB6qU6ta/AGFYN16R79jmFwTHBAIN9bclJU+it/agivdVBphlEKLAtnZHCHFeNDIToLUEYsT+6gxEqkm2/eKCg90Qq6E9GWqSwHpXD3xug8oHMmIDlh0byuMVpIrGjxxqpKmGSqNPhpKVqwhqK7Yr5RsN7ocg80xarhyPIBlZGjCH5JUWrywuLI6j7jzCXPLcrcJZ8toFAcWj3gkeYmvsr5+M7DHLw6z+xE2u8yACoYPJVgOSXciIi2RZ3t72q2F5tUQ4frTsHFziLpuRbBgQyvwzs2yUJFPp+jnErSZrR460oXmudtZs6nVK7G340lFmk6rwH5c+sbE4rIwRkbDpKIf3jzuzhe22fe+iJf6J/kxmCWM+EaJ71tGjohrWyGEx/bKcEpGU88FhZGpLZNWWnKSuM5GTU35cbBDDqWB01VECaGPBS2eeWICn8yU5DvRRw7sc3dbpPqboDyDEQ5jBzCWxazrxdMFoSWUDqQzGriBdloKgNomCxXtI91+JlTn+a/+/LfpPmcz3JXtDt5KMZsu59SBg7dsw0aNxOcrQH5YgMrrcjqlghv6+L5S2crvrVxjl/Y+mYu3pIXxie2HqRbhDy/sS5m8b9wqbc+zOBYROmKREMXkDY1d56pozND86LwqKxkapdyASXm7XsEWIDRssPBo4a5lxVWVpLVxCQd7Ff0TsqLqQhg75sz6q0J33XkAh9ovsrvdt/C07Vr/PLOe7g1bFMZxeF6lz85OM2SP+SL1QneMXedC8kqr91Zgbs+bib0jt4JCyuBcFfw1ZUtdAlnAKN1Uekf+uMRVj/GhJ4cydKM7MgMXk+w2daoRFXTl6YGa1KApZgs2ORTr77OINoqxULkuajBCLO7j7M4T/FESNYy9E7IW7t2R+xLhS9EC69XUfqKZN4lizTjVU0cfIPp/oaX+9YuCzPy6zvD1v1ORinDB4+e5+Zkht4kEGFmqVBRTq2ecGdrho9OHuajPMxoP8ItIW1o/J6I6PrvjXGdEsuqSFxJUc4ahmotZn5myMHmPP3YJ554KE8sM6qCZLXA3bcxE2mbrUTCN4tQhsDzX51MKQAlRTsQENr0JjJKEV49gL0D3NUlnv7515l1R/zu9Uf52bVP8Ijr87fmvsxv8TY6RcSuVcdVEmaqdUW2FYGWpKC9KGI2mlD3U3a7dVphzCD1UQrKqCResCW+aiI3c9Cp6J6WME9iBxVrQcDsheAbjDa4dzxqN8EdVgzWbUpP5n6SVgN5q4JGjpnYFEHBE8du8XeWv8BP//bfobkBte2SyhKcs50YwisdsC16jzWJtnKczR54LlZSkLUcIYEGivmXErKmzeaHc3724ofZuzyHM1TMvm64/S2z3Nlpo/dcwl2D9n2qJEF5Huk3PUI8K3FmpS+2k2RWfkbzz9nTYiQ4ZF3KEUvEwSKRuRc6O1mcFqddxWQRhkfEJ1i/KanOTFFB6VLO48duYeuKM8FdPjd6gAVnyLw9ILJTtrt1HlvbJKssumnInWGLU+1dHqvf4ZM7D2J2PYIDdf+45/YMwUGF3ynonfSoXIPbN0LguKtoXS2wrm3Bwgzq5hZFt4t16jhFYE15WhWVK4pnK6lEEhHa9NcdKkdR2yrvW3J0WmICD2Nrqo0u2vPIl1vEC0a8ilsSuKtKGfI78ZRSWxqM1vSOWV+znt3LePw6XW/qguU7Of1Y+LtJ6mBmM2ZnRjw2v8npcJvX+8uMLrVxUxFiVhOb8XYLZRtGsQW2gVxhj0RFfPCwoljO8JySdOyi91y8jiJrGarVhCqzGHxxAdMw0rXFFjSE1a6MwtuRj0tNE4FR0j4bSxFuT13xSYFRSlhL8zVQCruXoAcTSFJoNmj+0i7/1cKnuV40ydctTjgJEJEYh7qd4KiSdXefhkrJjIUxj+J1pl5BXwr29qBOUVgEQcZut04USkoPtqHwJWS1GEnnsf9WgwpS6kFGWWrC9oTJRgNnMkWvaMjmCkbGxuvoKebYkC5KFLwZ2XJkzOUcZ2KbV26v8ZOv/W1WvmpwxiVuLydeFJ3X7OtjspUmadsh3CkIXrxBdXRF7CNpzuBQnawlwaXjZZfBuqZKDNnvz7PQNzT+rWir6r+lMO94FPXs88DXqD3JM4/QP+JgxyJCLQIprOlCidW3ccYVSVuTzkxxMlMsjhwFpcvWU49j61rJaMWahlRAsAPhXklW04zWbCbrOXbP5qmHrpGVFkfCDv/qxrsZJR4PL2zx4eZX+fTnHqWMKm7UZkkLi7Vmn1976DcA+K3hQ1zbmSPYkeLhjMz9FCNdwu7jHkXNUNkGZ6TEuRCC180wq/OyCOh2sVpNspUmw0P2lF6hyCPRtE3mpEMKD0qZPaUiSvYrsSYpY0iWa4I+PrxK1YoYHfKpb0i+o5WJ6r6yFfGciFjdYYUu5WUu3k/II3OfqPv1ut7UBSv7+DzxSZ8yMLTPK/rHIVrqcCbaYjNrc6vTxhlK0AOANbCxEsHvYhsoFKpQxA8kJGcNWhtsZSQxuu9M48wNpW/wLgcEu4a0DcY2mEu1KRKY6RtX5l+lLzYa6gXWrovODW5PBqjDowFW5mMUFL7GmYg+ydiacqZGWZth44M+nz708yxaHv1qwgearzJnSf+uqXg0us3TwQ1CVXI+nyM3Nnlm45bS0dlzE4ajAMuucJ2C0dDHGEX/ZlNy+KYm3tIzFBFkMzKinp0bUlYKraUYO0NFERmwZCZFKhx6ZSBtiIDTGtiUlkGFJU6QU94JCe/qKe7ZJtqUEqJKKAKLLNL4nQqdCLLXLw2qrKjWl6VYGUPvwTaTZUEqF5GiOJJSZRbLn7RpffI8yve5v/cz/w97bxp72X3e931+v7Pfffnvy+wznOFOipSozYktJ46U2k6cxU1aFE1SNC8CtCiCIkCbFEidAkmQokELuCnSFI1Tw0XrOLWT2IakRpYsUqQo7hzOcNb/zH/f7n7v2X+/vnjujCrU6rtYfKHzisSAl3PPPef5Pc/z3Szq1Xd/4JmY/cJnSJp6bm6nJDo+EUqA19fkdcvJn43hVlXG0nlxsA4/ALREpwZvZpisOnOPL0lgDkaGpCW0g6JqoVT89Z/9Le6ni5ykNR7MOpz06wRhzv1Rh3/3vb+MP9AUuWKyEPAfXn2dv9G9TWkr/IPeE/yT659lrTukR0XQu1Seo6wJaUvE0qUvKGzlKCde9KltW9KOj2p5uNMS/8pFioUawwsBTip+Yk42DwDOLeFuOTds1BSBojotyRqORKWNcsrQpQwdxp0qRVij9MCbCQcr7oru07hibxSeWKJTsUm4Q8kAACAASURBVNeZLnvMVg3hkSavWrypIrqr2f63/N7//12f6II1umgJMkX7hkDkdjPmT62/S6hyXh+cpyw1+WKJDY04fGaKvAHB2hTfK2hGCaeTCvE4xHFKjNEUiYt34NHcUzip0BN0LpyYtC1E1eBEky6K5XF0IP7qs2WJL3+8uO4F1LYt03VZbOpCTuxHVrMA1d0Y62iRWWQF8aLPX/zytzgzZ7A/H/zg9w1Vzhcrd7mXd9jN21R1yuuji4RvV3BSGL2c0PQK0sSjPIhQmxPWlwZs31tEF0penAiSS7KwVeVcTJtqTu92ZExaTCn6IY1ThU4VedNS1ErckQixMYIK6hyStZzGwpS8cAi+0aByJGk5uhBHU12ANy0fAwqNhwneyQyyHHdYYqoRejAmP7uIG+dMLjWZrGnQYtqXtQ3tb4QsffMAHIf0xUsE230QYA333Bn2/8Q6lRNDEUgitJmDJDqTMT1rCoXF+HOeXSujyB2CRHhy44vih6V6PrUHGie3eDOIjnKOPhWQNyxOLC+qdCuiRDCexe8r1GbK7XiZEs3Pdt+ltJqPT5ZIUo+Dkw5ez6XzuSN+Zv0GT0U7/PnakNyW/Op4lX/81S/hTjQnWY3kakr9nYC8Lp5YqlCEJ2JYiNXUH0pn1LmZYx1FVpfi4+QOQb1L3JXAD29mhLNV08JKL/9f/MJRiRNoiqpD2pS4+bzikrYcks4c3c0sxlek87zHZD1HhSUMPaJ9h8pxyWTVwfiK4bUSqy2zS1Ll3bs+/o+lOT/86nyoKBbh+BXD2SsHNI3mv//eT+H6JeV+hDtVOAGwkKK0wQ6rkIF+p860bRm188exW3npQabxew7mfMxgxSW665O1xJ7XSSyNnizf06bCm2iSBYF13dhiXYV/+H0rmMkmxIuK1p1yrvuyVHdj6S6spaz684fJUtR9Zks19v9Ywd3pIiz+wd/3veQMvze+xtVoj0+FD3grOctrO+fwE0G0nIOAQabpLI9YXDvi1o0Niv+zRuWiJl4tyc+nOK7BuVORvU69JDh0CfqycJ5ulDDw0ZkiWRLzvLJqePnZu/xM9zo7WYd/fv85Qm14bmmPt3/tGYqtNk4pHcp0RZwLJmcsxjd03tMMLwh7PRhYajuQPNGi+nCKc9CnaEfQjkg7Hv3PV0g6sqPJW4bwqRFF7HNaC+g/tUzztmLxf/wOJZB++WW2/5hD0NcsfS/HH+WcPBvRvyZmiTpVWFe6SV1AbVu80cvI5fSpkOnGvBAAlR0HJ3YkFDUW7pNx4fDTAe4MvF1J0em/nFPrzJj0K6iZQ7Q64Wynz8G4zte3n+CXnvpN/rfDz/K9ty7zZ774Bt/cv0R/q0rpW651Dln3+7w/O8Pf/uBZ8tsNirUUXLFwLurgbfvEy5KSEx0olt6e4PRnqCynWGxQ1H3pdHxxWHATyY4EmC17OPMC7eSWtKWJu5q8AaPzDt7Eobpn5ioC2c2VgaIcK4rAwR8b/Il5vEx3YsPuH3EJnxjS+r9bNB4olJHl/2zBEY7hUgGBwYty8pGP13OpbVvc0Y93WD/0StoKKrBx6Yimn/D+++dQucI71timxXpiA+M5IiqddXL02CXtWspaSbUTYy0ksY81inDLF/pC4kKiiTcLnLGDKmQnEPYNQb+keVdekPpDMW0D2T04KSRdYSUvvpfjDXPSBZ/ZombxOwP50TsiqTGBQ97Q+INUko1XNZV2zH+0/C1+dxbwJyo/yMz+T/Ze5tZoiS8t3eTZYJe3krP88p2fIPh6A10IM98bg3chwdGWh//mLNUMjl+QrfDmVy0nT0dkLUvYV8QrlspDl+jYYuaJ1coogiMZm868ssMwCeHNRd5+/TKTTwUcjOuMD+qgLa9+2IG5L3pwJN99cHUeWTZVqJEma0J8LUGd+NQfQrzoEh0XGN+B5RbuKKFohJSBJq9ZyrUUXAO5ZnarhU4hsOKSkbbkPkz+3Gc4ekm62uU3c9xJzuHLFbIGREcwumjwU4XflzBWbyrOrfFyiM4tYc8wuggYsV92YoWPUDSshjxSZE2FPxDfqtPnDbUzI9QwYnJc5dLFAz63cI+2O+Uoa/BrN1/hqWvb/Obpi7x5/QLe8ozfvv8k8SRA+RbrWuLS4x/d/iLDYQWTO3z2izd54945ghMt8WZ2nkQ9/7saTxbaapZg6/K8uOOM8YUqTmoJ+yU6tzhxQbIYYByFmwgI4A8LkmYgBWwoo1xt11DbjpmthkzXHIpQeGe1bRF0G0+Ttj3xbVdQtB2iY4XzsEX1qMS4iqzmkDUFuMgbooxwjz3KwMUpoLKvCEYFzuRHa9fwiS5YVkP3p/ZpBAkPBm1UOyO4EZE1xcVBtAVQZI6kKM+DJ4uKBd8wmwTYudkfVgIbdKrQfokxorAvGwWZcqgcKeofD2WEObOAzmTO16W4G+QVRdLRRMcGJ4e465LVHNzE0Lybib6rGuGOEjAwO9eYx9mLTUhRga+c/4hf3v9Jfqpzk33/4x8QNxfWYbM64NZ0hWFR4Vff+TSL3xTaxGxZ7GtNo8C5X2fabxD2LWHPsv5vJhIU4LtsfnXK4StNKsfCtFdGugkzD7+02hJvFCxu9nm+vcPv7V3GuJb21R4A/UORWviHriyCI0PzDYeoV7L9ZaivjJkMKqhxgD8SegB9n/VvyqnrJpDXNEHfgtYUdY+s6XH8vKLcTGDkU7gGFZVgpTNa/v0TTl9aoPPP3yP96U8xvOjQuGfpfJQwPhNQbLi07hRU7w/JFqs077s4acHpkz7uTAjAeQ28maBlRagIjwRIUbkY41UOxEZnuiyBtGFPbHlOnzIESzOm45CNlT4XmydoLO8MNnFVyc8tvQdhSSeY8sHpKviGfOZTOAabONhmQWdxxBs3LrC4OqTbmWCt4jvvXybaEaTSKRTBqcS+WSUd0OqrU/SdHWg1MIEHWlGGwpPTOcwWXCpHBeOzEZN12dc5iUP740y0p3U1R4FL3FhG9GQxIGlrgp4lKmQ/lTV9iRXreuSV+X6yqYhODCuvzxhejPAmhqTjkFch6QoX0WpwBzJ7h4eSKN65PkaPYspR/w+xAvx/r090war/1CFaeVy/s45XzbF9n/hSCqWiyDTe0MGZavQgnO8CEItiz0LqSAJzoURkjMTIq1rBUmfM4XYb3UnBKpwjl6yuyJareIHDdD0kXlI4u3OEpa0Fhg+ENxQMhVhX2/m+TKFs1ci6wlYfb/qMzym61w3u8Zjj55bZ+NJDbo+XqLgZ7083CXXOT1XuMTAuf3f3yxgUkZNzo7fMNz56Bi9X9J6xmG6OteAe+zAU8bE7g86NFP9wjEpzTCXEyWW5vvTmmPH5KqqUxbLVkNU1o6sGtxuz0h5T81OuRvu86Z8leOmQWeaxM2xSW5gyu9+gtgP9Zyy1u2K1O1twaHyssLfbdAYWZcVmxJsaOh/nYCBZ8Im7mtbdFKsUZVUWvXHXIe+UVKsZuV+STXxsoTn7OynO771NCbRu3EY9cYnxpo8/lGzF6XpAdFrSv+IxXXUow5bscMYFvWsBZShL8jIUpriErzroXO4PSvZw/kg6q9NrDm4i9jaAmOptOSTjGtGVERu1AdPC526/y8X2KQ9Hbf7Om7/Af/onfpdNr0dSvszxfhMVO+jEo2wVKMcweb+Lcy5hOIkodivUtjWdmSzEi0eSIA3eWMbm1q0Z3sNjTFGA6+AMJthKSN7wKT3FZENT+tB/ysWbu30UPngji/E1SccVNLqw8/WE7LPySNKE0rbsZL29EuMrTCCgQtQvSeeOqDIyyqj4SAKUN+RQ07ncN28s0XFgad5P0P0Jahpjqz8oyv/Dvj7RBeuo18C72cI3gPY4/5ld6l7KMAvZeWeNMrD4A/2YYuBOYfSUtKxeI8UYjdqe28jOa0sQ5YzjgIX1Ib5bcHjapP4Quh9MsI5merbG6KxD0LcEQ5GR5JEw4oOhFX3W1ODGJc4wwdR8sqaPbXj0r3okHUu2XNB90yU6zjj+/BLDp0qGu0u4XkkYZYyPanxvfZPfbT3NII3YOumQzXxar/skXYVZKbEOeCONexxgPAlS1dUc907E8htTnHH6OE7dBg5FI6AMHPqXxX+8eiCcs/GGw2zZUl0bo5Wl//VVjqvwzZ+ZsFEb8Nqti6As1UZC+nGT2qFCZ5bl1xRp0xIvauJlS+uGpbafE3elaFot0Ls7iMk7FfxRQXhi8Hf72MAj2WwyW3IZn5UXIb/eIG8a3Jnm/G/NUK+99/h3jn/+02x/GdbOHXKxecLvf/AE7Vuavc+LvkTniqzh4A8so7PBnHclC3dvLPu5tCmomJNZlJUi5k2FBJnXRFtX+rJ3LKpCHJ2cL3BaGRutAdePV5hOQ9YWBmhlOTpuYCPDjekqX50+yc33z+DGiqJRwnpMdL2CLj1BmYce3mFEe8fiphLlZudAjJOIJUvYszTvxbi3tuVcXexSdGuPLW2MqygqQhydPVliPYOTuJhCrJLdWHIbiwiwgkr7E4N1hY6AgqwhNBbPyIrDm0hxVgayqiYYlrRuJRhXM1sLMQ7Ei5qsMad+uEKD8EbSheocKsdzWFUpbLvBbC2A2//23/0fdn2iC5bp+zhPjPnj52+y5I357b2neHjUwe6FlPUSZ+IQDOTUTLrCr1FhSb0RUxrNbD9CuwLRZ215kJNByPrmKQenTYIwo/O1kO73+tjAwXgOOrdEJ3KCTVdEBhH1SqI+ZDUtrpBxiRMXqLLEuBrrKiZrLk5ssS64fZfBFRifDag/gMq2w2wDOhdEm7h88YC9QYNbp4sMhxXcByGXf2tC1lbo3KO2I0hVvGTIupbqQwcVFdhewOp3MtzjETYMMO0aZejSf2Iu1rU8DsQI+gXWVeQVh6JREs8C9MMQ1ZI05W9/7xrWN6yfPWWpMuadj8+x8DF4sSFpKZJF/Tg7Megphpcsacufj6IlQT/D2zll9OIaRSRBskHfYBoVrOeQNRzGm4pkraD5kUheymMHb2wZXqzQ+o5CuR7mpWuUgebsvyzpXV3h46Nlzh0XHD/vUMyNCY1vyRuWvK4pAzsP+RBOUNIVJn/l4FHnK8/Oo4JWhpLpp0oe5yIaDzg/pV1JOdfqsTdpMpsF+EFOxcu43VsguhmSNS1fe+NZoj0HtWS49tn7pIXL7RvrFFWhw5jQoHL5e5Whwk3npEsjTgzGVwR9K+hebwqui53FqFLcTbOWR/X6IVlzSdQIEXNAQT3+nDIQOoRxwTpC5SgiiDuOFBoHylCKlnVk9Pw+sRTc1EAqeYmqtGhTUjlMGW8EUvwa37fIdrL54W5kmmjeyfH6MTbyKasBlYc/Hgl/6PWXvvhN+v4Cz1R2+OcHL9KbVCgSF39zhjYK01SM3ZCiItSCom5h5DHKNfXrPo1cOoGsCcWa2Bdc2Tzkzv4iWlucV5t0v9fDRh4UBlUKtOyk4nxQ2ytx4vKxcl/nlrjjMltwqB65+IFD6WlGmy5lIGJgfwiVfUl2sY7o+coQqutjDnfbbJ454e72Eqrn4T7UNBPL+ByMLlXRBfgTOf2DHlit6dws2fuiAatYeEeJPc21xXnMuuX0aQ93Bs27OXndQY2kqxCEUnY5K+dPyQqH3pIj6cx70o2cflaY9B/urhE98ABLEQjC9Cg7MTiF2ZpE0qOZL3Rz3P7ssUuAMuIK278SEvZ9nETQVm8CSSphqr1PFaAty7/nEvZKzBee5+CzEY0tQ+3hDJWW1Cs1+X4rwjbXqaJYyghrGclxJJ78BryxpEFnTUiXS6JDh9peSdoUS+asIeCA1VBUDZ3nTjkZ1GAvZP2bhuPnXLK5rGlv0qTqZ2xs7jArfG7tLcN+gBtCsZAT3ffJG5ba+SF/df33+NXDz7LVF3Jt0NPyrEjGLNVDeVZmy1poNloRnhqUgcYHJ6hZAq6LWuySrzQZnY9ofTwhX2sTL7rU9gyDi1roKKWMZ6IFnOdbekKEna1IMSsjEXY/KsJqjpqKvEaTR0I9cXJ5JqbLFYKhJWlLkQ+HhqywRAeyCyxDAZeCoSWPFJUjg9ebgbUUnRrKWLKlGvxwG7J/69cnumBNypDffOsFvnb/08QbJSpXrF09ojeuUlpo1mJW1w65fmMT/8ShDCyNWw5WO4+jtqYbBlMxKGWJaim7wyZ26OPvOKy8McNGHmXoktdckq5D6anHkLg3Q0ifnkDNeU0y3JwcpsuylEwbmjJSpG1LdCTL0Gy+D1AldD7OOfiMi/luC7dp2e+t0NxWVPdLeldhummp7micTPRhKHASQzDSNB7kxAsunfcVuvSJFxXTNZfmPUN1J0EXhuXvlkzWfaar0sXgKdK2Jl4MSD83JvJKRrOQeL+GO9OPH8jj5wV8cLQhH/ssf1QSHmfkdRfju8SrEN6TAhWeSACDaPYUxhe/qKIREgzsY6M4DMRd/bjTMR6Ex5rRkzkqdqjsa44+U9K45VGGHjqFymFKshBShorReckgrO1J5zpbtbhHPsWxLzzgeok7kfueLFjylqGy7RAMLeMNh6wB8aWUtdU+x4MaZxf7fGHhLmeDE/7Xh59j/M1Vjp93ic/kMPWYWoVWluNenWC94ErjiP1Rg0Hbwa6UuNqSLrhYxzKdhvwXH/5p8jfb1I6F9KoKGffcqbDXrYLxWYfykWYxtsRLGie2qKLENqqYwGNyocZsUe7T9EyVPFLz0FhLMFBY7WB86arq20a600CRV+UQ9IfiofVILK2siNyTjiB803OGhTccwoF57Pk1W1akHVmhOKn8NnnNIW1LsEtlV81DPQRJdTJLeCpi6XyxStoSlNHb+bGW8Idev/kvP8fafYe0aakcaE4+U4qVzMTHCUq0gpt7yzRuuYSnlrBvGJ4XglxRgWSxZPnyCbPUp1OdsbWzQPOdgKgKi+/n5DUX4/n0nnRRJdR2jJDpuoratiyblRGyni4k6cVNJGXGG8ls3/+MQ1EzBMfig5625KGqP7AEQ8N4w8UfysOi5kjlbAWsFm6QTgWaTtqyi/Nmdi75KUlbLklHU98RkevRFy0q05Shxh95j8cfyTYErCJryedNrmWca48YxiHj2x3cAvJuweiCS+OuwszVAVtbSyy+6uKNMkk07sfEC21qW3D8sugHVd8nOBGqwdI7Cd7pjHSlRrwgcVFFqKhvZ+jSQGk5ea5C+pMjnl/d5bvfeYLGRx6zNYt5aYQ9qQiqVVNCvF0JCIYlamZZ/m6OkxQYV3P8XIWy/n0HVyyoVO6R8eS3qG05OLH8XmnH0rh2yl88+z7vDjdYjKYkpcuv33ueSb9CuOWjFiA+n1H7yCd9aYIpHYb9KlfOHLAajThIGmLD3UwI/RzXMRyPfPRM49wLKeJIRNPzdO/h0zmVLY/oSHZn/tigM4ei+8jFQ9F4YKgc5uTLTdzBDD2JSRsN8obY30THlmBsqOzFMiLWI9zZPKLeE6lMdCKUBp1b/LE8j8ZzmJyRUa6yrxiftZjFDKau3KcCZosiT0q6lrKTQSqhmbUd9bjz1wVSrIaCKBeRpIe7iQS3Fq1IpGbjEictUTsnf9hl4AeuT7Tj6OY/+CVUNUCVCnesybsFqtDYoER5BjcoMDsVGncU8TxQMzjVpB2DqZToqYNpFZzbPObBR6t03xVpjT+2czmJmhekuZ1GpBmfEeeA1sfSdj8iilYPC6LdCdZ3yZo+ed2V1JMVGYnyuix/86pQLqJD6bbymoyKTiynsfHmadCZoFyTdflzN5bdQV6F6ER4V2UIlUPZiRhPHqRHe4p4Yd6NzTVx3lj2HzqHyUsxUTXD0YbZxy3cmSK7HPPC2W0+PlkiTTyK45Duu5rFV4/h6JSyL7uJ2S98hpOnHcIeTDcs5UaC7ft03tV0Ppqhs4L+kw0mm4p4vcTtxjS+VqV5P6MMNNt/zOHf/9LvcyU84G+9/vMsfdVnuqbxf+KE8STC/bBK645YFUc7Y9QsxbSqHL9YJ15UJKui3fT7clgY34o8KpMdTrGQ4/Y83InQV8pIeGEmEM7Yox2OspLO4w8tk01FUTVCeYnAOzch36phllNarSnd6owHx23sgypFN6e9NGY4quAHBZ5XkGUuReEQvl8RHZ8PRVW0kE4CrXsJ7iAhXq8xPOcRL0PjnqV6WKCM/H7R3VMGLy0zW9SyJz01eBODkxn8wynKGKYXWoRHMU5/yujZRZK2xptZRmeFGKw6Ga5XUuxVMI2CC2ePiNyco2mN4SQim3mEDwJqD+Wejc/J/QtONFnTYoI5WTgQSVb3LWH+51VFVhd0sPGwpHZ7iO6PsFmOXe5SNkOcSYoqDINzAW/8q//qx46jf9C1fOGEfrZAcRzKAnbqYEIxsLNGEb5ZQxXyYuUtSSMpnpqgdiosvO7Oi4XP8cfrRFr2Gv7I4uQwWdWMrha033MIRnNJxprCOJb6fU1WlyIE8vCp0pIuCqSbNV2KSH7k6NQwXdEUz00Ighz9RhuQ4hEvg3HkpfImIsJ2Ex5bm8zm8eBYCE+07MDGUoDcWFAuVUBRE0oFiAFgHsrJ7U8MRaAF8VrXpAuWyp5CHQZkeSi6uUAMDZ/Z3JfEoQ+aLH5oqe7E6LgAY1BhgK5U4PJZ4q6ejyIFyYILOyGVXUU4R0yzdsjps9B44pS16oyD39mkuZUS7A4ZP9nF35wyLCL+1tf+LN5Ac/Q5g27FTPs1grshG9+YonODnmUUrYj4UpPZgvCjQJjpec3iTZClekU6qscCZt9QNEqKBYMbFtihT7Arv0eyWuCOHIxradyRFOPTpx2ydilaved7bDSHfHywRNnOqTdi1hojdodNitRFrSUw9ugf1XGiEqUs03HIhbUTZrnHwVOK6HpE6YM/mnOmVhTdDwtMNPdjf5CzcL2Q7t2VCDGAcqH+OHoLhLTqDyVdujw+QS8ukLY65LUqeVSTtYKG8XnI2gXtjSG1IONoWJM4Ouvy4N01ykZJ2E4wW1WCRBLFdSHcPZ1J0bYOj2PsHnmB6ViKVdoQArAyUN8qiQ4T1MHxHByYMbp2gaymiXo+TmqZrP44+fmHXp42VCsp466mzDQ2dtCNnMr7EU48J3Q2hHfiTDT+5RHmgybVIzj9ownaM7AfEh7JS6hKCPslvase8ZKlftsl6hnijqByQU8KRRHC9JkErKL+bsDC93qSV1fzsY5mvOnL4tOF8Rdjrq0f8OEHZ+m8WmG6ymPPJeMryoYlOpQlrC7ks3U5j7GvP4KRtZA8PdmFBX3ppvyR7ECypoiZm28ZZoui0HdS6Qh1CcMLmunlDApFmoioOzqStt9cHfOFzS1uDxYp/+kS528Msa4Ga9FJhqlF2HaV7NkNnMyQ1xS1XUN4khGcuoAQDo0jrhO7P9+RUNDmgG4wJbm7Rnh9B9uosfMVw4X2kN/+2sv4GQTPDqgoy6BXxdv3ad4xjM9FZHV5ccbn58jXPF0nOBabH53LCFhU5ZB5tGgvQsvyEwMOTpsoZXG9cs6hs2TrOUEtpWw4VN6uUN8t6F9xSVYK2W9eiGlXYu73OpSFQ6Ud04oS+knELPGxsYvVFt3IsUMf4xlS6/GZC1tkxuHOg2XCh77wqQpZ6Kctgf9VnONMY4zXkXCKrgids6am9JXQGQ6HmGeqZC1wpwKe1LZPKXZ2ATALTcK+BL7Giz7G14zOQ9EoUZWSvHQ4HNRpVBOGqoY/0KJtTTXqvTqNYxlJk5YctkFfUr1ltJwjgAnkTck7aF+Xd0wXluqe/HPtwQxn+wi7vIDNcrQnHDh/KIj5bEUx6/zYIvmHXv04Itc+Slm0a9ATn/r7jgRKuMI7mT0Tc2alh1aWew+XaB3B4JkCpSD4sMLG18dMzlUZb2qKSHH0KY+gB7UdGdmKUBEviVQjGEgnlXQVf+SJ23zz5hW6H6ao3pDiwgrJgv84dDRrWYpGibMXEv/yCtfubDH8wjnyhhAXrVLUH8g44E9LilAx3hR0iUISfIqGEeJrIQRHAG80j3GfCQdqfElY4a0PRezqjy3RccF40yNeVJLBuGAe234UkaVoFaRLivVzJyxEU157cJ76V6ssvd+jaIQUVZfZimgAQZas1aOCQjs07xcUgWZ0PiRZFGlLbdfSvDEgWa+R1y0XWgPOVHv89q2neOKdfWy3xe3/oEO1O2Lr/TVa92D4hEUXDkpZuq8Kv2y2IiO4P5y7QSQKZw5iuFNFsvh9aL2oQdYUiUh4JGN3eiEVDtNDoXGkdYNdKlBGwJBqlNI7qbP4bsrJswHxssEZOyy/fMAgDrl3Z0WkQYVmFjt85fxHbMdtDnsNCEr+6LVb7ExbzBY8euMqlTBlb9pk/7urOKFFzVFnnQtBswwgUwrdH4EvHdbkQkMKsJbnMxgY3Dt7HP7sRQZPSGDq+ld7qINjipNTAPRz1yirPpXX7pA/dZa8okXs71jQ4t3vuwXVIONMo89bUQd3Ou/Y5yCEVYJOZnVZE2QtyBsFOtOER48cNgADtW2Zmb2pfRxh37wT4xwNsM06xncxrYi044uKYCLOGEXF4ox+tCXjE12wqn5GpTFinPoMb3VYfMsSL2jSNqRdS+XpHj+xvMuHJ6ucntao3PGZboqGbvF9izec0b9WE8a4Z1CdFOVYsv2Q9nV54PpPG2pbDmHPUlRguqZJV3K+u3uG4H5AvGQw3iZuXOJNxE0zWTJY3+L3HM7/+oh4o8r9v34BExlQJd49h/peQXCSEa8EhCc5o3OB5BD6oApp91UunYbOpPvCyriYtWQnl3YswbFDdUcQOqst4WlJ0hWQoL5tiBc19fsarHz3C595iLWKzDhcax3iqpL3Ts9SOyjIlqrMlnwhC9bnnuahJewprOsSncoJPVuW/Vm6muMfuHTe7oOr2f5pj/Mv7tDwEv7ld19g4U0HWwm58deaEObYe3U61xVZQ9G4A/Z+Qxwx1mTHZB0pTJUD+T7x+rxiegaVOFS257rOSJJzTGRQhaKIxNrE2QsY1Lss6AAAIABJREFUNwKcSxPKUqFyh6XuGGMVoVuw98EyG6/JgePOZIx8+vn7POi3mQwq6FhjtSboab7wlfeIS5/rRytEUcbC4pRxHuAoQ146aG3oVGIOf3sTuyCngXXkUHu0h7QOpB1LudohWYrEXNJadCbqgmBgqN+bQKdJ1lCEJ4qV78bo8RSTZoz+wisiP3ttH/PeDUrtkDc9ykCsXpSRe7O51Of57g6ZccnndhWPeFnGl/3lbFUE4TIuyjRR2XZxY+bd3txN5ETRvJdjAvUYMAmHBneQYH0PUwmYna1ilSJtamrb9nGR9kZix/SjvD7RBasdxexNl4nvNImOFIevGKxTgoaNy0es1YakpUsjTLh86ZjLzx/xK69+HidxmS675Bc9iopYGBcVS5G4UCgaDzX+uOTwFUVlT8ih8Z8ZYIwmG4UoYDYKcauWpCMdUHiSUNQ8Zsua2oPv87u2/nSDdCMnqMWkvUg8zfeEojBbC8krislaSLIgo03tgbxMSaFIFgAtI2JeESV9XpOx0IkVtYeyJJ5sKvwRlDNFvOCiC0s4kIh5dyo7i3hRsfLiARU349bJElcXD0lLl69/4wXOfbNgeM4lb3gCuSMFoWgYol0hcxaRemxZ/MgjzDtx2fhGhvUc7v/ZBuVCxt6gwb0H6yx8qKgeFtz7xQVUblh83SHsl8RdBzcRrV7WFlvl4FSRNyzuVFPfsozOa2YXM6L7vozgFXkh3OkcmCiksFnloOfhnfISWxSQZy6eX7De7VEaTW9aYfzmIpuv54w3XSab8PRP3uapxj5f33+CvHBYWBxxous4BwFZ27A7a3LzwSpMXZobQ5p+QmZcvrBwl28eX+Z4u83O+038gsc8JWUkwCRtCwtc54CFk+frGHcOpPTKeayY/GbJcoUyqFEGsPhujjPNwXHQjTqtf3Ud8pwimY9ZpiQ4TuhdrUun3BRwyXNKAl3wp1pvczdb4jsHz8n/LwVvCuPzAjJhleymYoU3nlNrDHNeGtQeWmp7Od6kwCrI55kA3kT2UmW7StoNyaoS8SWyLuG7laGVDmus+FFen+iCdXNrFX9ax5soJhcK/r3Pfod70wWOkxp3tpY5rNX5q099m7+w+T6f+93/jO/1rlIZSlJ0EYqrgsRTAUYR9Dw5uQOhESx915JXLSdfzKgaTXargVfIj7vy4gGHlTreR1Uqhyl6MMUtItw4oPjygKsLR1yrH/Aw7vD2wQbxzRaNQ3npH9l7GBeShbnfeC6yi8qxkfG0Kg+BN5ICltfVYx9udyr/bbwoC+cytPgjLY4N8wI1OuMwejaj9rGPO4HppZy60RirCbycg2mDD753maV3DMNzLvGSLKWrWy6VA0v/KQiOHaITS7wkXUwZOGRNS94u6WwMqP+jJv7RlN0/3iF8qs9CmLJ/0KZ1W1HfyXGnBVlX07zp0L9mKTdyTGrQIxe0RScKvy/JO2akCfqypPbGsPCqJ51yR2xihJkuSd8w9yLfE698VSIC4FQzisRNwnFL9npN8uOI8MAhWSvw//N9fnH5BrMy4FvHl/idnSeZpT6OY+gNatjUYf35ff7cxlv8d+/8NLZQUCn4y5e+wzdOr3AwafK6Pc+D4zbhviuLf0SSlbbEx8p4cxdPA+GpRe/L8+JPhAog45z4khWhIukIf6p11xDtT1HTeXFyHfSC+H9rRIs6PVdjeEF4XE4KqufgLU653Djm87VbjEzIP334WabnCmp35NUdnzc4iUKnLkW3wAQGU7FYV8JyjS+72ejEEPZLjK+JlwL8YfGYrhAcTBg82yJpyS41GIlO1Jsa9r7gYl0oWgXBgYs+/dEWrE80reHsP/mbNBehGmRcaJ7w9v4mWhsudU7QyrI7aRK6BfuvrbPwQUnvCYfi6SlmL6KMDDrVkqXXKlCxQ3iiRbYykLEha1ryTgFWEe65IgGpW1Q3pfZmROdmJlluCo6fr4qhWVRy7eIevi5578ZZVFhiUy0yoRPZUTmJMIaTrpIQU8fizOTkU3buBlozBKcO/kBe1rxu0YUS+oOW5eijbMHgVD3uWowH8WbO2tlTHGXZ+3AZZ6bwnx4KClg4aG1J7zRYeNdSf5CQLPr0rroUFSngWdPQvC0jwXTTYtYSuu0Jp7e6+H1NslagooJz/0xx8lxA+ukJlTBj+KDJyquKxr0pyWLI0ac8rJJTfnKhxB1pGndlGf2IqoFhrkkr8ccSajBddgRlbUnRVrmYBhZVGT+sI+NjdVtY5Glnfs8Wc6rtmOlBFb/nyPcxcPWlB/yrK7/DSTnlV4bP8Fr/AqFTMMkDDIpPt7f4M423ueZXuJ7F/K2HP8f7O+uUA5/a6oRqkHGlfUTDTXn3dJ3drQWcsSPZfj2htxRVHv8eupCRMBjwWHTfupORNRwmG/OCk0jnrDNLvKxY/1ZMXnNJGw71rRidl+hZhqkGDJ6oMl3VRMfSwT3qcE0359OX77PgT+llFQ7jOvuDBul2DZ3Nn+tU4yQa41pYSqnVEkYnVdxTT+77nmRjRsf53B76UfekiPYTVGnoX6sxW1GPPeXdRNxYBxc8hk8VrJw9ZfjqMpUDS+XOiFe/8bd/TGv4A6/DkNEoJLx2zLdvXSK8HZI2LHtP5+SlxtGWSRpQVA29aw7q+SHFJCA8O6Fdm3E8qGFKR7LzPMOV53e4cbDMbL9C80KPM/UxN+6u4Qwdipol6CkW3zXo3COrGU6e9TGuz+xczua5fbzCpT+scnN7BdcrWdzsc3KnSzCYa9xcabuVkaWsdUAvpFxZO+TG7XXciYcJhIJReegS9MUPvqgwdwaVhbTxFJUDeeCTrnxOXlWkXYs/UFQXZzjKsv1ggXCkSTYzigcNdCJL7TK0tG8LdD5dD4m70mU270D1IMN4iqMXPJZ+Yg+dBLQrMcYqeoUQGY3v4E5dDj4D5356i+dbO7zVO0O+16H93V2S8ws8/BmH1vlT+qc1Lp7f48b2Ct1vB5S+Ijqxc12c/N3X/vU2NgwYP9klq4nzBVYABn8oo0eyKPdFhSVoi+r5j73ErZausnbTp6j6RI+QdQsLLx/yv1z8daDKG2mXv9T8kNf6FxjlITU3ZSkccyk4ZGZdfncW8Pfu/zxHoxrlzKW+NuYn1u/xROWAd8ebvN9boz+NHhsDFlUrAvv+HGU2c4tlYRVQRHLYhD3L8IJH1pBi4ySKYGDnWYNigZy2PVQBzTtT9DQlWaszeqFO0pHfv3PDEHc1aVvcU02tRAFvP9ykVk0ojMZzSoxRmEaBAXRQYrRLUSklqzJ2Ka63qRUwuZIT7nrU9woqOzMpVlWPuOOCgoVv72OjgOn5JnlV3E+D8dyfv5eRtX3yOriNjNG3lll+O8MfZowWf7Ql4xPdYW3+t7+Evw5lqdE7IfUne0xm4iucDwMWXpd0l+mGjBKNLx7iKMvxm8uyC3Hhxc/e4m+s/w5PeIaaDvnXs5BfO3qFN7bO0f3tkOadGXnDZ+vnHH7jT/73PB/I53/h/V9g/8YSysDik8e8vPiQ64NV7t9YpXbfkXHTiNeUk8oLVUSyS8o6Bmc5Jp95hNs+pS9/nrUMzkKKKRVm6uGMHbypcL/CU0VttxQiX0UzPqNFeT8RiLoIYXRRXvCiZskXc3RQondDvIkiuZxwcf2Yw3GN8V6dp57c5uGgRfZem9Zt4WzFbZEs9Z4z/OOv/M/8/a0vs91vsdSYoJTl4YerVLdFKTC+lvFTT9/k2w8u4L1TY/N/eA8znVJ86VPc+/MalWn8vqb+4inDSUhxFGGrJZsbp+x9sEz9vhYrZUcxOWNp3pHRLq9Lx5LXIF2YU/UV+OtTLi8dc317FXcrlM64asXkrz/XZTYs2YLw7VRY8g8//2v8XHUGwN18wlvpOrl1Oecdc8Gd8Zfu/CL7owaONvT3G+hqwWJnzOeX7zEqIgqr2Zs2ORjXyQuHeBhSueOLx1YDktUcjMIdOlQOJV0mqykmZ6QLruwpgpHIX/KqFF5vKp1x5bQkPEzJmz7jDVdoLE2R8/gjS/uWRL9naw2mKz66hJNnpeDZsJRMgkwTHrj4A6EmJIuW8MqQyUENnYidTGVfU90TcXUeCYJd+rD+zRmqtMQrIfGCyMoaWyXhcSqOGq5D/6Ul0qYiHFjCk5zgJEblJeMrLcabDsaFle9M0UnB7GyVrKbJSHnvn/2XP+6w/qBr7cIxX7l0j//j3gs8+cUHXKic8OnaPT6MN/iVf/2TWAcaDwsW3005fbpKf1whm/kEhUI/OeRzG1tcqhxxXNb5rdElfu2jl8jHPsG+hwP0nrb0/qTiK1fe5e92vsOr8SX+zs4TbFQGHPQa2G6G4xc8293j3mSB+zdXCQ8lT+6Rn7hOhZmuS8tkXTo1286wDypEE2HNo6A0oIyS9GbAHTpEh8JWV0ba8fEZh3hRJDzeSJbQOgfjQLKoMEGJ8Ryq1/pUgoyD4ybB5RHnOj2WwzHvHK0zPqnyR1+8QeTkXL+5SfNURLN5RZwmBk8ofumP/zp/f+vLnMwqXF06ZJyH3D/s4sRzqL5lUZ7hjX/xLGEKK//wNQww/sVXOH5RgS1xJxqdKmapR5G5eENNmWoOjlao7yhqe5L8PL5sKLs5Q3z8oSzf86UcNXNwJ5q8XbJy9pQvLN/jNz9+FjvwKS/EaK/EBRYbE2q+iOZKo7mzt4iZePz1T3+VL4YnDI3inbTK3ewSJZoz3imfDzV/+/jTXKqfcP+4i/tejVoO8fMFf2T1DlfCAx5mXY6zOnU/wdQVdx4sU7vpEwws8aIi7coS25lqoiNF5dCQ1cU+W3hh8yX8kqwZUGJg6M/j1ZzEiutsVeg0rXs53khSmUUCNSNbbTDeCORzOpq8UeKNNVnN4kYFZhiStQ3J2YJae4aTO0x36+hciqPOJPVovKmoHAnnK2tId5u1fabLwp0qA0ttx1LdmqD3jrGtBvlSnfEZ6RyLQDSzKs6wkY8ylujE4I/EECBZq5BXZDyvnBY/7HX9Q7k+0QUL4Fc/fplWbca9QZdZ4fPhaI0XWtv8lX/n61yfrPLOwQaTXoXaxwrn3TqBP+fvPKzzja1n+PZIz10aDWWzYGWzx3gh5MvnPuJqtM/YhBir+Yuv/ceYvk+0OuGpS/usdEZ4TslL3YdMy4Drd9fFl6kte5hsoQTXcPY3FNHelPHFuuQGehZnP0BZGSnCI02ybLCuxRtrbCK2KcoKqlQ9KHFSS9xxcGfSiZS+jAlp21LbFg6MNwbrOGQXYz67vIvGcrF5Qs3NuDta4DCpM9hq4SyknItO+er+VVQpKKMgVmJ/23rpiP/63T9JNgj41JP3WQon7IxblGOPYCLIXlkxnPnfHdK2ofONLQpg9Bde4eCnC9yooBrmeKslg6M6/s0GnXvAnHeElZc27mriRYU3UrSv+yQL0j0Yz+L0PKp7itmqZeXsKV9avcULlQf8RvE83XN9GmHC9rEoBvqziMvNY362+y7vzM5y990NLjy3x19rbQMV/tFgnW8PLnO1dsD54JiRCfnz975AYTQfHy9h71bp3CzpX3YoU4df//AFsTF+4i4Px21KqxhOI0g1yaKM6HndihfZVMmhUQrHSRVyUDXu2jlK/EiBAEFPEDgnFYeDeLNO71pAMLCsfqNH0Y5w4hzvJIXSoNIM4zcfW8bkdQk3sRrUxJWIOQdUN2W5MyYrHKY7dXSm5HCILOZMgn0Q4k1FqpU+HVOmDuEDn+NnXfKG6A+xEPYMzvEAfB8TuOR1V1x7lawOwr0xajgG6nNicklwEj+2XHJjKyz4rf0fTSGYX5/oguU5JSZXHB43sTOXk0qddnvCOLvEtdYhv3L2W3AW/ubRM/yqeYXGRx5OX+DzogJlJFqv6YWc9uoIpSxZ4eC7BftJk68+vMropIqKHbyBplwu+NzGFr9x7znKUnNh4ZTL0SH/9MEr6KDEdg1BJcN1S8wsQN+PqNw/wVQDrKMI+uBNNHlN9khOIieh7WRgIXNdVCmsfAykTQh7iiJQ6MJS2zO4seHoBf8xsXJ4xRAdKRr3S5Iv9el6Ba9unWdzYUDk5kzygLjwuL29jCoV9iDkd9vXaAYJ+7Wc2bUC58AnXjO4i+ITlk18fv6ld1j1h/xPb/0E3rZPdaqYbZREew7d1yyVrQHGb2OzDOfyBU5eUDhhSb0W87nVLSIn419MnsedenP2tsUbi/d76UHaEbdM79gyfALyltjLRA88vIkQG41rOby7wG9MI95on8NxDVnhsHPaIo899MileXXMVzrvcy9d4ltHl7Aa/psL/wJw+CsPv8DHgyU60YxA5/yz3VdoBTF7kyb7J01s36d2otj/vGLz2V0+3zzivZN1Drc6vH77AiiLOvWxrkV3MtTQIV6e2z1PZJ+XNRTWCojizZFAlBjipR0hbIa9OUJYd7CuoqjUOXnaIzyxtL92G4oCXTuLHs7EteG0j9UKv9fEnPOYbsjz4k4F4ba+AW1xOzlBmDOYRGhtsbUCO/DI2gbTygnuhvhDQS/PvbLN7rBJutMgPIbByylhLUO/U6e2banuJpiFJhRG0otWHcJTS20nI9gdokYTzHKHsiq5B2hQSQGBSxloosME7+EJye6PC9YPvY4nNbLUh1LJzJ559PIGLI34U+23AJiZjNyKHXK8LEtSFhM6rSmzVxeE/5Rq8t/vEi8bwgtjZqOQ1/pVbCphq+5EYy9P+dT6Hh+crtKIEjbrA1xl+Htv/Qy20PgVgYiSmY/NNJSK7n2YnWsRL7hM16UdV2bOJXIgr5eSFThzxSNbI0Zpqbg0KAPjTUGHars5wWnC+HyVMoSsbfBGCn8oHulJW5MVLr3DBk9c2OfF9jaeLlnyRjgY7i8t8uvXX6BSTXm2u0egC447VcaTiGIFNlZ7XGsf8K0Hl6i2Y86FJ/xfu8/jP5Csu9mqQTUzNp88Yis4S+/qImd++UPK0Yjhl69QRoaXzj7kOK7x9ftXKAqHq+sHfLxz7jGyh3okM5J/d2LZ7eTNgsrilNkwIlkpSVsZZuKhY83ShVNeWd7i5nCZPHGxVuG4JUEt5dKFXXxd8Nb0HD/XfIf/h703jbIsO8szn33mc+58I+LGPGTkXFlZWfNcUqkkEJJAYGZZWHQ3NkO3scFtt900tmyvZhmWMDRgwGbGmEm2EEYSCIlCJapKUtaQNeU8RERmzBE37nzumc/uH/tWyixgrf7TqH7orJW/MuNm3HPv+fbe3/e+z/vLnccQkyHPDo/haRc45DV5vTlDP7b5xZffjgwMnLEAXc/JeyYiFwyWM0Q1Zn2vTs0eUrIjBlM+T85f50JnirXhJHolRuaCtJijBRp2S6jY9uTN8A81UAlrGlZfYkSqkOmhUo8bQzUZRQqqK5min0ZQXk/IDlponod+ZZ184COT+Pb32186QVpQgmCrrcS6IlU+v7yUkSUa/tBF6ys+vBiPEY0Itm2KF2zstsSfh2wp5PrWBNZ1F3eg5CH2LRt326Kwl6GHOVqSk1s6ybiLP6kRNKCykmJ2Q3LPJh8vQi5BCMxhij5M0fwA/3AZdzvAWN9Xi1e5BL2vRDVQ11u6YPm7BXRL9TrIFaDPuWXRoswfz5xhP1slzE2mrQ7FyQFRp8I9918nl4Lrf3gUM1GqaYY64bgkdyXx5TLaUoCm5SSJhlOKeNudF9CFZG1Qp2DFHK/s8frBDJsbdUg0StN9Joo+W+0KxqZ9O3dQZNA+psSpaXGEo80EcT3F2TXQmzrD+Qx9qI6luSFxmhqZM6IuaKr/ZYQSZ8dHrG5SbdXJrCl6h1R/obCdk3iC3hE4VT/gDd9mt1/idW2WU5VtBplDN3V5ozNDveojhGSlP86NzQlkpKMXEorVIevrY2xcbXD/Pde5r3KL68NJts5NIzRJ+Yk9/sHCy/xQbY2fay/yH7QFwjHIej2yd9zL7uM5X3vvG3QTlzA1qBYDDjpFbnzuELiq50YmVBJLqEb+aKq/F0xJsHOiyMR0E5y6z9B3sPcMognVU7oxGGe7V2Zmus10oUeYmQxim1udKv/g6Bf4+uIF/q+Nb8AwMh6dX+XXLz/CJ0p3KRpFZHKwWlO76qmY4409Ln9+GUuDdCnEGaVdRy2X661xpBQ8tXCVeafFX2wuY48KXJZpxFhoI/uNGSiPqTaKOMssoY5VsSSqaCr1JlP5hUlB0TScgxx9mBItmrj7Oc65VTIpyX0ffB8ArVQifuAYnaMW/izEtQxZyJiea7L94jS5MVK4ZwKtaeHsKwDicDFF0yRiw2HqbE5/Vnkx9QiMGw56IEYBumrXl5Rzso76We/lm8j+AHFsCVC2MasH/pSBP1XGbWW3GXBarPhm5r6PNHScZoyxeYAsFRCxhZDWVwvW33jZOWZbneuT8RTzwMDdk4jM4un6MV4rznKyustJb5vFWptbJyQ1K+BLW4tY72jy0NQtPrd2lDg0yFMNY08lraRaTtJ2EIWUbzn6KiU95PPNo1y+OY3QcybdPu+cvkIyqfMH186wVGtzaXOKLNahoOwi5RsaRpQTGcr7Zu4on19vWeJuGsRVSVRX4sk3cb65mxMcj7Fu2l8O0UR5B6MJDydsgB/gNlMQioUlNfW6cjbin83/Cf9H8K1srY2TSYEhcm60xsgyjSzTcOwEQ89YPTcHdk5xvo/fcwiuVqGYccfpWzxcXWUtHOMzf3avEq0+1OaLZz4GwF7m87OvvYOslrP8sYTdH3xUUT7dkC9tLZFmGpqmCAbuZZVwbfaVtkxLRmP/EX2TFHp3JggrQ3Qs9G1T5SHaHtKVxLUMZyLgoy8+gNFRhNHFx1cZJDYbnSp+y+WBE6u8vXCF77/+nay8OM+vfvsv8vfPfjdpZLCxU0A6mZqUxoKkmjE12eHC2WWwYfaebe6sqePLF7aXGFvyOVRu8T9PPsuE7vO9F7+LJDHUbizXiPc85etMRkf7fqYYZZGa/Jq+KlxhTSNoiNt+QcNXU2L3IKN8pUvUKOC0coorA4T95aRcfWKC4f1LGEFG54hF9whYh/qYmUatNKQbOArdLCEr5ribBt6WCvxo3SnxJnyy8xVKNyWdZYXecXcFWiKJq6Pp4vIQ840CWqamh9XrKcXzu8ggJHr8DnJdOSWSkppUvolViouqMLt7Kp3bXtknLxXIawWM5gBZLiBtE3QNhjFfyeutXbAkaMcH5LmAoUnmSIJJjcySxNcrdI9nUIVmWuTia4sAPP/yGVJP8vBTr/OZqydV81IDYu22QdgwcqaW95krdrjcn+TcjUVkolFt9PmJUx/ja72EH907zWFnj9l6lzeuz1GoBURAJgzcXY3x1wOCSUvxxPdVSnTnqEY0nUCiMgD1oYYxEIQLMdWJAYae07paV6wsX9JfVCudHknCcZP2sQa5PcIQ9xVVczgDyWTCTz7wMTbTGge9AmiSQcej5Ya4VoIfWhxuNDlV2ebF5iKtYoYopOQvVDE9iTzq8/2nvgjAH23dxc3rDYoHAn8hY+XB3719uxt6gR+6+2l+/0feg712QPT2WUXVTFTq0Ey1x8r2OMamfdvLpiWMIthVw9ocKMjcYFagDXRyV1C/KG5bmcKlmCdPXuXFrQWGfRurEpEkGuakj2fEnF9bQugStxryaO0G33P+Q2SfGiO9P+Efvv4B5Ah2JTX1YTqXXPWw6hq718exfYE81acbOPxZ5xh5pmE7Cd84/QbvLr3Bfzl4lCu9BgUrZvdWHaMckw5UMX0zsl7kksGsiT8rbjfaDV/iT2uEYwrWp0WjHt1AiVylLth/sIbdVQrx3DHQhl+mcybHZ7EPQsKGS2YrWHtw4FKeHDBT7PLq6jzCGJEpOjrBdEpc0dBitSCEt0rUNiSdE2qCXF5Vvba4LPCPxGgDg/E/9kBIxWJfTSi8tokcBsiFGey9IaQ5Zt9BTxxFkbjcJfMsdD9CmjpJxUEkOVlDhURqYUJaV/aLtGRi9mIYdP//etr/P11v6YIljJx6KcTSM2RNsLUzTVKQZLWE+fkDjlf3uNSZ5NPbd4CQlFYUlD8+GfDn144hOxZCgFEPwYWsqFGo+jw2vUJRj3i9O8vFzSlkonHm2C3+xfwfE6PMpbkUfOSNr8G1E9531xt0EpdXtmcJE4fGy2rM3p/X0QM12u7cmTI+1yJsliA2MDvqIRcZlMfVcaD32hi1FcXZGsyrVdHbhZ2HFf4k8030joE0lVVHZDB1zw73jq+zn5Y4788xXeuxkeqkgcHWG5NkXs7JkxscK+8xbg5wjIQHTt/gtc1ZhkdjPnjvWdaGY/zR5ml29itomw5eTxDcO2Tlyd+4fa9/vjPPlNHlFy69jal+xsFj04gE0jt9XDMjCCyuH0xSvGIhUkZ2I3UkicsQjkN5VeLtp8QlHZELZC3BvW4rlE0M4V1Djk02eebSMUTPxNnTMEJI7w6oFAJeePko9vQQ00wx9YyfffrdlFZ1sjKQCjwrYdDxsG7aSE1iDA2kBsVbEI5pWN1RT8lO8C/WSMs5jUMHuGbCG70Znmse5sD3sM2U/XZJ7XrzN61AArujjrRSV6EbyVhC7RWD4nZGf84g9ZTeL3PVtFPrqnSe3Pxy5mBU1nBaKXo/QkYRerlM+PAx9fdVi8GMrljsqaA83ePr5i/x6fWTVM46t490/mKG2dMVhsaTlK8LpC7onMjJihnlGwbhmPp+JQVuc/Ljsk5cVHmU7q0+aBpycZpo3MXwU3JHR/cTnFZKXNYRwwhj54Bsdw9jegoYQz/oEx0a5+CkAxrYnZyoolHaTLFaOYMTk3Drb+f5/+uut3TBMrZtdoIyeqi8dZpUtMgn5tfoxg5/fvUY9mWX2r7ECJWlYOsdOSLVaIz3SCrqQ41Tg+HAViu3mRBkJm+0ZwDQbrmwEPDk+BV8afHOkYz649fPoGmSb1p6nePONp/rnmC4X2DsgiAcM4kqAm8nZzilkRQUgeFgrYZ0si9D0lIIFhKCVgEV8NV6AAAgAElEQVRCDd2WtO6V6L6GMRRYHcHBIzHluk9vt4i1b6imfEcjPBrx3fd8kfsLK/xJ+wyeFrEyGKM5KJDnAnfNIhzPKUz5tAKPLwVLVJ2AshVyrLhHPiPoxw7P7BwlzTV6QwfjpkPmSsKG5Lcf/lUYFedXo4iffOY9FNcMyus5gxlBOC6IJnLywCRtqbzF+utq+iq1ESnARPXmbDXtVF41hdHxj8U4qzaFLaULap3J0bYdVjbmMRgRBGo5gZdzan6Hq19cQk4kfPD4i3xm+yQbVxoqwi1WAwx9oLO7WcPaUR45kb/JKBcMpyEaTwmWc4g1xFoV91iPip0wVegz4Qx4rTlDp+cpUJ+RkycahUkff69AYVX5BqWuOGbBhNLHubdMyrcUVz9zwNsZMc+Lo7/fz0feTslgRt3L4k6K2QoR+y0oFZETdfxJEy2T+FOKU58VUnRfp71R4ZOff5ziRo4RpbROGEQ1qRY7AeRQXhnhbKooC1bLVGZmTfVnCxuS4mZM6uqITJI56jvP9TWoVRFJhjYSkKauQI9NUlvt2rBMsr19tFKJbGaM3DHJp2sE4yZ2T4lkc0Pt1pztIUnNAfnVI+HfeBVvgewqI2lckUzdt8NOq8zK/30SLZXMeBphRVK7PCTzDHYetPngI89zddDgSrNB/1YZdKgttKlMhDzSWOUPLtzNzstTpDMxh+f3+KVv+084IuHVcIHfaz7Mjw/qmFrGh+/6JI6W4Oc2rw/neVvlKrsny2x9cRlzmGMOoX3UYLCYI03lFxSJhrlnoodq1U4LUoW5uhlGPSYr6dBVfbTcVFFNom/QD8p4GzrReM78Xdt89/wXmTHazBtdSlrO1Piz/MLuU9x4fhG7Jaj6ksHCSF2farhmwlKpRcPu8/zuMg17gCYkrcDDMlLafQ/LSgnGM/S+znPf9hGmjSKfGZp837MfonLOZqIvqV71iWsW3SWTcExizw0Ieg6lq7oyjNdHmBF/ZNYu5kx9KVFInIqBP6mRlJRH8833P1hQ3kWkICtlzC4ckOYa455PJ3TZ3KpzZWsS/fCA5XqXX3v1UWSqceTUFjc2J4jGDZaP7WDrKZfPz4MG4dGIan2Ap0m6r4/h7gqKN3XapzTEVIhhZJTciDjVubQzyWv9eUSgI10lBpWZoFALiCMDZ9tQOYWZ0lT1lyRWV6hj+0DSOWySlLj9b+y2IjUMp1XakdXR8XYkldWUuKRxcNLEWKxg+mWV3zhCWiOUODiugpbqCtncV70oqYEeSsVIG08w9k3FaxtIhpOC4UyOESipRTiZoQdKIzb5QoIWKxZa95BJVAdvS9J4do/85GFSWyf1TFJPp3S1g+j0ka4Nuk5WcWG3iTEzjXRtukdKCuesCSpXemhdn3ihTlw28ScNho0yxa0EuxV95QoCb/GCxde18NM65dIQG9h6fYpDnwwJxwQHpwzsjqR8M6V7xGP/wZzakgLkh5lJozSgV/KwvIS7J7YYtwf8t/P3YF13CRdiHjt2g3fULvMvrnwzuRS8Z+4itwY1BrHFN829zneW2iQy48N799CwejzTOcHF55cZDyXDCZ24IgjHpfK9FVLMW7Y6LqjNCEk5xz3cY3CgsMpZopMPjVEoaK50Lpn6I1H+u/TuIf9w8XN8S/HNMYzHq1HET29/LWu9OtrxAf2mi0gE6OBM+oyXfNb36mzs1ygVAypuyNndRbXb8zIW55q8/+gbfOrjj7D6A7/A04HOtFHk59qL/NJvvo+l12LicobVyxhOO4Q1NeSwOgLft9C6Bv1lJXQ1u9potVdHJ6ut4Wz2kKZO53CNzFHmbJEJ3BVLpQvNKg6ZaWWMVwbYRoqW6bRDVx3LQg2znDJe8smlEp4iJNdvNdDaJuPHDyiZEfdU17ks54nHU/SmSVf3ELokq2Y4TYPWXRJvvq92n3aMpWc4RoptpjQzTSWF75u3J7T6WE564CA9dbwzhgJpKhTRm33F1FU7kaSsEDmV1ZSwpjOckqRLoRo27LlUVlR4b+oqCYqWqagtFbslSQrKZaAyBAT54lBp5mLlvRw2lHUmHU9Ak1g9gUhVArbpg7urSKzuQ03ywIZLJcprkmDcoH0CnAPVa6vcyCmtBiAEuWcymHcIaypuLXWrWP0y3tV9ZLuF3tLJ56foHylit1MqFzrqe1pxyAoWnZNltEyht7UIvGaO0U8Iy9bfYgH4q9dbumB5ZkJv16InJAUv4sjv92meKYGAxssRw0mTjacM5FzAv773k5T1kF/ZfILmsMDudpXaRJ93zF7j2Z3DNA9KVM46hBNwcnmLMDP4sc98E42jTb5v+Vm+0D1CnOu8Y+oajxeucCMZ8mI4z5LT5NXBAp9fOYLVFfQXlN4q83Kycga6xLplY7eFcvSnijV16J5NOoFL0DFU5Jidq0a4BsLMkbmK2coTDXfFpvV4yMoT//kvvf9b6YDfbj/BCzcXSXoWM4sH7CW68iIODRbqbd42fp1Pcwc77RK6JgkSk+75MRxfIHWdm/k4f/Guj/Dv7wb4Yb4G+LWrj/GbP/1edBd6Sya5IXAOUowwR2QKkBjOJZjbNpkjkaUUY9ckrmekRYG7o+E0JcXtlGSsQPOMpwBxo4BTp6mmV/4MmFNDDCNDCEgynSA2aR8UIdAxejr6QkDRjbizvs1Le/PU6gOCyCJNNU4sb3Jf9Ra3gjof+89PUvUl3eNCkR0ATUhET6d/KsathAx7DrqVoes5j02vUjZC/vvqaQwzQ9RDEt1G76vo9sHAQR+o6Zgx1NAD1cwGxX9KHYG7JxlOC/RA+fC0RJLrUNiCvulQXFfHpczRSF0NI8hx93P8KUOFhsQKVKjHUjH3a5K4kcDQQBsYIEeG9raaNFtbCm9thEomIXJ1FAwbGbKU0m4XqX/exmsqe0xvwcDdVcJVa5BjdVO0JEP0BsiJIuVrfayGhxFkxBWVnYmUyOkGyYTHYEYtKgenbcplg7CiYYQKzZR6SswcTEqMvrrncsFlfzmGp/9Wy8Bfut7SBWv/xSnkvCQLDaJrHs27R/IAA1a/VafQ6PPA5Bb/aPrPcETKj6z9HS6tTWN5CceWdphwB7zYXGR/u4LeNumcSSg1Blxen8K8ZSMnU07Vd3jCu8HD7irhpI4nUvrS5LP+cSaMPt3M5dz+HPKmp/poIyuVnIyYn+iwsV1Hy5TNREi1bU9qisGd5YLcUT2rvJohA9WIkxJIBbqXkYc6wXLE2ad+Dijcfu9PBzoH2SyfvnkS58UCpXc0mS70GIQ2vu/wwKkV/vHMZymIhNVgnM29Kv2XxxES5p+N2L/b5vxHfvivva8/c+UpqusJ/rRJ6sDYxZCoZjKY1unclVCeHBD3HXJTJ/cyRN9QwLihpsBwIz59bgpuvdu9HcduDKGwAVqmEMgKxqdjmhnD9RKxr7RC5W3VA5r/xlWm3R7nW1N8aXuRLNcY9B3G6gOazRLX9ib4+sbrfGb7BP5crh6aWkLs6oi2hehqJLMJ1bEBfd9BRhppqONWfHbCMp9avRMArxgBOnkxJQOsakS66SlWvfnlOHktVEggkYPVkWSuIJhLKawaWL0MhMDp5IQ1jfIK1K6GiEzSXXaI6oqIIaf10S4R7P8hJHlwKEN6GZqZqWHQaHedO6qnaA40vF01jbQGueJqjavBS3FNZW0WtnOSgqKZ9hc04qoKQfX2U7Q4x+yGyJcvIE8dJymZSEPDHKjkHmc/Qu9FJNNVRC7Rg5TMsokqqn0R1DUKOxlxSSGSpKY+39KqVClBniCqiy9Hy32Frrd0wZK2xOzoOE1DjXbHBP7hhMm5Nk/WFVHzyfoV7rFzngs9oszgkWMrHC/ucqE/zdm1JdKhgXvTIilKMHP6zQIzcy3uObnJvNPi+2uvU9FUoUhkxs+1T+BpEQ+7K1yOp3itN8/uRg3dkGiZWgmDguSpo1e5NaiBbxCNZ4hYRZFJXZEEPDMmynSMsZDEsBEDQ1kucoHetBQXa6hDJeHYwi4NvcAgD1lJ4cVgiWFucy1oEAxt8kMZM2ZKzVJHvqITcaSwT4bG9178LrqvjlPeEgQN4FSfz/2rf/VX7mW0vczPdw7zX9fvxfrYJFtPqHj32tWYzFJhsakHZiXCtRKMakY709D0nFyX5COzssiguKnCKvbvMpBHB4R7LoV1HbslsXxJ95BGMJ2TVxKm6j0lRZiHMLDQbim90eL7VhnENi/35nh8ZoUpq8evnHucRqNLP7CxvYTFsRa/s/4gQWwix2I0J0F2HUSsgkdyEwwnJU6VTxANhJXSbJboDlzG6gOSVKfXc5FdC2nmzC81afYL1F+CwZzqD8UViR5qo12FKla5pTjxpWsGtaspepSTOfooCUdROvxpCyOUdI+Atw3FnYzcEMSFL4s4k4IqZFotJu9Y0DHU5HqgKYJnKEhLOd1TKWMv6XhNheHWMkn1hhoAhRW1K0SoSPq0IAimM+x9Rcs1+wm6H5N5JtHXP0jmCAxf/b7GIFG7Kl0jrblY6wcgBOlkBSMa5Sn6OVokGcwZiFT5W0UmCeu6atAbigoLI8rqV/B6Sxcsoydw4xFKGPg3f/e3GeY2JS1kJ62wEkxwyt7g44MGnzw4Q80esh8WeeHm4u3X0PoGhq+meJlr8OB91/ih6c/Syx1OW20+PlhGI+dD5Sam0Pkn9RX+IoQL8Qx/2jrFxeYkmDmGb5LrgAWynrDSH2NtZ0xxyHNAKrpC946M+4+scay4hykynjGOsjacQKJBLhQBdZR1mFYy7jl8ix9f/EOgwH6W8psHb+O4t8MD7gqhNMgTDUopc6UOBSPiaGWfbxw7x5g+4P+89i30X5zAbak4+ZkHt/iDE79LvvNbaFPX/tK9NIXOw+4N/lP/CaZ2EzrHTJICDGZM9EgynNQY3BFxZKJNN3Ror9aQxYxiNaRgx7T7HrJXpLAt6S0pQ3deTqh/roAWg57kSCFoH9OYfPsmE+6ArUGFKDVo9zyywECEOtlUzPwD+9xs1yjYMV8zf4X3VV7lp9bfzdedusCDpRVe6h+iGRd44cYSXjFSeCFd4toJ8bCAHqldXublyNAgHRrobsbkdJu9Vpk8FySBiVUZqF2ub6r4d0OwvjqB2dbpLQqGxyJMJ0XcUCk3b9JN3wxs0FKJ0wRzkGL4CamrZAOMdhlxSeBPa1SvSsq3AsytLiJO2HtqjvYdkryQYe0bWB2BdVlxtpKSCi9JliPywEC6KfqWQ/GmwG2pYhWXlU5PDyWpp1Faj0k9HX9aV2b2osTZ0bG7ymiuRSmZazJYcEkddQSNi4aKs3cMnLaksB2hBSn+yUmSko6WSlJbUL6pAnClEHh7Anc3RGqC/qJLVFbRc8GUJHUlzr6G8P9WHv2/8XpLF6zcBP/BAUUv4puXXuMBexNTwM3Uo587fEP1Vf6oey/X+hMMU9UMvLHeUD88MNBCgREJ/PmcqZN7vLexyg+OP8vluMbFaJYv+kdZC8b49YVnAfi+jUe41J7i2+bO8es3HiaMTeKbRcxYhSiYfcVd1/YtVpJJzKZakay+ihLvHckxxkJq1pBD9j67SYWCqeK3nG1F/JTzAYlnMN7oUbBi/ve5P+WYWeCZQOPV8E5+fOpF2nnIL7Ye4KPX70EGOvPL+yx6LYLM5Fhhl6NmkzfiaVq+hxYrTO6Pvff3OW1vUdM9Tv/0/4rd/inabw/5pjte499Pn+M/dmb5ib94H+Mv6EgtRYsF/qGUzFGDgPTMgKV6l27osL9ZxQg1xFAjdC3C0MT9UpH6pZj2cYuwkZOXUoi0UcirOj70D0H9zB7HKnvsBoqV1PMdsp4Ftgpdnar1Wd+vkecaU+U+H6ie5ZP9MxhaxjfVXub3mw/x6v4MrY0qRk8n1C3MnoY8GtC7UcUcqmNJejjEtlLSREcCM2NdNver5ImGEKCZOd3AYdDyEF6KMx6TXS5hdQRhQzI8pFhX8paHeyBuBy28mV4kdUVjKN9UW4rMMTCCjOI2hHV9FPMmcPah/kobefk61GrksxOknkBIiV5KYM8gtxQxNZ5M0QsJhAbatoORQGbrKjvQgO6STloAZ19idzMMP8VdHzI4UiF1lcRDZFC5oV5PacAE/kKB4o0eue6SOkqTZgxViK+WQmEjICmZ+MsO4bigspLhbQwpv9whnaySFi2MQUyhE5K5Jqln4LRSrIGmipapQU0dm+PqV0Mo/sYrXg6ZKse8Z/Yipsj4hYMn+MLeIfZaZe5bvMUwtejHNpaWsTcoYpspMtEQgYazrxPVc7KlkGrZp9ktsloY4+fF4zy/u0zdHfJwbZV/OvUZfqp1ip87+xRazyCvJvz09a+DYgI9E6elKQFdGwrbGZ0jKszVWTdVD8JUamMVhySIWw7PWcscP75LInV6kYMWKDOs0xQMYxfzxICjtX0eq13nM/3TfH6Qcq47z0O1VVbTkP/ev4vfOPsY9eku//adv8cT7jaXkwL/ZuX9fMfyWU5aHmdDG3+vAPMp3/zgS7wyXOSz7VNs/f05SqdySt+7wTvrG/zFRx7m+MmH0DJBuQvhGAzmTE6+6xqvr8+R76uHZGm8zSC2aHUL6H0d+0AwPBViahL99SKmL9l+zCSaVToc3U3xLnoYgSRzoPN4yMRYn3HPp2yEbMoq280K5opD6a4OSWJgmSn7vSJCk2Shxr31dT7eu5cF64AfPXyZd158PytrDdxqiCikaC0dzdcIp1KMLYfcUg/9zPwBcWooXZVvgoSNZgMtFpSPdPF9B03LSVMd4euMvWJS//VzAOz840dJK6k6mvd1zL5qsoNquts9SVwUI9sROPsBWcFUwaiWIKjrBA21gJXWYOyVHvn5yyowtV4hrdggQTYixJZDeVWJO4dzGSLUsG55KtPwcMj4RJfdqxPEFYkx8gJqsWLIO1sKTDg4UsGf1HE6KnHJ9JVOzDlQ+jY9kpSudGBnn7F+QO/uSfqzOpktqF1LsdsJSckkczXcdkb5ZobZDhFJRvvhWUAFoBiRiXOQkhZ0zF6K1Y3JHAOpGQSxBoeGpFKQ7n5lm1hv6YJluzFVJ+C17ixXmw1cK+FbF1/h/qMrLBldfnzn3ax3qpxubPEtM+dYMvdZPzTG5zvHaEUFbuyPEw1NWutVtFLCy1eWuDExTpQYdIYuS4UDXg7nuR40EAPliDd3LAXnszWMQAUnJGWFLvandfxDKVqojfRIIz/ZUOLtQNAQRPMpj8+vsBlV2Y+LdAKH+c9kxGU4OC0wTvT40LEX2ItLRLnJYXuXZlrm3so6j3rXeHZ4mF+79Ci1qR5PzV4bSRwK7GcBrpFwhxny0cE0nczjodPXuau0yR3uJitRg0/8t0eZP/8FTv5KkWf//DQ7uwtk39olWS9RWhFkIz1bbkpeuzmHvumoo8+8z/pBlTgwkZGOGQuGCxnkAq4XcA4kiSdIvRzTS0i6NpUXXKRQD1Hhm3fQEhMhJBdWZrk4WKB4U8exIK5Jhr6DEBLHSshzQbrpYc/5bAZVJu0e84UDPtI6TJZrHDu0w61WDTk0SEo5ciZFMxUaxzRT0lSn47sEvo0QksnZthpEtF2yAvRaBTQrw3Fj/NUKRz4aIL74GgDG7IySIgx1jJkhsl0gc1VTOStliNSgu6x2jVJTPai0ZNGft9VRUEAwqSio3jYUdlLE1TWE4yDTFBHF9BYcOmcS9B0HI4DWXRJnT1BcVaJglZAEzjWH8KxDWVNRXaAkINPPS4orA/RWj+4DM4RVDaetEpLkqIelrEiCyo2MyvkW+bVV9PExhkfH0aOc8rrEbsagC5KCgdTVDtLqZpj9GJFlDI5Wbr+n4bTiphU2LdyDHFHUkYZGUtDYen+C5QYkfRsSDW+i9ZUrCLzFEcnL//LHKD/k80+OPc2HX3o/2cDg2x98kXeWLrBkqlThOaPIdjpg2igC8Kmhw0v+MjeG4+wOy3Qjh97QoVEe0PD6dCOX69sTLEy2sLSMjacXVKTSUsi/ffCP2E0qtNICH/vDJ1SqTVdQWldx9MO5HHLwthRJIXOgeiNDD3L27jMR93RxrIRur4DYdDD7ijhqzfpoWk6jPOBrJi/j6RF/snMnvdjGMxP+5aFP8qSrVq7nw5yDrMgJa59jZuGv3JthHvNxfxpTpLzb2+GlqMgfd87whxfPkCc6p5Y32fOL7O9WqLyqCJpRRTBYyskKOWZbAQTNtlLbS0P1VaqX1CRoMC/J50KEAJlDHhhYu0rpbfbF7QSb3JTEixH6ro3VVuyopDCKhDrpg5AU3Jhez8XxYspeyM5OlXJtyKmJHZYLTR4vXuWT7bv5wvYSg6HNRHVAxQ5pBarDm2QamgDLSCmaMe3Q5eDKmGp6OzlHjm3Tj2y6vkvkWyPXNRyd22O9XcUwMgY3Kyx/PEZ/Ru2wVv/dI2SupHRDYXB6R3KkKTH6GlZHjKQZ6uhVuqka0rsPaCSNhNKYT3+3iLdmUthW07zMFOSmwAhy4pJG88GMk8c3bkeIFdZ0ymsZe/dr2G2B1VHFRuQq8MFpZ7SOGwxnciZfQIVFCOgtqipmDhXNQ0slreMGg2MJ7k2TqbMRUc0gKmsEk0qCYQTy9nGwuJXibvloBz2y7R2EbSPvWGY44xLUdeKyYOaZNv0jZXYe1pBTIbJtIYsZWs+gelFQWYkJGia5rvSFSVGQZCFXfuZHvopI/uuuf/V3Pspvd5/kw5/8NqQG3/DEy/xPtS/QlybOqFh184C+FPyztSd5/o2jaIWUSnmIH9hICfXykEZ5wF6vyEKpRaEQs3FxgZvdKaSRw0JKaapPQcv5RPMM+0GRtfMzuCGAoLClmpNpAewD5VezO2pVVloZSeukSXrKJ/VtrKcrNFrK3hLVJLmX8cDcTdYHNdbWJ/jltQakAq2YUKkM+YbZ8/jSAkI+OqhQ1Ya8vzAkk+5fuheryYAXo1me6Z4kyEw0JK20SDMtMe+0+K67XsDTYvbiEmt/cohyrNJm/DlIx2N0J8W95BFMp6ApLdFwSnkBrY6ikUZjknw2JA91RKAjqjEi1NAjNR3VA7UbiAsj7tfQoHhLYPiqX+LP54iZkIWJNivrE/S2VOHRl0MOXm2gWxK7kfJIdYWnCpf5yZ2v5UZ3HEPPmagOOFbd58LBFGFiYGg5lpHRD2wsIyWVGkFskldTtI6BFmisvTxH5qqCg5XjliPqxSGmnlF0I/bXa5z4kTfIfR/9yCEu/dMJtGJI8WVXaYwmRmP6RNx+j5kFQlM2nOJWzLChtFF526CflBBeCpiYQ0U5SF0o30zRUkl/Xgcr58orC1SvqtcWUtI5oiPnAsS+i5ZBLiRSCJKCpHfIIClK9FigJTn+tElmCaKa6j8ZkcQYZvQWTfw7IzW4yWE4aaqQkgmVWh5VBYN5JTQ1AiViHc4VsQsW6ckpjH5C/5DLYFbDX1CI62v/3EYTIUihnECWpHrOwhxIvL0UIWE4oY2KlSJHpPlXe1h/4/WvP/HtGIZDNp7xvvte42dnXgQ8/tAvksgefz5ssGQ22UxrnCjuMH7/gEudKeJcp9f3yEIdykMOfI9GeUArKrDnFzECuOPULTqhy/bFBt9y6DV+oP4i1xKXH3j9g+iBYDiTYR8of9jBgynFhg9fqOLu50rQV1Ewt8G0znAmR9zyqK5CYTdTKTcl+Pr3nmXM9LnsT3KyusteT+0CZ6o9loot7iut8cpggWV7j3++e4I5q817K7sk0sQU+u37cCEO8KXNJw/OsNId56Cv/ITnnDkem1ll2Y3ZCGoYWkY79oirakCQWRIxP8SQguLzHp3TKWdO3qQTubSvzFC9mpO6guG0olZmxVxBDVMNWchwL7qYA2VDyW1Jqa2RJyMGfUeStA0V5JrBYCnHXupjGRmrW+NoHZN7HriOo6e8+LmTCECbHXKivstD3nX+3dZ7uNVXGORxz6cbOXRjh3HPZxDb7LTKJCP+/eHxA8pmSCdwsIsRiZkhMw1hp4hUQ6YaXjlkqtKnYiniaH/oYLZ14odPMJi12H8qplbv0t4rYfYkvaPg7IPIlHg0N9RRTeSqWJlDiRQKJxPVcvJKyuJ8k91uCYRDf06FhBS2Je7mgK131BhOS9wb1igqS2nR4pLatRVecFU8mClIyhBV1U62MTbS1vUdOkcdtXO3AAGpqf7//fsNGBvtevsm018M0YcJvcMF3L1RCK41yrC0FbcrsxX2Zv+Mhx5JkqJFNCaJxlPMrq7i7XoWspiQ90yslk5pS4wGBJAUFY/e6kkSqWQkWgLiK8jCgrd4wRILPnY95FC5RyI1Tjz394hDk0MzTYaJyaONVV7KD/Enl+9gYapFyYpwjQRSMK0UsenQ2Zyg9sDeSBdlcHB1DP2hwe1jkzPv84Hqi+xnGv/owncinqlR7ksGixrlVcnBGcmPvu0T/Nb6w8S3ymipxJ/SyRyQhiCsK1a7ty1xWznBuEb/XT6ffvgXMAU8F8xzbdjgVGETayllyWlyrrfAlU6DduwS5wb/Zfgw99Vu8YR3lV/vHidD8N3li9R0Zc35rH8nb/Rn6cQe+90icc9Gc1OOzu5TNYd0MxdDy9gPi/QTZ5Tll2Mf6hOFFtYll879EQ8dW+X17Rni1RJjBxKnk9EvqN4KEkQslNO4lELXxOpz24AbVTWCCfW5ZI4c8c+Vfimz1S4tuVomTaF6psX/8/ivUdVCfrv9MC9oaur25KEbvK/+Gr+89yQ3umN4ZkKWa+z0S0SJQcmKWGvWSTYK6KFAVHIWju5yEHhc3JzC8yKmqn3C1KDd9xCjI6BXjHjH/DUeLV3nD/bvZW+/zOSfWlj9jO6yRfcoyEzQ3qjgrRv0jigcschUtmBSHBEXdJUNmXqCzBFIzSQpgxyLmRjvM0xM4o0CXqywMqUNRT3Y+Noag0MpGJKgCtneyEwtwOxLSrdyeosqscjqSQIPxOKQshexe2McWVB9Oj1SDXrEl6UVYSMnL6eInpMF83oAACAASURBVIWzpVNZzbFeW0UuTpMb4ssZkEM1GKpei8gtDXcvpXmXCxKSshI2FzYE3rZqyBtDk8ZLCe52RFaQbD/m0Tuak9s5zo5B94hyANQu52oBLqrBUlz6SlUDdb2le1jz//HDWDUdpCDp2IhUIJ2c8sQA10roDR3SVMO2U4SQ+AMHy045NbXNaqdOe61G7bzGcFqQlHK0mQDLTglXS2RF1VT+xgfPEecGnz57hspFHaeTk496DFFN4+QHLhHnOm88cxRpqgczqkrSRkKhGpBcLCMyhdTtHIOp07u8d+YCidR5euc4W80qppWyONbidHWLVX+MzUGFONWJEpPpSo9pr0ua6zScPn+v/gXusy020gHnoga/s/cwL1xfUjsfAXpXffFlLeGuQxvcX7tJzfD51O5pylZIL3a4ujVJnimTr27lZH2Tifk2Ugo6F8ZAqtF4OKaardGEOiY62wa5qfhOYkTatLoKcZIWJCJV0zEx2pGgj/RALcVoz+7uI6Xg3Ycv8R31s+xnZX746b+LdaAzef8O4+6A85szJB2b8nSfLNeQispLyQ3Jco39rSr2lkk0kVKa6ZOmOkHfRrczDCMj6tnK1jIeYZgZlpVyfHyPOa/Dn908jn/gcfQ3Epp3uQwWIJ2OEXoO+zZOU4k1k7kYe9XG3R1lSNbFbVYaqOOPHgqq13N2HwJr3kdKkFeLjL0h8fZikoKy34RVjfadkszNsVo6eigIZlKMvs74a6qdoJKIRlmMPvSWc/JqqsgSboo4sFTgRaBScLwdlQaeWQJ/QZKMJ1jbJrXL6pesvdahe2eV/ryiOjj7kvolH5FkKlMxTln9tjGSUo4+FJTWoLCXkTqC3pLO1AsBZJK0YKClknDMpD+nETSU+VpEOvpAo3JdWZSG0+o7UVqFLA45/6tfjfn6a69ydcjcZMQwsVjfnUKLBLXlFuOeTzt0CQc29AxmT+6w0ykjuxb33bPKmfI6nhHz3EGJ9mkDfaAp0dtywg+eeIYf3/4GkIIHTt9g2uryOzfup3pBo7ISY/gp3SMuuSHo3JGiCYmlZcgjQ/IND6cpsR5tcaaxRcPu81/792Ju2Ix/4Bbf0bhMSQt5rnOU1/em6e8WcbZNjDMdvn/+8/zSxttY71SRUuB3XLSOQfd4zHsmL3BhMMNPTH0RW6hj0Ebq8qn2GVY6Y9TqA6LEJM8FxZmIKDGwjIwJZ8AjhWtsJjUeHVvhD9bOqKOwb6D39ZGYVaN2X5OpYp+LLy5R3BQYgaR9clR4JmI0I0fbctBiZaRNXcVkUqnNCldidTTiSo5IIStnOJsm+si43z+kHiTrjRJSg8+IE6wMxrm+N071vEH2rjZvm7zOS60FkqHJ6TsUUOnantqyVYtDJr0B5zdmMFoGaSGnPNOnURpwc6+O5SWUCyF3T2zy9Nk7EY2QyXqPMDGYL3fpxi6vvHwEu6kxtivZfsTEX8zwZgdYgN9xEbZURVZC8XUbpyWJaoJ8pEi3ump3E05mSFPi3TKISwJ9eohlpgzWKky+ISluhKTuKLm6pJEUBIUNtWAlBTh4V4BpZNAr0F/QsLoSpy2JK4JgKscvp2hdA6NpkpaUXUsWMuJaTjI0IFUcfGMIldUEPTFIdizMvuLI54ag+UCNuKz6quUVSeX6EG0Yk4x5HJx06NyToHsB2k2H6jWoXB9irh8gbROnVcfc92ndWyeqaKPjHySVnKyutGkiEtQugtPJ2H5Ep3RTYZVzEwrrGV/J6y1dsE5PbHGoNuRj1+4GIJ8NeXRqlee3lxnzfGqL2zw6tkIidf4sO45T6/J49Ro3wgbbwwonFrf5ntnn+K3tR3h9bZZ7x/cY0wdQTLBu2Zy7ucDBZIH4XI3ZSyH2WpPgyARRTeDP5QgpuNicJIxNxA2PwoGg/WTA9yy9ynMHhznfnMYrRfhjBu+bPM+97iq/e/AIV9sTZJmGcDOi5Yy5cp/f2X2Iy+fnkcXRyhoqK8n+ToWfb7+ds2//D9iiQCQTngsdPtc/zbm9eXq+g67nVAoBd41tMWENeLUzx55fJMp1fq/5MOdbU+zuVxBNCy0RmFLx4+snD1iuKpzLuXNHGLugaJ1JQeWr504OfYPiDR23mYNUq3pUUbRUd1dgtxQiJpzMFK7aAHvVVMkxZYW4yWoJupsRmTbutkb+RokrpSLjr0r8afjg4Zd4V/ECpsjIpMaN5hgAjpWgaTl31HaZdrpcOLtMVsgpzvU43djmC9eXsd2Eo419jpd2WQ9qlBZ6NEoDbD1lstrn3O4c/etV7I5G/ZJikwdfN2DSC2n3PSLfQusZuNsaw9kMNLD6KiRUCpSFyJLklkrvrix2ic/WsTsSf1bAqkccFhhfk7j7MXHFJCnq5Dq4BxnhmDpSt+7QSV2JbFkw0HAOxO20aH9aY3gywilGxJGJODAx+wJjaJAbknQxRGYael/JZbwdSWE3xQgzqtczMksjLej053S8vZzeojJS1y9CeTWkt+zSPVygsCHxmjneZ3XsjoQ8Jrc0uoc90js9BvOQ1HO0aoGsl6MPwexr5PpoV91TaCQhwZ8RDBYMZp5LiSoadk+p8HuLX9mS8ZYuWIe8Jh+9/BhJy0Ebj/jw/Z+grId8Z+0sDztfbkp/KcxIcp3Pbp7gDmeTGbNNUY/43+ovMq4XOLzwR/wv3Q/RDIr8cesuHj92nee6J7GvudzcnsGSsPugg3NoluGUILdBJAJZzuher1G8qeFEkmAS3nP8Im8vXuJD1ZeZ0G0ef+WDLBzfoJkWuRErlf2459Ppu8ihgVGO6Uc2q7tjqjeUCbRAx9lV5lWRmLzz7RcY15WE4aVI5+neKb6wv4xrJrjVBF3LaQ4K7IdFpuweZTMk9wTXOhMqAi3VIBWYgbjNGQ+WEpYqLS7tTyKfreF40D6VoyVq9ZamxNnTqVzPbydTZ6YgrorbicypIwiOQ27lGAMNqycobua3A0StjuDUd12klzgYIuPxMzdYCSb4i81l4hsVDu4U5IsBH6i8ws/sv41Pr50kGNgKuZxqiIbPbHHApN3jfHeGzFH5jf3dIi+fuwOtnPPtX3OWw/Yuv7f9IFc2Jrnv0C0a9gA/s9gcVuiuVSltaOihVLKCe3PG7ARbz1gca3NtOEnu5ASTIA2Ju2Vg9tSEMK5I9KHA8FXijXQl6fP1UWQ7yH0or2cqgOIgweyEpCUbI8jI/l/23jPYsuw8z3vWWjuffG6OndP0YAIGGMwgDAgRSSJBUiQluUTSok1ZUllOssqizJJkuyRRkkVHVpGskqUqUiaLoougCNIEiBwHwGDyTE9P53DjOffksPPeyz/WRYNUKFXJNjE/uP909a0bus89+9vf+r73fV5XMVu3zJF6pcDtKla+ZRYyMiuI2wo7LEnqx0A9qZFSGyX+WkzUspAzhVqNCLyM2cjHnhtsT1aDiWdRWjZ+v6RwBPa8pH4/p1SC+t2S5u8MCE80uPMDHvZcUNnTeOMSmR9nEZaarGZx+C4jfNYCioaJWtMdFzsVZK0cryvBE3hdgUzBP9LYkWa2ZrIE4raxA8ULFtX9gqUXQ67+0ZaBP3S9pQvWS6Nt1NUq1Sf6/PULn+UjgTlKKARgVuZhmfKU5/CzO+sMJwGvRCd4fb5OVSX8r/2nGGUBL/c3+MCGGcr+45sfZr06xl0LScsKajVEn9DM+j6zU+AemYG6MxI0bljYoQZRGkLmhye8o3aHflHlgh1xVCScava50V/i0/FFzjUXGCQVemEFIUAEOZZd0NlpmehxAWpk4YzMhkmU8K73XeV7m2/wQzc+wvcsXuOzR5e48uYWwdKcNLEBKHKJtEqebt9myx6QlYqvzs6wEsyY1x1mEx/3nkdl36CI5xvg1hOu9ZZJX2pRtjXpoimWqm+6C6+rDLZ4QRJ0CoSG4XlJVjNzndLVVA40SSyYbxrESPNmgZYw3TZMqNbDPb72xlnkzEIux0wzj9O1HtPDGlYmaD7a40e2X+bne+/jhf42NT/BUiWTXgXcgsXqnINpjf+r83byROGuhiRDD2/fJm2XvO1xk4r03339BxFTC39jxrXeMt2gxsGwThbZuEPTbchMEJ1IDTBRaFyVE+U2bz9zj1d2NpE9H+YKZ/xArkVwYCQC3rAkWhSo2KQ4uyPThRpWO/i9FJGW5A2X4XmP3BNmC2gLnCm0rglyX1NaApUZ/5/fM4ZpK5SEqzay6zAPjxccpbFDlW5pfI5SY3UcKI9TbyTkC4YZX44FlYOMeMEi9yV2WFK9H3H4zALTk+AOjeo9XBaEywp3BFakGbztOBdTfedztLQI1wz+qLQ1lTv2g2WDPRAsvhYTrjpkviBpm4XE6IJ5nZZeilBRRp5/d5Of39JD99O//N/yocs73JosMogCvvr4r+IKcxM/l2QsyYQSKBAPRJaFLlFCPvhewyLkF4eP088q+CojKS1++9ojlHs+9fNDntm4xYY7pNSSf3Hn7UzfaJO3cuyhZdC8KaQLBafPHvLepVuc9w7Zz5q8OVvjIKoT5TaDecCHt99k0Z4xzn1GeUBU2Jz0+zzbO82NvWXUoUuxmrC4MEUKza9c/mVeS9b4vcEjfPHmOZRVoO9VyGsFdjumGiSGPT6oU8SKSiui6iX0hjWKiQ12CZlEzZQx7BYgM4H3+IDJ1Efueyy8YhYHhWO2Wnlg5lOFB42bGm9o5hFJ09AawlVBuJVjjxTOWPDID1zl62+cpf28RXBU0n1Ckq6Y45+yCgIvpV0Jee/SLb7RO0UvDFipzhjGPs+s3qLUgp2oxSxzubq7ipCa9YUxgZ3SdkOuHK0yvdfA60myikZvR2wujshLyTxxyEtJEttkkQ2pxB4pssXM6IYiifZKKrf/gEWqaaQIbESgBbaTI1+sUToYokZulN26mWEdOrh9c+TNA2GWBo6xyDjHN72VmG7FnpfELUW8YGgckwtGuxeGLuXApXlFUloCv1fijgqckbEvTU/6pDXB7IRZUiy8qvEGBZMTFpNzGlYTEJpiZiPnipVvQON3XgVAnNzk8JkFrAhzPIxySiXx7vYZP77CfE0xPVk+oDgAlM0MEjO79A7NptLvmtt7eBmyZoHdSCgOfGQqyFdSWt90WHp5TukqJic8RGFCLJK2MCTV2wlJyzZ6sjMWs3bIvZ/5W388dP83XfL1Gp/pPM7yox0eWdx/UKwAnnRtwP7XvuYPFiuAlgr4mcVrFLrkU1HALx++h7zrs3L5iB8/8RxX5ht00zpXxmtkhaL1th7vX7vJvbDNJPW42Ohwxjvibd4OV5INfn9wmZcON2kFET+08QoFgl5W47x3yP3UzGZmucP5SpffvPMYaa54+6n7cMoEW5yp9viR5vN8MTzH18dnuDpYYW1xzPhzq2gFeVNTlpLRsIIYOIbxvpKQxGaj2Ntfwi4gr5l3qbYMujdrlKyfPaI/rVB93jcFyjebKS0hWjlWqWvw+kaQmFUkcVscp7iY12vpOcXwEoinRrzw+Ys0OwKZakZnFPl2xGJrjpIlNTdhHHv8/dO/xWHR4BOzt+HaOUlh8cTiLpf9XT49eJg4t3lzbxWlSk6v9NgIxuzOm7zZX2Y+99BuSbyqcZZCLq50iQuLg4m5ETzbbH/zngf1DBoJIjvmTaWShW9Z+L2C2YZCxxhelgDvUkiY2JSvNsgDTbpYoObSYJBXE9ACFQqCjiZuC9I62DMToiEz/SBuS0twJgXD8w5J+zsaLVnJSBIbfejhzARaCryhKVb2NCNtOhw9bmOFEHRKvCNp0nWkoP+wTbhWohdT9Nwy9idpiKe1f/H1b4MgSE40UAnUdlOcfoTsDCg2l0hOtBmdM7gZv2O+r4qPN74j13RnFbMckanpEJOmoPBKkza0E+BOBGmzZPUzNvXbc0Reki56D9T6AOtfDhGl5uZ/4KGDwhzh8wI9+//q7v73u97SBcudgP3+Pu9cus9HG6/9v/pekU55fv4wwyTg4cfu8udWv8WdZAlH5nzl8AyWLFmvTxgnHvfCNlv+kL+w+Sy/MXonX+ifp9eo8qXOOfZ6TTYWRzyxcJ+4tHlX5SZbtQmB0Nx2D7mbLvJU9SZfmV5gozGmF1ZY9abshk0W3DlPVW/xC50PkJeKphOxGMx5c28VvXaMTXZLpCwptUIfHyPLqY3wc+52FlAxIMCaSOzzE8Kxj3/NYV7X7HebWPsu860SvZxg3/GMDud0hNYCHVo4R4rK/vFMwzU3W+Eao29Zh/GfnHNh5Rj/smfkCuMLJQunhtStnMNeg3ZzTpTZOKogRdHN64Sxwzx0qSylnA063EpWAPCsjIsbh/yJxWvcjRc4jOvcH7RI5g46Vqh6iuMYlPGrdzbRhcBvxLSrId1RlWzsEqzPqPmJQdykEjm1aF0RZDXBfEOhIvOaiALmJwvCG23cngQbspaRG2S1Eu0WiKmNVpqFNwqG5xVpU1NUSvKqpPAkflc/CJYIlxSFbT8oVu2rBdMthei4uPuSIDUsdndSEhwkWOOIw/e1Cdc11gy8viZuywcPirRhwlScsUQMPKITGbKS4V/x2fiHzz54r6YfeQezdYtKt0AmBSJMKJealLbJqVTJMV67NMUoa5ifJwrIaiXuQJJXNNNFjbZMxD3H6UD21AhAW1cE1Z2YpO0iUzOXlLmgftd0h+GaS+dJCc0EZhb2+PhBMf7DDcEf9fWWLljjxxLe2RzQsCJeibb5aHDj3/1Fx9duPmPz2F8I8D/1385Loy1Gkc/9eYsvehdp2iEv9rY46tewnAIaM043+lz5jUs88lOf5wd/778ApXn04n2uzVbozwM2Fkc83DrgIG7whb1z3Ftt8576DTJtccbpUlcxr0dbdJIaNzpLpEOP235IYKUsujN+7taHkELzUKvDIA24cnMDd8+hPD9nY3HEzlGLPLUQqmT74iF3b66YuKCZTa40XmEsHc6pKXHoUH/FMbmLEnQqUWdmXFw+YpJ43B+uGIb4zMbpGzJB5cB407JAEC0aQzQapu+J+ImHv8l7q9f49ORtXHvuJPOHS6hlnNro8d6lW3zu4AKVasx46uP5KWu1KT979/u48fIWwYFkdj5jWPH5VOcyG8GYR+s7dNM6a40xV2brvDlapjOoU0wc1ExStHJcNyPLFGni41UTHlnbR6K52lthuTnDXxqy02/S2W2ZLrAQeEeSwSMFop2idj2TKSggXTKBDF5XPjAUO31F2jJHXzVVlK4ZvI/OQrRWIBcSRCnIbYvgwGw/5+uS3DPoYS0hONBYkXmdgsOSwpW0buQGtJeb2VXhKwaXWoTrZpAvNPQf1ZRLxm/Zft1YoewQnI6RVMiZIrhms/5zplgl3/dO0qrCiku8cYl3FKMmsQHwuTbxskvmm3+bSjDD8PMxOrTIg+Mu+TjRyLo4Ybs5IS8l9w4WEEMbZyyNWHRnCkBZddDKJl6wcUeG7BAtOwzPS+KlEkSJOjD47293nNbRd3eC9JaeYf36y5dYbyQ86eo/ZFX59hWWKdczzWPHCbu7+Yy/ufv9/KXVL/LMcRjEf3XwDr6wc45Jr4LXSEj3Klx+/C4SzZudZRbrc3w7I8ktZolD/qUFEw2+UVK/JRk9lHPibJdFf8ayN+NbnW3GU58sshGh4geefoGWFfKZg4t8z+oNBlmFV/rrHI2q6FISBAnLtRnft/oae0mL10brOKrgYFqn16mjRhaiEKw80qHpRcxSl51uC9vJSSYu9pFN1ioQXoF/zSVZKJEbEXmmsPZd7LHZduWNAlnNaDbnhu2e2sTXGxRBiZobtLE9h8qhmXsMLwqStRxhlzx57g7/YPMT2AL+xs7H+MZL541IV8CJhw643DykaYd8uXMWKTTLwZS8lNwaGLLidOyjY4VdT1lfGDOOPAotKEvJ29d2OAgbHE5qhDOXcxtdbry8RemXqEaKbRcIoUkTGylNZHy9FrFYnbM3bBCNPLxGYszNEwsrlNgTsw11R2Z2lTQhPxc+gATWbijSulF/h+ulWXbERgCrErOJO/vMXZPac2+BM79eUCrB5KTDfNP8v4MDfUxWENR2jVyi/7BCS011x3Q27sBw7ZOmIm4bJ4DMj7MaaxpnKqjslwSHGb1HXaIl8z0XXtO0vrpDvrtn3qRPvo3+o1XsmensEAK/m2KNE9RoRtGuMj1TI1yUzLc03pHpkpIFSNoF1nJErRIb+c23GlT2NOmPDhnvNnC7imSpwJpKqvdh6aU5qjelbAQUvo0o9YO0nPmmz+FTRtmvOi4qMvoyMEUwbQiKJOb6//zH5ud/4/WRIKHu/est6C+NNriTLPGTrWd5zDXbwk+FLv9n93v40aXnecYzses/efPPcLffxrIK3HpCllqoUDBNXe7tL+BVUtarY0otuDFdYrpbp3JcF1uvC+Zb0NyYsBxMeXlnE+4EWKFASSDQFJsx1yfLZKXihzdfxhYFb0xW6Y2r5LGNW0mRQnOufsRD7h5h4RJYKXdHbYa9GnJimYJSz9isjRjGAUmh2F4ZEOcWh2PvgW2mcsXFmWjSliDv+tgTQRFo4hWNM5DIXJHaJcM7LeyViPwgAEcbEeTFEUlqYX+6ijMp6F+2yU5FvOv0Pf788jf4gUrIN2Kff7jzp3j9udN4x9SCzffvULFSPnvnPEqVDzx996ct+rOAsFOhtTmm1oiIHAfXy6i7MW1vzp3hAlpovnbzDLqQIDQPnTjg+tdP4kSCVIBsleSZQgjNw5v7vHL1BHYzZrE65+b9ZYTSNJdmzCNzfMQrsQ8VSy9n5IFkuqXIqlCcC/G8jHlsYU0kWc14/HL/eM6nTBfkHUkq+5rekwWTxGP2e6ucvpIQt21G5xTRaolupth7DmnzWFTqacI1SbkZU63GTO/XmQqDHRKlCV2VmSZc1YbuMTNaqsYtcGYFKjGs/9yHfClDjSxqd0N0FGGdPknne9fIqsab6cxK/MMI1Z9CmqF990GxGp01xzwtIOgaC5g9AZko7JtVgh0fuyJIGkZDlb3eQlSMONg7VDRul3j9HHVtB9aXyRoe1iylqNgkTZvZuiJaNkx55i7+kcA/Khmdlw8G9yqCyr0/Fo7+W69Cl/zfYUA/r/JauMU/Xn3JfBzJP1p5mUy7Dz431jYr7oTnZqe5ncz4fO8CB5M62e0aUb2gsjxHvO6jErh7awWsko3WmJqVcGO8RBTbiPw4nHMo2PwPbxPlNjd2l3n56nlyXyN886ZkyUi8VxfHnK93yUvF53sXGMU+09ilKCReNSEOHaQs+YWNbwDwK901elGVYbeGNbApvBKrkbLQnDGMA/YndSpuylowYXfWxG9FZBUL+55P/W5B0pBUdsyQfH7SPPXVVGK/fUgc28jDAC0g3wtQ6yHZzEHEivTFFkuvGRbS0eMu3vt7/JXTX2eYV8i0xZdj+PX+e7jyjdO4Y5O9N3xHxix1OBjXyXNFniuuHS6TZwrXy8hSi9r6lGGvht0xgsPoQkj/ARpGMR97KLdAWWYV/sZr2zgZpO0SuRyTRTa2l7PannB72EZWMp46cZdRGvD0+dvEhcWN/hJFrsx2q5CsPWu46dmiCcaITqQsNeaMJgGkRuw63ypJ2uB1hYlecwXuwEgYeu/KWdocEf/aKpal6b7dZXY6x2nPIFU4t32c4zR2IaH67h5Kloy+uYJ7x4NjG48VmQIT3J9y+0ebpMs5jddsnKn5uD0t0EowX7FI2hYyg/ZzNu0rEVoKRh88z+SUQdxUd0tUoqlcPYLeAF1q2FhBK8XoUo3xWYl/qM1SINdMTpp5kj3TOGNj++k/pEycV2CYZ/ZUsPRiiRVmyKzEO5ghZiF6fZlktYoKc2ScMTlbYXzGsLbcEVT2zVZ0vqoYPGQiwrKKoHG3oLIboY++uzyst3TB+is7z/DMxg5/tbkD9d6Dj//V5g7Ag2Pif3P4OM/3t5nELpcWuhwkDZpOxBv3ttHtDBEp5t0KYrnA6SvaGyPOtPq8cHebW+N1qGVIq8TbmvL42h4r7oRlZ8o/vfI0/pueOVpsQN7MEW5BpWoK1pI/5zN3L6BUSTj38IMEWxVcXO/wxuvbOANJetbsff6j++/j2Zun0ZHxRub1AlXLkKpknjjU3ITHV3fJS8Uo9bFVQVFIiqGLGwsKR5DWDd43W0kRoUFA6+2IKHTJxw7CMqlCP/rMN7kxXeLV3Q3EwGb5pZysIgmXHcK1kqoquDpf5++ufoG5Lvnd2QU+ff0SztREmCUPR7zn5F2uD5dwrJxGO0IAYWozLXw8J+OhlUPujNqooYU1E0RbOY4qSXOLC+0uL4cbeNWUbw8ckrkDbknaMqLVcuJgNxLyVNGbVshSi8vbByw5M9pOyCAN6M2aOFaO18zp92pY+w5Jy5hxx2chPxviqJLeUR3Zs/GHprtRkRlu5xVNVi9RsSTczg1Ab66IvriEbBtLSnoxQmSSdODhdg3EsfAMnx/gaLfJ6pcUXgviRSOujJc0DAXunQLtWGgbFp6z8PsFVmQcA6Ut6V+2KHxwhrD6QgxA2nKYbFlkNfMzKsfBFVZcguuQXzqJmieIQjM/U2e2IandNUZ1wMywKiATgw6yp4ZV5Xc08y0jwbHGivq9kurtGTJMoChgOqdYXyJZ9rEnGVoJbv54C3sq8I7nUn6/xB0XdJ5wCM+miFhhhYrG7YLK/RDrYEiyv/P/6z3/77re0gXrn2x/lXrtO0fCnx+eoKYifrLeZTefsZv7/OVXf5z5MdGyVo3YnTU5mlaI9qroWm7SamzND7/zeVyZs+aMmRYeK/aYo6jKoVunFsR8cP0aVZWwm7ToJHVGWUCRK5QD082CYG3Go0sd3t++gS1yvjU5xa3JIlmmiKYeSE2aWlRqKVdubCJTQbqdstKa8qGrH+PmtTWzBUxMam9e0bhLqbGnCPCtjCu9VeaRi1IlWWqRTR2smaSyZ44V07M51bUZFVlStoTRae20kJFEWBoVSoq1vvEWqAAAIABJREFUhIO4zvXeMsXIobErmC8rrNgEc4oCeq8tU35gj7+x/yFuThbZ6zdYXRiz/OFdumGN5WDKrfECNTfhbP2IflIhzB000FqOsGVBN6wxngagIa9qRCZwnJx3rtynG1dJU4XjFARuSlEKU9RHPqKZomML6efYTs7G4ohJ7BLPHapWQlQ6vHi0aUJVj6/eUQ05sqnfhrgpSVqCtFkgOh5yLKmNDd3A65ckTYEzNl+btDXWsU3GuqNMnJeCtAGz7ZLSKxEDB+2ViMzMttKWJq8VqFCiIsHKl003Ey8YXpRWJsrNPyopLUG44VO5L3AnRpEet8wtlTYMGTTYF9T2cmYbDknDFJvSNqGn7ijHCgszQ7IERcVBaE1RdUkbzvFQH6IlQVa1SJoQbZoEE+fIzD69gcYdlYzOmah6e2AAjZX9nKJiI1PT3WbnN5hvmODW+CGHtAZeD9pXc/zDiPlWwHxZErck9gycAxt7Jlj9Zow1MQUUS6FWlmDvj64G/KvXW7pg/djtD/BnTl3hE0ePsezN+OTrlzm73eWzgyl3Jm2U0FS9hI3GGEcWHM5r3L++grMccubyPvujOj/z7k/xp4IdvhQvcy1ew5UZXxqcY5ad5WhaJZk7+G5KJ6nzclQnKSyW/Bnf37rC7lqT6/EqP/aOb3J7vsjt8QK/m74NgHnmcNhvoEtgbkElpygkg1eWCCZmS6R7LuMbK3SWS4Sl0VaBNVQmwr6REc1cMsfCsgteO9hCejl6YrRXopFi11LKakY4CYjXSqxmSiuIOOg3KLsek6BAVjLqaxHxi21kBikuz1qnKVOFCiUyNcLIyVnMmw5YePiIikrYSVvcvb3Mn3j0Ktv+gEAlvKBOcK23TKEFD7U6VFVCZNmcqfaoqZivHJ0lKxVxbt46KhLosyHv2NrFkQVXRysUpWS1NaXpReSl5PrBMo6TG4nG3Ob8uX02KyNe7a2zc9RipT3hqbN3eGF3i1YtpDeqUoQWKI0c2zRuS/yjkum2IF42Hji0QFtGgyRyg22JW8ZBYEXgDUpkLglXNfMNU5xUJHGGEisy1Fh3KHAnmlIp/H5OVuFYnV6QB4po0SJpStK6sd+ouSTYN12WFoLRGRuZG3ZWqSDoZFixIlxWOCNN680clZZMth2mJwULrxc0vjSi9CySpYC0YRG3LbxhgdsJideCB9SI+ZrF9ISgtDVZu6C5NiEeVmi25owOa6TtghNnu9y/ukpwYIqqzAS1u5rqnunGwjWX/JRPHhh8d7SW4x9YVPY0zRsFR49adN9u4XeqyAysGCoHGVZYYPdmiGmIns0QtRrFYgPKEj3/7sbmvKUL1sVah08cPca9cZsXb53A9nIuNQ55f/0aL/gnCUuHRXvGtPD4Wuc008hl5UyPc80jJqnP33749/hIsMdhATvpAk9XbnA7XeZircPnDs4T7lURzZTl6oyfXvt9BoXHL3Q+wN3JAs+6Z7l+Y50Tp7v8zt2HmQyD46Reo5wL3JRWY87odYPszT3zVC8dTVaDrF2gZuYGQmqssSRv8EAvpCcWop1SrcRYqmSxNmf3sGUYU/WUIEjwjjsoAGc5pMgVB/0G+cSBam66qj2P4iUfS0G0rI3jfmYjZ4rKniQPeMCrUqlRafeGNb5lnWC/36C2MmMvbDDNXWpWwjAOWKzOUaKkZsdEpcO2P2TRnvL8+CSH0xpKlozHAfLAQ5+b8/D6ARUr5VzQpRdXuHW0xA9feplP3ruEJUsqQcJkGCCk5qNPvMql4IBPHD7CZO7hODmz2OWF8RZSalOsYuNMFsfEienpkvHFEqE1wX31IABV20ZPVr+fH+uTzNE5WhbMNiVpzTC77JmgSBVFrSSvaPIAaneNDi13QWUab2eMn2TEJxfIK4rZmkW4chxVX9OI1HRgVmgKVO4ec9Kn5u/W3BQ5mWq8YYmWgrwiCZctZicEzRsldliSN32Tb2ibFOba/QSZFiQrwbFWSzE6J8kvzygyhTj0EF7B6KgKhcBSJf/lez/Dv9x7jP0X16jvGR2d1OAegwfzikIlJSrV5B7MNgE0rVdNpy1KOHxakVdKGm8KWjdSRKmxJgmqN0EHHulKjcH7F3Enx95EIahfKykPvovtFW/xgnUY17mftLBUwcUTB9wbtPj8/fPkW4qv7Z1CAz9x9jm2nR6DVoUXsw16wxqdTpOVlRH/6M2P8Cv1CbPURcmS37cf4v6oSfZyizzQCEuztTLkbc19TlkeNhGngj6dsM4nr18Gq+RwVCPp+1TuGa75SFeRTkFRE1TcFCTkjRy3lpDtVggOzCDVHVnEixrtm7lXFkjUwCZr5Vg1E8bgBylZoVBSkxYKHSvcjkXiFtTbCQe9BkhNcimiHHnIuZnZCUsjKgVqx8OeCWYnSmNqrRQ4lRRxrYIzEthTfQyiM2hj94NH/PSpZ3mnf4e/fuPPstCccbHVpRPV2Jk2Gc0CtAbLKql6CapRItGUWhhJRneNeeiaYiKNkrooFJ2wxoIbEqiEi40OZ2s9Xhuts1AJuXtn2eCWWynvPnubmhXz8f3H6E6q6FIQRy5Z1zHYGqCslgQbM8JegAolefN4K6VBo1EJTE8XaMccf1o3zHA7Ou6usrowQlJAOcbIXp4LadVDBm8uUNkTqMiIPWUOsw2FzCDeqB8nVkvCJcsgoROORaSCwjYDaDs0Rz8k1HYLVKpRSUnSUFiRCWBNq8YOVVqS2UmTbej1CwpPMt02epvSMlFgWdWi8BwTk7ahiJ4yPPz8yEcUpot077iIEuKzMf/k8j/nr938s+y9vEZl35BiRSlYfKXA7yZYvRlozf5HVkjrxrIVHBg2fBYIZpugH50iNJz6RRt7GCOHUyhKiqUm2eYCh+8KCDdKGtfN65h7EmduZrEy8CH5IywC/8r1li5YX37tItXtgqc27rHmjXnzjS381RmfvXkBfT+gdDT/LHs32+0hJcIkDO/6WAV0potoW5PmirKUxGMX/66D19e4sSZcFUQXEx5qHXIQN3jiWz/OSm3GZmXEkj/jeriK34yJRh4iMytukYPVt8mrErs5J80VtYsDHKuge3OBoCvNalxBGRSGzODn1OsRo6MqpV8iI0XulFhdh1h6Rk9zKiQLjZ+sPD/nic09ZplLObGRsaQE/B2b5EKE7eQ0q5EZgLds8qpAJtLcVIXAuuFgRVDdLylsQMD4yYTbH/xnD17XV9OSzrjGB07eoGmFXOmvmsH1kUNRLWieGPCRjavcmi/xdPMW4zygm9V4dGWPuLDJS2m2d5FP3nERC/Cx9ksc5XVcmdOwIhbaM37z1mNQCJy1OR88dZ0SwZcOzjKa+SY9J1VYBw4yNZ1MvJpj1VPinRoS8C6MmQ0DiCV2KyELbSbnc/ALgusuC1fNIH2+qogXTEEROSQtHlBXS7/Eu1qh+qzF0o09tOdy9O4lkqaEEtxRSW0ngUKTthxyT1A5zNESsop1bGsBdwC1vYK4YegH1f0ca15QeIrJlo0z1+Q+hMuK7JjKKUqo34KF10OiZZekLknagrRmQH5eD0pH4g4ysrrF9AzQ9dFegSwEbl9iTyFe0MiLM37h8d8g1haHX91A2prp6ZL6DUn7aoLTD5GDKemJRXqPBMxOGnift29sR/GiYPJwSrUdEoUuzc972P0hIkpNEvTmAuG6T/cJSbAP25/MKHyFFZqlgDtIELsdiuHou1AJvnO9pQuW8HO0ljx/uEUUnYEC9MsNHON/JTyTsdKYMox9Wl5EmlvkSynVZoTMFHlmEU48yCXW0KLwNaOHSvx9RV7VNFtzXu2v0xnUWWjOaDjm0bztD3iukqG1QFgaay7NTEoeb2UqgoqTcTSpcmG5y86kgVpMyFcLfLtACk36YguZQbQuGM2NZEI7Je6RjbXrMt8uQAtKT2MBIlTodsbF9Q79uGIU7n4BtQzvhm8y66Qm268wGtdImyVCaeyJWUpk2wnOHe/YBA2H7zY375nHd/jyhY8DRvo9LEL+l8OPsFCbc3/e4gtH5zi12KcnaggNTjum4cZ8o3eKh5v7nHG6fCa6TMOKuOgf0MkavDDaZj7xcG2onh6TFoq/feUHH6ThVFXMx3ceI75TQ64k1IKEL+2eIU0t0onJ7VNjC38gSFua7HREmSqEVeK8FlA6EG9kJImFnJilSSVIIEiYXWvh3rPwBprxSQuEEY5+Gy+cNjSlY/yV2tE4A4Uzgdmmg7ZWSeuK6SlImyX2WNK8Lkia9oMkm8IRDM/Z1HbNjSoLkNPjeC5fktUFfrdktm4y+7QEv6/JPcF83WwpvSONMzdzLb+XUzqS2Zrpjv1uSfsN8zErLFBxQbjq0ntU4h8Ios0CNVPUbhsV/ficZvORQ965eI/fGrydV3obpI0SFQs2P1diT43AVFuS7oe2GD6k0cqInr1BSeYLjp4q0UEOkcL7nQb1aUlwGMOdPYrLp5BhyuR0QFYRnPi9iMlJj/sfcXBGgs3PJ3j7AyhK8v4AYVnwXQQ2vKULlo4V8WFALMDpKfzEzC5kalbS9cU5npWRFIof2/gGbMA/33uamh1zb9xiGH9H57P+0JjbowXGLy0SrZbQSjnd6tMNa+SRRdkQhLnDn15+iU7WQN4ISJrlMXLEaG9Kyzw1P/rkK1RUwmfjC9wZtpnNPCy7YLVpFOCdl1do7GuiZYG9HFHeqZAvZ7g75ugzP1VAAaKdUKnFFIVEzyUr54YkucW9N9YINqeUpSS7XzHK6ZY23WNihJBeVxJ0jHVk8EQOoflVukNN48/tsWWnPNW6w7srN/hqXOH9fsi1rODnDj7KK50NpqOAYkXw7q073BgvGXvHYkZgFdzttXGcnP/h1G/TLWr8p4tf5oxdpVfM+Ut3fohrh8voWFFaGiVLjjoNzp7oMEgCRukWgyige3MBsZIQVBIGowpby0Pq7Zhb1gLxTg17agiWpaURSnP2ZIebN9aOj3Ul588ccP3OKlYiyGs5YexQFhKvZxTm8YLBCZeOUbFrAdGxdEH4BXpiYY8Mw0slmuAox+1FpPUqaMHm5zRZxQhKo+Mk5+DQaKis0Gid4gWNTAVe3+ibkpbAHUDSMmk5eYVjPRRMt83m1woFtfsl1Xsh2pLMNzyywEYlGneqscISrQT2NEeFGVndof+wIquWpAsl3oFBTs+3NVmz4PLFHfJS8ptffxJrIik8Te2OZPnFkNxXqDhHu4rx2YD5hiA4EHg9jTfOOXi3Il8wYlVvx2XxtQxnFJE2bJzdAeMPP0RalVQPHJxpSe4pwlWX+YbEHUDQ0Vi3D9CAsCysE1toT8Kb372a8JYuWE7HRrfNTMjEcnMcHGBipbaaI/pRQLdf5xd5P71hje3lAblWfM/6TV70tvCtjKYTcXu8wHjmI0qobE+4tNThgwtX+d3uI1RP7zOMfS7VD4lLm093L+EOBLkvKddi4pmNd2ghCqg+2aNphbw5XaHipnSHNVwv4+SCEdS9ubNKfV8w34D4RIpILKQCq2fjDmF6pkAHOZVGjGPljHaa1K8p3A/2Abj56iY42sga5jbUCmIMGbLwzA1hhSYdWGaa6QmJ3Uh4ZGOfF/Rp9MWYJxtdZrnDabfL/axNWLqEeny8JS3IcsXKyohnVm/RTWrs7LdBgFNJyXPFpdUO37v4Jm0VH4MSq+zmM/633vt4fX8Nbleo9QXhesn4ZgtVQrJhsV0bYsuCGwfLaK806vOxz5Pn7nC2csT9qEW0dwK/Iwm3crA1IpWUI4db/XVkJoi3U1bWRwihaa9MGKiaOVpLjRAFflcz3RYUviZbMho7tCQ9mWA7BbaTE9+v4QzN+wZMHFtpC6anKtjTgpXnS0ShCVck0ZIRAwf7Rprg9TMQDuHad2QVpWMeVH7HrPDiBfM7qB2ZB8bwMuQVM2ur35K4w5zZiYDxGUXS1qhIsPElc2wTeUlRccirDtNTFaIFSXFpxtPb93n5cINkVic6mfHDj7/IQ8E+AP/jx/80rfswPqep3pc07uTsfiAgWSyp7LhUdw0oMDjQD0zRB08riqCk9byN3ytpvrAPYUR2Zg1/b0a62WZ43ohNi4HB5ngjI9Wo7Js5XVYRzJ4+SfX6CN3tQ65gNP2jufn/LddbumBhaey5wJ6aTRcaGrfNi5kHmqs7q+hSIJSmP6oi7vk8c/kmnzu8wLPhKaTQLHhz7kzahKlNOnJhueBEfcITjfts232eaN7nN+88iiVLWnbIb+y/g50vbBOfLZDtBNsqSLUgbUqaZwd8ZPPqA0zMT61/hUxbHGYNfrf7CDujJpXXPMI1Tb6eIPsOojBYYhWZMFNqOZV6zPwoIO1bBGPB9J0R//mZb/K/f/ajYBvUShrbZq0/sbAnEisESkH9XknSMN3JfE0SXYi5uNLjVKVP70yVtjfnUnDAuj0k0wpPZoSly/PzU3x67yJH3TqWW+DWC27NFnnx9jZiaqGrBZ6b8RfOfpP/un37+BdgGGO7+YzPhyfppVU8LyO0YXohM6upVOIsxAzmAWmhmEYu+sCDekE08KkuzZFoPrlzicFOExyN9+4ep2pTOrMavW4dNbSwp5LkZIKYW3TutxkvRPiuEcjaixHJ3KHyusvooib3S3TlmEBQCvJWDpmkUBpSC600SPAPjT3H75XIRGNPC+xJSrzscfSYTVo30WbuSki+BZ3lKguvOsxXJUnb5B36++qYJ2aCHKYbFlZojohJSxAvaEQGwa6itlNSKth7v0O6VCD8GGvPpbqrcQ/NYLus++RVh847XeYnc1AFzB1e6azzkRNXkSc1l4M9bFHw20eP8eI3zuHOzEZx4VWBMy24/zFtUC9uQbxoI1OJFWvCFRMSYk8E1fuGx+8NTbdHFJOeWydacUgrPqUFresFsjD5iuGKNObmyGQmTs6VyAxWvhkh4pS8Zx6oYrn1XSkF377e2gULowbWhmBL0NEkTYEWhiFUzmysiaKoljg7iqyiaVghf37rOd4I1/nMnYvs77WRToHt5tRXZjhWgW9l7CVNvnB0nmt31rCDjHds3+ezhxe5d2sZ2S5pnTApM3kpSQY+lZMTvn/7CttOnx+s3mJRVfhaXHJU1AlLl1IL4itNlGOIjoxtyqBEVjM2lkakheJoUMPzMvJcIhIzF7v4/df51dOf5NK//M9wxiZkIK3bSKWxb3mUlqFDZjWQqVnXywwmmyX29owTzQmnq32qKuFHNl4ikAlKmPToR9wdYm3zD67+SWbXWpSWRi4neH5KqQVvHq2gI2Mo1osJv/7YP2XdEoDPp0ObDwcZszLmt6aXCUuHi5VDWIVnE5ti4oLSNDcmLFbn3OksMO+b1byzGaL3AkQJUcVlf94gShxam2PW6xOqdsKNwSJpbkFm5njF+pyKlzHTPtVmRJ4rJjdaeCdmpImNd9NF5pDVC1QkKXKJPVTYE4HMJWhIFk3Ho6sFbh+CIxOvZc9LM4MUMD5bYXhJkFcMy11bmiKX5H0P4Wi6T2r8A3AmhnUebucm9ef5lHDFRqXGKJw0oAg0/qGRFdR2SrKKYHze8KharyhEqdDCqNkBJg8vkNQl4/NQeMb8/b7Tt/jGzknmuzUOlhvU7JjPDh7i67dOUc5sqBeUE0m8IAjPpZBK6m/aZAHIQuH1jXRh8IgxeVdvK4JOicrAGZtZmbYV4SObJC0LKyrx+wXVKx3SjRbTk54xbq+YkA6VGGmONRNsfiFlcrZCM84e3I/5Uf+7VAnM9ZYuWPZY4M00KjH6kqhtELalrcnrBSijShbVnPm25vT5Q16ZbnEQ1rl5uEQ5dJGJwJ7ZJBsZ/mLG4GabXrXOYCtgZ3eBSivi7zz8uzzm7vN3dj/GbqOJvViwUZ8wTV26kypLW0P+41PP8u7gFo84HsNC8CuTRaalz5bdZ9GacG13BTcU5FUjCm22jV5rvT7hjXtryJ6Dsz1npTE1XsFGkwvNLr+0+RX+Xu9RnL6ktKDYjiGX2De9Y2GkQGUw3yrwOoYuOt8o2XrkgCV/hnV87rkbLfBats7V7gpZavHRc29QkQlfHF1ker1lwkJbBRIT/T6KPOYDH6evyLYSfunJX6VE8EvDR/jphRt8OMj4+eEJroWr1K2IqkpItMVze9sUuaK6OKcoJHkp2ek3zdDcKVAdl+AVmzwwpITVhTFhZnNyYcDZ2hG3Z4vcOKY8JLENlkYXmmxus9yaUvUSZrFLdrdqko1nLvaeWRhMLhjxadHOIDYaLW1BehxDVtYKyASt1xTuqCRcMiyqg6cV/pGZQyYLmmzDWIbk2MZajClyiXV85Na1nKieo7oOMoHqLQuVmOj4b4er5hVQGejU4KOXXjLD+t67ckM6HSiiZYHXg6Bb4B+EHL1rgd5TOcLPWF6c8I6lHd5bv85//8r3I67UaPTgpdVNksiGkY09lhS+xusZn5/Q0HzBQSWa0aUS/9DM0UYXTN6gPTZEjqBT0n55iLYkB+9vMX40pfpmgDPReAOjD1NxYbRWTYfcFaQNs6ApWgV+1yJa1rSuGYmH188pX/0DQ6vyu2t+fkvjZS7/5Z9l/aUMkWREWzUOn7QpPGNTyVo5wi3xa7GZ94Q20i1wbvpYc4hWSsrFDMvLEAIqfkIriNgfNlhpTFmvjGk7IZ++dQHXNSr1JLZx3JyF2px54vCe9Tv83dUvkKFZPg6JeC7J+LXB07w2XOfpxTv8+pV34L7uE62W+Jsm+di2CiZzjzR0OLPVpTutstUccbZ2xH7UYN0f8/bKXcZFhV+7/w46txaNsv22j4qPOU2LCbZdUF6rYk+NcTcPMEpoYbZc1nrIenuMFJph6PPjp7/Fo/49/pNP/UXWzhyxVpkwTT2i3GYUediqoB1ESDTXb62BpfFqCT924Vv8rcU/PEn9e72LfPzuozhWwSx2CQ+qyFaC62akiU2RKnQqEW6BGDpU75ltZdzWZNuJgQzaBY1axEp1St2OiQuLMHe4vrOCX02QUtPwYy40u2Ra8pVXLiIygXukKB2NMxEUjvm/losZWvOg+0pji6CaUPUSppFHFDqGo7/noWLweibOzIo0Sd1YYrSEeFHjHxkkjyjM50XLmqxZIiNp9FfRMZ0VcxTUylh5ZG5U7qIwf9bvlagU9j9U4HQtKjswPWkosMGB4VYliyXe9pQrT/8qV9KIn3rjJ1ivjokLm7oT89LuJuLNKqIwCv20bqCNtTswvgB5OzObUgXBgTQqe2k6IZVorNhsIr1OSOlaxEsuvYct7BBa1zJGZ2xm24baIVPB1qdTo84fxURrFbKqpPtOSbkeowcOKjJq/sa9HFGAvz9HFBptK3qPVOmfjbj/N/8YkfxvvJyJZnyuQu4Z/o9/ZLZgk1PSPFo1ZNLBmgl0VWPFjsnOKyQqESwuj03izLjKaFhhHrnkqeLvP/FxajLlL175CcpSMutUsUYK+/SMHzn3Mp7MmBYeP9X+GhnwxWidTFvYIudqtEEvqWKJkrvhAvY1U6x03YDo4tAxm79cUWlEuCrnVGvAQ/UDAC7VDjnvHdLJGvx+5yFmsYu7EhIPPLLTESpIsXNFdhgQewWOMDeZeUMbwWK8ltFeH1OWkiizKUqJa+e8NtvgE/uP8Ne+51O8Pl/n9nSRnX6TVi2kHUQ03Yi0VOyOG2b+k8Fme8Qlb//Ba/6JecD/sW/yE0+1+qz6U75xcIJsMcJzM6LYxvNTEmGTFTbyyMEdmCNFHpTm3DWz0ULjrCacax3xWneN9fqEe/0W8tUaejNnYXXIucYRH1t4mVfCba5M1/D3LCq7GsQxurh1HJ6htPn3JpIkschCBzFTzOY2YdUQO2wnJ41tdLWgeu9Y7tASTE6ZouMcs7PsuRGW5mtm0zp+W2bal8wM6WViwh+8nhk/RKvaiEBrBfg5Zdc1nUzXBFVMtwRWX+CMBMP/h703jdbsPMszr3fPe3/zdOZzqs6puSRVSSrNtmRjYVtysAmDnQCBDoQ0BJK16M4iEJKQYXUIQ/cKaSAJSSfN5GDAEMB2DAbbsi3ZkkpySSrVXKfOPH/ztOf99o/3uAwkdP9qrB+8/6rqrHOqvvr2873P/dzPfZ1P0AKN6mWBt5+w/XadqTP7/PrZX+G71t5HO8xRsgOu7U0xV+3y5fV5xB2PqJJSWNbRQ4nUBfmn9onO6SQ7RXQvIVcfMRrb+JnDxMVDPFld6VOFldFdd3rvVIFMV9NOu59hNwMa/RiEhz+B4gsaGtZOn/HRIp0TpoKn1pR15ivDLasv6c8bh8j7PPnVEcMFj8QTGAPxP3pU/8LOW7pgKWy3giMkeaUtJJ6a0CQ5SIoqYVL3dcSRMW4uIOp7PPjoCqfzu3Rij+e2j2OaKZPlAX9j4SWe9m5y1PD4N52zNJeraKGGcDMyR1LJBRx39tiMqnxu5zj7YYHTuV1ujib5YP0irTRP1Rix5xd4tLbKgt3ihamTlK8YZJbNeNoiK6QUGz1sI6WRG3JPaYdmmOcPNs7wQyc/zWl7h1vRFC92FzH1FCkFwcDG6BkYWybELvF0CuUIYjW9QVNLvFFJEYPnZ1sMQ4tqbsyZ0h7NKMdrW7O8ODzKd5y6iCkSRonN3iDPyUmVPrrbLbA2qJOr+FhGwuRCm29ZuMT3li5T0T1uxiN+qf04n909gSbUzadkBVxqzjIOLBYbLfYGBQwjI0l0DDMlTizslkZclIrJZ2eYxQjDTHGsmO8+pmJ1rrcmWNmvoV/PkeQk9bku75m+hilSfmXncTYHZTQhqVxPyUxBb0kjmE5xJkew7yESDeklVOe6+C/X8XpqGTnJZaSmjpWPCDsOmpcgDUmSQ+Wma2C31AKx1A/bwcWAsG5hH+gEExlOWaUoxKv5u4mdcQHG0wp9JjUVypf5GlpLbRYovL1guJBhdQWFNejem2L2dHKbgsyQ9BcM8puwt1Dk+5c/hKFlHC8c8CON5/id4Rn+7bWnkOtK58tt6JhDNfmO7h9ytNTmZqsFZdViAAAgAElEQVSh3hM7Jv1Ji/wdQ+lkriCsKARX4moMFnMkZws0H5BIS5Jb0zD7kt0PRGS+w+wfapRvxUhhKv1qpYM0DXQ/uwvvINbIbyirSFSSxAW1htQ8Aid+tU9U85QHcSSxk78sWH/u0QNIKwJpKD0rqqjsn9SRxIext1qgES6GzFX7mHrKRH6IrSX8wfZZpnJ9/t6J5zhh7fK2u0GAeT5052ne2J5REbtmimslSClwjIR/8dI3YN9xOPWuZf5a/WUCaeJpEX/Uu4eiEbAdlvgrU5dZsvb5ROc8IhUMljK0UJB6GRfuvUPJDLD1hG+pXuRqMMfnd49xvNrknK32sH5p8wlW9mqkPQuzEuCVfMaJIKlK3nXvdd5VucaPf/KDGL5afkUeCvkTIcenmxTMgPtrXd5XfoPPDs7wpd0jWFbCexdUW/f7e+e5dmsW4etExT5BYhC2XbAyhJBIKfiOIxd5wruFJgS/O8rzsdbbudKeomQHPFxb486ozis78xhaxlKjxe6gwGDksDjZYtId8NLqUYyugT+nplXCkGhGRq08ZLHY5qHSGuthlY++doHCmxZ6EcLFkO984EX+XvVl3owKfKx7P3Nel9OFPd7ozdKVNTXmdyWiFBFHBsJLcfIheTdk6NsEkyn+tMQY6GiRgLZJrEvMUohtJxQbPeJZnXjkIN5UZtigLrHbgolXU8brDmFFMDweI0KNLBPETRdsxWwMphOEm6IbGfHIxLtjKpJQT6d8Q63mdI9p+HMpxmG+eVQSuJs6+U1JVIKoKA7Fa7CuelxvzjNxvMX7Gpf58Z338pkX7sM50HBiZdH5CvgiKkP+uRy3slOggzEpKKxIJl6F1FZ8RDV4AH8CvD2BP6ERVxNEqGE1dfzzPqcWNqhYPq//23Pk7/TJHIPKTXWRTCsemanTP2IxPJqhzY7Rl3NoyaGHb0Vpf53zirUYTOdV+GErAWEi+tl/95z+RZ63dMFKPIEmwOyrJdM4L+ifC5md7rDbLmJdUWFxxtExRTugG7g8OrnK6rjGUqlJ0VBLT2/7E6mlsUy51Wrw0NwGZdOnG7tEmc715gQbmzX0rkF4LOAHZj9DUQu4GU1iazGzdpcgMznl7RFLnbWoga0lfOdTzxNnOr935z7ubewz4/bIpMYotfhI8zFGicV0rs/3TD3PalLjTjjBne06xppDWk0RAk419tnximhC8pk3zvD83n3YoQKann9wmSA1ufH6AucXNnH0hMfLynbw2cEZvtyexzUT/tO9v8rLwSK/tX2B/UEes21gnuhTtcds9UoACENFEJ+oHXDeXUNH8nPtB3i+eQzPUOmrT9VucXM8RSI1xkObRm3ArZ0JkpFJeWJAL3BYb1ZIQh3qMcLMEJlABjoil1G0Qvb8As8lJ3lzZZb8dYvRQkZWirlvcYuKMeJnmm/j6wrX+L76F9hNc/zQm3+N7I9quGaGNCA9GtCoDGh185QqIzw7YhxaCCGhGCMG5l12YlpSNpGCG1BxfHb6RTQtw3y5QFCXJBX1MItMZ/+CSsrI6iFHptusrTTU9yzEyLFBaki1SrTikFkSJ1B4eWfXoHotxeqnNM9ZRBW1zJ6Zh1pSoPyB3VMQzUQQC8yWgR4JnAMorGnsF0v81PazOOsW9RVJah0OkhoaoznV8pduKqR9UJPERUnplkCPJJkpMMYZo0mTwWJGZmWUj3bpz3tYV11SWyerxEyd3uMDM2/wYneRz332HJUMRkfzGH6GFmeYw5gkZ9I9ZjFYUs9DuuMxcUXi7cYYw4io6hAd07FaOsZIMJhXQweqh7Ts8V/esP5fj9TUhrzUAAmFN222gjpO3af65C4AE96Af7nwezR0ydOvfi+Dnsv3PvAC7yu8cTfvHeBX+nV+cfUppot9Hi2t8K7cdf5odIZfvPok8Woety9UQFyk8RvNRwkzA1tLuL+wQS91SaXG9dEk/cjl5kGDODL4wfPP8eGVR/DsmDmvi60lLA/rVCyfnBEyStSE69f2H2e5V2NvuY4xVBMpnAzDSFnp1NB/v0JuL8V50CBYDMmVAn7szKf52evvIrhZQk5GPF69w+3xBP/59uP0By7PnrrKne06pdKYL4xPEkudD868yk++9Czm4oivW7jNle4UAMWpAbqWYRkp7SBHkJl8enQPAI/WVgkyk2mrSy/xaFgDbvQmuLC4zutbs6SxhlNWmeHdtho+kAoFLbUkwpSkY50s1NnqldC1jDsHk1j7BqOFlBNntrizV+fN1Rku357DKYaYJ1Je0WJ+7frDhB0Hc1oS1jTCmgpA3OmrdSkhJLsHJYSGYjdGmtK0JJh9DakZxAWd0DA4SPN4dkT3c1MYsdL8RGaQ5CSjsyGmG/O+Y9e41pti4/l59HxGmKol4/y6ysty2oqEHdRV4Sjd0ph8oUfUcNl60kQ7PcAAoq0c+RUNcyQZHIH0mE8x7yPHNrXSiOkzfS5vzhJFHkFD4F231TL1QOI2E6x+jDaOiXNFam+o9nM0paJsyjfBbaVIXfEQx0XB4Ih2l4wtCwmdrRIiFvhzCXbN597pHT7QeI3fP7ifzV88Ti1VH/DdSR1p6Mw+N0QkGeNJk875DFGKMNYc3F1BYXVEWLXpnMyjR2q1yxgqY7DUlI0mqCtmo773lwXrzz2ZroDJ0hD4NZh8JcY+CIgLBbSJDNeMKVk+H5q8yBlL3baOVDr8wL2/w9PumPUkBlTB+ucHZ3m1u0B7kOOfHP8Eo8zmRX+R3926n3DXw2upyZDV1wirkr2gwFqnwn0TO3y2dZJMahQtn3aY406zht/0OH9mjZ9//Z3ITHBmbpdB4nBtVCaTgpIVYIoUW0/IGRGXW9O0X2tgAPGEgpHmPTW53O/lEbOCzn0aouEzWRnwrumb/MQrz0LLxloaUnZDdsMSn759CqTg/MImX9hagqaN2+ihiQxPJKwGdbQDi3seXWd9XGEY2jhmgmUk+JES6B9trPLfeueZMAdsh2X2wzz3FHboJKoYvdhcZHWnxoZRwb6Ug5IkmBEQ6ndp1qx6anF7EkSiYVYDzs7sEmU6N7cn0ZyEaEoiRjq2kVArD2n3ciQC8m7IVlDmi2uLxAcu5BLFZPQk+fk+19enlJ6UCWSoIewM3VCMQrsYkqzn0CNlHhaTAScmDyhbPu3QY6dfRI/ACCSjghqAazFkwPnZLTbHZW7fmiY/ACFVSJ+7J1Qqw6HdKDNVqmjqZUx/uk1SzbH+XoPKqRbdvkcSGLgHGlZfwVbjqsS1Y77/xBf4n0tqgPHDuw9gLGS8mi3gve6S38oIKhr5nQRvtYsYB2SlHE43YzCrU72hfnjlVoo5TND7ERvPlhgvxuheAjs20pC8+7E3eL05e/f/MvAtfvbB3+Tjnfv5l7/9QfJrYErJwQWQmrI8zHxGudPXnykSnvbJ5UKGu3kmL6bkrzQZna4zbqjYnsQRJDnwFyOcVQv/VIixa6GHgsySjE9/1ZP1tThv6YJl9yS5cULiaoxmBWY/YeWb83zbs59DQ3K5P8NPLPzeXeozwLnSFg19QCxhUjdopiNuxC63RhOstKukicY/u/l+5gpdBpHD2p0JRKay3PUA5t+2yY8e/W9cDeb4RHYvhpbiAEFq0AzybHTLhL7J4/fd4gP11/hXnWd4bGaVmjni9qhBwxnyVOUmV8cz7IUFxonF9YNJxBdLUJdwdIRrZBxvNNkdFth5bUqNygXoY0EmJPvNIh99/W3oR8c8+PBNOoGHn5j84doZNKGmaK9/+RgA+pTPExMrOCLmf3/z3fBmAc2RXLq6SHW2i2smaEKy0yoxUe3zT49/jLG0+UzvDK04x7zT5pHCMjeDaa4PJrmyO00c61hOQtByiZcSzFKIlmrkKmOGfRe55qHHSqMxCjGOGzFf7tINXcJUp1oeUnF8VvZrWLcs7n1yG68S8V/GD5HzQsquz/XOhNo88FLcOwoAGhwNGXY9GBhIO0PYKZqnvFdJrONaCWFokpYT0irMzrSpumO6gUvRDLixNYl5x8GJVQ558bYSzBNPMMosDmbzpJnGxAs6B4+mKntsqDM8miESgTkUmH01iQXJ1POCvafqtC8k6LmQ3tBRnq2miduUuJ0UkcDkUot/ePyTfCA3BuCNKOCEu8dOUCIbmuihKqCFzQTdz4hrOYIzVbRI+brql9Xajh64SF3QPuXQO2Wjj9Xqkl5MMZcGPDi9wXfXn+fb3vg+iDQwJd964RV+Yvl97LRKPPveV/jkzXtIAgNz38TqqkTSuGyzd8EirGVYt11Cy8HKwNkbk0wUSVx1izJ8idOOSbc1RnsmURGitonuK/Cq1FXL/LU8b+mC5XRShkcdeqckWS6hfdbhHV/3Bk/lr3M9nOGjx/6Yr6yPAHx4UKMd57hgqzZsmAX84XiBjzXPc/VgkvFKkczNeOj4da50pzC0DBFqSCclsQUPv+0WT1evAdBOcjwzeYWjVpOH7F2uRhV+/OY3UsuNeWh6gwcL6xwkRX787CeIpc6dcIKHy6s86d2km3mshA1u9CaVgP3hE2SWmmo5h8XqTquGv1pAuhlJSUIGRl/HvuwRViUfevZ5PC3i1niCDnCuus2n2qeJhxbEAvIJRtPk5PQ+j+WX+alb7yX3qTyVmz7a5y4hbJvm33iQ3ad9ZCY4NbvHw9U12mmeqj5kwhoQZCY7UYm8HnCvu8lr3TkcKybvhnR6OaxKgGmm1PMjxrGJH5lqSbqcIkeaGgjEGrNTPTZ7JWwj5f7GFqaW8sfLJ8m2XaKSJEXjj3dPU8mPOVLo8OrmPEmsK8bgjklmSsKZWGmTrRJpLkW3U7JYI/N1jLaBORAgHXRPks1FmG5Ms5/DNWNOlA744sYi8vBhEilkHvhFARlElQx9ymfwmzP4dUHwQIa0MrSxTmarJFItOnwTCUgcOPqxAH0csfFjUNAzpBSMBo6ycbQE5iije0xlwEcvTvLqzCI3wgBPiximDv/+lacoXbKZX0vQkpjE0TBHqXLiGxqFKy2ka9197w6XirRP6/jTKVZXUZ2DmuSDT7zEh8ovE0iD50enOGL4kAomj6pifWswwTfPXaJ6ZMgvrj5FlgmMAxO7pQT61ILBnIm3JynflownVdyQtm+hxSm9k3mCqtLjzAEgDMKSIM4r0Ik+ULuOli6xzIR4FPG1PG9p4+j8v/+nVGcT0s/WMMaSj/7Yz7Bo5v+7r//7Ow/yamuBH136JM94IX9/50FOuHsE0qQZF1j3Kzx/4wRuIaDoBfzzE79PO83zE9eeIU01PDvmXbM3yaTgtLtDw+jzK7tP0PTzbOxX0DYdstmAv3r2dYapzZTdZ9bqsB7W8LSIGasDQDf1+IXX30kSGMzOtNm+2aB2SaP7bh/dSIlDg2xkoo80MkvizgyZK/eUiVOXiLFObm7Aqfo+u6MiB708Saxj2aod8lsuxckhXz9/g27scbk1TauTR99wOP5/75PeXEY8cA/y0hXQdJp/+xHGU4Innn2D91Xf4B3uDi+FNQ6SIjf9KW6PGuyOiuy2ixhXc2q3rhLf/RT95odexc8svrR9lO5WEaMckQTK/6a7KmPkyESbcWyqBzq0GG0WkLrEPjDITIk8/EiUswGpryNCHWdyhN9ysfYNjLHAPx0wPdlV2pOPQmZ5h9MoHSjEytWeanzHgy/xY/VXuRQZ/H7vQb7cnufO67M4TZVFnlowPBWjDXQmLn6VjiyFQnIFdaWLFlbV3y21VdaZd5BRWPVBwvCIy/77QyqlEb2Bi2GmzFe6LH95ntnPq+l066wCTIQNlbzx7U99kf+6fI5ouUjpJoexyQItkeQ3AqytDgQhaBrpRIXWA0X6i0r7QgrSSOPxk3fIGRE5I8TTIn6o/qW7huWf6xzhF2+8nehmkX/1zR/mhLXP9WiSWBpcGc/ysdV7MfWU8MUa5gD8KUlcypj5LHjbAZ3THr1T6t9evQx2P6V1j4E/naLXQowbHu6+Ev2NsTIpJy4Y9ymEUMnzqbljri4XWfnun/hL4+j/6FirNvrFIuEUvP7D/45vX3k/VWvMz8++9Ke+7vvqX+DktPqP/ZG9+wkzk081z5JInVOFPZpBnlp9wLcdfYUle5/nBmf4g40z3NvY5Xxxk4/cucDze0t8/fQNBpnDr60+yiiyGAUWMhMsPbzBN01fIpYGb45mSKXGS70lFr0mjhazZO3zun+E39l8gKOTLbq+y/atBtXLGr0TkAxMtKaLZoCeqTeNmAyRUnB7p4HeM9DmR5CDnB3R9PNsrdZVVEouIQoMssDALEb8nZOf59JwgefXloh6NtpQJ78GSS3P3g89wXAhYyn/ANZmG6svGbxzzD35bQqaz2f8GYpawAlrl48fnKPp59m8MYEx1AgaKdbUGANIEp1zc1tc6U0jpcA0UgozAwbbBUQmsCbGhD0HsxAy6Q7YkUVWNxpY2yZ2IgimErWrZ6roF+Z9Ut9A7ynHtr/vUbxlYA4lgyMqXmbnZgPbhNgAb1cQ1DXiwzZEdCyc2SGlnM93VV7ko8MjfHjrMWwj4fataSxfmT1HM5KjD29y8LvzFDcSYlcjKipXemErZjBrokVqcbx7RrnJzaEktxPjbioW4O7Tk4i/0qKuZ7R7OY5MtOkFDsuvzTH1YkZmCrrHlIeLTLnyjRF89PeeJJyLcPsqAFBISexpFG/0EEFMWi8S1B1a95pkj/WYK2/Q2W1gXfMoPbHHPzz+SV4dL2KKlE/vneLpyRt3i9Unxg63/AmiUCWGFDQfR6Q85mzxBf8Ix5x9fvTsH/LPfu9DeGMFWNVCQeGWjjmM6B1XxSozJNXLAnOc0T5jUL+c0MoM4p5Lbks57MXhrSzOS5KjAVloIKWgkwksPUXTv7b3m7d0wapdSZE/cMCV+z8KwIu3lrjznv/0p77mxSDlMeerbeHauMqF0hq3B3W6gcupwh7Tbp9xbHFlOMOX+wusDyo8PXeTdxav8TvNh8ikIJOCK/1pxonFVrNM3FHLvZPzHZ6o32HJ2udqOEteD7nan2Ih12FlXOeD9Yt8pPUYBSOgaAestqvIV0oUB9A/JkmmIoqv2cpRXFR0ZpkJSDRyToSmSaK5jFppRNEKSaTG6k5NmWY0kL6OzARGKeKZE1f5VPMs1/cnyXsB3S2P0i1Bbi9juOAynpFk+ZTWvQ7BO2YJTgQs1Hos2fvsJiXaaZ434gJ+atIJPdbWGhi+RlxPePK+G2RSoxu5nCttkaLRjV0GscMoVq3LKNSQNUVrrs+3MLSMVpBjq1XC3lBfE8xHCCODoYXIVMEKhybCV3EnZlfH2VPBd8M5gXZqQNZysQYaThO0RNI5n6mwRuMwiK+QoGmSc7Vt/s6tbyNnRvRCh9ZeHm2soY/VPlzqSnY+NU9WhLCgU9gMGU1ZaIkkqCice1RSD5xID/1TzRR730cKwd7XT9J5MMENLUJNks8FNIc5+nfKFO9ohKWvJCIoiIXTkiAlqaOMpN6yRXElQ0skWpThrfbJLINwIcfBAzbDYwkiTTFuFlkPS6TzEY//lTf4nyae5//ae4orzSnazQIXjq9hipSPDCr8mzvvouGNeHf9Glca06zEKgjwF5tPsjxs8AOzn+Go0+W9f/BD6JrEfc8Bwxt1Ji5Cfj0gKlscPJah+YrR2DovqZ1qM+v43KnOA5L8msBvqNcvsyRJPsOaGGMJiNdy5DZVe7p9UiMO/1J0/3PPL/zkz/NgtXD313+2WP1U6wQ/Urt199cfHtSIUp1xavNgZYOPvP4wH92+gFMKWay3uNVr0Bp6/MCZzxNmJr9x8AjD2KbkBthGQiYFaaah6aodyTXGVN0xe1GRS9pRgsxkZVS7OwH8YP0in+6fpWqOuDOqc+X6PNVLOnYvY/9hENMBOuBPKnEVK0NoIDMwnJhGbsjtQYNHjqyRSUE3crm91SALDPSBjhar1iydC3C9kJf3jzCOTB6c2eTixgKGLyitJNitgOb5PFJT4/7RjNq4BzhV3qOg+bzpz/HmYIZxYuEnJp2xi9FRUSxLS3t8eWeeRmHIt81dpKj5tNI8n1p/G72ux9xUh3Y3T1ZImJ3o4poKsqpJwe3X5xCTIUaCorKsWqS2ypjSYkG85CO6lmp5cwlyoKMlakw+c2GHtTsT5FYM8lsZUR46T0RoZoamZWRSIDOB48SUPZ/nVk5wtN7mTqvGaDeH2dfV6zufULhpUH9dsvewpLgM1jBjMG+rVvDQrW4OJd6uijzWImWUzG2H9E8WGE9ojGcOCcd6Ri03pjnMEYUG0lJFKfEUZFaLVauZGSqJYTirU1iTePspzr5PZhukrs5oqYRIJGFFEapzK4eaV1ki7u3zXScu0Utc/ubn/xZaSw0Tjsw3+fLKAluNEk9P38QxEjZ7JX52/V14+ZDvPP8SXxqd4PdunOOhI+v8h5138PoLJ6CYIidDpnID9mtFtNhEGhoH5w3M+hDrYp7CRkb3uEZzucqBJXEWh4Q7HuNphZ4z+2pCGBdVsq3uC+z+4a5lI8FI/3sK+1/0eUsXrON/Yvr3Z8+nff1usXojCvjJrWd582AKKQV74wI7+2XsXKSiQ2KdYWRzrrrN/EybX155DIBu32OqqlD0X1e7gSNi/uPK24n2PLAyyp5P0QooG2NsLeb6aIogNXHShLo55Jf23gZAK8hx+9Y0jS/pii58TiCFRFtzSfIZwlbLp6QC/Y6Dd1+XshuwN8zznuPXudSa5XR5n/WwgqZJ9KahKDeBYuix4TCoGwSFiPlGhxdXj1L+jEt+O8Fd75FUPFJL7chZPZPwpI/jRQgB31V/gUCarIzrZFJwNNdi2y+xfH0Ge6xuHHfWJ5ifbfF9C5/nrxc6xDLlf9k+Sbedo1IbEmcax6f3kVLQHHu0h57S1IY2WgZZy8KfTXB2DYLJFK0SkXUskGoH0OwrKIPRtjGHgrAiOfLIJmFiIEINu6MymDoPxZh2gtAkQkhydsyZ+h7TTg9Xj5lbaPNTz7+P/C2T0iFjsP5GiN8w6ZyCra8HowdOT3H6UluZjs0RCjFmgNvMSGxxOLULifMGoxlNAUM0QEjGq0WGBQ/dSzCve+RaHP6ZstiQqGTS/IZPWLWpvz5CCxLEKCCeLJLaGsYwJnFtNp5V0TcizQjnEoq1Ed8wf4ODKM9Hb9+PY8UszLRYp8bS3AH9wEEODZKqzreWXuH5/WN0Wkq3DW6W+Jh+L3Gqw7bDy/FRrDUbtydIhgb+UsZyuwYdC/cgwhiEGL5DvJbDbX4lG0xSXBWMZnSy9QJmTrWC5hC0WGINQIvUDTisZ2SmJHMlupdQKY3Y75v/Pz7x/9/nLV2wfn1Q5fsKXw29fzmM+eL4BABlfczP+AW+sfAGu0mZdugRRQZhz6F+dMSDi+vsjwsU7YD/7cjvcsRIaWcZy3GFL+SOc3NnAsNMMfWU+4rb6GT862tPEywXMWKo3t/i/toWDWuAo8UMU4f1YYVBaHN7t8GL4RIy1Ljn1Ca31ybJrRqMpyB1IS4nGH0VBSNSgazGeIehffL4GNtIGUUmk/kh7chDAJ+7cxzbjhFraglVSyCzFZihODOgZKSEic6d9QkKV6zDKN+UpOIR1C2ikrIZRLWE77jvFf5w8wxJqrGblPlU9x5udCeoumMud2bY7RaRmiSYiyATuMWAf3zs47zHi2mmI/7m8rdyZWWGYmXMXKmHo8dsDMqEsUEYG2qdZTuP01Khb+JwV88IIDgsNlKTCCkQHYuolmIdqFYmrKhww/1BnvH1MuVVGE+pBFG7GFLO+/THDoaR8sj0Gq4ec60/hSYke24RbaQyoEp3QuKCQeeUpUCjpYzSFUWu2Xp3htnRsNvKohDnVdqF28zI7UREJQOpqdtr8z4Lf1LitNTNi7Z5uA4lmG90aH7ZI6ygipUOzoFyt0tN0DvuUb4xQuuNkZ5NUi+AUECNrXfkGC/GGG0dqy/gQo8PHb/EnNUmp4W00jx/o/Elfr35GG82p3ni5DJRppMzI1iAvB3yTX/0d8ndMfEOb4nmCJL9GmFNYoaCWNoqfsiHwT0RbjEg8C20ekjnpEPjYsjUl0bog5CDRyv0ToHZFwRVpeNVn9hlv13Eec1DGjCuC8KJBOElWG4MkYG+4pAWUgp5nzA2KJb8v9gi8GfOW7pgfVuhzaEpBoCcSPjB8jL/dP8BPrz1CL9wz4cxkfzsxrsZRDYPzW1w9GQLR4t5czCDH5v865O/wf22TSxTttOIS/5RJp0BV+Npcl6IrSd85OYFgraD1TRIqympIfn+pc8TZCabURVPhNwcTtMZu+TtCMeNmJxo8/UT1/nPVx+ncEXpNUFNEtUUNVhLv8LOkzx4bI3X1ueZWmiTZhphbOAHJmdq+9xoT+BHJmy50PHIdUFkkqCmzHv/6+N/xGdbJ3nj5WOYR0bkbljktzKcZgwChnMOvWMa/nQKGiyd3OVed5PblQaWlvCftt5OJ3ApWiE1e8Rys0YUGOCoaVdlYsDfOv5F3uMpbeL7V7+RK8uz2JsWp06scn9xk9f6c/RGLn7TUy5zITFCQf6xAzpv1hV4oSkYLGaYlRDdyJC+htnXCBspItTQI0FqSeJ6ApHO+EYZuysYz0jCyZjGXJc40QljgyTWkVKw45fYHRYY+ja2mbA/ylO6oWJjmvc5mEPlEHf3VasnUknz0RQRaYhYFVI4TKsVypsFYPZTworB9hMumamYjVKDTFfTSWlmXDi9wpXdaXQDgqlUka17GnYvI3EE9iAjf7kLm7uIehXR7JEu1Oked+idULn7ZssgtVUekD+yuTWa4BOb9/DIxDpFw+el3iIA7527xivtBWa9Hk9UlmlMDXihf4LmrVlSS9GeRSYIQ4X9ym3ohBWJ3VFpvL1TGTMzbXpjF9uJGbU8+ksg9SL118ZEkzm15hZJpVMZ6t88DGzSA4dMh9GRFPIqigkgGlsIQxGg9L5B18qhGRlJ52tbMsp7jWQAACAASURBVN7SBetPnlRmrCYVvuvyB1gst/k/zv4mOZHwjzbfT9v3eHJqmb2wQCYFK+M6GpJHJ9W+3M14RDez2Ign2QrLvLI7j+3G9Hoew2sV0pzSltKjATk34nityd8s7vNznSOs+xWirEHVGnO2vkczyHGidMAH6xf5g9595D6bQxownFfRtN66QVySRNVURQjrkktr8yxNN9ntF0gSnaBnI6yML95ewjBTpdWYSmCOyjCeS6nOd3nX1Bof372Pm7dmEBMRQctlaj1DZDCeMhWs01W3MZEKpCaV7iJ13lm5wcf3z9ELHWruGE1IXt5aYNxzMfdM5GwIEh6Y2OKZ3DWuRDr/aO2vcuXFJXIdwehIQpQafPbgJHd26go5VojJQh2tb+Cd6qJrGakjMQdK/5FOitzwsDcFTqYKduJqOG2Va5W6Em2kI8sxzskecaxjmil6JugNXZ46usztfh1NUxrita0pslQwP9mh7g55bWOO7N4MMrC66vXK7SlvU1jS8CcFWBnE+uHPPrQ11DLcPQ27p1rPuKATlBUB2mirUX5UkHByBIHBA4sbTDkDXm0vwlIMZkbpVRu7mxFUNcrLMblrBwBIy0S2O4QXjtM6ays4yoqi6PhTEquvkbgSLx/yxVtLlCsjNsdlrm6fJu7ZTB1p0Y9c5nNdMin45duP0VsrIU1J9akm7Z2S0v8GBmIqQHZstAjcfeXOD8sCaWdsb1eVl69togtU9HNPoAUJwwX37i4uqBuikDBaLoEpGR+LMFomaR5MOyHedyne1IlK4C/E6kMq1MkCHYyvrQ/rLV2wQhnznO9S0AKW4wY/v/Iunp2/xkO5FXQyfqXzOK4e83+e+XU+2T9PbOmMM4uyOeZ7Jl7hIC3yS+23cZ+3Sc0YshbV2Q8LSFQO1Ha3yHhCwy0GyjBpRzzaWOVnpi7dXeWp2SPeXb3K870TbA7L3FvZ4T3ly/xR7x7+4BMPo9UFQSMDQyIy5a9KcxnaWEOkgszOKE0MuLNTx/UiZio9VoMauUJA1fPJpGCvW0Bvqjym8VzKzFKTNNP41PIpTDNl6fguppay8sICURGFJVfhlnTuyTAaAUIKZKwRxQbjzOa3ti+wvl+lXhkwjGy2mmWEloGQNB7YY69dpJj3OZ3f4bnxca6OZ7jTqZJOh1hnRkx6PjcPGvgtF81L8CZHhKGJMCRPPXGFkumzOS7THkwQFyXpRITomdhtBXCVusK5l25B5z6FpbLbCj5hOjGWkZAkOpaRoGsqQeLVvTnSTCOTgmHHQ7dVtPXGXoWDqzPUn9xnP9Ew12zcfQWNiL2v4OnVTUZvmegB2F3VBo7mMrwtjcJmht1Wt8jMFMQFgdRVu2j2JaN7QjwzZbqiIpw3x2XMUghS4L6YIzPUrl9hI8O702V0uqHC7RyLvbfXGE8JCuuS3J6aHIq8htgWyojqCZJUo1Yb0lqp0KWMMdAQhYxhYPP09E1MkVLQA+r2kG+671VKWshv9x/EXozxtIiyPmYtrPMfX3kSc6gRlQVhSTC6L4BYU3udY53UzdBqIcd/AfRegL9QIHEE/UW1WqP74jArTJIWU9yKj992yUxJvuQzGjjkV/W7tOfcskqPjSopWi3CSr+GFFXe4sbRn3z5HXzvzK27eU3fc+07GQQ2Fc9nJtfjFxY+wVqi8+8O3kmUGVxrTzIMbE7W95lyB1zcWyBvh/R8h4VSlwzBWqfCcOAwP9khb4VoQnIwzvHcuY9gCyUobiZD3vXCD5JJQbU0wjES/vGxj3Of1eE/dB7hIzcvkN7OH+7SqdUREWpKWLdTipXx3UVj14yJU6VN3FyZUqZMUyoacikiGxvqE3RoUDvWppEb0vY9RqHFkUqH5YM6rh0xHDnEIxOzaSJiiBop73/oEv9g4rN8uPcAF7tHuLQ6j6ZL0o4NGYiyis+x7YRaboypq93GnUGB+xvb/O2Jz7GVVPhU9x4+v3aceC1HVo/RzIx0ZHDk6IEyIyYGmpA4RsxOv0i/lVOBeppyus8vHrDdKqGvuJh9oXbsfKVNBefGpH0LrzFCCNC0r07gHplep24Peb0zy43lGYy2QWZLSjcE5ggV4leG4EiIZmawb+Pua+g+6JGkuJ4wmjAUEKIsiHNKPO7dkyASweQXlbiu+xlxQWf3MZi9Z49z1W2+sLWEBPwbZcyBQnS5+2oilh3xKRXGtLfKGH0dZ19QXFPxLlFBYPekIj5HktQWeNsBUhMqHG9fRWO3H6wSVDWsniQqCiZeOdSSHqvQP6ZasvJyysH9Gkcf3+BE8QBXj/jYxx7HPYDgHQNC30S0LbJCQqE2IvAtskxDbDrKma9BNPknEknnB4zaLpVXTAwfrFHGwf0acTFDOso35m4YiK+gyRZVZpgWKVc8qIw5aakPNjMXI9c80nwG+QTLiwiX9b9MHP3zziPuMr81PM5OVOa5/RMslZq41Zh7c9t8a+EKIwkf7T2KrSW8sLnEqOdwfGGfmj3mUnOWJNUwtIyHp9ZpWEMcLaZsjTGnMk7m9tBExqu9I/za2Y9ii6866N9/6Xs5PbOHn5hstss4xSGX/KP88JvfynhsI9Zc9EAQTCZoYzUZTAspufqYkufTcEccyx+olZ1hnaVKk4sHC8zOtRlHJhXPp2T5XLp1BBKBNtZpnGzyDXNvsmgf8Nt7D7KRVSiaATOVHoPQJk00rD211xUcD/nbDz7Pj9VvAHk+UHidDy8/RDYwyewMTPXm1DRwnJiFcpftfpFabkySKU2wbg/56c1nlHl0r4K+a5OWEwRQyPt0e0XGsUk4dgGoeD43lmfQ+zoUUzQ3wb3sIh7rsrlXgb6pQhR05SjvLx4W84GpcpriPEY9UDlTqc4zR67xWmeOz1w5DZpEcxKsrknjtYS4oDOc1RjcH/DI8VVeur6EseLg7Qq0WBJWFOXZakc4u2MOHioqmvIY+idSJl7Q0WOVMxWUNKIjOqO5jKPntnmots7ndo6jCUlvrURxU+HeU0fphsVlSLY9UuFR1L+SFCIZLOiIRMUSi0y1mlFe3Yr7Sy5aAuU32khNI5hTyZ+53YydJyVaLSQq5xCJyp3KbajA3IMHNOoX9rCNhE/dPs3Mr1oY58B89oCSGbOTFckmMmSilpzLxTHHy00ubp7GaQmGRzLEWCdzM4y+TnK5hJMBqGK6f0FT9CYz4/75TV69vkhYy8htacT5QyiwA2kuI8tAr4U4VkIUGWSJRpZpGEtD0gMPGegY1wuUr45Y/wuvBF89b+mC9c9WP0ClLHljc5ZqaUQ7zPF35z7DM17IOLP49cECusj4+NX7EJrEzkW8o3GLL3fn2d0t4xUDSpbPlN2nE3sMhc3euEjJ9qkbA5aDCb5n8gscM/Nci8b0Mpuf3nyGByc3ubg7z2jgKJev4fJfN85T8XxGt0tkjiRbCLBNFctbKo9YKHU5W9whRWM/LPBqawFbTzgY5Wj5HvdWd3mmcplRZnF5PM/v37oPYWSInkHxWJd/cvLjfLJznuebx1htVjk9uc/aoELF8RnHJkKXTF5MaZ0xOLmwe1is1DljeUwXBozLNjO1HtutEunAJA11BoMCV5o5CvUROSMiynTeNr3CH2+eJEoMBYLIBOlkSL4YEIYGvc0SmBlD31ZI+USn3/HQnAS9GJIFBvZ1l2AiI1sv4uxrWANIHRWfEtQEUTVFG2uYA/VQSyvjyESbhjMkkRoroxorezXK9SHdnSLWqs3EpRhzEHNwv4m80EcEJi+/egJzpOHuC7z9lN0nFKFZpBr9Yy6pqVzuegj+hMRu64ynIbUEwXSKFkikkDhHBnTGLr/bOkfODRm/WUE3oPdABKGmRHld0LqgxvwISf0lg8FR9RpPvRhj9mMyS2c0bRKWNFJbaUK1qyHGIEJqGntvryjgakdy8ETK+y+8xnObx8nfctASBavoH9XwZ1KMocbutQm6CwOMN3OsfUtEsdbBj0yazQJCl5SKY4SQZJnG6ara2shtqgFHZmdKs0vVDSmqp+TWdNxWxv4FTRlv2xZPPn6FnXFRkaa8jDinoYdK40sLKXpB5eUngaHywUDJDoeJuFKXGF1dedHcr60X6y1dsHb7RTaGedW27ZX49kcv8oynemhdCD7dPsONduMu7MAyEq4OprnZnGBp/oDO2OVWq8HJ/D7NMM/ruzMU3JBvmLrMUesAR4s5bXWAPH88OsN/WX+Ic7Vtni5f5YX1RWSqIX2d0DIY7uTJrRtkcynezJCy57O1WcUuhvihxdXtKa5uT3FubgtHTzhb2eVSc5b+wOMfPPiHrAZ1Pts7w36YZ2NQJt530aoR7mIfz474aPNhPv/Fe9BDQVxLuBzOMD/ZoeV7dAYe2rqLX1XemNOlvT/1On3a17m1MYkwMpqDHGnXUsPVGOyqT84Ncc2Ea7uT3DO9Q5gZhLGpRPNUQ0pw8xFpqhG3HbRIIDWB33PuPrwz0x08M2Z5YwJ7ReHmG2cP6L40id1VDnUpBIMjIJCYPUUBigsZmZeBBrfXJ1ix6tQrA/Z2ywgjI/lClXpbInVJnNfYu+DhzyaYtws4fYF7oEASiaNyzEUCVk8VivGkhjmQVK+NMHyXcaDTPR+TWzbVhNZJST2JV1SgEn/gIPSM/noV8+SQNNYxNlzl0ZoOsGoJup7RKAxZ264R1Ezy6xLvICW1NYanXfRITR1TW9kXiqsJnRMWWmLROaumloUVyeAoPH7vbUyREscGlRc2wTToXpjEn0lVjr/hovka8a0isig5s7SNJiQ3dxvQMxWWrGnfvTW/FBwl2fZwc0o0F56a9OauW4xnMvShRm47YzCvI6RERIJ4KqZgBFwPJ9DsFGPbRI9UXHRmSZyaT94NaTULOAWV7ArQ7uTgTo5oMiY/OSSu6qS386QWX9Pzli5YE4UB33jsy/RSlwmzzw+WN+7+2aVQY9rp0fJyVD2fvUEeXct4qnKTv9r4Mh/ZfYTtTonvO/sF3und4DtXv5tx12WiOOSvFa/yX/r3kEkNzVUP/GpQY7HY5t7cNv/w5W8GwLAT5ucOWN+v4u4YjGdSJpZauGbMxkEFMxcThwaGlRIPLYSVEmUGnhGxPqqgCcm5+U1+bf1R8lbIOLbojF1GyyVMX5BGNvmzff76/Kv8ysqjd1l42lhHy8ccDHIIAeYrBWqXY9pnTJzFPh+svMxrYcz9ts1OMuQnVr4dw07I51Q+eZBXgsS7T19jyu6zMq4xTixMPcXQMt5sT2PqKf2+SxbpzMy2yaSgP3bAlGSa4ilmvoEY60gzozd26eGi71mEEym1Q25jXMjQA43UEUpr6plkTkZxShGEklSje6Dw8GKoPFwHBzbWQJDbVmbOsKIgIyNTVwTqlvJsIVUmWmIrgTyoKnSWFiu3uNkXWEPJwQM5hguQLfiIWN0eRkeSu/n1ne0S+ckhlp0QhQa5kx0yKQj3PWQ1wauO0fVM3WIae3RCD3PTxuqr22J/SUePBN6OQs45nYzRhE5cFDTPGURFSfEOVK4JYk8wXJCkUxGvbMzz5NGYoOswuneaoKrTX9T4hscuUjQCXqoeZXmzgVUIefboVermkF++8SjZRg57JIhKh8OK5iFU42SKs68RlRWr0rtmI1LFN8i8jExIBgsqzsbdE4xmJY3JHi/sLNI+KJK7YanvU5XKblGKMc2ETi+HDDWCwCWMPbVvWUjJGgnCzDC0DH+9yORrEvpfW8zXW7pg/fTS73BPWWcjyfjM+NTd3/+F7jxf6JygE3jYRsLVzWn+n/buLMjOs87v+Pfdl7P36X1Rq1uW5LYkS7Yly7aw0QA2MGaZAgqyUDNhKJipFKQmwGSSqqSSSuUmmdRMUpNkkkkmJCGEASZQTHDAGAwY29iWhfbNUi9S73327d2XXDwKcxNSuQl2V72fS93oVEv9q/d9zvP//e2cx+Pji8TINKM8dTfPFw4/R4zMr1/4G/R3ciwcWOd3Zp5jNdJ4pT3PYmuYb6jHKBqe2DyjRvzRxdOkscTkWBs/Url9YRIScefo9Ogqa06ZG1ujyFJK6Knkyy4fmr/AHXeIMFHYazfYYzRYDyrYcoCT6PzP7iHKposXqXRreXRXIhiJ+ODxc/xm9UWWwmH6Z4aRIpBTicSK+PihM7RCm+9+/ziVrRTVi+kfi/nw3qtc8maIkRlSrrEVG5ysrrBaq6DIKTPFFm9EKp+590cMqX3O9Ocpay6XdiYpWR7X66OYWoRtBLiGhl7w6DiWaK0wfczxDu12ToSVHqNtqQTjKXEs4zUsKIhB6Pp2ERIJNZRwpmJSO4ZI5iNvfwWFhOu9MW41h3EcA9mIoWaQvyMaOiNTPCGlsqi+jnXRbrB9OkJSU+irotEiFh3+AIor1mD5Q2KtvN4WZzhRXoR8POMhbRkU1mR68zFqKaBku2zVSszM1dhqFYgaFqmS0t20SKwEY8Th2NS6mB/tFvETmXO3Z0j6GvZAQu8ltA+m6G0ZeytF8cWrZmtBFZ/HEYt+S0spgwmxJ9DZ76PoCfKGyYOPLePGGtZtjc5vN3l8apF3lK5hSz4/6i2QpBJjo2JN2yP5Rf7Oax8m6WvoHmjHWuiA4xgktyz0toTxqoW9k1A/KqEOxIKS2AK/koARoxoxka1SvRKz9k6J2YUtvEilfmsEsyWT2xABHJsJ2phLWLfod0qkWoK1of784N0dTUQPV18mGknp3Clh9GX8QorZzIaff6G8HLMUKbzi3sNOWOTPehVqUZF6lOdabQxFTmjVCuQqLodHtthr1nnIXKGR5Hh68jLn+rOcrU/zjpmbnD50nb1qg2k14rdXPgjAqYklVvpV9uSavNEdpaw7/PqhV9kJCjy7uEDoaqRDIffs2aEf6Hzn0mFIEI/Wuuhjn620+PadQ8yVmzxWWWJY7aJLMVO5JrWoyDe2H0SSUgahTqsnWlHlg33eP3edfzHxOq044e8uP4F6rM1spcXf2/MMp0wZJwl4//WPkF8BezvEHdG5f3aZv155hWOGwWt+yHl/lHZs89y66MnqSCkjOY1T00u83b5JgkSSk/na9nEODu/Q9i3KlkRzYOP0DYarPQaejtMRB+vlvCigS1OJ2dkaq5fHSQxYuGed1XYZtRiQJBK9Wh7Jk0n1u5W9WsrIeIf/cOhLKKQ8P7iX8/E0hhrTj2RxvtgUr4iJKkZA5PhuFa8nbpW3D0gc3b/KhZsz4opICkYTFE/M7iWauIKgt0VFjHW8gR2pOGoetSeTPyvWr7ujKRREHU97YJFEMuvXxkjMBKUcEHc15Ehi7/4t4kTmZnOYVisPHQ2tLZOMRegVDze0KN+E6edTwhy4IyKQUhXyd8TSCL8sYdZTNk8nYnd9LCFJEPsK0kjAazfnkJoaZgznTvwZzzgmz3UOc6k1yRMjtzhU3uSnW3M8Or7MK/19yGsmZkdi9qkV3EgjjBX2V2ucZxrfVRl5QUPvROhtHX8oxRtJkAPRlCs3NSJbQZNhMK4gD7us1iqwYWLXZKxaSm9Wwp0L0OyQsG5RuqrglyFVZLGQNpcSTfkUzpm4oynprIvUNEitGH8IcmuyGE16E72lA8tPJb7ceIzbzhDvG7nIVlSiFeV4pT6HH6iMl3v8oyf+B4f0HWIknETFS1Wq8oC84uHGGn948Gss6AG9JMZP4Xaks+MUODmywon8Ep8d/hFf7TxEVFC42hrncm2Cbs/m7ftuUvPzTFgdrrXGqV0eRY0hGgnJFTyCQCVN4cqNaU4fvc7J4hKPWEtsxUVkEpaCUV7tiqZ/U42o93PIcopR8rCMgP3WDud9n1fc/Xxg7ALhqMpnK7cBEVafvvMUq69PMbYtergHkxL/cOr5n3fUt2ObsuLw5/XjuIGG2lT5laOXqXl5rrXGWZgW4XjWU5jLNbjRG2OjW6RXzyFpCbOTDYJYoZJzUZUE19VpdHLkrIBfXbjCQm6Df3n2fYSVmPVOCadvIG+aJEMhWj4gN+rT7VlIbRXJivjnC1+nl+h8pfEo1zpjNAc27Z0CRsnDr1v4wwn2mnhdkyPQe6Kqxa1KtI7GvOuBK7y6uUdc+9ATijcVVC/BGb87h+jdnRyQwZsJ2V/qcHV9HKUnk1sVyxpaC+LAfHS0g67E1Hs5pIEqBs+BpK2DlKLv67In3+L1zRmc20W0gYTekegv+Dyw7w5RqnCpN01uPaR5n41XFVc19IEYqg4KMt15kNIUbzRlbE+TZieH9UoOJVAYTMPkwxt8bOp1NsMyU3qLz6yf5Jlz94sD8kJI1zOJYhlNjdlv7XCmOwtAcMRhs1tk4Bggpey080iAuaoTWSlBScWv3N0aJaUkOUQRoQQz8zU2Lo6LwexIRtVi4rszkM6Y6LmSuyphCmgJ7UMpUiSRWgmEEnpTrG/zHulzYKzGrZ1hklBc1yCVRHdYFli/2B9uvZOeVuG+4iYbQYVWZNONTBIkPrHwCr9XvclfDGy+2nmIWaPOuNpGIeVn7l4mtRafG3+OHzkHeCNw6SUWmhTz/cYCo3aP3x8/xytezGeXPsqY1cOPVW6vDiN5Cr//5FcIU4X/svEoZ7b20OnaJKUI2Y7Q784fxooMoczJw4tsuwWej+7lsjGNIYdc6Uxwa3OU2FExyx5xLImw0iP8QOU9M9fuhpPBsburv/w0BMQ9sL+2+H4uLM5Q3JZwRmXcYYlg6O7t78BhIy5QVQYshiOMGT18T+PE266z1BtmcW2E33zgZf5J/V4AvETj5Z05tndKpK6KnA8plwaM2aLne61XpmR5+IGKoiS8ffoWbqzxpZWTYo0W0K3lMTZVcbYxGfOpIy8yr9f4Zv1BzllTPDS5yp83T9AMctTcPDu9PIO1AnpbJrJV1L5CYVkseJAjUcPrjOm098n4Cy5PH7xKTvXpdy2QIX9VBznFHZXFWA0Q2iK0nIkE1IQ3fjRPcSvF6KS4VYnGwxGoCSf2r3CrOUy9nSfua0jFkNQV7aaplohvAwOV89tThJdK5DriYH8wCYohFoKcmlxm+cY8qRzhjkionnj9iw1oHVTQeuJ6Q+HBBo6v0bw4Qn5F/FlsQu5Iky/MPcsFZ5YPFM8xJAc8ZK5w/+OrfLd2CFlKubI1AYh7aV9aeRg/VCkfblCvFWg7eSQtIR2o4mnTk8k1wGok1I/KKPv7FEyf3sAkvZ3D3pDoH3cx1AimXIJNG33ZFKvuW+Lf0KqnNB4JkQYKSktcfzHqCpGdYqyLuVd3PMG8kEPrw80xUTwg73ORNk2KNyWGbniESfT/+9f+/+otHVgvXD+AbJp86G1nqUdFfrB2gCdnbvDesSu82NzHx3tT/ErlOsNaj2ebhzDkmKeHLrDul/mTq6eoFByqlsMg1CnpHtN2m7858UO+1nyYd197H1VzwAfGLvB8817Or06LFk0ropeYfGP7QW43KzgdC2tJF7e5fZlQAmcs5Z8e++88aOzwrf4C39k5zJ1uhVvRMJ2ODRLMT9TZk2uRU32+e2uBct7lw3vO8btDiwCc9QM0KeEeVcaWdQxJI0xjzvoQpTLFSzqxLpYCSCmUDjS57M3w1FBIOerwX7tHuc9c51PVF3nnw1d5dbCPhpfDLvisehXuz6/xk9Z+Xr+9hzQRZyVF3afjm/ihypTZph2K5oUgUDk2s4atBnzn1n2ENQtzWyGxUtASMYpzrMk7p0Ur67+/fIp4QzzBFfe1uVIXLRlBpDLYzmHfUdFyKVEhpfSiidkUN99DW6I/IxPbMvG0x8m5FfqRwbM3F0hiieLrpnj9etAhUBKKOY9urYAki9dG1YiIOwbGqk5hJaX9pMv83c/9G6Mv8c3mca51xjC0iELOI7Z9erU8el1Fb4mfY2xAUFbpY2N2JdyRlMEDHmkkQ9Ogt27x0veGGNwbs/CxK6x9+wSDoZTgsT6TlQ7d16fQ+mL20H1xmOLthMe+8CpVbcB/vnaSoGVi+jp/sPIUmhzTjw0+XH6dhwydlbDPXE70iBVmfDadopheGIlRuwrdgphZTPW7dURGgrWkY7TEYtfBoz7DlR5by1Wk9QLDiwmxDs4YqCsmt9xx1JaKNkgpL8VEhszmkyEjEx1q62X0TTGJkOgQ2TJhISUeCokqErkRh3SgEzkmsSkWFyeliOIZm9EzDvpGm8Q2Qc8O3X+xUOavnnqNZX+UL10+SbHg8NOdOZJUYrrQ5r3VS/Rik2PmHZRygimH/O0X/gqEMmN7muw0ingFDVlO6PsGTc/m9dqH2NkpoRoRK/IQP718j9gYnEroZsjx6VX+9a3TDFkOSSKTv66LDdSpuEs0s7fO7+37Dk/bHn/aEWdrC8Ut7ErA9zcP0goVFuY2eLCyypjWxUl0vv3oH3NAy9FJXMCiHg9YCSfoJSY/ji0+UrjChJrnm4MhNsIKV25OU/ZBccW6KfnBDmP5Pp8bWuJPOpM4ic595jorwQhf3n6UR8tLfG/zXnYujHH69EWeKl/hojtDzc2Ts310NaZiuuhyzJjd5TPjP+CT53+DftPGKPjcP73OycoyP64fYKg4gOKA7XwZ64aBWddJH29TzTk0gxw/XtyPvGqS35bwhlMGro6mxeK1cqCj18U3fIovifGZToJfFg0Bzv4ASU7RrJC8EXLmJ/cix6DEYDdEeOSPNQj7FsWchyIn4CsQSuSmxZOk2lYwaxLBB1vsLfQ5Ub7NTlDg77/xawSRQhgrDJZK2Jvi9dMqisN6KRJtFooHuTUxtuMNQTQWMDvaYr1eRm7rFBehsz9lz8FtklRGPdpmX6VFXvN5/eWD5DbFYgdtAKmUsvVEgiylXO1PEK3bqKGEl1hsSineQKfh5Nhn7vDF+ixL/Sod3xTd+KlEZ62EEUmoXYXKVWgeFqNdsiOT5EQ1T2ynOCak9ziMVnrYWojeUAhLKdtP+xjXLfQeFFag8JJYuNqZU1l9CvLLMqWLOr07I8hlsSjWr4idh8qIh7RmoVoRSSzh3i5gb4hu++6RsDcfGwAACNdJREFUAElPUHZ0rJ0EreWSFG2IEpRm/81MhLd2YO2Z2+FMc5ZbS+NInswHD7/Khl9CkxKW+lW+unWCz01/j/PeHi4PpgEYn2zR7tt0BhYL01t0fZO2a9LbzpMbcfjwvvO8bMyz3iqJ9gHgxPxtTpUXueZMcLU1Tn2riDKZwOUCqSQWdkalmAcWVvj89LOcMmX8NMSUQwwpwtYC/tvicUqWh2aFJKlEQfH4dPkWn1h5irziYeavMUhkvuUN81L3UaJEoaB5VFSHP6g/Tj3I48Yar96Yx1wX94ikRNxq//y9L/CItch/6k7jJxpHzFV+2LuPYa3H08MX+VdLp2lcGCUeDxgzuoSpwoX2NNvdAmPFHu8Zv4IpRfRik4Li8cfb7yBNJe7Zu83J6grTepOvbzyEd3cEp+cZyHUNvQu9+YSKFjFhd3j+/H1Y6+IbslSCYDykYvtIUoofaiSeihyKJxki0DspkSHRuj/h+NFb/Me9z/CsM8oXN07xxuYo2kC0DZiNlP40hLM+zVoRzQ7YX6lx5vYsSCn21ODnG6tLt6B12uVgqUNZd/nTK48S+Sr5kouhxvQ2CxTWxXzhYDJF9cRN9qiQoLVlzJoEqagB9iYjKtU+LcfCOivWlrmjEBVi/FjhjlPhkwde5t9dfZz0aoHipmiqcD7U4eDwDmu9MnKjwE+29tG4PCJ6pvakqOWAvOXzO4eeB2DRG+Un6/NYesh4rsfYUJel3jBttYBZU1DvQFCQMOsSQVl8VslIsAoeYadIstejUnDxQpX2wEI62Od3j/yAr64fp3Z+mpELLooTERZ1Vt+lMXlkk0GjRH8OrE0V+WiHdGAQprro9VJTpNsWZk3CvmCiOSmQ0jootk/rmxphJcFoyAydqyO1uqTdHslgQJRmjaO/kK2FLNdGUXMhTxy5RTcyiRKFTmyxN9/kk8MvcNbbyzc3H0CSUm4sT0AgI1kxqS9zzRtH0WLCrsHwVIdfnbnC/dYqa7kK9X6Ow4cXmbWbPFm8zA1/kguNSbbqJSRN9HlHIzGkQDHk6fuu8PnRHzCn5XGSgLU4RJMintk4xMbyMFrFo98zSfoaN+NRDpU2+dit9yFLCV9fe4ifFWe5WJ+k2crxiaM/xUs0wlThZG6RbmLyQudeLuxMUq726fTKkMqEB1yOzaxxx69SDwvMGnUet9/g2f5hNCnGiQ2e7e6hM7AoH6nzjw/+Be+xff6oNUsnMDk2vs5eu8Ftdxg/UXFjjav1MTodG0UTM4KvNvbyQnQPbdckihSC5QJ6V0KTxTIIe18HRU54eWkf+Vsqek98rd3fA3o+4EC1RjcwubY0idZQSdUUAonCakKsSzjjEr/1xPPM6nXedfHjuIFGdydP6bKG3kmR45T+lIwzHyIBR/at8Xj1Jv/mpXcgOwqUQyQpxRmYsGmQ/+gmo1rA8t2aHFlJyRU9PE+jv1NEdWXR8DottgV5juiSNzfF1mdnUlyLkFJASbH0kGYvhyqJbyQH0zB9YIcPTZ/j48UrfHr51/DaJrqaEpQl5t+7xKmhRb628gDdq1XRdnDOYuxOzPpTCWbFI2/5HKjU+MraCW5vVEkHKkMzbXaWq+wUiijqBHHDYOJFCSWIcYfENIA7nqA3ZQpLMqqro4Qa3VmJwZiM42s4TRtCifG5Bv/25uOk360y+VqX2FSp35+nc1A0qXa+M0F8MMJaV4mtlHi5gDrlQiCJJ01Dwt6QsBoJiSLhVST8iljU4U1EyLkQZd2ktJwg9RzScoFku4ZsmnDffjj7rTctE96SgfW/57FvLBXBlUjtCGuqw9XmCJu9AoeqW/xW6TnigcTFRpV2O2XnxghqP+Zt7zpHTgk4U9+DG+h01gtgugxJDWRnwHOtedYGBrHj4xshHy39hMVulZWBzfqyhaKJx4dg0yDVXCQ75sTECn/Lfo6ql6frJThJwj9Ye5KNQZFhs862oeJvGVQnm7xtdpEXNvfxzNV53ja9hK0EnL9zmG1znIcnlnlw7Dal0GFSbfOIJUMMX+7l+NlqlSOlJUaNHq9Le1hKxqGVcJ0iyojD/cUWk2wQhiGtroQTy9zsj+OEGmo44JN7f8hjsUu3B9+7s5dTpctc6U3y450pBoGBJKVEsUzR7LBvbI2LWxM0GxL7q23SwKBzJy8CR/YYVCNkT2FoX5Nps82VjXG0ixJyzyWJoDcHTAyYzzVY2rRpdm0UeviGgdFS0ddTfBkiVcLXUy5uD/HFzaMAhMsm1SsRShAS5O+ukyolpHHAR+Z/xry5wz97+d3QConyLpKf0L2joNchlX30oMeVGxMQg+ymSJ7EQNdRBhJqHJIqKfGcBwNIGgbWdkyixbgVMcpibqmkA+jcF6EpHqnjEXR0EtkjKELaT1H8Ae/mIs0uXF8tkvR90l5MkMKll8a53pmkuJJiDPn0j3qULsj0pzWSQUyoBIznt2m1ZfqDhLnKKp868gLfbDzEz7ZysAWyL2N2Qhoz4v+7lIjRouoLYiLAaMUYNRdk2DlYQJP74MfIGzp6W8J9rUhQlCjdGdCaVtD6MfZyD7mtElli4NtEpnrJRYoTNk/phJGEFLvEFbEeztMknHf38BsW9h0VKQJnJCEdJKirCtVLDuaWR1DUSA1Ijt/DYMqiXwjg7F/+jv6yvSXbGtbW1piZmXmzP0Ymk/kFVldXmZ6e/qX/vW/JwEqShI2NDQqFApL05t77yGQyfylNU3q9HpOTk8jyL38Q+i0ZWJlMJvN/8ubv7clkMpn/R1lgZTKZXSMLrEwms2tkgZXJZHaNLLAymcyukQVWJpPZNbLAymQyu0YWWJlMZtfIAiuTyewaWWBlMpldIwusTCaza2SBlclkdo0ssDKZzK6RBVYmk9k1ssDKZDK7RhZYmUxm18gCK5PJ7BpZYGUymV0jC6xMJrNrZIGVyWR2jSywMpnMrpEFViaT2TWywMpkMrtGFliZTGbXyAIrk8nsGllgZTKZXSMLrEwms2tkgZXJZHaNLLAymcyukQVWJpPZNf4XypI3bGQsnMcAAAAASUVORK5CYII=\n", + "image/png": "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\n", "text/plain": [ "Tile(masked_array(\n", " data=[[1225, 1244, 1247, ..., 1305, 1245, 1206],\n", @@ -129,7 +137,7 @@ " dtype=int16), int16ud32767)" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -147,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -156,7 +164,7 @@ "'Tile(dimensions=[256, 256], cell_type=CellType(int16ud32767, 32767), cells=\\n[[1225 1244 1247 ... 1305 1245 1206]\\n [1166 1188 1190 ... 1381 1251 1193]\\n [1156 1110 1122 ... 1248 1245 1270]\\n ...\\n [1485 1749 1761 ... 1034 996 998]\\n [1780 1777 1663 ... 1008 1027 1174]\\n [1728 1647 1562 ... 1189 1297 1382]])'" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -174,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -199,7 +207,7 @@ " dtype=int16)" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -219,39 +227,43 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", + "\n", "\n", "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
Showing only top 5 rows
proj_raster_pathtilecrsext
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[int16ud32767, (256,256), [1225,1244,1247,1222,1189,1216,1206,1185,1132,1040,...,1575,1489,1281,1189,1202,1145,1171,1189,1297,1382]][+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4455356755667E7, -2342509.0947640934, 1.4573964811098093E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[int16ud32767, (256,256), [1140,1227,1147,1106,1026,994,1047,1020,1174,1348,...,1793,1743,1685,1688,1706,1727,1766,1689,1561,1515]][+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4573964811098093E7, -2342509.0947640934, 1.4692572866529187E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[int16ud32767, (256,256), [1546,1445,1329,1539,1653,1576,1533,1603,1610,1584,...,1399,1434,1330,1429,1470,1451,1422,1407,1369,1310]][+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4692572866529185E7, -2342509.0947640934, 1.4811180921960281E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[int16ud32767, (256,256), [1765,1675,1704,1674,1665,1685,1551,1556,1576,1626,...,1814,1768,1771,1812,1825,1773,1737,1728,1734,1684]][+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.481118092196028E7, -2342509.0947640934, 1.4929788977391373E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[int16ud32767, (256,256), [1171,1272,1306,1294,1202,1065,998,971,976,1188,...,1455,1481,1458,1469,1449,1392,1227,1085,1102,1091]][+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4929788977391373E7, -2342509.0947640934, 1.5048397032822467E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4455356755667E7, -2342509.0947640934, 1.4573964811098093E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4573964811098093E7, -2342509.0947640934, 1.4692572866529187E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4692572866529185E7, -2342509.0947640934, 1.481118092196028E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.481118092196028E7, -2342509.0947640934, 1.4929788977391373E7, -2223901.039333]
https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ][1.4929788977391373E7, -2342509.0947640934, 1.5048397032822467E7, -2223901.039333]
" ], "text/markdown": [ + "\n", + "_Showing only top 5 rows_.\n", + "\n", "| proj_raster_path | tile | crs | ext |\n", "|---|---|---|---|\n", - "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | \\[int16ud32767, (256,256), \\[1225,1244,1247,1222,1189,1216,1206,1185,1132,1040,...,1575,1489,1281,1189,1202,1145,1171,1189,1297,1382]] | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4455356755667E7, -2342509.0947640934, 1.4573964811098093E7, -2223901.039333] |\n", - "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | \\[int16ud32767, (256,256), \\[1140,1227,1147,1106,1026,994,1047,1020,1174,1348,...,1793,1743,1685,1688,1706,1727,1766,1689,1561,1515]] | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4573964811098093E7, -2342509.0947640934, 1.4692572866529187E7, -2223901.039333] |\n", - "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | \\[int16ud32767, (256,256), \\[1546,1445,1329,1539,1653,1576,1533,1603,1610,1584,...,1399,1434,1330,1429,1470,1451,1422,1407,1369,1310]] | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4692572866529185E7, -2342509.0947640934, 1.4811180921960281E7, -2223901.039333] |\n", - "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | \\[int16ud32767, (256,256), \\[1765,1675,1704,1674,1665,1685,1551,1556,1576,1626,...,1814,1768,1771,1812,1825,1773,1737,1728,1734,1684]] | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.481118092196028E7, -2342509.0947640934, 1.4929788977391373E7, -2223901.039333] |\n", - "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | \\[int16ud32767, (256,256), \\[1171,1272,1306,1294,1202,1065,998,971,976,1188,...,1455,1481,1458,1469,1449,1392,1227,1085,1102,1091]] | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4929788977391373E7, -2342509.0947640934, 1.5048397032822467E7, -2223901.039333] |" + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4455356755667E7, -2342509.0947640934, 1.4573964811098093E7, -2223901.039333] |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4573964811098093E7, -2342509.0947640934, 1.4692572866529187E7, -2223901.039333] |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4692572866529185E7, -2342509.0947640934, 1.481118092196028E7, -2223901.039333] |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.481118092196028E7, -2342509.0947640934, 1.4929788977391373E7, -2223901.039333] |\n", + "| https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF | | \\[+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ] | \\[1.4929788977391373E7, -2342509.0947640934, 1.5048397032822467E7, -2223901.039333] |" ], "text/plain": [ "DataFrame[proj_raster_path: string, tile: udt, crs: struct, ext: struct]" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -278,7 +290,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -312,28 +324,28 @@ " \n", " 0\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF\n", - " \n", + " \n", " (+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ,)\n", " (14455356.755667, -2342509.0947640934, 14573964.811098093, -2223901.039333)\n", " \n", " \n", " 1\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF\n", - " \n", + " \n", " (+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ,)\n", " (14573964.811098093, -2342509.0947640934, 14692572.866529187, -2223901.039333)\n", " \n", " \n", " 2\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF\n", - " \n", + " \n", " (+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ,)\n", - " (14692572.866529185, -2342509.0947640934, 14811180.921960281, -2223901.039333)\n", + " (14692572.866529185, -2342509.0947640934, 14811180.92196028, -2223901.039333)\n", " \n", " \n", " 3\n", " https://modis-pds.s3.amazonaws.com/MCD43A4.006/31/11/2017158/MCD43A4.A2017158.h31v11.006.2017171203421_B01.TIF\n", - " \n", + " \n", " (+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs ,)\n", " (14811180.92196028, -2342509.0947640934, 14929788.977391373, -2223901.039333)\n", " \n", @@ -367,7 +379,7 @@ "3 (14811180.92196028, -2342509.0947640934, 14929... " ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -386,7 +398,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { "scrolled": true }, @@ -401,7 +413,7 @@ "Name: 8, dtype: object" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -412,7 +424,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": { "scrolled": true }, @@ -433,7 +445,7 @@ "Name: tile, dtype: object" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -451,186 +463,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
iataairportcitystatecountrylatlongcnt
0ORDChicago O'Hare InternationalChicagoILUSA41.979595-87.90446425129
1ATLWilliam B Hartsfield-Atlanta IntlAtlantaGAUSA33.640444-84.42694421925
2DFWDallas-Fort Worth InternationalDallas-Fort WorthTXUSA32.895951-97.03720020662
3PHXPhoenix Sky Harbor InternationalPhoenixAZUSA33.434167-112.00805617290
4DENDenver IntlDenverCOUSA39.858408-104.66700213781
5IAHGeorge Bush IntercontinentalHoustonTXUSA29.980472-95.33972213223
6SFOSan Francisco InternationalSan FranciscoCAUSA37.619002-122.37484312016
7LAXLos Angeles InternationalLos AngelesCAUSA33.942536-118.40807411797
8MCOOrlando InternationalOrlandoFLUSA28.428889-81.31602810536
9CLTCharlotte/Douglas InternationalCharlotteNCUSA35.214011-80.94312610490
\n", - "
" - ], - "text/plain": [ - " iata airport city state country \\\n", - "0 ORD Chicago O'Hare International Chicago IL USA \n", - "1 ATL William B Hartsfield-Atlanta Intl Atlanta GA USA \n", - "2 DFW Dallas-Fort Worth International Dallas-Fort Worth TX USA \n", - "3 PHX Phoenix Sky Harbor International Phoenix AZ USA \n", - "4 DEN Denver Intl Denver CO USA \n", - "5 IAH George Bush Intercontinental Houston TX USA \n", - "6 SFO San Francisco International San Francisco CA USA \n", - "7 LAX Los Angeles International Los Angeles CA USA \n", - "8 MCO Orlando International Orlando FL USA \n", - "9 CLT Charlotte/Douglas International Charlotte NC USA \n", - "\n", - " lat long cnt \n", - "0 41.979595 -87.904464 25129 \n", - "1 33.640444 -84.426944 21925 \n", - "2 32.895951 -97.037200 20662 \n", - "3 33.434167 -112.008056 17290 \n", - "4 39.858408 -104.667002 13781 \n", - "5 29.980472 -95.339722 13223 \n", - "6 37.619002 -122.374843 12016 \n", - "7 33.942536 -118.408074 11797 \n", - "8 28.428889 -81.316028 10536 \n", - "9 35.214011 -80.943126 10490 " - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import pandas\n", "pandas.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_us_airport_traffic.csv').head(10)" @@ -660,7 +495,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.5" } }, "nbformat": 4, diff --git a/version.sbt b/version.sbt index 8e8a39d95..ca68fcbd5 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.8.3" +version in ThisBuild := "0.8.4"