Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-boost-histogram for
openSUSE:Factory checked in at 2025-02-03 21:45:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-boost-histogram (Old)
and /work/SRC/openSUSE:Factory/.python-boost-histogram.new.2316 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-boost-histogram"
Mon Feb 3 21:45:15 2025 rev:7 rq:1242833 version:1.5.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-boost-histogram/python-boost-histogram.changes
2024-09-17 18:26:17.619114032 +0200
+++
/work/SRC/openSUSE:Factory/.python-boost-histogram.new.2316/python-boost-histogram.changes
2025-02-03 21:46:37.622205092 +0100
@@ -1,0 +2,6 @@
+Mon Feb 3 13:31:50 UTC 2025 - Dirk Müller <[email protected]>
+
+- update to 1.5.1:
+ * Make non-uniform rebinning work for Weight() and friends
+
+-------------------------------------------------------------------
Old:
----
boost_histogram-1.5.0.tar.gz
New:
----
boost_histogram-1.5.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-boost-histogram.spec ++++++
--- /var/tmp/diff_new_pack.YPrYea/_old 2025-02-03 21:46:38.106225153 +0100
+++ /var/tmp/diff_new_pack.YPrYea/_new 2025-02-03 21:46:38.106225153 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-boost-histogram
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-boost-histogram
-Version: 1.5.0
+Version: 1.5.1
Release: 0
Summary: The Boost::Histogram Python wrapper
License: BSD-3-Clause
++++++ boost_histogram-1.5.0.tar.gz -> boost_histogram-1.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.github/CONTRIBUTING.md
new/boost_histogram-1.5.1/.github/CONTRIBUTING.md
--- old/boost_histogram-1.5.0/.github/CONTRIBUTING.md 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/CONTRIBUTING.md 2022-11-09
13:37:21.000000000 +0100
@@ -42,12 +42,12 @@
```console
$ nox -l # List all the defined sessions
$ nox -s lint # Lint only
-$ nox -s tests-3.9 # Python 3.9 tests only
+$ nox -s tests # Tests only
$ nox -s docs -- serve # Build and serve the docs
$ nox -s make_pickle # Make a pickle file for this version
```
-Nox handles everything for you, including setting up an temporary virtual
+Nox handles everything for you, including setting up a temporary virtual
environment for each run.
### Pip
@@ -57,10 +57,11 @@
Python's built-in venv:
```bash
-python3 -m venv .env
-source ./.env/bin/activate
-pip install -U pip
-pip install -ve .[all]
+python3 -m venv .venv
+source ./.venv/bin/activate
+pip install dependency-groups
+pip-install-dependency-groups dev
+pip install -ve.
```
<details><summary>Optional: External Jupyter kernel (click to expand)</summary>
@@ -109,7 +110,8 @@
```bash
python3 -m venv env_cmake
source ./env_cmake/bin/activate
-pip install -r dev-requirements.txt
+pip install dependency-groups
+pip-install-dependency-groups dev
cmake -S . -B build-debug \
-GNinja \
-DCMAKE_INSTALL_PREFIX=$(python -c "import distutils.sysconfig;
print(distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False))")
@@ -285,7 +287,8 @@
brew install llvm # macOS way to get clang-9
python3 -m venv .env_core # general environment (no install will be made)
. .env_core/bin/activate
-pip install -r dev-requirements.txt
+pip install dependency-groups
+pip-install-dependency-groups dev
CXX="/usr/local/opt/llvm/bin/clang++" cmake -S . -B build-llvm \
-DCMAKE_CXX_FLAGS="-ftime-trace" \
-DPYTHON_EXECUTABLE=$(which python)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/.github/workflows/emscripten.yaml
new/boost_histogram-1.5.1/.github/workflows/emscripten.yaml
--- old/boost_histogram-1.5.0/.github/workflows/emscripten.yaml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/workflows/emscripten.yaml 2022-11-09
13:37:21.000000000 +0100
@@ -24,7 +24,7 @@
submodules: true
fetch-depth: 0
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
env:
CIBW_PLATFORM: pyodide
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.github/workflows/examples.yml
new/boost_histogram-1.5.1/.github/workflows/examples.yml
--- old/boost_histogram-1.5.0/.github/workflows/examples.yml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/workflows/examples.yml 2022-11-09
13:37:21.000000000 +0100
@@ -6,6 +6,7 @@
paths:
- "examples/*.py"
- "notebooks/*.ipynb"
+ - ".github/workflows/examples.yml"
push:
branches:
- master
@@ -21,13 +22,10 @@
- uses: actions/setup-python@v5
with:
python-version: "3.9"
- - name: Pre-install NumPy
- run: python -m pip install -r dev-requirements.txt nbconvert ipykernel
- - name: Install kernel
- run: python -m ipykernel install --user --name boost-hist
- - name: Build
- run: python -m pip install .[examples]
+ - uses: astral-sh/setup-uv@v5
+ - name: Build and install kernel
+ run: uv run --group examples -m ipykernel install --user --name
boost-hist
- name: Examples
- run: for f in examples/*.py; do python "$f"; done
+ run: for f in examples/*.py; do uv run "$f"; done
- name: Notebooks
- run: jupyter nbconvert --execute --ExecutePreprocessor.timeout=90
--inplace notebooks/*.ipynb
+ run: uv run jupyter nbconvert --execute
--ExecutePreprocessor.timeout=90 --inplace notebooks/*.ipynb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.github/workflows/tests.yml
new/boost_histogram-1.5.1/.github/workflows/tests.yml
--- old/boost_histogram-1.5.0/.github/workflows/tests.yml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/workflows/tests.yml 2022-11-09
13:37:21.000000000 +0100
@@ -60,7 +60,7 @@
strategy:
fail-fast: false
matrix:
- python-version: ["3.9", "3.13", "pypy3.9"]
+ python-version: ["3.9", "3.13", "pypy3.10"]
include:
- python-version: "3.8"
cmake-extras: "-DCMAKE_CXX_STANDARD=17"
@@ -78,13 +78,18 @@
- uses: rui314/setup-mold@v1
- - uses: yezz123/setup-uv@v4
+ - uses: astral-sh/setup-uv@v5
- uses: hendrikmuhs/[email protected]
with:
key: ${{ matrix.python-version }}
create-symlink: true
+ - name: Make requirements.txt
+ run: |
+ uv pip install --system dependency-groups
+ dependency-groups dev > dev-requirements.txt
+
- name: Install python tools
run: uv pip install --system -r dev-requirements.txt
pytest-github-actions-annotate-failures
env:
@@ -109,11 +114,11 @@
include:
- os: ubuntu-latest
only: cp313t-manylinux_x86_64
- - os: ubuntu-latest
- only: cp313-manylinux_x86_64
- - os: windows-2019
+ - os: ubuntu-24.04-arm
+ only: cp313-manylinux_aarch64
+ - os: windows-latest
only: cp38-win32
- - os: windows-2019
+ - os: windows-latest
only: cp313-win_amd64
- os: macos-13
only: cp39-macosx_x86_64
@@ -126,9 +131,9 @@
submodules: true
fetch-depth: 0
- - uses: yezz123/setup-uv@v4
+ - uses: astral-sh/setup-uv@v5
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
with:
only: "${{ matrix.only }}"
env:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.github/workflows/weekly.yml
new/boost_histogram-1.5.1/.github/workflows/weekly.yml
--- old/boost_histogram-1.5.0/.github/workflows/weekly.yml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/workflows/weekly.yml 2022-11-09
13:37:21.000000000 +0100
@@ -21,10 +21,13 @@
- uses: actions/setup-python@v5
with:
- python-version: "3.11"
+ python-version: "3.12"
- name: Build and install wheel
- run: pip install -v .[test]
+ run: |
+ pip install dependency-groups
+ pip-install-dependency-groups test
+ pip install -v .
- name: Test
run: python -m pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.github/workflows/wheels.yml
new/boost_histogram-1.5.1/.github/workflows/wheels.yml
--- old/boost_histogram-1.5.0/.github/workflows/wheels.yml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.github/workflows/wheels.yml 2022-11-09
13:37:21.000000000 +0100
@@ -22,7 +22,7 @@
jobs:
build_sdist:
name: Build SDist
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
@@ -40,38 +40,6 @@
path: dist/*
name: wheels-sdist
- build_arch_wheels:
- name: ${{ matrix.python }} on ${{ matrix.arch }}
- runs-on: ubuntu-22.04
- strategy:
- matrix:
- python: ["38", "39", "310", "311", "312", "313", "313t"]
- arch: [aarch64]
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- submodules: true
-
- - uses: docker/[email protected]
- with:
- platforms: all
-
- - uses: pypa/[email protected]
- env:
- CIBW_BUILD: cp${{ matrix.python }}-manylinux_*
- CIBW_ARCHS: ${{ matrix.arch }}
-
- - name: Verify clean directory
- run: git diff --exit-code
- shell: bash
-
- - name: Upload wheels
- uses: actions/upload-artifact@v4
- with:
- path: wheelhouse/*
- name: wheel-aarch-${{ strategy.job-index }}
-
build_wheels:
name: ${{ matrix.build }} ${{ matrix.arch }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
@@ -107,20 +75,28 @@
arch: auto64
build: "*musllinux*"
+ - os: ubuntu-24.04-arm
+ arch: auto64
+ build: "*manylinux*"
+
+ - os: ubuntu-24.04-arm
+ arch: auto64
+ build: "*musllinux*"
+
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- - uses: yezz123/setup-uv@v4
+ - uses: astral-sh/setup-uv@v5
- - uses: actions/setup-python@v4
+ - uses: actions/setup-python@v5
if: matrix.os == 'macos-14'
with:
python-version: 3.8
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
env:
CIBW_BUILD: ${{ matrix.build }}
CIBW_ARCHS: ${{ matrix.arch }}
@@ -137,7 +113,7 @@
upload_all:
name: Upload if release
- needs: [build_wheels, build_arch_wheels, build_sdist]
+ needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
environment:
@@ -159,7 +135,7 @@
run: ls -lh dist
- name: Generate artifact attestation for sdist and wheels
- uses:
actions/attest-build-provenance@210c1913531870065f03ce1f9440dd87bc0938cd #
v1.4.0
+ uses:
actions/attest-build-provenance@520d128f165991a6c774bcb264f323e3d70747f4 #
v2.2.0
with:
subject-path: "dist/boost_histogram-*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.pre-commit-config.yaml
new/boost_histogram-1.5.1/.pre-commit-config.yaml
--- old/boost_histogram-1.5.0/.pre-commit-config.yaml 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/.pre-commit-config.yaml 2022-11-09
13:37:21.000000000 +0100
@@ -5,13 +5,13 @@
repos:
- repo: https://github.com/adamchainz/blacken-docs
- rev: "1.18.0"
+ rev: "1.19.1"
hooks:
- id: blacken-docs
- additional_dependencies: [black==23.*]
+ additional_dependencies: [black==24.*]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.6.0
+ rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
@@ -21,7 +21,6 @@
- id: debug-statements
- id: end-of-file-fixer
- id: mixed-line-ending
- - id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/cheshirekow/cmake-format-precommit
@@ -31,32 +30,30 @@
additional_dependencies: [pyyaml]
- repo: https://github.com/rbubley/mirrors-prettier
- rev: "v3.3.3"
+ rev: "v3.4.2"
hooks:
- id: prettier
types_or: [yaml, markdown, html, css, scss, javascript, json]
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: "v0.6.2"
+ rev: "v0.9.2"
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
- types_or: [python, pyi, jupyter]
- id: ruff-format
- types_or: [python, pyi, jupyter]
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.11.1
+ rev: v1.14.1
hooks:
- id: mypy
files: ^src
- additional_dependencies: [numpy~=1.26.0, pytest, uhi]
+ additional_dependencies: [numpy~=2.2.0, pytest, uhi]
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
- args: ["-L", "hist,nd,circularly,ba", "-w"]
+ args: ["-L", "hist,nd,circularly,ba,fo", "-w"]
exclude:
^(notebooks/xarray.ipynb|notebooks/BoostHistogramHandsOn.ipynb|.*\.svg)$
- repo: local
@@ -68,7 +65,7 @@
exclude: .pre-commit-config.yaml
- repo: https://github.com/pre-commit/mirrors-clang-format
- rev: v18.1.8
+ rev: v19.1.7
hooks:
- id: clang-format
types_or: [c++]
@@ -81,12 +78,12 @@
- id: rst-inline-touching-normal
- repo: https://github.com/python-jsonschema/check-jsonschema
- rev: 0.29.2
+ rev: 0.31.0
hooks:
- id: check-readthedocs
- id: check-github-workflows
- repo: https://github.com/henryiii/validate-pyproject-schema-store
- rev: 2024.08.19
+ rev: 2025.01.10
hooks:
- id: validate-pyproject
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/.readthedocs.yml
new/boost_histogram-1.5.1/.readthedocs.yml
--- old/boost_histogram-1.5.0/.readthedocs.yml 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/.readthedocs.yml 2022-11-09 13:37:21.000000000
+0100
@@ -6,20 +6,14 @@
version: 2
build:
- os: ubuntu-22.04
+ os: "ubuntu-22.04"
tools:
- python: "3"
-
-# Build documentation in the docs/ directory with Sphinx
-sphinx:
- configuration: docs/conf.py
-
-# Include PDF and ePub
-formats: all
-
-python:
- install:
- - requirements: docs/requirements.txt
+ python: "3.12"
+ commands:
+ - asdf plugin add uv
+ - asdf install uv latest
+ - asdf global uv latest
+ - uv run --only-group docs sphinx-build -T -b html -d docs/_build/doctrees
-D language=en docs $READTHEDOCS_OUTPUT/html
submodules:
exclude: all
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/CMakeLists.txt
new/boost_histogram-1.5.1/CMakeLists.txt
--- old/boost_histogram-1.5.0/CMakeLists.txt 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/CMakeLists.txt 2022-11-09 13:37:21.000000000
+0100
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.24...3.29)
+cmake_minimum_required(VERSION 3.24...3.31)
project(BOOST_HISTOGRAM LANGUAGES CXX)
# Version is added later
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/PKG-INFO
new/boost_histogram-1.5.1/PKG-INFO
--- old/boost_histogram-1.5.0/PKG-INFO 2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/PKG-INFO 2022-11-09 13:37:21.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: boost-histogram
-Version: 1.5.0
+Version: 1.5.1
Summary: The Boost::Histogram Python wrapper.
Keywords: boost-histogram,histogram
Author-Email: Hans Dembinski <[email protected]>, Henry Schreiner
<[email protected]>
@@ -40,31 +40,6 @@
Project-URL: Homepage, https://github.com/scikit-hep/boost-histogram
Requires-Python: >=3.8
Requires-Dist: numpy
-Requires-Dist: cloudpickle; extra == "dev"
-Requires-Dist: hypothesis>=6.0; extra == "dev"
-Requires-Dist: ipykernel; extra == "dev"
-Requires-Dist: pytest-benchmark; extra == "dev"
-Requires-Dist: pytest>=6.0; extra == "dev"
-Requires-Dist: typer; extra == "dev"
-Requires-Dist: myst_parser>=0.13; extra == "docs"
-Requires-Dist: nbsphinx; extra == "docs"
-Requires-Dist: sphinx-book-theme>=0.0.33; extra == "docs"
-Requires-Dist: Sphinx>=4.0; extra == "docs"
-Requires-Dist: sphinx_copybutton; extra == "docs"
-Requires-Dist: matplotlib; extra == "examples"
-Requires-Dist: netCDF4; extra == "examples"
-Requires-Dist: numba; extra == "examples"
-Requires-Dist: uproot3; extra == "examples"
-Requires-Dist: xarray; extra == "examples"
-Requires-Dist: xhistogram; extra == "examples"
-Requires-Dist: cloudpickle; extra == "test"
-Requires-Dist: hypothesis>=6.0; extra == "test"
-Requires-Dist: pytest-benchmark; extra == "test"
-Requires-Dist: pytest>=6.0; extra == "test"
-Provides-Extra: dev
-Provides-Extra: docs
-Provides-Extra: examples
-Provides-Extra: test
Description-Content-Type: text/markdown
<img alt="boost-histogram logo" width="402"
src="https://raw.githubusercontent.com/scikit-hep/boost-histogram/develop/docs/_images/BoostHistogramPythonLogo.png"/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/dev-requirements.txt
new/boost_histogram-1.5.1/dev-requirements.txt
--- old/boost_histogram-1.5.0/dev-requirements.txt 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/dev-requirements.txt 1970-01-01
01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-cloudpickle
-hypothesis >=6.0
-numpy
-pytest >=6,!=6.1.0,!=7.1.0
-pytest-benchmark
-setuptools_scm[toml] >=3.4,!=4.0.0
-uproot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/docs/changelog.md
new/boost_histogram-1.5.1/docs/changelog.md
--- old/boost_histogram-1.5.0/docs/changelog.md 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/docs/changelog.md 2022-11-09 13:37:21.000000000
+0100
@@ -2,6 +2,12 @@
## Version 1.5
+### Version 1.5.1
+
+Make non-uniform rebinning work for Weight() and friends [#972][]
+
+[#972]: https://github.com/scikit-hep/boost-histogram/pull/972
+
### Version 1.5.0
#### Features
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/docs/conf.py
new/boost_histogram-1.5.1/docs/conf.py
--- old/boost_histogram-1.5.0/docs/conf.py 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/docs/conf.py 2022-11-09 13:37:21.000000000
+0100
@@ -8,6 +8,7 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import contextlib
+import importlib.metadata
import shutil
import sys
from pathlib import Path
@@ -31,11 +32,8 @@
copyright = "2020, Henry Schreiner, Hans Dembinski"
author = "Henry Schreiner, Hans Dembinski"
-# It is better to use pkg_resources, but we can't build on RtD
-from pkg_resources import DistributionNotFound, get_distribution
-
-with contextlib.suppress(DistributionNotFound):
- version = get_distribution("boost_histogram").version
+with contextlib.suppress(ModuleNotFoundError):
+ version = importlib.metadata.version("boost_histogram")
# passed if no version (latest/git hash)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/docs/requirements.txt
new/boost_histogram-1.5.1/docs/requirements.txt
--- old/boost_histogram-1.5.0/docs/requirements.txt 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/docs/requirements.txt 1970-01-01
01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-ipython
-myst_parser>=0.13
-nbsphinx
-numpy
-Sphinx>=3.0.0
-sphinx-book-theme>=0.0.33
-sphinx_copybutton
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/docs/user-guide/subclassing.rst
new/boost_histogram-1.5.1/docs/user-guide/subclassing.rst
--- old/boost_histogram-1.5.0/docs/user-guide/subclassing.rst 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/docs/user-guide/subclassing.rst 2022-11-09
13:37:21.000000000 +0100
@@ -14,12 +14,10 @@
import my_package
- class Histogram(bh.Histogram, family=my_package):
- ...
+ class Histogram(bh.Histogram, family=my_package): ...
- class Regular(bh.axis.Regular, family=my_package):
- ...
+ class Regular(bh.axis.Regular, family=my_package): ...
If you only override ``Histogram``, you can leave off the ``family=``
argument, or set it to ``None``. It will generate a private ``object()`` in
this case. You must add an explicit family to ``Histogram`` if you subclass any
further components.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/examples/cpp/CMakeLists.txt
new/boost_histogram-1.5.1/examples/cpp/CMakeLists.txt
--- old/boost_histogram-1.5.0/examples/cpp/CMakeLists.txt 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/examples/cpp/CMakeLists.txt 2022-11-09
13:37:21.000000000 +0100
@@ -1,7 +1,7 @@
# This file lets you quickly build projects with the exact same boost-histogram
# settings that the Python bindings use.
-cmake_minimum_required(VERSION 3.14...3.20)
+cmake_minimum_required(VERSION 3.24...3.31)
project(BOOST_HISTOGRAM_CPP LANGUAGES CXX)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/examples/simple_weight.py
new/boost_histogram-1.5.1/examples/simple_weight.py
--- old/boost_histogram-1.5.0/examples/simple_weight.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/examples/simple_weight.py 2022-11-09
13:37:21.000000000 +0100
@@ -22,4 +22,4 @@
# Iterate over bins and access bin counter
for idx, (lower, upper) in enumerate(h.axes[0]):
val = h[idx]
- print(f"bin {idx} in [{lower:g}, {upper:g}): {val.value} +/-
{val.variance**.5}")
+ print(f"bin {idx} in [{lower:g}, {upper:g}): {val.value} +/-
{val.variance**0.5}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/include/bh_python/register_axis.hpp
new/boost_histogram-1.5.1/include/bh_python/register_axis.hpp
--- old/boost_histogram-1.5.0/include/bh_python/register_axis.hpp
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/include/bh_python/register_axis.hpp
2022-11-09 13:37:21.000000000 +0100
@@ -93,7 +93,7 @@
throw pybind11::key_error(py::str("{!r} not in
axis").format(vp[i]));
}
- return std::move(indices);
+ return indices;
};
}
@@ -131,7 +131,7 @@
values, k, i < self.size() ? py::cast(value(self, i)) :
py::none());
}
- return std::move(values);
+ return values;
};
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/notebooks/PerformanceComparison.ipynb
new/boost_histogram-1.5.1/notebooks/PerformanceComparison.ipynb
--- old/boost_histogram-1.5.0/notebooks/PerformanceComparison.ipynb
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/notebooks/PerformanceComparison.ipynb
2022-11-09 13:37:21.000000000 +0100
@@ -394,7 +394,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.6"
+ "version": "3.12.8"
}
},
"nbformat": 4,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/notebooks/SimpleExample.ipynb
new/boost_histogram-1.5.1/notebooks/SimpleExample.ipynb
--- old/boost_histogram-1.5.0/notebooks/SimpleExample.ipynb 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/notebooks/SimpleExample.ipynb 2022-11-09
13:37:21.000000000 +0100
@@ -137,7 +137,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.6"
+ "version": "3.12.8"
}
},
"nbformat": 4,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/notebooks/ThreadedFills.ipynb
new/boost_histogram-1.5.1/notebooks/ThreadedFills.ipynb
--- old/boost_histogram-1.5.0/notebooks/ThreadedFills.ipynb 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/notebooks/ThreadedFills.ipynb 2022-11-09
13:37:21.000000000 +0100
@@ -198,7 +198,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.6"
+ "version": "3.12.8"
}
},
"nbformat": 4,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/notebooks/aghast.ipynb
new/boost_histogram-1.5.1/notebooks/aghast.ipynb
--- old/boost_histogram-1.5.0/notebooks/aghast.ipynb 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/notebooks/aghast.ipynb 2022-11-09
13:37:21.000000000 +0100
@@ -50,7 +50,7 @@
{
"data": {
"text/plain": [
- "Histogram(Regular(15, -3, 3), storage=Double()) # Sum: 997352.0
(1000000.0 with flow)"
+ "Histogram(Regular(15, -3, 3), storage=Double()) # Sum: 997277.0
(1000000.0 with flow)"
]
},
"execution_count": 2,
@@ -90,7 +90,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "<TH1D (version 3) at 0x7fa9b83ffd00>\n"
+ "<TH1D (version 3) at 0x000112a9ef30>\n"
]
}
],
@@ -115,17 +115,16 @@
"outputs": [
{
"data": {
- "image/png":
"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",
+ "image/png":
"iVBORw0KGgoAAAANSUhEUgAABIUAAAM6CAYAAAAfd/ODAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAewgAAHsIBbtB1PgAAcbBJREFUeJzt3Qm8ndO9P/6ViCRiDGIegoip3PqRUENjdmUgUUPNVAxFSy8iSg0XRXHNVAipVtVQoiS9eqkpMUTQaxZTkKLEFCREJP/Xd93/3q+dc/Y+54RznHPyvN+v13nttffz7O+z9mkqOZ/zXevpMGfOnDkJAAAAgELp2NoTAAAAAOC7JxQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAOrX2BGjfvvjii/TMM8/kcY8ePVKnTv5IAQAAQHObNWtWev/99/N4/fXXT127dv3WNf0Ez7cSgVDfvn1bexoAAABQGBMmTEh9+vT51nUsHwMAAAAoIJ1CfCuxZKwyqVx++eVbdT4AAAAwP3rnnXfKK3Uqfxb/NoRCfCuVewhFILTSSiu16nwAAABgftepmfbztXwMAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABdSiodB7772X7rrrrnTKKaeknXbaKS299NKpQ4cO+evAAw/8RjXvueee/N5evXqlhRdeOC2++OKpd+/eabfddktXXnll+uyzzxp8//Tp09NvfvOb1
KdPn7TkkkvmGmuvvXY69thj0xtvvNHkecS58Z54b9SIWlHzvPPOy9doqocffjjtu+++adVVV01du3ZNyy23XNpxxx3TjTfemOZFnL/DDjvk90edqBd1H3nkkXmqAwAAABRDhzlz5sxpseIdOtQ8dsABB6RRo0Y1udZHH32UDjrooHTHHXc0eN5TTz2Vvv/971c99sorr6T+/funl19+uerxxRZbLN1www1p4MCBDV7jzjvvzIHLtGnTqh6PkGrMmDE5uGrIaaedls4444w0e/bsqscHDBiQbr311hzy1DJjxowciI0dO7bq8Y4dO+ZQ7tRTT00tYcqUKWnllVfO47feeiuttNJKLXIdAAAAKLIpLfDz93e2fGyVVVbJnSzfxCeffJK23377ciA0ZMiQHN48+uij6fHHH0+33XZbOvrooxv8hnz66ac5ZCkFQocccki69957c6fOWWedlRZZZJEc8uy5557pH//4R4OhU5wT58Z74r1RI2pFzTBp0qR8rbhmLVdddVU6/fTTcyC0xhprpJEjR6YJEyak0aNHp6233jqfE8HST37ykwa/N3G8FAjF++L9USfqRd2oH+HTiBEjGqwDAAAAFMycFnTKKafMufPOO+e8++67+fnrr78eXUn564ADDmhynf322y+/p0uXLnPuuOOOmufNnj17zldffVX12K9+9avytX/zm9/UOz5+/Pg5nTp1ysf79etX8xpbbrllPifOffjhh+sdj9ql65x66qlVa3zwwQdzFl988XzOKqusMuf999+f6/isWbPmDBo0qFznvvvuq1rn3nvvLZ8T58f7KkXdqB/Hl1hiiTkffvjhnOb21ltvlecQYwAAAGBOu/j5u0U7haITJpZiLbvsst+4xrhx49Lvf//7PD7zzDPTzjvv3OBytU6dOtV7/auvvkqXXHJJHq+zzjp5L6C6Nttss3TwwQfn8QMPPJA7kOqKDpyHHnooj+PcH/zgB/XOidpxjXDxxR
fna9d1zTXX5O6ncO655+a9liotsMAC6YorrsiPIfYpqub888/Pj/GZK88vibpRP3z88cf5ugAAAADt4u5jl112WX6MDaWPOuqob1TjvvvuK4cwsZdR7LNTTeXm17fffnu947E0qyT2N6omau+///7lICauXatO7GG06667Vq0TS+G22267PI6laXWXosXzeD3EebWWzkX9uE6tzwQAAAAUU5sOhWbOnFneRyj2FCptuPz111/nTZUmT56cvvjiiyZ1G5X069ev5nkbb7xx6tatWx6PHz++Zp2429hGG21Us07lNerWic8UHUchOo06d+7caJ0vv/wyTZw4ca5j0ckUtRr7TFF/0003Lb+nWucSAAAAUDxtOhT63//933Los/766+fNnY855pi8LCo2rl5ttdVyB1EERvfff3/NOs8//3x5HLeQryWWYZXuGPbCCy/UO156Lc6ptkyt2jXq1olNqCPUamwujdVp6meqPD5r1qyad15raHfzhr7eeeedeaoHAAAAtA21k402oDL4iLtoRSdP3VAjumXuueeevJTq7LPPTieccEK9OhFelDp8llhiiQavGbd3e/rpp9P777+fO3S6dOmSX49waurUqXnc2G3funfvnq/1+eef546manNpSp3SreZCc9ZZd911Gzy/1nsBAACA+Ueb7hT68MMPy+PYMDkCoX//93/Py68ipHnvvffSlVdembuF5syZk4YPH15eblaptB9P3EK+MRHmlHz22Wf1asxrncoa81qn1lyasw4AAABQTG26Uyg6bUoiBIplYnfddVf5Lls9evRIhx9+ePre976X99WJbqITTzwx36Es7kRW+d7Q0P49JaXOoDBjxox6Nea1TmWNea1Tay7NWacxdTuU6orlY3379p2nmgAAAEDra9OhUGlj6cpuobq3XQ9bbLFFvsvWrbfemvfeeeaZZ9IGG2xQr05pY+aGxJKxkoUWWqjqXOalTmWNea1Tay7NWacxjS1
NAwAAANqnNr18bNFFFy2Poytoww03rHnujjvuWB7HXbaq1WnK0qnK7qTKZVmVc5mXOnWXds1LnVpzac46AAAAQDG16VCocpPjedlMOTaJrlR6b4QjH3/8cZOWS0UIVbnsKjpzllpqqXqbPFfz0UcflYOYuhs1V36OxupULt1qqToAAABAMbXpUGi99dYrj0u3ca+l8njd28VX3m3rxRdfrFkjbtn+6quv5vE666xT73ipziuvvJLPraXyGnXr9O7du7wErqG5NFanqZ+p8nh8X9Zcc80GzwUAAACKoU3vKbTqqqumVVZZJb355ptp8uTJ+Q5jlRtIVyqFOWHFFVest+dQyQMPPJA23XTTqjUmTpxY7vDZfPPN6x2POg899FA+54knnkibbLJJ1TpxjZK6dWJT6NiY+ZFHHslfsR9QrY2iS3WiY2njjTee61ifPn3y++L9cV7cea2aOP7oo4+W37PgggtWPQ8AaD09h49JRTL5nAGtPQUAoK13CoUf/ehH+XHatGnp3nvvrXnebbfdVjUECltttVW+bX343e9+l8OlakaNGlUeDxkypN7xwYMHl8fXXXdd1RpxB7Trr78+j5dYYom09dZb16wTn6ly3pViSdg999yTx9tuu+1cewiFeB6vhziv1hKyqB/XqfWZAAAAgGJq86HQMcccU77T1n/8x3+UA45Kf/jDH9L999+fxwMGDKi3b0501Pz85z/P47g72fnnn1+vRnTtjBw5Mo/j9vbRVVNXdPhsueWWeRznxnvquuCCC/I1wtFHH121M2fo0KHlkCo6fD744IN6S+GOOOKI8pK4448/vur35rjjjsuPsZTtyCOPrLfEburUqemEE04oB1RxXQAAAIDQYU6ttplmMG7cuLz/TmVIUQo4YllV3ZDiwAMPrFrnvPPOS8OGDcvjtdZaKwcdccv5UqfNlVdemQORxRZbLC8Bq7ZvzqeffpqXYE2aNCk/P/TQQ9OPf/zjfIv2++67
L/3617/Od/GK5w8//HD6/ve/X3UuTz31VJ77jBkz8p28fvnLX+ZuoHj+pz/9KY0YMaK8d1DMpW6HT8lVV12VDj/88DxeY4010kknnZTWX3/99Pbbb6eLLroozynstdde6Y9//GPN73Ecj+uGmEeEaCussEJ65pln0llnnVVeVhfXi8/c3KJDqRTCxYbWbmEPAPPO8jEAoDV+/m7RUChCnliu1VQNTeXEE09M5557bs1zlllmmTR69Oj0gx/8oGaNCKj69++fXn755arHI1S64YYb0sCBAxuc55133pn23Xffql1LpUBozJgxqVevXg3WOfXUU9MZZ5xR8zPFXP/85z+XO6WqiTBqt912S2PHjq16vGPHjulXv/pVOu2001JLEAoBwLcnFAIAWuPn7za/fKzk7LPPTuPHj0/77bdf6tmzZ958OZZgxTKvCFaiA6ihQChESBOdPhEuRddQLKnq1q1b7j76xS9+kZ5++ulGA6EwaNCgfG68JwKgqBG1ombUjms0FgiF008/PXdT7b333vl/2FjmFuHW9ttvn7uDIlhqKBAK0dkU50WYFe+L90edqBd1o35LBUIAAABA+9WinULM/3QKAcC3p1MIAGhMoTuFAAAAAGg+QiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAA
ABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABdWrtCQAAUCw9h49JRTL5nAGtPQUAqEooBAC0OUULDQAAWoPlYwAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACigFg2F3nvvvXTXXXelU045Je20005p6aWXTh06dMhfBx544LeqPX369LT66quX6/Xs2bPJ7/vNb36T+vTpk5Zccsm08MILp7XXXjsde+yx6Y033mjy9ePceE+8N2pErah53nnn5Ws01cMPP5z23XfftOqqq6auXbum5ZZbLu24447pxhtvTPMizt9hhx3y+6NO1Iu6jzzyyDzVAQAAAIqhw5w5c+a0WPEOHWoeO+CAA9KoUaO+ce3jjjsuXXDBBeXnEYJMnjy5wfe88sorqX///unll1+uenyxxRZLN9xwQxo4cGCDde68884cuEybNq3q8d69e6cxY8akXr16NVjntNNOS2eccUaaPXt21eMDBgxIt956aw55apkxY0babbfd0tixY6se79ixYw7lTj311NQSpkyZklZeeeU8fuutt9JKK63UItcBoFh6Dh/T2lOAZjP5nAGtPQUA5gNTWuDn7+9s+dgqq6ySO1maw1NPPZUuuuiiHJYsuuiiTXrPp59+mkOWUiB0yCGHpHvvvTd36px11llpkUUWySHPnnvumf7xj380eO04J86N98R7o0bUipph0qRJ+VpxzVquuuqqdPrpp+dAaI011kgjR45MEyZMSKNHj05bb711PieCpZ/85CcNfq44XgqE4n3x/qgT9aJu1I/wacSIEU36PgEAAADF0Kkli0
eHSiypiq9ll102d/Ksttpq36rm119/ncOXeIzulwg/GgpfSmJZV4Q1IZaPHX/88eVjP/jBD9JWW22V+vXrl5d+HXPMMen++++vWufoo4/O3TmdOnVKf/vb3/J7S7bZZpu05pprpmHDhuVrRSdTBDJ1ffjhh+mEE04oh2WPPvpoXlpXEp1KQ4YMyR1JsSzs0EMPzfOr6+9//3v605/+lMeDBg1Kt99+e1pggQXy8/ie77zzzmmjjTZKb775Zr7e7rvvnrp3797o9woAAACY/7Vop1B0wkTAEYFQc7n44ovTE088kdZaa61ysNKYr776Kl1yySV5vM466+S9gOrabLPN0sEHH5zHDzzwQHr88cfrnRMdOA899FAex7mVgVBJ1I5rlOYa167rmmuuSZ988kken3vuuXMFQiGCnSuuuKIc8ESgVc3555+fHyOgqjy/JOpG/fDxxx/n6wIAAAC0u7uPxebO0X0Ufvvb36bOnTs36X333XdfOYSJvYxin51qKje/jq6bumJpVslBBx1UtUbU3n///ctBTFy7Vp3Yw2jXXXetWifWBm633XZ5HEvT6nZDxfN4PcR5tdYSRv24Tq3PBAAAABRTuwqFjjjiiPT555+n/fbbr+pyqlrGjRtXHscSsVo23njj1K1btzweP358zTpxt7FYllVL5TXq1pk5c2buOArRadRQsFWq8+WXX6aJEyfOdSw6maJWY58p6m+66abl91TrXAIAAACKp92EQrF3TmyoHHviVN51rCmef/758jhuIV9LLMMq3THshRdeqHe89FqcE+fWUnmNunVir6HYD6mxuTRWp6mfqfL4rFmzat55raHdzRv6euedd+apHgAAAFCAjaaby0cffZQ3fw7nnHNO6tGjxzy9P8KLUofPEkss0eC5cXu3p59+Or3//vu5Q6dLly759S+++CJNnTo1jxu77VsEV3Gt6GqK28RVm0tT6pRuNReas866667b4Pm13gsAAADMP9p
Fp1DcKexf//pXXm5Vuu37vCjtxxO3kG9MhDkln332Wb0a81qnssa81qk1l+asAwAAABRTm+8UevDBB9O1116bl2vF5tIdOnSY5xrR5ROasjF1qTMoxK3n69aY1zqVNea1Tq25NGedxtTtUKorlo/17dt3nmoCAAAAra9Nh0KxfOvQQw9Nc+bMSUcffXTaYIMNvlGdrl275sfSxsyNXbNkoYUWqldjXutU1pjXOrXm0px1GtPY0jQAAACgfWrTy8fOOuus9NJLL+V9bU4//fRvXGfRRRdt8tKp2Aeo2rKsUo15rVN3ade81Kk1l+asAwAAABRTm+4UOvfcc/Pjdtttl+68884GA494jDuUhWWWWSZts802c3W7PPbYY/mcjz/+uMHNpkvLpWIz68plV9GZs9RSS6UPPvhgrk2ea22MXZpX3Y2aKztvGqtTuXSrsTobb7zxN6oDAAAAFFObDoVKy6Kuu+66/NWQuDPYXnvtlcf9+vWbKxSKu239+c9/zuMXX3wxbbrpplVrxC3bX3311TxeZ5116h2POg899FB65ZVX8rm1bksf1yipW6d3795pgQUWyLelrzxvXutU3kGsqXVivmuuuWaD5wIAAADF0KaXjzWXLbbYojx+4IEHap43ceLEcofP5ptvXrNOnPPEE0/UrFN5jbp1YlPo0sbMjzzySIP7AZXqRMdS3U6gPn36lDeYbugzRf1HH320/J4FF1yw5rkAAABAcbTpUCg2mG7sa9VVV83nxmPptfvvv3+uOltttVVafPHF8/h3v/tdPqeaUaNGlcdDhgypd3zw4MHlca3OpdmzZ6frr78+j2OZ2tZbb12zzrRp09Jtt91WtU4sCbvnnnvyeNttt51rD6EQz+P1EOfVWooW9eM6tT4TAAAAUExtOhRqLtFR8/Of/zyPX3jhhXT++efXOye6dkaOHFlefhZdNXVFh8+WW26Zx3FuvKeuCy64IF8jxB3TqnXmDB06tBxSDR8+
PO9TVCmWlh1xxBH5MRx//PFVP9dxxx2XH2Mp25FHHlk+v3JJ3QknnFAOqOK6AAAAAC2+p9C4cePy/juVIUVJvF7ZmRMOPPDAFptLBCs33XRTmjRpUho2bFi+/o9//ON8i/b77rsv/frXv87hSjy/6KKLata5+OKL85KwGTNmpB122CH98pe/zN1A8Tw2uh4xYkR576Bjjz22ao0ll1wyb6J9+OGHpzfeeCNtsskm6aSTTkrrr79+evvtt/P1Y04h9kmKTqdqYt+k+Axx3b/85S9p++23T8ccc0xaYYUV0jPPPJPv3vbmm2/mc+N63bt3b4bvJAAAADA/6DCn1lqqZhAhTyzXaqpvMpWePXvmYCWWj02ePLnBcyMI6t+/f3r55ZerHl9sscXSDTfckAYOHNhgnbgT2r777ltellVXBEJjxoxJvXr1arDOqaeems4444yanzvmGhtkx53Paokwarfddktjx46terxjx47pV7/6VTrttNNSS4hla6U7msVdzirvigYA31TP4WNaewrQbCafM6C1pwDAfGBKC/z8XYjlYyUR0jz11FO5ayY2bo4lVd26dUtrrbVW+sUvfpGefvrpRgOhMGjQoHxuvCcCoKgRtaJm1I5rNBYIhdNPPz13U+299975f9hY5rbMMsvkjp8//vGPOVhqKBAK0dkU50WYFe+L90edqBd1o35LBUIAAABA+9WinULM/3QKAdASdAoxP9EpBEBz0CkEAAAAQLMQCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIA
AAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFFCLhkLvvfdeuuuuu9Ipp5ySdtppp7T00kunDh065K8DDzywSTWmT5+ebrvttvTTn/409enTJ3Xv3j0tuOCCaamllko/+MEP0mmnnZbefffdJs8p6v3mN7/JtZZccsm08MILp7XXXjsde+yx6Y033mhynTg33hPvjRpRK2qed955+RpN9fDDD6d99903rbrqqqlr165pueWWSzvuuGO68cYb07yI83fYYYf8/qgT9aLuI488Mk91AAAAgGLoMGfOnDktVrxDh5rHDjjggDRq1KgG3//000+nzTffPH322WcNnrfYYoulESNGpD333LPB81555ZXUv3//9PLLL9esc8MNN6SBAwc2WOfOO+/Mgcu0adOqHu/du3caM2ZM6tWrV4N1ItA644wz0uzZs6seHzBgQLr11ltzyFPLjBkz0m677ZbGjh1b9XjHjh1zKHfqqaemljBlypS08sor5/Fbb72VVlpppRa5DgDF0nP4mNaeAjSbyecMaO0pADAfmNICP39/Z8vHVlllldzJMi8idCkFQhEOnX322el//ud/0pNPPpnuvvvudNhhh+XQI87bZ5990l//+teatT799NMcspQCoUMOOSTde+
+9uVPnrLPOSossskiuE8HSP/7xj5p1nnrqqXxOnBvvifdGjagVNcOkSZPyteKatVx11VXp9NNPz4HQGmuskUaOHJkmTJiQRo8enbbeeut8TgRLP/nJTxr8HsXxUiAU74v3R52oF3WjfoRPEZoBAAAAfCedQtGdEkuq4mvZZZdNkydPTquttlqTO4UibLn44otznXXXXbfqOXfccUcaMmRIio8RIUiEPtU6lKJbJrpyQiwfO/744+tdq1+/fmnWrFn58f777696vR/+8IfpoYceSp06dUoPPvhgXsJWKZaPDRs2rPz5I5Cp68MPP0yrr756+uSTT3JY9sQTT+SldSVff/11/kzRkRTuu+++tNVWW9Wr8/e//z1tu+22eTxo0KB0++23pwUWWKB8fOrUqWmjjTZKb775ZlpiiSXSa6+9lpffNSedQgC0BJ1CzE90CgFQyE6h6ISJpVgRCH0Tm222WbrppptqBkJhl112Sbvuumsev/rqq7mTp66vvvoqXXLJJXm8zjrr5L2Aql3r4IMPzuMHHnggPf744/XOiQ6cCIRCnFs3EApRO64RItCKa9d1zTXX5EAonHvuuXMFQiGCnSuuuKIc8ETQVM3555+fHyOgqjy/JOpG/fDxxx/n6wIAAADMN3cfKy23KgVDdUWnTSmEiQ6lWHJWTeXm19F1U1cszSo56KCDqtaI2vvvv385iIlr16oTexiVAq26IvHbbrvt8jiWptVdihbP4/UQ59VKCKN+XKfWZwIAAACKab4Ihb788svyuG63TBg3blx5HEvDatl4441Tt27d8nj8+PE168TdxmJZVi2V16hbZ+bMmbnjKESnUefOnRutE59v4sSJcx2LTqao1dhnivqbbrpp+T3VOpcAAACA4pkvQqFY7lVSWrpV6fnnny+P4xbytcQyrNIdw1544YV6x0uvxTlxbi2V16hbJzahjj2DGptLY3Wa+pkqj8d+SbXuvAYAAAAUS+1ko5343//
933yXrrD++utXDYViM6ZSh09suNyQ2LTp6aefTu+//37u0OnSpUt+/YsvvsgbN4fGNnOKzZzjWp9//nne/KnaXJpSp7SBVGjOOg3t0VRX5XWqeeedd5pcCwAAAGg72nUoFKHN0KFDy503cXv4akr78cQt5BsTYU7JZ599Vg6FKvf0aWqdCIWiRrW5NKVO3bm0RJ3GVAZKAAAAwPyjXS8fO+qoo8p77cQG0nFb9mqiyyc0tH9PSSkECjNmzKhXY17rVNaY1zq15tKcdQAAAIBiaredQmeffXb5Fut9+vRJl19+ec1zu3btmh9LGzM3ddPqhRZaqF6Nea1TWWNe69SaS3PWaUzdZWvVlo/17dt3nmoCAAAAra9dhkJXXXVV+uUvf1neRHns2LFzLZGqa9FFF23y0qlY8lVtWVapxrzWqbu0a17q1JpLc9ZpTGP7FQEAAADtU7tbPnbjjTemI444Io9XXXXV9D//8z9p6aWXblKwEeHIxx9/3KTOmB49esy17Co6c5Zaaqkmbb780UcflYOYunvyVIYsjdWp7NJpqToAAABAMbWrUOgvf/lL2n///dPs2bPT8ssvn+69994mdbJU3m3rxRdfrHle3LL91VdfzeNqdzEr1XnllVfyubVUXqNund69e6cFFlig0bk0Vqepn6nyeKdOndKaa67Z4LkAAABAMbSbUCgCoD322COHMdGxEx1Ca6yxRpPeu8UWW5THDzzwQM3zYtPqUofP5ptvXrNOnPPEE0/UrFN5jbp1YlPo0h48jzzySIP7AZXqRMfSxhtvPNex2EeptMF0Q58p6j/66KPl9yy44II1zwUAAACKo12EQg8//HDaZZdd8obJiy++eLr77rvTeuut1+T3b7XVVvl94Xe/+12aM2dO1fNGjRpVHg8ZMqTe8cGDB5fH1113XdUa0cV0/fXX5/ESSyyRtt5665p1pk2blm677baqdWJJ2D333JPH22677Vx7CIV4Hq+HOK/W
ErKoH9ep9ZkAAACAYmrzodA//vGPNGDAgNydE5tJjxkzJm200UbzVCM6an7+85/n8QsvvJDOP//8eudE187IkSPzuF+/frmrpq7o8Nlyyy3zOM6N99R1wQUX5GuEo48+umpnztChQ8sh1fDhw9MHH3ww1/Gvv/4675sUj+H444+v+rmOO+64/BjdU0ceeWT5/JKpU6emE044oRxQxXUBAAAAWvzuY+PGjcv771SGFCXxemVnTjjwwAPneh77++y4447lzaHPPPPMHKY8++yzNa+5zDLL5K+6Ili56aab0qRJk9KwYcPy9X/84x/nW7Tfd9996de//nUOV+L5RRddVLP+xRdfnJeEzZgxI+2www75LmjRDRTP//SnP6URI0aU9w469thjq9ZYcskl07nnnpsOP/zw9MYbb6RNNtkknXTSSWn99ddPb7/9dr5+zCnstddeudOpmm222SZ/hrhu7Le0/fbbp2OOOSatsMIK6ZlnnklnnXVWevPNN/O5cb3u3bvX/FwAAABAsXSYU2stVTOIkCeWazVV3alEaHTQQQfN0zVPPfXUdNppp1U9FkFQ//7908svv1z1+GKLLZZuuOGGNHDgwAavceedd6Z99923vCyrrgiEoqOpV69ejc71jDPOqLmcLeb65z//Od/5rJYIo3bbbbc0duzYqsc7duyYfvWrX9X8nnxbsWytdEezuMuZW9gD0Bx6Dh/T2lOAZjP5nAGtPQUA5gNTWuDn7za/fKw5RUjz1FNP5a6Z2Lg5llR169YtrbXWWukXv/hFevrppxsNhMKgQYPyufGeCICiRtSKmlE7rtFYIBROP/303E2199575/9hY5lbdDlFx88f//jHHCw1FAiF6GyK8yLMivfF+6NO1Iu6Ub+lAiEAAACg/WrRTiHmfzqFAGgJOoWYn+gUAqA56BQCAAAAoFkIhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAAB
dSptScAADSu5/AxrT0FAADmMzqFAAAAAApIpxAAALSgonX6TT5nQGtPAYAm0ikEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQC0aCr333nvprrvuSqecckraaaed0tJLL506dOiQvw488MB5rvfXv/41DRkyJK200kqpS5cu+TGex+tNNWvWrPTb3/42bbnllqlHjx5poYUWSmussUY67LDD0nPPPdfkOlOnTs2fa4MNNkiLLbZY/opxvPbBBx80uc6zzz6brx1ziLnEnGJuMceY63f5vQEAAACKo8OcOXPmtFjxDh1qHjvggAPSqFGjmlRn9uzZ6dBDD00jR46sec7QoUPTVVddlTp27NhgkNO/f//0+OOPVz0eYcpll12WazXkscceS4MHD07vvvtu1ePLL798Gj16dOrbt2+Dda6++up01FFHpZkzZ1Y9Hu8fM2ZMDtNa+nvzTU2ZMiWtvPLKef
zWW2/lMAqA5tdz+JjWngJAk0w+Z0BrTwFgvjSlBX7+/s6Wj62yyipphx12+EbvPemkk8qhx4YbbphuvPHGNGHChPwYz8M111yTTj755Jo1vv7669w5UwqEdt1119xFEwHPJZdckpZZZpn05Zdf5q6dhrpr4hs/aNCgHAh16tQpDRs2LD344IP5K8bx2jvvvJPPif/Bahk7dmw6/PDDcyC07LLL5jnEXOLaMbcQnzHmHHNvye8NAAAAUDwt2il06qmnpj59+uSvCD4mT56cVltttXnqFJo0aVJab7318lKqjTfeOIcvscyqZPr06alfv35p4sSJOZB54YUXUq9everVufbaa9PBBx+cx0cccUS6/PLL5zr+yiuvpI022ihNmzYtvz/qRL269t9///T73/8+j2+++ea0++67z3U8Xttzzz0b/IxfffVVWnvttdNrr72Wl509+eSTeflYpSOPPDJdccUVeXzddddVXW7XXN+bb0OnEMB3Q6cQ0F7oFAJoGe2uU+j0009PAwcOzIHQN3XRRReV99a59NJL5wo9Qrdu3fLrIc678MILq9Y5//zz8+OSSy6ZzjvvvHrHIyw58cQTywHR7bffXu+c6A664YYb8njHHXesFwiFPfbYIx8LER5VW2IWtSMQCnHNuoFQiDl27969PG7J7w0AAABQPG367mPRxHTHHXfkcXTWbLrpplXPi9fXWmutPI7z6zY/RUdNdMmUQpsIS6qp7MapFgr95S9/yXv4hIMOOqjmvEt14tx4T12x31C1a1aKOcZcw/PPP58/Q0t8bwAAAIBiatOh0Ouvv57efvvtPI5lUA0pHf/nP/+Zl6lVGjduXL3zqlluueVS796983j8+PH1jje1TuWxhupEWBPX/CZ1mut7AwAAABRT/U1z2pDokCmJbpiGVB6PrqDS3kXfpE505cT6vM8//zwtvPDC9eosvvjiDYY5cfex2Cso9icqdSiVfPbZZ7n2N/lMLfG9aUx
Dm2WH2FQbAAAAaH/adChUGUg0toFSabOlUApdvk2dWGYV7ystvaqs05TNnKLOc8891yxzCS1VpzGV7wUAAADmH216+dinn35aHi+yyCINnlvZ0RPdOC1Zp7EalXVaei7ftg4AAABQTG26U+iLL74ojzt37tzguV26dCmPZ8yY0aJ1GqtRWael5/Jt6zSmsc6iWD7Wt2/feaoJAAAAtL42HQp17dq1PJ45c2aD53755Zflcd1bs9etU/l8XutMnz690blU1mlsLk2p0ZJ1GtOUpXIAAABA+9Oml48tuuiiTV72FJtC11pO1dx1mrIEq1SnpefybesAAAAAxdSmQ6HKLpXG7oJVucyp7ubI36ROhw4d6nXJlJ43VqOyTt25rLjiivM8l2p1mut7AwAAABRTmw6F1l133fL4xRdfbPDcyuPrrLPOt64T4UnlBs2VdT755JP07rvvNrjPTtyOvtpcosOnFMx815+pWh0AAACgmNp0KLTaaqulFVZYIY8feOCBBs998MEHy504PXv2nOvYFltsUR43VCeCnkmTJuXx5ptvXu94U+tUHmuozksvvdRguNRQneb63gAAAADF1KZDoVjCtcsuu5S7XR599NGq58XrpW6YOD/eV6l3797lDpmbb745bxZdzahRo8rjIUOG1Du+8847p44d/+9bdt1119Wcd6lOnBvvqWvw4MFVr1kp5hhzLXUFxWdoie8NAAAAUExtOhQKxxxzTFpggQXy+Gc/+1m9W6rH83g9dOrUKZ9fzXHHHZcfP/zwwzRs2LB6x1999dV09tln53GvXr2qhkLLLbdc2mefffL47rvvTrfeemu9c2655ZZ8LOy33375PXVF7dVXXz2P45px7bqOP/749NFHH5XHLfm9AQAAAIqnRW9JP27cuPTKK6+Un0+dOrU8jtfrdskceOCB9WpEh0yEIuecc06aOHFiXkZ1wgknpDXWWCOHKeeee2566qmn8rlx3pprrll1Lgcc
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
2Wfnca9evaqGQsstt1zaZ5998vjuu+9Ot956a71zbrnllnws7Lfffvk9dUXtuANbiGvGteuKTbfje1MaAwAAAIQOc2In5zYuundiv6DoegmDBg3KG06XbkkfHT4XXXRRevPNN/PxbbfdNt1zzz316px44onpnHPOKe9PFCHSGmuskcOUuKPZU089VT7v17/+ddW5fP3116lfv35p/Pjx+fmPfvSjdMghh6Tu3bunCRMm5M2u33vvvRxm3XXXXWmnnXaquflzfKb3338/h1DHHntsOciK90UXUnRF9ejRIz355JM1bw0/duzY/P2IrqNll102nXzyyalv3745CLr66qvTn//85/JSs/vvv78cjDWX2OS6tLdRfCa3sAe+CzqFANquyef83y90AUht/ufvdhEKhQh59tprrzR16tQGz9tmm21y502ENHVFcBIBTuluZtUcfPDBacSIETnUqSXm0L9///T4449XPd6lS5d02WWXpaFDhzY418ceeywvAau1H1B0B40ePTptsskmDdaJ8Oeoo45KM2fOrHo8QqIxY8akpZdeOjU3oRDQGoRCALQVQjDgu1LoUCh88MEHaeTIkemvf/1reu6559LHH3+cu2wiPOnTp0/ae++98947dfcCqtZdE8FPhDoR8ERYEu8/7LDDanb21BVdPBHG/PGPf8x7DH3++ed5M+voUjr66KPTeuut16Q6cf2LL744hz+TJ08u74cUexrFEralllqqSXWeffbZdMkll6R77703L7OLO57F/kexTC3CqVr7MH1bQiGgNQiFAGgrhELAd6XwoRBtj1AIaA1CIQDaCqEQ0J5//m7zG00DAAAA0PyEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQC
AAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABdQuQ6E333wznXrqqWnjjTdOPXr0SF27dk0rr7xy2nLLLdMpp5ySnn322Qbf/9e//jUNGTIkrbTSSqlLly75MZ7H6001a9as9Nvf/jZfM+aw0EILpTXWWCMddthh6bnnnmtynalTp+Y5b7DBBmmxxRbLXzGO1z744IMm14nPHNeOOcRcYk4xt5hjzBUAAACgUoc5c+bMSe3IpZdemk488cT0+eef1zzn6KOPThdddFG912fPnp0OPfTQNHLkyJrvHTp0aLrqqqtSx44dGwxy+vfvnx5//PGqxyNouuyyy3Kthjz22GNp8ODB6d133616fPnll0+jR49Offv2bbDO1VdfnY466qg0c+bMqsfj/WPGjElLL710am5TpkzJgVx46623csAG0NJ6Dh/T2lMAgGzyOQNaewpAQUxpgZ+/21Wn0Jlnnpl+/vOf50Cod+/e6bzzzkv3339/euqpp9I999yTn2+22WY1A52TTjqpHAhtuOGG6cYbb0wTJkzIj/
E8XHPNNenkk0+uOYevv/46dxWVAqFdd901dxhFwHPJJZekZZZZJn355Ze5a6ehzqP4H3DQoEE5EOrUqVMaNmxYevDBB/NXjOO1d955J58T/8PXMnbs2HT44YfnQGjZZZfNc4i5xLVjbiE+Y8w55g4AAADQrjqF7r333rTddtvl8f7775/DmwUXXLDquRGQdO7cea7XJk2alNZbb728lCqWnUX4EsusSqZPn5769euXJk6cmAOZF154IfXq1ate7WuvvTYdfPDBeXzEEUekyy+/fK7jr7zyStpoo43StGnT8vujTtSrKz7D73//+zy++eab0+677z7X8Xhtzz33zOMDDjggjRo1ql6Nr776Kq299trptddey8vOnnzyybx8rNKRRx6Zrrjiijy+7rrr0oEHHpiak04hoDXoFAKgrdApBHxXCtspFMu+fvrTn+bxv/3bv+Vun1qBUKgbCIVYTlbaWyeWoFUGQqFbt2759RDnXXjhhVVrn3/++flxySWXzJ1JdUUQFMvbSgHR7bffXu+c6A664YYb8njHHXesFwiFPfbYIx8LER5VW2IWtSMQCnHNuoFQiDl27969PAYAAABoN6HQ3/72t/Tyyy/n8QknnFC186Yh0Qx1xx135HF01my66aZVz4vX11prrTyO8+s2UUW3UXT+lEKbCJKqqezGqRYK/eUvf8lBVzjooINqzrtUJ86N99QV+w1Vu2almGPMNTz//PP5MwAAAAC0i1DolltuyY8dOnRIAwcOLL/+4Ycf5rAoHhvy+uuvp7fffjuPY4lYQ0rH//nPf6bJkyfPdWzcuHH1zqtmueWWy3sehfHjx9c73tQ6lccaqhNBVlzzm9YBAAAAiqddhEKPPvpofuzZs2dadNFF0x//+Me0/vrrp6WWWiqHL/EYwUgs7YpNnuuKDpmS6BRqSOXxUlfQt6kT6/zq3imtVGfxxRdvMMyJu4/FXkHV5vLZZ5/l2t/2MwEAAADFNG/rsFp
BLJ168cUX8zhuqR63m487bNUVy6KOP/74vFwrbr++xBJLlI9V3r2rsY2YSps2hVLo8m3qxBK0eF9pWVplnaZsChV1nnvuuWaZS6hbpzEN3fksxB3SAAAAgPanzYdCn3zySXn/nWeeeSbfCj46aGLT5P79+6euXbvm12Kvoegoevjhh9NPfvKTdNttt5VrfPrpp+XxIoss0uD1Fl544bm6cSo1d53GalTWaam5NKYyUAIAAADmH21++Vjl0qsvvvgib5x83333pX322SffVSvuIvbDH/4w/f3vf893JgvRLfTYY4/N9b6G7kxWqUuXLuXxjBkz5jrW3HUaq1FZp6XmAgAAABRTm+8Uik6gSkOHDp1rKVZJhENnnXVWeSPqm266KW2yySb1asycObPB61XuSVT3tvV169Sd27zUmT59eqNzqazT2FyaUqNancY0ttwslo/17dt3nmoCAAAAra/Nh0KxsXSlHXbYoea52267bb5d/axZs/KSsmo1Gls+VdmZVHdZVt06DYVCjdWJUKgpS7lKdRqbS1NqVKvTmKbsewQAAAC0P21++VgsferRo0eT9riJkCY2ow7vv/9+1WCjsY2TKztj6l7rm9Tp0KFDvWCl9LyxGpV16s5lxRVXnOe5VKsDAAAAFFObD4XCeuutVx5//fXXDZ5bOh4dQyXrrrtueVy6k1ktlcfXWWeduY59kzoRwlRu9FxZJzbRfvfddxtcmjVt2rSqc4lOoVLA820+EwAAAFBM7SIUio2kS1577bWa50WAMnXq1HqdNKuttlpaYYUV8viBBx5o8FoPPvhg+f09e/ac69gWW2xRHjdUJ4KeSZMm5fHmm29e73hT61Qea6jOSy+91GC41FgdAAAAoHjaRSj0ox/9qDyOO4vVEsfmzJmTx1tuuWX59VjCtcsuu5S7ZuLW9dXE66Wumjg/3lepd+/e5U6bm2++Oe8LVM2oUaPK4yFDhtQ7vvPOO6eOHf/vW3/dddfV
/DylOnFuvKeuwYMHV71mpZhjzLXUoRSfAQAAAKBdhEIbbLBB2mmnnfL4xhtvTPfee2+9c6JT5uSTTy7fov2ggw6a6/gxxxyTFlhggTz+2c9+Vu/W7PE8Xi8tPYvzqznuuOPy44cffpiGDRtW7/irr76azj777Dzu1atX1VBoueWWS/vss08e33333enWW2+td84tt9ySj4X99tsvv6euqL366qvncVwzrl3X8ccfnz766KPyGAAAAKDdhELhoosuSksssUSaPXt2vu38iSeemB566KE0ceLEdMUVV6Q+ffqUN1w+44wz5lo+FqJDphSKxHtiGVXctj7G8RjPYxzivDXXXLPqPA444IDyEqzLL7887bbbbjm8mTBhQrrsssvSZpttlpexRXfPJZdcMtfeRpXOOuus8gbae+21Vxo+fHgaN25c/orx3nvvnY/FOWeeeWbVGgsuuGC69NJL87XimjGvmEPMJeYUc4vvTWmpWYRLAAAAAKHDnNJ6q3YgApMIOv71r39VPR7LvU466aQcClUTgdIhhxySrr322prXOPjgg9OIESPKy7uqiX2L+vfvP9dt7+veMS3CmaFDhzb4eR577LG8BKzWfkDRHTR69Oi0ySabNFjn6quvTkcddVSaOXNm1eN9+/ZNY8aMKd+ZrTlFEFfa8DrucuYW9sB3oefwMa09BQDIJp8zoLWnABTElBb4+btdhULhgw8+yN0xEZa8/vrrOQhZfvnl01ZbbZWXf2244YaN1hg7dmwOfiLUiYAnwpLoNDrssMPKy9QaM2vWrBzG/PGPf0wvvPBC+vzzz/Nm1ttuu206+uij57pjWkPi+hdffHH+PJMnTy5vjB17GsUStqWWWqpJdZ599tncmRRL695+++18x7PY/yiWqUU4Vatj6dsSCgGtQSgEQFshFAK+K0Ih2hyhENAahEIAtBVCIaA9//zdbvYUAgAAAKD5CIUAAAAACkgoBAAAAFBAQiEAAACAAhIKA
QAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAXUqbUnAMC313P4mNaeAgAUUtH+Dp58zoDWngLQjHQKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABdSuQ6ETTjghdejQofx1//33N/qev/71r2nIkCFppZVWSl26dMmP8Txeb6pZs2al3/72t2nLLbdMPXr0SAsttFBaY4010mGHHZaee+65JteZOnVqOuWUU9IGG2yQFltssfwV43jtgw8+aHKdZ599Nl875hBziTnF3GKOMVcAAACAujrMmTNnTmqH/vGPf6Q+ffrMFXrcd999aauttqp6/uzZs9Ohhx6aRo4cWbPm0KFD01VXXZU6duzYYJDTv3//9Pjjj1c9HkHTZZddlms15LHHHkuDBw9O7777btXjyy+/fBo9enTq27dvg3WuvvrqdNRRR6WZM2dWPR7vHzNmTFp66aVTS5gyZU
paeeWV8/itt97KIRvw3es5fExrTwEAKIDJ5wxo7SlAYU1pgZ+/22WnUCngiUBomWWWadJ7TjrppHIgtOGGG6Ybb7wxTZgwIT/G83DNNdekk08+uWaNr7/+OncVlQKhXXfdNXcYRcBzySWX5Ll8+eWXuWunoc6j+B9v0KBBORDq1KlTGjZsWHrwwQfzV4zjtXfeeSefE/+j1zJ27Nh0+OGH50Bo2WWXzXOIucS1Y24hPmPMOeYOAAAA0K47hS666KL0i1/8Iq299to58Dj77LMb7BSaNGlSWm+99XKItPHGG+fwJZZZlUyfPj3169cvTZw4MQcyL7zwQurVq1e9Otdee206+OCD8/iII45Il19++VzHX3nllbTRRhuladOm5fdHnahX1/77759+//vf5/HNN9+cdt9997mOx2t77rlnHh9wwAFp1KhR9Wp89dVX+fO/9tprednZk08+mZePVTryyCPTFVdckcfXXXddOvDAA1Nz0ykEbYNOIQDgu6BTCFqPTqGU0ptvvpl+9atf5XHsmdO5c+cmhUilZWaXXnrpXIFQ6NatW349xHkXXnhh1Trnn39+flxyySXTeeedV+94BEEnnnhiOSC6/fbb650T3UE33HBDHu+44471AqGwxx575GMhwqNqS8yidgRCIa5ZNxAKMcfu3buXxwAAAADtNhSK7pfPPvssd9BEd09johHqjjvuyOPorNl0002rnhevr7XWWnkc59dtoIpuo+j8KYU2ESRVU9mNUy0U+stf/pKXv4WDDjqo5rxLdeLceE9dsd9QtWtWijnGXMPzzz+fPwMAAABAuwuFYlnVXXfdlTt1Sl07jXn99dfT22+/nceNhUil4//85z/T5MmT5zo2bty4eudVs9xyy6XevXvn8fjx4+sdb2qdymMN1YkgK675TesAAAAAxVR/w5s26uOPP05HH310Hp977rlNvptWdMiURKdQQyqPR1fQaqut9o3rRFdOrPH7/PPP08I
LL1yvzuKLL95gmBN3H4u9gmJ/olKHUkl0SkXtb/KZ5lVDG12H2BAbAAAAaH/aTSgUd+WKvXU233zz8mbP8xpqNLYJU2nDplAKXb5NnViCFu8rLUurrNOUDaGiznPPPdcscwl16zRF5fsBAACA+Ue7WD720EMP5dvFx528YnPpDh06NPm9n376aXm8yCKLNHhuZUdPdOO0ZJ3GalTWaam5AAAAAMXV5juFZs6cmQ499NDcdRO3of/e9743T+//4osvyuPG7lTWpUuX8njGjBktWqcpd00r1WmpuTRFY91FsXysb9++81wXAAAAaF1tPhT69a9/nV588cW0yiqrpFNPPXWe39+1a9e5AqaGfPnll+Vx3dvW161T+Xxe60yfPr3RuVTWaWwuTalRrU5TNGWZGwAAAND+tOnlYxEGnX322Xl86aWXzrUUqqkWXXTRJi+fik2hay3Lau46TVnKVarTUnMBAAAAiqtNdwpdeOGFuRNm9dVXz901f/rTn+qd8+yzz5bHf//73/Nm1GHQoEE5RKrsdGnsTlqVS6XqbrBct05Ddz8r1Ym9j+p22sTzf/3rX43OpbJO3bmsuOKKc82lKTWq1QEAAACKq02HQqWlT6+99lraa6+9Gj3/jDPOKI9ff/31HAqtu+66c3UeNaTy+DrrrDPXsbp1vv/97zdaJ0KYut1NUeeJJ55In3zySQ6wat2WPvbqidvRV5tLdApF7Qh8vs1nAgAAAIqrTS8faw6rrbZaWmGFFfL4gQceaPDcBx98sNyJ07Nnz7mObbHFFuVxQ3Ui6Jk0aVIeb7755vWON7VO5bGG6rz00kvl7qhvUgcAAAAopjYdCo0aNSrfdayhr8rNp++7777y66VQJ5Zw7bLLLuWumUcffbTqteL1UldNnF/3tve9e/cud9rcfPPNeTlbrTmXDBkypN7xnXfeOXXs+H/f9uuuu67Bzx7i3HhPXYMHD656zUoxx5hrqUMpPgMAAABAmw+F
mssxxxyTFlhggTz+2c9+Vu/W7PE8Xg+dOnXK51dz3HHH5ccPP/wwDRs2rN7xV199tbwxdq9evaqGQrFcbJ999snju+++O9166631zrnlllvysbDffvtVXWIWtWOvpRDXjGvXdfzxx6ePPvqoPAYAAAAoVCgUHTKlUGTixIl5GdVNN92Ux/EYz2Mc4rw111yzap0DDjigvATr8ssvT7vttlsObyZMmJAuu+yytNlmm+V9gKK755JLLskBUzVnnXVW6tGjRx7HXknDhw9P48aNy18x3nvvvfOxOOfMM8+sWmPBBRfMd2SLa8U1Y14xh5hLzCnmdsUVV5SXmkW4BAAAAFDSYU6stWrHTjvttHT66aeXl49ttdVWVc+bPXt2OuSQQ9K1115bs9bBBx+cRowYUV7eVc3UqVNT//790+OPP171eJcuXXI4M3To0Abn/dhjj+UlYLX2A4ruoNGjR6dNNtmkwTpXX311Ouqoo/Jd2qrp27dvGjNmTIN3S/s24u5npbuaxcbXde+2Bnw3eg4f09pTAAAKYPI5A1p7ClBYU1rg5+9CdAqFCHpGjhyZA5LYMyg2n+7cuXN+jOdjx45N11xzTYOBUIhw5eGHH85dONGBs9RSS6WuXbvmpVwROsWdxRoLhEKEPc8880w6+eST0/e+9720yCKL5K/1118/v/bss882GgiF0jXjMeYQc4k5xdyuvPLKNH78+BYLhAAAAID2q913CtG6dApB26BTCAD4LugUgtajUwgAAACAZiEUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAA
AAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAF1Su3AxIkT09ixY9O4cePS888/n95///204IILphVWWCFtvvnm6eCDD05bbLFFk+v99a9/TSNGjEiPP/54rtWjR4/Up0+fdOihh6addtqpSTVmzZqVrrnmmnTDDTekF198MX322Wd5Ptttt136+c9/ntZbb70m1Zk6dWq65JJL0ujRo9PkyZPzaz179kyDBw9ORx99dFpqqaWaVOfZZ59Nl156abrnnnvS22+/nRZZZJG09tprp3322ScNHTo0derULv6nhmbTc/iY1p4CAMB8p2j/xpp8zoDWngK0qA5z5syZk9qwH/7wh+mhhx5q9Lz9998/XX311alz5841z5k9e3YOfkaOHFnznAhQrrrqqtSxY8cGg5z+/fvnUKmaLl26pMsuuyzXashjjz2Ww59333236vHll18+h0V9+/ZtsE587qOOOirNnDmz6vF4/5gxY9LSSy+dmtuUKVPSyiuvnMdvvfVWWmmllZr9GvBNFO0fLAAAND+hEG1JS/z83eaXj0XXS4gunOicufXWW9OECRPSI488kv7rv/4rrbjiivn49ddfnw488MAGa5100knlQG
jDDTdMN954Y64Vj/E8RPfPySefXLPG119/nYYMGVIOhHbdddfceRQBT3T8LLPMMunLL79Mhx12WH69lvgfcNCgQTkQii6eYcOGpQcffDB/xThee+edd/I58T98LdFBdfjhh+dAaNlll81ziLnEtWNuIT5jzDnmDgAAANAuOoUGDhyYu4B+9KMfpQUWWKBq104sIZs0aVJ+/sADD+TuorrieCzpimVfG2+8cQ5fFlpoofLx6dOnp379+uWlahHIvPDCC6lXr1716lx77bV5uVo44ogj0uWXXz7X8VdeeSVttNFGadq0afn9Uafa0q34TL///e/z+Oabb0677777XMfjtT333DOPDzjggDRq1Kh6Nb766qu8ROy1115Liy22WHryySfTGmusMdc5Rx55ZLriiivy+Lrrrms0OJtXOoVoq3QKAQDwbekUoi0pZKfQXXfdlfbYY4+qgVCIJVEXXHBB+Xl0ElVz0UUX5UAoxN47lYFQ6NatW349xHkXXnhh1Trnn39+flxyySXTeeedV+94BEEnnnhiOSC6/fbb650T3UGxF1HYcccd6wVCIT5zHAsRHlVbYha1IxAKcc26gVCIOXbv3r08BgAAAGgXoVBTbL311uXxq6++Wu94NEPdcccdeRydNZtuumnVOvH6Wmutlcdxft0mqug2is6fUmgTQVI1ld041UKhv/zlL3l/o3DQQQfV/FylOnFuvKeu2G+o2jUrxRxjriE26S51VAEAAADFNl+EQrGHT0m1jqLXX3+9vDdRLBFrSOn4P//5z/LdwEri7md1z6tmueWWS717987j8ePH1zve1DqVxxqqE0FWXPOb1gEAAACKZ764T3nsI1Syzjrr1DseHTIl0SnUkMrj0RW02mqrfeM60ZUT6/w+//zztPDCC9ers/jiizcY5sTdx2KvoNifqNShVPLZZ5/l2t/kM82Lhja5DrEZNgAAAND+tPtQKJZWnXPOOeXnpaVStYKNxjZiKm3
aFEqhy7epE0vQ4n2lZWmVdZqyKVTUee6555plLqFunaZcHwAAAJj/tPvlY7EhdNxyPcQt2OPOX3V9+umn5fEiiyzSYL3Kjp7oxmnJOo3VqKzTUnMBAAAAiqlTe182Nnz48DxeZpll0pVXXln1vC+++KI87ty5c4M1u3TpUh7PmDGjRes0VqOyTkvNpTGNdRbF8rG+ffvOU00AAACg9bXbUCiWVA0ZMiTfPr5r167plltuycFQNXG8ZObMmU3etLrubevr1ql8Pq91pk+f3uhcKus0Npem1KhWpzFNWeIGAAAAtD/tcvlY3E1shx12SB999FG+29if/vSn9MMf/rDm+YsuumiTl0/FptC1lmU1d52mLOUq1WmpuQAAAADF1O5Cobi1/HbbbZcfO3TokK699tq0yy67NLnbpbG7aVUul6q7yfI3qRNzrNttU3reWI3KOnXnsuKKK87zXKrVAQAAAIqpXYVCU6dOTdtvv3167bXX8vNLL7007b///o2+b9111y2PX3zxxQbPrTxe9/b236ROhDCVGz1X1vnkk0/Su+++2+B+PXE7+mpziU6hUsDzbT4TAAAAUEztJhSKAGXHHXdMzz//fH4et6E/8sgjm/Te1VZbLa2wwgrlzakb8uCDD5Y7cXr27DnXsS222KI8bqhOBD2TJk3K480337ze8abWqTzWUJ2XXnqpwXCpsToAAABA8bSLUCg2ZR4wYEB68skn8/OTTjopnXDCCU1+fyzhKi0xi66ZRx99tOp58XqpqybOj/dV6t27d7nT5uabb87zqmbUqFHlcWyGXdfOO++cOnb8v2/9ddddV3PepTpxbrynrsGDB1e9ZqWYY8y11KEUnwEAAACgzYdCcWetCFbGjx+fnx999NHpzDPPnOc6xxxzTN6UOvzsZz+rd2v2eB6vh06dOuXzqznuuOPy44cffpiGDRtW7/irr76azj777Dzu1atX1VBoueWWS/vss08e33333enWW2+t
d07cTS2Ohf322y+/p66ovfrqq+dxXDOuXdfxxx+fN+QujQEAAABChzlz5sxpy9+KH/3oR+m2227L42222SZddNFF9Tp4KnXu3LlmN8yJJ56Yl52FDTfcMHcbrbHGGjlMOffcc9NTTz1VPu/Xv/511Rpff/116tevXzmkivkdcsghqXv37mnChAnpjDPOSO+9917u7rnrrrvSTjvtVHPz54022ii9//77OYQ69thj08CBA/OxeN8FF1yQZs2alXr06JE7pGrdGn7s2LFp0KBBafbs2WnZZZdNJ598curbt28Ogq6++ur05z//ubzU7P777y8HY80lNrku7W0Un8kt7Gkreg4f09pTAACgnZt8zoDWngK06M/fbT4UaigAqmbVVVdNkydPrnosgpMIcOKOZbUcfPDBacSIEeXlXbU2vO7fv396/PHHqx7v0qVLuuyyy9LQoUMbnOtjjz2Wl4DV2g8ouoNGjx6dNtlkkwbrRPhz1FFH5a6qaiIkGjNmTFp66aVTcxMK0VYJhQAA+LaEQrQlLfHzd5tfPtacIugZOXJkDkhiz6DYfDo6i+IxnkfXzTXXXNNgIBQiXHn44YfTFVdckTtwllpqqdS1a9e8lCtCpyeeeKLRQChE2PPMM8/k7p7vfe97aZFFFslf66+/fn7t2WefbTQQCqVrxmPMIeYSc4q5XXnllbmrqSUCIQAAAKD9avOdQrRtOoVoq3QKAQDwbekUoi3RKQQAAABAsxAKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAA
ACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFFCn1p4AAAAAtEU9h49JRTP5nAGtPQW+Q0IhKIgi/oUGAABAbZaPAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhQAAAAAKSCgEAAAAUEBCIQAAAIACEgoBAAAAFJBQCAAAAKCAhEIAAAAABSQUAgAAACggoRAAAABAAQmFAAAAAApIKAQAAABQQEIhAAAAgAISCgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCChEAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABRQp9aeALSWnsPHtPYUAAAA2pSi/Zw0+ZwBqch0CgEAAAAUkFAIAAAAoICEQgAAAAAFJBQCAAAAKCCh0HzkjTfeSMcee2xae+2108ILL5yWXHLJ1KdPn3Teeeel6dOnt/b0AAAAgDbE3cfmE3feeWfad99907Rp08qvRRA0ceLE/HXNNdekMWPGpF69erXqPAEAAIC2QafQfOCpp55Ke+65Zw6EFllkkXTWWWelhx9+ON17773pkEMOyedMmjQpDRgwIH366aetPV0AAACgDdApNB84+uij04wZM1KnTp3S3/72t/SDH/ygfGybbbZJa665Zho2bFgOhi644IJ02mmntep8AQAAgNanU6idmzBhQnrooYfy+OCDD54rECqJfYbWWWedPL744ovTV1999Z3PEwAAAGhbhELt3OjRo8vjgw46qOo5HTt2TPvvv38ef/zxx+m+++77zuYHAAAAtE1CoXZu3Lhx+THuNrbRRhvVPK9fv37l8fjx47+TuQEAAABtl1ConXvhhRfyY9xVLPYUqiVuU1/3PQAAAEBx2Wi6Hfviiy/S1KlT83illVZq8Nzu3bvnbqLPP/88vfXWW02+xpQpUxo8XlnrnXfeSe3JrGn/970DAACgmK
Y08jNvW1L5M/esWbOapaZQqB2rvL183Iq+MaVQ6LPPPmvyNVZeeeUmn9u3b98mnwsAAACtbeUrU7v0/vvvp549e37rOpaPtfNOoZLOnTs3en6XLl3yY9y+HgAAACg2nULtWNeuXcvjmTNnNnr+l19+mR8XWmihJl+jsaVmEUy9+OKLadlll009evRocF+jttRyV+pqmjBhQlp++eVbe0rMB/y5oqX4s0VL8OeKluDPFS3BnytaSnv8szVr1qzcIRTWX3/9ZqnZ9n+Cp6ZFF120PG7KkrBYOtbUpWYlje1VVNrkur2K/+M35TPCvPDnipbizxYtwZ8rWoI/V7QEf65oKcu3oz9bzbFkrJLlY+28U2ippZZq0uZYH330UTkUmpd9ggAAAID5k1ConVt33XXz4yuvvNLg7uOxxKtknXXW+U7mBgAAALRdQqF2bosttsiP0QX0xBNP1DzvgQceKI8333zz72RuAAAAQNslFGrnBg8eXB5fd911Vc+ZPXt2uv766/N4iSWWSFtvvfV3Nj8AAACgbRIKtXOxW/qWW26ZxyNHjkyPPPJIvXMuuOCC9MILL+Tx0UcfnRZccMHvfJ4AAABA2+LuY/OBiy++OC8JmzFjRtphhx3SL3/5y9wNFM//9Kc/pREjRuTzevfunY499tjWni4AAADQBgiF5gMbbrhhuummm9K+++6bpk2blkOhuiIQGjNmzFy3sQcAAACKq8OcOXPmtPYkaB5vvPFG7hqK8CduUd+5c+fUq1evtPvuu6ejjjoqdevWrbWnCAAAALQRQiEAAACAArLRNAAAAEABCYUAAAAACkgoBAAAAFBAQiEAAACAAhIKAQAAABSQUAgAAACggIRCAAAAAAUkFAIAAAAoIKEQAAAAQAEJhaDCmDFj0mmnnZYGDBiQ1llnnbT00kunBRdcMHXv3j1ttNFG6dhjj00vvfRSa0+Tdmjy5Mnp0ksvTT/60Y/Smmuumbp165a6du2aVlp
ppTR48OD0pz/9Kc2aNau1p0k789lnn6UHH3wwnX/++WmPPfZIq622WurQoUP+6tmzZ2tPjzbqjTfeyH+frb322mnhhRdOSy65ZOrTp08677zz0vTp01t7erQj7733XrrrrrvSKaecknbaaaf876bSf4MOPPDA1p4e7djEiRPTf/7nf6Yddtgh/1upS5cuaZFFFkm9e/dOBx10UBo3blxrT5F2Ztq0afnf2/H3X79+/VKvXr3S4osvnjp37pyWWWaZtNVWW6Xf/OY36YMPPkhF02HOnDlzWnsS0BbED+QRADUmzom/pIYPH/6dzIv271e/+lU666yzUmP/uY0fym699da0yiqrfGdzo33beuut0/3331/12KqrrprDSKh05513pn333Tf/47ia+IErfkES/1iGxkT4U8sBBxyQRo0a9Z3Oh/nDD3/4w/TQQw81et7++++frr766vxDPTTmnnvuSdtvv32j5y299NLpD3/4Q9pxxx1TUXRq7QlAWxJpcaTEm2yySVp99dXT8ssvnzs63n777fyD17XXXps++eSTdOKJJ6YlllgiHX744a09ZdqBd955JwdC8Rv5IUOGpG233TZ3C0Wn0AsvvJAuueSS9Pjjj+ev7bbbLj355JP5t2HQmMqgMbo9Nt544/Twww/nDiKo66mnnkp77rlnmjFjRv5vTPxdFsFiPI/fnsYPV5MmTcrdsvFb+kUXXbS1p0w7Er/QiO6zv/3tb609Fdq5+Hd3WGGFFdLuu++ettxyy/zn6+uvv06PPPJIuuCCC9I///nPdP3116evvvoq/fGPf2ztKdNOrLzyyvnvvVgBEuP4WW/27NlpypQp+Rezt912W5o6dWraeeed04QJE9K//du/pSLQKQQV4i+bBRZYoObx119/Pf9H5KOPPko9evTIP+w3dD6EE044IS211FLppz/9adUfsuLP3d57751uvvnm/Pz000/PrfjQmBEjRuQ/U9FlVursiGVjsTxI
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",
"text/plain": [
- "<Figure size 432x288 with 1 Axes>"
+ "<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"image/png": {
- "height": 248,
- "width": 394
- },
- "needs_background": "light"
+ "height": 413,
+ "width": 578
+ }
},
"output_type": "display_data"
}
@@ -158,13 +157,20 @@
"if demo_file.is_file():\n",
" demo_file.unlink()"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": "scikit-hep-tutorials",
+ "display_name": "boost-hist",
"language": "python",
- "name": "scikit-hep-tutorials"
+ "name": "boost-hist"
},
"language_info": {
"codemirror_mode": {
@@ -176,7 +182,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.6"
+ "version": "3.12.8"
}
},
"nbformat": 4,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/noxfile.py
new/boost_histogram-1.5.1/noxfile.py
--- old/boost_histogram-1.5.0/noxfile.py 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/noxfile.py 2022-11-09 13:37:21.000000000
+0100
@@ -2,44 +2,55 @@
import argparse
from pathlib import Path
+from typing import Any
import nox
-nox.needs_version = ">=2024.3.2"
+nox.needs_version = ">=2024.4.15"
nox.options.default_venv_backend = "uv|virtualenv"
-nox.options.sessions = ["lint", "tests"]
[email protected]
+def _get_group(name: str, groups: dict[str, Any]) -> list[str]:
+ group = groups[name]
+ return [d if isinstance(d, str) else _get_group(d, groups) for d in group]
+
+
+def dependency_groups(pyproject: dict[str, Any], *names: str) -> list[str]:
+ groups = pyproject["dependency-groups"]
+ return [item for name in names for item in _get_group(name, groups)]
+
+
def tests(session: nox.Session) -> None:
"""
Run the unit and regular tests.
"""
-
- session.install(".[test]")
+ pyproject = nox.project.load_toml("pyproject.toml")
+ session.install(".", *dependency_groups(pyproject, "test"))
session.run("pytest", *session.posargs)
[email protected]
[email protected](default=False)
def hist(session: nox.Session) -> None:
"""
Run Hist's test suite
"""
+ pyproject = nox.project.load_toml("pyproject.toml")
session.install(".")
tmpdir = session.create_tmp()
session.chdir(tmpdir)
session.run("git", "clone", "https://github.com/scikit-hep/hist",
external=True)
session.chdir("hist")
- session.install(".[test,plot]")
+ session.install(".", *dependency_groups(pyproject, "test", "plot"))
session.run("pip", "list")
session.run("pytest", *session.posargs)
[email protected](reuse_venv=True)
[email protected](reuse_venv=True, default=False)
def docs(session: nox.Session) -> None:
"""
Build the docs. Pass --non-interactive to avoid serving. Pass "-b
linkcheck" to check links.
"""
+ pyproject = nox.project.load_toml("pyproject.toml")
parser = argparse.ArgumentParser()
parser.add_argument(
@@ -49,7 +60,7 @@
serve = args.builder == "html" and session.interactive
extra_installs = ["sphinx-autobuild"] if serve else []
- session.install("-r", "docs/requirements.txt", *extra_installs)
+ session.install(*dependency_groups(pyproject, "docs"), *extra_installs)
shared_args = (
"-n", # nitpicky mode
@@ -67,13 +78,14 @@
session.run("sphinx-build", "--keep-going", *shared_args)
[email protected]
[email protected](default=False)
def build_api_docs(session: nox.Session) -> None:
"""
Build (regenerate) API docs.
"""
+ pyproject = nox.project.load_toml("pyproject.toml")
- session.install(".", "-r", "docs/requirements.txt")
+ session.install(*dependency_groups(pyproject, "docs"))
session.run(
"sphinx-apidoc",
"-o",
@@ -121,10 +133,11 @@
session.run("pylint", "boost_histogram", *session.posargs)
[email protected]
[email protected](default=False)
def make_pickle(session: nox.Session) -> None:
"""
Make a pickle file for this version
"""
- session.install(".[dev]")
+ pyproject = nox.project.load_toml("pyproject.toml")
+ session.install(".", *dependency_groups(pyproject, "dev"))
session.run("python", "tests/pickles/make_pickle.py", *session.posargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/pyproject.toml
new/boost_histogram-1.5.1/pyproject.toml
--- old/boost_histogram-1.5.0/pyproject.toml 2022-11-09 13:37:21.000000000
+0100
+++ new/boost_histogram-1.5.1/pyproject.toml 2022-11-09 13:37:21.000000000
+0100
@@ -50,27 +50,37 @@
"numpy",
]
-[project.optional-dependencies]
+[project.urls]
+"Bug Tracker" = "https://github.com/scikit-hep/boost-histogram/issues"
+Changelog = "https://boost-histogram.readthedocs.io/en/latest/CHANGELOG.html"
+Chat = " https://gitter.im/HSF/PyHEP-histogramming"
+Discussions = "https://github.com/scikit-hep/boost-histogram/discussions"
+Documentation = "https://boost-histogram.readthedocs.io/"
+Homepage = "https://github.com/scikit-hep/boost-histogram"
+
+[dependency-groups]
dev = [
- "cloudpickle",
- "hypothesis>=6.0",
+ { include-group = "test" },
"ipykernel",
- "pytest-benchmark",
- "pytest>=6.0",
+ "nbconvert",
+ "numpy",
+ "setuptools_scm",
"typer",
]
docs = [
+ "ipython",
"myst_parser>=0.13",
"nbsphinx",
+ "numpy",
"sphinx-book-theme>=0.0.33",
- "Sphinx>=4.0",
+ "sphinx>=4.0",
"sphinx_copybutton",
]
examples = [
"matplotlib",
"netCDF4",
"numba",
- "uproot3",
+ "uproot",
"xarray",
"xhistogram",
]
@@ -81,14 +91,6 @@
"pytest>=6.0",
]
-[project.urls]
-"Bug Tracker" = "https://github.com/scikit-hep/boost-histogram/issues"
-Changelog = "https://boost-histogram.readthedocs.io/en/latest/CHANGELOG.html"
-Chat = " https://gitter.im/HSF/PyHEP-histogramming"
-Discussions = "https://github.com/scikit-hep/boost-histogram/discussions"
-Documentation = "https://boost-histogram.readthedocs.io/"
-Homepage = "https://github.com/scikit-hep/boost-histogram"
-
[tool.scikit-build]
minimum-version = "build-system.requires"
@@ -159,7 +161,7 @@
[tool.cibuildwheel]
build-frontend = "build[uv]"
-test-extras = "test"
+test-groups = ["test"]
test-command = "pytest --benchmark-disable {project}/tests"
skip = [
"pp38-*",
@@ -168,18 +170,18 @@
"cp*-musllinux_*", # Segfaults
"cp313t-*win*",
]
-free-threaded-support = true
+enable = ["cpython-freethreading", "pypy"]
environment-pass = ["SETUPTOOLS_SCM_PRETEND_VERSION"]
environment.PIP_ONLY_BINARY = "numpy"
environment.PIP_PREFER_BINARY = "1"
[[tool.cibuildwheel.overrides]]
select = "*pyodide*"
-inherit.environment = "append"
build-frontend = {name = "build", args = ["--exports", "whole_archive"]}
[[tool.cibuildwheel.overrides]]
select = "pp310-macosx_arm64"
+inherit.environment = "append"
environment.MACOSX_DEPLOYMENT_TARGET = "14.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/__init__.py
new/boost_histogram-1.5.1/src/boost_histogram/__init__.py
--- old/boost_histogram-1.5.0/src/boost_histogram/__init__.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/__init__.py 2022-11-09
13:37:21.000000000 +0100
@@ -32,16 +32,16 @@
"Histogram",
"IndexingExpr",
"Kind",
- "axis",
- "storage",
+ "__version__",
"accumulators",
- "numpy",
+ "axis",
"loc",
+ "numpy",
+ "overflow",
"rebin",
+ "storage",
"sum",
"underflow",
- "overflow",
- "__version__",
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/_internal/axis.py
new/boost_histogram-1.5.1/src/boost_histogram/_internal/axis.py
--- old/boost_histogram-1.5.0/src/boost_histogram/_internal/axis.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/_internal/axis.py
2022-11-09 13:37:21.000000000 +0100
@@ -38,7 +38,7 @@
# Contains common methods and properties to all axes
@set_module("boost_histogram.axis")
class Axis:
- __slots__ = ("_ax", "__dict__")
+ __slots__ = ("__dict__", "_ax")
_family: object
def __init_subclass__(cls, *, family: object) -> None:
@@ -234,21 +234,21 @@
@property
def edges(self) -> np.typing.NDArray[Any]:
- return self._ax.edges # type: ignore[no-any-return]
+ return self._ax.edges
@property
def centers(self) -> np.typing.NDArray[Any]:
"""
An array of bin centers.
"""
- return self._ax.centers # type: ignore[no-any-return]
+ return self._ax.centers
@property
def widths(self) -> np.typing.NDArray[Any]:
"""
An array of bin widths.
"""
- return self._ax.widths # type: ignore[no-any-return]
+ return self._ax.widths
# Contains all common methods and properties for Regular axes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/_internal/hist.py
new/boost_histogram-1.5.1/src/boost_histogram/_internal/hist.py
--- old/boost_histogram-1.5.0/src/boost_histogram/_internal/hist.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/_internal/hist.py
2022-11-09 13:37:21.000000000 +0100
@@ -72,11 +72,11 @@
Convert to NumPy arrays. Some buffer objects do not get converted by
forcecast.
If not called by itself (inner=False), then will work through one level of
tuple/list.
"""
- if value is None or isinstance(value, (str, bytes)): # type:
ignore[redundant-expr]
- return value # type: ignore[return-value]
+ if value is None or isinstance(value, (str, bytes)):
+ return value
if not inner and isinstance(value, (tuple, list)):
- return tuple(_fill_cast(a, inner=True) for a in value) # type:
ignore[misc]
+ return tuple(_fill_cast(a, inner=True) for a in value)
if hasattr(value, "__iter__") or hasattr(value, "__array__"):
return np.asarray(value)
@@ -136,9 +136,9 @@
class Histogram:
# Note this is a __slots__ __dict__ class!
__slots__ = (
+ "__dict__",
"_hist",
"axes",
- "__dict__",
)
# .metadata and ._variance_known are part of the dict
@@ -366,7 +366,7 @@
kwargs = {}
if copy is not None:
kwargs["copy"] = copy
- return np.asarray(self.view(False), dtype=dtype, **kwargs) # type:
ignore[no-any-return, call-overload]
+ return np.asarray(self.view(False), dtype=dtype, **kwargs) # type:
ignore[call-overload]
def __eq__(self, other: Any) -> bool:
return hasattr(other, "_hist") and self._hist == other._hist
@@ -508,7 +508,7 @@
threads = cpu_count()
if threads is None or threads == 1:
- self._hist.fill(*args_ars, weight=weight_ars, sample=sample_ars)
# type: ignore[arg-type]
+ self._hist.fill(*args_ars, weight=weight_ars, sample=sample_ars)
return self
if self._hist._storage_type in {
@@ -518,7 +518,7 @@
raise RuntimeError("Mean histograms do not support threaded
filling")
data: list[list[np.typing.NDArray[Any]] | list[str]] = [
- np.array_split(a, threads) if not isinstance(a, str) else [a] *
threads # type: ignore[arg-type, list-item]
+ np.array_split(a, threads) if not isinstance(a, str) else [a] *
threads
for a in args_ars
]
@@ -527,14 +527,14 @@
assert threads is not None
weights = [weight_ars] * threads
else:
- weights = np.array_split(weight_ars, threads) # type:
ignore[arg-type]
+ weights = np.array_split(weight_ars, threads)
samples: list[Any]
if sample_ars is None or np.isscalar(sample_ars):
assert threads is not None
samples = [sample_ars] * threads
else:
- samples = np.array_split(sample_ars, threads) # type:
ignore[arg-type]
+ samples = np.array_split(sample_ars, threads)
if self._hist._storage_type is _core.storage.atomic_int64:
@@ -767,7 +767,7 @@
hist, *edges = self._hist.to_numpy(flow)
hist = self.view(flow=flow) if view else self.values(flow=flow)
- return (hist, edges) if dd else (hist, *edges) # type:
ignore[return-value]
+ return (hist, edges) if dd else (hist, *edges)
def copy(self: H, *, deep: bool = True) -> H:
"""
@@ -921,9 +921,9 @@
for new_j, group in enumerate(groups):
for _ in range(group):
pos = [slice(None)] * (i)
- new_view[(*pos, new_j + 1, ...)] += reduced_view[
# type: ignore[arg-type]
- (*pos, j, ...) # type: ignore[arg-type]
- ]
+ new_view[(*pos, new_j + 1, ...)] += _to_view(
+ reduced_view[(*pos, j, ...)]
+ )
j += 1
reduced = new_reduced
@@ -1026,9 +1026,9 @@
# Support raw arrays for accumulators, the final dimension is the
constructor values
if (
value.ndim > 0
- and len(view.dtype) > 0 # type: ignore[arg-type]
- and len(value.dtype) == 0 # type: ignore[arg-type]
- and len(view.dtype) == value.shape[-1] # type: ignore[arg-type]
+ and len(view.dtype) > 0
+ and len(value.dtype) == 0
+ and len(view.dtype) == value.shape[-1]
):
value_shape = value.shape[:-1]
value_ndim = value.ndim - 1
@@ -1101,7 +1101,7 @@
for arg in args:
if arg < 0 or arg >= self.ndim:
raise ValueError(
- f"Projection axis must be a valid axis number 0 to
{self.ndim-1}, not {arg}"
+ f"Projection axis must be a valid axis number 0 to
{self.ndim - 1}, not {arg}"
)
return self._new_hist(self._hist.project(*args))
@@ -1139,9 +1139,9 @@
view = self.view(flow)
# TODO: Might be a NumPy typing bug
- if len(view.dtype) == 0: # type: ignore[arg-type]
+ if len(view.dtype) == 0:
return view
- return view.value # type: ignore[union-attr]
+ return view.value
def variances(self, flow: bool = False) -> np.typing.NDArray[Any] | None:
"""
@@ -1168,13 +1168,13 @@
"""
view = self.view(flow)
- if len(view.dtype) == 0: # type: ignore[arg-type]
+ if len(view.dtype) == 0:
return view if self._variance_known else None
if hasattr(view, "sum_of_weights"):
valid = view.sum_of_weights**2 > view.sum_of_weights_squared #
type: ignore[union-attr]
return np.divide(
- view.variance, # type: ignore[union-attr]
+ view.variance,
view.sum_of_weights,
out=np.full(view.sum_of_weights.shape, np.nan),
where=valid,
@@ -1182,13 +1182,13 @@
if hasattr(view, "count"):
return np.divide(
- view.variance, # type: ignore[union-attr]
+ view.variance,
view.count,
out=np.full(view.count.shape, np.nan),
where=view.count > 1,
)
- return view.variance # type: ignore[union-attr]
+ return view.variance
def counts(self, flow: bool = False) -> np.typing.NDArray[Any]:
"""
@@ -1215,7 +1215,7 @@
view = self.view(flow)
- if len(view.dtype) == 0: # type: ignore[arg-type]
+ if len(view.dtype) == 0:
return view
if hasattr(view, "sum_of_weights"):
@@ -1229,7 +1229,7 @@
if hasattr(view, "count"):
return view.count
- return view.value # type: ignore[union-attr]
+ return view.value
if TYPE_CHECKING:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/_internal/typing.py
new/boost_histogram-1.5.1/src/boost_histogram/_internal/typing.py
--- old/boost_histogram-1.5.0/src/boost_histogram/_internal/typing.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/_internal/typing.py
2022-11-09 13:37:21.000000000 +0100
@@ -20,12 +20,12 @@
__all__ = (
- "CppHistogram",
- "AxisLike",
"ArrayLike",
- "Ufunc",
+ "AxisLike",
+ "CppHistogram",
"StdIndex",
"StrIndex",
+ "Ufunc",
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/_internal/view.py
new/boost_histogram-1.5.1/src/boost_histogram/_internal/view.py
--- old/boost_histogram-1.5.0/src/boost_histogram/_internal/view.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/_internal/view.py
2022-11-09 13:37:21.000000000 +0100
@@ -7,7 +7,7 @@
from ..accumulators import Mean, WeightedMean, WeightedSum
from .typing import ArrayLike, StrIndex, Ufunc
-UFMethod = Literal["__call__", "reduce", "reduceat", "accumulate", "outer",
"inner"]
+UFMethod = Literal["__call__", "reduce", "reduceat", "accumulate", "outer",
"at"]
class View(np.ndarray): # type: ignore[type-arg]
@@ -16,11 +16,11 @@
_PARENT: type[WeightedSum] | type[WeightedMean] | type[Mean]
def __getitem__(self, ind: StrIndex) -> np.typing.NDArray[Any]: # type:
ignore[override]
- sliced = super().__getitem__(ind) # type: ignore[index]
+ sliced = super().__getitem__(ind)
# If the shape is empty, return the parent type
if not sliced.shape:
- return self._PARENT._make(*sliced) # type: ignore[unreachable]
+ return self._PARENT._make(*sliced)
# If the dtype has changed, return a normal array (no longer a record)
if sliced.dtype != self.dtype:
@@ -41,24 +41,24 @@
def __setitem__(self, ind: StrIndex, value: ArrayLike) -> None:
# `.value` really is ["value"] for an record array
if isinstance(ind, str):
- super().__setitem__(ind, value) # type: ignore[no-untyped-call]
+ super().__setitem__(ind, value)
return
- current_ndim = super().__getitem__(ind).ndim # type: ignore[index]
+ current_ndim = super().__getitem__(ind).ndim
array: np.typing.NDArray[Any] = np.asarray(value)
msg = "Needs matching ndarray or n+1 dim array"
if array.ndim == current_ndim + 1:
if len(self._FIELDS) == array.shape[-1]:
- self.__setitem__(ind, self._PARENT._array(*np.moveaxis(array,
-1, 0))) # type: ignore[assignment]
+ self.__setitem__(ind, self._PARENT._array(*np.moveaxis(array,
-1, 0)))
return
msg += f", final dimension should be {len(self._FIELDS)} for this
storage, got {array.shape[-1]} instead"
raise ValueError(msg)
if self.dtype == array.dtype:
- super().__setitem__(ind, array) # type: ignore[no-untyped-call]
+ super().__setitem__(ind, array)
return
- msg += f", {current_ndim}D {self.dtype} or {current_ndim+1}D required,
got {array.ndim}D {array.dtype}"
+ msg += f", {current_ndim}D {self.dtype} or {current_ndim + 1}D
required, got {array.ndim}D {array.dtype}"
raise ValueError(msg)
@@ -131,7 +131,7 @@
ufunc(raw_inputs[0]["value"], out=result["value"], **kwargs)
result["variance"] = raw_inputs[0]["variance"]
- return result.view(self.__class__) # type: ignore[no-any-return]
+ return result.view(self.__class__)
if method == "__call__" and len(raw_inputs) == 2:
(result,) = (
@@ -155,11 +155,11 @@
out=result["variance"],
**kwargs,
)
- return result.view(self.__class__) # type:
ignore[no-any-return]
+ return result.view(self.__class__)
# If unsupported, just pass through (will return not
implemented)
# pylint: disable-next=no-member
- return super().__array_ufunc__(ufunc, method, *raw_inputs,
**kwargs) # type: ignore[no-any-return]
+ return super().__array_ufunc__(ufunc, method, *raw_inputs,
**kwargs)
# View with normal value or array
if ufunc in {np.add, np.subtract}:
@@ -189,7 +189,7 @@
out=result["variance"],
**kwargs,
)
- return result.view(self.__class__) # type:
ignore[no-any-return]
+ return result.view(self.__class__)
if ufunc in {np.multiply, np.divide, np.true_divide,
np.floor_divide}:
if self.dtype == raw_inputs[0].dtype:
@@ -219,12 +219,12 @@
**kwargs,
)
- return result.view(self.__class__) # type:
ignore[no-any-return]
+ return result.view(self.__class__)
# ufuncs that are allowed to reduce
if ufunc in {np.add} and method == "reduce" and len(raw_inputs) == 1:
results = (ufunc.reduce(self[field], **kwargs) for field in
self._FIELDS)
- return self._PARENT._make(*results) # type: ignore[return-value]
+ return self._PARENT._make(*results)
# ufuncs that are allowed to accumulate
if ufunc in {np.add} and method == "accumulate" and len(raw_inputs) ==
1:
@@ -235,11 +235,11 @@
)
for field in self._FIELDS:
ufunc.accumulate(self[field], out=result[field], **kwargs)
- return result.view(self.__class__) # type: ignore[no-any-return]
+ return result.view(self.__class__)
# If unsupported, just pass through (will return NotImplemented or
things like == will work but not return subclasses)
# pylint: disable-next=no-member
- return super().__array_ufunc__(ufunc, method, *raw_inputs, **kwargs)
# type: ignore[no-any-return]
+ return super().__array_ufunc__(ufunc, method, *raw_inputs, **kwargs)
@fields(
@@ -260,7 +260,7 @@
@property
def variance(self) -> np.typing.NDArray[Any]:
with np.errstate(divide="ignore", invalid="ignore"):
- return self["_sum_of_weighted_deltas_squared"] / ( # type:
ignore[no-any-return]
+ return self["_sum_of_weighted_deltas_squared"] / (
self["sum_of_weights"]
- self["sum_of_weights_squared"] / self["sum_of_weights"]
)
@@ -279,7 +279,7 @@
@property
def variance(self) -> np.typing.NDArray[Any]:
with np.errstate(divide="ignore", invalid="ignore"):
- return self["_sum_of_deltas_squared"] / (self["count"] - 1) #
type: ignore[no-any-return]
+ return self["_sum_of_deltas_squared"] / (self["count"] - 1)
def _to_view(
@@ -289,6 +289,6 @@
if item.dtype.names == cls._FIELDS:
ret = item.view(cls)
if value and ret.shape:
- return ret.value # type: ignore[no-any-return,attr-defined]
+ return ret.value
return ret
return item
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/accumulators.py
new/boost_histogram-1.5.1/src/boost_histogram/accumulators.py
--- old/boost_histogram-1.5.0/src/boost_histogram/accumulators.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/accumulators.py
2022-11-09 13:37:21.000000000 +0100
@@ -8,7 +8,7 @@
)
from ._internal.typing import Accumulator
-__all__ = ("Sum", "Mean", "WeightedSum", "WeightedMean", "Accumulator")
+__all__ = ("Accumulator", "Mean", "Sum", "WeightedMean", "WeightedSum")
for cls in (Sum, Mean, WeightedSum, WeightedMean):
cls.__module__ = "boost_histogram.accumulators"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/axis/__init__.py
new/boost_histogram-1.5.1/src/boost_histogram/axis/__init__.py
--- old/boost_histogram-1.5.0/src/boost_histogram/axis/__init__.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/axis/__init__.py
2022-11-09 13:37:21.000000000 +0100
@@ -14,15 +14,15 @@
from . import transform
__all__ = (
- "Regular",
- "Variable",
- "Integer",
+ "ArrayTuple",
+ "AxesTuple",
+ "Axis",
+ "Boolean",
"IntCategory",
+ "Integer",
+ "Regular",
"StrCategory",
- "Boolean",
- "Axis",
"Traits",
+ "Variable",
"transform",
- "ArrayTuple",
- "AxesTuple",
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/boost_histogram-1.5.0/src/boost_histogram/axis/transform.py
new/boost_histogram-1.5.1/src/boost_histogram/axis/transform.py
--- old/boost_histogram-1.5.0/src/boost_histogram/axis/transform.py
2022-11-09 13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/axis/transform.py
2022-11-09 13:37:21.000000000 +0100
@@ -7,7 +7,7 @@
_internal_conversion,
)
-__all__ = ("AxisTransform", "Pow", "Function", "sqrt", "log")
+__all__ = ("AxisTransform", "Function", "Pow", "log", "sqrt")
sqrt = Function("_sqrt_fn", "_sq_fn", convert=_internal_conversion,
name="sqrt")
log = Function("_log_fn", "_exp_fn", convert=_internal_conversion, name="log")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/src/boost_histogram/numpy.py
new/boost_histogram-1.5.1/src/boost_histogram/numpy.py
--- old/boost_histogram-1.5.0/src/boost_histogram/numpy.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/numpy.py 2022-11-09
13:37:21.000000000 +0100
@@ -39,8 +39,7 @@
storage: _storage.Storage = _storage.Double(), # noqa: B008
threads: int | None = None,
) -> Any:
- # TODO: Might be a bug in MyPy? This should type
- cls: type[_hist.Histogram] = _hist.Histogram if histogram is None else
histogram # type: ignore[assignment]
+ cls: type[_hist.Histogram] = _hist.Histogram if histogram is None else
histogram
if normed is not None:
raise KeyError(
@@ -72,7 +71,7 @@
if r is None:
# Nextafter may affect bin edges slightly
r = (np.amin(a[n]), np.amax(a[n])) # noqa: PLW2901
- if r[0] == r[1]:
+ if r[0] == r[1]: # type: ignore[operator]
r = (r[0] - 0.5, r[1] + 0.5) # noqa: PLW2901
new_ax = _axis.Regular(
typing.cast(int, b), r[0], r[1], underflow=False,
overflow=False
@@ -160,7 +159,7 @@
# I think it's safe and the union is in the wrong place
result = histogramdd(
(a,),
- (bins,), # type: ignore[arg-type]
+ (bins,),
(range,),
normed,
weights,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/src/boost_histogram/storage.py
new/boost_histogram-1.5.1/src/boost_histogram/storage.py
--- old/boost_histogram-1.5.0/src/boost_histogram/storage.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/storage.py 2022-11-09
13:37:21.000000000 +0100
@@ -12,12 +12,12 @@
)
__all__ = (
- "Storage",
- "Int64",
- "Double",
"AtomicInt64",
+ "Double",
+ "Int64",
+ "Mean",
+ "Storage",
"Unlimited",
"Weight",
- "Mean",
"WeightedMean",
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/src/boost_histogram/tag.py
new/boost_histogram-1.5.1/src/boost_histogram/tag.py
--- old/boost_histogram-1.5.0/src/boost_histogram/tag.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/src/boost_histogram/tag.py 2022-11-09
13:37:21.000000000 +0100
@@ -11,7 +11,7 @@
from ._internal.typing import AxisLike
-__all__ = ("Slicer", "Locator", "at", "loc", "overflow", "underflow", "rebin",
"sum")
+__all__ = ("Locator", "Slicer", "at", "loc", "overflow", "rebin", "sum",
"underflow")
class Slicer:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/boost_histogram-1.5.0/tests/test_storage.py
new/boost_histogram-1.5.1/tests/test_storage.py
--- old/boost_histogram-1.5.0/tests/test_storage.py 2022-11-09
13:37:21.000000000 +0100
+++ new/boost_histogram-1.5.1/tests/test_storage.py 2022-11-09
13:37:21.000000000 +0100
@@ -301,3 +301,93 @@
)
assert h2d.sum() == h2d.storage_type.accumulator()
assert h2d.sum(flow=True) == h2d.storage_type.accumulator()
+
+
+# Issue #971
+def test_non_uniform_rebin_with_weights():
+ # 1D
+ h = bh.Histogram(bh.axis.Regular(20, 1, 5), storage=bh.storage.Weight())
+ h.fill([1.1, 2.2, 3.3, 4.4])
+
+ rslt = np.array(
+ [(1.0, 1.0), (1.0, 1.0), (1.0, 1.0), (0.0, 0.0), (1.0, 1.0)],
+ dtype=[("value", "<f8"), ("variance", "<f8")],
+ )
+
+ hs = h[{0: slice(None, None, bh.rebin(4))}]
+ assert_array_equal(hs.view(), rslt)
+
+ hs = h[{0: bh.rebin(4)}]
+ assert_array_equal(hs.view(), rslt)
+
+ hs = h[{0: bh.rebin(groups=[1, 2, 3, 14])}]
+ assert_array_equal(
+ hs.view(),
+ np.array(
+ [(1.0, 1.0), (0.0, 0.0), (0.0, 0.0), (3.0, 3.0)],
+ dtype=[("value", "<f8"), ("variance", "<f8")],
+ ),
+ )
+ assert_array_equal(hs.axes.edges[0], [1.0, 1.2, 1.6, 2.2, 5.0])
+
+ # nD
+ h = bh.Histogram(
+ bh.axis.Regular(20, 1, 3),
+ bh.axis.Regular(30, 1, 3),
+ bh.axis.Regular(40, 1, 3),
+ storage=bh.storage.Weight(),
+ )
+
+ s = bh.tag.Slicer()
+
+ assert h[{0: s[:: bh.rebin(groups=[1, 2, 17])]}].axes.size == (3, 30, 40)
+ assert h[{1: s[:: bh.rebin(groups=[1, 2, 27])]}].axes.size == (20, 3, 40)
+ assert h[{2: s[:: bh.rebin(groups=[1, 2, 37])]}].axes.size == (20, 30, 3)
+ assert np.all(
+ np.isclose(
+ h[{0: s[:: bh.rebin(groups=[1, 2, 17])]}].axes[0].edges,
+ [1.0, 1.1, 1.3, 3.0],
+ )
+ )
+ assert np.all(
+ np.isclose(
+ h[{1: s[:: bh.rebin(groups=[1, 2, 27])]}].axes[1].edges,
+ [1.0, 1.06666667, 1.2, 3.0],
+ )
+ )
+ assert np.all(
+ np.isclose(
+ h[{2: s[:: bh.rebin(groups=[1, 2, 37])]}].axes[2].edges,
+ [1.0, 1.05, 1.15, 3.0],
+ )
+ )
+
+ assert h[
+ {0: s[:: bh.rebin(groups=[1, 2, 17])], 2: s[:: bh.rebin(groups=[1, 2,
37])]}
+ ].axes.size == (3, 30, 3)
+ assert np.all(
+ np.isclose(
+ h[
+ {
+ 0: s[:: bh.rebin(groups=[1, 2, 17])],
+ 2: s[:: bh.rebin(groups=[1, 2, 37])],
+ }
+ ]
+ .axes[0]
+ .edges,
+ [1.0, 1.1, 1.3, 3],
+ )
+ )
+ assert np.all(
+ np.isclose(
+ h[
+ {
+ 0: s[:: bh.rebin(groups=[1, 2, 17])],
+ 2: s[:: bh.rebin(groups=[1, 2, 37])],
+ }
+ ]
+ .axes[2]
+ .edges,
+ [1.0, 1.05, 1.15, 3.0],
+ )
+ )