pax_global_header 0000666 0000000 0000000 00000000064 14635030442 0014513 g ustar 00root root 0000000 0000000 52 comment=030538d0bacb0de81776d90171179e31f29ed825
spopt-0.6.1/ 0000775 0000000 0000000 00000000000 14635030442 0012664 5 ustar 00root root 0000000 0000000 spopt-0.6.1/.gitattributes 0000664 0000000 0000000 00000000041 14635030442 0015552 0 ustar 00root root 0000000 0000000 *.ipynb linguist-language=Python
spopt-0.6.1/.github/ 0000775 0000000 0000000 00000000000 14635030442 0014224 5 ustar 00root root 0000000 0000000 spopt-0.6.1/.github/CONTRIBUTING.md 0000664 0000000 0000000 00000001732 14635030442 0016460 0 ustar 00root root 0000000 0000000 # Contributing Guidelines for `spopt`
Thank you for your interest in contributing! We work primarily on Github. Please review the contributing procedures [here](http://pysal.org/getting_started#for-developers) and [here](https://github.com/pysal/pysal/wiki/GitHub-Standard-Operating-Procedures) so that we can accept your contributions! Alternatively, contact someone in the [development chat channel](https://gitter.im//pysal/pysal).
## Style and format
1. At the time of this writing, Python 3.10, 3.11, and 3.12 are the officially supported versions.
2. This project implements the linting and formatting conventions of [`ruff`](https://docs.astral.sh/ruff/) on all incoming Pull Requests. To ensure a PR is properly linted and formatted prior to creating a Pull Request, [install `pre-commit`](https://pre-commit.com/#installation) in your development environment and then [set up the configuration of pre-commit hooks](https://pre-commit.com/#3-install-the-git-hook-scripts).
spopt-0.6.1/.github/dependabot.yml 0000664 0000000 0000000 00000001164 14635030442 0017056 0 ustar 00root root 0000000 0000000 # To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "jGaboardi"
- "xf37"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "jGaboardi"
- "xf37"
spopt-0.6.1/.github/release.yml 0000664 0000000 0000000 00000000725 14635030442 0016373 0 ustar 00root root 0000000 0000000 changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: Bug Fixes
labels:
- bug
- title: Enhancements
labels:
- enhancement
- title: Regionalization
labels:
- region
- title: Facility Location
labels:
- locate
- title: Transportation & Routing
labels:
- transport
- title: Other Changes
labels:
- "*"
spopt-0.6.1/.github/workflows/ 0000775 0000000 0000000 00000000000 14635030442 0016261 5 ustar 00root root 0000000 0000000 spopt-0.6.1/.github/workflows/build_docs.yml 0000664 0000000 0000000 00000003652 14635030442 0021121 0 ustar 00root root 0000000 0000000 name: Build Docs
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
workflow_dispatch:
inputs:
version:
description: Manual Doc Build Reason
default: test
required: false
jobs:
docs:
name: build & push docs
runs-on: ${{ matrix.os }}
timeout-minutes: 90
strategy:
matrix:
os: ['ubuntu-latest']
environment-file: [ci/312-latest.yaml]
experimental: [false]
defaults:
run:
shell: bash -l {0}
steps:
- name: checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for all branches and tags.
- name: setup micromamba
uses: mamba-org/setup-micromamba@v1
with:
environment-file: ${{ matrix.environment-file }}
micromamba-version: 'latest'
- name: install pulp via pip
run: pip install pulp
- name: install package
run: pip install .
- name: make docs
run: cd docs; make html
- name: commit docs
run: |
git clone https://github.com/ammaraskar/sphinx-action-test.git --branch gh-pages --single-branch gh-pages
cp -r docs/_build/html/* gh-pages/
cd gh-pages
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Update documentation" -a || true
# The above command will fail if no changes were present,
# so we ignore the return code.
- name: push to gh-pages
uses: ad-m/github-push-action@master
with:
branch: gh-pages
directory: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
force: true
spopt-0.6.1/.github/workflows/release_and_publish.yml 0000664 0000000 0000000 00000002454 14635030442 0023001 0 ustar 00root root 0000000 0000000 name: Release Package
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
workflow_dispatch:
inputs:
version:
description: Manual Release
default: test
required: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for all branches and tags.
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade build twine
python -m build
twine check --strict dist/*
- name: Create Release Notes
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
await github.request(`POST /repos/${{ github.repository }}/releases`, {
tag_name: "${{ github.ref }}",
generate_release_notes: true
});
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.pypi_password }}
spopt-0.6.1/.github/workflows/testing.yml 0000664 0000000 0000000 00000004312 14635030442 0020461 0 ustar 00root root 0000000 0000000 name: Continuous Integration
on:
push:
branches:
- '*'
pull_request:
branches:
- '*'
schedule:
- cron: '59 23 * * *'
workflow_dispatch:
inputs:
version:
description: Manual CI Run
default: test
required: false
jobs:
tests:
name: ${{ matrix.os }}, ${{ matrix.environment-file }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
matrix:
os: [ubuntu-latest]
environment-file: [
ci/310-oldest.yaml,
ci/310-latest.yaml,
ci/311-latest.yaml,
ci/312-latest.yaml,
ci/312-dev.yaml,
]
include:
- environment-file: ci/312-latest.yaml
os: macos-latest
- environment-file: ci/312-latest.yaml
os: macos-14 # Apple Silicon
- environment-file: ci/312-latest.yaml
os: windows-latest
fail-fast: false
defaults:
run:
shell: bash -l {0}
steps:
- name: checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for all branches and tags.
- name: setup micromamba
uses: mamba-org/setup-micromamba@v1
with:
environment-file: ${{ matrix.environment-file }}
micromamba-version: 'latest'
##############################################################################
#- name: install pulp via pip
# run: |
# pip install pulp
# pulptest
##############################################################################
- name: environment info
run: |
micromamba info
micromamba list
- name: spatial versions
run: 'python -c "import geopandas; geopandas.show_versions();"'
- name: run tests
run: |
pytest spopt \
-v \
-r a \
-n logical \
--color yes \
--cov spopt \
--cov-append \
--cov-report term-missing \
--cov-report xml .
- name: codecov
uses: codecov/codecov-action@v4
spopt-0.6.1/.gitignore 0000664 0000000 0000000 00000000410 14635030442 0014647 0 ustar 00root root 0000000 0000000 *.swp
*.pyc
.rope*
.idea/
notebooks/.ipynb_checkpoints/
.DS_Store
.ipynb_checkpoints/
*.bak
.eggs/
*.egg-info/
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
__pycache__
.coverage
.ruff_cache
.pytest_cache
spopt-0.6.1/.pre-commit-config.yaml 0000664 0000000 0000000 00000000320 14635030442 0017140 0 ustar 00root root 0000000 0000000 files: "spopt\/"
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.4.2"
hooks:
- id: ruff
- id: ruff-format
ci:
autofix_prs: false
autoupdate_schedule: quarterly
spopt-0.6.1/LICENSE.txt 0000664 0000000 0000000 00000002721 14635030442 0014511 0 ustar 00root root 0000000 0000000 BSD 3-Clause License
Copyright 2018 pysal-spopt developers
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
spopt-0.6.1/README.md 0000664 0000000 0000000 00000020714 14635030442 0014147 0 ustar 00root root 0000000 0000000
# `spopt`: Spatial Optimization
#### Regionalization, facility location, and transportation-oriented modeling

[](https://github.com/pysal/spopt/actions/workflows/testing.yml)
[](https://codecov.io/gh/pysal/spopt)
[](http://pysal.org/spopt/)
[](https://opensource.org/licenses/BSD-3-Clause)
[](https://github.com/astral-sh/ruff)
[](https://joss.theoj.org/papers/1413cf2c0cf3c561386949f2e1208563)
[](https://doi.org/10.5281/zenodo.4444156)
[](https://discord.gg/BxFTEPFFZn)
Spopt is an open-source Python library for solving optimization problems with spatial data. Originating from the `region` module in [PySAL (Python Spatial Analysis Library)](http://pysal.org), it is under active development for the inclusion of newly proposed models and methods for regionalization, facility location, and transportation-oriented solutions.
### Regionalization
```python
import spopt, libpysal, geopandas, numpy
mexico = geopandas.read_file(libpysal.examples.get_path("mexicojoin.shp"))
mexico["count"] = 1
attrs = [f"PCGDP{year}" for year in range(1950, 2010, 10)]
w = libpysal.weights.Queen.from_dataframe(mexico)
mexico["count"], threshold_name, threshold, top_n = 1, "count", 4, 2
numpy.random.seed(123456)
model = spopt.region.MaxPHeuristic(mexico, w, attrs, threshold_name, threshold, top_n)
model.solve()
mexico["maxp_new"] = model.labels_
mexico.plot(column="maxp_new", categorical=True, figsize=(12,8), ec="w");
```
### Locate
```python
from spopt.locate import MCLP
from spopt.locate.util import simulated_geo_points
import numpy, geopandas, pulp, spaghetti
solver = pulp.PULP_CBC_CMD(msg=False, warmStart=True)
lattice = spaghetti.regular_lattice((0, 0, 10, 10), 9, exterior=True)
ntw = spaghetti.Network(in_data=lattice)
street = spaghetti.element_as_gdf(ntw, arcs=True)
street_buffered = geopandas.GeoDataFrame(
geopandas.GeoSeries(street["geometry"].buffer(0.5).unary_union),
crs=street.crs,
columns=["geometry"],
)
client_points = simulated_geo_points(street_buffered, needed=100, seed=5)
ntw.snapobservations(client_points, "clients", attribute=True)
clients_snapped = spaghetti.element_as_gdf(
ntw, pp_name="clients", snapped=True
)
facility_points = simulated_geo_points(street_buffered, needed=10, seed=6)
ntw.snapobservations(facility_points, "facilities", attribute=True)
facilities_snapped = spaghetti.element_as_gdf(
ntw, pp_name="facilities", snapped=True
)
cost_matrix = ntw.allneighbordistances(
sourcepattern=ntw.pointpatterns["clients"],
destpattern=ntw.pointpatterns["facilities"],
)
numpy.random.seed(0)
ai = numpy.random.randint(1, 12, 100)
mclp_from_cost_matrix = MCLP.from_cost_matrix(cost_matrix, ai, 4, p_facilities=4)
mclp_from_cost_matrix = mclp_from_cost_matrix.solve(solver)
```
*see [notebook](https://github.com/pysal/spopt/blob/main/notebooks/mclp.ipynb) for plotting code*
## Examples
More examples can be found in the [Tutorials](https://pysal.org/spopt/tutorials.html) section of the documentation.
- [Max-p-regions problem](https://pysal.org/spopt/notebooks/maxp.html)
- [Skater](https://pysal.org/spopt/notebooks/skater.html)
- [Region K means](https://pysal.org/spopt/notebooks/reg-k-means.html)
- [Facility Location Real World Problem](https://pysal.org/spopt/notebooks/facloc-real-world.html)
All examples can be run interactively by launching this repository as a [](https://mybinder.org/v2/gh/pysal/spopt/main).
## Requirements
- [scipy](http://scipy.github.io/devdocs/)
- [numpy](https://numpy.org/devdocs/)
- [pandas](https://pandas.pydata.org/docs/)
- [networkx](https://networkx.org/)
- [libpysal](https://pysal.org/libpysal/)
- [scikit-learn](https://scikit-learn.org/stable/)
- [geopandas](https://geopandas.org/)
- [pulp](https://coin-or.github.io/pulp/)
- [shapely](https://shapely.readthedocs.io/en/stable/)
- [spaghetti](https://github.com/pysal/spaghetti)
## Installation
spopt is available on the [Python Package Index](https://pypi.org/). Therefore, you can either install directly with pip from the command line:
```
$ pip install -U spopt
```
or download the source distribution (.tar.gz) and decompress it to your selected destination. Open a command shell and navigate to the decompressed folder. Type:
```
$ pip install .
```
You may also install the latest stable spopt via conda-forge channel by running:
```
$ conda install --channel conda-forge spopt
```
## Related packages
* Region
* Locate
* [`allagash`](https://github.com/apulverizer/allagash)
* [`maximum-coverage-location`](https://github.com/cyang-kth/maximum-coverage-location)
* [`OR_classic_problem`](https://github.com/khamechian1987/OR_classic_problem)
* [`p-center`](https://github.com/antoniomedrano/p-center)
* [`pyspatialopt`](https://github.com/apulverizer/pyspatialopt)
## Contribute
PySAL-spopt is under active development and contributors are welcome.
If you have any suggestions, feature requests, or bug reports, please open new [issues](https://github.com/pysal/spopt/issues) on GitHub. To submit patches, please review [PySAL's documentation for developers](https://pysal.org/docs/devs/), the PySAL [development guidelines](https://github.com/pysal/pysal/wiki), the `spopt` [contributing guidelines](https://github.com/pysal/spopt/blob/main/.github/CONTRIBUTING.md) before opening a [pull request](https://github.com/pysal/spopt/pulls). Once your changes get merged, you’ll automatically be added to the [Contributors List](https://github.com/pysal/spopt/graphs/contributors).
## Support
If you are having trouble, please [create an issue](https://github.com/pysal/spopt/issues), [start a discussion](https://github.com/pysal/spopt/discussions), or talk to us in [PySAL's Discord channel](https://discord.gg/BxFTEPFFZn).
## Code of Conduct
As a PySAL-federated project, `spopt` follows the [Code of Conduct](https://github.com/pysal/governance/blob/main/conduct/code_of_conduct.rst) under the [PySAL governance model](https://github.com/pysal/governance).
## License
The project is licensed under the [BSD 3-Clause license](https://github.com/pysal/spopt/blob/main/LICENSE.txt).
## Citation
If you use PySAL-spopt in a scientific publication, we would appreciate using the following citations:
```
@misc{spopt2021,
author = {Feng, Xin, and Gaboardi, James D. and Knaap, Elijah and
Rey, Sergio J. and Wei, Ran},
month = {jan},
year = {2021},
title = {pysal/spopt},
url = {https://github.com/pysal/spopt},
doi = {10.5281/zenodo.4444156},
keywords = {python,regionalization,spatial-optimization,location-modeling}
}
@article{spopt2022,
author = {Feng, Xin and Barcelos, Germano and Gaboardi, James D. and
Knaap, Elijah and Wei, Ran and Wolf, Levi J. and
Zhao, Qunshan and Rey, Sergio J.},
year = {2022},
title = {spopt: a python package for solving spatial optimization problems in PySAL},
journal = {Journal of Open Source Software},
publisher = {The Open Journal},
volume = {7},
number = {74},
pages = {3330},
url = {https://doi.org/10.21105/joss.03330},
doi = {10.21105/joss.03330},
}
```
## Funding
This project is/was partially funded through:
[
](https://www.nsf.gov/index.jsp) National Science Foundation Award #1831615: [RIDIR: Scalable Geospatial Analytics for Social Science Research](https://www.nsf.gov/awardsearch/showAward?AWD_ID=1831615)
spopt-0.6.1/ci/ 0000775 0000000 0000000 00000000000 14635030442 0013257 5 ustar 00root root 0000000 0000000 spopt-0.6.1/ci/310-latest.yaml 0000664 0000000 0000000 00000000525 14635030442 0015742 0 ustar 00root root 0000000 0000000 name: test
channels:
- conda-forge
dependencies:
- python=3.10
- geopandas
- libpysal
- mapclassify
- networkx
- numpy
- pandas
- scikit-learn
- scipy
- shapely
- spaghetti
- tqdm
- pointpats
# testing
- codecov
- coverage
- pytest
- pytest-cov
- pytest-xdist
# with pip
- pip
- pip:
- pulp
spopt-0.6.1/ci/310-oldest.yaml 0000664 0000000 0000000 00000000621 14635030442 0015735 0 ustar 00root root 0000000 0000000 name: test
channels:
- conda-forge
dependencies:
- python=3.10
- geopandas=0.12
- libpysal=4.6
- mapclassify=2.5
- networkx=2.7
- numpy=1.22
- pandas=1.4
- scikit-learn=1.1
- scipy=1.8
- shapely=2.0.1
- spaghetti=1.6.4
- tqdm=4.63
- pointpats=2.3
# testing
- codecov
- coverage
- pytest
- pytest-cov
- pytest-xdist
# with pip
- pip
- pip:
- pulp==2.7
spopt-0.6.1/ci/311-latest.yaml 0000664 0000000 0000000 00000000512 14635030442 0015737 0 ustar 00root root 0000000 0000000 name: test
channels:
- conda-forge
dependencies:
- python=3.11
- geopandas
- libpysal
- mapclassify
- networkx
- numpy
- pandas
- scikit-learn
- scipy
- spaghetti
- tqdm
- pointpats
# testing
- codecov
- coverage
- pytest
- pytest-cov
- pytest-xdist
# with pip
- pip
- pip:
- pulp
spopt-0.6.1/ci/312-dev.yaml 0000664 0000000 0000000 00000001564 14635030442 0015232 0 ustar 00root root 0000000 0000000 name: test
channels:
- conda-forge
dependencies:
- python=3.12
- folium # for geopandas.explore()
- geos # for shapely
- matplotlib # for geopandas.explore()
- tqdm
# testing
- codecov
- coverage
- pytest
- pytest-cov
- pytest-xdist
# with pip
- pip
- pip:
# dev versions of packages
- --pre \
--index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
--extra-index-url https://pypi.org/simple
- numpy
- pandas
- pulp
- scikit-learn
- scipy
- git+https://github.com/geopandas/geopandas.git
- git+https://github.com/pysal/libpysal.git
- git+https://github.com/pysal/mapclassify.git
- git+https://github.com/networkx/networkx.git
- git+https://github.com/pysal/pointpats.git
- git+https://github.com/shapely/shapely.git
- git+https://github.com/pysal/spaghetti.git
spopt-0.6.1/ci/312-latest.yaml 0000664 0000000 0000000 00000000674 14635030442 0015751 0 ustar 00root root 0000000 0000000 name: test
channels:
- conda-forge
dependencies:
- python=3.12
- geopandas
- libpysal
- mapclassify
- networkx
- numpy
- pandas
- scikit-learn
- scipy
- spaghetti
- tqdm
- pointpats
# testing
- codecov
- coverage
- pytest
- pytest-cov
- pytest-xdist
# docs - only this env
- nbsphinx
- numpydoc
- sphinx
- sphinxcontrib-bibtex
- sphinx_bootstrap_theme
# with pip
- pip
- pip:
- pulp
spopt-0.6.1/codecov.yml 0000664 0000000 0000000 00000000543 14635030442 0015033 0 ustar 00root root 0000000 0000000 codecov:
notify:
after_n_builds: 5
coverage:
range: 50..95
round: nearest
precision: 1
status:
project:
default:
threshold: 5%
patch:
default:
threshold: 20%
target: 60%
ignore:
- "tests/*"
comment:
layout: "reach, diff, files"
behavior: once
after_n_builds: 5
require_changes: true
spopt-0.6.1/docs/ 0000775 0000000 0000000 00000000000 14635030442 0013614 5 ustar 00root root 0000000 0000000 spopt-0.6.1/docs/Makefile 0000664 0000000 0000000 00000001353 14635030442 0015256 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = spopt
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@rsync -r --exclude '.ipynb_checkpoints/' ../notebooks/ ./notebooks/
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
github:
@make html
clean:
rm -rf $(BUILDDIR)/*
rm -rf auto_examples/
spopt-0.6.1/docs/_static/ 0000775 0000000 0000000 00000000000 14635030442 0015242 5 ustar 00root root 0000000 0000000 spopt-0.6.1/docs/_static/images/ 0000775 0000000 0000000 00000000000 14635030442 0016507 5 ustar 00root root 0000000 0000000 spopt-0.6.1/docs/_static/images/lscpb-predef.png 0000664 0000000 0000000 00002606722 14635030442 0021602 0 ustar 00root root 0000000 0000000 PNG
IHDR ^ $ c
iCCPICC Profile HT7ZBzH .l$@(!Y\EDEWE\"kAD-
dQQV`C!;&g|dܹ(p4XtQ$ד=$'T)fDfC/&m\E p?ID_Ē, P{,$w L "|wyd
b" \I dgdd~f_$-g,'$L K)N?KztfCD0*!{v75#@Ƣ8Y9üLv^i3(dq"fX>Ò0\6ky2#˟=¨L
ai~sv^3^!G66+9Ovlk6gf6{6&R/%N|ep,@Ύ
a
?td4D%'/ ˳&, b.:}ѧ!D:ˍU{bb/9? _ P.p9'dO
yh=`́
p .x"@,Xx #/z
TjGqNn !` D*
@f
Ą o(
bx( ARh*J
h/TCWn4
Co/0
&4X6-a&̂x/s