diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3539b4851..896dbb8ac 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -611,9 +611,12 @@ jobs:
- name: Download ML data
run: |
python -m lenskit.data.fetch ml-100k ml-1m ml-10m ml-20m
- - name: "📕 Validate documentation examples"
+ - name: "📕 Validate code examples"
run: |
- pytest --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit --cov=lenskit-implicit/lenskit --cov=lenskit-hpf/lenskit --nbval-lax --doctest-glob='*.rst' --ignore='docs/_ext' --log-file test-docs.log docs */lenskit
+ sphinx-build -b doctest docs build/doc
+ - name: "📕 Validate example notebooks"
+ run: |
+ pytest --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit --cov=lenskit-implicit/lenskit --cov=lenskit-hpf/lenskit --nbval-lax --log-file test-notebooks.log docs
- name: "📐 Coverage results"
if: '${{ !cancelled() }}'
run: |
diff --git a/.vscode/ltex.dictionary.en-US.txt b/.vscode/ltex.dictionary.en-US.txt
index 4ad9b9375..f3bda7f53 100644
--- a/.vscode/ltex.dictionary.en-US.txt
+++ b/.vscode/ltex.dictionary.en-US.txt
@@ -22,3 +22,6 @@ RecSys
PyArrow
Numba
DuckDB
+ItemList
+Pydantic
+dataclass
diff --git a/conftest.py b/conftest.py
index 45e48f959..100f6abc6 100644
--- a/conftest.py
+++ b/conftest.py
@@ -16,10 +16,10 @@
from pytest import fixture, skip
from lenskit.parallel import ensure_parallel_init
+from lenskit.random import set_global_rng
# bring common fixtures into scope
from lenskit.testing import ml_100k, ml_ds, ml_ds_unchecked, ml_ratings # noqa: F401
-from lenskit.util.random import set_global_rng
logging.getLogger("numba").setLevel(logging.INFO)
diff --git a/docs/api/data-types.rst b/docs/api/data-types.rst
index 3abeed62e..8e40f464f 100644
--- a/docs/api/data-types.rst
+++ b/docs/api/data-types.rst
@@ -17,4 +17,4 @@ Entity Identifiers
Containers
~~~~~~~~~~
-.. autoclass:: UITuple
+.. autoclass:: UIPair
diff --git a/docs/api/index.rst b/docs/api/index.rst
index bfded543d..bde3dcc24 100644
--- a/docs/api/index.rst
+++ b/docs/api/index.rst
@@ -12,7 +12,6 @@ Core Abstractions
lenskit.pipeline
lenskit.diagnostics
lenskit.operations
- lenskit.types
.. toctree::
:caption: Core
@@ -81,3 +80,4 @@ and may be useful in building new models and components for LensKit.
lenskit.parallel
lenskit.testing
lenskit.util
+ lenskit.random
diff --git a/docs/api/pipeline.rst b/docs/api/pipeline.rst
index 45f46c76e..c18e5530b 100644
--- a/docs/api/pipeline.rst
+++ b/docs/api/pipeline.rst
@@ -31,7 +31,6 @@ LensKit components.
~lenskit.pipeline.Component
~lenskit.pipeline.Trainable
- ~lenskit.pipeline.Configurable
Standard Pipelines
------------------
diff --git a/docs/conf.py b/docs/conf.py
index b30fe3dbf..e54ca70f3 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -4,8 +4,10 @@
# Licensed under the MIT license, see LICENSE.md for details.
# SPDX-License-Identifier: MIT
+import doctest
import sys
from importlib.metadata import version
+from os import fspath
from pathlib import Path
from packaging.version import Version
@@ -25,6 +27,7 @@
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
+ "sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.mathjax",
"sphinx.ext.extlinks",
@@ -102,9 +105,9 @@
autodoc_typehints = "description"
autodoc_type_aliases = {
"ArrayLike": "numpy.typing.ArrayLike",
- "SeedLike": "lenskit.types.SeedLike",
- "RNGLike": "lenskit.types.RNGLike",
- "RNGInput": "lenskit.types.RNGInput",
+ "SeedLike": "lenskit.random.SeedLike",
+ "RNGLike": "lenskit.random.RNGLike",
+ "RNGInput": "lenskit.random.RNGInput",
"IDSequence": "lenskit.data.types.IDSequence",
}
# autosummary_generate_overwrite = False
@@ -133,6 +136,10 @@
bibtex_bibfiles = ["lenskit.bib"]
nb_execution_mode = "off"
+doctest_path = [fspath((Path(__file__).parent / "guide" / "examples").resolve())]
+doctest_default_flags = (
+ doctest.ELLIPSIS | doctest.IGNORE_EXCEPTION_DETAIL | doctest.NORMALIZE_WHITESPACE
+)
mermaid_d3_zoom = True
diff --git a/docs/guide/GettingStarted.ipynb b/docs/guide/GettingStarted.ipynb
index 2644c28d4..0bfc360fb 100644
--- a/docs/guide/GettingStarted.ipynb
+++ b/docs/guide/GettingStarted.ipynb
@@ -179,12 +179,12 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "model_ii = ItemKNNScorer(20)\n",
- "model_als = BiasedMFScorer(50)"
+ "model_ii = ItemKNNScorer(k=20)\n",
+ "model_als = BiasedMFScorer(features=50)"
]
},
{
@@ -231,7 +231,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "/Users/michael/Documents/LensKit/lkpy/lenskit/lenskit/als/_explicit.py:94: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at /Users/runner/miniforge3/conda-bld/libtorch_1733624403138/work/aten/src/ATen/SparseCsrTensorImpl.cpp:55.)\n",
+ "/Users/mde48/LensKit/lkpy/lenskit/lenskit/als/_explicit.py:59: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at /Users/runner/miniforge3/conda-bld/libtorch_1733624403138/work/aten/src/ATen/SparseCsrTensorImpl.cpp:55.)\n",
" rmat = rmat.to_sparse_csr()\n"
]
}
@@ -329,15 +329,15 @@
"
\n",
" \n",
" ALS | \n",
- " 0.129831 | \n",
- " 0.096835 | \n",
- " 0.208196 | \n",
+ " 0.125716 | \n",
+ " 0.092391 | \n",
+ " 0.199641 | \n",
"
\n",
" \n",
" II | \n",
- " 0.096751 | \n",
- " 0.035333 | \n",
- " 0.104951 | \n",
+ " 0.092792 | \n",
+ " 0.033473 | \n",
+ " 0.102041 | \n",
"
\n",
" \n",
"\n",
@@ -346,8 +346,8 @@
"text/plain": [
" NDCG RBP RecipRank\n",
"model \n",
- "ALS 0.129831 0.096835 0.208196\n",
- "II 0.096751 0.035333 0.104951"
+ "ALS 0.125716 0.092391 0.199641\n",
+ "II 0.092792 0.033473 0.102041"
]
},
"execution_count": 9,
@@ -366,7 +366,7 @@
"outputs": [
{
"data": {
- "image/png": "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oUO6//77e2SiAACgczr8dbkPPfSQ/vCHP6iiokKff/65JOnb3/62xo8f3+2TAwAAXdfh2Hs8HoWGhmrcuHEaN26cd/nVq1d16dIl/mIcAAB+pkMX6O3fv18JCQn66quv2rz21Vdf6cEHH9TBgwe7bXIAAKDrOhT7/Px8/fCHP9S3vvWtNq9961vf0vLly7V58+ZumxwAAOi6DsX+k08+0eTJk2/4+qOPPqqPP/64q3MCAADdqEOxv3DhglpaWm74+pUrV3ThwoUuTwoAAHSfDsX+vvvu04kTJ274+okTJxQdHd3lSQEAgO7Todj/4z/+o3JycvTnP/+5zWtut1urVq3SnDlzum1yAACg6zp0692KFSt04MABffvb39a8efM0atQoORwOVVZW6q233lJUVJRWrFjRU3MFAACd0KHY9+3bV8eOHVN2drYKCwu9v58PDw/XvHnztHbtWvXt27dHJgoAADqnw1+qExYWpry8PG3ZskX19fWyLEuDBg3yfnUuAADwLx2O/XUNDQ06e/asHA6HAgICfP6uPQAA8B8dukBPkj799FM9+uijcjqdmjhxoh566CHde++9+u53v+vzt+4BAIB/6NCRvdvt1qRJkzRo0CBt2LBBo0ePlmVZ+sMf/qDt27crOTlZn3zyie69996emi8AAOigDsX+5z//uaKjo3Xs2DGFhIR4l0+bNk2LFi3SI488op///OfKzc3t9okCAIDO6dBp/OLiYi1fvtwn9Nf16dNHy5Yt03vvvddtkwMAAF3XodifPn1aEyZMuOHrCQkJOn36dJcnBQAAuk+HYn/x4sWb/r36vn376tKlS12eFAAA6D4dvvXu4sWL7Z7GlySPxyPLsro8KQAA0H06FHvLsjRy5Mibvs6X6wAA4F86FPsPP/ywp+YBAAB6SIdiP2nSpJ6aBwAA6CEdin2vXr2+8TS9w+FQS0tLlyYFAAC6T4div3///hu+VlJSon/5l3/hAj0AAPxMh2I/a9asNss+++wzZWdn6+DBg3rmmWf0yiuvdNvkAABA13X4D+Fc97//+796/vnnNWbMGLW0tKiiokJvvvmmhg0b1p3zAwAAXdTh2Dc2Nmr58uW6//779emnn+qDDz7QwYMHFR8f3xPzAwAAXdSh0/ivvfaaXn31VUVGRmr37t3tntYHAAD+pUOxX7Fihfr06aP7779fb775pt588812x+3bt69bJgcAALquQ7GfP38+35AHAMAdpkOxf+ONN3poGgAAoKd0+mp8AABwZyD2AAAYjtgDAGA4Yg8AgOGIPQAAhiP2AAAYjtgDAGA4Yg8AgOFsj31eXp5iYmIUEhIil8ulo0eP3nT8kSNH5HK5FBISouHDh2vr1q1txvzlL3/RCy+8oMGDByskJESxsbEqKirqqV0AAMCv2Rr7wsJCZWRkKCcnR+Xl5UpOTtb06dNVXV3d7viqqirNmDFDycnJKi8v18qVK7V48WLt3bvXO6a5uVl/+7d/qzNnzujf//3fderUKW3fvl1Dhw69XbsFAIBf6dDX5Xa3DRs2aMGCBVq4cKEkaePGjXrvvfeUn5+v3NzcNuO3bt2qYcOGaePGjZKk2NhYnThxQuvXr9ecOXMkSTt27NAXX3yhkpIS9e7dW5IUHR19e3YIAAA/ZNuRfXNzs8rKypSSkuKzPCUlRSUlJe2uU1pa2mb81KlTdeLECV25ckWS9M477ygxMVEvvPCCnE6n4uPjtXbtWrW2tvbMjgAA4OdsO7Kvr69Xa2urnE6nz3Kn0ym3293uOm63u93xLS0tqq+v1+DBg3X69Gn9+te/1jPPPKOioiL98Y9/1AsvvKCWlhb96Ec/ane7TU1Nampq8j73eDxd3DsAAPyH7Rfoff1P5lqWddM/o9ve+L9efvXqVd17773atm2bXC6XnnrqKeXk5Cg/P/+G28zNzVVYWJj3ERUV1dndAQDA79gW+4iICAUEBLQ5iq+rq2tz9H5dZGRku+MDAwM1cOBASdLgwYM1cuRIBQQEeMfExsbK7Xarubm53e1mZ2ersbHR+zh37lxXdg0AAL9iW+yDgoLkcrlUXFzss7y4uFhJSUntrpOYmNhm/KFDh5SQkOC9GO/hhx/Wn/70J129etU75vPPP9fgwYMVFBTU7naDg4PVr18/nwcAAKaw9TR+VlaWXn/9de3YsUOVlZXKzMxUdXW10tPTJV074p4/f753fHp6us6ePausrCxVVlZqx44dKigo0NKlS71jFi1apIaGBi1ZskSff/65/vM//1Nr167VCy+8cNv3DwAAf2DrrXepqalqaGjQmjVrVFtbq/j4eBUVFXlvlautrfW55z4mJkZFRUXKzMzUli1bNGTIEG3atMl7250kRUVF6dChQ8rMzNSYMWM0dOhQLVmyRMuXL7/t+wcAgD9wWNevcIOXx+NRWFiYGhsbu/WUvmvZrm7bFtCdytbN/+ZBfoDPEPyVv3+GbL8aHwAA9CxiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDjbY5+Xl6eYmBiFhITI5XLp6NGjNx1/5MgRuVwuhYSEaPjw4dq6desNx+7Zs0cOh0OzZ8/u5lkDAHDnsDX2hYWFysjIUE5OjsrLy5WcnKzp06erurq63fFVVVWaMWOGkpOTVV5erpUrV2rx4sXau3dvm7Fnz57V0qVLlZyc3NO7AQCAX7M19hs2bNCCBQu0cOFCxcbGauPGjYqKilJ+fn6747du3aphw4Zp48aNio2N1cKFC/VP//RPWr9+vc+41tZWPfPMM/rxj3+s4cOH345dAQDAb9kW++bmZpWVlSklJcVneUpKikpKStpdp7S0tM34qVOn6sSJE7py5Yp32Zo1azRo0CAtWLDglubS1NQkj8fj8wAAwBS2xb6+vl6tra1yOp0+y51Op9xud7vruN3udse3tLSovr5eknTs2DEVFBRo+/bttzyX3NxchYWFeR9RUVEd3BsAAPyX7RfoORwOn+eWZbVZ9k3jry+/ePGi5s2bp+3btysiIuKW55Cdna3Gxkbv49y5cx3YAwAA/FugXW8cERGhgICANkfxdXV1bY7er4uMjGx3fGBgoAYOHKhPP/1UZ86c0cyZM72vX716VZIUGBioU6dOacSIEW22GxwcrODg4K7uEgAAfsm2I/ugoCC5XC4VFxf7LC8uLlZSUlK76yQmJrYZf+jQISUkJKh3794aPXq0Pv74Y1VUVHgfjz/+uL7zne+ooqKC0/MAgLuSbUf2kpSVlaW0tDQlJCQoMTFR27ZtU3V1tdLT0yVdO71eU1OjXbt2SZLS09O1efNmZWVl6fnnn1dpaakKCgq0e/duSVJISIji4+N93qN///6S1GY5AAB3C1tjn5qaqoaGBq1Zs0a1tbWKj49XUVGRoqOjJUm1tbU+99zHxMSoqKhImZmZ2rJli4YMGaJNmzZpzpw5du0CAAB+z2Fdv8INXh6PR2FhYWpsbFS/fv26bbuuZbu6bVtAdypbN9/uKdwSPkPwV/7+GbL9anwAANCziD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgONtjn5eXp5iYGIWEhMjlcuno0aM3HX/kyBG5XC6FhIRo+PDh2rp1q8/r27dvV3JyssLDwxUeHq4pU6bo+PHjPbkLAAD4NVtjX1hYqIyMDOXk5Ki8vFzJycmaPn26qqur2x1fVVWlGTNmKDk5WeXl5Vq5cqUWL16svXv3esccPnxYTz/9tD788EOVlpZq2LBhSklJUU1Nze3aLQAA/IrDsizLrjefOHGiJkyYoPz8fO+y2NhYzZ49W7m5uW3GL1++XO+8844qKyu9y9LT03Xy5EmVlpa2+x6tra0KDw/X5s2bNX/+/Fual8fjUVhYmBobG9WvX78O7tWNuZbt6rZtAd2pbN2tfTbsxmcI/srfP0O2Hdk3NzerrKxMKSkpPstTUlJUUlLS7jqlpaVtxk+dOlUnTpzQlStX2l3nyy+/1JUrVzRgwIAbzqWpqUkej8fnAQCAKWyLfX19vVpbW+V0On2WO51Oud3udtdxu93tjm9paVF9fX2766xYsUJDhw7VlClTbjiX3NxchYWFeR9RUVEd3BsAAPyX7RfoORwOn+eWZbVZ9k3j21suSa+99pp2796tffv2KSQk5IbbzM7OVmNjo/dx7ty5juwCAAB+LdCuN46IiFBAQECbo/i6uro2R+/XRUZGtjs+MDBQAwcO9Fm+fv16rV27Vu+//77GjBlz07kEBwcrODi4E3sBAID/s+3IPigoSC6XS8XFxT7Li4uLlZSU1O46iYmJbcYfOnRICQkJ6t27t3fZunXr9Morr+hXv/qVEhISun/yAADcQWw9jZ+VlaXXX39dO3bsUGVlpTIzM1VdXa309HRJ106v//UV9Onp6Tp79qyysrJUWVmpHTt2qKCgQEuXLvWOee2117Rq1Srt2LFD9913n9xut9xuty5dunTb9w8AAH9g22l8SUpNTVVDQ4PWrFmj2tpaxcfHq6ioSNHR0ZKk2tpan3vuY2JiVFRUpMzMTG3ZskVDhgzRpk2bNGfOHO+YvLw8NTc364knnvB5r5deekkvv/zybdkvAAD8ia332fsr7rPH3cbf7xG+js8Q/JW/f4ZsvxofAAD0LGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGM722Ofl5SkmJkYhISFyuVw6evToTccfOXJELpdLISEhGj58uLZu3dpmzN69exUXF6fg4GDFxcVp//79PTV9AAD8nq2xLywsVEZGhnJyclReXq7k5GRNnz5d1dXV7Y6vqqrSjBkzlJycrPLycq1cuVKLFy/W3r17vWNKS0uVmpqqtLQ0nTx5Umlpafre976n3/3ud7drtwAA8CsOy7Isu9584sSJmjBhgvLz873LYmNjNXv2bOXm5rYZv3z5cr3zzjuqrKz0LktPT9fJkydVWloqSUpNTZXH49G7777rHTNt2jSFh4dr9+7dtzQvj8ejsLAwNTY2ql+/fp3dvTZcy3Z127aA7lS2br7dU7glfIbgr/z9M2TbkX1zc7PKysqUkpLiszwlJUUlJSXtrlNaWtpm/NSpU3XixAlduXLlpmNutE0AAEwXaNcb19fXq7W1VU6n02e50+mU2+1udx23293u+JaWFtXX12vw4ME3HHOjbUpSU1OTmpqavM8bGxslXTvC706tTf+vW7cHdJfu/m+9p/AZgr/qqc9Q37595XA4urwd22J/3dd3wrKsm+5Ye+O/vryj28zNzdWPf/zjNsujoqJuPHHAIGH/km73FIA7Wk99hrrr18m2xT4iIkIBAQFtjrjr6uraHJlfFxkZ2e74wMBADRw48KZjbrRNScrOzlZWVpb3+dWrV/XFF19o4MCB3fIvKnQ/j8ejqKgonTt3rluvqwDuFnyG7gx9+/btlu3YFvugoCC5XC4VFxfrH/7hH7zLi4uLNWvWrHbXSUxM1MGDB32WHTp0SAkJCerdu7d3THFxsTIzM33GJCUl3XAuwcHBCg4O9lnWv3//ju4SbNCvXz/+RwV0AZ+hu4Otp/GzsrKUlpamhIQEJSYmatu2baqurlZ6+rXTIdnZ2aqpqdGuXdeuwE1PT9fmzZuVlZWl559/XqWlpSooKPC5yn7JkiV69NFH9eqrr2rWrFk6cOCA3n//ff3mN7+xZR8BALCbrbFPTU1VQ0OD1qxZo9raWsXHx6uoqEjR0dGSpNraWp977mNiYlRUVKTMzExt2bJFQ4YM0aZNmzRnzhzvmKSkJO3Zs0erVq3S6tWrNWLECBUWFmrixIm3ff8AAPAHtt5nD3RWU1OTcnNzlZ2d3eZXMAC+GZ+huwuxBwDAcLZ/Nz4AAOhZxB4AAMMRewAADEfs4XdKSkoUEBCgadOm+Sw/c+aMHA6HKioq2l2vtbVVubm5Gj16tPr06aMBAwbob/7mb7Rz587bMGvgzvDss89q9uzZbX6G2Wz/ulzg63bs2KEXX3xRr7/+uqqrqzVs2LBbWu/ll1/Wtm3btHnzZiUkJMjj8ejEiRO6cOFCD88YAPwbsYdfuXz5sv7t3/5Nv//97+V2u/XGG2/oRz/60S2te/DgQX3/+9/Xk08+6V02duzYnpoqANwxOI0Pv1JYWKhRo0Zp1KhRmjdvnnbu3KlbvTs0MjJSv/71r3X+/PkeniUA3FmIPfxKQUGB5s2bJ0maNm2aLl26pA8++OCW1t2wYYPOnz+vyMhIjRkzRunp6Xr33Xd7croAcEcg9vAbp06d0vHjx/XUU09JkgIDA5WamqodO3bc0vpxcXH65JNP9Nvf/lbPPfec/vznP2vmzJlauHBhT04bAPwev7OH3ygoKFBLS4uGDh3qXWZZlnr37n3LF9n16tVLDz74oB588EFlZmbqF7/4hdLS0pSTk6OYmJiemjoA+DWO7OEXWlpatGvXLv3sZz9TRUWF93Hy5ElFR0frrbfe6tR24+LiJF278A8A7lYc2cMv/PKXv9SFCxe0YMEChYWF+bz2xBNPqKCgQH//938v6drp/q+Li4vT3Llz9fDDDyspKUmRkZGqqqpSdna2Ro4cqdGjR9+W/QAAf0Ts4RcKCgo0ZcqUNqGXpDlz5mjt2rX64osvJMn7O/2/VlVVpalTp2r37t3Kzc1VY2OjIiMj9d3vflcvv/yyAgP5Tx3A3Yu/egcAgOH4nT0AAIYj9gAAGI7YAwBgOGIPAIDhiD0AAIYj9gAAGI7YAwBgOGIPAIDhiD2A22ry5MnKyMi45fFvvPGG+vfv32PzAe4GxB4AAMMRewAADEfsAUi6dnr9xRdfVEZGhsLDw+V0OrVt2zZdvnxZzz33nPr27asRI0bo3Xff9a5z5MgRPfTQQwoODtbgwYO1YsUKtbS0eF+/fPmy5s+fr9DQUA0ePFg/+9nP2rxvc3OzfvjDH2ro0KG65557NHHiRB0+fPh27DJw1yD2ALzefPNNRURE6Pjx43rxxRe1aNEiPfnkk0pKStJHH32kqVOnKi0tTV9++aVqamo0Y8YMPfjggzp58qTy8/NVUFCgn/zkJ97tLVu2TB9++KH279+vQ4cO6fDhwyorK/N5z+eee07Hjh3Tnj179F//9V968sknNW3aNP3xj3+83bsPmMsCAMuyJk2aZD3yyCPe5y0tLdY999xjpaWleZfV1tZakqzS0lJr5cqV1qhRo6yrV696X9+yZYsVGhpqtba2WhcvXrSCgoKsPXv2eF9vaGiw+vTpYy1ZssSyLMv605/+ZDkcDqumpsZnLo899piVnZ1tWZZl7dy50woLC+uBPQbuHvyRbwBeY8aM8f4cEBCggQMH6oEHHvAuczqdkqS6ujpVVlYqMTFRDofD+/rDDz+sS5cu6X/+53904cIFNTc3KzEx0fv6gAEDNGrUKO/zjz76SJZlaeTIkT7zaGpq0sCBA7t9/4C7FbEH4NW7d2+f5w6Hw2fZ9bBfvXpVlmX5hF6SLMvyjrv+881cvXpVAQEBKisrU0BAgM9roaGhndoHAG0RewCdEhcXp7179/pEv6SkRH379tXQoUMVHh6u3r1767e//a2GDRsmSbpw4YI+//xzTZo0SZI0fvx4tba2qq6uTsnJybbtC2A6LtAD0Cnf//73de7cOb344ov67LPPdODAAb300kvKyspSr169FBoaqgULFmjZsmX64IMP9Mknn+jZZ59Vr17/97+dkSNH6plnntH8+fO1b98+VVVV6fe//71effVVFRUV2bh3gFk4sgfQKUOHDlVRUZGWLVumsWPHasCAAVqwYIFWrVrlHbNu3TpdunRJjz/+uPr27asf/OAHamxs9NnOzp079ZOf/EQ/+MEPVFNTo4EDByoxMVEzZsy43bsEGMth3cov1gAAwB2L0/gAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACGI/YAABiO2AMAYDhiDwCA4Yg9AACG+/8bDdKpZQN+HgAAAABJRU5ErkJggg==",
+ "image/png": "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ADAcsQcAwHDEHgAAwxF7AAAM16Ovy71w4YI+++wz3XnnnZKkzZs3q6Ojw/t4SEiI5s+f3+1flgMAAPboUex37typ//iP/9D+/fslSYsXL9att96q0NCLm2lpaVFkZKTmzp0b+JUCAIBr0qND8G3btnn/It0l+/fvV0NDgxoaGrRmzRr94he/COgCAQBA7/Qo9vX19UpOTr7s4xMnTtThw4d7vSgAABA4PTqN39LSoqioKO/9o0ePKjY21ns/LCxM586dC9zqAABAr/XoyN7pdOrIkSPe+0OGDPG5GK++vl5xcXGBWx0AAOi1HsX+oYce0ksvvdTtY5ZlqaioSA899FBAFgYAAAKjR6fxCwsLNX78eE2YMEGLFi3S6NGj5XA49Pnnn2vt2rU6cuSItm/f3ldrBQAA16BHsR81apQqKyv11FNPKSsrSw6HQ9LFo/qxY8dq7969uuOOO/pkoQAA4Nr0KPaSdN999+lPf/qT6urq9MUXX0iSvvvd7+qee+4J+OIAAEDv9Tj2Ho9HUVFRuvvuu3X33Xd7xy9cuKCzZ89q4MCBgVwfAADopR5doLd7926lpqbq66+/9nvs66+/1r333qt33303YIsDAAC916PYl5SU6Mc//rG+853v+D32ne98R0uWLNHGjRsDtjgAANB7PYr9p59+qkmTJl328QcffFB//OMfe7smAAAQQD2K/enTp9XZ2XnZx8+fP6/Tp0/3elEAACBwehT722+/XYcOHbrs44cOHVJCQkKvFwUAAAKnR7H/13/9VxUWFuqvf/2r32Nut1vLly/XrFmzArY4AADQez366N3SpUu1Z88effe739Xs2bM1ZswYORwO1dfX680331R8fLyWLl3aV2sFAADXoEexHzBggD7++GMVFBSovLzc+/v5mJgYzZ49W6tXr9aAAQP6ZKEAAODa9PhLdaKjo1VcXKxNmzappaVFlmVpyJAh3q/OBQAAwaXHsb+ktbVVx48fl8PhUEhIiM/ftQcAAMGjRxfoSdJnn32mBx98UE6nUxMmTNB9992n2267Td/73vd8/tY9AAAIDj06sne73Zo4caKGDBmidevWaezYsbIsS3/605+0detWZWRk6NNPP9Vtt93WV+sFAAA91KPY/+xnP1NCQoI+/vhjRUZGesenTp2q+fPn64EHHtDPfvYzFRUVBXyhAADg2vToNH5l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",
"text/plain": [
"