From 4504f5240cfeda71f30e8d26eb76b5d27a82342a Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Fri, 28 Aug 2026 18:54:41 +0200 Subject: [PATCH 01/10] Add support for Directory pseudotype for stage-in A string annotated with "EOInput" will now be treated as a CWL "Directory" type to enable EOAP-style data stage-in. No additional stage-in functionality has been implemented yet: the initial goal is to at least let a notebook parse the stage-in STAC catalogue itself. --- test/test_parameters.py | 23 ++++++++++++++++++++ xcengine/parameters.py | 47 +++++++++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/test/test_parameters.py b/test/test_parameters.py index 4275a15..e2f656a 100644 --- a/test/test_parameters.py +++ b/test/test_parameters.py @@ -19,6 +19,7 @@ def expected_vars(): "some_float": (float, 3.14159), "some_string": (str, "foo"), "some_bool": (bool, False), + "some_directory": ("Directory", "/some/path") } @@ -37,6 +38,9 @@ def params_yaml(): some_bool: type: bool default: false +some_directory: + type: Directory + default: "/some/path" """ @@ -130,6 +134,13 @@ def test_parameters_get_commandline_inputs(notebook_parameters): "doc": "some_bool", "inputBinding": {"prefix": "--some-bool"}, }, + "some_directory": { + "type": "Directory", + "default": "/some/path", + "label": "some_directory", + "doc": "some_directory", + "inputBinding": {"prefix": "--some-directory"}, + }, } @@ -139,6 +150,7 @@ def test_parameters_get_cwl_step_inputs(notebook_parameters): "some_float": "some_float", "some_string": "some_string", "some_bool": "some_bool", + "some_directory": "some_directory", } @@ -148,6 +160,7 @@ def test_parameters_from_code(expected_vars): some_float = 3.14159 some_string = "foo" some_bool = False +some_directory: "EOInput" = "/some/path" """) assert parameters.params == expected_vars assert parameters.config == {} @@ -160,6 +173,7 @@ def test_parameters_from_code_with_xce_config(expected_vars): some_float = 3.14159 some_string = "foo" some_bool = False +some_directory: "EOInput" = "/some/path" {NotebookParameters.config_var_name} = {xce_config!r} """ parameters = xcengine.parameters.NotebookParameters.from_code(code) @@ -175,11 +189,13 @@ def test_parameters_from_code_with_setup(expected_vars): some_float = 3.14159 some_string = some_uppercase_string.lower() some_bool = not not_some_bool +some_directory: "EOInput" = "/" + "/".join(some_path_components) """, setup_code=""" half_of_some_int = 21 some_uppercase_string = "FOO" not_some_bool = True +some_path_components = ["some", "path"] """, ).params == expected_vars @@ -212,6 +228,12 @@ def test_parameters_get_workflow_inputs(notebook_parameters): "label": "some_bool", "doc": "some_bool", }, + "some_directory": { + "type": "Directory", + "default": "/some/path", + "label": "some_directory", + "doc": "some_directory", + } } @@ -221,6 +243,7 @@ def test_parameters_to_yaml(notebook_parameters): "some_float": {"type": "float", "default": 3.14159}, "some_string": {"type": "str", "default": "foo"}, "some_bool": {"type": "bool", "default": False}, + "some_directory": {"type": "Directory", "default": "/some/path"}, } diff --git a/xcengine/parameters.py b/xcengine/parameters.py index c88f3dc..0992096 100644 --- a/xcengine/parameters.py +++ b/xcengine/parameters.py @@ -2,7 +2,7 @@ import os import pathlib import typing -from typing import Any, ClassVar +from typing import Any, ClassVar, cast import xarray as xr import yaml @@ -13,7 +13,7 @@ class NotebookParameters: - params: dict[str, tuple[type, Any]] + params: dict[str, tuple[type | str, Any]] cwl_params: dict[str, tuple[type | str, Any]] dataset_inputs: list[str] config_var_name: ClassVar[str] = "xcengine_config" @@ -21,7 +21,7 @@ class NotebookParameters: def __init__( self, - params: dict[str, tuple[type, Any]], + params: dict[str, tuple[type | str, Any]], config: dict[str, Any] | None = None, ): self.params = params @@ -46,16 +46,27 @@ def from_code( ) -> "NotebookParameters": variables = cls.extract_variables(code, setup_code) config = variables.pop(cls.config_var_name, (None, None)) - # TODO: throw an error here if config has wrong type - return cls(variables, config[1]) + if config[1] is not None: + if type(config[1]) is not dict: + raise TypeError("Configuration variable must be a dict") + if not all(type(k) is str for k in cast(dict, config[1]).keys()): + raise TypeError("Configuration dict keys must be strings") + return cls(variables, cast(dict[str, Any], config[1])) @classmethod def from_yaml(cls, yaml_content: str | typing.IO) -> "NotebookParameters": input_data = yaml.safe_load(yaml_content) + def convert_type(yaml_spec: str) -> type | str: + match yaml_spec: + case "int" | "float" | "bool" | "str" | "Dataset": + return eval(yaml_spec, globals(), {"Dataset": xr.Dataset}) + case "Directory": + return "Directory" + raise ValueError(f'Unknown type in YAML: "{yaml_spec}"') return cls( { k: ( - eval(v["type"], globals(), {"Dataset": xr.Dataset}), + convert_type(v["type"]), v["default"], ) for k, v in input_data.items() @@ -70,7 +81,7 @@ def from_yaml_file(cls, path: str | os.PathLike) -> "NotebookParameters": @classmethod def extract_variables( cls, code: str, setup_code: str | None = None - ) -> dict[str, tuple[type, Any]]: + ) -> dict[str, tuple[type | str, Any]]: if setup_code is None: locals_: dict[str, object] = {} old_locals = {} @@ -78,14 +89,19 @@ def extract_variables( exec(setup_code, globals(), locals_ := {}) old_locals = locals_.copy() exec(code, globals(), locals_) + annotations = cls.read_annotations(code) new_vars = locals_.keys() - old_locals.keys() new_var_dict = { - k: cls.make_param_tuple(k, locals_[k]) for k in new_vars + k: cls.make_param_tuple(k, locals_[k]) for k in new_vars if not k.startswith("__") } + for k in new_var_dict: + if k in annotations and annotations[k] == "'EOInput'": + old_var = new_var_dict[k] + new_var_dict[k] = ("Directory", old_var[1]) return dict(sorted(new_var_dict.items())) @classmethod - def make_param_tuple(cls, key: str, value: Any) -> tuple[type, Any]: + def make_param_tuple(cls, key: str, value: Any) -> tuple[type | str, Any]: return ( t := type(value), ( @@ -125,9 +141,17 @@ def get_cwl_commandline_input(self, var_name: str) -> dict[str, Any]: } def to_yaml(self) -> str: + def dump_type(type_: type | str) -> str: + match type_: + case type(): + return type_.__name__ + case str(): + return type_ + case _: + raise TypeError(f"Unhandled type {type_} for YAML export") return yaml.safe_dump( { - name: {"type": type_.__name__, "default": default_} + name: {"type": dump_type(type_), "default": default_} for name, (type_, default_) in self.params.items() } ) @@ -223,7 +247,7 @@ def read_staged_in_dataset( return xr.open_dataset(stage_in_path / asset.href) @staticmethod - def cwl_type(type_: type) -> str: + def cwl_type(type_: type | str) -> str: try: # noinspection PyTypeChecker return { @@ -231,6 +255,7 @@ def cwl_type(type_: type) -> str: float: "double", str: "string", bool: "boolean", + "Directory": "Directory", }[type_] except KeyError: raise ValueError(f"Unhandled type {type_}") From a99d6d086a448cff851dd47517acb52da99eb027 Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Mon, 31 Aug 2026 17:09:55 +0200 Subject: [PATCH 02/10] Improve test coverage --- test/test_parameters.py | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/test/test_parameters.py b/test/test_parameters.py index e2f656a..de52767 100644 --- a/test/test_parameters.py +++ b/test/test_parameters.py @@ -166,8 +166,12 @@ def test_parameters_from_code(expected_vars): assert parameters.config == {} -def test_parameters_from_code_with_xce_config(expected_vars): - xce_config = dict(foo=1, bar="hi!", baz={}) +@pytest.mark.parametrize("config", [ + (dict(foo=1, bar="hi!", baz={}), True), + ("Not a dict", False), + ({42: "Wrong key type"}, False)]) +def test_parameters_from_code_with_xce_config(expected_vars, config): + xce_config, valid = config code = f""" some_int = 42 some_float = 3.14159 @@ -176,9 +180,13 @@ def test_parameters_from_code_with_xce_config(expected_vars): some_directory: "EOInput" = "/some/path" {NotebookParameters.config_var_name} = {xce_config!r} """ - parameters = xcengine.parameters.NotebookParameters.from_code(code) - assert parameters.params == expected_vars - assert parameters.config == xce_config + if valid: + parameters = xcengine.parameters.NotebookParameters.from_code(code) + assert parameters.params == expected_vars + assert parameters.config == xce_config + else: + with pytest.raises(TypeError): + xcengine.parameters.NotebookParameters.from_code(code) def test_parameters_from_code_with_setup(expected_vars): @@ -247,6 +255,16 @@ def test_parameters_to_yaml(notebook_parameters): } +def test_parameters_to_yaml_unhandled_type(): + with pytest.raises(TypeError): + # Create empty parameters and modify them afterwards to avoid + # __init__ catching the mistake. + np = xcengine.parameters.NotebookParameters({}) + # Disable the inspection, since this is wrong on purpose. + # noinspection bad-assignment + np.params = {"foo": (42, 42)} + np.to_yaml() + def test_parameters_from_yaml(expected_vars, params_yaml): assert NotebookParameters.from_yaml(params_yaml).params == expected_vars @@ -264,6 +282,15 @@ def test_parameters_from_yaml_with_dataset(): } +def test_parameters_from_yaml_unknown_type(): + with pytest.raises(ValueError): + NotebookParameters.from_yaml(""" +some_input: + type: unsupported + default: null + """) + + def test_parameters_from_file(tmp_path, expected_vars, params_yaml): path = tmp_path / "params.yaml" path.write_text(params_yaml) From c3f46f9acde53b7f7bb1260972f7c7c8f8ccf37c Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Mon, 31 Aug 2026 18:14:28 +0200 Subject: [PATCH 03/10] Handle directory parameters in CLI processing --- examples/dynamic/dynamic.ipynb | 40 ++-------------------------------- examples/ndvi/ndvi.ipynb | 2 +- xcengine/parameters.py | 13 ++++++++--- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/examples/dynamic/dynamic.ipynb b/examples/dynamic/dynamic.ipynb index 7a8cdf5..29f980c 100644 --- a/examples/dynamic/dynamic.ipynb +++ b/examples/dynamic/dynamic.ipynb @@ -60,6 +60,7 @@ "outputs": [], "source": [ "periods = 10\n", + "my_directory: \"EOInput\" = \"/my/dir\"\n", "\n", "xcengine_config = dict(\n", " workflow_id=\"dynamic\",\n", @@ -136,7 +137,7 @@ "outputs": [], "source": [ "cube1 = xcube.core.new.new_cube(\n", - " variables={\"v\": lambda x, y, t: ((x + y + t) % 10) / 9},\n", + " variables={my_directory.replace(\"/\", \"_\").strip(\"_\"): lambda x, y, t: ((x + y + t) % 10) / 9},\n", " time_periods=periods\n", ")\n", "cube1.attrs[\"title\"] = \"Cube 1\"" @@ -191,43 +192,6 @@ "Just to check on the data, plot a time-slice from the first dataset. This plot will make no difference to the functionality of the container image and application package generated by `xcetool` from the notebook." ] }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aa60aef0-fe54-4c1b-a5ea-fae5cfd6f1b9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjoAAAHFCAYAAAD7ZFORAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAfZhJREFUeJzt3Xl8E3X+x/FXWpr0oC2FYg+hBZVDDhWLIiACIhREBHURxeWQQ9mKiAgoP1wpyKFc1gsQDxBPdpV6IrQsCIuAAsIucoocrdBSQaQI9Eq/vz/YhoakkKRJZqb9PB+PPHY7eSf5zqDl63u+MzEppRRCCCGEEFVQgNYDEEIIIYTwFZnoCCGEEKLKkomOEEIIIaosmegIIYQQosqSiY4QQgghqiyZ6AghhBCiypKJjhBCCCGqLJnoCCGEEKLKkomOEEIIIaosmegIr9iwYQOpqan88ccfDs916tSJTp06+X1M/rBv3z7Gjh1LUlIStWrVonbt2rRv355PPvnEaT4vL4/BgwcTHR1NaGgobdu25V//+pdD7quvvmLgwIG0bNmSoKAgTCZThWMoLi5m8uTJNGjQAIvFQtOmTXn11Vfd2g9fjOtSXn31VZo2bYrFYqFhw4ZMnjyZ4uJiu8yvv/7K6NGj6dixI7Vq1cJkMrF48WK7TGpqKiaT6bKPsn/+du7cSUpKCm3btiUsLAyTycS3337rML6cnByeffZZ2rZtS3R0NBERESQlJbFw4UKsVqvL+3ngwAHuvfdeatWqRc2aNenatSs//vij0+zHH3/MDTfcQHBwMPHx8YwePZo///xTl58lhKEoIbxg1qxZClAHDx50eG7nzp1q586d/h+UH7z66quqadOmatq0aSojI0MtX75cDRo0SAFq8uTJdtmCggLVokULVa9ePfX++++rjIwM1bt3b1WjRg317bff2mWHDBmiGjVqpO6//36VlJSkLvWv6rBhw5TFYlEzZ85Ua9asUc8884wymUxq2rRpLu2Dr8ZVkalTpyqTyaQmTJig1qxZo2bOnKnMZrMaPny4XW7NmjUqOjpa3XHHHerBBx9UgFq0aJFdJjs7W23cuNH2WLZsmQLU448/bre97J+/xYsXq7i4OHXnnXeqXr16KUCtWbPGYYxffvmlql+/vpo4caL6+uuvVUZGhnryySdVQECAevjhh13az7y8PBUfH6+aN2+uPv30U/X111+rW2+9VYWHh6s9e/bYZd9//30FqGHDhqnVq1erBQsWqMjISNW1a1fdfZYQRiMTHeEVl5roVGW//fabKi0tddjes2dPFRoaqgoKCmzbXn/9dQWoDRs22LYVFxerZs2aqZtvvtnu9Var1fb/H3vssQonFD/99JMymUxq+vTpdtuHDx+uQkJC1IkTJy67D74YV0WOHz+ugoOD1SOPPGK3fdq0acpkMtlNiMt/1ubNm51OdC528OBBBahZs2Y5fb78e/7zn/+scKLz+++/q6KiIoftZfuclZV1yXEopdS4ceNUUFCQOnTokG3bqVOnVHR0tLr//vtt20pKSlRcXJzq1q2b3es/+OADBajly5fr6rOEMBo5dSUqLTU1lXHjxgHQsGFD2+mCslMCF5+6OnToECaTiVmzZvHiiy/SoEEDQkJC6NSpE/v27aO4uJhnnnmG+Ph4IiMjueeee8jLy3P43KVLl9pOQdSsWZPk5GS2bdvmj122iY6Odnr65uabb+bs2bP8/vvvtm3p6ek0adKEtm3b2rbVqFGDv/71r/zwww8cOXLEtj0gwLV/NT/77DOUUjz88MN22x9++GHOnTvHihUrLvsevhhXRVasWEFBQYHT8Sql+Oyzz7z2Wc64+p5RUVEEBQU5bL/55puB86fVLic9PZ3bb7+dxMRE27aIiAjuvfdevvzyS0pKSgDYtGkTOTk5Dsekb9++1KxZk/T0dF19lhBGIxMdUWnDhg3j8ccfB2DZsmVs3LiRjRs3cuONN17yda+//jrfffcdr7/+Om+99RZ79uyhV69eDB06lN9++4133nmHmTNnsmrVKoYNG2b32unTp/Pggw/SrFkz/vGPf/Dee+9x+vRpOnTowK5duy475pKSEpceSimPjsmaNWuoW7cuV1xxhW3bTz/9xHXXXeeQLdu2c+dOtz/np59+om7dusTGxjp9z59++sml9/D2uC71WQAtW7a02x4XF0d0dLRL49XS6tWrqVGjBo0bN7bbXn4dEMC5c+f45ZdfKjyu586d48CBA8CFY3JxNigoiKZNmzocE39+lhBVQQ2tByCMr169eiQkJADQqlUrGjRo4NLratWqxWeffWb7r+zjx48zevRomjZtyueff27L7dmzh7S0NPLz84mIiCA7O5tJkyYxcuRIXnnlFVuua9euNGrUiMmTJ7N06dIKP/fQoUM0bNjQpTGuWbPG7YXUb731Ft9++y0vv/wygYGBtu0nTpygdu3aDvmybSdOnHDrcy71nmFhYZjNZpfe0xfjutRnWSwWwsLCnH6eNz/L2zIyMnjvvfd44oknqFOnjt1zgYGBdn/WJ0+eRCnl0nEt+9+KsocOHdLss4SoCmSiIzRz55132p1KuPbaawHo2bOnXa5se1ZWFi1atGDlypWUlJQwcOBAWyUPEBwcTMeOHVmzZs0lPzc+Pp7Nmze7NMYmTZq4lCvzzTff8Nhjj/GXv/zF1nKVd6mrlDy9gsmV91RKOVwtVKNGDYect8ZV/s8Fzv/lXPY+vjgGvvbjjz9y//33c8sttzBjxgyH5y/e3zLu7GtF2Yu3+/OzhKgKZKIjNHPxf1WazeZLbi8oKADg2LFjANx0001O3/dy6zDMZjM33HCDS2Ms/1/Ol7Ny5UruvfdeunbtygcffODwl0adOnWcNhZl63ic/Vf25dSpU4ft27c7bD9z5gxFRUW293z33Xcd1mWUnZbzxbguXt+yaNEiBg8eTJ06dSgoKODs2bOEhoY6fF5SUpLbn+Vr27Zts7WFy5cvx2KxXPY1UVFRmEwml45rWTt04sQJYmJiHLKXO/7+/CwhjEgmOsJwoqOjAfjkk0/sFl+6yhenrlauXEmfPn3o2LEjn376qW1yVl7Lli3ZsWOHw/aybS1atHBpTBe/58cff0xubq7dOp2L37NXr14Vtli+GNfFn1V2vMvW5uzYsYM2bdrYns/NzeX48eMefZYvbdu2jTvuuIPExEQyMjKIjIx06XUhISFcc801FR7XkJAQrrrqKsD+mDRr1syWKykpYc+ePTz44IO6+SwhjEgmOsIryv4r99y5cz7/rOTkZGrUqMEvv/zCfffd5/brvX3qKiMjgz59+nDrrbfy2WefVfhf/Pfccw8pKSl8//33tr/kS0pKeP/992nTpg3x8fGu78T/9O7dm2effZZ3332Xp59+2rZ98eLFhISE0L17d+D8f8lfvK7El+Nq3bq10+3du3cnODiYxYsX2010Fi9ejMlkok+fPm5/lq9s376dO+64g3r16pGZmUlUVJRbr7/nnntIS0sjOzub+vXrA3D69GmWLVvG3XffbTt12KZNG+Li4li8eDH9+vWzvf6TTz7hzz//5N5779XVZwlhNDLREV5R9l+KL7/8MoMGDSIoKIgmTZoQHh7u9c9q0KABU6ZMYeLEiRw4cIDu3bsTFRXFsWPH+OGHHwgLC2Py5MkVvt5sNlf4F7G71q9fT58+fYiNjeX//u//HE4jNWvWjIiICACGDBnC66+/Tt++fXnhhRe44oormDdvHnv37mXVqlV2rzt8+LBtMvbLL78A2O623KBBA9v4mzdvztChQ5k0aRKBgYHcdNNNZGRksHDhQqZOnerSqQhfjKsitWvX5tlnn+Xvf/87tWvXplu3bmzevJnU1FSGDRtm1zKUf++yq4a2bNlCzZo1AfjLX/5y2X272NmzZ1m+fDlw/lJrgLVr13L8+HHCwsLo0aMHAHv37uWOO+4AYNq0afz888/8/PPPtve5+uqrqVu3ru3nGjVq0LFjR7u7SY8dO5b33nuPnj17MmXKFCwWCy+88AIFBQWkpqbacoGBgcycOZMBAwbw6KOP8uCDD/Lzzz8zfvx4unbtapusavFZQlQJGt7DR1QxEyZMUPHx8SogIMDuRmwdO3ZUHTt2tOUquqnbmjVrFKD++c9/2m1ftGiRAtTmzZvttn/22Weqc+fOKiIiQlksFpWYmKj+8pe/qFWrVvlk/5yZNGmSAip8XHwzutzcXDVw4EBVu3ZtFRwcrG655RaVmZnp8L5l++zsMWjQILtsUVGRmjRpkkpISFBms1k1btxYvfLKK27thy/GdSkvv/yyaty4sTKbzSohIUFNmjTJ6Q36LnVsnbncDQPLnnf2SExMdGk/cXLjQsDun/Ey+/fvV3369FEREREqNDRUdenSRW3dutXp2D788EN13XXXKbPZrGJjY9WoUaPU6dOnnR4Tf32WEFWBSSkPbxQihBBCCKFzcsNAIYQQQlRZMtERQgghRJUlEx0hhBBCVFky0RFCCCGEg3Xr1tGrVy/i4+MxmUx2X7pbkbVr15KUlERwcDBXXXUVCxYs8P1AL0MmOkIIIYRwcObMGa6//npee+01l/IHDx7kzjvvpEOHDmzbto3/+7//Y9SoUXz66ac+HumlyVVXQgghhLgkk8lEenr6JW/q+fTTT/PFF1+we/du27YRI0bwn//8h40bN/phlM7JDQMvUlpaytGjRwkPD5cvuBNCCHFJSilOnz5NfHz8Zb9nz1MFBQUUFRV55b2UUg5/t1ksFpe+w+1yNm7cSLdu3ey2JScn8/bbb1NcXOzwHXj+IhOdixw9etR2C3UhhBDCFdnZ2dSrV8/r71tQUEDDxJrk5lm98n41a9bkzz//tNs2adIkuztoeyo3N9fhy2JjYmIoKSnh+PHjxMXFVfozPCETnYuUfWXBrdyJ5ZrGnGsQxen65w/TmTgTRfFFXBF7ipuuyOKOiJ3cEVrEPY1bEnhNQ91kAU7Xr6FZFrCNWe9ZwO4Y6zkLOPwzodcs4PSfYX9lgQr/PdJbFrjkv/d6ygKX/T3lyyzg0u9Kf2bbBfyXQbf+7JOvuwEoKioiN8/Kwa2JRIRXrjHKP11Kw6TDZGdn276aBvBKm1Pm4raobHWMlmdIZKJzkbI/jC/37aFvk1DCAy3UCDr/fUGB5hqcCQ7meEgwP4ZZMNcMIjRwB//K2UlyfJBusgA1gmprlgVsY9Z7FrA7xnrOAg7/TOg1Czj9Z9hfWaDCf4/0lgUu+e+9nrLAZX9P+TILuPS70p9ZwgB+9vlf5BHhAZWe6NjeKyLCbqLjLbGxseTm5tpty8vLo0aNGhV+qbA/yERHCCGE0DmrKsVayUuHrKrUO4OpQNu2bfnyyy/ttmVkZNC6dWvN1ueATHQqtOqsmZVHt5McDyG2rbU5f8jMHKMWm2jwv+07dJWFsrw2WaDcmPWdBS46xnrOXtg/yV46C1zi3yN9ZYHL/Huvpyxc/veUL7Pg2u9K/2U3RybgD6UoSqncTMfd1//555/s37/f9vPBgwfZvn07tWvXJiEhgQkTJnDkyBGWLFkCnL/C6rXXXmPMmDEMHz6cjRs38vbbb/PRRx9VatyVJRMdIYQQQjjYsmULnTt3tv08ZswYAAYNGsTixYvJyckhKyvL9nzDhg1Zvnw5Tz75JK+//jrx8fG88sor3HfffX4fe3ky0anAqvzmhIbv0U1LYqRGBbRuPqQl0ToL0pK4nsXJMdZrFi73e8q3WftjrIds3rlI/KGUUip74sndd+jUqROXutXe4sWLHbZ17NiRH3/80d2h+ZRMdIQQQgidsyqFtZL3963s641KJjoV2JyX8L+rPPTRkhirUbkwZslWnZbEWI0KTo6xXrPgWpOgh2z5/at+6w+dZa0FZoS+yURHCCGE0DktFiNXFTLRqUBebiSbwspuoqSHlkQaFV9kQVoS32RBWhJXs/bHWM9ZqN7rD51lrUX+mTyUorDKRMcjAVoPQAghhBDCV6TRqYD5qJljIcG6aB2MlgVpSXyTBW1bEiM1KvbHWM9Z0N+6E61bEv225Y7ZkuJQ/EFOXXlOJjpCCCGEzslVV56TiU4FwnIUBcH6aUmM1KiA1s2HtCTaZ8vvn7Qkem5JjNWo2B9jXWSt3v/GcmdK//eo7HtUR7JGRwghhBBVlmEanZKSElJTU/nggw/Izc0lLi6OwYMH8+yzzxIQcH6+ppRi8uTJLFy4kJMnT9KmTRtef/11mjdv7vbnhWeXEGhW6KUlMVajAtKS+CJbfv/0nQVpSVzNgtYticEbFY2zXeKK8QerF666quzrjcowjc6LL77IggULeO2119i9ezczZ85k1qxZvPrqq7bMzJkzmTt3Lq+99hqbN28mNjaWrl27cvr0aQ1HLoQQQlSOVXnnUR0ZZqKzceNGevfuTc+ePWnQoAF/+ctf6NatG1u2bAHOtzlpaWlMnDiRe++9lxYtWvDuu+9y9uxZPvzwQ41HL4QQQggtGObU1a233sqCBQvYt28fjRs35j//+Q/r168nLS0NOP/18bm5uXTr1s32GovFQseOHdmwYQOPPvqoW58XcugkNYKC0c/pICOdOgJtT/HI6SCtsyCng1zP2h9jyep3WYCzbPq+HUQ1xudkMbLnDDPRefrppzl16hRNmzYlMDAQq9XKtGnTePDBBwHIzc0FICYmxu51MTExHD58uML3LSwspLCw0PZzfn6+D0YvhBBCeK4UE1ZMlX6P6sgwE52lS5fy/vvv8+GHH9K8eXO2b9/O6NGjiY+PZ9CgQbacyWT/B6mUcthW3owZM5g8ebLDduv+g4QEWtBPS2KkRqX8mPWdBWlJfJEFaUmqYhaq+4UWjtmzAdsR+maYNTrjxo3jmWee4YEHHqBly5YMGDCAJ598khkzZgAQGxsLXGh2yuTl5Tm0POVNmDCBU6dO2R7Z2dm+2wkhhBDCA6XKO4/qyDCNztmzZ22XkZcJDAyktPT8WceGDRsSGxtLZmYmrVq1AqCoqIi1a9fy4osvVvi+FosFi8XisD193w76NgnSUUtinEYFpCXxRRa0bkmkUfFFFvS37kTrlkS/bbljtiisGNiDr1m9cOqqsq83KsNMdHr16sW0adNISEigefPmbNu2jblz5zJkyBDg/Cmr0aNHM336dBo1akSjRo2YPn06oaGh9O/fX+PRCyGEEEILhpnovPrqq/z9738nJSWFvLw84uPjefTRR3nuuedsmfHjx3Pu3DlSUlJsNwzMyMggPDzc7c9bddasq5bESI0KSEvim+yF/ZOsvpsPY7UkRmpUwLXflf7Lbo5MwB+k0fGcYSY64eHhpKWl2S4nd8ZkMpGamkpqaqrfxiWEEEL4WqkyUaoqedVVJV9vVIaZ6PjbqvzmhIbv0U1LYqRGBbRuPqQl0ToL0pK4nsXJMdZrFi73e6oqrz90ls07F4k/SKPjOcNcdSWEEEII4S5pdCqwOS8Bc80g9NKSGKtRuTBmyVadlsRYjQpOjrFes+D95qNqNiqgv2bdWmDGH6wEYK1kN2H10liMRiY6QgghhM4pL6zRUbJGR5SXlxvJprCy++vooSWRRsUXWZCWxDdZkJbE1az9MdZzFqr3+kNnWWtRNb0Ln4HIREcIIYTQOVmM7DmZ6FTAfNTMsZBgXbQORsuCtCS+yYK2LYmRGhX7Y6znLOhv3YnWLYl+23LHbElxKP5gVQFYVSXX6FTT8kmuuhJCCCFElSWNTgXCchQFwfppSYzUqIDWzYe0JNpny++ftCR6bkmM1ajYH2NdZK318IdSTJRWspsopXpWOjLREUIIIXRO1uh4TiY6FQjPLiHQrNBLS2KsRgWkJfFFtvz+6TsL0pK4mgWtWxKDNyoaZ7vEFSP0TSY6QgghhM55ZzGynLoS5YQcOkmNoGD005IYqVEB77cZ0pKArDtxNQtaNx/SkvgiC/pr1tP37SCqMT53fo1OJb/UU05dCSGEEEKPSr3wFRCyGFnYse4/SEigBf20JEZqVMqPWd9ZkJbEF1mQlqQqZqG6rz90zJ4N2I7QN5noCCGEEDona3Q8JxOdCqTv20HfJkE6akmM06iAtCS+yILWLYk0Kr7Igv7WnWjdkui3LXfMFoUVA3vwtVIC5D46HqrcURNCCCGE0DFpdCqw6qxZVy2JkRoVkJbEN9kL+ydZfTcfxmpJjNSogGu/K/2X3RyZgD9YlQmrquQNAyv5eqOSiY4QQgihc1YvXHVlraanrmSiU4FV+c0JDd+jm5bESI0KaN18SEuidRakJXE9i5NjrNcsXO73VFVef+gsm3cuEqFvMtERQgghdK5UBVBayauuSuWqK1He5rwEzDWD0EtLYqxG5cKYJVt1WhJjNSo4OcZ6zYJrTYIesuX3r/qtP3SWtRaY8Qc5deU5uepKCCGEEFWWNDoVyMuNZFOY5X8/6aElkUbFF1mQlsQ3WZCWxNWs/THWcxaq9/pDZ1lrkX9aklIqf9VUqXeGYjgy0RFCCCF0zjs3DKyeJ3FkolMB81Ezx0KCddE6GC0L0pL4JgvatiRGalTsj7Ges6C/dSdatyT6bcsdsyXFofiDd74ConpOdKrnXgshhBCiWpBGRwghhNC5UkyUUtk1OnJnZFFOWI6iIFg/p4OMdOoItD7FI6eDtM+W3z85HaTn00HGOnVkf4x1kbXWwx/k1JXnDLXXR44c4a9//St16tQhNDSUG264ga1bt9qeV0qRmppKfHw8ISEhdOrUiZ07d2o4YiGEEEJoyTCNzsmTJ2nfvj2dO3fmm2++4YorruCXX36hVq1atszMmTOZO3cuixcvpnHjxkydOpWuXbuyd+9ewsPD3fq88OwSAs0KvbQkxmpUQFoSX2TL75++syAtiatZ0LolMXijonG2S1wx/uCdGwYaqtvwGsNMdF588UXq16/PokWLbNsaNGhg+/9KKdLS0pg4cSL33nsvAO+++y4xMTF8+OGHPProo/4eshBCCOEVpcpEaWXvoyPfXq5vX3zxBcnJyfTt25e1a9dy5ZVXkpKSwvDhwwE4ePAgubm5dOvWzfYai8VCx44d2bBhg9sTnZBDJ6kRFIx+WhIjNSrg/TZDWhKQdSeuZkHr5kNaEl9kQX/Nevq+HUQ1RuiYYXqsAwcOMH/+fBo1asTKlSsZMWIEo0aNYsmSJQDk5uYCEBMTY/e6mJgY23POFBYWkp+fb/cQQggh9KT0f6euKvOQGwbqXGlpKa1bt2b69OkAtGrVip07dzJ//nwGDhxoy5lM9tWcUsphW3kzZsxg8uTJDtut+w8SEmhBPy2JkRqV8mPWdxakJfFFFqQlqYpZqO7rDx2zZwO24w/e+fby6jnRMcxex8XF0axZM7tt1157LVlZWQDExsYCOLQ3eXl5Di1PeRMmTODUqVO2R3Z2tpdHLoQQQgitGKbRad++PXv37rXbtm/fPhITEwFo2LAhsbGxZGZm0qpVKwCKiopYu3YtL774YoXva7FYsFgsDtvT9+2gb5MgHbUkxmlUQFoSX2RB65ZEGhVfZEF/6060bkn025Y7ZovCioE9+JoVE9ZK3vCvsq83KsNMdJ588knatWvH9OnTuf/++/nhhx9YuHAhCxcuBM6fsho9ejTTp0+nUaNGNGrUiOnTpxMaGkr//v01Hr0QQgjhOTl15TnDTHRuuukm0tPTmTBhAlOmTKFhw4akpaXx0EMP2TLjx4/n3LlzpKSkcPLkSdq0aUNGRobb99ABWHXWrKuWxEiNCkhL4pvshf2TrL6bD2O1JEZqVMC135X+y26OTMAfrFS+kbF6ZyiGY5iJDsBdd93FXXfdVeHzJpOJ1NRUUlNT/TcoIYQQQuiWoSY6/rQqvzmh4Xt005IYqVEBrZsPaUm0zoK0JK5ncXKM9ZqFy/2eqsrrD51l885F4g9y6spzMtERQgghdE6+1NNzMtGpwOa8BMw1g9BLS2KsRuXCmCVbdVoSYzUqODnGes2Ca02CHrLl96/6rT90lrUWmKnK5s2bx6xZs8jJyaF58+akpaXRoUOHCvMffPABM2fO5OeffyYyMpLu3bsze/Zs6tSp48dR26ue0zshhBDCQBQmSiv5UG4uZl66dCmjR49m4sSJbNu2jQ4dOtCjRw/b/esutn79egYOHMjQoUPZuXMn//znP9m8eTPDhg3zxiHwmDQ6FcjLjWRTWNn9dfTQkkij4ossSEvimyxIS+Jq1v4Y6zkL1Xv9obOstUjhD1qcupo7dy5Dhw61TVTS0tJYuXIl8+fPZ8aMGQ75TZs20aBBA0aNGgWcv7/do48+ysyZMys17sqSRkcIIYSoRi7+fsfCwkKHTFFREVu3brX7omyAbt26sWHDBqfv265dO3799VeWL1+OUopjx47xySef0LNnT5/sh6uk0amA+aiZYyHBumgdjJYFaUl8kwVtWxIjNSr2x1jPWdDfuhOtWxL9tuWO2ZLiUPyhVJkoVZW7j07Z6+vXr2+3fdKkSQ63ZTl+/DhWq9WtL8pu164dH3zwAf369aOgoICSkhLuvvtuXn311UqNu7JkoiOEEELoXNk3kFf2PQCys7OJiIiwbXf2NUhl3Pmi7F27djFq1Ciee+45kpOTycnJYdy4cYwYMYK33367UmOvDJnoVCAsR1EQrJ+WxEiNCmjdfEhLon22/P5JS6LnlsRYjYr9MdZF1loPo4mIiLCb6DgTHR1NYGCgW1+UPWPGDNq3b8+4ceMAuO666wgLC6NDhw5MnTqVuLg47+yAm2SNjhBCCKFzZaeuKvtwldlsJikpiczMTLvtmZmZtGvXzulrzp49S0CA/bQiMDAQON8EaUUanQqEZ5cQaFbopSUxVqMC2jYf0pJonQVpSVzNgtYticEbFY2zXeKK8YdSAiitZDfh7uvHjBnDgAEDaN26NW3btmXhwoVkZWUxYsQIACZMmMCRI0dYsmQJAL169WL48OHMnz/fdupq9OjR3HzzzcTHx1dq7JUhEx0hhBBC56zKhLWSi5HdfX2/fv04ceIEU6ZMIScnhxYtWrB8+XISExMByMnJsbunzuDBgzl9+jSvvfYaTz31FLVq1eL222/nxRdfrNS4K0smOhUIOXSSGkHB6KclMVKjAt5vM6QlAVl34moWtG4+pCXxRRb016yn79tBVGOqrJSUFFJSUpw+t3jxYodtjz/+OI8//riPR+UemegIIYQQOufNy8urG5noVMC6/yAhgRb005IYqVEpP2Z9Z0FaEl9kQVqSqpiF6r7+0DF7NmA7/qC88O3lqpp+qWf13GshhBBCVAvS6FQgfd8O+jYJ0lFLYpxGBaQl8UUWtG5JpFHxRRb0t+5E65ZEv225Y7YorBjYg69ZMWF180s5nb1HdSQTHSGEEELnSlXl19iUancrG03JRKcCq86addWSGKlRAWlJfJO9sH+S1XfzYayWxEiNCrj2u9J/2c2RCQh9k4mOEEIIoXOlXliMXNnXG5VMdCqwKr85oeF7dNOSGKlRAa2bD2lJtM6CtCSuZ3FyjPWahcv9nqrK6w+dZfPOReIPpZgoreQam8q+3qhkoiOEEELonBZ3Rq4qZKJTgc15CZhrBqGXlsRYjcqFMUu26rQkxmpUcHKM9ZoF15oEPWTL71/1W3/oLGstMCP0TSY6QgghhM7JGh3PyURHCCGE0LlSvPAVELJGR5SXlxvJpjDL/37Sw+kgOXXkiyzI6SDfZEFOB7matT/Ges5C9b7QwlnWWlRNb05jIDLREUIIIXROeeGqKyWNjijPfNTMsZBgXbQORsuCtCS+yYK2LYmRGhX7Y6znLOhvga3WLYl+23LHbElxKP4g317uueq5MkkIIYQQ1YI0OhUIy1EUBOunJTFSowJaNx/SkmifLb9/0pLouSUxVqNif4x1kbXWwx/kqivPGXavZ8yYgclkYvTo0bZtSilSU1OJj48nJCSETp06sXPnTu0GKYQQQnhB2amryj6qI0M2Ops3b2bhwoVcd911dttnzpzJ3LlzWbx4MY0bN2bq1Kl07dqVvXv3Eh4e7tZnhGeXEGhW6KUlMVajAtKS+CJbfv/0nQVpSVzNgtYticEbFY2zXeKKEfpmuEbnzz//5KGHHuLNN98kKirKtl0pRVpaGhMnTuTee++lRYsWvPvuu5w9e5YPP/xQwxELIYQQlVP2XVeVfVRHhmt0HnvsMXr27Mkdd9zB1KlTbdsPHjxIbm4u3bp1s22zWCx07NiRDRs28Oijj7r1OSGHTlIjKBj9tCRGalRA2+ZDWhKtsyAtietZ+2MsWf225c6y6ft2ENUYn5OrrjxnqInOxx9/zI8//sjmzZsdnsvNzQUgJibGbntMTAyHDx+u8D0LCwspLCy0/Zyfn++l0QohhBDeIRMdz7k00bnxxhvdelOTycQXX3zBlVde6dGgnMnOzuaJJ54gIyOD4ODgS352eUoph23lzZgxg8mTJztst+4/SEigBf20JEZqVMqPWd9ZkJbEF1mQlqQqZqG6rz90zJ4N2I7QN5cmOtu3b+epp56iZs2al80qpXjhhRfsWhJv2Lp1K3l5eSQlJdm2Wa1W1q1bx2uvvcbevXuB881OXFycLZOXl+fQ8pQ3YcIExowZY/s5Pz+f+vXre3XsQgghRGVIo+M5l09djRs3jiuuuMKl7Jw5czweUEW6dOnCjh077LY9/PDDNG3alKeffpqrrrqK2NhYMjMzadWqFQBFRUWsXbuWF198scL3tVgsWCwWh+3p+3bQt0mQjloS4zQqIC2JL7KgdUsijYovsqC/dSdatyT6bcsds0VhxcAefE0mOp5zaaJz8OBB6tat6/Kb7tq1i/j4eI8H5Ux4eDgtWrSw2xYWFkadOnVs20ePHs306dNp1KgRjRo1Yvr06YSGhtK/f3+vjkUIIYQQxuDSRCcxMdGtN9Xq1M/48eM5d+4cKSkpnDx5kjZt2pCRkeH2PXQAVp0166olMVKjAtKS+CZ7Yf8kq+/mw1gtiZEaFXDtd6X/spsjE/AHBV74Us/qyaOrrv744w9++OEH8vLyKC0ttXtu4MCBXhmYK7799lu7n00mE6mpqaSmpvptDEIIIYSvyakrz7k90fnyyy956KGHOHPmDOHh4XZXNJlMJr9OdHxpVX5zQsP36KYlMVKjAlo3H9KSaJ0FaUlcz+LkGOs1C5f7PVWV1x86y+adi0ToW4C7L3jqqacYMmQIp0+f5o8//uDkyZO2x++//+6LMQohhBDVmnzXlefcbnSOHDnCqFGjCA0N9cV4dGNzXgLmmkHopSUxVqNyYcySrTotibEaFZwcY71mwfvNR9VsVEB/zbq1wIw/yKkrz7nd6CQnJ7NlyxZfjEUIIYQQwqtcanS++OIL2//v2bMn48aNY9euXbRs2ZKgoCC77N133+3dEWokLzeSTWFl99fRQ0sijYovsiAtiW+yIC2Jq1n7Y6znLFTv9YfOstYi/1zLJI2O51ya6PTp08dh25QpUxy2mUwmrFZrpQclhBBCiAuUMqEqOVGp7OuNyqWJzsWXkFcH5qNmjoUE66J1MFoWpCXxTRa0bUmM1KjYH2M9Z0F/6060bkn025Y7ZkuK/bNetRRTpe+jU9nXG5Xba3SWLFni9HusioqKWLJkiVcGJYQQQgjhDW5fdfXwww/TvXt3h++9On36NA8//HCVuY9OWI6iIFg/LYmRGhXQuvmQlkT7bPn9k5ZEzy2JsRoV+2Osi6y1Hv4ga3Q85/ZERylld5PAMr/++iuRkXLjJCGEEMLbZI2O51ye6LRq1QqTyYTJZKJLly7UqHHhpVarlYMHD9K9e3efDFIL4dklBJoVemlJjNWogLQkvsiW3z99Z0FaElezoHVLYvBGReNsl7hihL65PNEpu/Jq+/btJCcnU7NmTdtzZrOZBg0acN9993l9gEIIIUR1J6euPOfyRGfSpElYrVYSExNJTk4mLi7Ol+PSXMihk9QICkY/LYmRGhXwfpshLQnIuhNXs6B18yEtiS+yoL9mPX3fDqIa43Ny6spzbl11FRgYyIgRIygoKPDVeIQQQgghvMbtxcgtW7bkwIEDNGzY0Bfj0Q3r/oOEBFrQT0tipEal/Jj1nQVpSXyRBWlJqmIWqvv6Q8fs2YDt+IPywqkraXRcNG3aNMaOHctXX31FTk4O+fn5dg8hhBBCeJcClKrkQ+ud0IjbjU7ZlVV333233WXmZZedV5WvgEjft4O+TYJ01JIYp1EBaUl8kQWtWxJpVHyRBf2tO9G6JdFvW+6YLQorBvYg9Mvtic6aNWt8MQ4hhBBCVKAUEyb5CgiPuD3R6dixoy/GoTurzpp11ZIYqVEBaUl8k72wf5LVd/NhrJbESI0KuPa70n/ZzZEJ+INcdeU5tyc6AH/88Qdvv/02u3fvxmQy0axZM4YMGSJ3RhZCCCF8oFSZMMl9dDzi9mLkLVu2cPXVV/PSSy/x+++/c/z4cebOncvVV1/Njz/+6IsxCiGEEEJ4xO1G58knn+Tuu+/mzTfftH0NRElJCcOGDWP06NGsW7fO64PUwqr85oSG79HN6SAjnToCrU/xyOkgrbMgp4Ncz+LkGOs1C5f7PVWVL7Rwls07558zGWVXTlX2Paojtyc6W7ZssZvkANSoUYPx48fTunVrrw5OCCGEELJGpzLcnuhERESQlZVF06ZN7bZnZ2cTHh7utYFpbXNeAuaaQeilJTFWo3JhzJKtOi2JsRoVnBxjvWbBtSZBD9ny+1f9LrRwlrUWmBH65vYanX79+jF06FCWLl1KdnY2v/76Kx9//DHDhg3jwQcf9MUYhRBCiGqtrNGp7KM6crvRmT17NiaTiYEDB1JSUgJAUFAQf/vb33jhhRe8PkCt5OVGsinM8r+f9NCSSKPiiyxIS+KbLEhL4mrW/hjrOQvVe/2hs6y1yD8LX+SqK8+5PdExm828/PLLzJgxg19++QWlFNdccw2hoaG+GJ8QQgghhMc8uo8OQGhoKC1btvTmWHTFfNTMsZBgXbQORsuCtCS+yYL3m4+q2qjYH2M9Z0F/6060bkn025Y7ZkuK/fMf+XLVlefcnuicOXOGF154gX/961/k5eVRWlpq9/yBAwe8NjghhBBClE10KnvVlZcGYzBuT3SGDRvG2rVrGTBgAHFxcXZf7FmVhOUoCoL105IYqVEBrZsPaUm0z5bfP2lJ9NySGKtRsT/Gusha6yH0ze2JzjfffMPXX39N+/btfTEeIYQQQlxE7qPjObcnOlFRUdSuXfvyQS+bMWMGy5YtY8+ePYSEhNCuXTtefPFFmjRpYssopZg8eTILFy7k5MmTtGnThtdff53mzZu7/Xnh2SUEmhV6aUmM1aiAtCS+yJbfP31nQVoSV7OgdUti8EZF42yXuGL8Qf3vUdn3qI4C3H3B888/z3PPPcfZs2d9MZ4KrV27lscee4xNmzaRmZlJSUkJ3bp148yZM7bMzJkzmTt3Lq+99hqbN28mNjaWrl27cvr0ab+OVQghhPAmuY+O59xudObMmcMvv/xCTEwMDRo0ICgoyO55X32x54oVK+x+XrRoEVdccQVbt27ltttuQylFWloaEydO5N577wXg3XffJSYmhg8//JBHH33Urc8LOXSSGkHB6KclMVKjAto2H9KSaJ0FaUlcz9ofY8nqty13lk3ft4Ooxggdc3ui06dPHx8Mw32nTp0CsJ1GO3jwILm5uXTr1s2WsVgsdOzYkQ0bNlQ40SksLKSwsND2c35+vg9HLYQQQnhAzl15zO2JzqRJk1zKffTRR9x9992EhYW5PajLUUoxZswYbr31Vlq0aAFAbm4uADExMXbZmJgYDh8+XOF7zZgxg8mTJztst+4/SEigBf20JEZqVMqPWd9ZkJbEF1mQlqQqZqG6rz90zJ4N2I5feOPUkwevnzdvHrNmzSInJ4fmzZuTlpZGhw4dKswXFhYyZcoU3n//fXJzc6lXrx4TJ05kyJAhlRl5pbi9RsdVjz76KMeOHfPJe48cOZL//ve/fPTRRw7PXXy5u1LqkpfAT5gwgVOnTtke2dnZXh+vEEIIYTRLly5l9OjRTJw4kW3bttGhQwd69OhBVlZWha+5//77+de//sXbb7/N3r17+eijjxy+BNzf3G50XKV8dGeixx9/nC+++IJ169ZRr96F+xfExsYC55uduLg42/a8vDyHlqc8i8WCxWJx2J6+bwd9mwTpqCUxTqMC0pL4IgtatyTSqPgiC/pbd6J1S6LfttwxWxRWDOzB17S4M/LcuXMZOnQow4YNAyAtLY2VK1cyf/58ZsyY4ZBfsWIFa9eu5cCBA7ZlJQ0aNKjcoL3AZ42OtymlGDlyJMuWLWP16tU0bNjQ7vmGDRsSGxtLZmambVtRURFr166lXbt2/h6uEEII4TXevOoqPz/f7lF+nWqZoqIitm7darfuFaBbt25s2LDB6Ri/+OILWrduzcyZM7nyyitp3LgxY8eO5dy5c94/IG7wWaPjbY899hgffvghn3/+OeHh4bY1OZGRkYSEhGAymRg9ejTTp0+nUaNGNGrUiOnTpxMaGkr//v3d/rxVZ826akmM1KiAtCS+yV7YP8nqu/kwVktipEYFXPtd6b/s5sgEjKZ+/fp2P0+aNInU1FS7bcePH8dqtTpd91r29+/FDhw4wPr16wkODiY9PZ3jx4+TkpLC77//zjvvvOPVfXCHYSY68+fPB6BTp0522xctWsTgwYMBGD9+POfOnSMlJcV2w8CMjAzCw8P9PFohhBDCi5TJo8XEDu8BZGdnExERYdvsbPlGGXfWvZaWlmIymfjggw+IjIwEzp/++stf/sLrr79OSEiI09f5mmEmOq6s+TGZTKSmpjrMTD2xKr85oeF7dNOSGKlRAa2bD2lJtM6CtCSuZ3FyjPWahcv9nqrK6w+dZfPOReIP3lyjExERYTfRcSY6OprAwECH9uZS617j4uK48sorbZMcgGuvvRalFL/++iuNGjWq3A54yGdrdBITEx1uJiiEEEII/TObzSQlJdmtewXIzMyscN1r+/btOXr0KH/++adt2759+wgICLC7eMjf3G50srOzMZlMtkH/8MMPfPjhhzRr1oxHHnnElvvpp5+8N0oNbM5LwFwzCL20JMZqVC6MWbJVpyUxVqOCk2Os1yx4v/momo0K6K9ZtxaY8QsNbhg4ZswYBgwYQOvWrWnbti0LFy4kKyuLESNGAOdvz3LkyBGWLFkCQP/+/Xn++ed5+OGHmTx5MsePH2fcuHEMGTJEs9NW4EGj079/f9asWQOcv5S7a9eu/PDDD/zf//0fU6ZM8foAhRBCiOpOi++66tevH2lpaUyZMoUbbriBdevWsXz5chITEwHIycmxu6dOzZo1yczM5I8//qB169Y89NBD9OrVi1deecWrx8Jdbjc6P/30EzfffDMA//jHP2jRogXfffcdGRkZjBgxgueee87rg9RCXm4km8LKFmjpoSWRRsUXWZCWxDdZkJbE1az9MdZzFqr3+kNnWWuRH79XQYOvcEhJSSElJcXpc4sXL3bY1rRpU4fTXVpzu9EpLi62rdBetWoVd999N3B+53Jycrw7OiGEEEKISnC70WnevDkLFiygZ8+eZGZm8vzzzwNw9OhR6tSp4/UBasV81MyxkGBdtA5Gy4K0JL7JgrYtiZEaFftjrOcs6G/didYtiX7bcsdsSXEo/uDJqSdn71Edud3ovPjii7zxxht06tSJBx98kOuvvx44f0fEslNaQgghhPAi5aVHNeR2o9OpUyeOHz9Ofn4+UVFRtu2PPPIIoaH+mdn6Q1iOoiBYPy2JkRoV0Lr5kJZE+2z5/ZOWRM8tibEaFftjrIusVbvLpoVr3G504PzN+7Zu3cobb7zB6dOnATCbzVVqoiOEEELoh8lLj+rH7Ubn8OHDdO/enaysLAoLC+natSvh4eHMnDmTgoICFixY4Itx+l14dgmBZoVeWhJjNSqgbfMhLYnWWZCWxNUsaN2SGLxR0TjbJa4Yv9DgPjpVhduNzhNPPEHr1q05efKk3Q2A7rnnHv71r395dXBCCCGEEJXhdqOzfv16vvvuO8xm+7tBJiYmcuTIEa8NTGshh05SIygY/bQkRmpUQNvmQ1oSrbMgLYnrWftjLFn9tuXOsun7dhDVGN+TRsdjbk90SktLsVqtDtt//fVX+ZZwIYQQwhe8+O3l1Y3bE52uXbuSlpbGwoULgfPfGP7nn38yadIk7rzzTq8PUCvW/QcJCbSgn5bESI1K+THrOwvSkvgiC9KSVMUsVPf1h47ZswHbEfrm9kTnpZdeonPnzjRr1oyCggL69+/Pzz//THR0NB999JEvxiiEEEJUa0qdf1T2Paojtyc68fHxbN++nY8++ogff/yR0tJShg4dykMPPaTpt5MKIYQQVZas0fGY2xMdgJCQEIYMGcKQIUO8PR7dSN+3g75NgnR0Osg4p45ATgf5Igtanw6SU0e+yIL+FthqfTpIv8sCHLNFYcXAHnxO1uh4zO3LywHee+89br31VuLj4zl8+DBw/pTW559/7tXBCSGEEEJUhtuNzvz583nuuecYPXo0U6dOtV2BFRUVRVpaGr179/b6ILWw6qxZVy2JkRoVkJbEN9kL+ydZfTcfxmpJjNSogGu/K/2X3RyZgD+Y1PlHZd+jOnK70Xn11Vd58803mThxIjVqXJgntW7dmh07dnh1cEIIIYRAvtSzEtxudA4ePEirVq0ctlssFs6cOeOVQenBqvzmhIbv0U1LYqRGBbRuPqQl0ToL0pK4nsXJMdZrFjxtPqrC+kNn2bxzkQh9c7vRadiwIdu3b3fY/s0339CsWTNvjEkIIYQQ5ZUtRq7soxpyu9EZN24cjz32GAUFBSil+OGHH/joo4+YMWMGb731li/GqInNeQmYawahl5bEWI3KhTFLtuq0JMZqVHByjPWaBe83H1WzUQH9NevWAvuvQ/IZubzcY25PdB5++GFKSkoYP348Z8+epX///lx55ZW8/PLLPPDAA74YoxBCCCGER9ya6JSUlPDBBx/Qq1cvhg8fzvHjxyktLeWKK67w1fg0k5cbyaYwy/9+0kNLIo2KL7IgLYlvsiAtiatZ+2Os5yxU7/WHzrLWIj/VJNLoeMytNTo1atTgb3/7G4WFhQBER0dXyUmOEEIIoSty1ZXH3D511aZNG7Zt20ZiYqIvxqMb5qNmjoUE66J1MFoWpCXxTRa0bUmM1KjYH2M9Z0F/6060bkn025Y7ZkuKQxH65vZEJyUlhaeeeopff/2VpKQkwsLC7J6/7rrrvDY4IYQQQiBfAVEJbk90+vXrB8CoUaNs20wmE0opTCaT7U7JRheWoygI1k9LYqRGBbRuPqQl0T5bfv+kJdFzS2KsRsX+GOsia62HP8idkT3n9kTn4MGDvhiHEEIIISoii5E95vZExwhrc+bNm8esWbPIycmhefPmpKWl0aFDB7feIzy7hECzQi8tibEaFZCWxBfZ8vun7yxIS+JqFrRuSQzeqGic7RJXjNA3tyc6X3zxhdPtJpOJ4OBgrrnmGho2bFjpgXlq6dKljB49mnnz5tG+fXveeOMNevTowa5du0hI8M+XrwkhhBDCfQ8//DB//etfuf322zGZvLOmyO2JTp8+fWxrcsorv07n1ltv5bPPPiMqKsorg3TH3LlzGTp0KMOGDQMgLS2NlStXMn/+fGbMmOHy+4QcOkmNoGD005IYqVEB77cZ0pKArDtxNQtaNx/SkvgiC/pr1tP37SCqMT5nwgtrdLwyEt86ceIEPXv2pE6dOjzwwAMMGDCAG264oVLvGeDuCzIzM7npppvIzMzk1KlTnDp1iszMTG6++Wa++uor1q1bx4kTJxg7dmylBuaJoqIitm7dSrdu3ey2d+vWjQ0bNjh9TWFhIfn5+XYPIYQQQvjfF198QW5uLpMmTWLr1q0kJSXRrFkzpk+fzqFDhzx6T7cbnSeeeIKFCxfSrl0727YuXboQHBzMI488ws6dO0lLS2PIkCEeDagyjh8/jtVqJSYmxm57TEwMubm5Tl8zY8YMJk+e7LDduv8gIYEW9NOSGKlRKT9mfWdBWhJfZEFakqqYheq+/tAxezZgO35RjS4vr1WrFo888giPPPIIv/76Kx999BHvvPMOzz33HCUlJW6/n9uNzi+//EJERITD9oiICA4cOABAo0aNOH78uNuD8ZaLz+uVnVJzZsKECbZm6tSpU2RnZ/tjiEIIIYTrquGdkYuLi9myZQvff/89hw4dcigxXOV2o5OUlMS4ceNYsmQJdevWBeC3335j/Pjx3HTTTQD8/PPP1Kvnn3sLlBcdHU1gYKBDe5OXl1fhAbJYLFgsFoft6ft20LdJkI5aEuM0KiAtiS+yoHVLIo2KL7Kgv3UnWrck+m3LHbNFYcXAHoT3rFmzhg8//JBPP/0Uq9XKvffey5dffsntt9/u0fu5PdF5++236d27N/Xq1aN+/fqYTCaysrK46qqr+PzzzwH4888/+fvf/+7RgCrDbDaTlJREZmYm99xzj217ZmYmvXv39vt4hBBCCK+oJvfRqVevHidOnCA5OZk33niDXr16ERwcXKn3dHui06RJE3bv3s3KlSvZt28fSimaNm1K165dCQg4fyasT58+lRpUZYwZM4YBAwbQunVr2rZty8KFC8nKymLEiBFuvc+qs2ZdtSRGalRAWhLfZC/sn2T13XwYqyUxUqMCrv2u9F92c6R/bltSXe6M/Nxzz9G3b1+vXrXt9kQHzq+B6d69O506dcJisXjtWndv6NevHydOnGDKlCnk5OTQokULli9fbogbHQohhBDV2SOPPOL193R7olNaWsq0adNYsGABx44dY9++fVx11VX8/e9/p0GDBgwdOtTrg3RXSkoKKSkplXqPVfnNCQ3fo5uWxEiNCmjdfEhLonUWpCVxPYuTY6zXLFzu91RVXn/oLJt3LhK/qCanrnzB7auupk6dyuLFi5k5cyZms9m2vWXLlrz11lteHZwQQgghqJZXXXmL243OkiVLWLhwIV26dLFb93LdddexZ0/VWXm+OS8Bc80g9NKSGKtRuTBmyVadlsRYjQpOjrFes+D95qNqNiqgv2bdWnDhP/h9qbqs0fEFtxudI0eOcM011zhsLy0tpbhYvtxMCCGEEPrhdqPTvHlz/v3vfzss7v3nP/9Jq1atvDYwreXlRrIprOz+OnpoSaRR8UUWpCXxTRakJXE1a3+M9ZyF6r3+0FnWWuSnmqQa3RnZ29ye6EyaNIkBAwZw5MgRSktLWbZsGXv37mXJkiV89dVXvhijEEIIUb3JYmSPuT3R6dWrF0uXLmX69OmYTCaee+45brzxRr788ku6du3qizFqwnzUzLGQYF20DkbLgrQkvsmCti2JkRoV+2Os5yzob92J1i2Jfttyx2xJcShC39ye6AAkJyeTnJzs7bEIIYQQwglZjOw5jyY61UFYjqIgWD8tiZEaFdC6+ZCWRPts+f2TlkTPLYmxGhX7Y6yLrNVP3+sop6485tJEJyoqyuW7H//++++VGpAQQgghhLe4NNFJS0uz/f8TJ04wdepUkpOTadu2LQAbN25k5cqVmnyRp6+EZ5cQaFbopSUxVqMC0pL4Ilt+//SdBWlJXM2C1i2JwRsVjbNd4vx0WxUvnLqSRucSBg0aZPv/9913H1OmTGHkyJG2baNGjeK1115j1apVPPnkk94fpRBCCFGdyakrjwW4+4KVK1fSvXt3h+3JycmsWrXKK4MSQgghhPAGtxcj16lTh/T0dMaNG2e3/bPPPqNOnTpeG5jWQg6dpEZQMPo5HWSkU0fg/dM2cjoIZIGtq1nQ+hSPnA7yRRb0t4Qgfd8Oohrje9LoeMztic7kyZMZOnQo3377rW2NzqZNm1ixYoV8qacQQgjhA3J5uefcnugMHjyYa6+9lldeeYVly5ahlKJZs2Z89913tGnTxhdj1IR1/0FCAi3opyUxUqNSfsz6zoK0JL7IgrQkVTEL1f1CC8fs2YDtCH1ze6ID0KZNGz744ANvj0UIIYQQwqtcmujk5+cTERHh8puePn2a8PBwjwelB+n7dtC3SZCOWhLjNCogLYkvsqB1SyKNii+yoL91J1q3JPptyx2zRWHFwB58TtboeMylq66ioqLIy8tz+U2vvPJKDhw44PGghBBCCHFB2Rqdyj6qI5caHaUUb731FjVr1nTpTYuL/XQDJR9addasq5bESI0KSEvim+yF/ZOsvpsPY7UkRmpUwLXflf7Lbo5MQOibSxOdhIQE3nzzTZffNDY2lqCgII8HJYQQQoiLVNNGprJcmugcOnTIx8PQn1X5zQkN36OblsRIjQpo3XxIS6J1FqQlcT2Lk2Os1yxc7vdUVV5/6Cybdy4Sv5A1Oh5zaY2OEEIIIYQReXR5eXWwOS8Bc80g9NKSGKtRuTBmyVadlsRYjQpOjrFes+D95qNqNiqgv2bdWmDGH+SGgZ6TiY4QQgihd3LqymMy0alAXm4km8Is//tJDy2JNCq+yIK0JL7JgrQkrmbtj7Ges1C91x86y1qLqunswUBkoiOEEELonJy68pxHE51///vfvPHGG/zyyy988sknXHnllbz33ns0bNiQW2+91dtj1IT5qJljIcG6aB2MlgVpSXyTBW1bEiM1KvbHWM9Z0N+6E61bEv225Y7ZkuJQ/EKjU1fz5s1j1qxZ5OTk0Lx5c9LS0ujQocNlX/fdd9/RsWNHWrRowfbt293/YC9y+6qrTz/9lOTkZEJCQti2bRuFhYXA+a99mD59utcHKIQQQlR7yksPNyxdupTRo0czceJEtm3bRocOHejRowdZWVmXfN2pU6cYOHAgXbp0ce8DfcTtRmfq1KksWLCAgQMH8vHHH9u2t2vXjilTpnh1cFoKy1EUBOunJTFSowJaNx/SkmifLb9/0pLouSUxVqNif4x1kbXWo6qaO3cuQ4cOZdiwYQCkpaWxcuVK5s+fz4wZMyp83aOPPkr//v0JDAzks88+89NoK+Z2o7N3715uu+02h+0RERH88ccf3hiTEEIIIcrx5ndd5efn2z3KzsyUV1RUxNatW+nWrZvd9m7durFhw4YKx7lo0SJ++eUXJk2a5NX9rwy3G524uDj2799PgwYN7LavX7+eq666ylvjsnPo0CGef/55Vq9eTW5uLvHx8fz1r39l4sSJmM0X7mGQlZXFY489xurVqwkJCaF///7Mnj3bLuOq8OwSAs0KvbQkxmpUQFoSX2TL75++syAtiatZ0LolMXijonG2S5yfvtvRi2t06tevb7d50qRJpKam2m07fvw4VquVmJgYu+0xMTHk5uY6ffuff/6ZZ555hn//+9/UqKGfa53cHsmjjz7KE088wTvvvIPJZOLo0aNs3LiRsWPH8txzz/lijOzZs4fS0lLeeOMNrrnmGn766SeGDx/OmTNnmD17NgBWq5WePXtSt25d1q9fz4kTJxg0aBBKKV599VWfjEsIIYQwmuzsbCIiImw/WyyWCrMmk8nuZ6WUwzY4/3dw//79mTx5Mo0bN/beYL3A7YnO+PHjOXXqFJ07d6agoIDbbrsNi8XC2LFjGTlypC/GSPfu3enevbvt56uuuoq9e/cyf/5820QnIyODXbt2kZ2dTXz8+f/0mzNnDoMHD2batGl2f6iuCDl0khpBweinJTFSowLebzOkJQFZd+JqFrRuPqQl8UUW9Nesp+/bQZQ//l73YqMTERFx2b8To6OjCQwMdGhv8vLyHFoeOH9B0pYtW9i2bZttLlBaWopSiho1apCRkcHtt99eyR3wjEfd0rRp05g4cSK7du2itLSUZs2aUbNmTW+P7ZJOnTpF7dq1bT9v3LiRFi1a2CY5AMnJyRQWFrJ161Y6d+7s9H0KCwvtzk/m5+f7btBCCCGEB/x9Hx2z2UxSUhKZmZncc889tu2ZmZn07t3bIR8REcGOHTvsts2bN4/Vq1fzySef0LBhQ4/HXVken0QLDQ2ldevW3hyLy3755RdeffVV5syZY9uWm5vrMMuMiorCbDZXeD4RYMaMGUyePNlhu3X/QUICLeinJTFSo1J+zPrOgrQkvsiCtCRVMQvVff2hY/ZswHaqqjFjxjBgwABat25N27ZtWbhwIVlZWYwYMQKACRMmcOTIEZYsWUJAQAAtWrSwe/0VV1xBcHCww3Z/c2mic++997r8hsuWLXM5m5qa6nSSUd7mzZvtJlRHjx6le/fu9O3b13bJWxln5w0rOp9YZsKECYwZM8b2c35+vsNCLSGEEEJTGtwwsF+/fpw4cYIpU6aQk5NDixYtWL58OYmJiQDk5ORc9p46euDSRCcyMtL2/5VSpKenExkZaZuAbN26lT/++MOtCRHAyJEjeeCBBy6ZKX9119GjR+ncubNtZllebGws33//vd22kydPUlxc7PR8YhmLxeJ0IVb6vh30bRKko5bEOI0KSEviiyxo3ZJIo+KLLOhv3YnWLYl+23LHbFFYMbAHX9PqKyBSUlJISUlx+tzixYsv+drU1FSHq7m04NJEZ9GiRbb///TTT3P//fezYMECAgMDgfOrrVNSUtxe8BsdHU10dLRL2SNHjtC5c2eSkpJYtGgRAQEBds+3bduWadOmkZOTQ1xcHHB+gbLFYiEpKcmtcQkhhBCianB7jc4777zD+vXrbZMcgMDAQMaMGUO7du2YNWuWVwcI55ucTp06kZCQwOzZs/ntt99sz8XGxgLnb2LUrFkzBgwYwKxZs/j9998ZO3Ysw4cPd3sCBrDqrFlXLYmRGhWQlsQ32Qv7J1l9Nx/GakmM1KiAa78r/ZfdHJmAX2j0XVdVgdsTnZKSEnbv3k2TJk3stu/evZvS0lKvDay8jIwM9u/fz/79+6lXz/5220qd/5MLDAzk66+/JiUlhfbt29vdMFAIIYQwNJnoeMztic7DDz/MkCFD2L9/P7fccgsAmzZt4oUXXuDhhx/2+gABBg8ezODBgy+bS0hI4KuvvvLKZ67Kb05o+B7dtCRGalRA6+ZDWhKtsyAtietZnBxjvWbhcr+nqvL6Q2fZvHMX1rD6kul/j8q+R3Xk9kRn9uzZxMbG8tJLL5GTkwOc/1qI8ePH89RTT3l9gEIIIYQQnnJ7ohMQEMD48eMZP3687eZ6nqyB0bvNeQmYawahl5bEWI3KhTFLtuq0JMZqVHByjPWaBdeaBD1ky+9f9Vt/6CxrLXD/uxQ9IqeuPOb2RKe8qjjBEUIIIfRGq8vLqwK3JzoNGza85A34Dhw4UKkB6UVebiSbwsrur6OHlkQaFV9kQVoS32RBWhJXs/bHWM9ZqN7rD51lrUXVdPZgIG5PdEaPHm33c3FxMdu2bWPFihWMGzfOW+MSQgghRBk5deUxtyc6TzzxhNPtr7/+Olu2bKn0gPTCfNTMsZBgXbQORsuCtCS+yYK2LYmRGhX7Y6znLOhv3YnWLYl+23LHbElxKH5TTScqlRXgrTfq0aMHn376qbfeTgghhBCi0iq1GLm8Tz75hNq1a18+KIQQQgi3yGJkz7k90WnVqpXdYmSlFLm5ufz222/MmzfPq4PTUliOoiBYP6eDjHTqCLQ+xSOng7TPlt8/OR2k59NBxjp1ZH+MdZG12t+t32dkjY7H3J7o9O7d226iExAQQN26denUqRNNmzb16uCEEEIIISrD7YmOHr5y3R/Cs0sINCv00pIYq1EBaUl8kS2/f/rOgrQkrmZB65bE4I2KxtkuccX4g5y68pzbi5EDAwPJy8tz2H7ixAm7bzQXQgghhJcoLz2qIbcbnbJvC79YYWEhZrOfboXtByGHTlIjKBj9tCRGalRA2+ZDWhKtsyAtietZ+2MsWf225c6y6ft2ENUYn5NGx3MuT3ReeeUVAEwmE2+99RY1a9a0PWe1Wlm3bp2s0RFCCCGErrg80XnppZeA843OggUL7E5Tmc1mGjRowIIFC7w/Qo1Y9x8kJNCCfloSIzUq5ces7yxIS+KLLEhLUhWzUN3XHzpmzwZsxy/kqiuPuTzROXjwIACdO3dm2bJlREVF+WxQQgghhChHJjoec3uNzpo1a3wxDt1J37eDvk2CdNSSGKdRAWlJfJEFrVsSaVR8kQX9rTvRuiXRb1vumC0KKwb2IPTLpYnOmDFjeP755wkLC2PMmDGXzM6dO9crAxNCCCHEebIY2XMuTXS2bdtGcfH5ewX8+OOPdjcMrKpWnTXrqiUxUqMC0pL4Jnth/ySr7+bDWC2JkRoVcO13pf+ymyMT8As5deUxlyY65U9Xffvtt74aixBCCCGEV7m9RmfIkCG8/PLLhIeH220/c+YMjz/+OO+8847XBqelVfnNCQ3fo5uWxEiNCmjdfEhLonUWpCVxPYuTY6zXLFzu91RVXn/oLJt3LhJ/MCmFqYL72LnzHtVRgLsvePfddzl37pzD9nPnzrFkyRKvDEoIIYQQ5cidkT3mcqOTn5+PUgqlFKdPnyY4ONj2nNVqZfny5VxxxRU+GaQWNuclYK4ZhF5aEmM1KhfGLNmq05IYq1HByTHWaxa833xUzUYF9NesWwuqzjcCVFUuT3Rq1aqFyWTCZDLRuLHj/a5NJhOTJ0/26uCEEEIIIVddVYbLE501a9aglOL222/n008/pXbt2rbnzGYziYmJxMfH+2SQWsjLjWRTmOV/P+mhJZFGxRdZkJbEN1mQlsTVrP0x1nMWqvf6Q2dZa5GfZg9y1ZXHXJ7odOzYETh/h+T69esTEOD28h4hhBBCeEAaHc+5fdVVYmIiAGfPniUrK4uioiK756+77jrvjExj5qNmjoUE66J1MFoWpCXxTRa0bUmM1KjYH2M9Z0F/6060bkn025Y7ZkuKQxH65vZE57fffuPhhx/mm2++cfq81Wqt9KCEEEIIUY6cuvKY2xOd0aNHc/LkSTZt2kTnzp1JT0/n2LFjTJ06lTlz5vhijJoIy1EUBOunJTFSowJaNx/SkmifLb9/0pLouSUxVqNif4x1kbXWwx/k1JXn3J7orF69ms8//5ybbrqJgIAAEhMT6dq1KxEREcyYMYOePXv6YpxCCCGEEG5ze6Jz5swZ2/1yateuzW+//Ubjxo1p2bIlP/74o9cHeLHCwkLatGnDf/7zH7Zt28YNN9xgey4rK4vHHnuM1atXExISQv/+/Zk9ezZms/v3OQjPLiHQrNBLS2KsRgWkJfFFtvz+6TsL0pK4mgWtWxKDNyoaZ7vEFeMXcurKY25fOtWkSRP27t0LwA033MAbb7zBkSNHWLBgAXFxcV4f4MXGjx/v9DJ2q9VKz549OXPmDOvXr+fjjz/m008/5amnnvL5mIQQQghfKzt95emjuvJojU5OTg4AkyZNIjk5mQ8++ACz2czixYu9PT4733zzDRkZGXz66acOi6EzMjLYtWsX2dnZtonQnDlzGDx4MNOmTSMiIsKtzwo5dJIaQcHopyUxUqMC2jYf0pJonQVpSVzP2h9jyeq3LXeWTd+3gyjHe+gKHXF7ovPQQw/Z/n+rVq04dOgQe/bsISEhgejoaK8Orrxjx44xfPhwPvvsM0JDHS/n27hxIy1atLBre5KTkyksLGTr1q107tzZ6fsWFhZSWFho+zk/P9/7gxdCCCEqQ6nzj8q+RzXk9kTnYqGhodx4443eGEuFlFIMHjyYESNG0Lp1aw4dOuSQyc3NJSYmxm5bVFQUZrOZ3NzcCt97xowZTr+6wrr/ICGBFvTTkhipUSk/Zn1nQVoSX2RBWpKqmIXqvv7QMXs2YDv+IFddec6lic6YMWNcfsO5c+e6nE1NTb3s92Nt3ryZDRs2kJ+fz4QJEy6ZNZlMDtuUUk63l5kwYYLd/uXn51O/fv3LjFwIIYQQRuDSRGfbtm0uvdmlJhTOjBw5kgceeOCSmQYNGjB16lQ2bdqExWKxe65169Y89NBDvPvuu8TGxvL999/bPX/y5EmKi4sdmp7yLBaLw/sCpO/bQd8mQTpqSYzTqIC0JL7IgtYtiTQqvsiC/tadaN2S6Lctd8wWhRUDe/A5uerKYy5NdNasWeOTD4+OjnZpXc8rr7zC1KlTbT8fPXqU5ORkli5dSps2bQBo27Yt06ZNIycnx3b1V0ZGBhaLhaSkJJ+MXwghhPAHU+n5R2Xfozqq9Bodf0hISLD7uWbNmgBcffXV1Kt3/q6U3bp1o1mzZgwYMIBZs2bx+++/M3bsWIYPH+72FVcAq86addWSGKlRAWlJfJO9sH+S1XfzYayWxEiNCrj2u9J/2c2R9n8/+Yw0Oh4L0HoA3hIYGMjXX39NcHAw7du35/7776dPnz7Mnj1b66EJIYQQQiOGaHQu1qBBA5STy+QSEhL46quvvPIZq/KbExq+RzctiZEaFdC6+ZCWROssSEviehYnx1ivWfC0+agK6w+dZfPOReIPctWV5ww50RFCCCGqFbmPjsdkolOBzXkJmGsGoZeWxFiNyoUxS7bqtCTGalRwcoz1mgXXmgQ9ZMvvX/Vbf+gsay1w/7sUhX/JREcIIYTQOTl15TmZ6AghhBB6J1ddeUwmOhXIy41kU1jZjQT1cDpITh35IgtyOsg3WZDTQa5m7Y+xnrNQvS+0cJa1FlXT2YOByERHCCGE0Dk5deU5mehUwHzUzLGQYF20DkbLgrQkvsmCti2JkRoV+2Os5yzob4Gt1i2Jfttyx2xJcSh+IVddeSxA6wEIIYQQQviKNDoVCMtRFATrpyUxUqMCWjcf0pJony2/f9KS6LklMVajYn+MdZG11sMf5NSV52SiI4QQQuidXHXlMZnoVCA8u4RAs0IvLYmxGhWQlsQX2fL7p+8sSEviaha0bkkM3qhonO0SV4w/SKPjOVmjI4QQQogqSxqdCoQcOkmNoGD005IYqVEBbZsPaUm0zoK0JK5n7Y+xZPXbljvLpu/bQVRjfK9UnX9U9j2qIZnoCCGEEHona3Q8JhOdClj3HyQk0IJ+WhIjNSrlx6zvLEhL4ossSEtSFbNQ3dcfOmbPBmxH6JtMdIQQQgidM+GFxcheGYnxyESnAun7dtC3SZCOWhLjNCogLYkvsqB1SyKNii+yoL91J1q3JPptyx2zRWHFwB58Tu6M7DG56koIIYQQVZY0OhVYddasq5bESI0KSEvim+yF/ZOsvpsPY7UkRmpUwLXflf7Lbo5MwB+0uo/OvHnzmDVrFjk5OTRv3py0tDQ6dOjgNLts2TLmz5/P9u3bKSwspHnz5qSmppKcnFy5gVeSNDpCCCGE3ikvPdywdOlSRo8ezcSJE9m2bRsdOnSgR48eZGVlOc2vW7eOrl27snz5crZu3Urnzp3p1asX27Ztc39/vUganQqsym9OaPge3bQkRmpUQOvmQ1oSrbMgLYnrWZwcY71mwdPmoyqsP3SWzTsXSVU1d+5chg4dyrBhwwBIS0tj5cqVzJ8/nxkzZjjk09LS7H6ePn06n3/+OV9++SWtWrXyx5CdkkZHCCGE0DmTUl55AOTn59s9CgsLHT6vqKiIrVu30q1bN7vt3bp1Y8OGDS6NubS0lNOnT1O7du3Lh31IGp0KbM5LwFwzCL20JMZqVC6MWbJVpyUxVqOCk2Os1yx4v/momo0K6K9ZtxaY8YvS/z0q+x5A/fr17TZPmjSJ1NRUu23Hjx/HarUSExNjtz0mJobc3FyXPm7OnDmcOXOG+++/3+Mhe4NMdIQQQgidK9/IVOY9ALKzs4mIiLBtt1gsFb/GZH/3HaWUwzZnPvroI1JTU/n888+54oorPByxd8hEpwJ5uZFsCiv7w9dDSyKNii+yIC2Jb7IgLYmrWftjrOcsVO/1h86y1iLj3ZsmIiLCbqLjTHR0NIGBgQ7tTV5enkPLc7GlS5cydOhQ/vnPf3LHHXdUeryVJWt0hBBCCL3z81VXZrOZpKQkMjMz7bZnZmbSrl27Cl/30UcfMXjwYD788EN69uzp+gf6kDQ6FTAfNXMsJFgXrYPRsiAtiW+y4P3mo6o2KvbHWM9Z0N+6E61bEv225Y7ZkuJQ/EKDOyOPGTOGAQMG0Lp1a9q2bcvChQvJyspixIgRAEyYMIEjR46wZMkS4PwkZ+DAgbz88svccssttjYoJCSEyEjtrk6TiY4QQgghHPTr148TJ04wZcoUcnJyaNGiBcuXLycxMRGAnJwcu3vqvPHGG5SUlPDYY4/x2GOP2bYPGjSIxYsX+3v4NjLRqUBYjqIgWD8tiZEaFdC6+ZCWRPts+f2TlkTPLYmxGhX7Y6yLrLUe/qDVnZFTUlJISUlx+tzFk5dvv/3W/Q/wA5noCCGEEHonX+rpMUNNdL7++mumTJnCf//7X8LCwrjttttYtmyZ7fmsrCwee+wxVq9eTUhICP3792f27NmYze7f5yA8u4RAs0IvLYmxGhWQlsQX2fL7p+8sSEviaha0bkkM3qhonO0SV4zQN8NMdD799FOGDx/O9OnTuf3221FKsWPHDtvzVquVnj17UrduXdavX8+JEycYNGgQSileffVVDUcuhBBCVI6p9Pyjsu9RHRliolNSUsITTzzBrFmzGDp0qG17kyZNbP8/IyODXbt2kZ2dTXz8+f/0mzNnDoMHD2batGmXvWfAxUIOnaRGUDD6aUmM1KiA99sMaUlA1p24mgWtmw9pSXyRBf016+n7dhDVGN+TU1ceC9B6AK748ccfOXLkCAEBAbRq1Yq4uDh69OjBzp07bZmNGzfSokUL2yQHIDk5mcLCQrZu3VrhexcWFjp874cQQgghqgZDNDoHDhwAIDU1lblz59KgQQPmzJlDx44d2bdvH7Vr1yY3N9fhbo1RUVGYzeZLfi/HjBkzmDx5ssN26/6DhARa0E9LYqRGpfyY9Z0FaUl8kQVpSapiFqr7+kPH7NmA7fiFmzf8q/A9qiFNG53U1FRMJtMlH1u2bKG09PyJxYkTJ3LfffeRlJTEokWLMJlM/POf/7S9n7Pv37jc93JMmDCBU6dO2R7Z2dne31EhhBCiErz57eXVjaaNzsiRI3nggQcumWnQoAGnT58GoFmzZrbtFouFq666ynazotjYWL7//nu71548eZLi4uJLfi+HxWJx+oVm6ft20LdJkI5aEuM0KiAtiS+yoHVLIo2KL7Kgv3UnWrck+m3LHbNFYcXAHnxO1uh4TNOJTnR0NNHR0ZfNJSUlYbFY2Lt3L7feeisAxcXFHDp0yHaHxrZt2zJt2jRycnKIi4sDzi9QtlgsJCUl+W4nhBBCCKFbhlijExERwYgRI5g0aRL169cnMTGRWbNmAdC3b18AunXrRrNmzRgwYACzZs3i999/Z+zYsQwfPtztK64AVp0166olMVKjAtKS+CZ7Yf8kq+/mw1gtiZEaFXDtd6X/spsjE/ALBVT28vDqWegYY6IDMGvWLGrUqMGAAQM4d+4cbdq0YfXq1URFRQEQGBjI119/TUpKCu3bt7e7YaAQQghhZN5YYyNrdHQuKCiI2bNnX3LikpCQwFdffeXHUQkhhBBCzwwz0fG3VfnNCQ3fo5vTQUY6dQRan+KR00FaZ0FOB7mexckx1msWLvd7qipfaOEsm3cuEr9QeGExsldGYjgy0RFCCCH0Tq668phMdCqwOS8Bc80g9NKSGKtRuTBmyVadlsRYjQpOjrFes+Bak6CHbPn9q34XWjjLWgvc/9Jo4V8y0RFCCCH0rhSo+N63rr9HNSQTnQrk5UayKazsRoJ6aEmkUfFFFqQl8U0WpCVxNWt/jPWcheq9/tBZ1lrkn9NBctWV52SiI4QQQuidrNHxmEx0KmA+auZYSLAuWgejZUFaEt9kQduWxEiNiv0x1nMW9LfuROuWRL9tuWO2pDgUoW8y0RFCCCH0Thodj8lEpwJhOYqCYP20JEZqVEDr5kNaEu2z5fdPWhI9tyTGalTsj7EustZ6+IVMdDwWoPUAhBBCCCF8RRqdCoRnlxBoVuilJTFWowLSkvgiW37/9J0FaUlczYLWLYnBGxWNs13iivELubzcYzLREUIIIXROLi/3nEx0KhBy6CQ1goLRT0tipEYFvN9mSEsCsu7E1Sxo3XxIS+KLLOivWU/ft4Ooxggdk4mOEEIIoXeyGNljMtGpgHX/QUICLeinJTFSo1J+zPrOgrQkvsiCtCRVMQvVff2hY/ZswHb8olSBqZITldLqOdGRq66EEEIIUWVJo1OB9H076NskSEctiXEaFZCWxBdZ0LolkUbFF1nQ37oTrVsS/bbljtmisGJgDz4np648JhMdIYQQQve8MNFBJjqinFVnzbpqSYzUqIC0JL7JXtg/yeq7+TBWS2KkRgVc+13pv+zmyAT8Qhodj8kaHSGEEEJUWdLoVGBVfnNCw/fopiUxUqMCWjcf0pJonQVpSVzP4uQY6zULnjYfVWH9obNs3rlI/KJUUelTT9X0qiuZ6AghhBB6p0rPPyr7HtWQTHQqsDkvAXPNIPTSkhirUbkwZslWnZbEWI0KTo6xXrPgWpOgh2z5/at+6w+dZa0FZoS+yURHCCGE0DtZjOwxmehUIC83kk1hlv/9pIeWRBoVX2RBWhLfZEFaElez9sdYz1mo3usPnWWtRX6aPMgaHY/JVVdCCCGEqLKk0amA+aiZYyHBumgdjJYFaUl8kwVtWxIjNSr2x1jPWdDfuhOtWxL9tuWO2ZLiUPxCTl15TCY6QgghhN4pvDDR8cpIDEcmOhUIy1EUBOunJTFSowJaNx/SkmifLb9/0pLouSUxVqNif4x1kbXWQ+ibTHSEEEIIvZNTVx4zzERn3759jBs3ju+++46ioiJatmzJ1KlT6dy5sy2TlZXFY489xurVqwkJCaF///7Mnj0bs9n9+xyEZ5cQaFbopSUxVqMC0pL4Ilt+//SdBWlJXM2C1i2JwRsVjbNd4orxi9JSoJI3/CutnjcMNMxVVz179qSkpITVq1ezdetWbrjhBu666y5yc3MBsFqt9OzZkzNnzrB+/Xo+/vhjPv30U5566imNRy6EEEJUUlmjU9lHNWSIRuf48ePs37+fd955h+uuuw6AF154gXnz5rFz505iY2PJyMhg165dZGdnEx9//j/95syZw+DBg5k2bRoRERFufWbIoZPUCApGPy2JkRoV0Lb5kJZE6yxIS+J61v4YS1a/bbmzbPq+HUQ1RuiYIRqdOnXqcO2117JkyRLOnDlDSUkJb7zxBjExMSQlJQGwceNGWrRoYZvkACQnJ1NYWMjWrVsrfO/CwkLy8/PtHkIIIYSuSKPjMUM0OiaTiczMTHr37k14eDgBAQHExMSwYsUKatWqBUBubi4xMTF2r4uKisJsNttObzkzY8YMJk+e7LDduv8gIYEW9NOSGKlRKT9mfWdBWhJfZEFakqqYheq+/tAxezZgO34hd0b2mKaNTmpqKiaT6ZKPLVu2oJQiJSWFK664gn//+9/88MMP9O7dm7vuuoucnBzb+5lMJofPUEo53V5mwoQJnDp1yvbIzs72yb4KIYQQwv80bXRGjhzJAw88cMlMgwYNWL16NV999RUnT560rbWZN28emZmZvPvuuzzzzDPExsby/fff27325MmTFBcXOzQ95VksFiwWS4XPCyGEEFpTqhSlKnfVVGVfb1SaTnSio6OJjo6+bO7s2bMABATYF1ABAQGU/u9yubZt2zJt2jRycnKIi4sDICMjA4vFYlvH4470fTvo2yRIR6eDjHPqCOR0kC+yoPXpIDl15Iss6G+Brdang/S7LMAxWxRWDOzB55Sq/KmnarpGxxCLkdu2bUtUVBSDBg3iP//5j+2eOgcPHqRnz54AdOvWjWbNmjFgwAC2bdvGv/71L8aOHcvw4cPdvuJKCCGEEFWDIRYjR0dHs2LFCiZOnMjtt99OcXExzZs35/PPP+f6668HIDAwkK+//pqUlBTat29vd8NAT6w6a9ZVS2KkRgWkJfFN9sL+SVbfzYexWhIjNSrg2u9K/2U3RybgF8oLi5GraaNjiIkOQOvWrVm5cuUlMwkJCXz11Vd+GpEQQgjhJ6WlYKrkGhtZoyPKW5XfnNDwPbppSYzUqIDWzYe0JFpnQVoS17M4OcZ6zcLlfk9V5fWHzrJ55yIR+iYTHSGEEELv5NSVx2SiU4HNeQmYawahl5bEWI3KhTFLtuq0JMZqVHByjPWaBdeaBD1ky+9f9Vt/6CxrLXD/S6M9oUpLUZU8dSWXlwshhBBCn6TR8ZhMdCqQlxvJprCyGwnqoSWRRsUXWZCWxDdZkJbE1az9MdZzFqr3+kNnWWtR9Zw8GIlMdIQQQgi9K1VgkkbHEzLRqYD5qJljIcG6aB2MlgVpSXyTBW1bEiM1KvbHWM9Z0N+6E61bEv225Y7ZkuJQ/EIpoLKXl1fPiU6A1gMQQgghhPAVaXQqEJajKAjWT0tipEYFtG4+pCXRPlt+/6Ql0XNLYqxGxf4Y6yJrrYc/qFKFquSpKyWNjhBCCCF0SZV65+GmefPm0bBhQ4KDg0lKSuLf//73JfNr164lKSmJ4OBgrrrqKhYsWODpHnuNNDoVCM8uIdCs0EtLYqxGBaQl8UW2/P7pOwvSkriaBa1bEoM3Khpnu8QVU1UtXbqU0aNHM2/ePNq3b88bb7xBjx492LVrFwkJjt/xdfDgQe68806GDx/O+++/z3fffUdKSgp169blvvvu02APzpNGRwghhNA5Vaq88nDH3LlzGTp0KMOGDePaa68lLS2N+vXrM3/+fKf5BQsWkJCQQFpaGtdeey3Dhg1jyJAhHn+5trdIo1OBkEMnqREUjH5aEiM1KqBt8yEtidZZkJbE9az9MZasfttyZ9n0fTuIaozvqVIqf9WV668vKipi69atPPPMM3bbu3XrxoYNG5y+ZuPGjXTr1s1uW3JyMm+//TbFxcUEBQW5P2YvkInORcoWa5WUFlJSXIC1qAbWAhMApeeKsJ4ppOjPYs4GWMm3llKiilFWfWUBrAUmzbKAbcx6zwJ2x1jPWcDhnwm9ZgGn/wz7KwtU+O+R3rLAJf+911MWuOzvKV9mAZd+V/o1W1pq93eHr5RQXOkbI5dw/s86Pz/fbrvFYsFisdhtO378OFarlZiYGLvtMTEx5ObmOn3/3Nxcp/mSkhKOHz9OXFxc5XbAU0rYyc7OLrvPtjzkIQ95yEMeLj2ys7N98nfSuXPnVGxsrNfGWbNmTYdtkyZNcvjcI0eOKEBt2LDBbvvUqVNVkyZNnI61UaNGavr06Xbb1q9frwCVk5PjtWPiLml0LhIfH092djbh4eGYTCZNxpCfn0/9+vXJzs4mIiJCkzH4iuybMcm+GVNV3jfQx/4ppTh9+jTx8fE+ef/g4GAOHjxIUVGRV95PKeXwd9vFbQ5AdHQ0gYGBDu1NXl6eQ2tTJjY21mm+Ro0a1KlTp5Ij95xMdC4SEBBAvXr+uS/C5URERFTJX04g+2ZUsm/GVJX3DbTfv8jISJ++f3BwMMHBwT79jIuZzWaSkpLIzMzknnvusW3PzMykd+/eTl/Ttm1bvvzyS7ttGRkZtG7dWrP1OSBXXQkhhBDCiTFjxvDWW2/xzjvvsHv3bp588kmysrIYMWIEABMmTGDgwIG2/IgRIzh8+DBjxoxh9+7dvPPOO7z99tuMHTtWq10ApNERQgghhBP9+vXjxIkTTJkyhZycHFq0aMHy5ctJTEwEICcnh6ysLFu+YcOGLF++nCeffJLXX3+d+Ph4XnnlFU3voQMy0dEli8XCpEmTnJ43NTrZN2OSfTOmqrxvUPX3Tw9SUlJISUlx+tzixYsdtnXs2JEff/zRx6Nyj0mpavrlF0IIIYSo8mSNjhBCCCGqLJnoCCGEEKLKkomOEEIIIaosmegIIYQQosqSiY6Gpk2bRrt27QgNDaVWrVpOMyaTyeGxYMECu8yOHTvo2LEjISEhXHnllUyZMsXn37tyOa7sW1ZWFr169SIsLIzo6GhGjRrlcPdPPe6bMw0aNHD4c7r4y/Bc2V+9mjdvHg0bNiQ4OJikpCT+/e9/az0kt6Smpjr8+cTGxtqeV0qRmppKfHw8ISEhdOrUiZ07d2o44ktbt24dvXr1Ij4+HpPJxGeffWb3vCv7U1hYyOOPP050dDRhYWHcfffd/Prrr37cC+cut2+DBw92+LO85ZZb7DJ63TehDZnoaKioqIi+ffvyt7/97ZK5RYsWkZOTY3sMGjTI9lx+fj5du3YlPj6ezZs38+qrrzJ79mzmzp3r6+Ff0uX2zWq10rNnT86cOcP69ev5+OOP+fTTT3nqqadsGb3uW0XK7jVR9nj22Wdtz7myv3q1dOlSRo8ezcSJE9m2bRsdOnSgR48edvfPMILmzZvb/fns2LHD9tzMmTOZO3cur732Gps3byY2NpauXbty+vRpDUdcsTNnznD99dfz2muvOX3elf0ZPXo06enpfPzxx6xfv54///yTu+66C6vV6q/dcOpy+wbQvXt3uz/L5cuX2z2v130TGtHsW7aEzaJFi1RkZKTT5wCVnp5e4WvnzZunIiMjVUFBgW3bjBkzVHx8vCotLfXySN1X0b4tX75cBQQEqCNHjti2ffTRR8pisahTp04ppfS/b+UlJiaql156qcLnXdlfvbr55pvViBEj7LY1bdpUPfPMMxqNyH2TJk1S119/vdPnSktLVWxsrHrhhRds2woKClRkZKRasGCBn0bouYt/R7iyP3/88YcKCgpSH3/8sS1z5MgRFRAQoFasWOG3sV+Os99/gwYNUr17967wNUbZN+E/0ugYwMiRI4mOjuamm25iwYIFlJaW2p7buHEjHTt2tLthVnJyMkePHuXQoUMajNY1GzdupEWLFnZfhJecnExhYSFbt261ZYy0by+++CJ16tThhhtuYNq0aXanpVzZXz0qKipi69atdOvWzW57t27d2LBhg0aj8szPP/9MfHw8DRs25IEHHuDAgQMAHDx4kNzcXLt9tFgsdOzY0XD7CK7tz9atWykuLrbLxMfH06JFC0Ps87fffssVV1xB48aNGT58OHl5ebbnjL5vwvvkzsg69/zzz9OlSxdCQkL417/+xVNPPcXx48dtp0Vyc3Np0KCB3WvKvlk2NzeXhg0b+nvILsnNzXX4BtyoqCjMZrPt22+NtG9PPPEEN954I1FRUfzwww9MmDCBgwcP8tZbbwGu7a8eHT9+HKvV6jD2mJgYXY/7Ym3atGHJkiU0btyYY8eOMXXqVNq1a8fOnTtt++FsHw8fPqzFcCvFlf3Jzc3FbDYTFRXlkNH7n2uPHj3o27cviYmJHDx4kL///e/cfvvtbN26FYvFYuh9E74hjY6XOVv0ePFjy5YtLr/fs88+S9u2bbnhhht46qmnmDJlCrNmzbLLmEwmu5/V/xbrXry9sry9b87Gp5Sy2+6vfXPGnf198skn6dixI9dddx3Dhg1jwYIFvP3225w4caLCfSnbH3/sS2U5+3MwwrjL9OjRg/vuu4+WLVtyxx138PXXXwPw7rvv2jJG38eLebI/Rtjnfv360bNnT1q0aEGvXr345ptv2Ldvn+3PtCJG2DfhG9LoeNnIkSN54IEHLpm5uKVwxy233EJ+fj7Hjh0jJiaG2NhYh/9KKatxL/4vusry5r7Fxsby/fff2207efIkxcXFtnH7c9+cqcz+ll0Fsn//furUqePS/upRdHQ0gYGBTv8c9DzuywkLC6Nly5b8/PPP9OnTBzjfcsTFxdkyRt3HsqvJLrU/sbGxFBUVcfLkSbvmIy8vj3bt2vl3wJUUFxdHYmIiP//8M1C19k14hzQ6XhYdHU3Tpk0v+QgODvb4/bdt20ZwcLDtku22bduybt06u/UgGRkZxMfHV2pC5Yw3961t27b89NNP5OTk2I3bYrGQlJTk931zpjL7u23bNgDbXzSu7K8emc1mkpKSyMzMtNuemZlp6L80CgsL2b17N3FxcTRs2JDY2Fi7fSwqKmLt2rWG3EdX9icpKYmgoCC7TE5ODj/99JPh9vnEiRNkZ2fb/l2rSvsmvESzZdBCHT58WG3btk1NnjxZ1axZU23btk1t27ZNnT59Wiml1BdffKEWLlyoduzYofbv36/efPNNFRERoUaNGmV7jz/++EPFxMSoBx98UO3YsUMtW7ZMRUREqNmzZ2u1W0qpy+9bSUmJatGiherSpYv68ccf1apVq1S9evXUyJEjbe+h13272IYNG9TcuXPVtm3b1IEDB9TSpUtVfHy8uvvuu20ZV/ZXrz7++GMVFBSk3n77bbVr1y41evRoFRYWpg4dOqT10Fz21FNPqW+//VYdOHBAbdq0Sd11110qPDzctg8vvPCCioyMVMuWLVM7duxQDz74oIqLi1P5+fkaj9y506dP2/6dAmz//B0+fFgp5dr+jBgxQtWrV0+tWrVK/fjjj+r2229X119/vSopKdFqt5RSl96306dPq6eeekpt2LBBHTx4UK1Zs0a1bdtWXXnllYbYN6ENmehoaNCgQQpweKxZs0YppdQ333yjbrjhBlWzZk0VGhqqWrRoodLS0lRxcbHd+/z3v/9VHTp0UBaLRcXGxqrU1FTNL7++3L4pdX4y1LNnTxUSEqJq166tRo4caXcpuVL63LeLbd26VbVp00ZFRkaq4OBg1aRJEzVp0iR15swZu5wr+6tXr7/+ukpMTFRms1ndeOONau3atVoPyS39+vVTcXFxKigoSMXHx6t7771X7dy50/Z8aWmpmjRpkoqNjVUWi0XddtttaseOHRqO+NLWrFnj9N+vQYMGKaVc259z586pkSNHqtq1a6uQkBB11113qaysLA32xt6l9u3s2bOqW7duqm7duiooKEglJCSoQYMGOYxbr/smtGFSSoe3mRVCCCGE8AJZoyOEEEKIKksmOkIIIYSosmSiI4QQQogqSyY6QgghhKiyZKIjhBBCiCpLJjpCCCGEqLJkoiOEEEKIKksmOqLK6dSpE6NHj65Snzt48GDbdzJ5qkGDBrYvI/3jjz8qzC1evNj2FSPC+wYPHmz7c/jss8+0Ho4QVZ5MdITwkmXLlvH888/bfm7QoAFpaWnaDciJKVOmkJOTQ2RkpNZDqfK+/fZbp5PKl19+2e47z4QQviXfXi6El9SuXVvrIVxWeHi47duttVZcXExQUJDWw/C7yMhImWgK4UfS6Igq7+TJkwwcOJCoqChCQ0Pp0aMHP//8s+35slM1K1eu5Nprr6VmzZp0797d7r+6S0pKGDVqFLVq1aJOnTo8/fTTDBo0yO50UvlTV506deLw4cM8+eSTttMUAKmpqdxwww1240tLS7P7Nnar1cqYMWNsnzV+/Hgu/qYWpRQzZ87kqquuIiQkhOuvv55PPvnEo+OzePFiEhISCA0N5Z577uHEiRMOmS+//JKkpCSCg4O56qqrmDx5MiUlJbbn9+zZw6233kpwcDDNmjVj1apVdqdmDh06hMlk4h//+AedOnUiODiY999/H4BFixZx7bXXEhwcTNOmTZk3b57dZx85coR+/foRFRVFnTp16N27N4cOHbI9/+2333LzzTcTFhZGrVq1aN++PYcPH3Zp3y+3X3PnzqVly5aEhYVRv359UlJS+PPPP23PHz58mF69ehEVFUVYWBjNmzdn+fLlHDp0iM6dOwMQFRWFyWRi8ODBLo1JCOFdMtERVd7gwYPZsmULX3zxBRs3bkQpxZ133klxcbEtc/bsWWbPns17773HunXryMrKYuzYsbbnX3zxRT744AMWLVrEd999R35+/iXXVyxbtox69erZThW5c6pizpw5vPPOO7z99tusX7+e33//nfT0dLvMs88+y6JFi5g/fz47d+7kySef5K9//Str1651/cAA33//PUOGDCElJYXt27fTuXNnpk6dapdZuXIlf/3rXxk1ahS7du3ijTfeYPHixUybNg2A0tJS+vTpQ2hoKN9//z0LFy5k4sSJTj/v6aefZtSoUezevZvk5GTefPNNJk6cyLRp09i9ezfTp0/n73//O++++y5w/s+lc+fO1KxZk3Xr1rF+/XrbRLSoqIiSkhL69OlDx44d+e9//8vGjRt55JFHbBPLS7ncfgEEBATwyiuv8NNPP/Huu++yevVqxo8fb3v+scceo7CwkHXr1rFjxw5efPFFatasSf369fn0008B2Lt3Lzk5Obz88stu/dkIIbxE068UFcIHOnbsqJ544gmllFL79u1TgPruu+9szx8/flyFhISof/zjH0oppRYtWqQAtX//flvm9ddfVzExMbafY2Ji1KxZs2w/l5SUqISEBNW7d2+nn6uUUomJieqll16yG9ukSZPU9ddfb7ftpZdeUomJibaf4+Li1AsvvGD7ubi4WNWrV8/2WX/++acKDg5WGzZssHufoUOHqgcffLDC4+JsPA8++KDq3r273bZ+/fqpyMhI288dOnRQ06dPt8u89957Ki4uTiml1DfffKNq1KihcnJybM9nZmYqQKWnpyullDp48KACVFpamt371K9fX3344Yd2255//nnVtm1bpZRSb7/9tmrSpIndN9YXFhaqkJAQtXLlSnXixAkFqG+//bbC/a7I5fbLmX/84x+qTp06tp9btmypUlNTnWbLvoX75MmTTp8vf3yEEL4ja3RElbZ7925q1KhBmzZtbNvq1KlDkyZN2L17t21baGgoV199te3nuLg48vLyADh16hTHjh3j5ptvtj0fGBhIUlISpaWlXh3vqVOnyMnJoW3btrZtNWrUoHXr1rbTV7t27aKgoICuXbvavbaoqIhWrVq59Xm7d+/mnnvusdvWtm1bVqxYYft569atbN682a7psFqtFBQUcPbsWfbu3Uv9+vXt1v6UP1bltW7d2vb/f/vtN7Kzsxk6dCjDhw+3bS8pKbGtYdm6dSv79+8nPDzc7n0KCgr45Zdf6NatG4MHDyY5OZmuXbtyxx13cP/99xMXF3fZfb/cfoWGhrJmzRqmT5/Orl27yM/Pp6Sk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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "cube1.isel(time=0).v.plot.imshow()" - ] - }, { "cell_type": "markdown", "id": "8aa500f2-f041-453d-9d71-90be150db9ff", diff --git a/examples/ndvi/ndvi.ipynb b/examples/ndvi/ndvi.ipynb index 778c264..5fcd018 100644 --- a/examples/ndvi/ndvi.ipynb +++ b/examples/ndvi/ndvi.ipynb @@ -692,7 +692,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.3" + "version": "3.13.15" } }, "nbformat": 4, diff --git a/xcengine/parameters.py b/xcengine/parameters.py index 0992096..1cc2fdd 100644 --- a/xcengine/parameters.py +++ b/xcengine/parameters.py @@ -1,3 +1,4 @@ +import builtins import logging import os import pathlib @@ -182,9 +183,15 @@ def read_params_from_cli(self, args: list[str]) -> dict[str, Any]: for param_name, (type_, _) in self.params.items(): arg_name = "--" + param_name.replace("_", "-") if arg_name in args and type_ != xr.Dataset: - values[param_name] = type_ is bool or type_( - args[args.index(arg_name) + 1] - ) + match type_: + case builtins.bool: + values[param_name] = True + case "Directory": + values[param_name] = args[args.index(arg_name) + 1] + case _: + values[param_name] = type_( + args[args.index(arg_name) + 1] + ) if "product" in self.cwl_params and "--product" in args: self.read_datasets_from_product( args[args.index("--product") + 1], values From 10b5dbfda8bf439c3a8beaf04132f5a029c3c622 Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 09:31:07 +0200 Subject: [PATCH 04/10] Roll back accidentally committed notebook changes --- examples/dynamic/dynamic.ipynb | 40 ++++++++++++++++++++++++++++++++-- examples/ndvi/ndvi.ipynb | 2 +- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/examples/dynamic/dynamic.ipynb b/examples/dynamic/dynamic.ipynb index 29f980c..7a8cdf5 100644 --- a/examples/dynamic/dynamic.ipynb +++ b/examples/dynamic/dynamic.ipynb @@ -60,7 +60,6 @@ "outputs": [], "source": [ "periods = 10\n", - "my_directory: \"EOInput\" = \"/my/dir\"\n", "\n", "xcengine_config = dict(\n", " workflow_id=\"dynamic\",\n", @@ -137,7 +136,7 @@ "outputs": [], "source": [ "cube1 = xcube.core.new.new_cube(\n", - " variables={my_directory.replace(\"/\", \"_\").strip(\"_\"): lambda x, y, t: ((x + y + t) % 10) / 9},\n", + " variables={\"v\": lambda x, y, t: ((x + y + t) % 10) / 9},\n", " time_periods=periods\n", ")\n", "cube1.attrs[\"title\"] = \"Cube 1\"" @@ -192,6 +191,43 @@ "Just to check on the data, plot a time-slice from the first dataset. This plot will make no difference to the functionality of the container image and application package generated by `xcetool` from the notebook." ] }, + { + "cell_type": "code", + "execution_count": 5, + "id": "aa60aef0-fe54-4c1b-a5ea-fae5cfd6f1b9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjoAAAHFCAYAAAD7ZFORAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAfZhJREFUeJzt3Xl8E3X+x/FXWpr0oC2FYg+hBZVDDhWLIiACIhREBHURxeWQQ9mKiAgoP1wpyKFc1gsQDxBPdpV6IrQsCIuAAsIucoocrdBSQaQI9Eq/vz/YhoakkKRJZqb9PB+PPHY7eSf5zqDl63u+MzEppRRCCCGEEFVQgNYDEEIIIYTwFZnoCCGEEKLKkomOEEIIIaosmegIIYQQosqSiY4QQgghqiyZ6AghhBCiypKJjhBCCCGqLJnoCCGEEKLKkomOEEIIIaosmegIr9iwYQOpqan88ccfDs916tSJTp06+X1M/rBv3z7Gjh1LUlIStWrVonbt2rRv355PPvnEaT4vL4/BgwcTHR1NaGgobdu25V//+pdD7quvvmLgwIG0bNmSoKAgTCZThWMoLi5m8uTJNGjQAIvFQtOmTXn11Vfd2g9fjOtSXn31VZo2bYrFYqFhw4ZMnjyZ4uJiu8yvv/7K6NGj6dixI7Vq1cJkMrF48WK7TGpqKiaT6bKPsn/+du7cSUpKCm3btiUsLAyTycS3337rML6cnByeffZZ2rZtS3R0NBERESQlJbFw4UKsVqvL+3ngwAHuvfdeatWqRc2aNenatSs//vij0+zHH3/MDTfcQHBwMPHx8YwePZo///xTl58lhKEoIbxg1qxZClAHDx50eG7nzp1q586d/h+UH7z66quqadOmatq0aSojI0MtX75cDRo0SAFq8uTJdtmCggLVokULVa9ePfX++++rjIwM1bt3b1WjRg317bff2mWHDBmiGjVqpO6//36VlJSkLvWv6rBhw5TFYlEzZ85Ua9asUc8884wymUxq2rRpLu2Dr8ZVkalTpyqTyaQmTJig1qxZo2bOnKnMZrMaPny4XW7NmjUqOjpa3XHHHerBBx9UgFq0aJFdJjs7W23cuNH2WLZsmQLU448/bre97J+/xYsXq7i4OHXnnXeqXr16KUCtWbPGYYxffvmlql+/vpo4caL6+uuvVUZGhnryySdVQECAevjhh13az7y8PBUfH6+aN2+uPv30U/X111+rW2+9VYWHh6s9e/bYZd9//30FqGHDhqnVq1erBQsWqMjISNW1a1fdfZYQRiMTHeEVl5roVGW//fabKi0tddjes2dPFRoaqgoKCmzbXn/9dQWoDRs22LYVFxerZs2aqZtvvtnu9Var1fb/H3vssQonFD/99JMymUxq+vTpdtuHDx+uQkJC1IkTJy67D74YV0WOHz+ugoOD1SOPPGK3fdq0acpkMtlNiMt/1ubNm51OdC528OBBBahZs2Y5fb78e/7zn/+scKLz+++/q6KiIoftZfuclZV1yXEopdS4ceNUUFCQOnTokG3bqVOnVHR0tLr//vtt20pKSlRcXJzq1q2b3es/+OADBajly5fr6rOEMBo5dSUqLTU1lXHjxgHQsGFD2+mCslMCF5+6OnToECaTiVmzZvHiiy/SoEEDQkJC6NSpE/v27aO4uJhnnnmG+Ph4IiMjueeee8jLy3P43KVLl9pOQdSsWZPk5GS2bdvmj122iY6Odnr65uabb+bs2bP8/vvvtm3p6ek0adKEtm3b2rbVqFGDv/71r/zwww8cOXLEtj0gwLV/NT/77DOUUjz88MN22x9++GHOnTvHihUrLvsevhhXRVasWEFBQYHT8Sql+Oyzz7z2Wc64+p5RUVEEBQU5bL/55puB86fVLic9PZ3bb7+dxMRE27aIiAjuvfdevvzyS0pKSgDYtGkTOTk5Dsekb9++1KxZk/T0dF19lhBGIxMdUWnDhg3j8ccfB2DZsmVs3LiRjRs3cuONN17yda+//jrfffcdr7/+Om+99RZ79uyhV69eDB06lN9++4133nmHmTNnsmrVKoYNG2b32unTp/Pggw/SrFkz/vGPf/Dee+9x+vRpOnTowK5duy475pKSEpceSimPjsmaNWuoW7cuV1xxhW3bTz/9xHXXXeeQLdu2c+dOtz/np59+om7dusTGxjp9z59++sml9/D2uC71WQAtW7a02x4XF0d0dLRL49XS6tWrqVGjBo0bN7bbXn4dEMC5c+f45ZdfKjyu586d48CBA8CFY3JxNigoiKZNmzocE39+lhBVQQ2tByCMr169eiQkJADQqlUrGjRo4NLratWqxWeffWb7r+zjx48zevRomjZtyueff27L7dmzh7S0NPLz84mIiCA7O5tJkyYxcuRIXnnlFVuua9euNGrUiMmTJ7N0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3L4pdX4y1LNnTxUSEqJq166tRo4caXcpuVL63LeLbd26VbVp00ZFRkaq4OBg1aRJEzVp0iR15swZu5wr+6tXr7/+ukpMTFRms1ndeOONau3atVoPyS39+vVTcXFxKigoSMXHx6t7771X7dy50/Z8aWmpmjRpkoqNjVUWi0XddtttaseOHRqO+NLWrFnj9N+vQYMGKaVc259z586pkSNHqtq1a6uQkBB11113qaysLA32xt6l9u3s2bOqW7duqm7duiooKEglJCSoQYMGOYxbr/smtGFSSoe3mRVCCCGE8AJZoyOEEEKIKksmOkIIIYSosmSiI4QQQogqSyY6QgghhKiyZKIjhBBCiCpLJjpCCCGEqLJkoiOEEEKIKksmOqLK6dSpE6NHj65Snzt48GDbdzJ5qkGDBrYvI/3jjz8qzC1evNj2FSPC+wYPHmz7c/jss8+0Ho4QVZ5MdITwkmXLlvH888/bfm7QoAFpaWnaDciJKVOmkJOTQ2RkpNZDqfK+/fZbp5PKl19+2e47z4QQviXfXi6El9SuXVvrIVxWeHi47duttVZcXExQUJDWw/C7yMhImWgK4UfS6Igq7+TJkwwcOJCoqChCQ0Pp0aMHP//8s+35slM1K1eu5Nprr6VmzZp0797d7r+6S0pKGDVqFLVq1aJOnTo8/fTTDBo0yO50UvlTV506deLw4cM8+eSTttMUAKmpqdxwww1240tLS7P7Nnar1cqYMWNsnzV+/Hgu/qYWpRQzZ87kqquuIiQkhOuvv55PPvnEo+OzePFiEhISCA0N5Z577uHEiRMOmS+//JKkpCSCg4O56qqrmDx5MiUlJbbn9+zZw6233kpwcDDNmjVj1apVdqdmDh06hMlk4h//+AedOnUiODiY999/H4BFixZx7bXXEhwcTNOmTZk3b57dZx85coR+/foRFRVFnTp16N27N4cOHbI9/+2333LzzTcTFhZGrVq1aN++PYcPH3Zp3y+3X3PnzqVly5aEhYVRv359UlJS+PPPP23PHz58mF69ehEVFUVYWBjNmzdn+fLlHDp0iM6dOwMQFRWFyWRi8ODBLo1JCOFdMtERVd7gwYPZsmULX3zxBRs3bkQpxZ133klxcbEtc/bsWWbPns17773HunXryMrKYuzYsbbnX3zxRT744AMWLVrEd999R35+/iXXVyxbtox69erZThW5c6pizpw5vPPOO7z99tusX7+e33//nfT0dLvMs88+y6JFi5g/fz47d+7kySef5K9//Str1651/cAA33//PUOGDCElJYXt27fTuXNnpk6dapdZuXIlf/3rXxk1ahS7du3ijTfeYPHixUybNg2A0tJS+vTpQ2hoKN9//z0LFy5k4sSJTj/v6aefZtSoUezevZvk5GTefPNNJk6cyLRp09i9ezfTp0/n73//O++++y5w/s+lc+fO1KxZk3Xr1rF+/XrbRLSoqIiSkhL69OlDx44d+e9//8vGjRt55JFHbBPLS7ncfgEEBATwyiuv8NNPP/Huu++yevVqxo8fb3v+scceo7CwkHXr1rFjxw5efPFFatasSf369fn0008B2Lt3Lzk5Obz88stu/dkIIbxE068UFcIHOnbsqJ544gmllFL79u1TgPruu+9szx8/flyFhISof/zjH0oppRYtWqQAtX//flvm9ddfVzExMbafY2Ji1KxZs2w/l5SUqISEBNW7d2+nn6uUUomJieqll16yG9ukSZPU9ddfb7ftpZdeUomJibaf4+Li1AsvvGD7ubi4WNWrV8/2WX/++acKDg5WGzZssHufoUOHqgcffLDC4+JsPA8++KDq3r273bZ+/fqpyMhI288dOnRQ06dPt8u89957Ki4uTiml1DfffKNq1KihcnJybM9nZmYqQKWnpyullDp48KACVFpamt371K9fX3344Yd2255//nnVtm1bpZRSb7/9tmrSpIndN9YXFhaqkJAQtXLlSnXixAkFqG+//bbC/a7I5fbLmX/84x+qTp06tp9btmypUlNTnWbLvoX75MmTTp8vf3yEEL4ja3RElbZ7925q1KhBmzZtbNvq1KlDkyZN2L17t21baGgoV199te3nuLg48vLyADh16hTHjh3j5ptvtj0fGBhIUlISpaWlXh3vqVOnyMnJoW3btrZtNWrUoHXr1rbTV7t27aKgoICuXbvavbaoqIhWrVq59Xm7d+/mnnvusdvWtm1bVqxYYft569atbN682a7psFqtFBQUcPbsWfbu3Uv9+vXt1v6UP1bltW7d2vb/f/vtN7Kzsxk6dCjDhw+3bS8pKbGtYdm6dSv79+8nPDzc7n0KCgr45Zdf6NatG4MHDyY5OZmuXbtyxx13cP/99xMXF3fZfb/cfoWGhrJmzRqmT5/Orl27yM/Pp6Sk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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cube1.isel(time=0).v.plot.imshow()" + ] + }, { "cell_type": "markdown", "id": "8aa500f2-f041-453d-9d71-90be150db9ff", diff --git a/examples/ndvi/ndvi.ipynb b/examples/ndvi/ndvi.ipynb index 5fcd018..778c264 100644 --- a/examples/ndvi/ndvi.ipynb +++ b/examples/ndvi/ndvi.ipynb @@ -692,7 +692,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.15" + "version": "3.13.3" } }, "nbformat": 4, From c3b6c509ac6ff025bdda0f1a5e68958632a41c38 Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 09:49:57 +0200 Subject: [PATCH 05/10] Improve test coverage --- test/test_parameters.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_parameters.py b/test/test_parameters.py index de52767..291ac1c 100644 --- a/test/test_parameters.py +++ b/test/test_parameters.py @@ -314,12 +314,15 @@ def test_parameters_read_cli_arguments(notebook_parameters): "--some-float", "2.71828", "--some-bool", + "--some-directory", + "/a/different/path" ] ) == { "some_int": 23, "some_float": 2.71828, "some_string": "bar", "some_bool": True, + "some_directory": "/a/different/path" } assert notebook_parameters.read_params_from_cli([]) == {} From 41fb8ac1c7067f614268e17d80fd898dc9f5351b Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 10:13:30 +0200 Subject: [PATCH 06/10] Update changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b3923d5..86dff5c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ `s:softwareVersion` (#90) * Allow creation of EOAP-only and xcube-server-only images, omitting unnecessary dependencies (#56) -* Add a utility function to read annotations from notebook code (#91) +* Add support for notebook-assisted stage-in (#23, #91) ## Changes in 0.1.2 From 47fa35465f5ac97fd50e55c5f532b02fc9ad123f Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 13:28:24 +0200 Subject: [PATCH 07/10] Set XCENGINE_VERSION env var; update micromamba - In the container environment, set an environment variable XCENGINE_VERSION (closes #95) - Update the micromamba base image version from micromamba:1.5.10-noble-cuda-12.6.0 to micromamba:2.9-cuda13.2.1-ubuntu24.04 (necessary for support of environment variables in environment.yml) --- test/test_core.py | 3 ++- xcengine/core.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/test_core.py b/test/test_core.py index 09153c1..030a296 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -444,7 +444,8 @@ def test_image_builder_build_dir( build_env_path = build_dir / "environment.yml" assert build_env_path.is_file() output_env = yaml.safe_load(build_env_path.read_text()) - assert {"name", "channels", "dependencies"} <= set(output_env) + assert {"name", "channels", "dependencies", "variables"} <= set(output_env) + assert type(output_env["variables"]["XCENGINE_VERSION"]) is str if env_type != "none": assert output_env["name"] == env_def["name"] assert output_env["channels"] == env_def["channels"] diff --git a/xcengine/core.py b/xcengine/core.py index 32ed087..8fb373c 100644 --- a/xcengine/core.py +++ b/xcengine/core.py @@ -28,6 +28,7 @@ import nbformat import yaml +import xcengine from xcengine import util from xcengine.parameters import NotebookParameters @@ -322,6 +323,9 @@ def ensure_present(pkg: str): for package in packages: ensure_present(package) + + env_vars = conda_env.setdefault("variables", {}) + env_vars["XCENGINE_VERSION"] = xcengine.__version__ return conda_env def _build_image(self) -> docker.models.images.Image: @@ -346,7 +350,7 @@ def write_dockerfile(destination: pathlib.Path) -> None: destination.parent.mkdir(parents=True, exist_ok=True) with open(destination, "w") as fh: fh.write(textwrap.dedent("""\ - FROM mambaorg/micromamba:1.5.10-noble-cuda-12.6.0 + FROM mambaorg/micromamba:2.9-cuda13.2.1-ubuntu24.04 COPY Dockerfile Dockerfile COPY environment.yml environment.yml RUN micromamba install -y -n base -f environment.yml && \\ From c446df147e0f0d1a4e6958e7d5860f1d9cbebe86 Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 13:52:18 +0200 Subject: [PATCH 08/10] Update changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 86dff5c..65d129b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ `s:softwareVersion` (#90) * Allow creation of EOAP-only and xcube-server-only images, omitting unnecessary dependencies (#56) -* Add support for notebook-assisted stage-in (#23, #91) +* Add support for notebook-assisted stage-in (#23, #91, #95) ## Changes in 0.1.2 From 59d33ca9545d1d854aee5b1790a4a24bc5f09643 Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Tue, 1 Sep 2026 16:47:54 +0200 Subject: [PATCH 09/10] Fix bug in CWL generated for Directory parameters Directory defaults were previously given as plain strings. They now use the structure specified in https://www.commonwl.org/v1.2/Workflow.html#Directory . --- test/test_parameters.py | 10 ++++++++-- xcengine/parameters.py | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/test/test_parameters.py b/test/test_parameters.py index 291ac1c..8f2618a 100644 --- a/test/test_parameters.py +++ b/test/test_parameters.py @@ -136,7 +136,10 @@ def test_parameters_get_commandline_inputs(notebook_parameters): }, "some_directory": { "type": "Directory", - "default": "/some/path", + "default": { + "class": "Directory", + "location": "/some/path" + }, "label": "some_directory", "doc": "some_directory", "inputBinding": {"prefix": "--some-directory"}, @@ -238,7 +241,10 @@ def test_parameters_get_workflow_inputs(notebook_parameters): }, "some_directory": { "type": "Directory", - "default": "/some/path", + "default": { + "class": "Directory", + "location": "/some/path", + }, "label": "some_directory", "doc": "some_directory", } diff --git a/xcengine/parameters.py b/xcengine/parameters.py index 1cc2fdd..ad99565 100644 --- a/xcengine/parameters.py +++ b/xcengine/parameters.py @@ -133,7 +133,8 @@ def get_cwl_workflow_input(self, var_name: str) -> dict[str, Any]: "label": var_name, "doc": var_name, "type": self.cwl_type(type_), - "default": default_, + "default": {"class": "Directory", "location": default_} + if type_ == "Directory" else default_, } def get_cwl_commandline_input(self, var_name: str) -> dict[str, Any]: From c3989d331ed041d611b592ad0099bcd77df0db7c Mon Sep 17 00:00:00 2001 From: Pontus Lurcock Date: Wed, 2 Sep 2026 11:35:46 +0200 Subject: [PATCH 10/10] Update documentation --- docs/notebook.md | 52 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/docs/notebook.md b/docs/notebook.md index a3a73bf..3e44682 100644 --- a/docs/notebook.md +++ b/docs/notebook.md @@ -35,7 +35,7 @@ name `xcengine_config`. Available configuration settings are: - `workflow_id`: a string identifier for the workflow in your Application Package. The runner or Application Package platform can use this - identifier to refer to you Application Package. By default, the name + identifier to refer to your Application Package. By default, the name of the notebook (without the `.ipynb` suffix) is used. - `environment_file`: the name of a YAML file defining a [conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) @@ -51,17 +51,45 @@ name `xcengine_config`. Available configuration settings are: Some of these configuration settings can also be set on the command line. +## Dataset input + +As well as the usual methods of dataset input, xcengine provides support for +the Application Package ‘stage-in’ process described in the [OGC Best +Practice document](https://docs.ogc.org/bp/20-089r1.html), in which an +Application Package Platform provides the Application Package with a +[STAC catalogue](https://stacspec.org/) of one or more input datasets. + +xcengine currently provides basic support for stage-in: in a generated +Application Package, the xcengine support code provides the notebook code with +the path to the STAC stage-in catalogue. The notebook code can then read this +catalogue (e.g. using [PySTAC](https://pystac.readthedocs.io/)) to find the +staged-in datasets. + +An input variable for a STAC stage-in catalogue can be defined in the +parameters cell (see above) as a string variable. The variable name can be +freely chosen, but the variable declaration must be annotated with the string +`"EOInput"` to distinguish it from an ordinary string parameter, like this: + +```python +dataset_inputs: "EOInput" = "/some/default/path" +``` + +When the converted notebook is run as an Application Package, the variable +`dataset_inputs` will be set to a string specifying a filesystem path +containing a STAC catalogue called `catalog.json`, which the notebook code +can use to find staged-in datasets. + ## Dataset output ### Selecting datasets for output -No additional code or configuration is needed for datasets to be written from -Application Packages or served when the container image is run in xcube -Server/Viewer mode. xcengine will automatically output or serve any instance -of `xarray.DataSet` which is in scope when the notebook's code has finished -executing. If you're created some datasets which you *don't* wish to be -written, you can use the Python -[`del` statement](https://docs.python.org/3/reference/simple_stmts.html#the-del-statement) +No additional code or configuration is needed for datasets to be written +(‘staged out’) from Application Packages or served when the container image is +run in xcube Server/Viewer mode. xcengine will automatically output or serve +any instance of `xarray.DataSet` which is in scope when the notebook's code +has finished executing. If you're created some datasets which you *don't* wish +to be written, you can use the Python [`del` +statement](https://docs.python.org/3/reference/simple_stmts.html#the-del-statement) to delete them at the end of the notebook to remove them, e.g. ```python @@ -77,3 +105,11 @@ like this: ```python my_dataset.attrs["xcengine_output_format"] = "netcdf" ``` + +## Determining whether your code is running in an xcengine container + +In an xcengine-derived container, the environment variable `XCENGINE_VERSION` +is always set to the version of xcengine that created the container image. If +your notebook code needs to determine whether it's running inside an xcengine +container, you can check whether this variable is set (e.g. using +`os.environ`).