From 5db23da96f080a1ea112aa2f9f0d17722ed24163 Mon Sep 17 00:00:00 2001 From: dwest77 Date: Thu, 25 Jan 2024 13:31:02 +0000 Subject: [PATCH] Added builder directory --- builder/assess.py | 297 ++ builder/environment_settings/requirements.txt | 31 + .../requirements_working.txt | 74 + builder/environment_settings/spec-file.txt | 75 + builder/examples/UKCP_test1.csv | 3 + builder/examples/UKCP_test1.txt | 2 + builder/group_run.py | 175 + builder/issues/showcase_issue01.py | 9 + .../compute/parallel/batch_process.py | 53 + .../pipeline/compute/parallel/combine_refs.py | 35 + .../pipeline/compute/parallel/correct_meta.py | 21 + .../pipeline/compute/parallel/correct_time.py | 14 + .../compute/parallel/process_wrapper.py | 80 + builder/pipeline/compute/serial_process.py | 458 +++ builder/pipeline/init.py | 350 ++ builder/pipeline/old/create_group.py | 87 + builder/pipeline/old/wide_config.py | 51 + builder/pipeline/old/~compute.py | 63 + builder/pipeline/scan.py | 341 ++ builder/pipeline/validate.py | 513 +++ builder/scripts/deploy_gh.sh | 5 + builder/scripts/extra_tools/add_dap.py | 26 + builder/scripts/extra_tools/corrections.py | 183 + .../scripts/extra_tools/metadata_viewer.py | 79 + .../scripts/extra_tools/wide_corrections.py | 95 + .../showcase/notebooks/Kerchunk JSON.ipynb | 3181 +++++++++++++++++ .../Kerchunk Parquet with HTTPS.ipynb | 157 + .../notebooks/Kerchunk Reading Recipes.ipynb | 221 ++ builder/showcase/notebooks/StoreSize.ipynb | 1065 ++++++ builder/showcase/notebooks/Untitled.ipynb | 632 ++++ builder/showcase/scripts/ice_thickness.png | Bin 0 -> 59666 bytes builder/showcase/scripts/read_kerchunks.py | 40 + builder/showcase/scripts/test_parquet.py | 28 + builder/single_run.py | 243 ++ builder/templates/base-cfg-template.json | 8 + builder/templates/cmip6-kerchunk.conf | 10 + builder/templates/phase.sbatch.template | 18 + builder/templates/setup-cmip6.sh | 4 + builder/templates/setup-metoff.sh | 3 + 39 files changed, 8730 insertions(+) create mode 100644 builder/assess.py create mode 100644 builder/environment_settings/requirements.txt create mode 100644 builder/environment_settings/requirements_working.txt create mode 100644 builder/environment_settings/spec-file.txt create mode 100644 builder/examples/UKCP_test1.csv create mode 100644 builder/examples/UKCP_test1.txt create mode 100644 builder/group_run.py create mode 100644 builder/issues/showcase_issue01.py create mode 100644 builder/pipeline/compute/parallel/batch_process.py create mode 100644 builder/pipeline/compute/parallel/combine_refs.py create mode 100644 builder/pipeline/compute/parallel/correct_meta.py create mode 100644 builder/pipeline/compute/parallel/correct_time.py create mode 100644 builder/pipeline/compute/parallel/process_wrapper.py create mode 100644 builder/pipeline/compute/serial_process.py create mode 100644 builder/pipeline/init.py create mode 100644 builder/pipeline/old/create_group.py create mode 100644 builder/pipeline/old/wide_config.py create mode 100644 builder/pipeline/old/~compute.py create mode 100644 builder/pipeline/scan.py create mode 100644 builder/pipeline/validate.py create mode 100644 builder/scripts/deploy_gh.sh create mode 100644 builder/scripts/extra_tools/add_dap.py create mode 100644 builder/scripts/extra_tools/corrections.py create mode 100644 builder/scripts/extra_tools/metadata_viewer.py create mode 100644 builder/scripts/extra_tools/wide_corrections.py create mode 100644 builder/showcase/notebooks/Kerchunk JSON.ipynb create mode 100644 builder/showcase/notebooks/Kerchunk Parquet with HTTPS.ipynb create mode 100644 builder/showcase/notebooks/Kerchunk Reading Recipes.ipynb create mode 100644 builder/showcase/notebooks/StoreSize.ipynb create mode 100644 builder/showcase/notebooks/Untitled.ipynb create mode 100644 builder/showcase/scripts/ice_thickness.png create mode 100644 builder/showcase/scripts/read_kerchunks.py create mode 100644 builder/showcase/scripts/test_parquet.py create mode 100644 builder/single_run.py create mode 100644 builder/templates/base-cfg-template.json create mode 100644 builder/templates/cmip6-kerchunk.conf create mode 100644 builder/templates/phase.sbatch.template create mode 100755 builder/templates/setup-cmip6.sh create mode 100644 builder/templates/setup-metoff.sh diff --git a/builder/assess.py b/builder/assess.py new file mode 100644 index 0000000..2da9569 --- /dev/null +++ b/builder/assess.py @@ -0,0 +1,297 @@ +import os +import sys +import argparse +import glob +import logging + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +# Hints for errors +HINTS = { + 'TrueShapeValidationError': "Kerchunk array shape doesn't match netcdf - missing timesteps or write issue?", + 'slurmstepd': "Ran out of time in job", + 'INFO [main]': "No error recorded", + 'MissingKerchunkError': "Missing the Kerchunk file", + 'KerchunkDriverFatalError': "Kerchunking failed for one or more files", + 'ExpectTimeoutError': "Time remaining estimate exceeded allowed job time (scan)" +} + +phases = ['scan', 'compute', 'validate'] +checks = ['/detail-cfg.json','/*kerchunk*','/*.complete'] + +def format_str(string, length): + """Simple string formatter to a specific length""" + while len(string) < length: + string += ' ' + return string[:length] + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +def find_redos(phase, workdir, groupID, check, ignore=[]): + checkdir = f'{workdir}/in_progress/{groupID}/' + proj_codes = os.listdir(checkdir) + + #if phase == 'validate': + #checkdir = f'{args.workdir}/complete/{args.groupID}/' + redo_pcodes = [] + complete = [] + for pcode in proj_codes: + check_file = checkdir + pcode + check + #if phase == 'validate': + #print(check_file) + if pcode not in ignore: + if glob.glob(check_file): + if phase == 'validate': + complete.append(pcode) + else: + pass + else: + redo_pcodes.append(pcode) + return redo_pcodes, complete + +def get_code_from_val(path, code): + path = path.split('*')[0] + if os.path.isfile(f'{path}proj_codes.txt'): + with open(f'{path}proj_codes.txt') as f: + try: + code = f.readlines()[int(code)] + except IndexError: + print('code',code) + code = 'N/A' + else: + code = 'N/A' + return code + +def extract_keys(filepath, logger, savetype=None, examine=None): + keys = {} + savedcodes = [] + total = 0 + listfiles = glob.glob(filepath) + logger.info(f'Found {len(listfiles)} files to assess') + + for efile in listfiles: + logger.debug(f'Starting {efile}') + total += 1 + with open(os.path.join(filepath, efile)) as f: + log = [r.strip() for r in f.readlines()] + logger.debug(f'Opened {efile}') + # Extract Error type from Error file last line + if len(log) > 0: + if type(log[-1]) == str: + key = log[-1].split(':')[0] + else: + key = log[-1][0] + + logger.debug(f'Identified error type {key}') + # Count error types + if key in keys: + keys[key] += 1 + else: + keys[key] = 1 + # Select specific errors to examine + if key == savetype: + ecode = efile.split('/')[-1].split('.')[0] + code = get_code_from_val(filepath, ecode) + savedcodes.append((efile, code, log)) + if examine: + print(f'{efile} - {code}') + print() + print('\n'.join(log)) + x=input() + if x == 'E': + raise Exception + return savedcodes, keys, total + +def check_errs(path, logger, savetype=None, examine=None): + + savedcodes, errs, total = extract_keys(path, logger, savetype=savetype, examine=examine) + + # Summarise results + print(f'Found {total} error files:') + for key in errs.keys(): + if errs[key] > 0: + known_hint = 'Unknown' + if key in HINTS: + known_hint = HINTS[key] + print(f'{key}: {errs[key]} - ({known_hint})') + + return savedcodes + +def get_attribute(env, args, var): + """Assemble environment variable or take from passed argument.""" + if os.getenv(env): + return os.getenv(env) + elif hasattr(args, var): + return getattr(args, var) + else: + print(f'Error: Missing attribute {var}') + return None + +def save_sel(codes, groupdir, label, logger): + if len(codes) > 1: + codeset = ''.join([code[1] for code in codes]) + with open(f'{groupdir}/proj_codes_{label}.txt','w') as f: + f.write(codeset) + + logger.info(f'Written {len(codes)} to proj_codes_{label}') + else: + logger.info('No codes identified, no files written') + +def show_options(option, groupdir, operation, logger): + if option == 'jobids': + logger.info('Detecting IDs from previous runs:') + if operation == 'outputs': + os.system(f'ls {groupdir}/outs/') + else: + os.system(f'ls {groupdir}/errs/') + else: + logger.info('Detecting labels from previous runs:') + labels = glob.glob(f'{args.workdir}/groups/{args.groupID}/proj_codes*') + for l in labels: + pcode = l.split('/')[-1].replace("proj_codes_","").replace(".txt","") + if pcode == '1': + pcode = 'main' + logger.info(f'{format_str(pcode,20)} - {l}') + +def cleanup(cleantype, groupdir, logger): + if cleantype == 'proj_codes': + projset = glob.glob(f'{groupdir}/proj_codes_*') + for p in projset: + if 'proj_codes_1' not in p: + os.system(f'rm {p}') + elif cleantype == 'errors': + os.system(f'rm {groupdir}/errs/*') + elif cleantype == 'outputs': + os.system(f'rm {groupdir}/outs/*') + else: + pass + +def progress_check(args, logger): + if args.phase not in phases: + logger.error(f'Phase not accepted here - {args.phase}') + return None + else: + logger.info(f'Discovering dataset progress within group {args.groupID}') + redo_pcodes = [] + for index, phase in enumerate(phases): + redo_pcodes, completes = find_redos(phase, args.workdir, args.groupID, checks[index], ignore=redo_pcodes) + logger.info(f'{phase}: {len(redo_pcodes)} datasets') + if completes: + logger.info(f'complete: {len(completes)} datasets') + if phase == args.phase: + break + + # Write pcodes + if not args.repeat_label: + id = 1 + new_projcode_file = f'{args.workdir}/groups/{args.groupID}/proj_codes_{args.phase}_{id}.txt' + while os.path.isfile(new_projcode_file): + id += 1 + new_projcode_file = f'{args.workdir}/groups/{args.groupID}/proj_codes_{args.phase}_{id}.txt' + + args.repeat_label = f'{args.phase}_{id}' + + new_projcode_file = f'{args.workdir}/groups/{args.groupID}/proj_codes_{args.repeat_label}.txt' + + if args.write: + with open(new_projcode_file,'w') as f: + f.write('\n'.join(redo_pcodes)) + + # Written new pcodes + print(f'Written {len(redo_pcodes)} pcodes, repeat label: {args.repeat_label}') + +def error_check(args, logger): + job_path = f'{args.workdir}/groups/{args.groupID}/errs/{args.jobID}' + logger.info(f'Checking error files for {args.groupID} ID: {args.jobID}') + + savedcodes, errs, total = extract_keys(f'{job_path}/*.err', logger, savetype=args.inspect, examine=args.examine) + + # Summarise results + print(f'Found {total} error files:') + for key in errs.keys(): + if errs[key] > 0: + known_hint = 'Unknown' + if key in HINTS: + known_hint = HINTS[key] + print(f'{key}: {errs[key]} - ({known_hint})') + + if args.repeat_label and args.write: + save_sel(savedcodes, args.groupdir, args.repeat_label, logger) + elif args.repeat_label: + logger.info(f'Skipped writing {len(savedcodes)} to proj_codes_{args.repeat_label}') + else: + pass + +def output_check(args, logger): + job_path = f'{args.workdir}/groups/{args.groupID}/errs/{args.jobID}' + logger.info(f'Checking output files for {args.groupID} ID: {args.jobID}') + raise NotImplementedError + +operations = { + 'progress': progress_check, + 'errors': error_check, + 'outputs': output_check +} + +def assess_main(args): + + logger = init_logger(args.verbose, args.mode, 'assessor') + + args.workdir = get_attribute('WORKDIR', args, 'workdir') + args.groupdir = f'{args.workdir}/groups/{args.groupID}' + + if args.show_opts: + show_options(args.show_opts, args.groupdir, args.operation, logger) + return None + + if args.cleanup: + cleanup(args.cleanup, args.groupdir, logger) + return None + + if args.operation in operations: + operations[args.operation](args, logger) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Run a pipeline step for a single dataset') + parser.add_argument('groupID',type=str, help='Group identifier code') + parser.add_argument('operation',type=str, help='Operation to perform', choices=['progress','errors','outputs']) + + + parser.add_argument('-j','--jobid', dest='jobID', help='Identifier of job to inspect') + parser.add_argument('-p','--phase', dest='phase', default='validate', help='Pipeline phase to inspect') + parser.add_argument('-s','--show-opts', dest='show_opts', help='Show options for jobids, repeat label') + + parser.add_argument('-r','--repeat_label', dest='repeat_label', default=None, help='Save a selection of codes which failed on a given error - input a repeat id.') + parser.add_argument('-i','--inspect', dest='inspect', help='Inspect error/output of a given type/label') + parser.add_argument('-E','--examine', dest='examine', action='store_true', help='Examine log outputs individually.') + parser.add_argument('-c','--clean-up', dest='cleanup', default=None, help='Clean up group directory of errors/outputs/dataset lists', choices=['proj_codes','errors','outputs']) + + + parser.add_argument('-w','--workdir', dest='workdir', help='Working directory for pipeline') + parser.add_argument('-g','--groupdir', dest='groupdir', help='Group directory for pipeline') + parser.add_argument('-v','--verbose', dest='verbose', action='count', default=1, help='Print helpful statements while running') + parser.add_argument('-m','--mode', dest='mode', default=None, help='Print or record information (log or std)') + parser.add_argument('-W','--write', dest='write', action='store_true', help='Write outputs to files' ) + + args = parser.parse_args() + + assess_main(args) + \ No newline at end of file diff --git a/builder/environment_settings/requirements.txt b/builder/environment_settings/requirements.txt new file mode 100644 index 0000000..0c956fc --- /dev/null +++ b/builder/environment_settings/requirements.txt @@ -0,0 +1,31 @@ +aiohttp==3.8.5 +aiosignal==1.3.1 +asciitree==0.3.3 +async-timeout==4.0.3 +attrs==23.1.0 +certifi==2023.7.22 +cftime==1.6.2 +charset-normalizer==3.3.0 +entrypoints==0.4 +fasteners==0.19 +frozenlist==1.4.0 +fsspec==2023.6.0 +h5py==3.9.0 +idna==3.4 +kerchunk==0.2.0 +multidict==6.0.4 +netCDF4==1.6.4 +numcodecs==0.11.0 +numpy==1.26.0 +packaging==23.2 +pandas==2.1.1 +python-dateutil==2.8.2 +pytz==2023.3.post1 +requests==2.31.0 +six==1.16.0 +tzdata==2023.3 +ujson==5.8.0 +urllib3==2.0.6 +xarray==2023.8.0 +yarl==1.9.2 +zarr==2.16.1 diff --git a/builder/environment_settings/requirements_working.txt b/builder/environment_settings/requirements_working.txt new file mode 100644 index 0000000..319ce43 --- /dev/null +++ b/builder/environment_settings/requirements_working.txt @@ -0,0 +1,74 @@ +aiobotocore==2.6.0 +aiohttp==3.8.5 +aioitertools==0.11.0 +aiosignal==1.3.1 +asciitree==0.3.3 +async-timeout==4.0.2 +attrs==23.1.0 +botocore==1.31.17 +certifi==2023.7.22 +cf-python==3.15.2 +cfdm==1.10.1.1 +cftime==1.6.2 +cfunits==3.3.6 +charset-normalizer==3.2.0 +click==8.1.6 +cloudpickle==2.2.1 +contourpy==1.1.0 +cramjam==2.7.0 +cycler==0.11.0 +dask==2023.8.1 +distributed==2023.8.1 +entrypoints==0.4 +fasteners==0.18 +fastparquet==2023.7.0 +fonttools==4.42.0 +frozenlist==1.4.0 +fsspec==2023.6.0 +h5py==3.9.0 +idna==3.4 +importlib-metadata==6.8.0 +importlib-resources==6.0.1 +Jinja2==3.1.2 +jmespath==1.0.1 +kerchunk==0.2.0 +kiwisolver==1.4.4 +locket==1.0.0 +lz4==4.0.0 +MarkupSafe==2.1.3 +matplotlib==3.7.2 +msgpack==1.0.4 +multidict==6.0.4 +munkres==1.1.4 +netcdf-flattener==1.2.0 +netCDF4==1.6.4 +numcodecs==0.11.0 +numpy==1.22.4 +packaging==23.1 +pandas==2.0.3 +partd==1.4.0 +Pillow==10.0.0 +ply==3.11 +psutil==5.9.5 +pyparsing==3.0.9 +PyQt5-sip==12.11.0 +python-dateutil==2.8.2 +pytz==2023.3 +PyYAML==6.0.1 +requests==2.31.0 +scipy==1.11.1 +six==1.16.0 +sortedcontainers==2.4.0 +tblib==2.0.0 +toolz==0.12.0 +tornado==6.1 +typing_extensions==4.7.1 +tzdata==2023.3 +ujson==5.8.0 +urllib3==1.26.16 +wrapt==1.15.0 +xarray==2023.8.0 +yarl==1.9.2 +zarr==2.16.1 +zict==3.0.0 +zipp==3.16.2 diff --git a/builder/environment_settings/spec-file.txt b/builder/environment_settings/spec-file.txt new file mode 100644 index 0000000..7964682 --- /dev/null +++ b/builder/environment_settings/spec-file.txt @@ -0,0 +1,75 @@ +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +@EXPLICIT +https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-openblas.conda +https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2023.08.22-h06a4308_0.conda +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_1.conda +https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.9-4_cp39.conda +https://repo.anaconda.com/pkgs/main/noarch/tzdata-2023c-h04d1e81_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h7f98852_4.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/c-ares-1.19.1-h5eee18b_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libev-4.33-h7f8727e_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-ha4646dd_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.0-h7f98852_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-hcb278e6_0.conda +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.3-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/libedit-3.1.20221030-h5eee18b_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.43.0-h2797004_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libssh2-1.10.0-hdbd6064_2.conda +https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.12-h27826a3_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda +https://repo.anaconda.com/pkgs/main/linux-64/krb5-1.20.1-h143b758_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/libnghttp2-1.52.0-h2d74bed_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.24-pthreads_h413a1c8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/python-3.9.18-h0755675_0_cpython.conda +https://repo.anaconda.com/pkgs/main/noarch/asciitree-0.3.3-py_2.conda +https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.2.0-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.4-py39h06a4308_0.conda +https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.0-py39hd1e30aa_0.conda +https://conda.anaconda.org/conda-forge/noarch/fsspec-2023.9.1-pyh1a96a4e_0.conda +https://conda.anaconda.org/conda-forge/noarch/idna-3.4-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-18_linux64_openblas.conda +https://repo.anaconda.com/pkgs/main/linux-64/libcurl-8.2.1-h251f7ec_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/msgpack-python-1.0.3-py39hd09550d_0.conda +https://conda.anaconda.org/conda-forge/linux-64/multidict-6.0.4-py39h72bdee0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.25.2-py39h8a23956_0.conda +https://conda.anaconda.org/conda-forge/noarch/packaging-23.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2023.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.8.0-pyha770c72_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/ujson-5.4.0-py39h6a678d5_0.conda +https://conda.anaconda.org/conda-forge/noarch/wheel-0.41.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 +https://repo.anaconda.com/pkgs/main/noarch/fasteners-0.16.3-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/hdf5-1.12.1-h2b7332f_3.conda +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-18_linux64_openblas.conda +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-18_linux64_openblas.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.25.2-py39heeff2f4_0.conda +https://conda.anaconda.org/conda-forge/noarch/pip-23.2.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.8.0-hd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/yarl-1.9.2-py39hd1e30aa_0.conda +https://conda.anaconda.org/conda-forge/noarch/async-timeout-4.0.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.2-py39h2ae25f5_1.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/h5py-3.9.0-py39he06866b_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numcodecs-0.11.0-py39h6a678d5_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.1.0-py39hddac248_0.conda +https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.8.5-py39hd1e30aa_0.conda +https://conda.anaconda.org/conda-forge/noarch/xarray-2023.8.0-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/zarr-2.13.3-py39h06a4308_0.conda +https://conda.anaconda.org/conda-forge/noarch/kerchunk-0.2.0-pyhd8ed1ab_0.conda diff --git a/builder/examples/UKCP_test1.csv b/builder/examples/UKCP_test1.csv new file mode 100644 index 0000000..d1ac95d --- /dev/null +++ b/builder/examples/UKCP_test1.csv @@ -0,0 +1,3 @@ +proj_code,pattern/filename, updates, removals +land-rcm_uk_12km_rcp85_01_tasmax_day_v20190731,/badc/ukcp18/data/land-rcm/uk/12km/rcp85/01/tasmax/day/v20190731/*.nc,, +land-rcm_uk_12km_rcp85_01_tasmin_day_v20190731,/badc/ukcp18/data/land-rcm/uk/12km/rcp85/01/tasmin/day/v20190731/*.nc,, \ No newline at end of file diff --git a/builder/examples/UKCP_test1.txt b/builder/examples/UKCP_test1.txt new file mode 100644 index 0000000..05e6195 --- /dev/null +++ b/builder/examples/UKCP_test1.txt @@ -0,0 +1,2 @@ +/badc/ukcp18/data/land-rcm/uk/12km/rcp85/01/tasmax/day/v20190731/*.nc +/badc/ukcp18/data/land-rcm/uk/12km/rcp85/01/tasmin/day/v20190731/*.nc diff --git a/builder/group_run.py b/builder/group_run.py new file mode 100644 index 0000000..340a438 --- /dev/null +++ b/builder/group_run.py @@ -0,0 +1,175 @@ +import sys +import json +import os +import argparse +import logging + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +def get_group_len(workdir, group, repeat_id=1): + """Implement parallel reads from single 'group' file""" + with open(f'{workdir}/groups/{group}/proj_codes_{repeat_id}.txt') as f: + group_len = len(list(f.readlines())) + return group_len + +times = { + 'scan':'5:00', + 'compute':'30:00', + 'validate':'15:00' +} + +phases = list(times.keys()) + +def get_attribute(env, args, var): + """Assemble environment variable or take from passed argument.""" + if os.getenv(env): + return os.getenv(env) + elif hasattr(args, var): + return getattr(args, var) + else: + print(f'Error: Missing attribute {var}') + return None + +def main(args): + """Assemble sbatch script for parallel running jobs""" + + logger = init_logger(args.verbose, 0, 'main-group') + + # Set up main parameters + phase = args.phase + group = args.groupID + + WORKDIR = get_attribute('WORKDIR', args, 'workdir') + if not WORKDIR: + logger.error('WORKDIR missing or undefined') + return None + SRCDIR = get_attribute('SRCDIR', args, 'source') + if not SRCDIR: + logger.error('SRCDIR missing or undefined') + return None + VENV = get_attribute('KVENV', args, 'kvenv') + if not VENV: + logger.error('VENV missing or undefined') + return None + GROUPDIR = f'{WORKDIR}/groups/{group}' + + # init not parallelised + if phase == 'init': + from pipeline.init import init_config + logger.info('Running init steps as serial process') + args.groupdir = GROUPDIR + args.workdir = WORKDIR + args.source = SRCDIR + args.venvpath = VENV + init_config(args) + return None + + # Establish some group parameters + group_len = get_group_len(WORKDIR, group, repeat_id = args.repeat_id) + group_phase_sbatch = f'{GROUPDIR}/sbatch/{phase}.sbatch' + master_script = f'{SRCDIR}/single_run.py' + template = 'templates/phase.sbatch.template' + + + # Make Directories + for dirx in ['sbatch','outs','errs']: + if not os.path.isdir(f'{GROUPDIR}/{dirx}'): + os.makedirs(f'{GROUPDIR}/{dirx}') + + if phase not in phases: + logger.error(f'"{phase}" not recognised, please select from {phases}') + return None + + with open(template) as f: + sbatch = '\n'.join([r.strip() for r in f.readlines()]) + + time = times[phase] + if args.time_allowed: + time = args.time_allowed + + sb = sbatch.format( + f'{group}_{phase}_array', # Job name + time, # Time + f'{GROUPDIR}/outs/%A_{phase}/%a.out', # Outs + f'{GROUPDIR}/errs/%A_{phase}/%a.err', # Errs + VENV, + WORKDIR, + GROUPDIR, + master_script, phase, group, time + ) + if args.forceful: + sb += ' -f' + if args.verbose: + sb += ' -v' + if args.bypass: + sb += ' -b' + if args.quality: + sb += ' -Q' + + if args.repeat_id: + sb += f' -r {args.repeat_id}' + + with open(group_phase_sbatch,'w') as f: + f.write(sb) + + # Submit job array for this group in this phase + if args.dryrun: + logger.info('DRYRUN: sbatch command: ') + print(f'sbatch --array=0-{group_len-1} {group_phase_sbatch}') + else: + os.system(f'sbatch --array=0-{group_len-1} {group_phase_sbatch}') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Run a pipeline step for a group of datasets') + parser.add_argument('phase', type=str, help='Phase of the pipeline to initiate') + parser.add_argument('groupID',type=str, help='Group identifier code') + + parser.add_argument('-s',dest='source', help='Path to directory containing master scripts (this one)') + parser.add_argument('-e',dest='venvpath', help='Path to virtual (e)nvironment (excludes /bin/activate)') + + parser.add_argument('-w','--workdir', dest='workdir', help='Working directory for pipeline') + parser.add_argument('-g','--groupdir', dest='groupdir', help='Group directory for pipeline') + parser.add_argument('-p','--proj_dir', dest='proj_dir', help='Project directory for pipeline') + parser.add_argument('-n','--new_version', dest='new_version', help='If present, create a new version') + parser.add_argument('-m','--mode', dest='mode', default=None, help='Print or record information (log or std)') + parser.add_argument('-t','--time-allowed',dest='time_allowed', default=None, help='Time limit for this job') + parser.add_argument('-b','--bypass-errs', dest='bypass', action='store_true', help='Bypass all error messages - skip failed jobs') + + parser.add_argument('-i', '--input', dest='input', help='input file (for init phase)') + + parser.add_argument('-S','--subset', dest='subset', default=1, type=int, help='Size of subset within group') + parser.add_argument('-r','--repeat_id', dest='repeat_id', default='1', help='Repeat id (1 if first time running, _ otherwise)') + + parser.add_argument('-f',dest='forceful', action='store_true', help='Force overwrite of steps if previously done') + + parser.add_argument('-v','--verbose',dest='verbose' , action='count', default=0, help='Print helpful statements while running') + parser.add_argument('-d','--dryrun', dest='dryrun', action='store_true', help='Perform dry-run (i.e no new files/dirs created)' ) + + parser.add_argument('-Q','--quality', dest='quality', action='store_true', help='Quality assured checks - thorough run') + + args = parser.parse_args() + + main(args) + + \ No newline at end of file diff --git a/builder/issues/showcase_issue01.py b/builder/issues/showcase_issue01.py new file mode 100644 index 0000000..0f0a5ec --- /dev/null +++ b/builder/issues/showcase_issue01.py @@ -0,0 +1,9 @@ +import fsspec +import xarray as xr +kfile = '/gws/nopw/j04/cmip6_prep_vol1/kerchunk-pipeline/in_progress/CMIP6_rel1_6233/CMIP_BCC_BCC-CSM2-MR_historical_r1i1p1f1_Amon_huss_gn_v20181126/kerchunk-1c.json' +kfile2 = '/gws/nopw/j04/cmip6_prep_vol1/kerchunk-pipeline/complete/CMIP6_rel1_6233/CMIP_AS-RCEC_TaiESM1_historical_r1i1p1f1_3hr_clt_gn_v20201013-kr1.0.json' +mapper = fsspec.get_mapper('reference://',fo=kfile, target_options={"compression":None}) +# Need a safe repeat here +ds = xr.open_zarr(mapper, consolidated=False, decode_times=True) +print(ds.time) +print('Pass') \ No newline at end of file diff --git a/builder/pipeline/compute/parallel/batch_process.py b/builder/pipeline/compute/parallel/batch_process.py new file mode 100644 index 0000000..bff97ef --- /dev/null +++ b/builder/pipeline/compute/parallel/batch_process.py @@ -0,0 +1,53 @@ +from kerchunk import hdf, combine, df +import fsspec.implementations.reference +from fsspec.implementations.reference import LazyReferenceMapper +from tempfile import TemporaryDirectory + +import matplotlib.pyplot as plt + +import json + +import xarray as xr +import os, sys + +VERBOSE = True + +def vprint(msg): + if VERBOSE: + print('[INFO]', msg) + +tasks = sys.argv[-1] +id = sys.argv[-2] +DEV = '/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder/' +PATH = '/gws/nopw/j04/esacci_portal/kerchunk/parq/ocean_daily_all_parts' +pq = f'{PATH}/batch{id}' +with open(f'{DEV}/test_parqs/filelists/gargant.txt') as f: + files = [r.split('\n')[0] for r in f.readlines()] + +fcount = len(files) +files_per_task = int(fcount / int(tasks)) + +subset = files[int(files_per_task*int(id)):int(files_per_task*(int(id)+1))] + +try: + os.makedirs(pq) +except: + pass + +single_ref_sets = [] +for url in subset: + vprint(url) + single_ref_sets.append(hdf.SingleHdf5ToZarr(url, inline_threshold=-1).translate()) +vprint('Kerchunked all files') +out = LazyReferenceMapper.create(100, pq, fs = fsspec.filesystem("file")) +vprint('Created Lazy Reference Mapper') +out_dict = combine.MultiZarrToZarr( + single_ref_sets, + remote_protocol="file", + concat_dims=["time"], + out=out).translate() +vprint('Written to Parquet Store') + +out.flush() +vprint('Completed Flush') + diff --git a/builder/pipeline/compute/parallel/combine_refs.py b/builder/pipeline/compute/parallel/combine_refs.py new file mode 100644 index 0000000..b26eba8 --- /dev/null +++ b/builder/pipeline/compute/parallel/combine_refs.py @@ -0,0 +1,35 @@ +import os + + +PARTS = 'esacci7_parts' +FULL = 'esacci7_full' + + +# Combine metadatae into a single zmeta directory +if not os.path.isdir(f'batch/{FULL}'): + os.makedirs(f'batch/{FULL}') +varnames = [] +for dirname in os.listdir(f'batch/{PARTS}/batch0'): + if dirname != '.zmetadata': + try: + os.makedirs(f'batch/{FULL}/{dirname}') + except: + pass + varnames.append(dirname) + +specials = {'lat':1, 'lon':1} +repeat = 76 +#for varname in varnames: +if True: + varname = 'time' + print(varname) + refid = 0 + if varname in specials: + repeat = specials[varname] + + for index in range(repeat): + directory = f'batch/{PARTS}/batch{index}/{varname}' + for ref in os.listdir(directory): + #if not os.path.isfile(f'batch/{FULL}/{varname}/refs.{refid}.parq'): + os.system(f'cp {directory}/{ref} batch/{FULL}/{varname}/refs.{refid}.parq') + refid += 1 diff --git a/builder/pipeline/compute/parallel/correct_meta.py b/builder/pipeline/compute/parallel/correct_meta.py new file mode 100644 index 0000000..181800f --- /dev/null +++ b/builder/pipeline/compute/parallel/correct_meta.py @@ -0,0 +1,21 @@ +# Correct shapes and chunks +import json + + +old = 4 +new = 304 +PATH = '/home/users/dwest77/Documents/kerchunk_dev/parquet/dev/batch/esacci9_full' +with open(f'{PATH}/.zmetadata') as f: + refs = json.load(f) + +meta = refs['metadata'] + +for key in meta.keys(): + if '.zarray' in key: + # Correct chunks + if meta[key]['shape'][0] == old: + meta[key]['shape'][0] = new + +refs['metadata'] = meta +with open(f'{PATH}/.zmetadata','w') as f: + f.write(json.dumps(refs)) \ No newline at end of file diff --git a/builder/pipeline/compute/parallel/correct_time.py b/builder/pipeline/compute/parallel/correct_time.py new file mode 100644 index 0000000..a71e6ad --- /dev/null +++ b/builder/pipeline/compute/parallel/correct_time.py @@ -0,0 +1,14 @@ +import pandas as pd + +PATH = '/home/users/dwest77/Documents/kerchunk_dev/parquet/dev' +raw = None +for x in range(0,76): + df = pd.read_parquet(f'{PATH}/batch/esacci7_full/time/refs.{x}.parq') + if not raw: + raw = df['raw'][0] + else: + raw += df['raw'][0] + +df.to_parquet(f'{PATH}/batch/esacci7_full/time/refs.0.parq') + +#df.to_csv('time0.7.csv') \ No newline at end of file diff --git a/builder/pipeline/compute/parallel/process_wrapper.py b/builder/pipeline/compute/parallel/process_wrapper.py new file mode 100644 index 0000000..19f841c --- /dev/null +++ b/builder/pipeline/compute/parallel/process_wrapper.py @@ -0,0 +1,80 @@ +#python +import os +import sys +from getopt import getopt +import numpy as np + +BASE = '/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder' + +PATH = '/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder/temp/ocean-daily-all' + +dirs = [ + f'{PATH}/outs', + f'{PATH}/errs', + f'{PATH}/jbs_sbatch', + f'{PATH}/filelists' +] + +def mkfiles(p): + if not os.path.isdir(p): + os.makedirs(p) + else: + os.system(f'rm -rf {p}/*') + +for d in dirs: + mkfiles(d) + +SBATCH = """#!/bin/bash +#SBATCH --partition=short-serial-4hr +#SBATCH --account=short4hr +#SBATCH --job-name={} + +#SBATCH --time={} +#SBATCH --time-min=10:00 +#SBATCH --mem=2G + +#SBATCH -o {} +#SBATCH -e {} +{} + +module add jaspy +source {} +python {} {} +""" + +def format_sbatch(jobname, time, outs, errs, dependency, venvpath, script, cmdargs): + outs = f'{PATH}/outs/{outs}' + errs = f'{PATH}/errs/{errs}' + return SBATCH.format( + jobname, + time, + outs, + errs, + dependency, + venvpath, + script, + cmdargs) + +with open(f'{BASE}/test_parqs/filelists/gargant.txt') as f: + files = [r.split('\n')[0] for r in f.readlines()] + +fcount = 160 #len(files)/4 + +VENVPATH = '/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder/build_venv/bin/activate' +script = f'{BASE}/processing/parallel/batch_process.py' +cmdargs = '$SLURM_ARRAY_TASK_ID 1600' + +arrayjob = format_sbatch( + 'parq_%A_%a', + '30:00', + '%A_%a.out', + '%A_%a.err', + '', + VENVPATH, + script, + cmdargs +) +with open(f'{PATH}/control.sbatch','w') as f: + f.write(arrayjob) +print(fcount) +os.system(f'sbatch --array=0-{int(fcount-1)} {PATH}/control.sbatch') \ No newline at end of file diff --git a/builder/pipeline/compute/serial_process.py b/builder/pipeline/compute/serial_process.py new file mode 100644 index 0000000..70fc09b --- /dev/null +++ b/builder/pipeline/compute/serial_process.py @@ -0,0 +1,458 @@ +# Borrows from kerchunk tools but with more automation +import os +import json +import sys +import logging +from datetime import datetime + +class KerchunkDriverFatalError(Exception): + + def __init__(self, message="All drivers failed when performing conversion"): + self.message = message + super().__init__(self.message) + +WORKDIR = None +CONCAT_MSG = 'See individual files for more details' + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +class Converter: + def __init__(self, logger, bypass_errs=False): + self.logger = logger + self.success = True + self.bypass_errs = bypass_errs + + def convert_to_zarr(self, nfile, ctype, **kwargs): + try: + if ctype == 'ncf3': + return self.ncf3_to_zarr(nfile, **kwargs) + elif ctype == 'hdf5': + return self.hdf5_to_zarr(nfile, **kwargs) + elif ctype == 'tif': + return self.tiff_to_zarr(nfile, **kwargs) + else: + self.logger.debug(f'Extension {ctype} not valid') + return None + except Exception as err: + if self.bypass_errs: + pass + else: + raise err + + def hdf5_to_zarr(self, nfile, **kwargs): + """Converter for HDF5 type files""" + from kerchunk.hdf import SingleHdf5ToZarr + return SingleHdf5ToZarr(nfile, **kwargs).translate() + + def ncf3_to_zarr(self, nfile, **kwargs): + """Converter for NetCDF3 type files""" + from kerchunk.netCDF3 import NetCDF3ToZarr + return NetCDF3ToZarr(nfile, **kwargs).translate() + + def tiff_to_zarr(self, tfile, **kwargs): + """Converter for Tiff type files""" + self.logger.error('Tiff conversion not yet implemented - aborting') + self.success = False + return None + +class Indexer(Converter): + def __init__(self, + proj_code, + cfg_file=None, detail_file=None, workdir=WORKDIR, + issave_meta=False, thorough=False, forceful=False, + verb=0, mode=None, version_no=1, + concat_msg=CONCAT_MSG, bypass=False): + """Initialise indexer for this dataset, set all variables and prepare for computation""" + logger = init_logger(verb, mode, 'compute-serial') + super().__init__(logger, bypass_errs=bypass) + + self.logger.debug('Starting variable definitions') + + self.workdir = workdir + self.proj_code = proj_code + + self.issave_meta = issave_meta + self.updates, self.removals, self.load_refs = False, False, False + + self.version_no = version_no + + self.concat_msg = CONCAT_MSG + + self.verb = verb + self.mode = mode + if mode != 'std': + self.log = '' + else: + self.log = None + + self.logger.debug('Loading config information') + with open(cfg_file) as f: + cfg = json.load(f) + + with open(detail_file) as f: + detail = json.load(f) + + self.proj_dir = cfg['proj_dir'] + + if 'update' in cfg: + self.updates = cfg['update'] + if 'remove' in cfg: + self.removals = cfg['remove'] + + if 'type' in detail: + self.use_json = (detail['type'] == 'JSON') + else: + self.use_json = True + + self.outfile = f'{self.proj_dir}/kerchunk-{version_no}a.json' + self.outstore = f'{self.proj_dir}/kerchunk-{version_no}a.parq' + self.record_size = 167 # Default + + self.filelist = f'{self.proj_dir}/allfiles.txt' + + self.cache = f'{self.proj_dir}/cache/' + if os.path.isfile(f'{self.cache}/temp_zattrs.json') and not thorough: + # Load data instead of create from scratch + self.load_refs = True + self.logger.debug('Found cached data from previous run, loading cache') + + + if not os.path.isdir(self.cache): + os.makedirs(self.cache) + if thorough: + os.system(f'rm -rf {self.cache}/*') + + self.combine_kwargs = {'concat_dims':['time']} # Always try time initially + self.create_kwargs = {'inline_threshold':1000} + self.pre_kwargs = {} + + self.set_filelist() + self.logger.debug('Finished all setup steps') + + def set_filelist(self): + """Get the list of files from the filelist for this dataset""" + with open(self.filelist) as f: + self.listfiles = [r.strip() for r in f.readlines()] + self.limiter = len(self.listfiles) + + def add_download_link(self, refs): + timecount = 0 + total = len(list(refs.keys())) + t1 = datetime.now() + for key in refs.keys(): + if len(refs[key]) == 3: + if refs[key][0][0] == '/': + refs[key][0] = 'https://dap.ceda.ac.uk' + refs[key][0] + if timecount == 100: + end_time = (datetime.now()-t1).total_seconds()*(total/6000) + self.logger.debug(f'Expected time remaining: {end_time} mins') + timecount += 1 + return refs + + def add_kerchunk_history(self, attrs): + """Add kerchunk variables to the metadata for this dataset""" + + from datetime import datetime + + # Get current time + # Format for different uses + now = datetime.now() + if 'history' in attrs: + if type(attrs['history']) == str: + hist = attrs['history'].split('\n') + else: + hist = attrs['history'] + + if 'Kerchunk' in hist[-1]: + hist[-1] = 'Kerchunk file updated on ' + now.strftime("%D") + else: + hist.append('Kerchunk file created on ' + now.strftime("%D")) + attrs['history'] = '\n'.join(hist) + else: + attrs['history'] = 'Kerchunk file created on ' + now.strftime("%D") + '\n' + + attrs['kerchunk_revision'] = self.version_no + attrs['kerchunk_creation_date'] = now.strftime("%d%m%yT%H%M%S") + return attrs + + def combine_and_save(self, refs, zattrs): + """Concatenation of ref data for different kerchunk schemes""" + if self.use_json: + self.logger.info('Concatenating to JSON format Kerchunk file') + self.data_to_json(refs, zattrs) + else: + self.logger.info('Concatenating to Parquet format Kerchunk store') + self.data_to_parq(refs) + + def data_to_parq(self, refs): + """Concatenating to Parquet format Kerchunk store""" + from kerchunk.combine import MultiZarrToZarr + from fsspec import filesystem + from fsspec.implementations.reference import LazyReferenceMapper + + self.logger.debug('Starting parquet-write process') + + if not os.path.isdir(self.outstore): + os.makedirs(self.outstore) + out = LazyReferenceMapper.create(self.record_size, self.outstore, fs = filesystem("file"), **self.pre_kwargs) + + out_dict = MultiZarrToZarr( + refs, + out=out, + remote_protocol='file', + concat_dims=['time'], + **self.combine_kwargs + ).translate() + + out.flush() + self.logger.info(f'Written to parquet store - {self.proj_code}/kerchunk-1a.parq') + + def data_to_json(self, refs, zattrs): + """Concatenating to JSON format Kerchunk file""" + from kerchunk.combine import MultiZarrToZarr + + self.logger.debug('Starting JSON-write process') + + # Already have default options saved to class variables + if len(refs) > 1: + self.logger.debug('Concatenating refs using MultiZarrToZarr') + mzz = MultiZarrToZarr(refs, **self.combine_kwargs).translate() + if zattrs: + zattrs = self.add_kerchunk_history(zattrs) + else: + self.logger.debug(zattrs) + raise ValueError + mzz['refs']['.zattrs'] = json.dumps(zattrs) + else: + self.logger.debug('Found single ref to save') + mzz = refs[0] + # Override global attributes + mzz['refs'] = self.add_download_link(mzz['refs']) + + with open(self.outfile,'w') as f: + f.write(json.dumps(mzz)) + + self.logger.info(f'Written to JSON file - {self.proj_code}/kerchunk-1a.json') + + def correct_metadata(self, allzattrs): + # General function for correcting metadata + # - Combine all existing metadata in standard way + # - Add updates and remove removals specified by configuration + + self.logger.debug('Starting metadata corrections') + if type(allzattrs) == list: + zattrs = self.clean_attr_array(allzattrs) + else: + zattrs = self.clean_attrs(allzattrs) + self.logger.debug('Applying config info on updates and removals') + + if self.updates: + for update in self.updates.keys(): + zattrs[update] = self.updates[update] + new_zattrs = {} + if self.removals: + for key in zattrs: + if key not in self.removals: + new_zattrs[key] = zattrs[key] + + self.logger.debug('Finished metadata corrections') + if not zattrs: + self.logger.error('Lost zattrs at correction phase') + raise ValueError + return zattrs + + def clean_attr_array(self, allzattrs): + # Collect attributes from all files, + # determine which are always equal, which have differences + base = json.loads(allzattrs[0]) + + self.logger.debug('Correcting time attributes') + # Sort out time metadata here + times = {} + all_values = {} + for k in base.keys(): + if 'time' in k: + times[k] = [base[k]] + all_values[k] = [] + + nonequal = {} + for ref in allzattrs[1:]: + zattrs = json.loads(ref) + for attr in zattrs.keys(): + if attr in all_values: + all_values[attr].append(zattrs[attr]) + else: + all_values[attr] = zattrs[attr] + if attr in times: + times[attr].append(zattrs[attr]) + elif attr not in base: + nonequal[attr] = False + else: + if base[attr] != zattrs[attr]: + nonequal[attr] = False + + base = {**base, **self.check_time_attributes(times)} + self.logger.debug('Comparing similar keys') + + for attr in nonequal.keys(): + if len(set(all_values[attr])) == 1: + base[attr] = all_values[attr][0] + else: + base[attr] = self.concat_msg + + self.logger.debug('Finished checking similar keys') + return base + + def clean_attrs(self, zattrs): + self.logger.warning('Attribute cleaning post-loading from temp is not implemented') + return zattrs + + def check_time_attributes(self, times): + # Takes dict of time attributes with lists of values + # Sort time arrays + # Assume time_coverage_start, time_coverage_end, duration (2 or 3 variables) + combined = {} + for k in times.keys(): + if 'start' in k: + combined[k] = sorted(times[k])[0] + elif 'end' in k or 'stop' in k: + combined[k] = sorted(times[k])[-1] + elif 'duration' in k: + pass + else: + # Unrecognised time variable + # Check to see if all the same value + if len(set(times[k])) == len(self.listfiles): + combined[k] = 'See individual files for details' + elif len(set(times[k])) == 1: + combined[k] = times[k][0] + else: + combined[k] = list(set(times[k])) + + duration = '' # Need to compare start/end + self.logger.debug('Finished time corrections') + return combined + + def save_metadata(self,zattrs): + """Cache metadata global attributes in a temporary file""" + with open(f'{self.cache}/temp_zattrs.json','w') as f: + f.write(json.dumps(zattrs)) + self.logger.debug('Saved global attribute cache') + + def save_cache(self, refs, zattrs): + """Cache reference data in temporary json reference files""" + for x, r in enumerate(refs): + cache_ref = f'{self.cache}/{x}.json' + with open(cache_ref,'w') as f: + f.write(json.dumps(r)) + self.save_metadata(zattrs) + self.logger.debug('Saved metadata cache') + # All file content saved for later reconcatenation + + def try_all_drivers(self, nfile, **kwargs): + """Safe creation allows for known issues and tries multiple drivers""" + + extension = False + + if '.' in nfile: + ctype = f'.{nfile.split(".")[-1]}' + else: + ctype = '.nc' + + supported_extensions = ['ncf3','hdf5','tif'] + + self.logger.debug(f'Attempting conversion for 1 {ctype} extension') + + tdict = self.convert_to_zarr(nfile, ctype, **kwargs) + ext_index = 0 + while not tdict and ext_index < len(supported_extensions)-1: + # Try the other ones + extension = supported_extensions[ext_index] + self.logger.debug(f'Attempting conversion for {extension} extension') + if extension != ctype: + tdict = self.convert_to_zarr(nfile, extension, **kwargs) + ext_index += 1 + + if not tdict: + self.logger.error('Scanning failed for all drivers, file type is not Kerchunkable') + raise KerchunkDriverFatalError + else: + if extension: + self.logger.debug(f'Scan successful with {extension} driver') + else: + self.logger.debug(f'Scan successful with {ctype} driver') + return tdict + + def convert_to_kerchunk(self): + refs = [] + allzattrs = [] + for x, nfile in enumerate(self.listfiles[:self.limiter]): + self.logger.info(f'Creating refs: {x+1}/{len(self.listfiles)}') + zarr_content = self.try_all_drivers(nfile, **self.create_kwargs) + if zarr_content: + allzattrs.append(zarr_content['refs']['.zattrs']) + refs.append(zarr_content) + return allzattrs, refs + + def load_cache(self): + refs = [] + for x, nfile in enumerate(self.listfiles[:self.limiter]): + self.logger.info(f'Loading refs: {x+1}/{len(self.listfiles)}') + cache_ref = f'{self.cache}/{x}.json' + with open(cache_ref) as f: + refs.append(json.load(f)) + + self.logger.debug(f'Loading attributes: {x+1}/{len(self.listfiles)}') + with open(f'{self.cache}/temp_zattrs.json') as f: + zattrs = json.load(f) + if not zattrs: + self.logger.error('No attributes loaded from temp store') + raise ValueError + return zattrs, refs + + def create_refs(self): + self.logger.info(f'Starting computation for components of {self.proj_code}') + if not self.load_refs: + allzattrs, refs = self.convert_to_kerchunk() + zattrs = self.correct_metadata(allzattrs) + else: + zattrs, refs = self.load_cache() + zattrs = self.correct_metadata(zattrs) + + try: + if self.success: + self.logger.info('Single conversions complete, starting concatenation') + self.combine_and_save(refs, zattrs) + if self.issave_meta: + self.save_cache(refs, zattrs) + else: + self.logger.info('Issue with conversion unspecified - aborting process') + self.save_cache(refs, zattrs) + return True + except TypeError as err: + self.logger.error(f'Detected fatal error - {err}') + raise err + +if __name__ == '__main__': + print('Serial Processor for Kerchunk Pipeline - run with single_run.py') + \ No newline at end of file diff --git a/builder/pipeline/init.py b/builder/pipeline/init.py new file mode 100644 index 0000000..ed58fcc --- /dev/null +++ b/builder/pipeline/init.py @@ -0,0 +1,350 @@ + +__author__ = "Daniel Westwood" +__contact__ = "daniel.westwood@stfc.ac.uk" +__copyright__ = "Copyright 2023 United Kingdom Research and Innovation" + +import os +import json +import logging +import glob + +config = { + 'proj_code': None, + 'pattern': None, + 'update': None, + 'remove': None +} + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +def get_updates(logger): + """Get key-value pairs for updating in final metadata""" + logger.debug('Getting update key-pairs') + inp = None + valsdict = {} + while inp != 'exit': + inp = input('Attribute: ("exit" to escape):') + if inp != 'exit': + val = input('Value: ') + valsdict[inp] = val + return valsdict + +def get_removals(logger): + """Get attribute names to remove in final metadata""" + logger.debug('Getting removals') + valsarr = [] + while inp != 'exit': + inp = input('Attribute: ("exit" to escape):') + if inp != 'exit': + valsarr.append(inp) + return valsarr + +def get_proj_code(path, prefix=''): + parts = path.replace(prefix,'').replace('/','_').split('_') + if '*.' in parts[-1]: + parts = parts[:-2] + return '_'.join(parts) + +def make_filelist(pattern, proj_dir, logger): + """Create list of files associated with this project""" + logger.debug(f'Making list of files for project {proj_dir.split("/")[-1]}') + + if pattern.endswith('.txt'): + os.system(f'cp {pattern} {proj_dir}/allfiles.txt') + elif os.path.isdir(proj_dir): + os.system(f'ls {pattern} > {proj_dir}/allfiles.txt') + else: + logger.error(f'Project Directory not located - {proj_dir}') + return None + return True + +def load_from_input_file(args, logger): + """Configure project directory and base config from input file""" + logger.debug('Ingesting input config file') + if os.path.isfile(args.input): + with open(args.input) as f: + refs = json.load(f) + + proj_dir = refs['proj_dir'] + if not os.path.isdir(proj_dir): + os.makedirs(proj_dir) + if not os.path.isfile(f'{proj_dir}/base-cfg.json'): + os.system(f'cp {args.input} {proj_dir}/base-cfg.json') + else: + logger.error(f'Input file {args.input} does not exist') + return None + +def text_file_to_csv(args, logger, prefix=None): + """Convert text file list of patterns to a csv for a set of projects""" + logger.debug('Converting text file to csv') + + if not os.path.isdir(args.workdir): + if args.dryrun: + logger.debug(f'DRYRUN: Skip making workdir {args.workdir}') + else: + os.makedirs(args.workdir) + if args.groupdir and not os.path.isdir(args.groupdir): + if args.dryrun: + logger.debug(f'DRYRUN: Skip making groupdir {args.groupdir}') + else: + os.makedirs(args.groupdir) + + new_inputfile = f'{args.workdir}/groups/filelists/{args.groupID}.txt' + + if new_inputfile != args.input: + if args.dryrun: + logger.debug(f'DRYRUN: Skip copying input file {args.input} to {new_inputfile}') + else: + os.system(f'cp {args.input} {new_inputfile}') + + with open(new_inputfile) as f: + datasets = [r.strip() for r in f.readlines()] + + if not os.path.isfile(f'{args.groupdir}/datasets.csv') or args.forceful: + records = '' + logger.info('Creating filesets for each dataset') + for index, ds in enumerate(datasets): + skip = False + + pattern = str(ds) + if not (pattern.endswith('.nc') or pattern.endswith('.tif')): + logger.debug('Identifying extension') + fileset = [r.split('.')[-1] for r in glob.glob(f'{pattern}/*')] + if len(set(fileset)) > 1: + logger.error(f'File type not specified for {pattern} - found multiple ') + skip = True + elif len(set(fileset)) == 0: + skip = True + else: + extension = list(set(fileset))[0] + pattern = f'{pattern}/*.{extension}' + logger.debug(f'Found .{extension} common type') + + if not skip: + proj_code = get_proj_code(ds, prefix=prefix) + logger.debug(f'Assembled project code: {proj_code}') + proj_dir = f'{args.workdir}/in_progress/{args.groupID}/{proj_code}' + if 'latest' in pattern: + pattern = pattern.replace('latest', os.readlink(pattern)) + + records += f'{proj_code},{pattern},,\n' + logger.debug(f'Added entry and created fileset for {index+1}/{len(datasets)}') + if args.dryrun: + logger.debug(f'DRYRUN: Skip creating csv file {args.groupdir}/datasets.csv') + else: + with open(f'{args.groupdir}/datasets.csv','w') as f: + f.write(records) + else: + logger.warn(f'Using existing csv file at {args.groupdir}/datasets.csv') + return True + + # Output completed csv setup part + +def make_dirs(args, logger): + """Set up directory structure for working directory""" + logger.info('Creating project directories') + + # Open csv and gather data + with open(f'{args.groupdir}/datasets.csv') as f: + datasets = {r.strip().split(',')[0]:r.strip().split(',')[1:] for r in f.readlines()[:]} + + # Map dataset parameters from csv to config JSON + params = list(config.keys()) + proj_codes = list(datasets.keys()) + + if proj_codes[0] == 'proj_code': + proj_codes = proj_codes[1:] + + for index, proj_code in enumerate(proj_codes): + cfg_values = dict(config) # Ensure no linking + ds_values = datasets[proj_code] + pattern = ds_values[0] + + logger.info(f'Creating directories/filelists for {index+1}/{len(proj_codes)}') + + cfg_values[params[0]] = proj_code + # Set all other parameters + if len(params) == len(ds_values)+1: + for x, p in enumerate(params[1:]): + cfg_values[p] = ds_values[x] + else: + logger.warning(f'Project code {index}:{proj_code} from {args.groupID} does not have correct number of fields.') + logger.warning(f'Fields specified must be {params}, not {ds_values}') + + if 'latest' in pattern: + pattern = pattern.replace('latest', os.readlink(pattern)) + + if args.groupID: + proj_dir = f'{args.groupdir}/{proj_code}' + else: + proj_dir = f'{args.workdir}/in_progress/{proj_code}' + + # Save config file + if not os.path.isdir(proj_dir): + if args.dryrun: + logger.debug(f'DRYRUN: Skip making Directories to {proj_dir}') + else: + os.makedirs(proj_dir) + else: + if not args.forceful: + logger.warn(f'{proj_code} directory already exists') + + status = make_filelist(pattern, proj_dir, logger) + if not status: + logger.error(f'Issue creating filelist for {proj_code}') + else: + base_file = f'{proj_dir}/base-cfg.json' + + if not os.path.isfile(base_file) or args.forceful: + if args.dryrun: + logger.debug(f'DRYRUN: Skip writing base file {base_file}') + else: + with open(base_file,'w') as f: + f.write(json.dumps(cfg_values)) + else: + logger.warn(f'{base_file} already exists - skipping') + + logger.info(f'Exporting {len(proj_codes)} dataset config files') + + if args.dryrun: + logger.debug(f'DRYRUN: Skip writing {len(proj_codes)} project codes list {args.groupdir}/proj_codes_1.txt') + else: + with open(f'{args.groupdir}/proj_codes_1.txt','w') as f: + f.write('\n'.join(proj_codes)) + + logger.info(f'Written as group ID: {args.groupID}') + +def init_config(args): + """Main configuration script, load configurations from input sources""" + + logger = init_logger(args.verbose, args.mode, 'init') + logger.info('Starting initialisation') + + groupID = None + if hasattr(args, 'groupID'): + groupID = getattr(args,'groupID') + if hasattr(args,'group'): + groupID = getattr(args,'group') + + if groupID: + logger.debug('Starting group initialisation') + if not hasattr(args,'input'): + logger.error('Group run requires input file in csv or txt format') + return None + + if '.txt' in args.input: + logger.debug('Converting text file to csv') + status = text_file_to_csv(args, logger) # Includes creating csv + if not status: + return None + elif '.csv' in args.input: + logger.debug('Ingesting csv file') + new_csv = f'{args.groupdir}/datasets.csv' + if not os.path.isdir(args.groupdir): + os.makedirs(args.groupdir) + + os.system(f'cp {args.input} {new_csv}') + make_dirs(args, logger) + + else: + logger.debug('Starting single project initialisation') + + if hasattr(args,'input'): + load_from_input_file(args, logger) + else: + try: + get_input(args, logger) + except KeyboardInterrupt: + logger.info('Aborting user input process and exiting') + return None + except Exception as e: + logger.error(f'User Input Error - {e}') + return None + +def get_input(args, logger): + """Get command-line inputs for specific project configuration""" + + # Get basic inputs + logger.debug('Getting user inputs for new project') + + if os.getenv('SLURM_JOB_ID'): + logger.error('Cannot run input script as Slurm job - aborting') + return None + + proj_code = input('Project Code: ') + pattern = input('Wildcard Pattern: (leave blank if not applicable) ') + if pattern == '': + filelist = input('Path to filelist: ') + pattern = None + else: + filelist = None + + if os.getenv('WORKDIR'): + workdir = os.getenv('WORKDIR') + + if args.workdir and args.workdir != workdir: + print('Environment workdir does not match provided address') + print('ENV:',workdir) + print('ARG:',args.workdir) + choice = input('Choose to keep the ENV value or overwrite with the ARG value: (E/A) :') + if choice == 'E': + pass + elif choice == 'A': + os.environ['WORKDIR'] = args.workdir + workdir = args.workdir + else: + print('Invalid input, exiting') + return None + + proj_dir = f'{workdir}/in_progress/{proj_code}' + if os.path.isdir(proj_dir): + if args.forceful: + pass + else: + print('Error: Directory already exists -',proj_dir) + return None + else: + os.makedirs(proj_dir) + + config = { + 'proj_code': proj_code, + 'workdir' : workdir, + 'proj_dir' : proj_dir + } + do_updates = input('Do you wish to add overrides to metadata values? (y/n): ') + if do_updates == 'y': + config['update'] = get_updates() + + do_removals = input('Do you wish to remove known attributes from the metadata? (y/n): ') + if do_removals == 'y': + config['remove'] = get_removals(remove=True) + + if pattern: + config['pattern'] = pattern + + with open(f'{proj_dir}/base-cfg.json','w') as f: + f.write(json.dumps(config)) + print(f'Written cfg file at {proj_dir}/base-cfg.json') + +if __name__ == '__main__': + print('Kerchunk Pipeline Config Initialiser - run using master scripts') diff --git a/builder/pipeline/old/create_group.py b/builder/pipeline/old/create_group.py new file mode 100644 index 0000000..4c3a848 --- /dev/null +++ b/builder/pipeline/old/create_group.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +import sys +import json +import os +import random + +config = { + 'proj_code': None, + 'workdir': None, + 'proj_dir':None, + 'pattern': None, + 'update': None, + 'remove': None +} + +general = "/badc/cmip6/data/CMIP6/" +groupdir = '' +workdir = '' + +# List 100 random CMIP datasets + +def get_CMIP_data_recursive(path): + contents = [] + for c in os.listdir(path): + if os.path.isdir(os.path.join(path,c)): + contents.append(c) + if len(contents) > 0: + randsel = contents[random.randint(0,len(contents)-1)] + return get_CMIP_data_recursive(os.path.join(path, randsel)) + else: + return path + +def get_proj_code(path, prefix=''): + return path.replace(prefix,'').replace('/','_') + +def get_fpaths(): + file = f'{groupdir}/CMIP6_rand100_00/proj_codes.txt' + with open(file) as f: + contents = [r.strip() for r in f.readlines()] + return contents + +def test_cmip6(): + fpaths = get_fpaths() + word = '' + for x in range(400): + print(x) + fpath = get_CMIP_data_recursive(general) + while fpath in fpaths: + fpath = get_CMIP_data_recursive(general) + proj_code = get_proj_code(fpath) + workdir = '/gws/nopw/j04/esacci_portal/kerchunk/pipeline/in_progress' + proj_dir = f'{workdir}/{proj_code}' + pattern = f'{os.path.realpath(fpath)}/*.nc' + word += f'{proj_code},{workdir},{proj_dir},{pattern},,\n' + + if not os.path.isdir(f'{groupdir}/CMIP6_rand400_00'): + os.makedirs(f'{groupdir}/CMIP6_rand400_00') + + with open(f'{groupdir}/CMIP6_rand400_00/datasets.csv','w') as f: + f.write(word) + print('Wrote 100 datasets to config group CMIP6_rand100_00') + +if __name__ == '__main__': + # Get a list of paths from some input file + # For each path, get project_code, workdir, proj_dir, pattern. + + group = sys.argv[1] + prefix = sys.argv[2] + + groupdir = os.environ['GROUPDIR'] + workdir = os.environ['WORKDIR'] + + with open(f'{groupdir}/filelists/{group}.txt') as f: + datasets = [r.strip() for r in f.readlines()] + records = '' + for ds in datasets: + proj_code = get_proj_code(ds, prefix=prefix) + proj_dir = f'{workdir}/{group}/{proj_code}' + pattern = f'{os.path.realpath(ds)}/*.nc' + records += f'{proj_code},{workdir},{proj_dir},{pattern},,\n' + + if not os.path.isdir(f'{groupdir}/{group}'): + os.makedirs(f'{groupdir}/{group}') + + with open(f'{groupdir}/{group}/datasets.csv','w') as f: + f.write(records) + print(f"Wrote {len(datasets)} datasets to config group {group}") diff --git a/builder/pipeline/old/wide_config.py b/builder/pipeline/old/wide_config.py new file mode 100644 index 0000000..45557cf --- /dev/null +++ b/builder/pipeline/old/wide_config.py @@ -0,0 +1,51 @@ +import sys +import json +import os + +config = { + 'proj_code': None, + 'workdir': None, + 'proj_dir':None, + 'pattern': None, + 'update': None, + 'remove': None +} + +if __name__ == '__main__': + csvfile = sys.argv[1] + + groupdir = os.environ['GROUPDIR'] + groupid = csvfile.split('/')[-2] + + # Open csv and gather data + with open(f'{groupdir}/{csvfile}') as f: + datasets = {r.strip().split(',')[0]:r.strip().split(',')[1:] for r in f.readlines()[:]} + + # Configure for each dataset + params = list(config.keys()) + proj_codes = list(datasets.keys()) + for dsk in proj_codes: + ds = datasets[dsk] + cfg = dict(config) + cfg[params[0]] = dsk + for x, p in enumerate(params[1:]): + cfg[p] = ds[x] + + # Save config file + if not os.path.isdir(cfg['proj_dir']): + os.makedirs(cfg['proj_dir']) + + with open(f'{cfg["proj_dir"]}/base-cfg.json','w') as f: + f.write(json.dumps(cfg)) + + else: + print(f'{cfg["proj_code"]} already exists - skipping') + + print(f'Exported {len(proj_codes)} dataset config files') + + if not os.path.isdir(f'{groupdir}/{groupid}'): + os.makedirs(f'{groupdir}/{groupid}') + with open(f'{groupdir}/{groupid}/proj_codes.txt','w') as f: + f.write('\n'.join(proj_codes)) + + print('Written as group ID:',groupid) \ No newline at end of file diff --git a/builder/pipeline/old/~compute.py b/builder/pipeline/old/~compute.py new file mode 100644 index 0000000..c8e4a5e --- /dev/null +++ b/builder/pipeline/old/~compute.py @@ -0,0 +1,63 @@ +# Main script for processing, runs all other parts as needed including submitting batch jobs for large parquet sets. +import sys +import os +import json + +from serial.CFG_create_kerchunk import Indexer + +def rundecode(cfgs): + """ + cfgs - list of command inputs depending on user input to this program + """ + flags = { + '-w': 'workdir', + '-i': 'groupid', + '-g': 'groupdir' + } + kwargs = {} + for x in range(0,int(len(cfgs)),2): + try: + flag = flags[cfgs[x]] + kwargs[flag] = cfgs[x+1] + except KeyError: + print('Unrecognised cmdarg:',cfgs[x:x+1]) + + return kwargs + +def setup_compute(proj_code, workdir=None, **kwargs): + if os.getenv('KERCHUNK_DIR'): + workdir = os.getenv('KERCHUNK_DIR') + + cfg_file = f'{workdir}/in_progress/{proj_code}/base-cfg.json' + if os.path.isfile(cfg_file): + with open(cfg_file) as f: + cfg = json.load(f) + else: + print(f'Error: cfg file missing or not provided - {cfg_file}') + return None + + detail_file = f'{workdir}/in_progress/{proj_code}/detail-cfg.json' + if os.path.isfile(detail_file): + with open(detail_file) as f: + detail = json.load(f) + else: + print(f'Error: cfg file missing or not provided - {detail_file}') + return None + + if detail['type'] == 'JSON': + Indexer(proj_code, cfg=cfg, detail=detail, **kwargs).create_refs() + else: + pass + +def get_proj_code(groupdir, pid, groupid): + with open(f'{groupdir}/{groupid}/proj_codes.txt') as f: + proj_code = f.readlines()[int(pid)].strip() + return proj_code + +if __name__ == '__main__': + proj_code = sys.argv[1] + kwargs = rundecode(sys.argv[2:]) + if 'groupid' in kwargs: + proj_code = get_proj_code(kwargs['groupdir'], proj_code, kwargs['groupid']) + + setup_compute(proj_code, **kwargs) \ No newline at end of file diff --git a/builder/pipeline/scan.py b/builder/pipeline/scan.py new file mode 100644 index 0000000..510afef --- /dev/null +++ b/builder/pipeline/scan.py @@ -0,0 +1,341 @@ +## Tool for scanning a netcdf file or set of netcdf files for kerchunkability + +# Determine total number of netcdf chunks in first file +# Determine number of netcdf files + +# Calculate total number of chunks and output + +__author__ = "Daniel Westwood" +__contact__ = "daniel.westwood@stfc.ac.uk" +__copyright__ = "Copyright 2023 United Kingdom Research and Innovation" + +from kerchunk.hdf import SingleHdf5ToZarr +from kerchunk.netCDF3 import NetCDF3ToZarr +import os, sys +from datetime import datetime +import glob +import math +import json +import logging + +import numpy as np + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +class FilecapExceededError(Exception): + def __init__(self, nfiles=0, verbose=0): + self.message = f'Filecap exceeded: {nfiles} files attempted' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class ExpectTimeoutError(Exception): + def __init__(self, required=0, current='', verbose=0): + self.message = f'Scan requires minimum {required} - current {current}' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +def format_float(value, logger): + """Format byte-value with proper units""" + logger.debug(f'Formatting value {value} in bytes') + if value: + unit_index = -1 + units = ['K','M','G','T','P'] + while value > 1000: + value = value / 1000 + unit_index += 1 + return f'{value:.2f} {units[unit_index]}B' + else: + return None + +def safe_format(value, fstring): + try: + return fstring.format(value=value) + except: + return '' + +def map_to_kerchunk(args, nfile, ctype, logger): + """Perform Kerchunk reading on specific file""" + logger.info(f'Running Kerchunk reader for {nfile}') + from pipeline.compute.serial_process import Converter + + quickConvert = Converter(logger, bypass_errs=args.bypass) + + kwargs = {} + supported_extensions = ['ncf3','hdf5','tif'] + + logger.debug(f'Attempting conversion for 1 {ctype} extension') + t1 = datetime.now() + tdict = quickConvert.convert_to_zarr(nfile, ctype, **kwargs) + t_len = (datetime.now()-t1).total_seconds() + ext_index = 0 + while not tdict and ext_index < len(supported_extensions)-1: + # Try the other ones + extension = supported_extensions[ext_index] + logger.debug(f'Attempting conversion for {extension} extension') + if extension != ctype: + t1 = datetime.now() + tdict = quickConvert.convert_to_zarr(nfile, extension, **kwargs) + t_len = (datetime.now()-t1).total_seconds() + ext_index += 1 + + if not tdict: + logger.error('Scanning failed for all drivers, file type is not Kerchunkable') + return None, None, None + else: + logger.info(f'Scan successful with {ctype} driver') + return tdict['refs'], ctype, t_len + +def get_internals(args, testfile, ctype, logger): + """Map to kerchunk data and perform calculations on test netcdf file.""" + refs, ctype, time = map_to_kerchunk(args, testfile, ctype, logger) + if not refs: + return None, None, None + logger.info(f'Starting summation process for {testfile}') + + # Perform summations, extract chunk attributes + sizes = [] + vars = {} + chunks = 0 + for chunkkey in refs.keys(): + if len(refs[chunkkey]) >= 2: + try: + sizes.append(int(refs[chunkkey][2])) + chunks += 1 + vars[chunkkey.split('/')[0]] = 1 + except ValueError: + pass + return np.sum(sizes), chunks, sorted(list(vars.keys())), ctype, time + +def eval_sizes(files): + """Get a list of file sizes on disk from a list of filepaths""" + return [os.stat(files[count]).st_size for count in range(len(files))] + +def get_seconds(time_allowed): + """Convert time in MM:SS to seconds""" + if not time_allowed: + return 10000000000 + mins, secs = time_allowed.split(':') + return int(secs) + 60*int(mins) + +def format_seconds(seconds): + """Convert time in seconds to MM:SS""" + mins = int(seconds/60) + 1 + if mins < 10: + mins = f'0{mins}' + return f'{mins}:00' + +def perform_safe_calculations(std_vars, cpf, volms, files, times, logger): + kchunk_const = 167 # Bytes per Kerchunk ref (standard/typical) + if std_vars: + num_vars = len(std_vars) + else: + num_vars = None + if not len(cpf) == 0: + avg_cpf = sum(cpf)/len(cpf) + else: + logger.warning('CPF set as none, len cpf is zero') + avg_cpf = None + if not len(volms) == 0: + avg_vol = sum(volms)/len(volms) + else: + logger.warning('Volume set as none, len volumes is zero') + avg_vol = None + if avg_cpf: + avg_chunk = avg_vol/avg_cpf + else: + avg_chunk = None + logger.warning('Average chunks is none since CPF is none') + if num_vars and avg_cpf: + spatial_res = 180*math.sqrt(2*num_vars/avg_cpf) + else: + spatial_res = None + + if files and avg_vol: + data_represented = avg_vol*len(files) + num_files = len(files) + else: + data_represented = None + num_files = None + + if files and avg_cpf: + total_chunks = avg_cpf * len(files) + else: + total_chunks = None + + if avg_chunk: + addition = kchunk_const*100/avg_chunk + else: + addition = None + + if files and len(times) > 0: + estm_time = int(np.mean(times)*len(files)) + else: + estm_time = 0 + + return avg_cpf, num_vars, avg_chunk, spatial_res, data_represented, num_files, total_chunks, addition, estm_time + +def scan_dataset(args, files, proj_dir, proj_code, logger): + """Main process handler for scanning phase""" + logger.debug(f'Assessment for {proj_code}') + + # Set up conditions, skip for small file count < 5 + escape, is_varwarn, is_skipwarn = False, False, False + cpf, volms, times = [],[],[] + trial_files = 5 + if len(files) < 5: + details = {'skipped':True} + if args.dryrun: + logger.info(f'DRYRUN: Skip writing to {proj_dir}/detail-cfg.json') + else: + with open(f'{proj_dir}/detail-cfg.json','w') as f: + f.write(json.dumps(details)) + logger.info(f'Skipped scanning - {proj_code}/detail-cfg.json blank file created') + return None + else: + logger.info(f'Identified {len(files)} files for scanning') + + # Perform scans for sample (max 5) files + count = 0 + std_vars = None + ctypes = [] + filecap = min(100,len(files)) + while not escape and len(cpf) < trial_files: + logger.info(f'Attempting scan for file {count+1} (min 5, max 100)') + # Add random file selector here + + scanfile = files[count] + if '.' in scanfile: + extension = f'.{scanfile.split(".")[-1]}' + else: + extension = '.nc' + + try: + # Measure time and ensure job will not overrun if it can be prevented. + volume, chunks_per_file, vars, ctype, time = get_internals(args, scanfile, extension, logger) + if count == 0 and time > get_seconds(args.time_allowed)/trial_files: + raise ExpectTimeoutError(required=format_seconds(time*5), current=args.time_allowed) + + cpf.append(chunks_per_file) + volms.append(volume) + ctypes.append(ctype) + times.append(time) + + if not std_vars: + std_vars = vars + if vars != std_vars: + logger.warning('Variables differ between files') + is_varwarn = True + logger.info(f'Data saved for file {count+1}') + except ExpectTimeoutError as err: + raise err + except Exception as e: + if args.bypass: + logger.warning(f'Skipped file {count} - {e}') + is_skipwarn = True + else: + raise e + count += 1 + if count >= filecap: + escape = True + if escape: + raise FilecapExceededError(filecap) + + logger.info('Scan complete, compiling outputs') + (avg_cpf, num_vars, avg_chunk, + spatial_res, data_represented, num_files, + total_chunks, addition, estm_time) = perform_safe_calculations(std_vars, cpf, volms, files, times, logger) + + details = { + 'data_represented' : format_float(data_represented, logger), + 'num_files' : num_files, + 'chunks_per_file' : safe_format(avg_cpf,'{value:.1f}'), + 'total_chunks' : safe_format(total_chunks,'{value:.2f}'), + 'estm_chunksize' : format_float(avg_chunk,logger), + 'estm_spatial_res' : safe_format(spatial_res,'{value:.2f}') + ' deg', + 'estm_time' : format_seconds(estm_time), + 'variable_count' : num_vars, + 'addition' : safe_format(addition,'{value:.3f}') + ' %', + 'var_err' : is_varwarn, + 'file_err' : is_skipwarn, + 'type' : 'JSON' + } + + if escape: + details['scan_status'] = 'FAILED' + + if len(set(ctypes)) == 1: + details['driver'] = ctypes[0] + + c2m = 1.67e-4 # Memory for each chunk in kerchunk in MB + + if avg_cpf and files: + if avg_cpf * len(files) * c2m > 500e6: + details['type'] = 'parq' + else: + details['type'] = 'N/A' + + if args.dryrun: + logger.info(f'DRYRUN: Skip writing to {proj_dir}/detail-cfg.json') + else: + with open(f'{proj_dir}/detail-cfg.json','w') as f: + # Replace with dumping dictionary + f.write(json.dumps(details)) + logger.info(f'Written output file {proj_code}/detail-cfg.json') + +def scan_config(args): + """Configure scanning and access main section""" + + logger = init_logger(args.verbose, args.mode, 'scan') + logger.debug(f'Setting up scanning process') + + cfg_file = f'{args.proj_dir}/base-cfg.json' + if os.path.isfile(cfg_file): + with open(cfg_file) as f: + cfg = json.load(f) + else: + logger.error(f'cfg file missing or not provided - {cfg_file}') + return None + + proj_code = cfg['proj_code'] + workdir = cfg['workdir'] + proj_dir = cfg['proj_dir'] + logger.debug(f'Extracted attributes: {proj_code}, {workdir}, {proj_dir}') + + filelist = f'{proj_dir}/allfiles.txt' + + if not os.path.isfile(filelist): + logger.error(f'No filelist detected - {filelist}') + return None + + with open(filelist) as f: + files = [r.strip() for r in f.readlines()] + + if not os.path.isfile(f'{proj_dir}/detail-cfg.json') or args.forceful: + scan_dataset(args, files, proj_dir, proj_code, logger) + else: + logger.warning(f'Skipped scanning {proj_code} - detailed config already exists') + +if __name__ == '__main__': + print('Kerchunk Pipeline Config Scanner - run using master scripts') \ No newline at end of file diff --git a/builder/pipeline/validate.py b/builder/pipeline/validate.py new file mode 100644 index 0000000..61dd190 --- /dev/null +++ b/builder/pipeline/validate.py @@ -0,0 +1,513 @@ +__author__ = "Daniel Westwood" +__contact__ = "daniel.westwood@stfc.ac.uk" +__copyright__ = "Copyright 2023 United Kingdom Research and Innovation" + +import os +import xarray as xr +import json +from datetime import datetime +import sys +import fsspec +import random +import numpy as np +import glob +import logging +import math + +## 0. Custom Error Classes + +class ChunkDataError(Exception): + def __init__(self, verbose=0): + self.message = f'Decoding resulted in overflow - received chunk data contains junk (attempted 3 times)' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class NoValidTimeSlicesError(Exception): + def __init__(self, message='Kerchunk', verbose=0): + self.message = f'No valid timeslices found for {message}' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class VariableMismatchError(Exception): + def __init__(self, missing={}, verbose=0): + self.message = f'Missing variables {missing} in Kerchunk file' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class ShapeMismatchError(Exception): + def __init__(self, var={}, first={}, second={}, verbose=0): + self.message = f'Kerchunk/NetCDF mismatch for variable {var} with shapes - K {first} vs N {second}' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class TrueShapeValidationError(Exception): + def __init__(self, message='Kerchunk', verbose=0): + self.message = f'Kerchunk/NetCDF mismatch with shapes using full dataset - check logs' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class NoOverwriteError(Exception): + def __init__(self, verbose=0): + self.message = 'Output file already exists and forceful overwrite not set.' + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class MissingKerchunkError(Exception): + def __init__(self, message="No suitable kerchunk file found for validation.", verbose=0): + self.message = message + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class ValidationError(Exception): + def __init__(self, message="Fatal comparison failure for Kerchunk/NetCDF", verbose=0): + self.message = message + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +class SoftfailBypassError(Exception): + def __init__(self, message="Kerchunk validation failed softly with no bypass - rerun with bypass flag", verbose=0): + self.message = message + super().__init__(self.message) + if verbose < 1: + self.__class__.__module__ = 'builtins' + +levels = [ + logging.WARN, + logging.INFO, + logging.DEBUG +] + +## 1. Misc Small Functions + +def init_logger(verbose, mode, name): + """Logger object init and configure with formatting""" + verbose = min(verbose, len(levels)-1) + + logger = logging.getLogger(name) + logger.setLevel(levels[verbose]) + + ch = logging.StreamHandler() + ch.setLevel(levels[verbose]) + + formatter = logging.Formatter('%(levelname)s [%(name)s]: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + return logger + +## 2. Array Selection Tools + +def find_dimensions(dimlen, divisions): + """Determine index of slice end position given length of dimension and fraction to assess""" + # Round down then add 1 + slicemax = int(dimlen/divisions)+1 + return slicemax + +def get_vslice(shape, dtypes, lengths, divisions, logger): + """Assemble dataset slice given the shape of the array and dimensions involved""" + + vslice = [] + for x, dim in enumerate(shape): + if np.issubdtype(dtypes[x], np.datetime64): + vslice.append(slice(0,find_dimensions(lengths[x],divisions))) + elif dim == 1: + vslice.append(slice(0,1)) + else: + vslice.append(slice(0,find_dimensions(dim,divisions))) + logger.debug(f'Slice {vslice}') + return vslice + +## 3. File Selection Tools + +def get_netcdf_list(proj_dir, logger, thorough=False): + """Open document containing paths to all NetCDF files, make selections""" + with open(f'{proj_dir}/allfiles.txt') as f: + xfiles = [r.strip() for r in f.readlines()] + logger.debug(f'Found {len(xfiles)} files in {proj_dir}/allfiles.txt') + + # Open full set or a subset of the files for testing + if thorough: + numfiles = len(xfiles)+1 + logger.info(f'Selecting all {numfiles-1} files') + else: + numfiles = int(len(xfiles)/1000) + if numfiles < 3: + numfiles = 3 + logger.info(f'Selecting a subset of {numfiles} files') + + if numfiles > len(xfiles): + numfiles = len(xfiles) + indexes = [i for i in range(len(xfiles))] + else: + indexes = [] + for f in range(numfiles): + testindex = random.randint(0,numfiles-1) + while testindex in indexes: + testindex = random.randint(0,numfiles-1) + indexes.append(testindex) + + logger.debug(f'Filtered fileset to a list of {len(indexes)} files') + + return indexes, xfiles + +def pick_index(nfiles, indexes): + """Pick index of new netcdf file randomly, try 100 times""" + index = random.randint(0,nfiles) + count = 0 + while index in indexes and count < 100: + index = random.randint(0,nfiles) + count += 1 + indexes.append(index) + return indexes + +def locate_kerchunk(args, logger, get_str=False): + """Gets the name of the latest kerchunk file for this project code""" + files = os.listdir(args.proj_dir) # Get filename only + kfiles = [] + + for f in files: + if 'complete' in f and not args.forceful: + logger.error('File already exists and no override is set') + raise NoOverwriteError + if 'kerchunk' in f and 'complete' not in f: + kfiles.append(f) + if kfiles == []: + logger.error(f'No Kerchunk file located at {args.proj_dir} - exiting') + raise MissingKerchunkError + + # Which kerchunk file from set of options + kf = sorted(kfiles)[0] + logger.info(f'Selected {kf} from {len(kfiles)} available') + kfile = os.path.join(args.proj_dir, kf) + if get_str: + return kfile + else: + return open_kerchunk(kfile, logger) + +def open_kerchunk(kfile, logger, isparq=False): + """Open kerchunk file from JSON/parquet formats""" + if isparq: + logger.debug('Opening Kerchunk Parquet store') + from fsspec.implementations.reference import ReferenceFileSystem + fs = ReferenceFileSystem( + kfile, + remote_protocol='file', + target_protocol="file", + lazy=True) + return xr.open_dataset( + fs.get_mapper(), + engine="zarr", + backend_kwargs={"consolidated": False, "decode_times": False} + ) + else: + logger.debug('Opening Kerchunk JSON file') + mapper = fsspec.get_mapper('reference://',fo=kfile, target_options={"compression":None}) + # Need a safe repeat here + ds = None + attempts = 0 + while attempts < 3 and not ds: + attempts += 1 + try: + ds = xr.open_zarr(mapper, consolidated=False, decode_times=True) + except OverflowError: + ds = None + if not ds: + raise ChunkDataError + return ds + +def open_netcdfs(args, logger, thorough=False): + """Returns a single xarray object with one timestep: + - Select a single file and a single timestep from that file + - Verify that a single timestep can be selected + - If yes, return this xarray object + - If no, select all files and select a single timestep from that. + - In all cases, returns a list of xarray objects + """ + logger.debug('Performing temporal selections') + indexes, xfiles = get_netcdf_list(args.proj_dir, logger, thorough=thorough) + xobjs = [] + many = len(indexes) + if not thorough: + for one, i in enumerate(indexes): + + # Memory Size Check + logger.debug(f'Checking memory size of expected netcdf file for index {i} ({one+1}/{many})') + if os.path.getsize(xfiles[i]) > 4e9 and not args.forceful: # 4GB file + logger.error('Memory Exception - ensure you have 12GB or more dedicated to this task') + raise MemoryError('Projected memory requirement too high - run with forceful flag to bypass', verbose=args.verbose) + xobjs.append(xr.open_dataset(xfiles[i])) + else: + xobjs = [xr.open_mfdataset(xfiles)] + + if len(xobjs) == 0: + logger.error('No valid timestep objects identified') + raise NoValidTimeSlicesError(message='Kerchunk', verbose=args.verbose) + return xobjs, indexes, len(xfiles) + +## 4. Validation Testing + +def match_timestamp(kobject, xobject, logger): + """Match timestamp of xarray object to kerchunk object + - Returns temporally matching kerchunk and xarray objects""" + + if hasattr(xobject,'time'): + # Select timestamp 0 from multi-timestamped NetCDF - after shape testing + if xobject.time.size > 1: + timestamp = xobject.time[0] + else: + timestamp = xobject.time + + logger.debug(f'Kerchunk object total time stamps: {kobject.time.size}') + try: + ksel = kobject.sel(time=timestamp) + xsel = xobject.sel(time=timestamp) + assert ksel.time.size == 1 and xsel.time.size == 1 + logger.debug('Kerchunk timestamp selection was successful') + return ksel, xsel + except Exception as err: + raise err + else: + logger.debug('Skipped timestamp selection as xobject has no time') + return kobject, xobject + +def compare_data(vname, netbox, kerchunk_box, logger, bypass=False): + """Compare a NetCDF-derived ND array to a Kerchunk-derived one + - Takes a netbox array of n-dimensions and an equally sized kerchunk_box array + - Tests for elementwise equality within selection. + - If possible, tests max/mean/min calculations for the selection to ensure cached values are the same. + + - Expect TypeErrors from summations which are bypassed. + - Other errors will exit the run. + """ + logger.debug('Starting xk comparison') + + try: # Tolerance 0.1% of mean value for xarray set + tolerance = np.abs(np.nanmean(kerchunk_box))/1000 + except TypeError: # Type cannot be summed so skip all summations + tolerance = None + + testpass = True + if not np.array_equal(netbox, kerchunk_box): + logger.warn(f'Failed equality check for {vname}') + print(netbox, kerchunk_box) + testpass = False + try: + if np.abs(np.nanmax(kerchunk_box) - np.nanmax(netbox)) > tolerance: + logger.warn(f'Failed maximum comparison for {vname}') + logger.debug('K ' + str(np.nanmax(kerchunk_box)) + ' N ' + str(np.nanmax(netbox))) + testpass = False + except TypeError as err: + if bypass: + logger.warn(f'Max comparison skipped for non-summable values in {vname}') + else: + raise err + try: + if np.abs(np.nanmin(kerchunk_box) - np.nanmin(netbox)) > tolerance: + logger.warn(f'Failed minimum comparison for {vname}') + logger.debug('K ' + str(np.nanmin(kerchunk_box)) + ' N ' + str(np.nanmin(netbox))) + testpass = False + except TypeError as err: + if bypass: + logger.warn(f'Min comparison skipped for non-summable values in {vname}') + else: + raise err + try: + if np.abs(np.nanmean(kerchunk_box) - np.nanmean(netbox)) > tolerance: + logger.warn(f'Failed mean comparison for {vname}') + logger.debug('K ' + str(np.nanmean(kerchunk_box)) + ' N ' + str(np.nanmean(netbox))) + testpass = False + except TypeError as err: + if bypass: + logger.warn(f'Mean comparison skipped for non-summable values in {vname}') + else: + raise err + +def validate_shapes(xobj, kobj, step, nfiles, xv, logger): + """Ensure shapes are equivalent across Kerchunk/NetCDF per variable + - Accounts for the number of files opened vs how many files in total.""" + xshape = list(xobj[xv].shape) + kshape = list(kobj[xv].shape) + + if 'time' in xobj[xv].dims: + try: + xshape[0] *= nfiles + except TypeError: + logger.warning(f'{xv} - {nfiles}*{xshape[0]} failed to assign') + except: + pass + + logger.debug(f'{xv} : Comparing shapes {xshape} and {kshape} - {step}') + + if xshape != kshape: + logger.warning(f'Kerchunk/NetCDF mismatch for variable {xv} with shapes - K {kshape} vs N {xshape}') + raise ShapeMismatchError(var=xv, first=kshape, second=xshape) + +def validate_selection(args, xvariable, kvariable, vname, divs, currentdiv, logger): + """Validate this data selection in xvariable/kvariable objects + - Recursive function tests a growing selection of data until one is found with real data + - Repeats with exponentially increasing box size (divisions of all data dimensions) + - Will halt at 1 division which equates to testing all data + """ + + # Determine number based on + repeat = int(math.log2(divs) - math.log2(currentdiv)) + + logger.debug(f'Attempt {repeat} - {currentdiv} divs for {vname}') + + vslice = [] + if divs > 1: + shape = xvariable.shape + logger.debug(f'Detected shape {shape} for {vname}') + dtypes = [xvariable[xvariable.dims[x]].dtype for x in range(len(xvariable.shape))] + lengths = [len(xvariable[xvariable.dims[x]]) for x in range(len(xvariable.shape))] + vslice = get_vslice(shape, dtypes, lengths, divs, logger) + + xbox = xvariable[tuple(vslice)] + kbox = kvariable[tuple(vslice)] + else: + xbox = xvariable + kbox = kvariable + + # Zero shape means no point running divisions - just perform full check + if shape == {} and vslice == []: + logger.debug(f'Skipping to full selection (1 division) for {vname}') + currentdiv = 1 + + try: + kb = np.array(kbox) + isnan = np.all(kb!=kb) + except Exception as err: + if args.bypass: + logger.warning(f'{err} - check versions') + isnan = True + else: + raise err + + if kbox.size >= 1 and not isnan: + # Evaluate kerchunk vs xarray and stop here + logger.debug(f'Found non-NaN values with box-size: {int(kbox.size)}') + compare_data(vname, xbox, kbox, logger, bypass=args.bypass) + else: + logger.debug(f'Attempt {repeat} - slice is Null') + if currentdiv >= 2: + # Recursive search for increasing size (decreasing divisions) + validate_selection(args, xvariable, kvariable, vname, divs, int(currentdiv/2), logger) + else: + print(np.array(xvariable)) + logger.warn(f'Failed to find non-NaN slice (tried: {int(math.log2(divs))}, var: {vname})') + if not args.bypass: + raise SoftfailBypassError + +def validate_data(args, xobj, kobj, xv, step, logger): + """Run growing selection test for specified variable from xarray and kerchunk datasets""" + logger.info(f'{xv} : Starting growbox data tests for {step}') + + kvariable, xvariable = match_timestamp(xobj[xv], kobj[xv], logger) + + # Attempt 128 divisions within selection - 128, 64, 32, 16, 8, 4, 2, 1 + return validate_selection(args, xvariable, kvariable, xv, 128, 128, logger) + +def validate_timestep(args, xobj, kobj, step, nfiles, logger): + """Run all tests for a single file which may or may not equate to 1 timestep""" + + # Run Variable and Shape validation + xvars = set(xobj.variables) + kvars = set(kobj.variables) + if xvars&kvars != xvars: # Overlap of sets - all xvars should be in kvars + missing = (xvars^kvars)&xvars + raise VariableMismatchError(missing=missing) + else: + logger.info(f'Passed Variable tests') + print() + for xv in xvars: + validate_shapes(xobj, kobj, step, nfiles, xv, logger) + logger.info(f'{xv} : Passed Shape test') + logger.info(f'Passed all Shape tests') + print() + for xv in xvars: + validate_data(args, xobj, kobj, xv, step, logger) + logger.info(f'{xv} : Passed Data test') + +def run_successful(args, logger): + """Move kerchunk-1a.json file to complete directory with proper name""" + # in_progress///kerchunk_1a.json + # complete// 0: + print('WARNING: Missing additional fields - check manually') + print(' >> ' + ','.join(missing)) + return 0, 0, 0, None + else: + return xattrs, kattrs, corrections, True + +def correct_attrs(proj_code, revision, old_file, new_file, fl, cfg=None, skip=False): + # Default approach is to compare with xr.open_mfdataset + # Correct any different metadata and save kerchunk attributes + direct = False + # Get Xarray Global Attributes + if len(fl) == 1: + skip = True + if not skip: + print('Opening Xarray Datasets') + xattr0 = xr.open_dataset(fl[0]).attrs + xattr1 = xr.open_dataset(fl[1]).attrs + skip=True + + # Get Kerchunk Attributes + with open(old_file) as f: + refs = json.load(f) + kattrs = json.loads(refs['refs']['.zattrs']) + + kattrs['time_coverage_end'] = xattr1['time_coverage_end'] + + if not skip: + # Set all attributes if they are incorrect + if direct: + print('Using direct comparison') + xattrs, kattrs, corrections = direct_comparison(xattrs, kattrs) + success = True + else: + print('Using specific comparison') + xattrs, kattrs, corrections, success = specific_comparison(xattrs, kattrs, cfg) + + if not success: + return None + + print('Corrected: ',end='') + if not corrections: + print(None) + else: + print(', '.join(corrections)) + + # Set kerchunk specific attributes + now = datetime.now() + stamp = now.strftime("%d%m%yT%H%M%S") + ymd = now.strftime("%d/%m/%y") + kattrs['history'] = kattrs['history'] + f"\nKerchunk file last updated by CEDA on {ymd} in the context of the CCI Knowledge Exchange Project" + kattrs['kerchunk_revision'] = revision + 'b' + kattrs['kerchunk_creation_date'] = str(stamp) + kattrs['tracking_id'] = str(uuid.uuid4()) + print('Added Kerchunk Attributes') + + # Export new attributes + refs['refs']['.zattrs'] = json.dumps(kattrs) + if not os.path.isfile(new_file) or OVERWRITE: + with open(new_file,'w') as f: + f.write(json.dumps(refs)) + print('Written to',new_file) + return None + +def find_firstlast(workdir, proj_code, getall=False): + filelist = f'{workdir}/{proj_code}/allfiles.txt' + if os.path.isfile(filelist): + with open(filelist) as f: + content = [r.replace('\n','') for r in f.readlines()] + if getall: + return content + if content[0] != content[-1]: + return [content[0], content[-1]] + else: + return [content[0]] + else: + print('File not found - ',filelist) + +#correct_attrs(proj_code, old, revision, textref, old_file, new_file) +config_file = sys.argv[1] + +OVERWRITE = ('-f' in sys.argv) + +if True:#os.path.isfile(config_file): + #with open(config_file) as f: + #cfg_attrs = json.load(f) + +## Revisions +# Initially generated 1.0a - uncorrected version +# Post metadata corrections 1.0b - corrected, untested version +# Post testing version 1.0 + + cfg_attrs = { + 'proj_code':'ESACCI-L4_FIRE-BA-MODIS-20010101-20200120-fv5.1', + 'revision':'kr1.2', + 'workdir': '/gws/nopw/j04/esacci_portal/kerchunk/pipeline/in_progress/' + } + + proj_code = cfg_attrs['proj_code'] + revision = cfg_attrs['revision'] + workdir = cfg_attrs['workdir'] + + # Assume no metaref + fl = find_firstlast(workdir, proj_code) + + old_file = f'{workdir}/{proj_code}/kerchunk-{revision}a.json' + new_file = f'{workdir}/{proj_code}/kerchunk-{revision}b.json' + + if not os.path.isfile(new_file) or OVERWRITE: + correct_attrs(proj_code, revision, old_file, new_file, fl, cfg=cfg_attrs, skip=False) + else: + print('skipped existing file') +else: + print(f'Config file not found - {config_file}') \ No newline at end of file diff --git a/builder/scripts/extra_tools/metadata_viewer.py b/builder/scripts/extra_tools/metadata_viewer.py new file mode 100644 index 0000000..96e80bd --- /dev/null +++ b/builder/scripts/extra_tools/metadata_viewer.py @@ -0,0 +1,79 @@ +# Script for viewing and editing current metadata +# Global attributes (.zattrs) +# .zgroup +# List all variables that contain a .zattrs/.zarray (inspectable) + +import sys +import json + +def format(text, size): + newtext = str(text) + for x in range(size - len(text)): + newtext += ' ' + return newtext + +def rundecode(cfgs): + """ + cfgs - list of command inputs depending on user input to this program + """ + flags = { + '-f':'filename' + } + kwargs = {} + for x in range(0,int(len(cfgs)),2): + flag = flags[cfgs[x]] + kwargs[flag] = cfgs[x+1] + + return kwargs + +class Editor: + + def __init__(self, filename=None): + self.filename=filename + if not self.filename: + self.filename = input('Kerchunk file: ') + + with open(self.filename) as f: + self.refs = json.load(f) + + self.glob_attrs = json.loads(self.refs['refs']['.zattrs']) + self.zgroup = json.loads(self.refs['refs']['.zgroup']) + + self.variables = {} + for key in self.refs['refs']: + if '/.z' in key: + var, type = key.split('/') + if var not in self.variables: + self.variables[var] = {} + self.variables[var][type] = self.refs['refs'][key] + + def display(self): + print() + print(self.filename) + buffer = len(self.filename) - 35 + print('_'.join(['' for x in range(len(self.filename)+1)])) + + print('Global Attributes:') + for k in self.zgroup.keys(): + print(f' {format(k,30)}: {self.zgroup[k]}') + for key in self.glob_attrs.keys(): + print(f' {format(key,30)}: ',end='') + lvalue = len(self.glob_attrs[key]) + cs = lvalue // 4 + if cs < 1: + print(self.glob_attrs[key]) + else: + raw = self.glob_attrs[key].replace('\n','. ') + value = [raw[i:i+buffer] for i in range(0, lvalue, buffer)] + print(value[0]) + for v in value[1:]: + print(format('',35) + v) + + + print('Variables:') + for key in self.variables.keys(): + print(f' {key}') + +if __name__ == '__main__': + cfgs = sys.argv[1:] + Editor(**rundecode(cfgs)).display() \ No newline at end of file diff --git a/builder/scripts/extra_tools/wide_corrections.py b/builder/scripts/extra_tools/wide_corrections.py new file mode 100644 index 0000000..b999bcd --- /dev/null +++ b/builder/scripts/extra_tools/wide_corrections.py @@ -0,0 +1,95 @@ + +import json +import glob +import os + +with open('corrections.json') as f: + refs = json.load(f) + +workdir = '/gws/nopw/j04/esacci_portal/kerchunk/DELIVERY_09_10_23' + +for proj in refs.keys(): + kfile = glob.glob(f'{workdir}/{proj}*.json')[0] + newfile = kfile.replace('DELIVERY_09_10_23','DELIVERY_10_10_23') + if not os.path.isfile(newfile): + + with open(kfile) as f: + kdata = json.load(f) + zattrs = json.loads(kdata['refs']['.zattrs']) + new_zattrs = {} + for attr in zattrs: + if attr in refs[proj].keys(): + if refs[proj][attr] == 'remove': + pass + else: + new_zattrs[attr] = refs[proj][attr] + else: + new_zattrs[attr] = zattrs[attr]] + + + kdata['refs']['.zattrs'] = json.dumps(new_zattrs) + with open(newfile,'w') as f: + f.write(json.dumps(kdata)) + print('Written corrections to ', newfile) + else: + print('File exists - ',newfile) + +print('End') + + + +""" +with open('corrections.csv') as f: + content = f.readlines() + +def get_portion(raw, proj_id): + raw = raw.replace('\n','').replace('\t','') + if raw.replace(' ','') == 'id': + return {'id':proj_id} + else: + if '=' in raw: + attr = raw.split('=')[0].replace(' ','') + value = raw.split('=')[1] + else: + attr = 'id' + value = proj_id + if '"' in value: + # Loop and cut everything not inside "" + x = 0 + inside = False + reached = False + fval = '' + while not reached: + if value[x] == '"' and inside: + inside = False + reached = True + elif value[x] == '"': + inside = True + else: + pass + if inside and value[x] != '"': + fval += value[x] + x += 1 + value = fval + else: + value = value.replace(' ','') + return {attr: value} + +projects = {} +for x, line in enumerate(content): + print(x, len(content)) + if line.startswith('ESACCI'): + proj_id = '' + x=0 + while line[x:x+3] != '-kr': + proj_id += line[x] + x += 1 + projects[proj_id] = {**get_portion(line[x:], proj_id)} + else: + projects[proj_id] = {**projects[proj_id], **get_portion(line, proj_id)} + +with open('corrections.json','w') as f: + f.write(json.dumps(projects)) + + +""" \ No newline at end of file diff --git a/builder/showcase/notebooks/Kerchunk JSON.ipynb b/builder/showcase/notebooks/Kerchunk JSON.ipynb new file mode 100644 index 0000000..8bb80e3 --- /dev/null +++ b/builder/showcase/notebooks/Kerchunk JSON.ipynb @@ -0,0 +1,3181 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3aaa059a-18c7-4dd0-b091-5d05f4da2465", + "metadata": {}, + "source": [ + "# Kerchunk JSON File Recipe\n", + "The standard format for Kerchunk files is JSON for storing references to archive data chunks. This requires fsspec and xarray - although these do not need to be the latest, there is no need to not use fsspec 2023.6.0+ and xarray 2023.8.0+ as these will also work with Parquet." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e2d976ae-58b8-4c6f-a34d-836ffebdd14c", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "id": "5ab538fc-c1d0-4517-a7e1-aae509b4f4b1", + "metadata": {}, + "source": [ + "Open a virtual filesystem object from fsspec, providing the kerchunk file as a 'reference' type file. Note that if the file is compressed using zstd as some kerchunk files are, the compression needs to be set to 'zstd'/'zst'" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "78a06225-11bb-4748-a44f-fe67aeb3881d", + "metadata": {}, + "outputs": [], + "source": [ + "kfile = 'https://dap.ceda.ac.uk/neodc/esacci/land_surface_temperature/metadata/kerchunk/AQUA_MODIS/L3C/0.01/v3.00/monthly/ESACCI-LST-L3C-LST-MODISA-0.01deg_1MONTHLY_DAY-200207-201812-fv3.00-kr1.1.json'\n", + "mapper = fsspec.get_mapper('reference://',fo=kfile, backend_kwargs={'compression':None})" + ] + }, + { + "cell_type": "markdown", + "id": "ea7afb26-7e2b-40db-a8a0-1558c34559d9", + "metadata": {}, + "source": [ + "Then we can open a virtual xarray dataset object to plot or perform some processing." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "45aac096-a60f-4a18-9ae2-77d29ceb2a03", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_zarr(mapper, consolidated=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3fea9e67-f1c3-40c0-8c49-318ac90cdc3d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:          (channel: 2, time: 198, lat: 18000, lon: 36000,\n",
+       "                      length_scale: 1)\n",
+       "Coordinates:\n",
+       "  * channel          (channel) float32 11.0 12.0\n",
+       "  * lat              (lat) float32 -90.0 -89.99 -89.98 ... 89.97 89.98 89.99\n",
+       "  * lon              (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n",
+       "  * time             (time) datetime64[ns] 2002-07-01 2002-08-01 ... 2018-12-01\n",
+       "Dimensions without coordinates: length_scale\n",
+       "Data variables: (12/14)\n",
+       "    dtime            (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    lcc              (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    lst              (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    lst_unc_loc_atm  (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    lst_unc_loc_sfc  (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    lst_unc_ran      (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    ...               ...\n",
+       "    n                (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    sataz            (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    satze            (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    solaz            (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    solze            (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "    variance         (time, lat, lon) float32 dask.array<chunksize=(1, 1000, 1000), meta=np.ndarray>\n",
+       "Attributes: (12/44)\n",
+       "    Conventions:                CF-1.8\n",
+       "    cdm_data_type:              grid\n",
+       "    comment:                    These data were produced as part of the ESA L...\n",
+       "    creator_email:              djg20@le.ac.uk\n",
+       "    creator_name:               University of Leicester Surface Temperature G...\n",
+       "    creator_url:                https://climate.esa.int/en/projects/land-surf...\n",
+       "    ...                         ...\n",
+       "    time_coverage_resolution:   P1M\n",
+       "    time_coverage_start:        20020701T000000\n",
+       "    title:                      ESA LST CCI land surface temperature data at ...\n",
+       "    kerchunk_revision:          kr1.1\n",
+       "    kerchunk_creation_date:     031023T093248\n",
+       "    tracking_id:                8efceb61-53cb-4361-a3b4-e809046b9a19
" + ], + "text/plain": [ + "\n", + "Dimensions: (channel: 2, time: 198, lat: 18000, lon: 36000,\n", + " length_scale: 1)\n", + "Coordinates:\n", + " * channel (channel) float32 11.0 12.0\n", + " * lat (lat) float32 -90.0 -89.99 -89.98 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2002-07-01 2002-08-01 ... 2018-12-01\n", + "Dimensions without coordinates: length_scale\n", + "Data variables: (12/14)\n", + " dtime (time, lat, lon) timedelta64[ns] dask.array\n", + " lcc (time, lat, lon) float32 dask.array\n", + " lst (time, lat, lon) float32 dask.array\n", + " lst_unc_loc_atm (time, lat, lon) float32 dask.array\n", + " lst_unc_loc_sfc (time, lat, lon) float32 dask.array\n", + " lst_unc_ran (time, lat, lon) float32 dask.array\n", + " ... ...\n", + " n (time, lat, lon) float32 dask.array\n", + " sataz (time, lat, lon) float32 dask.array\n", + " satze (time, lat, lon) float32 dask.array\n", + " solaz (time, lat, lon) float32 dask.array\n", + " solze (time, lat, lon) float32 dask.array\n", + " variance (time, lat, lon) float32 dask.array\n", + "Attributes: (12/44)\n", + " Conventions: CF-1.8\n", + " cdm_data_type: grid\n", + " comment: These data were produced as part of the ESA L...\n", + " creator_email: djg20@le.ac.uk\n", + " creator_name: University of Leicester Surface Temperature G...\n", + " creator_url: https://climate.esa.int/en/projects/land-surf...\n", + " ... ...\n", + " time_coverage_resolution: P1M\n", + " time_coverage_start: 20020701T000000\n", + " title: ESA LST CCI land surface temperature data at ...\n", + " kerchunk_revision: kr1.1\n", + " kerchunk_creation_date: 031023T093248\n", + " tracking_id: 8efceb61-53cb-4361-a3b4-e809046b9a19" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "935074c2-d3b1-45d5-b9f6-c46c8aa23b68", + "metadata": {}, + "source": [ + "Any plotting can then be done with this object." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "42d21b4c-ce9c-4049-b9f4-a60b217d4a46", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHBCAYAAABqqb/VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9eZxkZ13v/36Wc05VV28zk5ksJGSyJyAB4YqG1R+yCFyURcBcBAQUwSAS1gRICIFsGJYLIlwvSFhEdtQggmxGWeLFCBoEAiQzSSDrLL1W1TnnWX5/PM851Z19untmMjPPm1cx3dVVp05Vp6u//f1+vp+P8N57EolEIpFIJA5Q5N4+gUQikUgkEom9SSqGEolEIpFIHNCkYiiRSCQSicQBTSqGEolEIpFIHNCkYiiRSCQSicQBTSqGEolEIpFIHNCkYiiRSCQSicQBTSqGEolEIpFIHNDovX0C93acc9xwww1MTEwghNjbp5NIJBKJezHee+bn5znssMOQcvf1G4bDIVVVrfo4eZ7T6XTW4Iz2bVIxdDfccMMNHHHEEXv7NBKJRCKxD3H99ddz+OGH75ZjD4dDjjpynJtusas+1iGHHMKWLVsO+IIoFUN3w8TEBBD+w56cnNzLZ5NI7Jv80t+8E5Ub8AKER2qHqxVSOZyVtKFAHrwXCOlxleIHzzl9r553Yv/igZ+5GO9BSI+3AlcrALyLXX8Pwgm88uAEalGB9GAF0oCw4WtegCwFSPDa4zRIA04DC0OuPf8t7e+O3UFVVdx0i2XLFUcyObHy7tPcvOOoh1xLVVWpGNrbJ3BvpxmNTU5OpmIokVghIutCHv6KlcojlYNcIISHWiGlRwjwDmim0VKnn7nEmnH0/34H8pACbwVC+VAAlaEYopahAAJwAmkEIBC90f1FHf/DVKCGAgl4BS73SAXCggJ8EW63J2QVkxNyVcVQYkR6FROJxG5HdQ0qswjhcVbgPXgr0Nqx5Tln4p1Y1h0KHaK9ecaJ/Q05FOBF6EQ6gbexWGlqFg9CEDpB8eLz8B+hrAXCCPCgBiLcR4ZiKHwdfPxt6rI99x+u9W7Vl0QgdYYSicRu57jDbmF22KV2ktooZm8ZR+SOHz/9bAC6vZKyzNpfUt5Irn3ha/fyWSf2J9x9B+jMIpVDSI81ElOp0JGUPozAhEcYgZcgTOgGhbEZ4DyqDJWTLTxeh26Ql+EiYhG/R58THreKB13Nffc3UmcokUjsdm6an0Ary0ReUmiDyBwsjP4W++FTz8FWKhRDTrL191+3F882sT+yYXohdHaUQ0mHd0GbhvRBywaISoIXiNg1ElbgpQ+XDGwe9EHIUAjhBCgfLi7ojaTZc8/JrcH/EoHUGUokErudXFkyaamdol/l4AQ+d2z+8EV4I9A9g5ACbyVbn5cKocTaM7MwFj/yrUgfCThCQeTCGAxHEP9IcB0HNhQ5ofUTiiNZjbpBzfisPVZinyR1hhKJxG7nu088n442oSAyCpRHj9cI5ZCFpZUu2OTlldg9KOXQ2jaStNEGmfLIIoj7feZBRLG0A1EJZC1R/dAx8tnoeMJFfdCSSZNXvtUR7Qms96u+JAKpM5RIJPYIgzrDeIkUPgipa4krFaprEBK8ha0vSDqhxO4h0xbnBXWp8D4KqB0gBd6GFXkxjEWPiCv2ucdbj5dBQO21R4jwdUTUDGVBX+R1WMH3e7CeT5qhtSN1hhKJxB7hxtlJKqNxTiC1x9eKa1/02rDm7MGb9HaU2H2UtWY4DK0dpR0IUB2LzCwgwphMe9Ae4UOXR1RLKhsZRmIuD90fHzfKALwGrAhjs1Rf7JOkd59EIrFHuOrpZ2OcpJzp4EwUngKujm9D6bdIYjdSLWZIGf4bq/oZeHA26n1s1AQ1IzIIhZEgeA6J0P2hkQ7JIJr2OlQ/XnqEi92hPYjDY1dxSZ2hEWlMlkgk9hj/8aS33u46oYLhYiKxuzjqPW+nuE+FgNCZVA5nFODxVsVtsCXjLw+YIJbGi3bdvjFmbJ2oJcFRvZahO+TSmGxfJXWGEonEXuWaU1+Ps4Ktzztjb59KYj9FHzKgLjVShvGY1I6sW49W623s/sTNMi9jl8iKuEk2OpZwItxn6eeeWDjt+eeWWBtSMZRIJPY6W55z5t4+hcR+zE+f+UayIhgAKemCZgjwTkY3ad96CzUbZYRN+lGRo+JthMcpWn2QF2GrTNggsN6Tv1XTNtnakYqhRCKx2znu029l84cv2tunkTiAaVbpq0oHw0XhUbkNG2Xxa17G7pAa+Q4JD67r2rgNH4snL8DnDoQfrdkDTu25AsOtwSURSJqhRCKxZjz8K6/jW4+7fdFz8Lo5bqinOfrj5wMgJNgqaDYQsPW5aUSW2L0I6TFGIYTH1ApnJFnHYFEQjRMFS6I1lMcTzEHlomqNFRs9kYj5emLpiK35N7HPkYqhROIA46g/fzvHvvxyrrn4FMaP38l//s+3rMlxj/3UWzloSvKMb/8xV/z0SCglFI6tz38dvaxCZQ7nBK6WSG1RebifLfegS13igKW8eQwxUZN1DEI4XKmohzp0gaTFVyqMy6QPafaxAyQX4sex4+PFaDyGjxtkja5oD29ENlthq7l/IpCKoUTiAOOQ429lxz8cT1HOMXPTJJv/75+x8fCdfPeJ5+/ysR73z6dTWs3N3z4Mc6TmpuE0t+6cAOFRUxW21Gy+5CKQh6KiZgMRukKdXoXzAqXtGj/DROL2bH3pq9n80QuxViKaNXoRih/vBaIb/vt0QzXSB8URmYibZa2uaOnGWPy4LZD2INaHy2runwikYiiROMCYLIZUVtHRhjyzzOzoceu2yWW3+e1vvoy/e8Sf3+kxHviFsyirjLK/CZVb9P3n6QpPXYcuj1BBk6E7NQDOSKT0uBiOqXNLVWYgfOoMJfYY6zcssNAv8LG9I1QURzdiaSvCdY3XkBdgaR2p260yP1qzb7LN2niPPbpavzrdT5rojUgC6kTiAOKYT57HzsEYUnhyZciVRRcGIT2bP3wRJ3zuXE75pzO4fm6aoz52wZ0eR0mPtTIIUAm5T+Ugw3uBsxKVLe/2COVxNhREWWGwRuJdFLXOZ3f0EInEmtP4XHkPqskj80tX52PnR3noWOiZ0XiscPjCtYVTuFKE36LNiEwtKZIS+xSpM5RIHCCc99//k/tuPAEtHTsGYyjh6eUlZlyihGNYZ2zoLSKEp1AGt05w1McuQGofHKMFZIXhkHVzLAwm8R42Ti+wfb7HRKdkOMixVRCoehl+WwjRGCp6pHJ4L2IhJJDaYYaarae9aq++LokDi3qoyboG24impcdbgbdBHe2dDJ2fWobxWOYQSgQTxtzB0nDWxqfIiVEhtEc7QwK7igd0e/Jk7+WkzlAicYDwg/nDkFHg2dGGTlZTO8URkzP08orJ7pBf7JjGe4GSQezsvWB8fECnV5F3w8hL4lHS4Z3E2PAWErxbbHDg9QJbqTb6oCmImhGZMxJvQwfJ1+ktKLFn2fJ7Z4aOZCPwaTo98V8hiB2fUOgII8NNlUfUMgim76j540amjXsK51d/SQTSO1EicS/kgV84i2M+cT6bP3rhmh3zxsWgC9LSMZ6XDKqMQZ2xdWYdt8yPMz8smB7vo2RQElR1aBw7J5nuDVDSsX6iH8SnkW5etyn042PlSEwqR2MxCGMJGXUVurBkHYOLQa2JxJ7mp898I3lRx5Dg2CHK3GhVLOKVD50hT7sxJuKKfTseg2XbZol9k1QMJRL3Mo766wvoD4rwiV27NvbMsBuS420QLM8NOszM9pif79ItaoyVDOsMLR1SeJwX5N2aye6QW3ZMkmnL0OigN8oMQjoyGZZztXCs6/bJumF1udsr27GY9wIhwFqJqRTOhutwsPkjF3Hi585ds+eYSNxTfvS0N+GtQKq4Tt+OvkZ5eULSXu8z14ayNgGtLXE7jaartIewcUy2mksikIqhROJexFEfu4Cx8TJuXBk6k+WaHfvg8XkArJNo4dDK4R1I5ahqjbGKdb0+OrrGOSvQ2jKel3gHWoXR2a0L4wyrjMM2zOK8CIUT4d/DN+xk0/Q8xiicC/qgUACFdWadW7yTYWSmHUI5hgvFmj3HRGJX0IUNQn4v8E4ipEPI6Cqd2+guLVotkFc+FEhNIbQ39umXkIqhtSMVQ4nEvYCzrnwamy+5iKxjmB4bcMzGbWzesINOUa/J8V/w3RcAMDU25Jb5cRyC2ig6Y1X4C1h4JsaGdHWNibkDWWZR0nP9zmkQ0M1qrJP0BznVIOPWuXFqp7BOMtPv4rxAS9eO0ZwJQlSpPLaSoUMkPd7HVfss5kPV6Q05sXf4yTPOQmXhv1mZ2dGYN17XxG7gBDiBkGHkK/SSrlAMdfWNDGkPaoYSa0cqhhKJvczxn3kLn/jxQygmS448aAfrO6E7I0Xw5VkLrrjpCAYmo19lbJpYYK7sUA805TAPa/G1Zroz4JpbDuInPz+YHYMxymFGZRRKerpjFd4LjJWsn+yDhyI3/PzG9VT9jMEw2EnfMDvFrXPj7XmrzKFzgyosh6yfw1mBqxW+Ma9zIumGEnuVnz7zjRTdGiFC4e6bTs/Swih3QV/kosC6CkLqpXllQoXR2Z5sFDkvVn1JBNJqfSKxlzjp82+mvG6C6eNKFoc5Sjo6yrQdlsooFvurHyFt/tDb0L2cTmYYLyoyZSm0Yd36RXbu6OFzOPqg7RgnkcqRdx29vGI+67RGckVmmB8WSOGZ6gwYO7RCScdiv8CUClMq+nUe1uvLEGvQHS9ZP95nocwZOMFMv4utFSq3eE80tEtvxom9z4+e9iY2f/gi8vEqdH5EGBO3lU3jTugF3nuiW0RzVTRdjMaMe5DVjrrSmGxE6gwlEnuBB3/xjQzmO8hD++zc0cNZyRHrZtDS0dEGKTy3LoyT52bVj6XGapR2KOnIY7HlvGBmdgwEmEpjnAzFkPAce9A2CmWYHh+AACkd40VJVWs2TCwihaeXVVx763q6nYrueEmnVzGWVfj4S0Mqx3inZH5YMF6ErpK1EqkdzgqkiiOyVAwl7iVsff7rsNf20JkNvlrNtMuJsFaf2dD9WVrwyJGQWuggrk5jsn2TVAwlEnuBxWGOzCzeC9atXwyCaeFwXmBc+LEcVhmDNRAXX/3sNwCwfa6HluExSquZmBhEPY/impsPwntBnplWM7RY5phSsa47YG7YwQO9rAKCWZsQkGlLVWnKQYbzgsmpAfl4xYZ1CwzrjDqmhAvpqSsd1utrGQWrIPspiiNx7+HqV74SAKmXbIdJj9RNle/bjTIh48issSuK6fV7MvvUIld9SQTSmCyR2AtMdofMui4AubIU2agD1BgjamWpXL4mj6eko9et2sf76S82sGnDPKZbMfB5yA1DMF5ULNY5UniGg5zDNs2wfbGH8yK4RgvPz2emEcJz8Lo5ZvtdpPKYUmK9JJOWQ6bnmOl3Wdfro4TDeomSjqrKIQdZWLwTuFKz9U+S+3Ti3oWpVeuQ7jytD5HUHus9QoXCx0f3atFEePjlxdGewK9S9+OTZqgllYWJxB7mmE+ex+GTswjpmegN2dBd5L7TO5HCY5zEecE1O9cz3qnWrOU+3qlYLHNqq9rO0823Bu8gVynqxYyf37yOyWLIumKA84L7btoeYjm8oMgMSjm2bl/PwlyHXlFRKMOG3iLTvQG9yWEYrXUHKOEYy2uGdYb1kltmJ9ocMyFd8B+ygq0vSMLpxL2Pa059PVuecyab1s3jnVhmMqriBuTSrpD3tD+nbdDrHiKt1q8dqTOUSOxmNn/kQoTyqDgWyzLLtbPrOPqg7a2nT65sq9n5ya0bMUbRB7Y+94wVPeYb/uvp/HjhEDqqRgvHRDHFWFZxw84pDls3y6YN89w6M87CYsHY1ADrJKbSLNY5mbRsn++1fzUq5ehmNTtunQAPncmS2X4H25FMFEPm+h2OOmh7O+KTMfNsbtjhpplJ8LTbZd5J7I6crX/86jV5bROJ3cVNV22EjsNJTzZRRa8sYuEzSmsVcTQmpAfl8VUqMPZFUjGUSOxGTvr8m4GCrDCYWqG0I88MG3sLbSGkpWNoYvQFwZ3ZOcHVz34Dx3/mLZhacc2pr9/lx/7+9ffhEUddwz//4ASE9gjlyLs1ty6MU1UaV4dujXMSrRxlFbpSOwdj5JkJRoxG4YGh0eS9irFuxbpunxtnppgfFMz1Oyjlgt6J4OZbWUVpNbP9LkVmKCsdjBaNQOzI2fryNBpL3PvZEke4D/qHs5ib66K0CwWR8ngThypNcdRsRxJ8tPYU1ofx9Mrvv4Yns4+TxmSJxG6kv7MLAqr5gvHxId1O1YabQiiEmn+1dFy7Yx3OC+xQc/xn39IGm+4qX7/peITwfGvrUcjCIjOLyiymCnEa1kh0Ydk4vcBwISfTlsl1fXpZxcHj86wf66OVo17McFaGnDIBG8YWAeh1S7RyZNoCMF8VGC+pbFix37EwhneCXtwk8y4EZF6TCqHEPsb3n/wW7GKGraNDdTRjDFtkoRDyrgl2jZ2iPYRD4JCruKQuVkMqhhKJ3cih99nJpo1zyMIwGOYs9guqSgdXZ0amaVJ4rp1dh7EKa+Tor01Yvsq7CyjtgpGcdujcorXD1pI8M+SFwVnJjTetI+/VDMuMjeML5NKSS8st8xNk2iILi3MCKR3VYt6u/m/qLWCdoJvXLM516Nd5u6U2s9hlamzIhslFrAtdLje7NkLwRGJvkO1UjP97l5896424xSz4YzkBVkLjrG6jb5ZI7ZZ9kTQmSyR2IzsXu+TaMjE5YGGhS5Yb6lrhoram2QQxTtLNauYXOmH9XLnwBusEmw+/dZcf9zuPv5CTPv9mpib6dLI6bIN5wY1DjbGSsp8hM0feq8DDoetmmS87bL1lA5s3bSfTlv4wR+cWUykmOiULRWeUReYFzkkyZelNDlnX7WOcpIrjPiUdC2VBJi14wdaXJo1QYt/lZ6955egT3XgJCbDxOknINIvF0Z4imS6uHakzlEjsJh7w92+ik9co5XBOcp+NOzlyw47WSLFvMgCun5vGIZgshmyYWsQ5wcEHzZFrSzXI+OffuHhFjy+EpzSK2UEH7wU375xgcmqAsQoEuFpy5IYdeC/YeuNB3LptAjvUDE2GFJ5OUXOfdTN0uhVT+RClHf06R+KRwnPQ5AK5MtQmeAU1wun1431u2jHJYr9g+8w4pp/+5krsP2x9wWtHfkLKhcLIETpFzQhtD9FohlZzSQTSK5FI7CYOGl9golPSH+RsmpgnkxYtHJs37OCI9TvJpcV4ifcwM+yydft6KqsY61Z85/EXsjDfWfE2GUBVaQZlzsJCF+skG6cXQqcGyLs1rlL89LpD6I2VHLIxrPrjQ6r94jBnbq7Llp9v4tCpObR0TIwNAVpTxom8pKMNx228lRtmp7hhdortiz2AkGhvJW4h49oXphX6xP6Fr2SbWO9t8OAS2sFtHaoT+wypGEokdhPWS35x8zqsUa1AWgqPxJNLixTBdXpdd8Bc7N70hyNtzZbnnLmix/2Nb7yS3/jGK/nZs95IkZk2+mJu0GH7zDjA6M3bBk1PaTRHHbqN7tSQXl6GjbY6vOHfODvJ0GpyZcmkZcu2DQxNiPAYGs3QhtHb4myHYZlx884Jbp6doNOt2PqHr1n9C5lI3Mvorhu23SGhgsO6r1X4WduDmqEgoF7dZVd43/vex8knn8zk5CSTk5Occsop/OM//mP79eFwyGmnncaGDRsYHx/nGc94BjfffPOyY1x33XU8+clPZmxsjE2bNvGa17wGY1YfO7RaUjGUSOwmti/0kMozMTFgoSpas8P2jcgLjJfcPBdMCaXw1APNwnxn1Y99/fZ1HP3x8+OILrzhdfIabwX9+SJ6CAlkx5Bpy9xCBy0dh0zNMTPsIoRH5aFYKsuMhapgfafPzXMTOCvaWI9mG279eJ98rGbD5CJKO0yt6F8/sernkUjcW8k6JkZ2hC0ypMdVao9qhtwqozjcLpYAhx9+OBdeeCFXXHEF//7v/85jHvMYfvu3f5v//u//BuD000/n0ksv5dOf/jSXXXYZN9xwA09/+tPb+1trefKTn0xVVXz729/mwx/+MJdccglnn332mr4uKyEVQ4nEbuK+63aC8OTKUsXuEBA0N3FVbMu2Da2lvhCerGtwg9VpbObLDkVu0IWlNooNU2GrK1eW7ngZvYVCxIDOLIMyQ0rPwGR4L5AE4XbzF64daKqoC1o/3kcqz9U3buSGmal2i0xJh1KOnXGl3m7rsOVlaY0+sX8i44q9zMLYWSg3yjLbj7fJnvKUp/CkJz2J4447juOPP57zzjuP8fFxLr/8cmZnZ/ngBz/IO97xDh7zmMfwkIc8hA996EN8+9vf5vLLLwfgn/7pn/jhD3/Ixz72MR70oAfxxCc+kbe85S28973vpaqqvfrc9uli6JxzzkEIsexy4okntl+/6aabeO5zn8shhxxCr9fjwQ9+MJ/97Gf34hknDiS293so7dgwtshBvUVyaXFeMLQah+DGhUnyzDDRHXLI9Fzw7PEgouX/SsmUJc8M3gmMlQxrHWIxdk5QRQNEITzZWE3Vz1pflIUyeAV185pqMY7rBOAFvbzi+tlpOrrGGomrJdZJbp0db4s5ayXWSsq5gq2npUIosf9ijMJaic5jkr2HxnNoT/5W3ZsCamstn/jEJ1hcXOSUU07hiiuuoK5rHvvYx7a3OfHEE7nvfe/Ld77zHQC+853v8IAHPICDDz64vc0TnvAE5ubm2u7S3mKfX/O4//3vz1e/+tX2c61HT+l5z3seMzMz/P3f/z0HHXQQH//4x3nWs57Fv//7v/PLv/zLe+N0EwcQE8UQJUeFTbOSPqbDqvuw0ijp2dRbwCGYFaGjU/WzVT3u3KBDN6+RyqGkCyGsXmBLje7UwTxOCHwduj1KOnrjFbP9sDrfzWqysZp6qNu/dGeGXapac8PMFEo7lHaMdSrmF8JIb8fCGAD1zoJrX5x0Qon9m5/8zlkc/9m3IIVn3bpFZmbGwuh5D+aSAa154srvH853bm5u2fVFUVAUxR3e58orr+SUU05hOBwyPj7O5z//ee53v/vx/e9/nzzPmZ6eXnb7gw8+mJtuugkIDYqlhVDz9eZre5N9vhjSWnPIIYfc4de+/e1v8773vY+HPvShALzxjW/kne98J1dccUUqhhK7lWM/9VakWocQnm2z42htOXzdDM4LOspw/ew0R63fwXUz61oRY20UmyYWlgVDroTaKKR0aOVCHEatqWtFb2oQglm7FYNhTlUp8DA/26W3aZZuUdMf5nS0YaI3ZPv8JDK3oGButkvWCUaNEHKYOtrQ144bdk5hjcJtK9iaRmOJA4SfPOOsO7z+qA/d8fW7A+sFdhUapea+RxxxxLLr3/SmN3HOOefc4X1OOOEEvv/97zM7O8tnPvMZnv/853PZZZet+BzuLezzxdBPf/pTDjvsMDqdDqeccgoXXHAB973vfQF42MMexic/+Ume/OQnMz09zac+9SmGwyG//uu/fqfHK8uSsizbz29bMScS9wTvBUKE7bG6lthaUk5qbtwxxfEH38KGXoi12DQx3ybVAwxNRlmv7seyKnXUNDDS8xShQ2RteCylXBjH2eCee9OtU3R7JfiQZu+9QGiP1B6pgj4iBFWGzRklHTOLXfBQDzVC+qQRSiSI0Rz7GNdffz2Tk5Pt53fWFQLI85xjjz0WgIc85CF897vf5X//7//Ns5/9bKqqYmZmZll36Oabb24bFocccgj/7//9v2XHa7bN7qypsafYpzVDv/qrv8oll1zCl770Jd73vvexZcsWHvnIRzI/Pw/Apz71Keq6ZsOGDRRFwR/90R/x+c9/vv1G3hEXXHABU1NT7eW2FXMicU+4+tlvYF1vwIaJRTpjFUJ5frFtGltLrt52EN4LFuuc+bJDbYO4upMbNnQXuerpq9usuObU17O4rcfiDePBCXqhg3VBz2Pi1lqeGSamBhSTJVI7fKXoz3VDsVQpfKnwRmBryaHrZ9k4tcD0eB8bO0OZtpSDjGqQ4aOfUCKRgP965p5zW1/NJllzAdpV+eZyV8XQbXHOUZYlD3nIQ8iyjK997Wvt16666iquu+46TjnlFABOOeUUrrzySm655Zb2Nl/5yleYnJzkfve73xq9Kitjny6GnvjEJ/LMZz6Tk08+mSc84Ql88YtfZGZmhk996lMAnHXWWczMzPDVr36Vf//3f+eVr3wlz3rWs7jyyivv9Jhnnnkms7Oz7eX666/fU08nsZ9x+RMuoDIarRzTk32KokYoT10rbp6bYKoYsjDMuWl2EhNFzf/wqHevyWNf+wevIZtR9Ic501N9pPCUVeg4yagjUiqswJvFPDjp2hAQKwSI3IURWSOOdpIds+Mo7agGGYPoh+QriZjTbE06oURij+O8XPVlVzjzzDP5l3/5F7Zu3cqVV17JmWeeyT//8z/znOc8h6mpKV70ohfxyle+km984xtcccUVvOAFL+CUU07h137t1wB4/OMfz/3udz+e+9zn8p//+Z98+ctf5o1vfCOnnXbaLhVgu4N9fky2lOnpaY4//nh+9rOfcfXVV/Pnf/7n/OAHP+D+978/AA984AP513/9V9773vfy/ve//w6PcVfCsURiJfSKiunOAD3u6JuMG2cnsU5SOcXBk/Ptyn0Ta7EWbP7LP8Nv8uTSMzvfpShCLAgQPYY8QkCnU7M41MjMYaOGCEA48EKAg1tmJ6gWM7yRWC3RHUM91MG4sZRs+ZM0HkskDgRuueUWnve853HjjTcyNTXFySefzJe//GUe97jHAfDOd74TKSXPeMYzKMuSJzzhCfzFX/xFe3+lFF/4whd46UtfyimnnEKv1+P5z38+55577t56Si37VTG0sLDA1VdfzXOf+1z6/T4AUi6vfJVSOLe61eVE4p5y3Lpb+cXCFDfOT3LE5AzWSUwseq7dsY51vQHeW+argsX+yovwo//3O3Drqza+Y/LQefqDnMXZTtgIK2qk9NRG4eugGbJWUpUa1TE4I1G9Gu8ErlQI7ULRJMCUCpU7rBMI5ZHSY6xEKIfrpJ+lRGJvsXTUtbL779qyxgc/+MG7/Hqn0+G9730v733ve+/0NkceeSRf/OIXd+lx9wT7dDH06le/mqc85SkceeSR3HDDDbzpTW9CKcWpp57K9PQ0xx57LH/0R3/ExRdfzIYNG/jbv/1bvvKVr/CFL3xhb5964gDhR9sPDhtaRc2PbzqYzRu3g6BdS//FXLc1brvm1Nev6DEe8dXXsulExc7FLps/fBGqYxjrCpyVTK1fpKo1ZZnhrUBljuC3GLRDQkCeG6yWwVtIeIqpkmoxi8GT4TGEdKgOOCvCyr30eCPJtmUc9+m3YspQ4G35vZVFiCQSiV3Hwaq2ydKfMiP26WLo5z//Oaeeeirbt29n48aNPOIRj+Dyyy9n48aNAHzxi1/kjDPO4ClPeQoLCwsce+yxfPjDH+ZJT3rSXj7zxIFCrixzRpKPWe5z8C3M1wXOhjcvH/+95tTXc/TfnL9Lx33wS96J/Z87GFYZB00I+lWGVo6S0TZL0anJlUUIYhcoi52dYMxYlpqxsZLFhdCREnGMVs3n6LEaU+qgGSo13lm8a8Ipw2o9mUdWUM7nyL5CDfa9LZpEIpGAfbwY+sQnPnGXXz/uuOOS43RirzLVGbChu4hDsHXneg6fngFg5pYJOlNDysGoINoV9FNvpYhao23zPZR0OCfJexU+rs4bK9kx10NnNnZ4QviqjdEfZqZgPg9aINk14EFqj63DY0jtsIuhgHJV6PyIzCO1w1WKzmRJ/sAB1fYeftxgJvffGIJE4t7I6k0X9+kdqjVlny6GEol7M5s/fBFCHczkdJ9N4wso6bh+5zST40Ncr2Tm1nG2/v7rVnTsbTvHOWjdAkIEZ+vhIKfo1KyfGFA7ifeCTNsQjzFfIDOLyi3eQVYYypkCtA8+Q8rjSoUsLEWnwuYSAcjc0B9qRGbxlQq+RB6cUe34bFhl6LEaZyTOpDfWRGJPsupIjVXcd38jvRKJxBqy+SMXcvS73w5APl4xta7Puu4ALR29osI5yex8FyXdigshgIM3zDFRDBkvypCRlFm6RYj5yKRDCUembdABxYZNlhtcrbC1Qqhgnigyj+oaVMcEr6GdY5TbunhgsFgwvWmeyek+3elhSOO2El+LIJ6OYa9tITRcu224RCKR2JOkYiiRWGPcpAFC5ldtFJkKAunFMqcaasxixhVPPG9Vj3HjTetwXgQRtPR0ihrrgtv00Gj6Vc7CoGBsagDK0+1V5JlBKIf3Qa/krYCBQmmLqxT5RAnSs/7wWSa7Q3wtWVgsmN3ZYzhXgBWgHEJ7vBeYWlGXOnaEBJikGUok9iQOsepLIpDGZInEWuIExWQZBNE+6G1uYIqJTsliv0BIuPaFr131w+RjFdsXewCsH+8zs9hFK8f2+R7TvQEz28dBeFTm2HDQPBKP9RJdWEypyCcrnJXYuQxTKfRYzfqJPou5YeeOHi5uh5lSh6y0zOMGGryMKd1BfyRk7DDdmnPN6a9c9fNKJBL3nDQmWztSMZRIrCH3P/oXXD87jXcCaxR5boKmx2hcLdds9Vxri3WSTl5jnSTPDAsLXQAqq0IHyEqkcswvdqLRInSKmkUj6RQ1Ujpm+iGZXmnHrTsn8B7cUCPy4EiNkXjhw4aa8Ajt49jNAyJc72HLPSiENn/obYjMrslrsPkv/ww6lq3PO4PNH70QnGDr81c+dkwk9kVW7zOUiqGG9EokEmvIPzzq3Ux2hwjpcUbwo6e9icnukEGZrakHzw+feg7DQc5EXjKz0KWbGXRuGBsrmZ0ZwxsJNngN1UNNvZBjjWR+5xhSuTYYVvdq8GDqMC5T2tE7aBGGEt+YkHiBEATRtPDtZhrCAx4Gd68V2vyRi1BjNVJ7HviFu0713vzet/PAL5zFUe95e6vBOvpd72i/fuyfvSMUalZy8qVnMzE1WMlLmEgkEi2pM5RIrBEP+oezmJ/vsn5KY43EL4bw0m897qJdOs79/+4cBos51/yvu163Hx8fsH2xRz3U9IuMTl6jlSPv1pRzBSK32OgmrXsVZqbAK4/Z0cGMWbJujRCesfGKYZlhjSLLDYvbeggrEJknnygpZ4sguFaj1Xm5M4ONQ5yR+PzOrds2f+RCVO5QhW9dr+fnumy+5CJY1Gw9LUR5HPXnb4fpKnSaxgWzt07guw7R19hxi7CCzR+5EPoaWQh85lEzmoW5ady6GoRn80cvbB24E4kDARezA1dz/0QgFUOJxBqxrttnUGYsDAsOWT/HNr0yf1djJYgwCrqzANSHf+V1eF8w3ilZXCzoFRXb53tUCzm96QH5+j6DYcbkukXmFzvUgww6FuEFKIuvJNmkoT/bpZQeqRx1P0NIF6I4pAArqPo5QgJySTG0I8PlwaHE15JrX7RcA/XH//F7APzFgz/GUn2mtTJspAEoD+OGzR8OhaJcb/FeIKTHe+JIDsgFAg9GAQKvPa5wCOXxm0xw1c4d3oHKHJs/eiFC+OSEnTggcKsckyWfoRGpGEokVsHmj1zI+oMWMFZi3QQQ/trasTBGp6g5+uPn322HZylH/tXbKKZiwVDceTH1rcddxCO++lq6uibbtBPrJOvH+9wSzRGdF5h+xryA3ljJIoRulRNkhaFayPFeMLl+kbmdPXQnOC2aQQYSpLa4MuSYiSwIpr2J8RwdB9rjjEQuGZEd/9m3YGuFM/fHL2ZsvvKidhDfuGJL5UAIhPcgl7hZC8JojyDI9gRjSGQowMRE8DISuW0frxFvOxuKKGtkMISs04p/IpHYNVJZmEisgmK8QgnHYJgDkGvL4etmcC5kf/XGy1073lSJrRU6s+huKKbu9LbKYJwkkxYlHTfdMgWA91DXiqxX0xsr6Q/zUFh4EMIHfyCgHGYszHcQ0lEv5HgrkLkFB95JhA6CaW9EyClzoVtE5oJeaD7DF44H/P2b2Pyht1Et5rHYATlRkY3VSBW6NkKEQkjGoFchfTgnwMfNtEaP5F14W1p6m6ZoEircJusalA4mkFI1zy1elOOYT67OuiCR2BdwXq76kgikVyKRWAXeCxbLHO/hvut2cvj0DLmyrBvvM1kMw8jrLjjxnHfe7joVg1vz3CzT6dyW0obGbq4sSjiKXoWQwY266ufUg4zFftEsfmEHGjsI9xGZw0eBNSJ8LrQLnkE+iKNlZpG5DZ0baMdXRFshtMcLmJ/pIjKL1BZTjboytg6dKGeDGNt7ETpHzWsiwnVNRlvzOEKOOmJ+iaahKY6a24XrQC95nbxn2dcTif0Zi1j1JRFIxVAisUJecsVzUdLhveCIg3YCYGJXI1OW2il+9LQ33en9j37XO6hOGCzrYgjhWyNF7wVSejZ/5I4F2N987NuQwnPD3CTWh60xW6pQXPgw6rK1ZHwsdKdE5lBdg3cSbyUqt3THSzpjVfPoYZXeA7GIaSI2fOy8IAjFVSlR0yWqV4di6jZFm2jHYxJ8LGq8CIaPbonpow/3VblDaoeQHqmDhknqcFlKOE4Y+TUdrqZg8nG5LXwi7vR1SyQSiduSiqFEYoW8/yEfpao0da3YtjDOfFWgZVhbL5QZjXjuBHHoIIx6luCsxJiQLWadjF2OOz7O/f72HEqrMVYh8UxP9+mMh+5Qb3rA9HSfyanBqMCKG2FKWxAeWymqSlNVOoy34qkI5cNILAa6tsVO1PYEgTW42PmRMe3e++A75J3AGRGKOW3jseLzq2Urqm4E0yoL5yNE+Dh0d5qx12iU1oz5IBRT4fGhHuq2sCKO44Aw0ksk9mPSmGztSK9EIrEKvBMo7VrR9NBojJPcMDvFQlnc5X1FLABCF+NCIPwib4warZHUg9GOw5EffBv3+9tzAHjiv/wpxihumZlgw/giQxPW+KV0dMYqvCdskRmFsbIdLxVFHQosL3ClwpYKs5i147JwYiNxc6PfaXEgbyxCaCtBrxOKH9mKpJtOkG86S9KjC9vqiZR2y47bdI3MMER7SOUQ0mEqtfzxY2dq6RisMX10S8aRzViOFW7zJRL7CpbVjsoSDWmbLJFYBdecGjbFHvD3b8K4YI2fqxopPPMLnTu936v/89mYbb9CvmmAs6EYOOYT5yOkROhQ1EgpsV7ELSvIJqp2JGSc5LB1s/TrnBt3TMWRlmD9hgWU8Ny6PWy2ZZmhqnVwqS4MSnoGCxlCOaT2uFohrEB2HToPUR12qEdjr1bAHDsvXmA3GGRucbXEmWZTTCBkcL1uR2mO4Fgtwgir6QQFXVHsPimPtwKdW2y1XE9EHKlBKBx1ZjFLNsVEvO8yoXWk6SQlEvszq+3upM7QiPRKJBJrwLpen42TC8wNO1y/c5rJ7vB2I7CGU/7pDL645SSYMDgnyDqhuGh0OVKGxHmtbdDRxIaLs5KqWv73S64N6yb6bJheYGyiZGZujGGt8bUMxY2No7C5guH2LvMzY2GUtRi6MNlYTWfDgKITCriiW6PHgn+PzOKIi/gxwFAishDsKpQPhVqj2Yn6IFqhdfi6NxJnJWPdCl8HvVJzTBE7S6ZSQbStXeg01WrZ2M37cJtGt9Tcrxn9iaYAiwjpycdqjvzAn63hdzmRSOyvpM5QIrEG3Dw7QZEZOplBScdilaPVHTehx7KKnW4MlYVVc1OqIDgW0aXZSQjB92EEp3z0Hxpta2np+MXMFJPdkp3zYxy8bg4lHVJ4BsMc1bFBZNwUK8oFvyBi9ljhKMZDp8l5QbVQoAqDUg6lLVapeF+CmNqFVX2b2zhS820XSBWhq9MUIzILRZzWjnKQ4a0gLwz9fgEqboN52iJnaVfHGRl1SiOt0PKxGFGL5NpCqRVoAwLf3qcaZIikG0rsx6Sg1rUjvRKJxBrQ/Mo9dHyOXIUuzw+fes7tbve0b53GL3ZOI+P6uDUSlbkQkFpL6kqjlWuLFAAcrDt4nrFOhZsP2qBBnSEE1E6G0ZaTjGUVzguyzNDpVq02CBs8gvxihitVCGEdKoY7O1TbO1TbujCU2JhUX/Xz1uwQmpX6+DxVE9QqEMoxNjWg1xuGx/BhY60phCbHhqjMko/VOCeC31AcafkoEseKUSET9VPtOn0zobvN1tjS62CJXmiJdqjpFIk6FUOJ/RePwK3i4tNqfUsqhhKJNaApXCoXCpOqvuOm66Hd2Wh8KFGZRcrQDSo6NTJzOCsoy6DxkU3HRHmslfQHeRvP0a9zBv0c6yTeSeYGHW6amwweQ3HDbf3kYhhvaRcEz2MGWVjC3r1H1KFr5LWDwiEzR9XP8PXIZLHd0iIUGrbUYEMIbGeswjnJsMxC8SRpC6GxThBxy2iS6JzAVSoUQXFTTWqHLCwqt6NiSy5dp7+N7mfJx96JVoDedJpEjBURwofCS3m2vOxVa/MNTiQS+zWpGEok1gApPMZKjJMsDPOQw3UH/MWDP9Z+vGFikSwzbZdoerIfEuSHOvxC93Ft3UgGw4yqn7X3nVnsIpVjw9giedwes1aSFzVSeorcIARMTAzaMVTRq5DaozsGOhZ6BroG3TOoIsZvGNmu1reanJCSga1UcKMGRGbRylGVGmuD9ijvVWSZJc8Mzgusl0z3BmTaYoYZQgdjRyE9IrPtJl7QCMm2W+RquWwdv9UhwWistrRb1az8L/E68k7ghimWI7F/04zJVnNJBNIrkUisAS6Od67dtp76TrpCDcdvvJVM2xCnYRXOhSJgbqGLyoOo2FQaD1SDDJpV9CVjovXjfY45eBul1XH0BHkWhUYCunmN91BWWTQydME0OhZJ+VhcsUdgK4UdqugrRIzECIdaOo6CWHhEYXRlVKvb6RQ1nbzGA4uLoy260gQBd6MRmpgchPV5HTbBbC1xlQrdpiX6IKEcxPMGlo3OvFuiI2oKIuHbc21GZZ0bRsVjIrE/0qTWr+aSCKRiKJFYA4Tw4Y0lBqMet+nWO73t3z3iz1HKsXPQRQhPOchwTqBUGDGpzAahsBN0eyUqt4yNlaFAiNyyYwLjJIUKgu1BP2dYZgwXc+qhZsfcGC5WCuMTQ7wTDLd3qW7oUW/rUN3SbVf2m6R6pEd2DPl4hexYhBXtJpu3Al9HwbII52ZqFbyESkVtwvZXrsO5zmzvsWP7OAsLXepB1m6jLUS7gcZOwBnZfs078E3QbKWCC7e7k9V5N9o0g9F2WdM58osZV511+mq/rYlE4gAhFUOJxCo58gN/hnehEDhsehbv4R8e9e67vM+gzFDSo2QYGx22brYtqLyL3RJinlelWFwsyDqmvf+rH/wVrJMsVgX9nWN4K6JJoWBsvGRyfBjW0Y1kbnsPN9RQC1zHhdT5bgiCxY0MEhFh08zGLTLRNW0emZC047LOeEkxVY66RioUdGWtR39t+qA5Mn0dih1B0ESVCmKBk43V4WMVND5NXAcQAmOb+kcs+VfcfsOs8T9qNETeSrb+0atX901NJPYBLHLVl0QgvRKJxFoQ/YGUdGh1987HVz39bAZlRic3rJte5NqbNjBYCI7VKrPtT2aeGfJuTV6YkFN2Scjb+uMTvsG6zoCbt00ichu8fOpQaNS1YufOHju2jVMv5OFYyiHXVaixuo3VMIt5KC5qGYTSNhQjdqDxdXB/FrUEGTfKZCiKpHQUmWmT5hsRsxBB6F2b4BmED9EdUrlWGwSgOra9verYNqJDFBbVMUAoCL1bYuDIyLG7idtYGtrqbOhY6cIiZ5NjSOLAII3J1o5UDCUSq0QU0dMnboAp4XnA3995QGvDj572JhaHOVc88Tzuc/DOkDovQreoNzVoOyLWKOpaMd0bMLlhkQd/8Y0AfP7h721HSXiB0A7VCV0YEbPIismSrFsjtcPN5Lj5HDGnYTF2nmxToJg26FRkLnRqrICuQaho/LhkVNUf5MjMBY2T9MHgsdJUpcbEFX3kKDrDlMGHSBYWpS1C+GDC2OSJxbiO5Rolv6w7NApkFaOLW7KaLz1aWa55edogSyQSu0YqhhKJ1RKNAvPMYGJBZO5km+y2XPX0swH4+S82hDBVCOvyjeC4U+Js2LpS0tHJDOUSgbbOLJ1e1YqNlbZMjQ2Q2sXVd0E91LiFbLQiP2Zh3EAVtraECKLjYrJkbP2ArGPa7DGW6HJ8Hc5rOMixcbNNx62wajEPcRp1cJvGCVRhQoGiXdtp8tFXSOlgENkEtXonYqZY1CaZmHLfdIiaQk0uyXRjFNyKD4Xd4PqJ1X0vE4l9CIdc9SURSP3kRGKVHHqfHWyf63HQ2CLXbl9PXSsOWT+3S8fobMmxD6jaFPi6DltigzpDZbZ1ta5qxbCf86ivvYbrf3QIYr2iN15SNUVJmTMrYKxbsTAfxMq+koiOw5tQ+KiOCe7SwiNckPdI6XFOIKQIIyfiRpmIbs8QE+vDFhhL1tgbfVNYbRdxRBY0PKoILtQi6oa8FZhSkXXD/XVmybVlKAhCa23xMrpbNwaNsQskbzN+HNkPeJwNRduWP0ldocSBg/UCu4pR12ruu7+RysJEYhVs/j8Xc9MtU0jpKY3mkKk5xroV33rcRbt0nB+fczrj3RKtLVU/ox5q6qFmZm4M7yTlMGNutks5zPFOcNPMJH6yRkiYn+niYlcGD/VAMxjmQUMEqDGD1BbVDZljrlT4WkLmEWMGNRZ0Sc3mmBlqfBUiQoT2oTvjY7Fjo9jaBj+gapChulHY3Yy4YrHkjESrMEZrglNVYfEuXL/j1gnK+YJ+v2hHay56DYnWPDE8pybx3jfdIRnOR+rg3i21g535mnxPE4l9haQZWjtSMZRIrIKtf/Rqsm7I9PrFjullI5xd5T+e9NZW/5J1DFK7YGJY1Cjt0IVFZZasa5gaG9CdKJmYGKAKi8wtxXiF0A5XKWwdOiuuHHn8uDoKm0vVrtK3hodeYI2kXMhDoRT9hKS2bdQGEDpCS/RDUkXXZyvC7TMbOkcOnFEYo9C5RRcmbKsZSXdiSH+uMxrbmVHsSPg36oDi4wgV88aWuFQ322cN3gr8VL2i1z2RSCRSMZRIrJKJsSHew+aN2xmabJmmZ1cRwtMdL8nz0G1RyjHeKcMWVbxsmppHK0c5zCgrHbeqQs6Zj95ATRdnbF0/jJlqFYoNAeQuFHCdUKDkvZpqrsAtZPhaRtfpEJbqYySHaN4pHK3fkNQOZwRSeshCcWUH4bl7FwqiaiHHVApTarLCtPoj3TEjzyITdUGyGbONhNfLIzho9U2hQAqvT3jhYOvzzljx655I7It4L3GruPjkQN2SXolEYpVsv2USrRzGSUqjMfXKYyAeep/rWD/e5/DpGdZPLlJVmm4egk7LQUamLTsXx9i5MIaQYZW9TZGPq+git+2WWH82mCvKIozIhArGik2GF0ZSLWZQCyhca6iIAJW7YMwYCyN8KFxEMw4ThFwxCF2mWiK0DxcVQ2IFIRxWeOpSo3KLMfH18bGwsiIYPyofu0OjVHvieK3ptvkolG4y07wXZIVpu0aJxIGERaz6kggkAXUisUq8FdRGMTQZ3azGjK38b4wPP/SDADzhsleglcPWkm3zPYQAnVuUcnSkpbIK5wXVYoZQHqUd9UDFbo3CW4HuVaFAInoXAa7UQcRcK2yp4wq9QnQc4EcdoOg3BLFL42PR4sErj7AC29e4zIUujwkbZB5uX5jErTDdqXFGUpeqzROD4EXU5KAFX6FQHOHgtn+4CkHrk9Scm5KOemWTyUQikQBSZyiRWDXXvvC1WCtZGBbUVjGsVp+Jta3fo6NrJqcGDPs5KhZGc7Nd5gcd+oOCqp+x9XlnIJVH66AlEspTjJeIzGKGGjtUeA+mUgjlySdKZObaQgcvwhp9GYJSRZMFZuTyfDIRM8liIRQMFT1YielnYUXfE74WU+PDFYAK2iMz1K2oux3FuWgr3XSkYgK9i4GxTUeoyRvzcdSno7+RFB4Vs9mO/ODbVv26JxL7Es6vVkS9t5/BvYfUGUok1gClHNYJcm3u/sb3gCueeB4AJ7zlnYgxz7Dj2XzijcxXBR1tuHVuHJxg8/svRowLBnXRmh8CdHoVw8UcmcfixkGeG4b9sI0mtMN7gZ6oMItZdJcOF1/J9s8kb8Ntg5EjELU6QntUYbGVDIJr4UFHA0gjEblrx2AArsziGM5TjFdU/YzOZEk5WF44CuHxQrRZY02R1JhLyuh/ZGsVhNTAYJghlePaF712TV77RGJfodH+rOb+iUAqhhKJNcB5gQRu2jHJ+sn+io/zhMtewZcf/a7286Vho4/62muoak1/mIOH3vQAOyEpBxlShi0y1a0p+1kodAqDrRVuoEF4XMegc0s1l0Me3KODc7Vv197tUOGbcdWy0RVhk8yB7ARNkjMijMfibREeYQRe+VAELc0Uy0JxpLsmfNo1GCPJu3UIfY25ap5oyqgsDokQRN+hJd2jZpUeqEsdvZnSn7iJRGLl7NNl4TnnnIMQYtnlxBNPBGDr1q23+1pz+fSnP72Xzzyxv3HV08/mR097E1J5tu0Y36X7HvXXF/Ar//h6TvjcucyVHX77my9j8/svvt3thnWGsZKq0tQ3jWGtZKxT0e2VMUQ1tL6ljuvuIqzo51Ml+WQVapYlbtK2n4Xip45jMOERmQsC6RjQivQI5eKmV/x6I2ZusssIuh8qGYorFW+nHSJzYWtNhYLGDLKQYRYdqetSU/WDJ1LTAZLaBTfqWHAt3ShrXKhdFI5L5ZDaYYcrF60nEvsqDrHqSyKwTxdDAPe///258cYb28s3v/lNAI444ohl19944428+c1vZnx8nCc+8Yl7+awT+xPHf+YtnPT5N4dPPPgdxS7df+OGeYrMUM526FcZO8su3YMXl93mIf/4BqY6A6pKI6Vny8teRZHXDCvNYLFASEc2XlHNFWF05UVb+NSLYRQ1nCuwQx23tkYJ8Y1fjy01bqig2QjLGk8hwMowqoqeRCoPgmsftT/Ndhe5QxYxiFX5MNaK77eqY0B6BgsFSltsOTKKDLcRuBg46+2SGJDYoWr1Q0a0Tt0Q3LOp9/m3skRil2kcqFdzSQT2+TGZ1ppDDjnkdtcrpW53/ec//3me9axnMT6+a3+5JxJ3xuaPXsjYhMXFra1qR4etL9u1SIj/95vnA3D035zPsMqoao3zgmM+eR5XP/sNAEwWw+AW6wXVXChuyipDKddumQ1mOugxgzMhCsPM5/hejR6rsbVsw1DruWIUw1FYXKlgoENho0Mx42qJKmyI7YgjMqk91gXxsjXNGr/D13GcpjwytyONjxe4SiFUSK73XrQFVTVfgHJhFKfDWr2rVft5sAYI8znvg2eRdyK6UseIECdDdIiHrX/4mrX6liYSiQOQff7PqZ/+9KccdthhHH300TznOc/huuuuu8PbXXHFFXz/+9/nRS960V0eryxL5ubmll0SiTsjH6vJtCXTQbi89cUr/6WstMNUoRCyRi5LcP/GY96OFB5bS6590WvZ/Jd/Rl1phoMc5wTD+QI9Zig6Fd5KXKXorB8glcNWim6vojsWVu2FB69jl6VW+MzhY0GiOqOujh2O3KtF3GbDhkBVnYfCisYJWobRWBPg2qz3h7GWD5/XEleqUJQVpu0ajU2UdMeqMI4Tns5YFVy1tUU17tWMsshAtI8vhA+6pUTiAGQ1hourFV/vb+zTr8Sv/uqvcskll/ClL32J973vfWzZsoVHPvKRzM/P3+62H/zgBznppJN42MMedpfHvOCCC5iammovRxxxxO46/cQ+zuZLLiLTlrG8ZrI7XPXxJnpDstygpMPWivHxIZs/PMo4+8qvv5Otzw0uy9P3maMXb68zy8S6PkWnohzmCOVQHRu8hGqFzBy1UVgrQ0GTu1Yc3XR11JhpzRhtP8PPZ3gTc8hKhY/6HNU1o5T5SrXeQzIKpEeGj9F4URKKKmiNILtjFUUUTgvtKDJDHWM7ivEqiL8zS9YxISYkBsEGV2uBym0bH+KdCFqlROIAxLHKbLKkGWrZp99FnvjEJ/LMZz6Tk08+mSc84Ql88YtfZGZmhk996lPLbjcYDPj4xz9+t10hgDPPPJPZ2dn2cv311++u00/s43SnhlgrmVnscuvs6kevMz9Zj1KO4SBHZZaFhQ7FRMmxn3rr7W67sFgwLDPGOhVKOgbDjLrWKG3xtcJWChvNDb0VVHMFw7mColehuzWqV7eO1EI77GKGHWjqHZ3gRt0zbUJ90AUFY0TvoZwtwkaaCGJmr3zQ/sQYDSE9WdcE/ZHwFFMlulPT29BnbN2AxZku1knGxkvWr18AYGpswIbJRSa7Q6qhZrI7DI7V0ZBxKbYKRZ3OQujrarpxicS+jF+leNqnYqhln9cMLWV6eprjjz+en/3sZ8uu/8xnPkO/3+d5z3ve3R6jKAqKYtcEsIkDj2M+cT4b1w2ZWewy1qlaX6DVMhxmjI8PKWuNGWpKky/fpooIAfVQs7MMP8I6t9QDDYSRlTcCWThcrVCFCcnywlPOduJmWDRNdI2BYojeaMZlQoTUedmJXaChHnWOouDZN5tkWbxvk5MqQI3VdNYNMZUm05ahCVEi83NdZGZbMXSuops2I8H3unWLLAwLDlq3gHGSHf2sFVnLzLavh6nUKNw1kUgkVsE+3Rm6LQsLC1x99dUceuihy67/4Ac/yG/91m+xcePGvXRmif2RuUFBXWm2Xz+9Jse75hWvxN3SYW5Hj3Jbl6n1iyGE9TYeOsd/9i0I6Zmc7oc4isyOgk0hpMdHITN4bKmxtQxi6Ia4St+EsSKDGFp1TShubOO6SDBRtMH/p17Iw6ZZ1BWJLI7cms/j3ZosMiEdmQ4C72GVkXWCS3a5mNPJa4yVLAyKYBlQa+b7HSSeTFuk8Gjp6I6X7ZiujfFYekkkDlBW5z4dLonAPl0MvfrVr+ayyy5j69atfPvb3+ZpT3saSilOPfXU9jY/+9nP+Jd/+Rf+4A/+YC+eaWJ/4+rffT1VpVGZXdMxjZegtmVgBFq54Bmkl7c/TKmwRlJWGUWnDqvlBNNE3anbzS2pQzp91q1RWRg3ySKst+MEWdeMion4EK5WoctjRfAbil/3KhgzNl2ZpXEdqOgppF37MYTuldKO/iBHSI+pNFJ4xroV+ViNit0hU2kWFrrUJgS6LgwLqjp0vDJlw/NrzjNupLXFn0tv5okDlySgXjv26THZz3/+c0499VS2b9/Oxo0becQjHsHll1++rAP0V3/1Vxx++OE8/vGP34tnmtgf+dmz3rjmx9x62mgt/+RLzyYvaqpyeWRFb7ykrHRIse8YtLYYq1A6CK+F8kjh2rV4F1PihQwhrjhARv8htSQh3oiQLZYHw0YKu/zkShViNgRtRyjojsAbEQNZg0N1Ocha80RbS1TmENJhjEIrR7WYsaCCEFpllnqocS6MyiwglWd+WFCbxozRISRRuyTDvz6JpxOJxNqwTxdDn/jEJ+72Nueffz7nn3/+HjibRGJt+a+nnMv9/vYcTH/5j2m/X2BLRWeipMhrZnf2IGaINenwtg4J9jq3VJUKOqKmiyJj8RKLjOZjpAcjQDswYYtM9OpWsuSVR3jCGE6Hwip4JXqInSIhwVcK2TUIERyvO2MVda0RAmwtmR92wQmqSuO9IM8NnckBZa3pdSqGVUYnr8MGXNwYkzqO9Lxo//VxpT+ROFBZ7agrjclG7NPFUCKxv3LUe96O6zqu/YNzbvc176LgGZif74KHrFeHmAujMHGVnSiyFtq1YyXvBK5UiEqC9lBKRGHxlUKUEsYsLOrgQyRC7EXjVC3j7fAxNb5jQiyGE3gVt81mc8gcVssQpSFg6PJ2q03nFu/dMg1TnoXCqdepWBgUdPKassow8etChI4QhPMRArwHv5Cx9Y9evVu/D4nEvZnVRmqk1foRqRhKJO6FbPmTV3H0u9/O5v/7Z2AE3UMWGe+UdPOag9ZnzCx0KTJDrm3YPCuDT48tVSh+mvwwK0F68k4dQk19HIUJwAp87qCWobiSInSYivgWOZB4IcOKvROhYIrC7MYVWkT9UZMT5seDQSJGQm7DxlksxrwXSOmpK4Uzit7UgMW5DoMyZ7xb4rwIhVCt2y6WlB7X6JliIRSeGHCbKV4ikUislDRwTyTupVzz8leFUdZkTTnMqKziul8cxI65MaxRDMuMstLYWpF1DNVCHsZhViKUJysMqmMQ0odxkw15Xl4CXYsYr4MbdGcUoSFkCGdFOXzhQhBrM0KTQV8kohO29wJnBbYM3SLvBaqwbcArPnaT4mMDlIMMlVmybk1/viDv1kjhKWtNJm0bt2GtjKMw2sIuCMPDa+NKzdY/Tl2hxIFN2iZbO1JnKJG4F5OtH1LN5cjCsrDYIevWmCoUP1pZymGO0pZyrmi7PUhPnhvqWiHjmn09yFC5DWaF48EQyBlB3g0dI9U1oeMzn+EzhyxcGJ+5IIpGgO7WrSO0LxUIEzo0ToRUeidw0Y063E8Ev6M8tnBiNId3gjpGfSAIhQ/Qr/LWKRtGRVDTUfI+FERmmLH1Ba/d09+KROJeR9IMrR2pGEok7sXcZ/0MM2Nd+sMc7wTdTsV82UUrixCQ5YbhYj7y3InFSTnIEBKsDeGmYaTl8FUYqQnl8Q7q6GHkhprO1JDSA3VwrnaVQo7X2IFuvY5spWCooIgFTy3jRlrIL/OVCuaL2sXCjBDCamKnx4iw0SY8eS8Uds3oq2x8kJo3aDESR4cOUTBanPivfE+89IlE4gAiFUOJxL2Ym+cm2g6JKRUD8lZ/MxyElXtfBy2NyC3ZmMFUYZNMKg8o7FCBFzgTukJt4GkccwHt+KkYqxkuiJAgX0lEx5JPVMGR2olQCGUO+gqXjVbxUT5oirI4FitV+FrsOAkZxnamUrhSk43XoSiThHMQor0dAMIjY7dJiGjyKDy+yrny4tP39LchkbhXkjpDa0fSDCUS9xI2v+/iZZ8/4O/fxHRvgIqaHwir6lnHYJ1sU+GLqZJ8ogQPpla4WrWbWt4TfsqbdXQnMKXGVqp1dC66NflEhbUS5wUqeglROGwlqWcKqsU8xHP06tC5KcJtvApbYsSiKmiOwuPRtbEDFfyITB0KIRHHdcuctaOZYjBY9HEzbvQcmo/TeCyRGJE0Q2tH6gwlEnuZYz5xPuPjAzZsXu40nWdhM8tYidKOoqgxRoW8r9y0G1fVYobuxA6M8iGIVQdTQr+tCMXJuMHbkB/mTShE6n6GryXDoR6NtURwshYyRnI0sRylxA0UPncjY8Zo1OhjLIe3ElcrhHLIrseZkGov47ngCZtlwofNMB+6PzIWRW33yYvgbeTD3M+7cA71ULP5wxex9fmv2/3flERiH8CzuvX45NI1InWGEom9TK83xDnZxlM0XPHE89g+32Mw1wEP/fkOdcwZGy7ko5GSF5h+dHyuFWaYIYBqWxc/ZfBdC6XE1wJZWFSvbmM5RG6RhQmRHyqsydtS4QcaoUbX0URzNILpUgaDxuYvSw9CuaAb8mLkGq38yAE7BsACyHbdHpS2sRsUVumlCkWh91ErJIN7tatUKoQSicRuIXWGEom9yMmXno2xkk5umO13ln1t8/+5GDGuQXqqxbA2L5qV9Syst+NBdUwYYekQWaG0DX/xmSBqDoFnHmxIn6cW+Bi2qjoWHbtMTjl8LrADHTyIjAwFUNwmQ/pgzJh5vPRhJd/KcDwn25gPIR0yc+DDKn+9oIJXkR05STdFVBOroZRrY0WskUjpR4WVJxw/dfQTiWUkzdDakTpDicRe4v/7+quC9scL+sOcq55+9rKvZ+uHbfenMVIMq+kSZ8NafN6rw7gsFgyNU7PZMg6ZC9teVQxelR6UR01VwX9IO0xf46xE6xCIahYzKFUoPEqFryU+d+EigJ4d9dY9MQYkFjh1KIi8k+BDh8lUClmYkXbIhe5P0+1pNsm8FxijcHa0Rg+MdESQQlkTiduwpzVDF1xwAb/yK7/CxMQEmzZt4qlPfSpXXXXVsttcffXVPO1pT2Pjxo1MTk7yrGc9i5tvvnnZbXbs2MFznvMcJicnmZ6e5kUvehELCwurfj1WQyqGEom9xFwZOkEbJhbpFPWyr530+TfjlvjtBONCGbo2BGNFF4sgqYKY2ZngBF1t6+JyjxyPhVIeR1JGIpTDlkFg7Y1EZKHIqmNKvMxHpom+SZ+P6/FqrA4FSdcGjZAJ7tbeiOA7FIXS3gQvIqFcGL8J2mJMyNHmGoSPm8iPMF6L8R5N9pgPonEABuntKpHYm1x22WWcdtppXH755XzlK1+hrmse//jHs7i4CMDi4iKPf/zjEULw9a9/nW9961tUVcVTnvIUnBtpIp/znOfw3//933zlK1/hC1/4Av/yL//Ci1/84r31tIA0Jksk9hgP/MJZzG4fB+mZnO5jXYZzgm8+9m23u21V6dDlaYTHhJFRk/HljcAs5qixGm9D8ruUHlNHN+ipIKKma8LtrUT16rAy74gr6+ArgStCN6ZazMNmmAq5ZKKUiMkaN1SIOqTPhygP33ajhASReRiKOMYLhQ/O45G4mM4hpEdnFtvoh5p8sWZcFnPQliJEs10G1VAmx+lE4jbs6THZl770pWWfX3LJJWzatIkrrriCRz3qUXzrW99i69atfO9732NychKAD3/4w6xbt46vf/3rPPaxj+VHP/oRX/rSl/jud7/L//gf/wOA97znPTzpSU/i4osv5rDDDlvx81kN6U+tRGIP8MAvnAVA3quQ2rHYL6iN4kdPe9PtbnvC584lzw0bpxfCVpgTyNjBcdEAsRlNhULIxQwvgZvLyQ4aBjG1le1YDUHbVcKH0ZbsGHQvhK2aWkEpkYVF5A6ROejEMZsgeAlJD4UNuiAbNtdEbpGZDREfmQtC6Cyu5kevoCbmw1rZCqWdC10gbwVK21H3pym0aJynXTCYnM32yPcpkdiXWKsx2dzc3LJLWZb36PFnZ2cBWL9+PQBlWSKEoCiK9jadTgcpJd/85jcB+M53vsP09HRbCAE89rGPRUrJv/3bv63J67ISUjGUSOwByipjUOZkmaXXK1Ha8ZNnnHWHt1VR9zM36ITuSObCWMuJMJ6ay8Lmlg7bWraWWKOwtYIxEwXHoXNjyzj+yiyysME0UXpUjMiwtcTVYfzmdTBObEdeHqii148JYm3RrOAv0Q0JQdxQi4VSPDcA78LX8aLt9Lg4TkOETlJTCDV6p6U6oXKYM9wyyZY/edVaf0sSiUTkiCOOYGpqqr1ccMEFd3sf5xyveMUrePjDH84v/dIvAfBrv/Zr9Ho9Xve619Hv91lcXOTVr3411lpuvPFGAG666SY2bdq07Fhaa9avX89NN9209k/uHpKKoURiN3P/vzsHpRxSBGGwdaI1EbwjrAvmh2WpybVFR1fn0NFxMB4ywXz0H9KFDRtkM3kwZKxVCFE1qjVDlCo4Uqupqn0c0a6xh5FZ8AoSCCNGguuubYsg3QuhrwgPHQu1xC9mmEXdGkAiwlgrOGAvX5FvtUEueA81ND5CAEo5VDSDFMJj+pprTn/l2n5DEon9hEZbt5oLwPXXX8/s7Gx7OfPMM+/2sU877TR+8IMf8IlPfKK9buPGjXz605/m0ksvZXx8nKmpKWZmZnjwgx+MlPfuciNphhKJ3UyRGcpah20wEfRAVz/7DXd6+6uefjZH/835eCvoO0nRqSgmSqp+1oqgffT9qXZ0yNcNqW7pIqaqMBqLBYn3AlTsHlUhjwwn0N063m7UQVJjMYPMA2M2uFM3QamdUJg4I3CViuv9ArQHfCvwJnOhIPIE40QvQqRGc52IG2/NuRG6QarpIvlGh+RR0mGM4toXJsfpROLOcIhVmS42952cnGw1PveEl73sZa3w+fDDD1/2tcc//vFcffXVbNu2Da0109PTHHLIIRx99NEAHHLIIdxyyy3L7mOMYceOHRxyyCErfi6r5d5dqiUS+wneh/l+f77gp898493eXipHd7xsN6+cDdqdbKxGZg7diYnxhaWcLZCVxDuJnctwRqJySz5WkY8tzSIjaIdiOKotNb5WYfur1OHdIGqR3EDj5vMwPrPBe8gNR4Gt3ojgJp3ZsIEW30lk5paYQYZ/mi2ysP4/GocpFQqhblHTLWo6eU2WWaTwOCcxN4yt2eufSCRWj/eel73sZXz+85/n61//OkcdddSd3vaggw5ienqar3/969xyyy381m/9FgCnnHIKMzMzXHHFFe1tv/71r+Oc41d/9Vd3+3O4M9akM2St5corr+TII49k3bp1a3HIRGK/YaozYFhN4J1gy+/dffsZQsHitGP8/3VZ/LXo3BxHTVI5bC1RcTwmpKeUHbJuje8Q9UWSqgyjNYQHE0ZvWIEsTEift0EXJJQPjtJR84ORQUQtgzDbDjSiltAz8WsWpGzF1a4RU+um+on/qFBYSemxRiAkbR4aflSgWSvp94PgUkiHKTViJmPLy5NOKJG4K/b0Ntlpp53Gxz/+cf7u7/6OiYmJVuMzNTVFt9sF4EMf+hAnnXQSGzdu5Dvf+Q5/+qd/yumnn84JJ5wAwEknncRv/uZv8od/+Ie8//3vp65rXvayl/G7v/u7e22TDFbYGXrFK17BBz/4QSAUQo9+9KN58IMfzBFHHME///M/r+X5JRL7PNfevIHhIOcnv3PHguk7YsvvncmPn342c78cND7OhgLHuxBaKiQUnQohfavF0dpSL+Rxi8yNTAo9MVVeoroGlYXYDJHbcJtahpqp0QNpF+4kwJmQPu+zoAGSsSMlpAsdIUB2TDgWtNohZ5qV+VAgNaMwqVzrHeScoJrPmd/ei5tnDu9CsZcE04nE3bNWmqF7yvve9z5mZ2f59V//dQ499ND28slPfrK9zVVXXcVTn/pUTjrpJM4991ze8IY3cPHFy0Oo//qv/5oTTzyR3/iN3+BJT3oSj3jEI/jLv/zLNXlNVsqKOkOf+cxn+L3f+z0ALr30UrZs2cKPf/xjPvrRj/KGN7yBb33rW2t6konEvsw1p76eo//m/BXdd2xyQF1rnBf0pgYYG7bKrFHh+mYTywgGcx30mMHZpjVDq99BefKpEmskJjpM+0oFjVDmELXED3RIo7cE9+nChuJG+7ApFhHK44Y65JvlQWCtcxuLtCZ7bNQV6hQ1g2EeRN4+FEFCgLm1g5iuUJkNAu4oMG9W6xOJxF2zpztDfqlj6p1w4YUXcuGFF97lbdavX8/HP/7xXXrs3c2KOkPbtm1rhU5f/OIXeeYzn8nxxx/PC1/4Qq688so1PcFEYn/gmlNfv8v32fyhtzE1NozbVQ5jJfVQY41CxiwvfDBMxAtkZnEmbGrZWrVO0s2auzUyGjYG92nqKIKuJGiPVx5fixDHQUy3l7S5YnaosX2Nq1ToNC0RPDeeRo1bdTiAwFpJbVTQPkXBtvfBKVtMVa2oHMJxssKsxcudSCQSu8SKiqGDDz6YH/7wh1hr+dKXvsTjHvc4APr9PkqpNT3BROJAZWxdn8UyZ6I7xFaKcjHHO8HYWIlSDmslSluquTyInmsVTRZDkZJ3a7KOwcdCxdUqjNpMMD8kD6MyOV6Hf+Ooi2Zc1mSEWRG6SFaMwlLjZnzTapdxw63p7DTr9MTMMe+DnUD7dQcqt6jMtSJx7wQybsIlEom7Z0+PyfZnVjQme8ELXsCznvUsDj30UIQQPPaxjwXg3/7t3zjxxBPX9AQTiQOJ4z/7FjJt6S8UdMYE87NdFlQwSbSVQhc2dIgqjdI2bJhtD+7M/sg+rg4ZZgiwbUfGtyMoPMhu9ClChMLEhDBVV+kwUsuC27SwsZMkPMIRfI6iy7TMgxFk43dkTQyUFaPHayI2vA+aIWfFqIMUv+49rcFiyCRTqMyy+SMXImazpB1KJO4Cv8oxWSqGRqyoM3TOOefwgQ98gBe/+MV861vfaq23lVKcccYZa3qCicQBRdyu0rnFWonUQVjsrKQ7XpJlhsFCQa83pJwrMNf3+NlrT6deb0Ih5MK4rHGYdqUC4l+B9SiY1VWKNpojs6GwUQ7RaIMG4e8kUYSCy0tgLCTdN/loQnikduGxohP17Z6Oi2/YsRBaiohxHUVulvylGm6vCovYULL5Q7fPbUskEom1ZsWr9b/zO78DwHA4bK97/vOfv/ozSiQOYEIel22jKxrBcadbYZ3kqqefDcCRf/W21pDwyA++jWJdSbWYhxBWL/C3ld74EJnhShUKGydQeUiwbzpJEDLEPIQ1ewjFkhF4HVb7kTGaQ4SID3yI9JBR19S4Sbcmj2JU9AgRRmJS+dbzSAjPsAydrWbzrP1Ygcgsmz98EVuf/7rd9IonEvsuHrgHmua7vH8isKLOkLWWt7zlLdznPvdhfHyca665BoCzzjqrXblPJBK7TmPI6LygNop6qDHzOT986jltIQQsc2YWEmytkNqG8VZ0hF5a5HgXMsiEdngjEHnwKkKAr2UwUYwbZioLa/PNSMxH52rCoRDKhXBWF8ZsUrmwri/Cyr0zMhRxpQpjtii0bkdisRCSS0JZYWmCvW+LKpktsQhIJBLLaByoV3NJBFZUDJ133nlccsklvO1tbyPP8/b6X/qlX+IDH/jAmp1cInEgIgR08hpTKbY+9wyu/YPX3PUdYgZY1jFIPYrqoPlXEAolL0KB5KEZkTXIInSjVNdgK9kWOhC2yYKoOmyKNS7T3om24Gp8g4IXkogFjYjxGx4TxdumUiG9PjpyW6Pa+zYRHst1Rx7vbvuEE4lEYm1Z0ZjsIx/5CH/5l3/Jb/zGb/CSl7ykvf6BD3wgP/7xj9fs5BKJA5H//u1z7vFtj/rYBa2uqOpnsfDxWBM6Mc3kydVqySgsrNe3iJBWj/RYGz+3oVskMo8qLLaW7RirEU6LuLY/KoxC8aWy0HUS2occtVjgeBcCXH0sgoR0y8XWjrYAkjHN3s7mXPviuykGE4kDlNVuhCUB9YgVFUO/+MUvOPbYY293vXOOuq5XfVKJROKeEdbmg+Gh1J6iU1FVGkQTqEpb+AgJLHG+aDQ9uLDWLiB6Fam2o4QDO1ShayM9CBc0PwSXaSGC67RbYrhoSxXGaH6UTu99ePxQGPmROaNqdvRBad92lJpRmVdJ1ZBI3BnOC8QeNF3cn1nRmOx+97sf//qv/3q76z/zmc/wy7/8y6s+qUQicfcc9bEL6EyUOCtxQ413UA5DHIfMonu0F61xYusfRBO9Adglb4ZO4ErdJs+LzIV3CAm6V5H3KnQ+cqKW2of1fgh6Ix+6Q0K5ME5TYRTXjNwaZ2wpPd1O1XaatLJUN48FMfWOLtWODubnPVytuPZFKbU+kUjsflbUGTr77LN5/vOfzy9+8Qucc3zuc5/jqquu4iMf+Qhf+MIX1vocE4nEHSC2FfROWMAYiXFZdHiOHRiCDsh7EbVDSzosjYiZUcdGdQx2qINmaBDT6X3I81DRU8grj1JudKy46aayKKCWo8ewtWotASCO1ATozOKsZFhFbyQnGFY5W08LfkLHvOMdiFqgKrjqFWmDLJG4K1pz01XcPxFYUWfot3/7t7n00kv56le/Sq/X4+yzz+ZHP/oRl156aetGnUgkdi+6L5hf7GBiN8fV4cdZ6dgVYqTraQXVcWTmjQQXR2XRFbqJ3RA6bnDFRPumwArGjQKlQpo9wqN0iAVpA1itaAsh78FWMmiMIGiRojt146fknMDNjZYwrn7lK3H3HXDVWafvyZcykdgnSQ7Ua8eKfYYe+chH8pWvfGUtzyWRSOwC9ugBOnZ5ZG5Dh0fbUSQHcWQlfOsP5ON0TOQxmT6OsfAijMxUWGd3gjhi862ux1nZbno1m2gCsE6ipMNLMJWK2qAwDtMdEzyH4so/hDfwbqekrDKG27ts/aNXL3teK8lxSyQORJKAeu1YUTF09NFH893vfpcNGzYsu35mZoYHP/jBre/QbVm/fv0uPY4Qgv/4j//gyCOPXMlpJhL7NMd+6q1AMDDc8ntnLvvaMZ88D5U14mPBNf/r9Rz7qbfivcCUTUZZLIBKCZkH5aEWo+4PhG0uHXLCnAz+RCKz5N2aeqiDN1G76h7uYktNMz6T0WixrhVaB62Qt0GnBOCdDF5BQJ4byjIL2qAqo5wv2PqHaVMskUjsfVZUDG3duhVr7e2uL8uSX/ziF3d6v5mZGd71rncxNTV1t4/hveeP//iP7/BxGs455xze/OY3L7vuhBNOWLbe/53vfIc3vOEN/Nu//RtKKR70oAfx5S9/mW63e7fnkEjsLY755HnozFGXOkZqjDjyA39GMR2yvpT2iDnN5o9cCEKj8jCyMlUWW0AeOi50faI+QOiRUEBmDp1Zqn4eOz7gKoWLK/NS+2V6I2dD3IcrQ+5ZVenWKbuuwttJ89eqjaO6oDOCsmx0QhJTC8T8ihvTiUSCtE22luzSu9Hf//3ftx9/+ctfXlbUWGv52te+xubNm+/yGL/7u7/Lpk2b7tHj/cmf/Mnd3ub+978/X/3qV9vPtR49pe985zv85m/+JmeeeSbvec970Frzn//5n0i5IqlUIrHH0JmlyAzmNhtVR/31BRTrTChK4tr5lj95FUd//HycldihRjQi56B/Bjyqa0cRGQAudIe8FTglyMcqrFFYgp+QsxJdBJdp50ar8zq3ofOUuag1kjiChkgIhzUhaFWIUbxGG8Qau0t5XjMc5Gx52e1DWI/687fTPXw+FlOSeqjxcxlb//jVt7ttInGgkwTUa8cuFUNPfepTgTC+um0OWZZlbN68mbe//e13en/nds1Kdn5+/m5vo7XmkEMOucOvnX766bz85S9fFh57wgkn7NI5JBJ7AxnNB3W2vDPa7ZXUtY5ZX556qNn8/osRE7Hz48QyL6GmIrKVgvbHL2qIrAyFE8HgEFjm/2NrhdLBd8hbibfBvNEbgYzZZUI6lHZI4bFOImTwIaoWcpCerGNwHpR0ZJllMNPlpy94450+7/H7zlGZ0ROQmcOO3Xl3OJFIJNaCXWqROOdwznHf+96XW265pf3cOUdZllx11VX8z//5P3fXud4hP/3pTznssMM4+uijec5znsN1110HwC233MK//du/sWnTJh72sIdx8MEH8+hHP5pvfvObd3m8siyZm5tbdkkk9jQ6OjcPd4zGuZs/fBFKBsNCJUPshh1qKJoqJ6zQ+yh8Ho3Gor9PbsNPvBOj63QolLR2OBNunxWmFVZao0KHpxmV2bCq7ysVzBkj3gs6ec1Yt0IrSz5eoTKHqVToLnnBYKFg6wvu3DfoqI9dgLESKXwoBmVc5Veeoz52AUf/zfkAnPJPZ9zpMRKJA4nQGVrNNtnefgb3HlY0tN+yZcuaPPhPf/pTvvGNb7SF1VLOPvvsO7nXiF/91V/lkksu4YQTTuDGG2/kzW9+M4985CP5wQ9+0Iq4zznnHC6++GIe9KAH8ZGPfITf+I3f4Ac/+AHHHXfcHR7zggsuuJ0OKZHY01z5W2/mV/7x9ctyyfLxisoolAwbYtYorn3haznu02/FVLEwiaMx7wUyt6OCRfg2RgPJKGFehNRUKR06xm5obTGx2BEyiKKzjgnxGGUYw6k8jOKk8mjlqGsVwlm9wDo5MlhUPgTCErpOmz980WgbzYm2ODrqPW8nO8wAQccghQ+SJ+npjpd4L6iGmiP/6m0cdvge+AYkEvsAaZts7RDer6w2XFxc5LLLLuO6666jqqplX3v5y19+t/f/v//3//LSl76Ugw46iEMOOQQhRt+UZotsV5mZmeHII4/kHe94ByeddBIPf/jDOfPMMzn//PPb25x88sk8+clP5oILLrjDY5RlSVmW7edzc3McccQRzM7OMjk5ucvnlEisFSd87lyk8GTaMqwyTKmw/Qw9UYEXZLlhuFCEUZWO22RxdV5qh6tl2BZTodMjZAhdtZWCBU1xcB/vBVpZhoM8+BZF7Y/MQidKx5gNpVw7WjO1CnEaS4wXm1iN5jZSeqyVKBXGZQD9hYItzwlbckd//HyKbo2NafUiFkOe8BycFUjpQ5G2mCEXVYjqENyh9iiR2FvMzc0xNTW1W39nNI9x7EfPRI11Vnwc2x/ys+dekH6/scLO0Pe+9z2e9KQn0e/3WVxcZP369Wzbto2xsTE2bdp0j4qht771rZx33nm87nVr5zI7PT3N8ccfz89+9jMe85jHACE6ZCknnXRSO0q7I4qioCiKNTunRGItOOpjFyAzhYrjM1Mprvlfr+fEz51LXengLyR86Ph4gS0lqrB4S0yrH43KvGtMEEORIgqDcQJrZFiPF4wKKCORuVuWcC+kxxiJ0i4UQoQAVmcluJgv5mW4j/DhMaRHCUemLZm2eA9Ft+a4T78VIT15JxRLCCgyQ2VU2HTxIz2Tj9EiFBY/DI7YspIce9E7+dnrkklj4sAj+peu6v6JwIrWqk4//XSe8pSnsHPnTrrdLpdffjnXXnstD3nIQ7j44ovv0TF27tzJM5/5zJU8/J2ysLDA1VdfzaGHHsrmzZs57LDDuOqqq5bd5ic/+UnyLUrc6znxc+fyqK+9hod/5XUc/9m3kI/VKB26MdaOQlEHO7roPGh8hv28dZTGBxG0txIZ88Oy7kgL1Oh+mkBUGTPHqqFmOMzICkO3VzE2OaQoaqRy0VU6FChaLx9ru2joCAQ/oqhHUHp0PyE8nbwO22kudIm0tqHgaUwchaesdZtn5r1AxaT75hxU7mB9hZiq8QeVmEMrjrvwnbv9e5JI3NtIDtRrx4qKoe9///u86lWvQkqJUoqyLDniiCN429vexutff8/cY5/5zGfyT//0Tyt5+JZXv/rVXHbZZWzdupVvf/vbPO1pT0MpxamnnooQgte85jW8+93v5jOf+Qw/+9nPOOuss/jxj3/Mi170olU9biKxO/iVf3w9R//N+dz/785hojtECcfcoIMUnl6nCjEX0qO1xUbvoWv/4DUIgvNzVhjUkiLFmtG2GAQH6fZPQQnoRuAcr5IeqV37GACd3KCVI8sM3U4dbhh12daMtEDex/X7RvisLTq3YcvMSKyROCsZlBnWSUyM4rBOtgUWhI6UNTGmY0nRhw/Xe0/oNmlHVhh0YZGZpdpYr/03JJFIHDCsaEyWZVnr1bNp0yauu+46TjrpJKamprj++uvv9H7vfve724+PPfZYzjrrLC6//HIe8IAHkGXZstvek1Hbz3/+c0499VS2b9/Oxo0becQjHsHll1/Oxo0bAXjFK17BcDjk9NNPZ8eOHTzwgQ/kK1/5Csccc8xKnnYisds44XPnolVOp1vhnKBf5SyWOeUwR0jHVGfAwqBAK4sxiq3PG21UDecKVMeGMZOPm2IxGLXJA1O5DQLqxl/IhzGYkE0kRziWjJ2lutYo5SjRjOUVUgaTRdWs4jcdm2aE5Ua+RzDSCMnMIuVoa2U4yGOHJ2yMaWWprKbZbgu5ZaKt2YrMUEch9+i4oj0P3+SqZbtm25FI7BekOdmasaJi6Jd/+Zf57ne/y3HHHcejH/1ozj77bLZt28ZHP/pRfumXfulO7/fOdy5vZY+Pj3PZZZdx2WWXLbteCHGPiqFPfOITd3ubM844Y5nPUCJxb6WuFfdZP8Mt8xNAI34GhKB2YUXdyzAmW8aSvLBw+/AOZ4cK1bE4K4IWKLMMnSDrGqqFHCHCGMtZgc6D/kdnti1kMm3JM4NDoKRD4iEP5zWsMnJtsU5QllkoSFQwa1TaBMuj2PkxbXCrQAiWFU1Nm9450QbBhi+EsZiNa/lKu9CJEiwphKLDdWZxIhmpJg5AVjvqSmOylhUVQ+eff35riHjeeefxvOc9j5e+9KUcd9xx/NVf/dWd3m+tVvITif2Nq55+NidfejbbF3vtdSEZPvzyH9Shc2qtbEdkLXHjy0WdjZAeHzfBIIibG8GzkJ56oJE7MzjUxKR5SZ4bKpPhpEcoR6eoo9B5VKQIGdborZMUmYmPORJQexeE2q2oWvplhVA411FyvfWyjfLwTuAZjct64yV5ZpB4FoZFO05rOlgimlIKCXiwLr2pJw48kgP12rGiP6f+x//4H/x//9//B4Qx2Ze+9CXm5ua44ooreOADH3iPjnHuuefS7/dvd/1gMODcc89dyWklEvssL7niuUD0B4rjI+9BR2HzsMradfaJ6cHt7m9rFVbhofUSQoCdCR0gU4a/e3QRUu0f+bD/bu+rtAsZY0s6NsZKqlpTG0VtFNYJbPQQqmrVdmdk9DxqOjkhIFbgaokpwznZOnS1hAgmikKGDlKjD2p0Rg1SO4yVZNLhEO2avlyytk/jG9l4KmnP5ksuWqPvRiKRONDYa73lN7/5zSwsLNzu+n6/n0wPEwcc73/IR7FOtmMhY4OJoZJR0KxsKIaM5Mrfus3PRzQ/bDRAInZ38MCY5erffT3q1hxBCFr1XnDZj49rC5MGpW27Nl9VmmE50vF5L1gcFAzKLBggxu6Pkj52sIKpozMqRHb4MDYT8byajbAgjI4O2T6Kr51stUdChedinYyvg0TH8wwdptFIrc0+Uy6ce+Y46mN37B+WSOyPpG2ytWNFxdDNN9/Mc5/7XA477DC01iilll3uCd77ZUaLDf/5n//J+vXrV3JaicQ+yzEXv6P92NqwNeX8qBuy2C8Yyyuu+V+339acXr8YwlGbzo4IRYYqbDt2uvqVr6SuNFkWt7yykCQ/EkDLtkAB2vHYMG5/NWaISoYxWZ5ZaqOQ0oUuUdwmU4UB4VGZa1fhi6IOeh8vQpfIi+hBRKtZaDPRmn+Fp7KKhYUuwyoL+iVtg+P1bdb6Rfy/rGNwtx0hJhL7M83P0mouCWCFmqHf//3f57rrruOss87i0EMPvcOi5s5Yt24dQgiEEBx//PHL7mutZWFhgZe85CUrOa1EYp/l6le/khM/dy4uui3nuQv5Yz6MhbR23HLj9B3e9/tPfgvHf/YtKOUwdqTR8U6gOobNl1zE1t9/HXZ7gTvUhET6PCbSWxndqEPYqo/jNXyI+xAyjKwaXVGjSyorjTFqmRZIKN+aNSJ8+zguFlqh0JGtvum2hO5R8CxCO8pKI2OHq+kQORuCaKXwbeyah+CArRwiSyKIRCKx66yoGPrmN7/Jv/7rv/KgBz1ol+/7rne9C+89L3zhC3nzm9/M1NRU+7U8z9m8eTOnnHLKSk4rkdinMSYIisd7JdZK6pgr1ilq+sMc3btzLx1TqtE2VxaKimtOfT33+9tzqKXn2d95CVtPez/HfPK8UOCUirwTssBE4xIdx04CcDG3LLhda4R07fl4HzbfhAiaIWMVWWapong73Gj0sWfU8bG1RGW3WcWPmiMhHI0QyDsBklgMhptJMSp0pHQ4J9u4DiHDaK0xmEwkDgSSgHrtWFExdMQRR7DCSDOe//znY4xBCMFjHvMYjjjiiBUdJ5HYn9j8l3+GmpSgwi9zKR0eRa9T0c1qykpT17f/cT3yr97GtS98LUW3xhiFJRQctp/x2998GcPBYQB87xf34fjPvAXvFIgQa6GUa4uK5l+I2uQY4OrqkGXmrcTWIhoqLjFybEJZw2Hbggrh21gPF1fqIeh7EB6dO+pBhtSWvGMxRmKNaj2IvFtuIeCdoKx1W7Q1Hanm48a4UWrHUX99AVlh+MnvnLW236RE4t5G8hlaM1akGXrXu97FGWecwdatW1f0oFprXvrSl94uqT6ROFApDhqE7stAM7N9HIBcW4yVzA1CEKO8jbHg5ksuQvdqTvjcudS1Ct2huKquejVDq8kKQ9GpqYeaameHa059PVf/brgEbdLycVXbHWq0OzoUP66W+FriatU6QQsRxNZCRDfqWAA1XaBG7BzW5+PnscBxTuCNaLfMgueRjaaLtLEjoxOL+qYmTeS2Wof4pi6VJ+sYtLYc/fHzSSQSiXvCioqhZz/72fzzP/8zxxxzDBMTE6xfv37Z5Z7w0Ic+lO9973srefhEYr/DWYnpZ2z5vTNpfrM3hUmzYeZvo7ORuR3FVMSujlShc+IqxQ2zUxx70DbqWqELC8XyYmp481j7OM3IK4i2HQLQmQ0F2jB2pKK5Y2OcGPRDo5T5ZvW/LjUu6oyUcsEbqVY4I9uMtXCfsOpvjGp1RFLFOA/l2vMC2qy1pSwzaWR0OyGakVn6Yyuxf5O2ydaOFY3J3vWud636gf/4j/+YV73qVfz85z/nIQ95CL1eb9nXTz755FU/RiKxr/DTZ76RzR96GwDrD1pgYVC0a/XehwLjmlOXb5KJmzrYDTXdyZphP3j52LqZR/llRoSmuoMtKwHlIGN6uo/zgtoolGwKFd86RgvhgyFi4wckfMw0C8WLj14/1kiEdMER2oaOkY8bcTK3rWjaWYHOLIw1cRoSlY20Pk0HSCrfWgHI6F8kpKetj+LGW7OU1gS7ehuul8qz+aMXsvW5yYE+sR+TRl1rgvArFf+skibbbClCiHbl3tp7hxBybm6OqakpZmdnmZyc3NunkzgAeNTXXsO2+R51rckygzHqLvUvJ37uXKqhXrYmLzNLp1sx2S2ZGxQYo6gG2e0Kg81/cTEbjtqJicVLbRTWSoq8pqwyXNt5Wv4XpKvDqrzMbTBbjOv8pgq6n6YY0rlpDRONGXWvbK1iDIhtA191ZlsxtBS+3ayTjXdSfOygZornEU0qPWHt31i17Ab1UONKxbUvfO0qviOJxD1nT/zOaB7jvn95NrLbWfFx3GDIdS8+N/1+Yxc6Q3Nzc+2LNTc3d5e3vScvaormSCTumO0LvVBIaEt/rgsLd+2d02p/llQLOrPUtWagLZm2GKuWGSy2eMH2a9chJyvWrVvEx4cqdFiJN1YiMh91QsGXxFay9QnyViA0rUu0awue0NWycUOuGak5IyC36NxQLuRBRxQNHG0cj+koIndWLdEfRSdqYgeoEWuHRTSk8MsKoeZ8dG4xwLGfeis/e9YbV/mdSSTuXax21JXGZCPucTG0bt06brzxRjZt2sT09PQdegvtSlfnyCOP3LUzTSQOEKTwdLKaW7euZ+tLX32Xt9380QtR2WjM5J0EHVbmO0XNwmKHTqcOYy17+5/Zrae9is0fvohr/tfr2fzhixibClEflVVBpxRX620dNDhNRwgnQEX3aG/jRlro4GSFWbYN1oirm1wxKT3VICPrGmwtwYHqWGylkB2PMUuKv8bGqCmE4jkJwuhOx6JNxAgT62ToFPlRwSS1w97RmDCR2NdJ22Rrxj0uhr7+9a+34uhvfOMba/LgV199Ne9617v40Y9+BMD97nc//vRP/5RjjjlmTY6fSOyL3C5u4y5QmWujMJr1cl9rrn7Baznhc+eCF5Qxl0xIz+YPvY2tL1g+Mtr6/NcBocvTFBvDUsaVeN86SVsjUbnD1hKhXVtcmUGGzCwuPkYz9oK4cVYqsq7BRz+jZj2+EVmj/ChS47adoGb0RxiHNbqjRpjtvWg/FsIv1zw1rtnatR2rRGL/ognpW839E7ALxdCjH/3oO/x4pXz5y1/mt37rt3jQgx7Ewx/+cAC+9a1vcf/7359LL72Uxz3ucat+jERif8cZgfcyuE47gcocdjB6g8uLmjwzLCx0kbnFZ3e+YSWWfK0ZR4m43dXkiIU8MxfNHW0rbjZVEF/LzC4rZHSM0KgHmu54STnMIbM4EzpNebcGEUTVzqrQ4Ypu0k1SPYRNN2DZqE9Go0VrIcssUgTReOOX1HSIEKFblUgkEnfGPS6G/uu//useH/SebIKdccYZnH766Vx44YW3u/51r3tdKoYSiXuAH2go7CjB3cHWP3wNEHyKFhcLqjILxohNsXEnhFFTiN9oOi6NwzSEAqXZMJMxNNYZhY+uz43HkXeCapi1wbFNsryxKngJOUFnvAJGfkFaO+o6iLV1Zls9UJtQ39x2iSbI2lHMh3MCxyjLzTMqhqTw1C51hhL7IWlMtmbc42LoQQ960LJtr7vinmiGfvSjH/GpT33qdte/8IUvXJPV/UTigCB3yGyUVq+WdHesE9EryGPqsApvyjv/kd/ye2fykH98A7Up2s0sH/U4Nm6HNWMwITzOKHAjI8UmjFVltk2qbz2KYlGCAOehGmpUFnyJlHbUtVq2Naakp+nleCfwiNZ3SSvb+g9ZI6lqRdGt2/P0QJGZWLiFEZqUac0+sR+SiqE14x7/ubRlyxauueYatmzZwmc/+1mOOuoo/uIv/oLvfe97fO973+Mv/uIvOOaYY/jsZz97j463ceNGvv/979/u+u9///ts2rTpHj+BROJAJu9VSOXQmUXly/8I+eFTzwmFwNJNrzsQUS9FMsooa8dMLDFzjB5BWocAVZRHFwaVuTgaC/dTOozSnFFLzBo9daVbA0YXizVbj8Td1gStkosr9k2HahTzEf7xTTBr9CMqB8EGQCkXx2Wyvd3S+yUSicQdcY87Q0u3v575zGfy7ne/myc96UntdSeffDJHHHEEZ511Fk996lPv9nh/+Id/yItf/GKuueYaHvawhwFBM3TRRRfxyle+cheeQiJxYPKgfziL8TFPWet2c6vuZ8tuM94bUhvVpsk7d+dbVUf99QWsXy/asZMQfvTX0pLCKHRqABEE3FJ6UBZnBVnHYKKYO8tNWMMnZIYZo4LeyMhw3+hH5GwwSmy6Wo0bdTB1dKN0eifQyrbnUdcK7wVFpwrWAc2pxg6RygxKxi1XCFtwicT+RLS7WNX9E8AKHaivvPJKjjrqqNtdf9RRR/HDH/7wHh3jrLPOYmJigre//e2ceeaZABx22GGcc845vPzlL1/JaSUSBwybP3ohRS9Dx06I1BYPuNtogqpao5VjbLzEWom5vnuHxzv2U2+l2zMYK9uNLaD9eBSMGnPDKgXCoxq9kPBo7UPArBTUQ0XZrOF7yGORJKXHS1DKhoJFuxCboULxpTNHri1V7Cg1rtKNcLqNDhFhBd8MFbX0QagdzRprq5AyCLCXPhd5F3qpRGJfJKXWrx0rKoZOOukkLrjgAj7wgQ+Q5zkAVVVxwQUXcNJJJ92jYwghOP300zn99NOZn58HYGJiYiWnk0jsdY56z9tBwC89cCuXPvI9u/8BfRgpmUqTFzVVFRyo3W38dAY3jEPmwIS/ILe+9vTbHWrzh95GNg7WSYQdZXs1q++2Dt2dZvNLePBZ0AQ1ERneCYqiZlhmowLKhRurLGSeKe0oF3NUbrGD8NZjVRBK5706HAtPbVRwsJa+FYY7G6I/GmPFsKXmWtfrIP42rR1As9GWaRvF20lAnUgk7pwVFUPvf//7ecpTnsLhhx/ebo7913/9F0IILr300l0+XiqCEvs6wgjcQRVXbrkPm6+5qPXu2W2Pp6JPj5FY3YSlAmr5n3pbT3vV3R5LdU2ryTFWhvrDiyB+jiv1Qo0KDFOPCq6mY6OUY1hlcdMLso6hHuqwzdV4FOmgG7Klbouo0Kb3rZDT+zCCawosET2JrFFAGKvp3EZxt0AXtnW5btbqrZVobVu9VB1NHN1wRW93icS9lySgXjNW9OfSQx/6UK655hre+ta3cvLJJ3PyySdz3nnncc011/DQhz70Hh3j5ptv5rnPfS6HHXYYWmuUUssuicQ+xcFDOr0KVQSfnGM/9dbd+nBC+rYzYo0CL3BG3HHkxt0ebHQfJV3rMRS+Rrsu75yIG2O0nSnv4pYYYXQVujJQlzoURrGoMaUOG202iLhFk65qR2O4NpXeN75DMna/FK6W2BgO24TECuHJMkPRqaPOaCSaXiq8FjHn7LaFYiKxz9NohlZzSQAr6AzVdc2JJ57IF77wBV784hev+IF///d/n+uuu46zzjqLQw899G7X9ROJezN5xyCloygcFHUwF9yN9HolZaXx2rXeOiDbyIt7yuaPXojKQ/FQaBO6K1ZSDzVFrwqeQf0MbyReeFytQgJ9rZDYcJ0TYbuMpnCSrbdQU7BJFSMxBKBdiPNwzcwtPKb3tCvz3oswnmuemhOojmnX+BvsEoPFRiekdCzo/FKtk0dmls3vv5itL7nriJNEInHgscvFUJZlDIfDVT/wN7/5Tf71X/+VBz3oQas+ViKxtzj6f7+DbFZQ3rdgYn2fYZm1epaj3vN2tvzJ3Y+pVsL8zeNk0yVSevLchO0r5RguFLt0nN7kkKoKbwOVUW2XpylQQqcpbHs5pyF2erwRkIUsNC9CERL8gRxeW6QSrceQgJhrpkYr7tGMMaSsOlRmMaUK479ahoLK0fauZW7bIgtG47k2m7aJDhGjOA8lfashEj6EtlbdJKJO7D8Iv6yxu6L7JwIrGpOddtppXHTRRRizcov7I444Ap+k7In9gOroIflEhfOCLAs/E0J6WFfxqK+9ZkXH3Pzet3PS59/M0X9z/h1+fesfvob7rJ9ZtmU1XCjY+rxd1yo1uhzvRChqhCfr1tg6jKjC8QnvnG60VSakJ8tN6MDEMRqEmAzvm9y06Aat4rv20h/55pgsGYuVOozSotM0ViCkC9qgKjpexwLHmmCw2IzChAgu1TLGhjgvQnHmBVK64MKdSOxP+DW4JIAVCqi/+93v8rWvfY1/+qd/4gEPeAC9Xm/Z1z/3uc/d7THe9a53ccYZZ/B//s//YfPmzSs5jURir7D5kotQHcvVv/t68iMWcD743zRhodCMZRzX3bCBze+7mPvf/zp+8LPDufaFr72bowfUhrKNqrgzMmVR0rGwbYxrX3TPjntbTGPKKIIGyFYKIT26CB0UqYK5ohNxTZ6wCt/cVmlHltk2ad57QZ4ZPBpnaTfRlHTtZhiEQikk1o80Q7ow7ZisHugQChtHa9VihlBxjzgumcnoVk382DmBqRVauTawtRFPN4+xu4XticQeJfkMrRkrKoamp6d5xjOesaoHfvazn02/3+eYY45hbGyMLFtuFrdjx45VHT+RWGs2X3IR+URFd8q1oyXXCItFMBr0VrZCYBX1PEZ6fvDTw+/SBfmYT5yP92HjSXYM15z6+rCuv6660/t85dffuernpOTouTRCae8ElZGowrYanSaLTGYxrT6OuLwTODFKkpfSU9W61fzI6EQtVAhlrfrZyKlaORwSlQUH7cZTSKpQcHkPQobHE9KTdUwUY6vgUaRc6ABFEfdgmIdjuhBe69zS4jQUTJs/9Da2vmBlhWMikdh/WVEx9KEPfWjVD5zyxxL3djZ/+CKQnq3PPYPNf/ln6OkaJV07ijn+re+Ek6LY10jGuhVVrduOjrPhdlJ55HiNWRgV/M/89kvZNhxjdtilrDVFJ4iBXSwejvrrCxAbgmB5d/4CDwUDywq4qp+BE2SZpRpqnAnaoWK8oo6fh02xUUyG1na0SVbpdnTm/agdZI0KBVYdttBUbqOLdehCeS9Gm2CZi9tq0TZAhpyz1nsoHrVxyq5iB0jK0cis8RtqIjqE9IhkvJjYn0ir9WvGqow3br31Vq666ioATjjhBDZu3HiP7/v85z//Ht3uwgsv5CUveQnT09MrOcVEYsXobh1+8QMThyxgrAzbStJRG4k9rCaPQaN42Di+wPU71oGHLLMM6xyhDXlRA2C1ZvMlFyFnM9zUZmRhcaWiOzVs09VRLkRQNCOfbo2tFZs/ciFbn7e2IaPHfPI8sgyyGGpaDrPQ/Ykdm6oMHR6hPFkx0geqwmIr1Y7SnJU4wnG0cpTC423olOFHXkE6D4/j4nq+VB6lDVIsETpLWhfp0Xp/jAKJBZZUwXHa+VBsNcVn40tknWzX/JvxGTJ0wWy2i+t2icS9mVQMrRkrElAvLi7ywhe+kEMPPZRHPepRPOpRj+Kwww7jRS96Ef1+f01P8Pzzz08js8QeZ/NHLqTbqemMVRzzifMxVoZsrSUZXapjwup47I5cv2Nd8OERMVldunYyNpjvhA2sWgZX5o6l1yvpToXNzEzb9pe4NcE0MCsMWWZRmUUVlqP++oI1e35HfeyCtovSFkL1aMQnlWs7ON6FzTATs8Aajx9TqVCwxa6QsSo4Pbfhrg6dG7QedWOcDRlpQnrqgW4NHpt/ZcwVcyY8Do5QUImRG3UT+trJa6R01KVGCk/erdvXOxRX4eOlOi6dOkOJROIOWFEx9MpXvpLLLruMSy+9lJmZGWZmZvi7v/s7LrvsMl71qrVdJU4bZ4k9wf3+9hw+8JNHAqFjko/VbSyFVI7BXKft2HhoNS4NTWHRFAKDMkeqGDjqBRPTfdSYQYwZ/IaKqck+tsndimOeZgSndFhVr4e6FSZL6dtk97VAF5ZOUYcRn5XtsZviR2WOXizUGm0QXsT0+iXHySxVGZynMz0SXWcdQ94JnaIGAa3ZooxRHvUSN2vd5KtZGQsh0b5DNWv++VgdrQRkCKD1gk63ItO27QY1NNttjaB6sluu2euXSNwrSNtka8aKxmSf/exn+cxnPsOv//qvt9c96UlPotvt8qxnPYv3ve99a3V+icQe4aj1O7j4B4/jLf/yZ3TXW6R0DIY5WWYwtWJsahAiIHzoVsioXRllaDX+NvGAPvwyNts6yOkK1XNkhcFUGpVZylq3RYWLozcALUN8hBSevGMoBxl4mJgatGvuq+Uh//gGtM6xLhZCzRp7EzxGPPdmOy56CyltYxZYiNNQ7ZhMkOXB48d6QR7X7ZvjtGvvLoisWzuApsDLQtemSaEXMhgMCeXwRoaCKI7XjAivn2yP2TwHMVrpv415ilaO2ij6VbasgE0k9nnSNtmasaLOUL/f5+CDD77d9Zs2bVrzMVkisbu53+vfyTXbN3CfdTNMHzLX/rGk4+hKaYcQUGRhLGatpP7/2fvyMLuqKvt1zrnTG6oqAwkBDCRhFARUUBpFWhtFgcaJnyhNO7Vt24q0QoMgMoRBgiigtt3aNiqg0ogIjoiiIoM4tAyiMgcigiAhSU3vvTuc4ffHOfvc+yoJVCqVkIS7vu99qXrDfffd+1Jn3b3XXisPwIVBMR7Zio7iNoICAAyQdyKEv28BgYujUNw6ObtCidYMYaC8H45yQmbAvo8BkPVCLNjmKTTamWs/Tc/nHR1vOOLAEATKTr0JAx6ocvTdVcHAAOOCUInEhJF0Y+7MiqJDBSm5S7y3/9pqjH2+4AZScUShy0Bz2h+qHjGXQK8lRxgqK9imLLRA21aZe51WdpoMgLcy4M5c0Rj0HUdCVjjzR2bQbOTY4eJPTs+BrFHjOYYlS5bgJS95CQYGBjB37ly88Y1v9LphwhNPPIG3v/3tmDdvHlqtFl784hfjW9/6Vt9zVq5ciaOPPhqDg4OYMWMG3vOe92B8fHxjfpTVMCUytP/+++OMM87oc6Lu9Xo488wzsf/++0/bztWosTHQna/AuUEzKNBwIuCtB8eQ54F3NJaKIysCyDxw7SIrdEbObZsI6MvzQsdVcULb2tGueqElh1a2PUYJ74GgaSr7Eu00NADw+PAQ8jywae3TBKrcaMOQZ6ELUVV+Sos53Y4sLNFhofLBsNSKEqFyFRz48XvSVHGnQ+LucfIyosoac6aIshDeMFEIjSCybTIwIIisizcPNcDRl2BPouk+/ZYzVySYNVzxas1tpaoWUdfYQkAO1OtzWxfceOONOOaYY/CrX/0K119/PYqiwMEHH4xOp+Of8453vAP33Xcfvvvd7+L3v/893vzmN+PII4/EHXfc4Z9z9NFH449//COuv/56fP/738dNN920TvFejzzyyBolNMYYPPLII+v2oRymRIY+85nP4Be/+AWe97zn4aCDDsJBBx2E+fPn49Zbb8VnPvOZKe3IVLB48WIwxvpuu+22m3/8la985WqP/+u//utG278amzYO/OmJ2O3qszCw3RhCN52UBAXCQOEvw0OYMdhFIDQacQ7BNWQuXNaW88BhBmIoRxBJyEyAB25Bd1oX86IxOwnlWkVJK0fYkFDV1HdmILjxbTL6/03/zYtC2KqNm9BaX+z4jY/7qTg7Js88cWC8rP4YzRC4Kg0YbIsqE6VDNT0GqwOyVR3pNVCkHyLdFY3dc649oQpj2UdoKGONRv2DWEFlwgumeVV/VHkdgV5PRI8xlCGy3HoSFdJmq9WosUVgI2uGrrvuOrzrXe/CHnvsgb333huXXHIJHnnkEdx2223+ObfeeiuOPfZYvPSlL8WiRYtw6qmnYsaMGf4599xzD6677jpcfPHF2G+//XDAAQfgP/7jP3DFFVfgL3/5y6T2Y+HChVi+fPlq969cuRILFy5ctw/lMCXN0Ate8AI88MAD+PrXv457770XAHDUUUfh6KOPRqPRmNKOrA2veMUrnnabe+yxB37yk5/434Og/yO9973vxVlnneV/bzab07p/NTZvpCMJ4ITCXRmiFeaQhmNsPIFJGGa3OkhlCKkEgkj5kXBjGLKRGGE7BwOQtHI/DZYXAnwoR7qiAUMhqs6nUEnuU9QDobwfTiOW6GUhGLPtHwAwisFwO2FlAIAbLPjqeVj29vUYsXdVJ+lIDg8MtCwF1EGkrF4oDaAY/Eg7fQaZC7DY+BYaVYdE4FpiztOnERboFSGMKCs2WnNHOi1h4UDFD4jG5xmCyI3bA7YdB4A5HmjcH3BZCIRuMoxIDhHKKhgzXkNkq3AaMqgrQzVqVDE6Otr3exzHiONnzjkcGRkBAMyaNcvf97KXvQzf+MY3cNhhh2HGjBm48sorkaap1xj/8pe/xIwZM7Dvvvv617z61a8G5xy//vWv8aY3vekZ39cYs8Zw9/HxcSRJ8oyvXxOm7DPUbDbx3ve+d6ovx+23344wDLHnnnsCAL7zne/gK1/5CnbffXcsXrwYUWRTv6+99tqn3U4QBJg3b97T7ufTPV7juYs/LZsD0ZCIQom8CLCy28RK2EmwJCnQjHKkMoTSzLbMhIYBcyGgGtFAbmMpWJnvBVhCAQB8tvQ8IgqUFSQ70bDRlugAlgTkxZr/KzJuiZDg1sF5qiLqBZedBwAIGxpScpvfFUhnjCi8R08VNl9Mlb5AQel/FIaujSXK8XwyWCyUwFga97WzrH5Ie22PDVGd8Fkr02BaO1G0cIn3RUkQeaARRdb3SLtpOPqZKkFEjGjfSEQNAM1Gtv6kskaNLQjz58/v+/2MM87A4sWLn/Y1Wmt8+MMfxstf/nK84AUv8PdfeeWVeOtb34rZs2cjCAI0m01cc8012GmnnQBYTdHcuXP7thUEAWbNmoUnnnjiad/z+OOPBwAwxnDaaaf1FTeUUvj1r3895fD3KZOhpUuX4tOf/jTuueceALZC82//9m/YcccdJ/X6973vfTj55JOx55574qGHHsLb3vY2vOlNb8I3v/lNdLvdSTtUP/DAA9h2222RJAn2339/LFmyBNtvv71//Otf/zq+9rWvYd68eTj88MNXO4ATkWUZsqwcwZ3ImGtsGdjxwgvBt1ZoD6Tg3GBGq4eZjS4eHZ6BgWaKua1xjOUxGmGOx4eHfJAp6WpoAab4B2aAwXaG8V7sSQWN1QMAhWrYqlDp50PhogB8i8lHTLiYiiINoEONMJRQct3J0ILLzkPczr2mSUkBzpXN93KC8CBSvn3Hhc1Vq5bQjWbWhyiwwml6iEiHRkk8ijzwn8EYKxS3RMe+fxgoSyhdC606cWbbjy7bDXCVJVsZEoGC4i6igzRJbl+IBGnD7Ouc87RUAoFQ4DBIQglVaQnWqLG5o5J1POXXA8Cf//xnDA4O+vsnUxU65phj8Ic//AG33HJL3/2nnXYahoeH8ZOf/ARbbbUVvv3tb+PII4/EzTff7IsfUwXpjowx+P3vf++LJgAQRRH23ntvnHDCCVPa9pTI0I9+9CO8/vWvxwtf+EK8/OUvBwD84he/wH//93/je9/7Hl7zmtc84zbuv/9+z+C++c1v4sADD8Tll1+OX/ziF3jb2942KTK033774ZJLLsGuu+6Kxx9/HGeeeSZe8YpX4A9/+AMGBgbwD//wD9hhhx2w7bbb4q677sJJJ52E++6772mDZJcsWYIzzzxzUsehxuaJt/7yXzHr+bMwnsaY0x5H5ATMAdPYbasncedj26GbRlgweyX+MjpoKymuXUMRG0oKO2pe+WukDUMcSvTS0D6H/HLcmD1NbWlpXGXI/qcWbhrKEizttS9Jw1IoyYHtZg1j+XjbBpeuI1pDqSUcgUbmxN6yEEgauW9NcWYgdUnywti2qvIs9KJnMjwkBIH2wayMGWjNkZODtWtJkWYoFBrKdaeI9Bl3vAAbqEr3ca4hIWzrDORP5KptFaNIXXGaJlA1ijODQCgIblt2dJ9wk3thIuvqUI3NH9M0Wj84ONhHhp4JH/zgB73w+XnPe56/f+nSpfjc5z6HP/zhD9hjjz0AAHvvvTduvvlm/Od//ie+8IUvYN68eXjyySf7tielxMqVK5+xi3PDDTcAAN797nfjM5/5zDrt8zNhSmTo5JNPxnHHHYfzzjtvtftPOumkSZEhYwy0tn8df/KTn+Dv//7vAdhy3VNPPTWp/TjkkEP8z3vttRf2228/7LDDDrjyyivxnve8p0+dvueee2KbbbbBQQcdhKVLl661gvXRj37Ul+IAWxmaWEKssXkj4AqdLLLtE67BYaBhF8tHx4cghLatMyWQ5pbYGM2gFbdTVG6aioTRtGL3shBRoPzYOpzeRoS6r43GuH0+q1Yz3Ig4gXMrmqbMrSfH2pYohAoLv7YED//jRyf9eXvdCI2mJVZCaLDQja0ziqhQ1vzQhZnaNpb2E2z289qsMEsEufdXSqLCPceKlI0O7OScswzgsJUgmpqj8FTBjY000cxXb6iK5gXdrGI6DesXpDTz5JGOTyTKlhh5NNE5EMyer9Cd50wFiAKJRmxz1mrUqDF5GGNw7LHH4pprrsHPf/7z1cTKZK3Def+whxDCr/f7778/hoeHcdttt2GfffYBAPzsZz+D1hr77bffpPZjYj7q6Ogofvazn2G33XbrG6JaF0xpPOWee+7Be97zntXu/6d/+ifcfffdk9rGvvvui3POOQdf/epXceONN+Kwww4DADz88MNr9DCaDGbMmIFddtkFDz744BofpwO9tscBWx4klryubLnG5oGv7/c/6D42gNkDHSRColPYUqs2DCPdBM0kh1QCqQz9ok8EKIls5AMRIb+Au+T0rAj887kbF2eO2BjNIJ32CIAnJFZIbXw7ibubdloXVdjpL5/ovo6j4WZFf8k7DqUf52fM+OoM2QVwbrxrswgV4kbRZ6JIr6N2FwWsArYFpwrKNQO63RjDT7Ux+lQbWR6il4bWADGNMDbSQOycowHrESQqE2OFFN5Q0T7OXPVJoJACWW7jPJRm9vci8L5D9PkKbSfgtGHIlM1ak0pAa+61XTVqbLbYyNNkxxxzDL72ta/h8ssvx8DAAJ544gk88cQT6PV6AIDddtsNO+20E973vvfhN7/5DZYuXYoLLrgA119/Pd74xjcCAJ7//Ofjda97Hd773vfiN7/5DX7xi1/ggx/8IN72trdh2223ndR+HHnkkfjc5z4HwNr67LvvvjjyyCOx5557ruZpNFlMiQzNmTMHd95552r333nnnasJo9aGT3/607j99tvxwQ9+EB/72Me8uOqqq67Cy172sqnsFsbHx7F06VJss802a3yc9nltj9d47mDZMf+OJ4cH8PCqWX1TSHMHxrHdwAiaUY4nVgxZvYp7jDHjU+lpDJ38b7iwERpG2wR731qqVLCro9/9sRH9/w1LDZHVwojQEhNa6MW6TkMRUVF2gsz6G5XvGQYKUSQhAo3IGUECthITBgqRG5kPIvs8LrSf5CLRM2NAlodgXEOELmzWMCx92ylY9s6TsOzdH8G9bz4dg+0USSQRRwWiRuE1PIIIozs2RBC5m04rj2H52SkTrTpib0mj3ZeCSJO0JEhpjkJzpDLwo/41amzW2Mhk6POf/zxGRkbwyle+Ettss42/feMb3wAAhGGIa6+9FnPmzMHhhx+OvfbaC5dddhkuvfRSHHrooX47X//617HbbrvhoIMOwqGHHooDDjgAX/ziFye9HzfddBNe8Qobn3TNNdfAGIPh4WF89rOfxTnnnLNuH8phSnXi9773vfiXf/kXPPTQQ564/OIXv8AnPvGJvhbT02GvvfbC73//+9Xu/+QnPwkhJqeLOOGEE3D44Ydjhx12wF/+8hecccYZEELgqKOOwtKlS3H55Zfj0EMPxezZs3HXXXfhuOOOw4EHHoi99tpr8h+2xhaLbWaNIOQKo2mCdpxhMMrQCAtwZrBVq4OVI21rkigMZGE9hrTiNpfMOHdms/oUFnckyY+lU+yGsZEWFHZqfy7FvFVvHGoHMWbQbGZQuiKuNmydUuwfPvbfscd3Fvtx/jy31SutGbSrnNDEVdXMUCo7Ci+VsO+rGMLAwDjRc7WtlxcCBvC5YTTuXsWCy87D7DkleWk6zZIQ2uu20jxAIDSyIiiPk9sv42JLGADh2mrVViNDSSSFE4ZrbR2oqa0WCYXQEcvU6adq1KgxOUwmK3TnnXd+xurMrFmzcPnll095P0ZGRvw4/3XXXYcjjjgCzWYThx12GE488cQpbXNKZOi0007DwMAALrjgAnz0o1a7sO2222Lx4sX4t3/7t0lvZ3h4GFdddRWWLl2KE088EbNmzcLdd9+NrbfeGtttt90zvv7RRx/FUUcdhRUrVmDOnDk44IAD8Ktf/Qpz5sxBmqb4yU9+gk9/+tPodDqYP38+jjjiCJx66qlT+cg1tjAsuOQT2HPHFMu7bWgwNIMCT/VaEFzjL73EjoIzA8aZH2dXzgCRgk3DRNqcMhLxMgPNbGWIk3+OY0LSVYtEoMFQalqCSsuMWmMA+gJOtWF91Q/ODIJErtPn9VUmbiMplOZQypIW4Uwki0KAcds2o1wyaoFx7mIvNIMIlW+RAbadFQYKUgpII3yLqnrVueCr52FoVsfqqkLlJ8c0mK8GlSP4Th+kOKRhGGikGOslEEIhEBppHkIr4UTSlnRR+5FxK9iOAgXpjpVxAvZ2I4PSHL0iRCvK64myGps9puIiPfH1myPmz5+PX/7yl5g1axauu+46XHHFFQCAVatWbVyfIcYYjjvuOBx33HEYGxsDAAwMDKzTNu666y4cdNBBmDFjBpYtW4b3vve9mDVrFq6++mo88sgjuOyyy55xG3QA1oT58+fjxhtvXKd9qvHcQWMoxR8f3QaDgz0UUuDPcgY63Rjzt1qFmY0enhgZtO0oV9mx7tPGh5WK2LbFqguq0s6PxwmuDazGRxbCewvR9AaLpF/4q9NVgG0FxYFCLw+9TsYAvkrCmEEcSyz633MRxhL3vfn0Z/y83dEEzcHUkq1K9YSEy3RLwsKPwwO2hRcIDTjSQRNzVJHJi8DvO+cGcVSg040hAo18vBx7nTV7HFkRIAoVQq4cCWJI8wBhoJDJAIFziSYBt1IcUSShDPe8qnqsyhadQdLILZkjkTqzrt5RqPy4flYEyKT9k9cr6tDWGlsAptDqWu31myE+/OEP4+ijj0a73cb222/vDR1vuummKY/vT0kz9PDDD+OBBx4AYEkQEaEHHngAy5Ytm9Q2jj/+eLz73e/GAw880MfkDj30UNx0001T2a0aNSaF/X9s20si0BjvxNCaodNJIITGn5+aiUeenIU8DazvjhtnInGxMcznjDHYhznXvqJDLTGqRmhlJ7AoeJSMDEmPA6BCJkgbhH4tjfPV8WnvzOp8aPR+pyufuUd+8O73QLhJMaoShYHCQGI9tWgMnoTIADz56aVRn3khEQ4iP2GgoFx6/MijQ3jwyFNx35tPx7J3neTfn46PUhzaHSTtt2fzy9LCiq5z1yIT7nineeBH6Wm6brVxekcUqY3GufFTbKQd0ij3P3VeSGRGWaNGjc0HH/jAB/CrX/0KX/7yl3Hrrbf66bVFixbh4x//+JS2OaXK0Lve9S780z/9E3beeee++3/961/j4osvxs9//vNn3Mb//d//4b//+79Xu3+77bZ7RhfKGjXWB53MViyCQEG5nK6kkSPLAgwN9LBqVcvmjHmRMEqzRWlT7I0z+2Puca1W19EA9v4gkmCMQXOrN6q2bmj8nBZ3u7ADAK9UOWw1RmmGogiQxAXyQkAq157Kn/m/8Rf3vRTPv+ZMv02lGXIZ4s7DzsbzrznTkqu4gCQ3Z5f+rhSHKjg6D8+C3DrHwMxun0Fiuc8cxcoEy/51dcOzPz+2DbS2bvXaWHISBxLSlKP85MtE2+NcA9r6O+VSAMYWtGjkn/yL2kHWV7GyhNNGoogKeQyEdQD3btQgQXtdHaqxGeM5VBlamx755ptvXu2+qQxhTYkM3XHHHd5ssYq/+Zu/wQc/+MFJbSOO4zW6O99///2YM2fOVHarRo1JgXPjJ6SGminG0hiBUEhNiKwIMHNmB2OdxC+T0hEgwUlfYxdrmshSinx3nBuzZjCKOX8h7SIvmM80Y8xVf5wg2AqVy4R3qmiQkSHlbvWJhd0CDwBmksNl97zpDOzxncUAbNXn/iNO8/c//5oznXki/Ig/3OfkgcaDHzkOiz5zIfhs+2adboxmo3Rqz7ohlr1vzc6vf3vTsRgY6NnWlxNrF9qSufLz26BcwaiiUyGDAMDL8XvOjB/xT4sQYaBQSIGBJANjBk+NtsG58bonUdFnScWcwSOcwHszWg1q1JiA55JmqJp6/3RYU2bZZDBlzRBphaoYGRmBUpPz7nj961+Ps846C1deeaXf5iOPPIKTTjoJRxxxxFR2q0aNZ8Siz14APdRGa0YPYWDNFwuKoeAGRSGwYOZKjHWs39DoeAKjOZQEWFAOh1V1PIxbLRERGBEY8ND43/OedXEOEzuWztxiHkwIMbUantJAECjFyQAJp3MfYcErafeTRZYFaCQFYGyC/dK3fgyAJUQ7XXkOWk1LcIiokBcSADz0oeOx53fP6Btv15qj04nXagK5y7kXobFH7qfTAPhJNqoEEVmpfhalbTmOJuq83xMsGWw2cuSF8M8LhMZoL0Hbtf1o28xP5tnthoFCpxf78X0ZTC3rrUaNGhsX5D69oTAlzdCBBx6IJUuW9BEfpRSWLFmCAw44YFLbuOCCCzA+Po65c+ei1+vhb//2b7HTTjthYGBgyj2/GjXWhj1OvggH3XA8wud10JrRg1IcvSy0Oh0nJNaaYeGcFXiiMwBVcIw7IXAQSahCoCiEb4f5Ca/KeH0QlE7TdMElC+ENGpkTVksl+kbAk0h64XDZGrOvJ6JWrQytNt26DhdCDx55KnIpEARqNRv/B488FWke+sk2wBkdqvLPxOiTbfRcm7GQAlJxPHTUKWt9v2D3EfQ6EQop+qbnlKZptXJajlpf/tg4p2ljGMJQebIkuPZeSVpzO8WmuI3xqJAgIm3UVgPgHMUt6UwiiSBW2OHL50/+ANaosSnBO92vx60GgClWhj7xiU/gwAMPxK677uqNj26++WZviT0ZDA0N4frrr8ctt9yCu+66C+Pj43jxi1+MV7/61VPZpRo1nha7vf4B5Ep43jB/1io8MTqIQGgEIrf5VZrjTytmodXI0B5IXVuFY3w8sdUfoVFkdnoqrIy2U4BrnyO1m64yxoA3pA96DUNpyZDiUFyDMQbDygoQ6XG0thNdA+0Uyomwrc7ILv5NJ54upHhaMrImZCMJGjN6a6yR3/fm07HjNz6OVjNDXthJLy3LP5h/+ufJe3i85ufHQcpZiBKJPk2UI1vVv8PaMD8uzytRIJwZBC7yAwB6qbBM0aB05Obki2RfQ5U0AK4qVAqx6ZwSkRNcQzTWzaagRo1NBs8hzdCGxpTI0O6774677roLn/vc5/C73/0OjUYD73jHO/DBD37QGyFNFgcccAD23XdfxHE85V5fjRpPh4VfW4KhmbMRcoWZ7S5WjjexotvypntKM3TTCFEoIQTDyFgDRnO02z1r2FcIgBmIpIBo5n4KiipEWjNwRnERzKeuU/UDDC6KQ3hBtQjKKapA2ADVoNJC66URkoEuwLU3YQTg3a9pPH2s11jn47Hs3R/B7t9evFYna9kJwVopAKxG/CaLHS+4EOHCmQjdaDtVeQB47ZAlhQxBoMuUeysQcg7UdlucGavh4gZhaCfgRrqJ3UYh3LG0LcPcTcIx50HUiGXpqcQrAa+OIGnDECcFdrziXCx927qRyho1nm08lzRDGxpTapMB1mTx3HPPxQ9+8ANcddVVOP3001cjQh/4wAfWGrqqtcbZZ5+N7bbbDu12Gw8//DAAa+j4pS99aaq7VaNGH3b5+EWYOasDrRm2HxqG0hzbz1pl/W1CCc4tEYkjiSwP+6owhRSIAgVoAIYhS0OflSXdFJpWHEZza8zogk5V4TQ9ThOkZPnfjHLJAPgxemoRja5qwhg75p+PxMiVdYdWuvQBCgOFRlwgVwKr7p8NOW4J3W5Xn4UFl35iUsdkwRc+5eMvFn59yWqP/+mfPoI0J6JYZoOtC5b++/GQkntjRM6tlQDn2ofQCq49kanmkFHsCWBbgkozNBJbCZvd7qAR5mUyvZvOI4IVVHRXdMxIbE0WCCRMp7bdUDOFcAG4NWrUeG5iymRoMvja1762xokxADjnnHNwySWX4Pzzz0cUleZsL3jBC3DxxRdvyN2q8RzC/R87zi+uj40NQWqOJ8fb0Jo7Qz6GIFR+PFtrq08JYxsr0e1FADfgoSorKZWrKWMAVDK0yIeIWjfMOTczZhDG0hMkepzcqzk3WPaOk3HX4Wdh6dtOQXN212+fFvWgktM1sqoFNq+HeEaKXb51tvXYiSc3vBA9VWqW2FouDbMVDaSdCIJrPPCWqbm2t5pZRQ8E7yGknL6HO7drIjZhqPyxIkJKCAPrel0ogVwFXkhtozl0+bgUnjwClkjxivbIu4WjNGYkrE0EXqPGJouNnE22JWODkqGnyzG57LLL8MUvfhFHH310XxbZ3nvvjXvvvXdD7laN5xi2bY9iq8FxjPZi7+hM2VlScShpKznCLdCCl9UFC1dZcK0cgtHMuVLbCoeB9RXyqfSaefF0ZTP2fSoLMlCGuBIaceEXanpOVgRI8wCFFEhaOeK4QBgqDDV7CIRCGMlJVTfuP/U43+Jbq/haMSAVuOvws55xe2vCsbcfjV4WuWOqfassDBTSLHTGilbQbJ2ipTeEZAxoxbmv3hjnTRQIhVjYlh1N6hnYyTEyVsyzwGavVaJNkkD6Y6lddY0IFyEMFBZ88ZNT+qw1ajxrMGWrbCq3mgyV2KBk6Onw2GOP+aT6KrTWKIpiDa+oUWNqmBV3sfuMv6IRFzYI1bVsSN8TBGVbpRowqrUd4WbCxnJIN9klC4EiLeV2VBECnLu0q9BQqj0t6PQe3LlK04JMAayEHa841z+X/qWFPXJTVUm8+v+RKJTgweT+ullvpLW3v5b96wlAvG5j+1X8x4u/bt/HTXzZ1HibHK9k2aJqxDmSiLLQaMweSIvAP58guMHKbhMhVwgChTmD46tFaohAgwvjfZgYgxXOV8gPCa0JPScUn7HdKBZ89TzsdvXUCGCNGjU2X0xJQD0d2H333XHzzTdjhx126Lv/qquuwote9KJnaa9qbIm49KVWg/amXxyD+5bPAWNA76FBsG17EIGGzATiRoHecIK2a09p5x+UZqGN4wg1tOSAW0e14tZUkQwAGXwbK5eiEstRyR0zpcdOrgMnwsZqLSFVcJdSX7bIjLFEaHazg1SGGM+iMkJDl4s7F5MjMPf/v9Oe8TnL3nHSMz5nbdjxUxeitWvR9/mrxCYKpf/cnTRy5MiKwpUzRbQaKVsJIrE55wZPjrUhuMF4FmOglaKbRt6MsZHknjxKJbzfUBgotJMMeSEcUbLHbkazh9E0QTvObKr9HIXh8QYWXHYemDB4+OiPYoeLPwnR5Xjo3/59ysejRo0NgnqabNrwrJGh008/He985zvx2GOPQWuNq6++Gvfddx8uu+wyfP/733+2dqvGFoxrXv6ffb/v8q2zwZnBQ/9wChZ99gKwgTIrDAC0FF78zBgQRAqyEJ5w6IqnDWCrLZzyxoCyjUMkgMG3x0jHwgGkWYC0U+rmWoMpsjxEHBV94uWQ221HQiISAspYTx5R8dcJAoVF/3vuOo/bTzfMdnYajT4j7adx01tKc6S5QBIVMJohCGwVpygEkrjwjt192zQMgisAwuehjfdia8jIDFigfYWJjjMq5LBXWFE46YYGEqtpakU5YiHBmcFomqCR5Pb8aIYdvnw+eEMB3Qg1amxyqMnQtOFZa5O94Q1vwPe+9z385Cc/QavVwumnn4577rkH3/ve9/Ca17zm2dqtGs8hyEzgXpf43thhDOgKv4hKJey0mdAQkYIQNkWd9EFhLP1cKk1HGaBssblKiEEZ2lrVsVBYKmM2k2vZ20/GDhd/Evv88GPIXYgoVVUAW9mIAoVOHmM8o0kzK/gmo0RKcN8UULYH7e80fdeICsSR9PdnReCfSyJqijuhLDGaCAsDBQ6rO+plISJhjwkZWgLweWS2xVYSSRLHE7izJwiYRjuypGhlr4m8sNqjKJRWSN/OEUQKekaBhV9bgp0+eeHGOYA1atTYqNigZOgf//EfMTg4uNr9UkqcddZZWLhwIa6//no8+eST6Ha7uOWWW3DwwQdvyF2qUcPjoX8oqyeFFGhuN+Zzv2CsiJcL4zQoJcmg3NYgtCSJxrXdy6xxYIWYqEIAbvKJ7qfUemMY8rEIO115DnhDYuXKNoJA+fDSqiO10hzdPIRGOWofCI2iEH4UHbDC7QVfeXZdleO48PEinGs04gKcGXSyyHv+xKGE0QyROw7MHTc/+eXyxcjKQCqOQpcBrGO9BElYIAiU120pbdttVFHzlThm0IpzpxtzuiRpK0W5m1DLi8C356Sy3kRBoBFFEiLSMIUAUww7L7no2TmoNWpMwPqIp9fXo2hLw5TJ0M0334x//Md/xP7774/HHnsMAPDVr34Vt9xyi3/O5z//eWy11VarvTYIApx//vmQsnZ+rfHsYtFnL8CuV5+FfDzy3juFFBBCl+0WA0gpbMBrJFervpAmhogQ4BLp3aRaECmIUFWe3//aoCkhnbO1KTiiULrcMvucMFCIhPK+QxRASpUmIaxpoc0TK6skzyYoa4w8fcbGGlCaIcsCJKEVf9uwW0tgqBJmx+LLEFsAvsJD5omkHRJCI1cC7SQvz4FhyPLQ/y4V967WsZBohKXwnDEDaSzBolYmEVRRIaLGACJQYJGCSgxUw2Dn82pCVKPGloQpkaFvfetbeO1rX4tGo4E77rgDWWbDEUdGRnDuuedOahsHHXQQbrzxxqm8fY0a0wfNkK1oOMNEO0mmpCUbo93EB4pqxVGsSLzvD4C+SpDBhCn1CQLqqrdN4rRAyrXOkkaO1mCKuFGABaUPkXYLNOltqOpBZIoqJIHQSHuR334QKfD42b3QYMwgze0IvVQcYWRjSLgw6OaRjx3hwqbK0wh+Etn9JiIYOFJa3S611JTiiAPlzlOp36qSVZog05pjLI/RK6zTt+DGVdoijKUxekVgW5uKo9XIkIQFolCimdhqkhCuNTo3BeamKGbXF3I1amxJmJKA+pxzzsEXvvAFvOMd78AVV1zh73/5y1+Oc845Z1LbOOSQQ3DyySfj97//PfbZZx+0Wq2+x1//+tdPZddq1Jg0FnzlfIh5Ekkk3ag99y7J5C6tFYcqOHigAWGQZSGiyE5CKcW9+R9AE2jw496Mmz43ZFrIyVuH7qMsLWOAxqwCAbcVjzBQvgrUzUNPfqiVR+9Lr7W6Gru9vBtuxCO5OpJIep2ONTc0CLiG1BwB1xjuNBCHEgPNFIIZ+3m5ckTJitENN7ZKZrQ3UqSKUVYEvvo0s93FSDdBIDS6vchbJZAIGtwSVtsGM16TpI2dNqOxezonSnNEYYFWlKMV5ljRa/nzODAzxfBoE6zOM6uxKaAWUE8bpkSG7rvvPhx44IGr3T80NITh4eFJbeMDH/gAAODCC1cXJDLGoNTk3HRr1JgqhuaMWWNAYRdXAH783RgGVXBvmigCDdOU3oW6KsZl7nfKKKM7SUfkRdMoq0fS6Wb8mwKe4IRCQbp2mI3DoJZYqUdCZbuMuVgKLyLW1jTxWcTth56DF197Kgyzn6uXhYhCiXacY+V4047BRwWMAaQbi1eGe0dqa75Y6oBs20pD5dzHbjSjvG9c30+SOVID0DbgW4dV76ZqeCxQvhfn9r5CC3QKW3HjXKMZSuRFYL8DhmHRZy7EQx86fiMe1Ro1+rG+up9aM1RiSm2yefPm4cEHH1zt/ltuuQWLFi2a1Da01mu91USoxobGHt9Z7BdE7ZyiZSZQZEHFE8gZJzoBddQokI9HvhVDf0dI8BsEuo/xUPuMtDNV80XSpFC7SHCDSCiEXKFXhL6FRq9F5b3oVnWxtlUo+/8mKwIse9fUPYKmC5008iaKnBs0owLjWYR2kqGZ5OjlIZThfgKPJsDIrZrIiXbEMC8CBEL5z93NI4ynkTNVtKRrRrvr88m0qybRtiYSICJcAErtEjdohLbqQ5qlXAkrdHettDiUCCNZE6EamwbMetxqeEyJDL33ve/Fhz70Ifz6178GYwx/+ctf8PWvfx0nnHAC3v/+90/3PtaoMe0IhM2xEi68k4wTYYC8E9q2CXkGuQBWoxl4pEp9ClAGhgaqL5WdJppMhdTQJBnpYUqCZLcTBRIarFLxgWvbmZK0GfSRIMDaAMiCjApLp+z1xfOvORN7fe907PKts6f0+vvefDoE035ybLjTQBwoTwRpfL6Qwo7YOxJJ1R3tiAxgYzuyPIDW3Gt7lKucpZltCWrNvMi8akmwJrsBXSGmQFlVkoojEAqtKAOHQSeP7DnmBlu1xy1RExpSciy47LwpHZcaNWpsephSm+zkk0+G1hoHHXQQut0uDjzwQMRxjBNOOAHHHnvspLbx2c9+do33M8aQJAl22mknHHjggX25ZTVqrC92uepsNBulS7F2k2NhqBCF0mZcFaVzMYEWxCBSkJIjDE3fhVUplHYLreaAQV81qNSrlBUhyuLizCArAtcW62/dEHmi7VC7jH4PhILRkSd3E3PO1gUv+eEpUIZjvBsjiR2RWJ8yPAMYjG9nGQMUxv5MGh7OrT0A7Ttnxjl6F5DKTtcRQSTtUNWzSQjtCGg5Ri8rWiCqAOlKS606ik+O1IHQGIxTdIsIjaCAdhYIjAGZFOgVkT9ncSxhDMPC/7gADx9bO1PXeJZQa4amDVMiQ4wxfOxjH8OJJ56IBx98EOPj49h9993RbrcnvY2LLroIy5cvR7fbxcyZMwEAq1atQrPZRLvdxpNPPolFixbhhhtuwPz586eymzU2Yxxy04fw1/EB3H7o5AT5k8HCry3BwFABrZkX4ALltNY2g6P486oZMJqDh7YdQw7UMICGSz0P3MSSqwqRzxD9XGSBm5QqxdOkY+GVlPRqBIfdRmkMSAu+rJAyO4rOQX/BBNNQWkAqgVYrc5483DtjTwWFFhjvxGgkRZ/fzlTxm9eda7VDjpDkSmCokSKXgReOZy7J3k6JaQRcQ1V8lAAShytHqixJ6aWRP8aFFH1kk8CZ8edNu0M/UYs02Ei9O3Unj1BogZG0AWOAua1xPD4+iDhQmNMcx+xGByt6LazKQwShQjZYC6lrPHuoNUPTh/UyXYyiCLvvvjte+tKXrhMRAoBzzz0XL3nJS/DAAw9gxYoVWLFiBe6//37st99++MxnPoNHHnkE8+bNw3HHHbc+u1hjM0UzKNAIC7zl1tXbri/8wWnY6RMX4YU/OA2v+tnkr8opQLWQNgZiqNlDEhdoJlaI+6cVswC4VlMmoDVDECqogkMWwgeb0mg26XkE17bDZhhkbgW2zWYGrXifLqU6Fg4AsWuBKfe8vAhciKs1CKxOoFFye1YEnsxpUFXDTsAFzqvn6QJYnwndNELozCQ5t58zDNdPw7fdwIhv+RVSYDyLkUqbzZZmIZS0zt6kocqVAIeB0syLyK1rNUNRCH88GknuJsBsG3NWu4solIhD6c6P9YxSirvKnq08xYF0QblALoUns0ozNCJrDik1RxQoPLRiNjpphOFOA8u7bTzw5Bys6jT8sWbB1MNsa9Soselg0pWhN7/5zZPe6NVXX/2Mzzn11FPxrW99CzvuuKO/b6eddsKnPvUpHHHEEXjooYdw/vnn44gjjpj0+9bYfPGqn/07xrMYI90G7j/iNKxMG+gVIR5YtRUO/OmJWD7axj1vOgMAMLyiDWxrgzUD3r8YveXW9+ObL/v8Gt9Da4Y0CzF7sINOZisA3V6EIFQIhIKUAgZWO2IAKCkQRhJhIiFzAaWtT07IbBhrdTxeO30QYINWe8blYFXytarp88YwJ8wtH+NuYWcMSKX9r8ncVJpyY//9ZoBlC430Nnke4OGjPzrl85CvTJDM7qGQwpsVSrl+Y/p/u9X9uHzsJVCu0kM6K+baYYxZOwKlOWJIGNeeUoZDMA3tFOnVCpXSDGFgyZo21n+JxvKrlgNUkSNRdvX4A0AcSnQrcSajaYKQKxRaIAmcW7XiCAKFVLroEG0nzcJQQbK6jV/jWUTdJps2TLoyNDQ05G+Dg4P46U9/it/+9rf+8dtuuw0//elPMTQ0NKntPf7442t0oJZS4oknngAAbLvtthgbG5vsLtbYzNGOM8wdGsMHbv9HdPIYkVBoxxk6uU0lP+AnH8E+P/wY9tnpT2gOpEjzAI8ND2HHK6zR5z//9l1Y3mth52+eg12vPgsvvvbUvu3zh5oYaKW28uC0JHFcQEmOPLcLXRIVCCM7Qs+4Rp7ZnLAwkUiauTc/pOWW07SXgRvFh/cnEmE5+UTVjCgoqyzWTdlmjNFov2/d6TKtvupFRESIs36SZcXEDGo9/IUWffpCxLN7iCOr1cmKAJ1ujCiS2OnKqbcrT3j+j9y+299peix0QnPhWl30GYMKyazGY0jFkcSFJzRZHkIqDq1ZmQnnRObkFyWV8O8tmBWx2+kzO32ntJ1SK6SA1hxZHvjIkOG04dtuUWgjUpTkEEIjjqStyNWVoRrPIqhNtj63GhaTrgx95Stf8T+fdNJJOPLII/GFL3zBC5yVUvjABz6wxiyyNeFVr3oV3ve+9+Hiiy/Gi170IgDAHXfcgfe///34u7/7OwDA73//eyxcuHDSH6bG5gvOSpHtSNHASDfBYCPFUJIjYBqdXoyAaQhmsHTV7D7xcRhJ7PKtsyGzXRAlEonLnxrvxQCAHa84F0YDbJFBIywwlsYIhPZeP43ELrBScXTdawgi0Pbiqa/dVba8aMFWUoAJWzUQoZ4Qv+EIDDdesEufmSo75EpN2iPjJpu0ERUiZO8Lg2ommts5AEoLLHv3R6Z0/He84ELw+V2fE0ZJ8DaXrSRpUwVjBhyAYWU+G02LaQ3/uTMZIA4klHs/8lzKiwBxJJHlVuuldallCtzxSfOSUHJuXLRGuQ/KUIxJqfUi0knTZaVlgUZeBF6nlBfCEysrcmcIA2CwneKwm/4NPzhwzQMhNWrU2DwwJc3Ql7/8ZZxwwgl9k15CCBx//PH48pe/PKltfOlLX8KsWbOwzz77II5jxHGMfffdF7NmzcKXvvQlAEC73cYFF1wwlV2ssZlhLEvQLSKMZzFu/8vzkEQFCi3wVLeFOY0OolBiu/YIAGC8E/e1TDjX1qxvPPSVGuNaJztecS6azQxJM0cUSawYa/lQU6rKUPo7UJonGgOv+dGKA8xGOmhnEEitK5oEE4GyYayOnNHiTkSIRsSJxJkJV2QTIzhIYxMI5fdJ6zJri7QyBFYVe08BwcJxtJqZ1dhobn2LAmUrXoojSYpn3sjTgMPqdwKhEYXSZqxp7jLgrE8SERLbCizzzQSzobbdNHKGi+UxIUsD8mqi42YMXPp86e6tXCuurNbBB+ZyZvxUGmmlSOzuI1CMa3uasiIoFcfdj2yzXsemRo0pY308hmqvoT5MaZpMSol7770Xu+66a9/99957L7SeXNl43rx5uP7663Hvvffi/vvvBwDsuuuufdt81ateNZXdq7GZ4fnXnIkwsOLhSCjkzAaOpnkAYwLcJ+dg19nL8VTa8gQgDBQyd+XOGNDpxBBDua+i2NgGg2bT5ubZxU2h24vRatLkldXYcGH62k6tZoZON0ZQqe5QFpZ2oaKATaMPhALcws24BhemzCurGCxyrm31iJ7rKxPc/z0KUBosUtWL2mT0cxLZKhYHfHWLCNSDR/a3BdcVWR66SghDEhVQ2ralCinwxzcsXq9tF1qgERU+doM7XQ4AL2oOuTWdrGqKuK968VKTxeznjSJpA3SF9r5RADzpEkK7n603VBRKK8x2o/3WjNH4ihDT5fQaESHG7HfSGAa4DiQRJ+5E1yJSWHDZeVj2jpPX6xjVqLHOqDVD04YpkaF3v/vdeM973oOlS5fipS99KQDg17/+Nc477zy8+93vXqdtLVq0CIwx7LjjjgiCKe1Ojc0cu819En8amelHrMkob7CRoZuH2HX2ciwbmYm95/wFI2kDg+0U3TRCElH6uYFop8jduDx32p+8CJAVAQTXkFIgDCXCUJatEc0RRTYhnqpFItDodGPbzwEqzzWYNdjFaNeGtWrNEUQSWRYiSQq3Xe72x47AU4UqK4LVDBepzUOp9qQpIqIlXEsNcMJrbRfsLAvQamZY+dQAlr1z+lymI9d6y/Iyv4vIX28sfuYNPAPyX8yCedlKBEKj0MKTT8E1eGi8UJrDIJMCsWvXScOhjK3mRJH0xzHNQ2RpiDgpyjF7Rzq1YUjCAt088iJ3ElIXhvcRLcXKahGN9wuhwSreUMrY+I/qyD5t17dZn+Vg3Bo1aqwfpsQ+PvWpT2HevHm44IIL8PjjjwMAttlmG5x44on493+f3Khzt9vFsccei0svvRQAcP/992PRokU49thjsd122+Hkk+urrOcKVqRNKCeCbSY5ACuundMcx5/ymfjT6ExoMETcLjidNPLkoUowYqe7MQaIhEIjLPDk8IAVKufCtmIUQ8GcUZ9ri0g3eu1H0itEiDx7RGS9b4ggwI20m6AMIyUS1Bf7gNWT1L3eyJk4UhVJG4aE20qXdC042jaRusF2ipHR5rRf0TFmkOWBr6gQpOLTUvGQLx6H0BwiUJAGALPnCAAMrBeQYJYI0Tm0o/XCH1vmdF3WS4mBC0tyleaeqCht881S5xtEOjRLgMrPRRUisiaoRqbQ8aj6UE2cRiMUbjSfM4MdrzgXS992ynofqxo1JovaZ2j6MCWRAeccH/nIR/DYY49heHgYw8PDeOyxx/CRj3xk0o7RH/3oR/G73/0OP//5z5Ekib//1a9+Nb7xjW9MZbdqbKbo5BHyIoDM7Lh6Iyyw68wn0Q4zDCSZFdEqjqawLaLd5j7pc7gmRi3YySOBWEj0ihBaM8ybOQrufGy4MAhDidj5yVjfHg5VCKhcOH2QARfau0gTieploa0UqNJdmrRDdl9caKrTwWhTTp1VA0IB14Yx5VQYLbJUzSCQWDcOJXadsxyDcYpWKwXE9P4Vo7R20iRxZhPj18fNeiKyPMD4zXPQjApPYr1QmmuETptTbS8W7vOTpQARnyiy+xY4vU8USl/ZIXLLmXGeQ9rbFtDxVoZ7WwYStFMGGmFiy1IwjZArp2My3uiRzpepB8tqbGzUmqFpw3qZLgLA4ODgpCfIqvj2t7+Nz33uczjggAPAWHm1tccee2Dp0qXru1s1NiP0stASjL9aUpwEtv31VNpymg2JOFCYH69AM8yRCOlHp6uoTmOt7DYx1kmw87zlWDiw0lc7SD9Cz40CZas9qswmM8pWbUSoEEQKWnJoJ07WmsGoiks04IkRtV8KaSePaBFm6DdeJHjx8ARBdO6E3VozP2XXinOM5jGG04b97GJ6V95cCuuy7ciEYLZ1WCUH64P7/99pAIC7P36c1dww49tiQBlAa0XSzkyycn7puAWCMt6AMFQ2xsNpg6rJ9IJrJGHhYznsNvo9iHIlvBidqk8E37bkFKRrRdVpESLNQ6RF0FdBA4C4UWCXq87GosvPnZZjVqPGM6ImQ9OGKbXJFi5c2EdgJuKhhx56xm0sX74cc+fOXe3+TqfztNuusWXhpdedgii05OGh447HPj/8GDgzeKI3gMEow2CU4c+jMzCU9HDtX1+ATh7hr2ijEUqkMkCZ41UilwLbDI3isXQGHh2egWS29OPXghsEQvYZIAJAmEgUvcBeHhggH48gEgmjmSVEiqMorNjaGFsdEkK6CpBtldAiTgJq6Rbb6mg9Ta1NFEdTlSqJCl9xsO7UzIq8m9YQ0E5RCQwM9qb1PJDWKnY6rLQI8fvXnzmt70GESGnuK0JkqFgUAncdbr2h4kDa6g7K80OkLHY5Zdo5S4eh8joz0or1stCRIOE/G2CPdSvKvaEltUM5jK8OkYC6rPoxtOMcuRTOn8q264h0k6mm0k6AHdhJt4VfX7Je5pc1atTYuJgSGfrwhz/c93tRFLjjjjtw3XXX4cQTT5zUNvbdd1/84Ac/8MGuRIAuvvhi7L///lPZrRqbIVaNNZHEhZ8UCrlGJ4/x/FlPYHbUxZ+7M5ErgceGhxCFCjOSHqTzi6HYBFtZKQXHgms8OdYGc62VB1ds5Rd7GoemUXfuxroDoSC5nfYCA3jkDAAjhSK1omIWWB+hOC76RuDJvI/gRbso9UIkSCZUiRDpluJQum3aEXshtCVIcYFUBm6s3FZB7jr8rGk9D4FQfjIPwLRVhNaE4U4Dg80UyjDkReBJ12t+fhyUbluhsxZIAomicpy1ZlC6bGtVdVl2jN4G7baTHMowP1VGn0VrhkKJCX5CFuQ6PbHtSpEdQBkSW+qTSmILlPYJcSzRLWpn6hobHrVmaPowJTL0oQ99aI33/+d//mefK/XT4dxzz8UhhxyCu+++G1JKfOYzn8Hdd9+NW2+9FTfeeOOktrF48WKceWb/1euuu+6Ke++9t+8+YwwOPfRQXHfddbjmmmvwxje+cVLbr7Hhsd2sYfxleAiMG7zl1vej0DYfTDCD3z41H7MbXbx060dww8M7IwwUpOHYbcaT+OPKedCGIc1DNGIruqZqSxRaTxoY2LiNQPsJNWuW50bmNfdRDnY6TDnvGus8DcBPe1FFJ3CEoSQ5ZYuMpr6qLbGisLEN2pRibOZGswFUxr5thYNzg7HxBM1GjrGxBoLItgQ7vRjNJLcTZcX0Tl0+/5oz0XQ+QkpzdNMI9x9x2rS+RxX3vvl07PPDjwGAJ0I7nX8RWru3vU6IWleqYq7YF7PBjCcvRD4JUnPnl9Sv6QoD5SNQYvez4OUUW8iVr0b1ESiUFSar4TJeG0akSsNOrLXjHE8OD9RVoRobB/Vo/bRhWi//DjnkEHzrW9+a1HMPOOAA3HnnnZBSYs8998SPf/xjzJ07F7/85S+xzz77TPo999hjDzz++OP+dsstt6z2nE9/+tN1620Txc8P+hTuP+I0JFGB3/1lWy/ifaw7hEZYYPvmStw9vDWMsT4427VG8afxmQCcGNaNudNCqTXHjKSHXec+CTCgkRSIXMVFKt6nC6GIh9w5F3My+4NNnKeJM2PsyL3wLRSUHkGVihPnxuuAAEt64lh6bZEQGlxoX7GqVjgoQsIYePLEhcZgI0UkFJpJbtPcFd8gRCXNQ3AY9LJwgxIhwoykh9sO+bj//Yw3fQNxYONXhKvelcJ00guVpDQMlMtqK/2A6PnUJgNsxUhw7QkwiaFJL8Rhb4UWnhRR28yLthV3OrB+cbUnQob57Q53G3jgLevn91SjRo2Nj2m9xLzqqqswa9asST9/xx13xP/8z/+s13sGQYB58+at9fE777wTF1xwAX77299im21qp9hNGUlcYHazg6c6LYxmCV46508AgJ2HluPxFUN+AVrRbSESCoL1E5S8sKPhj48MYkWg+qpB1jHYEhjynIkjiW4vKrU8E3QjlKbOXSuLc+NN/EgUbVtazG+jmjK/JtE03L4ApTEjESMrFtcIGhppHqLVzDCexlCao93IoAzD2HBj2o97HEkMPzaIP/7LYuzyrbOnfftrwk9fdWHf74tvez3mzhpFLgPfvsqVKJ3BDYN2Y/bkLl3qr8qEeq37w2C1I6vlFBmJ361eSRvbjtNw1aUKSSVna841tBL+e2HfE30VKcasU3evG224g1ajxgTUbbLpw5TI0Ite9KK+SosxBk888QSWL1+O//qv/1rr60ZHRyf9HpOdUHvggQew7bbbIkkS7L///liyZAm23357ANbL6B/+4R/wn//5n09LmGo8+8iLAIPNFH9eOROz2l0ozbFVOI6nijYaokAcF2AMeGhkFpRmyCEQCdtaiipaG0s0BHqpJROU3VWmuxs/Qk2VHOk0IVQyprZMGFotkJIcPDSQqiQ7pcCZ2inltqs6IVqwCQb9DtQc6BtfJ0NCre1EVBRK9LLITlr14g3icnznYSUB2hhVoTVh6dtOwUuvO8X7+ZQTXEASSAx3Gz5kFQAEV570VElJIDRyKdBuZLba5Y4leH+4LbVUBS+DWwXT3kuoanlgiVZ53sg6wX8PUE7D1aixUVG3yaYNUyJDb3jDG/rIEOccc+bMwStf+Urstttua33djBkzJt2uUko943P2228/XHLJJdh1113x+OOP48wzz8QrXvEK/OEPf8DAwACOO+44vOxlL8Mb3vCGSb0nAGRZhizL/O/rQuBqrDtee+OH0Q5zxNFszG52AAADcYqeDHHTUzthYXsF2kHuBbRpbs30GLOxEYwbjI010GjmiFxKfODMFMscMBK9Gj/yHgY2viHPAxi3HRHY15F2x75GAwIo8sDmjwHQNqoMWsNXhWiBJB9iat1VF2qqSFElg0gTVTAAu/CnMkAjLvqmoKqEZUtFNWuNfo6EwmCcopPbJPkiCxA7fZMPf3WTfJQXRqG33JFjIqWN2DmWM4NeEfpKoDdYdPoj5cgxnT/yetLGjvsTiY2E/Q46ruVH/mvUqLH5YUpkaPHixVN6sxtuuMH/vGzZMpx88sl417ve5afHfvnLX+LSSy/FkiVLJrW9Qw45xP+81157Yb/99sMOO+yAK6+8EnPmzMHPfvYz3HHHHeu0j0uWLFlNlF1jw+BNvzgGq3pDWNVr2gBPrjAQp5gRpRhJGwi5wh9WbYOXzXkYi2atwLJVs3xqu1JWZBsIDRNaU8ZAKPRcvhZVDYAyEV05sTQJYQki0N6jBoDX9FAUh32OsvfDaYoc2UIlT6w6uQSUbTADZ2FUaakIofuqRuQnFDq/odTlrmnNkffCDXH4NzmM9hK0GxngJsZIpxNWtEJRLH37k1LkuSOX5AAOAFJZckQTZaQpSsICo6n1s6oSVcHsdynkCopzQGsE3JEyXkZxlG1NS2Ap5wxw7brgmS/iatSYNtSVoWkDM2ZifvYzQwiBxx9/fDWfoBUrVmDu3LmTquocdNBB+Od//mccddRRffdffvnl+OIXv4if//zn67pbAICXvOQlePWrX41er4fPfvaz4Lz8Y6WUAuccr3jFK9a6/TVVhubPn4+RkZEpmUvWWDuef82ZmNHqwRiGoaSHiNtpMQ6DThFhLLeZWCHX3htGOdFzFEqfRUZOyeQ3A5QRCoCt0uRSVDxkAOliH4KKrogqNkSiqKpkp8IChKH03kEkrK7CB37S75X7GTPQiiNwRE0qjjiS/jMROLd6ofvefDoAYK/jLsJdFx03nYd9k8ThNx+LJ8YHfDXP6oU4FsxcieXdtrUWcM7S1VR6GmdnzIa9jqdxHxnWfhxe++cKpj2JoYwyxoBWlCEJJEazBLm0guqQaxQVZ2pq3xHKSBjmBfl3v3Hxxj14NTYpjI6OYmhoaIOuGfQeu3/gXIg4eeYXrAUqS3H3f51Sr2+YYmVobfwpyzJE0eQEhL/85S/xhS98YbX79913X/zzP//zVHYL4+PjWLp0Kd7+9rfjyCOPXG07e+65Jy666CIcfvjha91GHMeI4/UPpqzxzLjnTWf4n99wyweRqgB/HR8AYBfERTNXoh1keDJtY4coxYPDs/2VfiEFZrW7WDluq0rKpcnTQkfePVQ9UJL7iS6ADBDLfSERM43aS+dHQ1UfCgktCgbu2nHKlL4zVfPHKgniTuHImQET/VUkT9aqGhXNIfPyv+WWToT++bfvwu1PPg+C2fPuzRhdFWdl2kTPRaZ4d2zfbrTbINuCqmCeyDCdZ8GtJogQCeWjPhTsCKEyHKNZgkJZvynuRuhD1yoD7PeSo+Ke7cbqgVIztvu3F9eEqEaNzQzrRIY++9nPArAGiRdffDHa7bZ/TCmFm2666Wk1Q1XMnz8f//M//4Pzzz+/7/6LL74Y8+fPn9Q2TjjhBBx++OHYYYcd8Je//AVnnHEGhBA46qijMGfOnDWKprfffnssXLhwUtuvsfGgDUNPhkgCicgJZnMl8KfUjtGP53aqiqoCSguM9hK/QNLEEHN9LKW5XUDdhFcQOLEtyjaVQSXgsxLbIFGdVLIj3YWrFCRxAaVZxXCvX5xdlYwYVPQo7jMyw1BIXhn1Lh8jt2rZmV4foU0Zdz21rbUM8NU45qcEleHIpSUyUtnjE02o/IlAg2kG7tLnk8gaL+aFrRolYQHFbLyIBvPbr4qd6RxRuGsVlGgvXMuNVcgPgUiRgrCeUOP1xVSNjYS6TTZtWKe/uhdddBEAWxn6whe+0BfKGkURFixYsMZqz9q2dcQRR+CHP/wh9ttvPwDAb37zGzzwwAOT9ip69NFHcdRRR2HFihWYM2cODjjgAPzqV7/CnDlz1uVj1dgE8L1X/Ade9bN/R64EZja6yKMAXRkil4ElH4b7Nlgni1x8RX/cRXWB8yTItaQYMwi47psoKqsxzEdoVKeSlMsGm5hED1RF2eV70f0Tn8cm3B+FEkpzCDfpVoUxDPFQhkWXn4uH/mHLT0BPnR0CtasUmG9n5kpAM2uSSOeKtFZUiVOK+xiU0E2EKc4QBjRKbz2CEFjHaMEtmTGa+dgPAFBgUIZBVMgtAC+gBsrvRBUUpUJTZ1bwtIEPWo0aDvVo/fRhncjQww8/DAB41atehauvvhozZ86c8hsfeuiheOCBB/D5z38e99xzDwDg8MMPx7/+679OujJ0xRVXrNN7TkEeVWMjYjDK8NR4G1JzzB8YxriMcMPfXYAdL7wQeusMzbbVcpHWB0CfmZ7WHKkuHaYpemNi8jrdXwqruZ8+A0pPGlOp4tjQTtXnIVRIgTiUFHHVVwWqjs970XVlu7TP1cWUwLmBCDUW/e+5eOioLZ8QteMMPT8laJDJoOLXVJ6vKJSIhEJHRn1klNqmaW6J1UCSIZcChRY+sFWDgTHmBfhUUfTGl+j3IQJsxYdCX6E5FADBy3PrI2BYOf3GGKY9RLdGjbWirgxNG6ZUj69Oha0L7rrrLrzgBS/woubnPe95+PjHP77W5//xj3/ErrvuiiB47rQNnsv4zgGfw/4/PhlbJR2kKsQPD/wMAGDp8cdj928vttEJhqGZ5FBOgNzvAFySEYAWLfjqUdUQkaaOlLuQl0o4R2M3JaRKV2vONeJIe38iPyrvFmmqGJQj9DZglapCE9tnVVBavVbCv18USkjOoeSWb+DHuZ3yqraeSNtDx9VGazh9j7crsO2rJCyQFqE9Zk4fRuJnwTU4LGkRzlk6CLWP5FCGQ8BpyCo6ICJIth3LEAhLkEOh0CtCP1qvDUMUKBSqrJBz15J9rlT2atTYUjBplnH88cfj7LPPRqvVwvHHH/+0z73wwgvXeP+LXvQiPPHEE5NuY+2///648847sWjRosnuZo3NGDt+4+PQxRB+efB5+NAdR2HBZZ8ANLDsXSd5Xx7y9ZkYqAmUfjO5y+4iPY8GQyi0n0Sjx8JA+diHMFC+csOZgamkk1vNCi/JFPpbI9pUAzzLdg65VWtdViOoghAIm3Fm40dK52TyxTGG+fDaLRmRUP5cVokIYKs1caBdBaYMkeXcIOI2iiMtbPRGyMqpskJbstMIpdX6OG+p2AnfBdfomsiL5gncUOUOZTvNteMCoZC7ihUqhNuSNPj3BqyTulIce5x0Ef74iS1bAF9jE0Bd3ZkWTJoM3XHHHSgKa1p2++23T9o8sQpjDE477TQ0m81JPT/P83V+jxqbL5KkgAo5Flz2CQzM2AWzthrDWCfBy68/CYzFblFEpQqEyiSPJSBKC/c7tThKXQ/nGgHgR65JZF11GyaSQyPe7SRHWgR9btOkAaqO6nNukKYhmg37nbUVBetgTaGjHOirgJSESkMpp43Swi/QQbTle9bkSiAKpNULGQ4GA1FpJyrAk03fmgwklOGIhEIvC/0UmZ0gFN5/KgmoPWZDWCOhEHGF8SLqI9M0eUjnnDHYsNjK90Jp63cEJUBnhVpqVX8pDgPDDLjQ6O6VbrTjWOO5iVozNH2YNBmqtsam6gF04IEH4r777pv08/fff380GtOfxVRj00R3PEbUKCAiO71FuWGjvcQnkK+Ng9MiRkaFQP+EVlXALLgGZ/3xCVUhtnAGfUR2pOJg2j6H9EgThbRaMwQuYNW+B1UqNKrmjdX3oW0Y069zIg3McwHk2aMM7xO4C/cz+UtRYGojKqx5pnsdHWc6vklUoJeF/tyFXCGVIQot0AwK/16RI6rKMCTCJthzY9CIbNuNuwiXsmXG+lYOG99hEAUSIVcouEBWqUhGgYIKpzUHu0aNGhsQUxLj/NM//RM+85nPYGBgoO/+TqeDY489Fl/+8pfX+Lqpkqgazw08fPRHAQB7fvcM38YCrAaEAchybvVCmvW1nqqoaoaoRVXmhPWn1htXLSJfGlq6fNuGa5ePVQplycm4qkVSboTf+hAJJHHhqxh2O2UFyP/uyN2aiBu15ORzgBCRhw+J2enY20qO9FlkjBtwoby3U68ISuLpjjW1PaPQfm+ksW3RVAYQzCAPrC6rOkIvmLFtNEdstNMlTdQOwbU0BdeA86ASwrbdkkAi0NpOPrrXcq4hAo3drj4L9zoDzRo1ph21gHraMKVLl0svvRS9Xm+1+3u9Hi677LL13qkaz22QMWLokucHGylmD3QQR4UXMJPBItCfCTVRKA2UDtRKM/TSCGke9jkKU8tNVUbkbTvGjvELUboXE/EByvYJZwatRuY0P8brgKrVoGoMiK5UhDi3OqFAKE/M6LHnwvDjQJxiRtJDK8qd2SX3gupUhnZUXjPb4goUxITJO6CsplHlMOSODDkiFXKNUCiMpA0/YVYd16djnRWBFdJz7duZRIZpMlAq7rfPmUEjKCz5cQJrwYwTbxvEoUSR18MfNTYcqE22PrcaFutEhkZHRzEyMgJjDMbGxjA6Oupvq1atwrXXXrtaREeNGusKYywRokVQuFaZcIGotHiR91DZbrKvrwqsq47PAByx0YhCVWllwf/riZRLjafqFK/8TO9FlR7yyKGoCK3LGAhytdaa+/emalI1x4wqV4wZJKFco0B8S8T1r7zIVeVceCqA0LWwQmGPt+D2nORSoJNFZcWNND2u4qdd5UZwg0iU54q8gmi7tsJj0Ioym3tmSjdr0noBNE1WOl+TRq0RFVa3pDlyJdApIjy8fPZqYmrODaK4wN7fP21jHMoaNWqsB9bpsoVS5xlj2GWXXVZ7nDFWh5zWWG8wBqQucHX+wDDuXr41mlFuHaADSxSSQKLnJom4IyHUzqpmfU3cblBZJKsZZH3aEAChm0SCEkgCmyHWKwIvlvYtL1eJSovQC6IpnqO6bVt1Yv61jJHrdel+7aNCfJvuuUGIfvS3n8ZLrzvFC5aJgGjDoGEnBLsqrLiMl2aadKa1J5cBkkbq245SCbSiDNowjGYJBuMUSnO0ogxKc0TCan40rDP1eBb7wFwiURTbQa3O5aNtDDQydLIIYy4LrZHk6DkDSaD8HnFuMD5e6x5rbCDUbbJpwzqRoRtuuAHGGPzd3/0dvvWtb2HWrFn+sSiKsMMOO2Dbbbed9p2s8dxCEkg3Gl3grie2se2lkKMRFmiGOTp55DU5USj96+gKv1pV4dw+j0byAbjqgH28SoTK12i0kwLjWYx2nCGXAdJi9f8qVEVqxznG0ni1iSTSwQBW82IXSOPz1Qy34/7UHlPKVo9SN8L9XCFDL73uFDTDHIUWKJRAKgM0wgKcKm6uzRkFZYSJctOAFM/CGLzWqleEvnIjKpqkGUnPmjbmMbpFhFAoFE6gzZlBrgM0ogK5u4/8igDrfSSYfZ9mksMYoBXnXiOkYS0dDE0vkh+SAIJI4m9+9FH86rVLnoWjW2NLRj1NNn1YJzL0t3/7twCsE/X8+fP7EuFr1FhfLLroQjx03PEuJVxg1XiIwUYKZTiyIsA27VFslXQwrzGGu5Zvg7GRBgaGel4UXdXY+IgO17KiK/bqRBlNjJHup6o36uYhjGEYS2PManZdino54l3VJPWKEGkWIo6kF3dT5AaAkuxoBiFcZYlpMMHQkwJClOPdesLU3MKvL/HC8i0VA65aQwSCV1qIgdAQWkO4PLig4u7cjHI7js+NJzyA1f5EQqER5shVgLE8du1WjUwFENwaL1bblERiyQmbWrK5EjZ7DNXJNWeRMGEhScICI90G2o3M+xMxBsShxPJV/cMmNWrU2LQwJTazww47gHOObreLe++9F3fddVffrUaNyWDBJZ/wP+/0yQuhY40X/uA0bNXsIBAKUSgx0m34hWysiJFrgbtXbm3JSFHqhSaKqIGyVUHiV7qPiBBpQqpEiLYhlQ3lbMe5j+tQuoz2IAKmjXVIFp5swcd3lO7YrvVW0RwpY31sAmFHyGmht5Nm3OumtnTt0Btu+aA9TmDlWH0lXZ4qZlIKr6mic1BogYBrhG4Mf2ar51PtKdmeRO7dPMR4FlvtkRNWW2F0GYlCP1e1Y4SqPxRjdgqNVzyRQq7RinK0G5nXNGVFgCSQSPMQrDLFWGPLw65Xn/XsvLGZhlsNAFMkQ8uXL8ff//3fY2BgAHvssQde9KIX9d1q1JgU8vLrF+w4DhMZ9LIQT3VbmNsehzEMQ007tRgHEivGW5Ba+KpMc2avTwg9EURwAidcpgqNVLwvlLU/WNVWI0hblLsoCCJk5H9jDLPVHxfbEQjtdSoAfLK9b5OxkuRobRfpzKWgK82sC3WFQNFr4kYxzQd908Lj44PIVOACebmvpihDcSnOPygu/FQfZySkhxdZa1exazhbg14RYiyP0c3DvnDeTu5yzWD8uSRUf06CwhsvMmbNFKOgbMkC/e1VbRgyFaAZ5X4q7Y9vWIxfvXaJFeMHNRnaUvHS60559rJ5NzIZWrJkCV7ykpdgYGAAc+fOxRvf+MY+78Bly5Z5XfHE2ze/+U3/vEceeQSHHXYYms0m5s6dixNPPBFSyjW95UbDlMjQhz/8YQwPD+PXv/41Go0GrrvuOlx66aXYeeed8d3vfne697HGcwDzZ61Ca6sOGIC8CBBwjXmDo8ik9ZNpRTlacY5Hx4fQy0KMjTSQZ7alUR21pit7+ln0TZaV93vHYDfZBcARJds+KVwlgkaxqZpAbTKlOfIi8DEeqjJuTzEdVZI2sb1WbaMAcKP38PtEz+fcYMcrzsUuV5097cf82cbf/Oij1lixCPum/4xxFTctkEmr4+HcoBXniIRCwDUGogzNqPBVP2Nsu5I0RjThZ4wVRkfu+IZcoRnlENz6CzXC3L8vfY+SsEAqwz7CFAUKjaDAUNLrO09UUTLGfqeyIkAzyVEUAi+9zmaTPfCWU3Ff7TW0ReLAn56IKJBoJs9OWsLGHq2/8cYbccwxx+BXv/oVrr/+ehRFgYMPPhidTgcAMH/+fDz++ON9tzPPPBPtdhuHHHIIAEAphcMOOwx5nuPWW2/FpZdeiksuuQSnn/7s/h+ZkgnGz372M3znO9/BvvvuC845dthhB7zmNa/B4OAglixZgsMOO2y697PGFohl/3IiFnz1POs6LWZg9kAHjaDAX8cGEHGFh5+aDSE0pCMrY70Yjbjwqe6x+wNEbS6OfldnwHiTPttuKSeCjLF6oTQPEYcTr/jtX4jx0QTtwRTjWezvt6nn2k+TUXWpO5agOWDjFyZWqppRgbE07mvdcNA4Pfz0Ge2zENpph+xna7VSdDrJdB/+Zx2dLEIrzvvIX66Eb2Haip6N7Ai5QhRIe4wcSQXgxc40fl8YK6omogrY19tJQo1GVCDkto2ZF7Z1psHQCgp08rh0lFbCEVrtq3ZSc8yIUyw3bUScxv41BGwFkXLqBpMU7TjDEysHn5XjWmPjIS1CGAPcfug5z/aubBRcd911fb9fcsklmDt3Lm677TYceOCBEEJg3rx5fc+55pprcOSRR6LdbgMAfvzjH+Puu+/GT37yE2y99dZ44QtfiLPPPhsnnXQSFi9ejCh6dgKqp1QZ6nQ63k9o5syZWL58OQBgzz33xO233z59e1dji8b+Pz4Zs2aPY+6MMTSTHMtH23hyvI1CCvxpZCZmD3RgDJDmAVb1GggDhTS3AthmM4OUAnkh+vQdkbAZVNaEr9R/0Og65YVRuwwozRZp+ovcraOmbVGN92L3nFJnMrHFlrRyt3iXFQ7GDKLQuihX3ZWTqLBEpyKalkp4p+rq5JtwZoJbogFjO8kQBbJP9wUAg0mKOFBoRTkGosy3xbLCTtkVFVfxKJBIwsLrjEKuMBhbUtpzlUOqxJEXFHkNxa7tZQyzER2BRCwkCi0QCmWNMFlpowAAy3stAPAtU+Um3chPqtpqmzdr1IYN19hiscPgKk/MnxVMU5us6hk4OjqKLMsm9fYjIyMA0DdZXsVtt92GO++8E+95z3v8fb/85S+x5557Yuutt/b3vfa1r8Xo6Cj++Mc/TvKDTz+mRIZ23XVX3yfce++98d///d947LHH8IUvfAHbbLPNtO5gjS0Xvzz4PDBmDRU5DBis87M2DFkeoFeESCIJ6a6640CineTWU0hoJHHhXZ2JfFSFrqUpov2dpsEoY4zEzlVhs31+KcDu3j9UcSqGM/crq0/UYqPtVIXatOhGQvVljxlHeMoWmfYj4rRtwJKDyKXbc7HlaU6ITFjHZu3NF3Np/ZwKJTCWxxiMU2+mCJTZcYA9RkSEtCM1gmsIJ0YHXFaYUFCGo1eEyFSAJChAQb7U2pwZ9/o8jqrEBrCCbTqf9BwbEGsgSQ9mmKsW2PMfNeuw6S0Z33zZ53HnYc9eC5sZs943wLa3hoaG/G3Jkme2gdBa48Mf/jBe/vKX4wUveMEan/OlL30Jz3/+8/Gyl73M3/fEE0/0ESEA/vcnnnhiqodivTGlNtmHPvQhPP744wCAM844A6973evwta99DVEU4dJLL53WHayxZUNp7qdvZrR6GOkm2H7WKjy6agZ6WYitB8eQFQHmtMYxkjagNPNxGkUWQBcc8ezyCl8bBvAyqsNMECTTc2Ka+KoEfionbIZhviogt0v9dFh1n0knVG2JVX1tqKJAYumqC7XSpTFjGCgIpqGN9R7isK0iInLSxXfIVVtem+yWV5+PF197anmuvNZKI5URCi1cWGtoK0BBYUXKzpOoGWXOlygExXC0ohxjmT1WrTiHdN+vzJlhwjAYriENdyJp0Vf5iQMJyADScHAYSCfkFtyeGwX7PQqFqrTo7Oi/FX4zP2GWK4F2M8NLfngK/u+Qczfika3xdHj7r/8ZXRVh78FHcfoL1qxx3f3bi9GICwxEGbZrj+Dr+/3PRt7LjYs///nPGBws27pxHD/ja4455hj84Q9/wC233LLGx3u9Hi6//HKcdtrm4cA+pcrQP/7jP+Jd73oXAGCfffbBn/70J/z2t7/Fo48+ire+9a3TuX81tnDcedjZ3jG6VwTYbe6TkJqjnWRoxAW6RYTBRoo/rZiFnWcsRyYDZJldhHTBgUolhdpcNo2ce1fhanI9VRRU3+tKokQkhqo3RrGKj5F9TeAqA9WWGImuq5lipFXKHNmj/aP3kcqKtKmaVUjhp6hI/OtH/ttb5lRZmgdoxxkiIdEIc9c2K8mkTZe3x6eTR8ikbZO2owyByxATXCMJCyjD0S0iZFL0vR4oiap2U37jWWzbYVwhCSQ4M1iZNv32vdM1030VrOrEH4muq07m5EnkXayZhjK8juR4lrH390/Dx+56M/7mRx/Fo50hPLBiK3z7kb384y/8Qf/5aSc5QudLJSfRBtv5m8+SZmia2mSDg4N9t2ciQx/84Afx/e9/HzfccAOe97znrfE5V111FbrdLt7xjnf03T9v3jz89a9/7buPfp+oN9qYmHRl6Pjjj5/0Ri+88MIp7UyN5ybIFHGb9ig4M3hiZBBRKDFvYAxSc6zotjBvaBR/6Q4id07QxjCISEMVvIzGgIFCmQ5vDFvjuARnBnkRIAql0wGVLsUEmuQKYuWnkwD0LdTValFRCDQbed+EGHexG4CrLLCyQpUVgRduEzkiIgTYlkwryjGeRdCab7HGi3luvXis1UDgyUU7thEaWRFAcIPxLLbkhGsElfPdCAr0pDNKZBrK2Dy7ee0xjOWxC3wNoKVA4awMBDfQsCSnW0RQ5APFNSKnGaqCcs2qFcaJsL5R2v3M+iYM7WuARf97Lh466pTpP4g1nhav/OkJKKQV7/ac7ixxWr6dv3kOZg50AfSf89nNDjpFhK0b4/jG/l9Y43bf+Zv34NHOEJaPtzHQ0tjjO4vxxzcs3sCfph9TmQib+Pp1gTEGxx57LK655hr8/Oc/x8KFC9f63C996Ut4/etfjzlz5vTdv//+++PjH/84nnzySa89vv766zE4OIjdd999nT/DdGHSZOiOO+6Y1PPYxGyDGjWeBs+/5kxEka2sREKBo9TzzIq7eGRsJpTi2KY1iqXDW9kFMXCaEGagisgZ7Rlo1m/Yp1m/WR4Af1VvA1XdCDazi+9Y2n81FAbW+LGaNcZROkrTZBpjBs1G7hfJwJEgWhCrIaDUKiMNUbXSIFzeVnWxjYRCVz17As1drz4LWnE88JZTN8j2o0j25ZD1ihCCGcRCYrjXQCA0ekWIkCvEoUTA7HQhVYWktiSEWmU05UXEZVWniaFmDyvyFoyxcSlBkiEQdlSe9D1U5ekVkW+RcmaQOWIkmIbSpRdSNZuOSLGtRBoYzVBoXjpXMw3GGOJky6zubcp45U9PwJ8en42Zszq45qG9bMVHKITON6w9M0PANHaeOdL3Om0Ybjrok6ttb8HnP4W991wGqTmWd7eG4BqtOPffhx2vOBd3HPrBjfLZng0cc8wxuPzyy/Gd73wHAwMDXuMzNDSERqPM4HvwwQdx00034dprr11tGwcffDB23313vP3tb8f555+PJ554AqeeeiqOOeaYSbXnNhQmTYZuuOGGDbkfNZ6jaCa5v2JfkTYxp9GxJEQojOYJFg2uwO9Sm3e3TXsU2w0YPNEZwHgaI05yJHHhWh+OiDttB7NT6j4vTGuOJCyQyQBw7TLBtX/vXAY+moOyrpKwsM7IMCi0cPebvnYZYLcNwGuQZjW7WNFpQcMtsppBcLvNKJR9FaWQW2EvhYUmge7zLCJB8MbGXt87HZwbJJH9fM+/5kzc86Yzpm37R/3qX3DXX7fFVgMdjKQNzGx0oY3CjKQHbZir2HDEXGIwSZHLwJEijUaYoydD3wLNVQBjGNIiAOcGg0mKsSLGSC9BIQV6zscoiSTacWbH9IVCOqElZgzDQJwiU/bPYreIyiBeGa7R0Ryw54naeYpIcsV/SMO2S+Po2TWVey5hj+8sBmcG7STAdvNWQSqBcRnjN687Fy/54SlQhuP2Q8/BfX/eFgf/+MP4+Xs+BcBdnIUShZyBvb53OuJAYvuhYfy120Y3jzBje4Y/j87wPlZUJSbhPeMa7/vtMRvvg07BOHG1168DPv/5zwMAXvnKV/bd/5WvfMVLZwDgy1/+Mp73vOfh4IMPXm0bQgh8//vfx/vf/37sv//+aLVaeOc734mzznqWXLwdmDFb4tDu9GF0dBRDQ0MYGRnpE5jVmB6QjX3kqjBKcyjFMXdgDKNpgl1mLUeqQizvtTAQujFrrvH7x7ZBq5n56k4zKrCqY3OhiAyRxxCNqzOn05k4JUQu1QHXyJzup8wws+9HCy2AvmkyWkRJNzTYyDCU9PD46KB/DlBWkwI3Kg/YtgwlnRvD0AiLymNO62I4OnmEsW6C+4/YOLqTvb9/Wl8GGOWq9dII9/+/6dmHV/70BDcmLyCVwMxGF6kM7MSXywdjzOaWAcBomvhW1IxGz5syxkJ6EbVtgcCHvK7qNKA1x4xWzzpRc4N2nGEoSqHBMJbHnmBRBS8JC1+tK5yQPWC2CpUWlFvWT045M8idLkwZ7oX1Vb0TEaLhkWbdKtvAePn1JwGw04ihKCNtbnn1+X3P+9AdR+HXTy7w1d2sCPx3rNACC2esxOPjg97UE4C/OCojXIyv7GYywHgvxm9f86ENvmbQuvTioz4OEU19uELlKW7/34/V6xumKKCuUWO6cN+bT8d9bz7dmeHZSk0YKAxGGZ43OILhrAGpOZ4aa6EZFBjJE9y3fA6Ma1cU0jpG50r0VVyAUsxK5EVr7nyGWJ/+w+uBSDvi2nTkWVSNYaDxfCI1ZVaZrTwAwGiWVByky4WT3oeE1gXFfDBrG9DJIwSVNh93Fas0DyG4xg5f7v9jvqFQ9VGi/WYMkMXTt+sWfHH1tgIA7HjB6hpCaaxxIgmUc2XF49pprmY0bAxLt4i8eNkHsarATprBeL1QdbKvV4RIZYB2koNzjVQGLvON+W113Harn5nG++32eBn1AYZCiTVqxTzZBvNCfHI9r1o7CLdgBmG/jUON6UcnjzwR6hUhbnn1+X1EaPdvL8a//PadWJm38ILZdiq6V4R+4AKw//dWpQ1b9XHnF0AZz1I5v2WMjCVGL/n+M4+l19j0UJOhGpsEfvO6c/Gr1y5B4UwUAfsHZyRPcPfj8xCFCgFXmNPoIIkkRKBQSAHOrf6mkKKv5OuTxVFJqhfaVZLKqzr7OGWJcfez/W/RiAqfL8ZdJtaMZs+bJdLkGP0RlIqjVwQYjNO+yhItkFRl4tw+V7B+X6QkkL5S0gwKZxDIkEQFAqHxp3/6yAY/DwCgKrolyvECgKTx9J45rCmx4CvlorPjpy7Eos9eADVLYvdvL8ZLfngKFn7dLhRZYdte3SJCyBUeHxlEyK2Op+rrlCuBTAXes6nQAuNZ7FuXAJDKsI8shdw6UOdKoBXn1lHaVW7sqL5tg4VCIeT95LPaCqNFjh6rWjMQKIhXsKqLeAmyCqBt1K2yDY9GaLVZTw4PrOYMveCy89BOcvz2yfmIhcS9w3N9VY/MWqmq1wgLb6kg3P9hP6UYSERi9XNJQxkbDdM0TVajJkM1NjHc//9O8xNbAGxLQzMkgYTUAo+NDWF2s+OvxAR3QaxCQ0mBTi/u+2M0MYTVtsSUD2AF7OJPE10EwTVyGXiyohRHIyxcjhZ8G4n2I+DaL5ZUGSI9EkFpO2Yfclu6l5XFloTTicu/ooW5k0W47ZCP4/evP3PDHPA1QDi/I8CKf0tSCSy6fM1+OXt+9wyEDQkIjQVfOR+LLj8XwaJxtBeOYNbWoxhqplCGY3CoiwX/80kMJqkfey+0rQaS7kJpW4mh9mHVdwlwxoYy9G7SgVC+Qmiv5Dk418gLgUILaDA/uZfKAKkMbeXAnYeJAbkAEDDtH6P98lEqFaJILZayClSSJiJd9D0jR/Idv/HxaTtXNVbHrKSL37zu3NVE/ws/dwHAgCiQGIxTPDiylfeKSgJZyaGzov6nOi0fy1K9eCKCVGbTuaEMrpGEEnojSvxommx9bjUsajJUY5OD1gwPD8/CIyMzkKoAQaiw3cAIAq4wf2AY7TAHq8RVEMJIIo4KX9YuvXpWH4fm7kreCx9ZOQptjP3jqDRzehKOVpz70jswkWQxH9gJALGQaCeZF2RvMzjq2z9ac6RF6FPuGbP5acpwSGWrHwHTSJU1/jOGYacrN56HyV7fO92RhLLNSMcrDBSYMNj5m+estk+DjRSNOEfczgFhwANLoaSyx5f+LaSAGMyxdNk8fw6I+DwxMogV3Ra6eQQN5o81EUZarHhlUVKao5tHrtomvIO59GTK7gNFr5B7dSYDZCpw7Tm7/VlJ13+eie89UWdWrRTR8+iYVY9bXtGocdj3ptZqjQ2DHxz42TXeP7hgGFGzQFYEGMtjdHKbgRWH0mvDiOgAZMTKfVud7DeolZ2pwBPoKJA2104oNOKNWP2rK0PThpoM1djkYAzD7Yeeg+VPDWJGnGKwkeLe5XPRlfaPV8QVXrTtY1g4ayVmNro+IqHVsASEHIApnZ6iHKp+QZxTgjwqi6tBK7KtIG0YZjR6mN3ooFeENixU2ADPJJAusFUhDqQb/7YREkko/eTRwpkr3ZQU+djYGJFGZKMgQm71QoKuLl0FZqyIvRZmVruLZiPHgq+et8GP+0uvOwWJK/NXyZ1tE2iEXCEIFQZaKZqVltle3zvdJcBLtBsZZsweRxxLzGj10IpztKLcVmuYQRQqDA30MDC7gyeHB2wiPbNtiblDY0gCiTi0+qnxLHZj6ZZghK4KQ1fiubRkJuCW9ChHJm2lr1qRKSt45AEkmK38hW7x04ZhebftK4Y9GTpCpTxpBfq1InbblWpB5ZiVLVhLsqtJ92ILjFbZHGAMw1Cz13df5Aw3q98zwArpy2w66zjeijLErjWmYb9HsbAEyLjvY6FEn+6vxuaDmgzV2ORALaHnbbMSgG2jxKHEo2NDSFWAXAukKrA/q8CLHK3jb6ndMAY+jFNp5kJP7XvQlX3VfVpp63OzVasDpTlG0gZW9FouLsM+plxrJK7kkBEENzY01E2J/bUzgEILtMMcM5IelOFu30ofHGNs5EZeBOhloZ1wykOboeUM4jg3wPiUknPWCUQUqgs3gY5bu2HNEMn88vnXnAmpuG8zSWVtAppRjm5uK2CpDBC7Shu1lZKwQCOx1TaqyAl3ZR65xYXMFQUziENp21GsHGlWjlBSmj13hITIRtVJPHJtMqoQxaH0k2PC+UhlzgG8Koiln4kE0X3Vc096Jjpm1QqR8N+x0um8KqqvsX446Ibj8dobP/yMz9v17IuQuO9AILQbjOiP2TFeCF+2TikGZrUJwkpJpVDCe45RRXFjom6RTQ9qMlRjk8Utrz4fAdNYOGMlZjc7yIsA40WEJ7tt/LUzgG4RIXdaEQAY7cV4cvkgVo62VtsWLeZ+oXfVopIUleLYFd0WWlEGqTlSV30YTFIEbqGeEfd8MCe5RhtHBEZ6CQo32dbJbHXjyW4b3SLy1QKqhpDuSDDtiVqnF2O0l2B0vIHRXoKeG+de9v4TNuShBgDcdsjHPTmgBYH0UdVWj9YMBjbCoOmCcwGXy8UNMjciH7toDYq7iCYsFK04L8kDsy7TRCrI5oBAV9vkAUWmhtXJtyhUfUG6nvgEsm/xopDWwrXIiIwFovR4qoqn6XdaECkOhHRdgpevA0oSWf3OVSuQgdC1bmiaUGiBfBKmpO19n+qr3JHpYrUaRNNkVLUlUMu9ilAor6eLhXTV51I3ttFAX671udUAUJOhGps4nkqbkJpj96EnUEiBkbSBXAqMpTGeun1rZDLA7/7+bNx2yMdx9xsXY9nbT4aWlfiMatDmGv5ITbxK19pWEsazGNu0R326vDbW7biTRXh8fNCPchdS+Ek0WkBJp0Lb6xUh0iKAVByB0OjkkTcMpH3UrmpS5EGfJiYv7O8Lv7ZxxnV/87pz0c1Dbz5JEFz7SZswUGglObpphEIKT3JKM8pKUK6Bn9YRboqOw7gqmf3MrSgDYL2mAKrUwWa3wRoZpq5tCKCi27LbJ6EytTRy5zfknb9dTl11Uox8oSKh/FRa6AgyUGbX0T5WA3gjIRG4+8h2oRrYO3ExpP3QleODCVXFGlNDLw+Rq8lVTanaQy0t+j9IJpvkL2TbqbxP/1XVh8WBROK+A9qwMsyX6dWqxTU2H2z42nuNGlPEPj/8GG47pOJR86IJT3jDml9nFHNCVeUXZQrZpCqEVNwToWp+GODG7A3Hk522F7t28wiDcYpVvYafLFK6X8Dtzdtk4KsrNEZP/kmkZ6JWmQbzk2RSCcSJzTdrNjJ0ezEa7Z79oxxuvNbKXYefhX1++DHfjgLgBaTG2LaVdAtLmll35wgKAdc+HkOZij4LVBFREEr4pHjv6eMWkySwwbwAXEXKkh46ZkpzRG7qjFppZKzpPYiKAGFgpwVpgizgGr089AvaeBZbcazhUJJ7EkUEKPTThpbwasOQcOWrVkkgMZol/jMQUaLFkjQkZOTInR5MOZsCBYagHrGfFmgw/OI1n1in1zCn9Qm4RpMXGDGlL5gX61cuVuCCn+l+oIz1qUazkBP6xsT6trvqVlmJujJUY5PFTjNWYMFln8AOF6/ZzG+tyMqyedXHhzPb4ikq7RdarCbqY8jhmDODrdtjaMcZRjPr9GoMPEmKhEIrKltFNIGShAVmNHtox5knO5wbZw5pCQAZRZK/kdYMRRGgnWTWaFFQXAg2+gRSEpR+KdWFnvZbG4aBRorAfe5uHvVVxGhhqU6CWT+eflKnNLcWBpXn+ckvXuqDAmd+SWJmX3mrjP1XW1WxczO3+8xsqr37na7+PVE2pXdQIyysBsRtl8hO1YxRupZZSYrLz0yaoirIh4pIHbViaqwf9vzuGbjtkMm1GwUzaEWZt6+QhpeBvxPa5KQRq/5NIJF9KkNIzdGVobWE4KtrhDZum2wabjUA1GSoxiaK3a4+C7//6zxst81KiFaBPb97xhqft8OXzseOV1jvmxf+4DS8+NpTMThvrDTZq/xvH+/F1ozPR27Y+6tZYNWpIfpDN57bnKtq60S70NVeHmIsjaE1w6ymHc2OQwkNW4EYz2JEoUIUKiSBzcYiWM2LFQcbA+RZCC40xtMY2wzZFp1UHJkUG30C6Rev+QSUYegVQZ8mhkTOhRSVCljZomLMEj5rE2BfU2iBXm59gRpRgbywj1eT4I1hGMsSSCXK7bGyUieVQC4DF35btj6Fm9aidmZQ0SXRz4UUXoRPV/KcWdNGyhVrRRmiwDoWU3uQ9oNIHVX+xvO4L5eKV74zRJIYM4gCtYbH7f0bdcHcArH/j09GEhZ4yQ+fOdrkpdedgsgZmsZCerLTK0KMFXHFgsNOjVEVuRogHDvdWywsIR/PY0+OWmFeTls+CwLqGtODmgzV2CSRxAWSSGIsjdFqZWt93uxtRsGFxi7fOhuAK4EHEq04L7UalVZUkQeQeYBeGkKp8uuvKqLbsuxtCRWJmAnGMHR7EdIs9GZ/jBkMpw23cHOvJQKoKmJFv0TCBNNIi9A6KUsBrTna7R6M8zQZilMIp9GRSiCOCjz/mo1nvAhYQTXFVJAmJi1Cr51JQnuc80Igd/4+WnN/A2zbCrCEqDqFVUiB8Szyx84eV3uMCNUpLKrQVHU6qQwgK1UZIqi8YoBJN63tdFoUWluE3GmdksBOlQWu1WXJnulrEQL9kRz0eQBUtFFlHAMRp8gJa6uRLwBWqxzVWDccfvOxAErj02eCMsx/DzVYf7UY5fkkt3Wq3FXNX3Ml0AgKhG7cPhTKOaLbIQtPprjaqBNlTK//rYZF/b+yxiaJOw87215tBWXY5T4//Nhqz5OKo5HkaMTW98Yn1ldg3CJtjE2V9qGLfmS6XIylEpW2B2llmNeoaG0XUq04tOIoCoE8d/EOXPW1TUqBNfeLcse1kzTsqD+ZLXZ7ERgDtp05gihQuO/JuZDOwTqJCghukHajaT/Oz4RIqEporB1Rt2ngGUa7CXIlkEQSWnGMp5Edb3ekI3ei8TQLPSEEgCSSqxFV0ucYU5otVkf9BdeIhUQuA0hFRMR46wTGbKYctTkA21qsVp4ohJeqWdUJoLEs8dUcslyoVgqr7TLfMnTxINVpRKr2cRLhVnQotJ1ciWfMeauxdizvtr1Oi0jp06EvcgX9OjbA5uTR/1kNhmZQ+J+Vm1rkTgs4cTvVVjCFSE+cPNugqNtk04aaDNXYZPF/h5xrF0dHiKqj2S++9lTseMW5nnyQVwxj1i+GtDmZ06MUUkAV9sa4ARdlSwOgoE7jF21dWYirV6CMGRRZAObeT0sOLsqrR85LZ2uqMlXH97UTZ0/UjIShwuxmB2N5jDQLEYUSodO9VF2yNzZ+87pzvXiU9oVaYQMNazfQTSP32bg/jpTdpqQ1QeymkffwAWwLiwhq7IwetdMUkZ2BdWwuF5o4kP4Y2Mk27Rcj0uRU22jGWILEJ5AYaoeQUJoISp9GhJVxC/TZq/ELFMFRbYEBJWmr6pAIVSNGLes/vVNFI7QXPpOdDA9c5tjESp+P2nGRLjQVJp34n8P452WViTWlOaQjuo2w8N8Fmi6b6ElUY/PAZv0/cvHixWCM9d122203//j73vc+7Ljjjmg0GpgzZw7e8IY34N57730W97jGuuL2Q8/B7/7+bEShwkjXCpgXfeZCrFo6E61Wil4a+raUnRBivv0BwEcyaM0gAgXGy5aFdIt0IQWU4kjzAJR3RoQocDldubIVANIiGcU8qQLKsfI1aVcIstKWs60x5kkO5xp/GR7y20/z0FcviJSxZ+l/Kzk9k1YoEgrjLgMuLQLrkcQNDEqtD2PwbUituK9ylUSF9REG0tvQ8S4NMS25CrmCdASTzB0BRz6csDpz70HVGK3LSTFrsujG4FnpIi248flURIzs1Jr0z5mVdPsWUn+uJ+w7vVZWjBurrUHanjEMDx/90Q1zsp4DyF1wr+AGaR4+8wuAtRIUcpLmzMZscBhr3+HicKgyRD5XY1niBysI9Ls2pVHoxgJNk63PrYbFZk2GAGCPPfbA448/7m+33HKLf2yfffbBV77yFdxzzz340Y9+BGMMDj74YChVi9w2N+SFwN1vXAwAYAVQafuDobzqJhdZ7+nCy8kdYxjC2LVoDFA4cXAUStfKKSdKqiP4VWNFwI3iuwmvIJJ+koxaNWHF2Za7pPqtWh1fxSikqOhagDwPoLVtuXV7EbjQgLGEijGDXha6999wx/fpoLSt2ERCYbCRQiqOrYfGPEEMhIKSFe0OnEjZh9kCYSidv5Alf3kRQGtrbkfC04nTO6QHou1mKrDGiERSnUaDyCu1O+m70IrLaJWsCHwGWZW4KM2QFoG9qgdpjCwBpCv+3LViqlNjE0HfN6ogmAlED7At2FAorFq5uilojclhwaWf8AaYSjPc9+bTn/E1RHb8WDyZLBq21oqrb5uZsoIkDfd6NXodGaxKR3ql5qtVBDcoatPFacNm7zMUBAHmzZu3xsf+5V/+xf+8YMECnHPOOdh7772xbNky7LjjjhtrF2tMA4gIEWYuWgVtGOJYoijKqo1w2WQU10BRF3BRCEraVo6SAmBlhIQQ1gU65KUJXzFhiksq2/JhXCMKlSMCVrswq9m13jPMoFeI0sVZM2RGIFd2ASTn66wIrO+O068YAC9f8DDufHJbaxoY2OpKXgjEUamL2djY5aqz0WzYK980DdGICtt6hBUlc27Q6cYQgfbHguJQWknu/JzKNiIRljgqoJ1/SyePfQWMXIKNQd9VdieP/c8UnttOetbbyHAEmiPNQx/HoRRHrwgQB8oSpchpOZgdrU5laNtZgkFwm0NF8SescqApp4wqToXTK1ElgMOUpntce81Z1Y04YNpXGdbFE+eFPzgNxgC/+/uzp3j2tjzMnjvq4m7Cvkrr04Fau4Ct8jTCAr0ixHCvgWZUIAkK3w6z1WBLzDlKl3gKTYYj4LZVHPRbLFQmFTcW1re6U1eGSmz2ZOiBBx7AtttuiyRJsP/++2PJkiXYfvvtV3tep9PBV77yFSxcuBDz589f6/ayLEOWldNLo6OjG2S/a0wdZtsUSjNkeegEu04Q66oFNG4NOO0P1zCaw2jSjbhKgjBoxAWMgRcGV0vg2lVu7MJvy/KS2YWec+NjHzizk2TcaWmoMpQ7A0BKqAfg3x+AJ0Vc2OrV/cNzLEFwBCLLywklqThUvnELubt/ezGCwBKyJLKTY1RR4do6UXMYJHHh2pTUkrQTXVUiVG0R2YXJCsgjofrPFR17MC/upNanVNy3NSjTray6cCRRYZ+jrc7MV3YcgbFxC8YH6QqukbACvSJCK8zRCnOs6jX7tEjaMLBKW6yaWQbYSiCR8aqQls4bORTbWJJi0sd+0UUXwoQzYNzxe+l1p6AZ5giFwvWvvGiqp3SzBx3jQgrcdfhZ6/RabRjA7HSoNNwToYmgQYjq1Jmv9GkOISTaYY4RwwGqCBmOgGlbGdSTP881Nh1s1m2y/fbbD5dccgmuu+46fP7zn8fDDz+MV7ziFRgbG/PP+a//+i+0222022388Ic/xPXXX48oWvtUzpIlSzA0NORvT0ecamx8vPbGDyOIbFsqCiWi0LalvK7GVYQ0mK/wSDf9RXohrTi407mkWYieEwBTujjpUoAy8JV0PbTQAehrhynFMRinfVVnqipVKxyU+ZVEdpw7iQo04gKNOMdIN0EvDV3FpQwFJcFu2NjwrsWL/vfccv+5vTJuxIW/CjcGSKKi7zlhoDCz3fWTXUlY9E3ZkB8QxV+UDtJ2GzR2D7jpPWNJi2D9BobVqAzr6GwNEFthjrji7k3bAayAvnQVLvVEgK02KWPFsxFXfeP7Vb+piQZ8oZuwC91rqj9XMRSlfmHtZBFu+LsL1njM9/7+adj/xyfjiFs/gAN/eiJeet0paO04gsEFw9hmp6fw4mtPtRNohiPiCp+79+8AAAs/t+btbcl48dxHsWBwJUaHm+v0OjvQUJJi0oXR7wC8Noja4tRGo6R67qqKADCWx14P5okzmGvbbkTd0PpMkdGtBoDNnAwdcsgheMtb3oK99toLr33ta3HttddieHgYV155pX/O0UcfjTvuuAM33ngjdtllFxx55JFI03St2/zoRz+KkZERf/vzn/+8MT5KjXVAI8lBAaJaWz1Ir+L5Q5NMgK1qKMWhCntf4NpPXBjv6RMEyqewV1tRVAGy9zvDvFCikRRlyCPXvsU2nDa8ZxBpabirTBCh6tciMT963ssiSCVg3OJP7RbOyqytaCNEODSaORZ+bQl2uvIctJPMtwlIpAxYUhEJhUIKpC7jCYBv+XVze7GhHZFUmiMtAvSyCN08RDeN/Jhyobkf3adFJXSxHklY+MfI9Trk2k/jDXcbKLTw0RikCQqD0g4gEmUkC+k5iJBGLsA1YHYSKOIKM5IepBOLAyV5paoV/Z4p2ypMZeiJmT0G2vvN0Hi90hxbD5QXaBNBBPGxsSEv5m7FOZqRJZVk6Ld8tI2lT22FC257DXb81IUw8XNvammX5l9xz4qtMWNWZ0qvp4R5wH4/40BCMI2BMOvTDlHrE0BfyDKRH7JUsOaNTl9G36ON6TNUC6inDZs1GZqIGTNmYJdddsGDDz7o7xsaGsLOO++MAw88EFdddRXuvfdeXHPNNWvdRhzHGBwc7LvV2HTwo7/9dN+YLLVCqH1jYy3sdJmvAhgGHmhoZRdCESgvTiZDwTiSqwlw6Y+d/bnM56o+pxrQSc9TmqHbi/3v1X+BckpNaY7MTcPEoYQqBLRkCF21S3DrsyTcRNyG1iI8/5ozoRRHo52hkRTehDDk2u9/ILQ1nDNlVtlIt4EVY62+ytpEQ7xqdhiRQSI+VrjsKj4VUWsvD/sCMzkzPpSVtpfLAJkM0HMGlpFQXutRrRSFXPu8Kbq6T4sQcSB9RYszg9EsQRTIPoIWMO1tBQBLVKv6oepUHO2XMhyrsoavHqyttfXy60/yx3Tt4/r288xs9RBHBebNGUG80yjCGRne/X/vntK53lxx/ZO7YSjp9RGOfX74Mez1vdNx9K/fu8bXVM8TAG+/QG3tQtuqWyePEJDIHAAAmxJJREFUIU2/AJrOAbVV6bmE0taD+bZoKjd79clzElsUGRofH8fSpUuxzTbbrPFxYwyMMX2aoBqbHwop/Ag6VWuAslJEehWlmRc8i0CjkRSuspPbBShUVgA8HvtReqCM26ia9inlQkorLRTALYSOBNj9Ib0JPCGz2yxbbqRrElwjiQs0Ezv1RKP/yvkTVXUvUom+TLXpxoLPfwq9kQQGtipBLT67EDtiJhQyN2UVOn1QXgSYMziORpzbhcUFpCqn26HPDFjCFwhryhgI7duRkVCebPmJL9ZPTKsTgnR1Hgjd51htn29v0p2v8j5b2WuEOdph3jcV5I0QK35KuQrKiaGKsV87yvzrJo7bV9tp1QTzTrb2tjxVkOg807/02enY2/2yU46ZDBCFCq1mhpse2gm7Xr1u2pnNGYUSrjII/Mtv34kFXznfEmBucPtfnrfG15BBI7VAqy0yMsbMZIAk7Nf6BO4cJkHRR3iNsW7kWRH472/1gmxjCqjrabLpw2ZNhk444QTceOONWLZsGW699Va86U1vghACRx11FB566CEsWbIEt912Gx555BHceuuteMtb3oJGo4FDDz302d71GusBGk0vozDg872o4tCIC9tKC1RfWwuwf8x6aeRJzMBgz7evADsOHwbKxTswl5dlr/7WFKUQCO1HxakS0EjstFSaB94/p1pqzydMHQlH5IJIoZHkbnvOxJAZNKMc6fiGc6Ae2G4MjaEU7UYGZTiSQPYdsydXDuIXr/kEOmnkJu5s9ScMFDp55PycmD8eVJ0rpECWh751KNwkHuDMGTWvtBHL/aHfiRQ1wsKP0tOYNLn9Nlw7TYP5cfxGVCByjtTkaC24RhJI7zAcBRKJkMicp0xVB1IloZRlB5RtFqoCAKVgmoz6qD1GotvBRoqX/PAU/Ottb1/tuJNepWr/UI3voP3hzLpjR6K8hVyh3UrBACz8+pLp+SJswljw1fMgja1WtqIcf1w1Dwu2f7KvejMR1eyyUCgETFfIJccTw7byT+chYBqBa0uS1YLNzLPfqypxJUuHwLU5lSn/P28s1G2y6cNmTYYeffRRHHXUUdh1111x5JFHYvbs2fjVr36FOXPmIEkS3HzzzTj00EOx00474a1vfSsGBgZw6623Yu7cuc/2rtdYDzSTvC/qIssDr+1JIulaJM6HxldXyqyqNA/BXOuBzPmAas4UXFq8W5AqI7y0PYJ3q+ZlJlV1QaMU+yqJ8tWhynM5MwhDhSBQkEr4alchBZTTKCx7x8kb7JhKxdGILUkgJ10AGE9j3PLq87H0bXZRSVdaQzqalIsrLaU0Cx1htF5KaS8qk+M1tTGNn/YSgvQ12ldfyLOFMVslsuPK1hixcAsOaa+oikS+UPQz+QSRLohcoUOuMJbHGM4TL6gdy2MUSmDcESEyy5TOP6Y66VYogVSG7vOUpor0M+BM/NBf1aIIkJv+3G/nsed3z/AtHADe2A8oWzn0etqHaguNdHNJXIAL4wOLt1QkD8bIiqBsWSmBVT3bimyEBcJArbFtaHP0ChSu+qcNQy6tceOcwXF/nGMhEboqD4X40oUL4Kp/sGGt9gJHeRLlK8h17txmi826uXnFFVes9bFtt90W11577UbcmxobC0Qg4qhApxsjDK2Yl7Kp6KqOFsnSC8S2dZTkSJLChjc6MtMQ2utcCi18lQcApOQIA9t+C7nq88uhBYoz49pzZWvM6oIYolC7hVZPIEUTIjmckDuJC1/OZy74dU1XvdOFXb51NpqJdCLQstUznsb4/evP7Hvun/75RLz8+pNsQKsS6BahN50sx+iNH1JRkqPZTn2lx0dkwKDQDDOSrE8ATeSIMQMpA2f46IIxXYvOGAaF/nwo8pUC3HSaMV6YjMoUoFLWNwiAb4GFwk2CmbIKWN6ImFCmmQEH/O8TUc2l4szAMAMNu0gS2SQQ0aJ98TEQ7jUcFIFi3fXp/uqUnlEchhm0Wim6vY2fXbcxkW2lMVNYzyatLSFqhFSlseapNy3dGXhJ+Rr/f1rZiJ6EVcTzlUotUBpmUvXRvr7UkwmnbwtZaZuQBNKTs4mt040Cg/WbCKsrQx41ja2x2YKu3km3Q5qaKOif5iBhrzEMRSEAw5D2ImhlfUeMZm4qJPQtGyJPBFqEqYKhK1UD5XRKgK0iCVdxIhKT5iEaYdFHNOj1PgPJ2P0faKR2X7LQ65YYwzp7qqwL8o4NUiWHaGqPZfnar5UKJ642BuhldkLMHgvuR9S50AhCajdanUczssdBw372bhHZKp4TSdOxIT0RxakUSkC4c0CWA3aiB94WgdpHdP5IW0TOzx1X/SmUba/SiLxyE23VVhUAP4ptnbZLrVKVxBCq02Z+LB9lFYdM/Kphw7LSfqMKEx0/az9QRoJMJMN9GW3Mem2JQGPBV89bl1O/WeGQl9/hW110vIkI2bR5413PCb88+Dz0Ckt+k0AilwLDnQZ6RYjC5d8FTPspPsHKKiVlk1UDfQslPGmiSt5Ep/GNibpNNn2oyVCNzQ5ETAKhEMcFjCaNh/GkhsN4/5ey5cERBBpJIwfjGq1mZoXBYWn8R9No9IctzwM/0k4tnurCVBXpiqrgWjP/ntpXd0piBtjn2wqJ/eMbRxKZDJwTchkOWm3TbQjwlZHLA+uvtmANxahF/3tuHxlJIlm2+hyJygvhBOp2Me+lEZRmiAPlPxON51cJpzLcj9UXWnh/IqrOcGZ8vIqPWOAazTDvE2BHQqHhxLBUBUiE9I7kxlUMlebIlK02kWAaKM9daSVQLrA+5sUZaVYnj7Qjy9X0+om+MyHX2OM7i7HHdxY7cl2G+RIyZ/OQu0V3YhWy+p6hczEPuUIcSnCh8cIfnLYOZ3/zwUjR8ASlOk0KwAenBsHqY+23H3oOfnnweXjs8Vn4v0POtSHI7pyQRQJNEFbDhKk6awxDSuSpQnSJ0NNzyI18o8Zx1Jg21GSoxmaF3a4+qxSzSmH9eJTVf1A1QTDte/m0qBKRIZfqRmI9XEI3Zp/lofcksqJsg8K3rIxvBQFAEkrvPl0d42dOo0RVKKoWcW4JD+2T4MaPBtMEFk2QMWaQZQGMcdNXXD9thWY68NCHj/cL7kingafGWtZLZzhe7bl6lRVQR0LZllNmIzAacYEkki4nDv5zSiWQxPZYj3YT21rLQ982s9qfUrOldCleXptfS9X6gEhLKGxlh8gTCV5DN2qv3WNASWiqeh1PPDURpTJ9nMhYOU3Yb8ZIrS36XsaB7NOV2eDaMtphIMnQinPMnTFm9VKq9Kyh96sG2VarTV5f5iIj0iL0rwkDhUYrR6e7+nnbEvCLe3fyZGMiyaxW1NaGZe84CbtdfRaaUeFJTO6qQ0pzdIvI2TNI913kXucWCoXBOPX6uOp4fdg38beRl1Rt1v9WA8Bmrhmq8dzCzt88B1FUlqa9PsdNNZETNZEOn3ElNMa75PujAFZOb1H1RkoOrQIEoR1vl4qjkeR2gXVj4GTCmIRFXzvNVwlUOU1iYyE4YKxjcxnQaiehVPXq3hEoW0XiiCJpheC8/3kbEr967eSmkZZ94ATs8Z3FmNHswYRAitAuQooj1wwGQDOyVgGFFgiNsiG4TugbCQUeGN+GpJYmeb5URccUv0EaIsBWVqAEZOW4UG5ZLw/RTjLv/eLF0IZjRa+FoaSHscwSssjphJKgQDMoMFbQJJnw+WaRkD4hHSgrNKQPIcRuIs36MhmvSfIaEtc29HEN7nMMxilS55BNi3xVhF+tAtH99P4+DqSid4qEArZg2RCPSu8nqqZS7htnBtwRxEWfvQAL93wMr5izFItf8J2+bdBFDVlFUHWwCiK1NhhYOfIpvVEoAE9ESaAfcoVUhpjbHMeKdCNWhmrN0LShrgzV2Cyw9/dPQ7ORoRnl/uq43cgQhdIHmQpux61XrbKhqESEBNMu2h4+YLXaejIG0LKc3JEuRV5p7kfsgYrnTUVPRFNnglvdBk2o+ZwqXlYMqgJtuuIspHCWAMLqhAzZApSVgg3dJltXpKnVGHWyyGeSkaCYRvPTIkSWBz63q5nknvAoTfoamsqy2yXDRKW5dbyuTGZRK8L6zDCvMwKqrUrrF0MGhvYx5ty8GcYdaWqERekBlMcYzhplRcARLyu4DXzFgTReviXCSmIUVNpc1YoOUGqXiKRTNSnk7rO6CkPAVg/4ZJX3qGqHqtUi+p5U2zdJVGDP754xjWd808A2W434lmyVjNK4PGMGrUaGrXdbjtE0wZUPvmi1bUwUOQvnSUY/V40VqfpGFSe6X7uWWPXxQgtEQiJVG7e+wLCemqGNurebNjatv7I1aqwB7/zNexC4aS/y/vAiVafToVFkY4Awkb5dQplBWjHAlNNMALwBoNIcTBinF2JApS1RHZsv2yU0WWTH/AsnhPUTJbzUk1SXN9IlkZZJaW5bS84nqZXkPveLFr3qZ91UsPStH6u0Z4yvxJCvkJo4AcfKhZ1IQZUsFFp4kgTY4zMj6QGgiA/jfHakb0H6FpsuRdaB0EjzAIXTiNE5YdXvgmHIvdDebi+VAVIZelJRFTUD/bqw6uJI2+7JsE9APVGITai2cQot0HFtGUpMt59Xey0Ute6qwmw6FlVzvyrxAywhEmLj+t1sDJTVQdVnQ1C9v+WqkqJyEVKFj9Fh5eACXaQYwzCaJv0WBrDb6RbWJmLr5jgGosznkOnKMSeyT47mNTYv1GSoxiaNQ276EH63fFsvULRTI9oLVAFLJJjTdORK+MWxGea21eSE0w3nT0RaIYIshI+8AMqA1apB65oIiU1op4mlqimbbY0FQiFyvkSBM2mrXpVW/5jSH1CqPAROSKw0g0zD6T2o04DxNPJaKsqDo4m4SNiWZRRKJHHhDDHL6poxzLf/jLHHgbGSFLSiHNK1nOxzGAacXsMmz5ftwyrhHUp6SCLpR/QjIb0uiEgMOQ/7tmTl2lhp7sTYlapcZXKMBPBVEkLZYURgyueWr6tWjapVjapRI03gVVtw5T6UzthEjAD4KhpQVjUCodc48r8loBXmllC6qo2fWnTH0ArwyzZYvIYsvzgov4tDsZ3cjIUsSa7h/v9yK8z9NFkUSARCYTSPkSthfaxcpS9wGkVLhoK+qtUGR+1APW2oyVCNTRYLvvhJPDo8o2+xBNB3JT2xtUDaHGU4OnnkF9tWI3PJ5hPiNCpGgFEsfehqX6uL2fZX5NovVPWhVppvf7mqCIlsA7etaiK7r4i4cE+lrAC7m4eQivs/ysZY88Px8QaWveOkDXugpwBjGLI8QBxIDDZS28oztlKXyQCdToLxcWtumIS27UeiVHo9/R0mN26lbQ5Zt4iQqaBShWEY7jW8toPyysi8kiIRALvYNcICSVD4dlaVmEg3Jh+5qBAb5FoSmcLtC4HE4KEz2KMRe1qEiRCF3H63qhWL6kLN0U+WyLG4GvVRKLFajla1PUbf9YEo867a9C+JsG07x36PFly2ZY3Zj6QNH9gLlHEZQP/FChlsar06KamGCHdlaPWCpl9/RYaLVbsHwH7XMhX4oQzaDoHOwcYkQ+vVIjP1aH0VNRmqsUni5defhHBmZgkEVv/DBGC13wU36HRjZCMxeplzCnYLDuURxaFEEki/eFIrymju8sfKSI2q869wlSfAZkP5YFE3/UTi6jhQfmzXXqVbcaXU3EcodLIIHRfkmoTWYLGoeM5Urf5jl1u2KWHh15agnWSYNdAFY8BYLwGN4itl9T4iVI4QKj9uDsAfd8ZsvASJUunYUu5ULw+9DUHfJB4zfW0IIiZVwkPZYrISj0DPo0pP4dpy1EobjFM/jl/1giKRdySkJ6vkT0RVCIKZsDBXF8WBKPMVpGpLlapaVFmq6n+qr6cqktIcqQwwM+75xHWgP3+LqqZRs9/kcXMHYzZ6peUqvozZahC1taj1rMGwqtdYozdXHFJlkPn2pnGt01wGPvbFGIaxon8qjyrSvopHLvdO60ZWCjU2T9RkqMYmib+uGkCrmflJLGUo+6dsDWgw/0eRc4PxboyBdooZc8fQTjKvTaExbSI6uRQ+4DMQNt+p3e6Bu1aZ1yAEyk+kSXclT20RMuTjlf2puiBXF17vR2KY9RFKI/8eytjKUkIicJcSr7SNAbj7jYs3zgFfB8ybO+LDWEe7Ntw1CBTajQyDzRQaDI04B3eZbWRXkCuBzOl1lOYYzyJvKul9gjTzlT+qxFgS2S9SbkQlcbGiV+51PwD6SNBAnFa0OKU/EZHVWEgETGNW3EXLtcmq7TGlbaI5TaBpw5ApqzOiShA5WVdbbNTaBYCxnKYZ7ZQbEWiqmJE2pappAcrxf6oMkWBbG4bIOSXT/WUGm9kidUPNMEfANNphjlQGvkLImbWuIIFzWoT43d+fvcZtrHxyoO9ip5zQMz52ox3bMN5GUHpVAfBRMCR+r57f2DlaV8X0GwVmGm41ANRkqMYmiAVf+BREUCZM01XxiicGsarT8H+MaBKLWi5hqLwHDgDfmiCNCnMCx2qlQrgJMOY8Bm2VyN6AskpAOgK/WFfiGDgzXjRtDEPP5SeVC7w1E6SqRtLIKzqQ/hF7eg0RhE0xb4oEvLkSiKMCgdBoJxkaYWFz1GRpukjkgQTwNN1H1TmKPjDGVpXI+JH0MLkSkK4aUhVtp0UIDTsaPxBlaEU5ZiVdNMMclFtFrsIRV74FQm0MaoNSDAYApCpEV4Z9VSaqSCl3PmmCCEAZDusWZTo2VCWYqDMzhvmpsWo7rd/VvPyTPFE8Tcey2kqj5wesrAxFgRXl8y1QO1QV3wPlhcuqThM3HfRJ/11aE3b5+EVggUav6J/4KpS9OIqEQixKg9Vc2YokfY/WZHNA91OrdmMbLjJj1vtWw6L2GaqxyaG1zbgvZ3NmMDLWgDEM87d/Cre8+nws+t9zEUS2EkELiZ06Kis5gF1k1uTsSwRp4phtHBXlhZKBJzi0TaUZBpIMY2nsU+gFM/7nqh8NYwYw5dQRjZ7nWlinYNLQwO2/Wxxt7pklTiFXm2SbjMiEJTa22kIJ8YIZ5MYKysNAIUTZjiRBtNVc2AWb/Jr8yLhm0LwkomSgabQLbWXGk1/S+gRMYyhKPVEwhnkPGaV537gzZzYvjPZJVnQe1MrsVbpL1BYJ3XeByDlQIUpON9YMCnRlCM3MGq+4qa3DYUmxlv0LeyzsIEBVR2S1K+Xr6fta1bsYw4AJi3MzzDGeblmmQ0pzxEKiK8uBgkKLPu3QTQd9cq2vl4t62GrGOJThNnqnsA7qjbAAbbFqpkhaMB4a36pPAoleEfr/62tqidYO1Jsn6spQjU0OiXOIJTF0q5mh3Uox0m3gxdeeioGBHgaaqSc3QDnlU73QocWUQItXVRhd1QYxBrSSHBGZN04IVZVKYDyLy9dXYhJ8G8O9H1WlSCBdGkEaHypLHjNVcXhVc8AYUBSb3vXKcKdRaT3az98rQh85AthAXOsELXwuGVVPRKUNSE7U1mag8K0H8m/Kleir1HDXZqIWFwDfmoiE8m7AufMbAoBUhr6aQseXMeOF3SSO5sygU0R9mi36l94bKKe7KNsqCQrEgfRtK6Bf8Nwngnaj9J3CEpWJgmtCJEoXaz8p5p4rK5ER5LEj3L9UfYoD2ff93dyx+7cXI3UkKHNGlUB5/MJAYe/vP30MSRRLCG6cwF6iERd9nk2p7M8cI1RF0fR8GxJb+OodTX9udOhpuNUAUJOhGpsoummE4eEmfv/6M33LKKQxdVH+ASxjEowXWwPUZjJ+FNv0kZ5ySqm60BE5orHw/ogEp02QZYvCmzo6HQdQ6oOACQnmMH2VhaouhaodVpNQepZsqsjzoE/8m+U2XT4tQj+JQ/YGSVS4yBPtqyKiUv2o2g2QlgPAaiJpOufaLfZEepTmGM6ScsLPMLTCHElQIBL9o9WZtJNAgXtt9Thrw7AibfpqElUEq/vgtWTu9USi6HuVa9vSa4c5IiH9+R+MslLD5No8QUX4TKPZfS0v56pMQuuJfjZ9E5Uu3067SoY0HKNZAim3nD/v1Sy4VIZea0Uaq0go9LK1V8JefO2pmNnueiITiEo7nRm0wtx7FJGjNYC+iyXAfoeUsa7V9H+aqoqZG6vfmJEcdZts+rDpXXbWeM7jtkM+7n9e8NXzMHsr7aMZRIVo5IrDcO1yyUoxLQBfiVCGQzP05ZV5wzpn2icV939siRBR64uu8Ek8SaQnqExF0fsROCxhU5p7/yIia1keoOGyumy4q/Zj9LlzVwbsyKsyDK1mtmEP9hSw9K0fw4LLPoF5Ww/7dhnlxHFpkMQFur3ICXglYhc3QnO80oe1aieIdwS0skABcAG8TsCuOBqhROScqautiCpxJD1OK8wh3SRhwDS6RYTATfaFQiHiCqmbONOGYSRtAKh6/8D/Lnj/oqgNA1xrit47YNq340h3RN+N1NkEqAn72wpzayVgQnADrz1qhTmG00bfaD5pk6qv18YK3bRhPhIEKCtXQbBlXfaTNxRVwKoGlNV8sDVBMCuUJxLeCAr0ZIhGWKCTR97zi6bSaHy+6vEUCBunYoz1q+oUkXWqdgGvtqW5kU1S11cEXXMhjy3n0qHGFocdvnQ+BoZ6EMyg4RLQKe2cMcoX4ygKgTwPkMvSI6acRuqvzgBVF+GyUkRj01VBMxk8kr+QfW6ZUQWULTf6Y0jvnSvrqhxyhbwIMNqL7USaC4GtmvdR1cM7CzsPnUIK3HnYmqdinm20hnqWmJAoWXNbcREaaRYiiQs04sITocJppahSBwBpEaKbh36Kh/RSuRJIi8BPApKxYioD5NI6TEvXPqNWhTQcAbeTRu0wQzMoEHHlF0BqNWUqQMA1hrMGOnnsiHSp0aEKYlUsC1jSOpT0vGljlZBIw62bNDNrrAxQ+8RPezmvq9QZ9xlX7ZDOQ4cqXzS5SPYM3uCv0iLiMD7zzBjmdXITjUU3dzSjAq0oRxxINJ0ZYu7IX8tV4oaa6Rpfe9ANx2OrVse32QDb4qyGvaaOwGrDbCWvIkgnXVYqQ+9zJNw5ClzV2U6plkaMNTY/1GSoxiaJHa84FzyhYEYSkhp/dQi4WIvABq9yoRE7wkQLDP2Rsq0puG2VzsdVrRAhcleYtGBr2EWYc+NiOcq2DZEin2xN7resjEuwY+aFJzyMl/EVNFItFYd0rRla/JXhGB9LNuxBXg+kvQi5DLzbdBzZ1HqleF97prQksIZ3UnFkMsB4Lwbn2nszaW1bPOThRHosG3hbktqi0saiWzMoEDBLojzBdOQhca0yigchUlUFtU2r2hDODFqRrcpR5QWAF2hTS4ocwwGgV4R++qvqGaSNtYCgBdjun/bxDbQPtkop1kio/MQZyupl1YTUa4dc2ygJCsxuddb7PG8qmNmwtgdScyRCohEU/lh2isj9X19duLzzN8/BWJZY4un+f1Xd6wF4XzDAnvfhLEEzKKBhYziyIvB2CIAd8a+23L3vVMW7bKOhdqCeNtRkqMYmh1f97N8RxQXaA6kNSl1LnGBflILklZaV/cNIuh57X/k6e2VudSnUhqGFkHyMqpqMKsrWFkNWBMicjw6NgVv3azt6LxVH1030hIGC0gyDjdRtp9R9qMoEC1WvpOJ46B9OmfpB3MCoHldL6ESfrqZKMHwEh1vspeIuQsVuIy0s2cwrFZpqvIRx58W21srqnnFaDSIdqQowmsfQE9pJdn/I6LGMPQFKokMtESK7NB1YXdjG89gTX6rCEDGqGjxWjROprSrd60joTY9pw6yLd2z9mQrNsTJt+tBYX5lyxLla3fTHqiKirsZRVKfStgRQe7TrzBILLTCex+6CJfQGnosuL+0ookgikwK9IvLnHigrgMpVNMnlHrAXIiRw///tvXmYFdXVLv7WXOf06dNNM6MIOIAY54kPvM5GHJKo8WeiMYr5jMYocUjipyYmgF4kA4nm80uMuTeBxOjN6DwlqNFEcUBURCSoCKICokAPZ6h5//7Ye+2qambpgZb9Pk8/dJ9TVWfXruLsVWu9630BLrpJwWaDMIp2RFYUyN8vJPjZU9CYUqDuKijOkMIOhZG/+wEamhqhC98r8m4C0kAE4F9mVZ9nGsAAJrI/lhDgy/M8soti6h7OFzPI4zEGdHgO4lhHY8FLOUo65yxRJojzY3T4vgXXDSUvKBGLp56kgnpExLbkE2nG7FXwmFLCNf/Ct/UY1eqOmxVa/t5QaNo3RBZCQ1vNRckN0F5zYVsRwpB3kBkGn7esdlLRDuBHpsyeAIDnO7CtiOsQ6QnoGY3rM6WlJQoaLSNGGBtycSM9mDDmwoetgYuy5eeyJwCf90bLhxebMqABIBXKAV4CDRMdLNYRJ7bM8IQJt8qgoInKWBTgSJHExIBjpAulradCjZQNyko68PIqzxpRoEefyVhq2Apgg+CcMhymKP8ZGp+/MOGfsa5S7KIr3rs4/NHvoMHmxOUgMuGaIVwrQIWl0hWGzgU+T3t6Mkx7MPa+m6tPu04s39c1Ju8RgN9fUayjZPN7xROq57YZAxSoioygoSfQ2MbNXwHIjKBSoe67UJkhhR0KQwa3QdeY1BkC0jKWLrg99MTuWBF3edcAwyJuii6f1qnzy9AFkTpDoM7pgpAejW8hjnUU3SBTaoM8Bi1qxJFpKPq5dv4smTphGoLQzJTSKAuUHiNmXNemswFtFOuI1+atAHYknPTC12GYaYmId4ppaCx48HwLtp0a52oaN7OlrIsvSo687V6XJHPLjPmiHuWzQzHTud5TRsU7q/gdJgY6Qgfr60V4Gff4SmTDi02p/MwzMtyKxRXGnFmNGApo4kQTsghplpGCNtIu6swJSbsT+bgoW2UKvkl2+2z7NZV+9cx9AwBNNs8eUocYZRCpe4nuF7pHiTgtM2VgqAbOJhfuvoZ17UWuPi9K1xQAlh0PrrBQiRMdrhNiZUcZ0LhmWNEN4JppVx8A2Z0XJ1xryDZj1CMLXmTJsmg2w+dnSPZZSY664B91llvo8TlXZbIugwqGFHYoJIxbLaRdPRtmdWLGf0xRRqGgKMnwNyw95uKGekqKprQ41xDSpOM8wLvDCkLgsOZx77C6b+VKISkng3/ZZktA6U+qMUPEbOk/hdTUU4dYLEXmhMplmsa5Ncsv+1YPz/zWw6vaGNTcIeeDe2QxVH0blhXDq6d2I1nbC0IaPIrAUVyHLH8mi6wsAm1HZSESWkwY7/Ch0lN2XzpmSXRvEVEdSNvkc4rColxFQW0YG2h26jlOzsYc6qm1OlueMjPmrZLfpKedi5rG0Gx7aXZQS+0lOs8DcYMIpIBN50v6Q0Si/qQQqFvKNRgaF7W0zYhLFwhOWNZxPkl4YF50AwxoqKJoB/KhCUgzxUHEmy2IH5gtmdK/We4YzXkttOV8W3osS6DSE05wtXoSWrL9PwocKhhS2KHwwkk3Yc2KfrnXKPtSCywEoSm5ODLwEAtUNnMTy6c5kZ1gqeI0GXSGkYG64PQwpqHu24hjHX7dkiEY8YmotEXBFP8iZXCtCK4VwTJjFOxQiPTxTh7LjEUWZMNFLfs7KSvbRix5RzsqRt36E+hmIrNrQWRwRd/AQhCYsMwYDQ2+DBA4j0KTQZ9jRrnuOUNncOwIXmAK3oZYXERp0TZiFMmHTGTNEsYVlktWIIMH24xQDyxUAgfV0Ea776IeWZLkrGsM6/0C2kMHtciSJbZmp44GK8iIMaZ2IFkNpLbAzRlzZoMpQsn25Xj82ESU6AiEyazMGon70tZ5e3+z46EiOtFKjo+CFcCLTVmeofPWwVKvrKxERCazRIR9Eqtc+Llp3XAH9A6C2ETRDGEICYNaZKFk8ocXL7TQWimgfT3XiepXqMlAxbXCnKlunPB7lYsvBjKQ8SIT7b6LghD+tPQYhpagZPtwzCgNMDMlMNeIcp2m/DiWzNQp9C2oq6aww6FpWHuOJ0SlAj/gqekkMWEIET8i5YYhDyDCyECpwNPdupYapzIGGWzw4/Lj2zY3HNU0Hii5xQChbcgMAN83JWMXhEFp1be57YbFF23KFNhWBC9IPbQoiAIAanahhTZOUt0kAFIEkm2kK2ZHweDRH0nZAAoIkST8m8RNic/S90t4ulmixZ4yZDH4+ZpGAktLoNtCIFNP4AUWkkTjQabgB5mkx2Sk18WjTExsoMH2Een8ulHHFwCEYhxhbHCLisCR21BLfvae0JH6kGW5PVmNIY2l4obZLFSU6JK3k80ybEw8kTIMrhZxnSEtJe7rLOUVkVBlAl4CM/QESPSN8ofouMSF+aSgwfZRD21UIh40RokOW48RJAa3QDH4A41hJ2iwfS7AmGmjp8wsL42ZGNlvHdZ5xRzpOmFcpiGR/9fToNKLLGnCaxsxvIgHZgDvICTyNDfHjdCjBjrbW+pSZTKJT87/GIU+h5G3z9zke4bglTDGF6dq3UFEHWMaDzrS8hffJ44MxKEhCc5xklcRppIXvZ9tZQf4MRnjhqHZDAZxFRjT0OE5qAU2wtCUx/Eik3sdCXuGoh1wkTczNQclHzOAk2ZDsaDR+UkycWDhzbOu78pp7jIc+8S30OEJDg74QlELLD4fkcG922wflrAqIAkBJsipAGQXVpKk2Q0/4tk+KilSeZNkFCgzSB1hBApobJNzgbJBTmfBPMrokFUHBSd+ZCIQvBCAOoMgFaazIGd6CqIoU5gSnjU0Ox50jaHFqcvyTZZDBEBq1VBnVCCCPT82OfdFZIXSB4KUnB1vJBCibVIH9rQLra9j/N+vlbwtkp+g+Sf+VdEK0NjgoX9zBUFsohI4PFMpAp2I6aj4/L4tWBG8mLSq0mtuGzGKItNI153Ks3SvWEYs2/hrkYUo4d8TjPFuQrouPdrFx7rgRwGACoYUegn73DsVKMQ4/NG0fXzU72cAAKo1/sVFmYQ4Ia0ZEagIDgB9WZkG9wBjov7th6Yk9xI/SLZx+xa8Gg9mHCsl+spW7djgHVEicEr1ibj2jWwLl91uafePF1hye/K0IgVhgDIOQnmZyLvggQI9ve7IS9iKNf0RhoZc1AHIa+NaoZRBoPIZwANJy4yhISWhZzlDOSJzhrvBg5ssXwxCzyWRdh70WVkBRNcM0ezU5e9ZAjRlC0zRCZYlH0ed2vo3ZsfQaPvyWlLmgI5NLfetvoso0dEa8G7A7HGyXCFa2AHk3M5tgy/WLHOvpOrGGcJ3ps2e7GZSLa6Na+70Raz+sAmNtg9XcK1sI0bZ9hElei4ganbrsIwY9dBCh+ekD1IyIOZcM9uM0OG7MhtYtNM8DrXGA5CcLeJpmVoCTxi09nPrIAPgurAGAXjwahsxDBVh9EmoMplCr8EqhKh4Nr638Az8ccnBcBv4wtJQTNuidfDW9sYGD5W6A5ZoUgTNMmNuAUGZFztBkvDMAi1isRDsI34RYxo0HUhiHUFoQte5eGKWbJotMRCZVZa1BOm56AYIQgOWmZbByFojGxBpLJGlOkAIMjJNPpFx6450MWwo7Hj2GwTHDVBwQsRMk1IDrh3CFhyaghXBE8KDXmzmSMYNBV8Gp2FswA9MWFaMBieApmnSvJbIqUBKaKX5iyNTCuQFkQlbPJUn4OWKrEcccW7MTHaHgpl1XlFmjwBOROamqzzgoqxNtiXbNUNpvpt0Ijd7oYVYBF9xokvxlmzQQ1mi7HmFSRpYUvAGpIFVVn+K/MuyHCFNY9DZhiro1cDG66dP/djXeUfC6F0/kMRzKotJIUstyWX04kRHyfHhhRaa3DrW1YuyVA3wErpup9fG0FmaPUpSnSjSjArEPZzNxBl6gvbAgWXEMpPX4ATQY14qs/UYmtbz3mTbs78Ch8oMKfQKKHNiGglebdsFlpWSUiPhZm5oDLaZZgMa3ADQ+AIXxQaqNUdyhQpuiDgyYFl8MYtj3pJN2R1N45kd3UhgmDEsm5OeXfGvqXMndeKx5PyfkJYqXDtCFHP9myhKhQYTESDwc8t3HFH5B4AkS2ef7O1O5ZiRv/tBd079x0a96nC+T6IjEQs2qW37okwWxAbCTHnKC61cBoPmMQoNyemyhBJ1GBlykQIguwaBtGREJqupSGYivaTIsoJa0amslG2HNzMdYTSWmhDky/JFAO5fVbR45iBMDFRDW94PsgtRS2CbEQpWuIHdQ5TkDT+pVEYka9IjouwGE9mjrCdZZ7PfzvOYBZVz408IX2jk736IemTxUqIoPbUHDoLYgGtGiJiOuihXBbEpZREswRmiezVOdDjCLDhiOmqBBcfkZfZIdA0SSIOMhDh1MKEBlaB/scr1iMRnEl+tGtpwhTfcer/Qs5OkWuu7DCozpNCjGHP3DSgXPJTcBK4VIogNvNPWT3Zfjf7LjYBmIDA4QTfMlC9sI0b/xqpsr25tLYLpQD3RkMQ6TIt3b5lGLMteAF8cDMH/aXAD2U2m6ylRNRILfJxo8KhFnwHQOKFZNxIUnFAGNlXReRZGBgJmwLUjuHYku6GaXM4ZWV8vCv5TRrBNLPhhwnWG+DFTwciWARXsffcN+Pfnv9/Tl2eT2OvP/xstLXUAovRjJLBIs4XxTjxPY2CJhmIhkNYaulBCds1IBkm2FcFujiRPSHbo2WHuu5mMdnlGjkm/KCDVgqESEc2vH5nwIiuXlaJMQjW00SEyCK4ZIhAEbIAHNcxIOV5lx0PJCrh5rmhXh57k5BuAtLPL1BIkGg/CLI0hyWSCqAyWtQEpiSCrEtqSJA0ALU4d7aEjhSQNLYEBljvHLI8lNw5xbtnX+zLGjFglifpU1qqHNrzIQlFYc4SxgUQXopYGN+RtdDwe1Jo829bqFdBo+/zaCKXpemgJNekItcCWZcwsJ2uXhjasqpZTg9eIX+cIOlwzQhzqKFpBLvsE5LOR3Q4GYHva41UsJPHJeIRQ6HPIfunEsY5a3YYttH5c0Upd8RzYZiQzCNkveduIYdqx6L7SYdrC4kB0OOl6auWQ9YoigmxW14X0arKvORYvwbg2V5gmEi8pY1tmjP5NVd5S74QZfgcPrmqhjUrgyBKeF1jyyZ2Q7ZjTNC4YScJ6lPHaUdCvsQYgJTFnbR8Mjc9JHPFAwTZ4psY0OImcFu5slkP6s+lMLlB8rvg1bHS48KChJamvm5bq8JD+C5FXiZgtx5QhE2evPS1aQUaoEIAMoKh8FojMTiW0pX4QwdAT2EYk9WdMjWstOQYX+MtmhCh4K9u+zPwQAdjLtGATAfcjrwgvMoW8wMZXuex9SuicRfokIFtejBkJfPIMMnne8c45Q/D9eHDiGhEXaRRl04IVon+hxgnzsSnuu1R8MRaaY67IBjlGhDA20BrwLA8JZ3IdMCYfngiMaegIHOxaakOT7eVkERT6DlRmSKHHMObuG+BY/IvKFG7wQWhK365YEJhpIdt38GqsqjXmlHopK5QwDRBBhKYnkgwNUGeN4FSIoIhnIfixdZ0rSOt6AgjBQ0NPUPcduHYoidq2zQOiohvAD01EMee1mAZ1Ihmpd1bGLoL7ohm5p/cgMKUInK4xfNTWgCEt7ZK4SwEfdVot/eJ3e+EKbYj9H/i+sMlArqyXzY7UAwthZMAwEzBxHd1MGYKUo7O+a0mii+xS+hQdCn0hgJeuAMgFiGeA+HZUvihYnMfTETry4ZgCIuoqc4QWDC/fbT7AJP4IKV8HSX4f4vLwcpohS1n0mh+bksCsE7GapUKJWSNYLzJzc5gVgtTBg6VsWQzYUN1Y17hEAR07ZvonZiEe9fsZ2Hu3BNXQlh17VMKiDBkpdcciQ0Qk+7bART200OzWEQhz3HahRB6LDrAo1uWcFyyetTQzARIZNHO+YPq6YfJrUQkclGxfZq4NPUGQGIiYDlPvOeFFxRnqOqhgSKHHUCr48AKLBz9Mgye8xXZrXo/V1UYA4MFSomHPlrVYWS3LBYIyJ0SglQq7DDDNOMcPCkWQQvuR0aemxXLfJMMhYYxzmBrcQPKN4kSTpGo/FFokSX7x8kKTqytr+RZ86mTJlVME4diPNDw3cYZ8fe+7b5CkaR0MTGPwwpR70pvY/a6b0FhO+TtZk1DK1OmA5N/YZgw/4Is88TKy2Q1OKAeYzmCIbJBpJFLrBQCgcdPXzpwY24y5wCMFDHoM14iEMasmF7asro+0xMiUjohnRN1XpC2UVRym7WghBsS17FQOoYAcTAOLU/0gyTMR3CQvNuFm1LGlYnJWfDNLrqYMmAi0SlYgzUmzY6HxEzFd12KukvwJ6CTbZch66GBosAJ0BA4PaDyXq82bIWLGs3bZjC5jPAiuC54atczbeoya4HNRsOgYPHAuWAHafReGyPaYeiK7Do3MNFp62oFI3nRZCYcwMWR3WRT1oKwzw3bqDHXZSPo8VJlMoUdB5SdDY2hwArSUalhbbwDAMwamnqBfoY7V1UaEsSGFCHVB1g0EmREQVg8iUwMIgrSWdobxp3Tx1Cw6wXSNE3VpEYky5bqs9xGReKlsY2U+B+ABl2tzGwqu+os0M8SE2aOA1BfK2H8Qxgxag46aixdOugnzTr4Jfmgi8HaMZ5RB/TvkOadBAURQkmY4oliHa4f8NRGMhpEh54XPYRrE8syZJjWGDJElpK6/OCH9ntSShZ7AJWEdGtoDJ5e5oXKobaQlKz/imjKB6PxJx5B3ts92lxGJOoxTAjYAaaNCvxdEhxmJItLvVPLKBjgUtAGQopBZfg+5ome7zgi1KB8cd7buIF2chHFj0Y2Rq/saHCExYGoJ5/swDSXH54ri4v+ZF1myXArweyxMUjFQU0+kOCJd535uPXedS1YAS+fl7fbAkYEQ2W1QVogfN5K8I7q3TD1Bg8UfomjfTwpna2fDjvGtq7DTIIwMSWYGaGGAECvkbbMdgYOClaaaE/CavjQx1fLltKwcviSYZr4gSf8jAW/hJhVhPWPGybMb1J3EpCYOETgBXh6KxfG5vUReM4japHXGF+8PP2pES/8KdDAsPfs72O/+KRtYJNz3v/4n9/ei06Z21VRvM3b/fzfBcUPYFrWlp89K5INlZeacBCw1TZCEEx1RzDNpBYcvMqTi6woSMXX20DxqgidEgWKipURybnshdKQywVic6IB4IqfyKb8H0uCCgqTOwoUpb2zDgCHLL8vqE5ENA3GTaN+y7aMWWaiHluxkA4AkTrNotL3kviT5QCkLIoNTwoirUaf6VNlxIhM0RSIzYWqcQJzVZ+prOOSR70IHw4CGWIpRBhEPHgui4QJIUPEdKaEBDWh0PHHupNAtvMRE1oz0pIinZegJDJakKuaRgQocroguOG8tbh0f1Lh4I72WzQxqIpuUaGm2z9SS3DbdDqVA3WVQmSGFHkODHUAXrdC+KHmQsKKhMzx74g+wa6kNUaxL/gYttBRwOGaUy9ZQFojKYRSkxMJmoVJ3ZHbCoAUp1lGtOeiouPACE15gohZYshSkaUA9NCUZmvgmlJ2yjRjNDXXpmVX1be6ptqwFL5x0Ez78qIwXTroJy758HdZ+UMa8k28CgB3aK+rgh69Hv+YqSq6PghXJOdfBRCs3coGQIaQIGpwAlhmj6ttwrRCJKBcVREDFMz8M9cBCJGw8KNgwBfcHQOpKn+iyy47I7tRtls0wke5OxHRJcHVERoiOmw2EshkECqyA1LMuS7LPmsLKNn5oucCGSl7U9QWkgVZn4jNlIAFsoGoNIBc40d/pvLP8fHXKBGXb9blQ6I59n20O+z/wfdQ8Gw12gPV17jO23isgEoGxLfhlQWyiYKcPSzp4KXFYqR2OwctousZgiy4wusaOEaV8Q/AAnzJHlFXKBsCV0JbSCSTimoigjLbxIgt1UcKkoLxHiexJF/xsA2bMmIHDDjsMjY2NGDRoEE4//XQsWbJkg+2effZZHHfccWhoaEC5XMZRRx2Fer0u31+3bh3OPfdclMtlNDc348ILL0SlUtnWs+9SqGBIocfQYAUwdIYP3+2HWt3BMUPfxPG7vIH5J0/HcxNn4IqXz0Fr4MIx41zXUOo8zn+C0OjEBUq1fbgHFn/SI3Vq8tKKmSbbXi0rvygVrEh6hgEQrdxMlswoo5TVEOIkalNmc5Z//dv83/OulcddfsE13T2tXQLSDDJ0HvwRGZW/x7fJChFGYhsuQqjBtnj5Qje4ECMvLeg5TzFDKAhTOZQ8wKhtmjJ4WV5YVg2aDFJzXVQia0MlJwqiDJ1ryvixKcsq5CW2sdKY9DLrxFeibQ0t72wPAK2+Kz/X1DfMCMh9M2KQ5F9GQo7ZrjxLZC/pB4Bs9+782brG5EJOxG1+nL77pB/FOnZrWQ/HjDZwf0+YJg1tLT0V56SMZZTwpgzX4IGLbUSo+A7XuopS7zeAB1Nhwg2Ga5EF1wrl/2niB9JnRKLZg/6/mxondQMQ92pqAkuZvY0FvJ8UPPXUU7jsssvw3HPPYc6cOQjDECeeeCKq1arc5tlnn8VJJ52EE088ES+88ALmzZuHyZMnQ9fTcOPcc8/FokWLMGfOHDz44IP45z//iYsvvrg3TkmiT5fJpk6dimnT8k9BY8aMwb///W+sW7cOU6ZMwd///nesWLECAwcOxOmnn44bb7wRTU1NvTTinRuPHPWzjb6+x8yfYvhBK2HoQ1EVRpr10JL+VtlFK050vvDGvBtJBk1guc4Py4xR9zlZu1a34TohAM5Dsa0IYWTAtrnlg0sGjdCQXc9ilrqNN7o+Ojw+tkbXRz20UPNsLD5jSndPW5fiP/52HeqhiQWfuVG+tv8D34dj5tP/9IVO3XJZBJEpy4ek18R/h1AF11GJbVhmDFs8wZNrPcDJ0AnTYCBVjmZMk+VTWxCvgzjtuKLSJgC52JH+ThZZywoqmcrXNUhisw7uMl/PaBJJDzM9Rp1KLuBZqJIVYL1fSIUdqUQlslJBbKBkBYiE+nCCPHckEN1t2VILmX5KOxKRVcpmpiiwo4DLFVwaXRCzKViKkepb9UWMvH0mho7i3WED3Cq82JI8K1NIHbhmhCjR0Wj7qIS2LFPqjEm5AoAHllQWCyIDZdeTRHoAMgNJXapNtie9ymKmCzVyBt2IZQZS0xhApVPRVUiq1XGiS+FPx4i2S/ZnW9HT3WSPPvpo7u/Zs2dj0KBBmD9/Po466igAwFVXXYXLL78c116bPhSOGTNG/r548WI8+uijmDdvHg499FAAwK233opTTjkFM2fOxLBhwz7u6WwX+nxm6FOf+hRWrVolf55++mkAwMqVK7Fy5UrMnDkTr732GmbPno1HH30UF154YS+PWCGLPX7yU7BdPPixiQEu1wKpi26qbFagFqSv2UYM24rkYhVGhiwREGk6jLiTfRCa3MA1k1EgLzDbiuCKlHfMNAShCV94asUJ9wwLM3+bIqvR4TkwNJYjVPcV8ICOYeTPfwIAOODB73GpAWEaS+3tlAHKqjXTF78f8YWJggLP567epsEDxSTR4dqRzPBRZo5Maam85EemzOBl287DmNsu2EKh2RPGqtQ1FSeaKIPEMpAga4RaZEm+UJLJBJKJK5C2yJsZEUcg5RWR5pCmMRTMEAUrlBkCClCIp0N/A5D8EwrEiibPONB2Wejgwn9Zy41sJomQdAqMyraHZtuDLYKySASGCdPwwYdl/O3oW7rgLul5OANrKNk+ypYv5xcAimaIkhXI808Y1/QBkCOlk3FqIAjUlh6LbCTnC2VLWZTJ0TUmAyvXDHNZtVT3im9P2aGsMS9l++i+ofspq0HU7egiBer29vbcj+9vnS1QW1sbAKClpQUAsGbNGjz//PMYNGgQJkyYgMGDB+Poo4+W6zLAM0fNzc0yEAKAE044Abqu4/nnn++qmdlm9PlgyDRNDBkyRP4MGDAAALDvvvvir3/9Kz772c9ijz32wHHHHYfp06fjgQceQBR9MrQ4PglIBvtoaPDRXnfx5voBQgmaf8Fxw1W+cHqBhbXtDWmgpJHUPi+JkRp0mPBOplrdBkt0xLEOTU+klhEAuHYI1wlFuz7nfBDXKBFfZlLlV3ShkT8ZleC80MyVU/oKLDNGzbOhMWC/+6fIhQNI1ZQBSFNKgJenqPsJAPzAkh1husbgiLIYwDMgDILnpadii0HIs0lkkSCNReWCw5/cyUTVy5S3KEgwRfCjaZALJmUGSzb/8k47+vTc52QXMYAHF1TuoGtN2bBsuYvKLzr4wimPzdIsQ0GYiBJYZoEmvzCyBqEsZrYURp+Z5QDRsSkABHjJrBbZXAMnIwTJmIbWagHLvnzdtt8QOwhKBV8GM0Fi5kjPsowq5qEa2JJDlbU3oTIWiTRS4OyHvKOwJAQZW0RHWRgbaAtcVEVXom3yTrzO3oSm+P9vaqkNTNZTDoAMzKPMvdGXMHz4cDQ1NcmfGTNmbHGfJElw5ZVX4ogjjsC+++4LAHj77bcB8KrNRRddhEcffRQHH3wwjj/+eLz55psAgNWrV2PQoEG5Y5mmiZaWFqxevbqLz2zr0afLZADw5ptvYtiwYXBdF+PHj8eMGTOw2267bXTbtrY2lMtlmOamT9v3/VxU3N7e3uVjVkgxoH8H2usumCDjMsafsA3xxEJWGrv2a8WKj1p46avA+SmWHqPk+FiHorDS0JEkCcLQhGEmiCMe4BTclH9AvCIgT1gl/osXmNBFa3eSaNIzqyhax4lDZJkx2jp62IdoO3Hu8xchjofBtiJou1SkMGACTab6uUQAiSaSYaWRLtRGDMNI0F53MaCRezVRBsjQuWaQnZlfCkBLri/nmGw4sm7fNLcUcHX4rtQzonIcXS/b5A8zusa79shclcok2cCNskDQsYF+EbVJ04IWi2AsWwbzYzOnVUMBjOQpgYstFsyQd3OJrBLxeChLRCRsUjemsm7WlDanNYRUz4kyDdXQRj3k+k1Zm5qNZZ76Cma8fgoSpkPH/ljT0Yh228WQhg5Z/vug2ghXiGvaOr8OWfV6CpRKViCzd0Q+TzQNBTsU0goGzxrpaVcjl4kwwRi/NzgPiQc8WQsQXqILc3IMG8v+0HWIeyMztD37A3j33XdRLpfly47jbHHXyy67DK+99lou65Mk/Dvla1/7Gr7yla8AAA466CA8/vjj+M1vfrNVQVZvoU8HQ+PGjcPs2bMxZswYrFq1CtOmTcORRx6J1157DY2NjbltP/roI9x4441bJGnNmDFjAx6SQtfj1H9ejnVeEaYBNBU9WEaMDs+RpacwMrivVWSgwQkwwK3hQ7eEWt2GF1q8zGElaPMKqNUdHvgImX1N6NM4TgjLjOUiDEA+lVP7PT2hc+FFwVkx8ppCUcw7nMihmqwB+goOeeS7GNRQwdraQFkWtMxYZtKSRENRZHfIIJc4FbEoE1I2phZwUT8NKS8n20VjGzG8QIhUCoJ7Vlma3O5JxVuXWRDAFn5mJGEQZxYnyvBYRswtOjJlr6IZol1Yn9BCx4OrlP9EgV2cyT4BmRZ8EXhQ2zpxRaik5xoR2rxCatkh3qcgMkp0QOf3DolIZhdFymrUBZkXSEn/WeTEIDXOW0nEmJDwzjlfBIqWHsMT5Z8dycduWzB37R5Y0dYMTQOai3XUQwsR01EyAm6t4UZYXWlEyeHlLFPMmc5SsruuMdQiC7YRo0NwDgFITzHK+LX7LprdOryQl10LdiKCZR6kOma0gVI5PXTZRoxAvEb6Re2BIwPdamjLTsbWauez7EZ0UTBULpdzwdCWMHnyZEl83nXXXeXrQ4cOBQDss88+ue3Hjh2LFStWAACGDBmCNWvW5N6Pogjr1q3DkCFDPtZpdAX6Xj4vg5NPPhlnnXUW9t9/f0ycOBEPP/wwWltb8ac//Sm3XXt7O0499VTss88+mDp16maPed1116GtrU3+vPvuu914BjsnPnXfVKyuNkpBO8b4wjmwVMEezWsxZuCH6N9YhaEz9CvV4EUmFn7A/5McMXIZCnYIPzRR9W20dRRgWRGam2owDG6k6VgRCk6Y8b8SfBPKAGmpYzl1LpkGX9xcO5IlDVowHTMWpF0eWPmhiXUfNeKtL1zfOxO4DZj41JVosAO819qMqm9ngr+0ndwRJqq8TEVkYk3KHkiZAs9G1bNhWxEcOwR5RbmZrqZ6aKLBSc0r44RndqiUQUrijhnxoErElFlScZzwIMg1I3ntaJssQboguoDaAyclvmqp/xyBAjtJehZZAMoaUacR3ROUeaB7wI9NrPWKcK1QPvlTyzaVRqhEQ632FCBmuVCErM0GdUtmA6Rs6z6pItPxyE2dZ+T470cNXdrVt02P4Z3WfnBMHmxUfFtej4+8Ig9EEwMlx0dZCC/WIyujT5VeOyAV5Mz+DfB5JtkFKq2ScGLCNBStAI22Lzv0KLg19QRNNjfs7RD8JLomFaFOXrBCeX2ou7Rz51+3oodb6xljmDx5Mu655x488cQTGDVqVO79kSNHYtiwYRu027/xxhsYMWIEAGD8+PFobW3F/Pnz5ftPPPEEkiTBuHHjtm1AXYg+nRnqjObmZowePRpvvfWWfK2jowMnnXQSGhsbcc8998CyNm914DjOVqUIFT4+yNwzEgFGkBgIAgO1wMKHlRL26v8RKr4tF9FRzeuwutqIKNaxrKMFseB4OBZfUGmxbGzwREaJf0mSgSoAqZVDC7ShpdYKlDWgrAXAH5g0neXKRZQ56E1hxG1FJXDQWivw8g+QO0cAUknXtSJAS7uzDJ1JJWji//gBL4EliS51XrhQYspdCSMDjplvLfYjE/2LVe43JoJfWtyD0IDhJNBERoqySLSoZReWIDJg2AnANJh6JEt3CdNQEGWMbOBB5TMKdDo7vyMTgGT30zq9bmqJ7BojzRldYwgiU3Z7FcwQQaZcpYNnpHzR+ZUtfdH72XFGiY6iGea4QAByFh48KNURCLuZKNGxvlrAzAP++HFujR0CDU6Q8VOzuU1PlJYmI6ajbPuSxwcIXTKRhaxHlix1UsceBedBYkibFIIfmzKzaAqOkGtECESXnykaNLiGkIlA41wjCuapA5AyVHWRpaZj1iPrE2eYm8Vll12Gu+66C/fddx8aGxslx6epqQmFQgGapuHqq6/GlClTcMABB+DAAw/Eb3/7W/z73//GX/7yFwA8S3TSSSfhoosuwi9/+UuEYYjJkyfj7LPP7rVOMuATFgxVKhUsXboU5513HgCeEZo4cSIcx8H9998P13V7eYQK//G36xDFDuqM63t4kSlamR1YZoxywcOy1hYU7VCILxpYXW2UGYI1bY0oFz2U3ABtNVe2afNuLya9whJoUjQQgLR2AADTSDVFHCuCJTIUupDxl0+UoqySMA2VuoMlfawUsf8D34em2bmAIkl0GCLtn+iCUG5FUgso18quQXJaSLPJMBI02IHchhBEfNF37Qh+ZMAx0+y9oSVYVy9KHgbxQUwj4d1+iQ5XHNPKLf78+A22LzMx5NdFXWo0tkBYZ4QiK+CakQxU0kWUI9spBKRt99l2/gSp3QUpTxvE79F4gOWaoeQp+bEJx4jQYAWohiIDlym3ZIMguq86I2Kp2KTULgLjBqCJMG4V5R1DS/De+uY+d092hmXEqAY2bDOGa4VotHy0BS5KVoCy7SGITbSHDmw9Fg8sZk7egAj5ZIcSMw0eTBkAU/BLKIhAKduxFjEd1dDmZUeYaHHrvGVf4w8KUaKj0fJRDW1EIiByRQcfBT+GlqSZyR6cv55urb/tttsAAMccc0zu9VmzZuGCCy4AAFx55ZXwPA9XXXUV1q1bhwMOOABz5szBHnvsIbe/8847MXnyZBx//PHQdR1nnnkm/vu///tjn0dXoE8HQ9/+9rfx2c9+FiNGjMDKlSsxZcoUGIaBc845B+3t7TjxxBNRq9Xw+9//XrYMAsDAgQNhGJt3sFboHpBqMREgk0RDovM29yA0eedHxP3HaoENx4rgeRZsK3WQpzZ424zhi/p/onHdISDln2S1bRImLDxEhsg1Q5h2Ai+yuGWHeBI0Ne68DkB2lYSJgb0HrdnwZHZwtL9bxpA91iLMdFXZViT5O1nQPBl6Ao1pubkjJe4GJ5CBFQUappagGtiSn2NoCSpeAXZDHQn4ddJ1PudVQUQn0IJVsNJuNO4hl+fUUFdRLHg5lhZLgUU/MlGwQrhCZI+EMzuXpsiQlTJO2UxRxHQ0iKd/4ovw0pVY1jQeSFEHEWOcmGvrMbzYRCVwZJapaIboCJ1cJoiCOiJPd+YSUZmFSjOSrC6yDUFiyHMgbaV23+3zgRAA1AOL88qE/pMXm2iySRfIkP5kpiClEw+IMYYYmSwemOSR6VpqxEyk/yBTQu0sjkn+Z17EOxjX1ovyuBHTZcCQzSBmCdRxwps8KBMY9WQ3WQ/bcbCt3P7aa6/N6Qx1RktLC+66665t+uzuRp/mDL333ns455xzMGbMGHzhC19A//798dxzz2HgwIF46aWX8Pzzz2PhwoXYc889MXToUPmjeEC9hwSa7LrQNIgOMg0lJ0BjwYdtxmgq1uGFXDCRBBRtQZyteamTuGEkKAnHd2qxNzRezsq2xxIZNxGLmGWkJoy0KHqRKTMMWZ4MEYw7e4j1BSy/9Ns53gQtAlGGK5O1H6An6KyCrmkkskxGrcdZ64pqYMvANop1eKGFgsuzPNmggxAI0qtp8GtaLvi51mkKqsJs1icyEcVpCYra1XWNu5oT98PQUwVxAi2A1D5Px4gy5FvaJogNqShsC25OlvPjx7xFO4Em1Z9LViBEHHnQ5okuMrL+ACDfByCtHGj+iKdCC76u8a4pU5jXukZq/SC5KdCwe9M6jP5LKpzZ1zD6ppsx+i83SqFUKmmWbR+ByAISKdo2YhkUAXm/uSzfyhXXjOaqJAxUycbD1BPZTZYNSskIlzhpdJ94GbI7BTh03wWJIe9RGkdNZJcU+ib6dGboD3/4wybfO+aYY7Y6ilXoWRAxl0odnDDL0+UEQ2RropgrTld9ri3iOiH8wETJ9TGssR3vtPWTnUlRrMMyUz6IzHZkns6rgQ1LPGXGiS6DJvI1Mw2+KMUADJ1/0dXqfb+8augMSARvSiwYQazDNhPoGWFCqZtipi3flhFLN3YZkFBAqvNsBWV0dm9Zi4/qDagGvDxn6Qy2GSOIDIQwZMAaxTpsk3cQFm1uwNlgBzJwIVI9IYgNFO0gLTdpDM12HatrjYgZD8IYAxwrQpQJrjqXyqibrLOtR7YzibJOdH92ziQAwOpqI3euFyrpEEFlLbLy5TfwQJTUkkm12MwEofSviWSDxbcW2bnPpfffae8njYb7Ivof+gE+aivJgJzuJ1LXznq/kXp0lhxNc5wlUbcFruQPZa9ZTZCuo0RHhFTRPivN0BE4Qj2alzcpKGq00usWJgYaLV+avVIHZcI0KdPAFcZ7UMcuYcBG7s9t2l8BQB8PhhT6HnYrt2JZa0uurdg2YjRYAbyIi/llW1tDoR5dtAPZpr1by3pUQxtvr+ufa00mUUTOuTByvBD+ftopVQ1s2V3GGFCpOSgVffkFzBhXqu7rpYgXTrpJ/n7EnGty3ltUTqKuMAA5+wFdY0hE5xV1V9HCQ0ESwHlFRAJuE35dAKQ+U4fnwPMtKX0AQHR/AeWCh4IZcnI1xGKvMWiaJjNGVLKrhxYabZ93/RkRWoMCTD2BF1hSDynKZJSyi0TCNCCjPcRJ/OlYaEEOGfcOo84gS4hS0jxFQsyRsl7tvgvbiLjIn+CvRExHwQyhs1RgktqwDRmIGjIgqnUi3RJfZW29KEsv2YyDoSUoWgFe+Hx6bfsa4kTHgKaK1LAqOx6qoY1qaKOfwzk7pDRdMHkZtWTxjKPkUIlgpmiGaE90WFpawtU1JvenB6FQBDmJyOS4ViCPGYosMNmhZKUiOAeMB7cUCHGFdE6m7ggdfk3MENXQzmlAdTuUa32XoU+XyRT6Hu454ueyJPPsiT8QZFUNbYGLhGnYtdyGJOHO8jXPhmkk6NdQgxdaMlMwvKGV83+MRD4dx7Eus0OkYJ3tHEqdwJnQDuFZEl764ZmoVNG3d+amO7HPvVM3yIZIB3YjNTo19ASBILXTokLt5GnbOg9qXDM1uMwuQHzeIflBus7g2BFKBZ8LNUJD0Q4QJTrqoSUDtM5cGrLqiET5yhVlOno/iA20eQVUfRtRrAshQ12OkasJ84WJAjduu0ABiQlXCDh25nqQiKOtxygL5WnKjFG2iDSGimbIF2zwdn8q57hGxNvuoclSI5XGOvNXiDxNdhKdBRgpU+IanDu3pqPUxXdIz6LB9rkTvRGjHlqpsCe4W7wXmRhYqPJsDUvtV7LkcoBnmCuhLeUwElHeigSpmuYfSDN1FOyULH4PerHJS2LIZ5sMLcF6r5DrLszCi/g9o4Nv78U8eE674xT6ElQwpNDjoCfv4//xTQCQ3UmM8cxE/4YqRg/4EI4domCHMsMTJTp/goxsLoIYC4XkiAdGlG0iQjQ9vXPH8fR1INXRqQU2/MiAbUWpMJ7PCcF9PStEGP/3a1HrcGWgkF2Ig8hAPbRk0FMNHGGBkpYCZHdXpr2ZAiDS4QFS93Su3q2jHgqvrkRDyfVh6ZxsTdcbIEFLI8exoQDLNBIULH79KRgmq4N2YaFgGbEU1gSEk3hG1yirMWWJjiSybKBsEgBJWAZSBWtT44TeQPCVyI6Bxkj3ZYKUb1Qy+bmRoaqp8QxUlGn7pwU9G5iamawGZT3IBiYbALgmL+W8fvrUrrtBehjj/35t+oCicSuW9fUigsjkvCzBKWz1eXmaghyal0rg8M6uJM3GkXs98cmKZiizPJQBpACZHpLW+QVUQltmkKh0T75yhKwwJwCpf9QROjmBTfIly9qsdD8yHmMfy5fsE/jk9zGhymQKPY4hpQ48cOStOOOZy1AT4mW8m4ThjXUDUPdsmANS4u4uDW2o+Dzj8EF7I4KYd5zZFtd8KTjCbFVwfqhjDMhneTrzDUhh2DZidNTdPqviuyWsWVdGoeTzRSOjmwQQl4hvJ8XqoEkuRWeF5Cy/Q7qqa5w8TO33WcJ0lqCdAJJjQ/MOgy8uvniqpgDL66TinA3ILD2WxGoiJ3MF8XzWi/6lTACQZlhMJNJlnMT4svYYTJQBw9hANeElvJpwsqdski06mxBBZi5aAxeOGaEjcHjpFyZKVoCKKANmA6FsMESZBQpU6ccxIrTWC2gQWYwP6w345/E//tj3wo6AuvC9qwcWygVPlmiBDG9Ngyx7Za9dq+9K0jRdIwKLNVnWJPI17QcALU4dldCWZTbSLiqYISoJL49SmZN0pWIRBAN5Mj757FFLP40dyCuPdztUmazLoDJDCj2OB468FQAvmUUxf6JqdDw8N3EGWoo1NJfqWFtrkGquQcIXxrpvoeBwryHXivi+sQ7P590gaadTWoqQ7eEiE0RfgPS0T1oiYfjJlVpIYi5JAKSLcbYsZhqpG3eY8BJidpEh2GYELzJlgEGZGVqYAsHv6vC4ZhRdB9NIeDnJCuTCYhkxQpE9osxUwjThj8azgJw/xtuW3UxLPu3f6Hiyi4yQJSQDqQkrdW3VM6728rxEcEX6NYDwUMvo0PASGT8uldpIjK9kBZxDonMRwCA2pNgikYGpEyw7NlPwTEhLKBsEJWJ+V7Y1oeJxnZ23Vw7s04HQfvdPwT73TuUcPaFkTgKJBSuAacSo+DxLQ9njbDD8Yb1BmKrqsquPMm5EsKbsmytKVZ3NfklckV7Lmvd6kYVqYCOITGkI3Rn5B4lENhZkS6yqo6xvQgVDCr2KeSffhDjR8PixP8WZcy9FPbQ5GTfWoesMfmhieVs/ANxPSwcTAQ3fn/OGEng+b8VP7TXiTClDKCozPVP/T8tlAKS20CcRph3L7phsqt+PUrVjU2RlSNTQENIDTbYnM0SxCJQIuW4apqHiOZJ8DpBmUIKize0M6KkbgDQrdcxYtpsDkAEqWZ8QSAk8u9CYmUWJWvI7W2Bk29qJqKxrfAHL2i44ZiTLY3Rsyij5IW/tp3umFtoblLyCxEAltEU2Ia+c3eq7ssRD+1Cg5BpcuZquBWWuAF7CLRc8lFwfDxx5K5ad23dd6Q986HsouT7KBR+OGXOPv8yckMt8Z1NeQJQtmY4gMhEmOoLQRC2wZJYmm2WjuaOgx9K5jAaZ6HYuUYa0nRFnxsIzlTUhnkkPBlmrDco6ZXlgFMB2Dra7FQnb/h8FAKpMprADYN7JvCtmeVs/aRdRtEPUQ357GhpD0fbRv1DDGx8NRIMTyMwOhAhd0Q2kmGDCNPihCXJgB4S9BgVComOKMQ1JoqPS4fbphWZLaGzwZDcYta8DAIRqNAnV1UMLr5ya166Z9MKFWFUp54QRyR+LlH9NLUEMHU1Fj/OEEh2VmgNNBA9kz0HZEkNPEIon75hpsMRC4gjeB4F0XxpcD2FsSLf6BBravIIkf2eP02j76BCmrVTGADqVSDOLIXV6AZClEUtLUi4IS8/R0LnHFckyVEKbd8IJnZogNlESHlq2HssFOUp0HiBp6cIZJToCzUAl5J9NC26U6AhiE0UrQNnxEDEdrdXC9t8EvYzBpQ5URUmcAh4jYVjZ1oTmYh26sDyxzUhmZihTSCrzthmhoCWIbZ4NGlioYr1XQBgb3OtOBJNRosM1ImnpQQavYDzIpU6+UIiwRqJE1uAECMx8MJMwrjLtGBHXK0t0WdIlThIAeCFX1A9jA5bu9dzEsoT/bM/+CgBUZkhhBwGRKklkDeCCf5TmbrR9fFArwTBSIbxQeDTZVoSaZ+dIqlSiMTKLIj1x+pGJum/BC0z4gfmJDoQA4KVT/jfn9QQm2j0XgVDapoCGnmo3ht8e/muZbbGMGE1uXS7ctGhku9ISUuO10gyOHxniX1MGFK7IBoWRAdcMc23rYWxI8rWmpVYfnQ1O6XMZ0ySPpxpmtKr01NleBkXifjI0Xgokg05ZJgNXoY6YLjNADTb3zyJhPYCUpXWUrEAek7JWYcz3p7ZtarsH0swFLaIUSGXv3ZLoXqNshWX2/bKLL0RN6bxlR6IdorVWwJqOUq6E6pgRSg4XYTX0BAMKVUmEtvSY83xEFlkTJdCy7cM1ImmVQa3w2Wxb1uOMxFdl2SxzfzXZnvw8U0tklgiA7DQzM9m/BttHgxWgaAUbLTF3G7aHPL29fKNPGFQwpNDrOOe5i+UXFIn9GXoiHaEbHQ+rK41oqxXAGCdgWnqMkutztV9RKgOw0XKEoTNp/pkwDbrOEIYm6lUHb/x/3+udk+5hvHDSTdBEGYLKAHGGZ2EZ8Sa/F6NY50EDuKllKJ6sbcHLMHWue5NmW1Irk6It9FgCi6t+Z7rGwoQ/0QN58TyAB7MUFNfJckUsRvXQRpxowruOc5goEMnyoYjfQYRwaoPOqnFn5QL45xIhW5QPhecUfTYRdLOBpCW83gw9zSiVLZ4havMKKJihXCCprOOYkSTx0hzKdvFM5iphGqpLmj/GFd+x4Mcm1+TxHBnc0v3Y4ATQNGB9vZBKDcS6DNgLQtMHSInqrhHJji9TT+AaIdZ5Baz1irw1Pzaxzk8zajSnpp6gSXDN6HU6BmXydI1J013S3YpF5xpdf8Y0tDh1OGYkgygi/RdM1VrfF6GCIYVex+K1g4UmjA4v4l+a6ypFfNheQr9CDWFioBbY0uOKlF4TpOTZghMijAy5uGdbyGVQlFmsk1j/xGeEOoPasS2dK0DnnMCZhnFDVmx0vwWfuREtTg2DixUMdCtcCFB88TcIy4NItBYDPJBx7RCmwYMDx4pEi7tQ+qZgRYgpUiCRMA0dHi8b2QY37owSHU0F/pROGT4iyWfNdyPRUh2IcZlaIvkgxJcicjadL4C0hCJA2S7qpiO7CPIVI3E+S49REgFi1k+syfHQ5HhwDe5A75qhDCClF1qmm47GmFWk7txptvuhfd8+qK3mIghNLDptKhodD44RSa6OoSdodH0YOkNrjQcwJUdkx4TeFfGx6P9z54xPa1CQ2b2Y8c7ArIo4za+pJTJ7RA71QGp3QtcxS54H0k4x8lDTNCaVqTWNpQa/LDWA7REozlCXQXGGFHYI+JEJXWfyads0EtTqNj6sllC0A6lAHcQGKmLBLLqBbO2OGfcwY0wDAy2WCRJRJokTTvDl7eUxDKvvlx4+DiijQaWd1auasfyCa7a4Xy2y0R44aA1c7tRN3Buh80LHNYRZbhzr6F+qYm2lAQUrlCavfsyzPCSaaQkTTceI0OG7cjsSWqzUHTS59XT8WgLDTFAVvKBsO76uMVhWmBPPS5gm9WOIt0MdZkDadUTCj6lzfTpX1PXlW9ybrGCGMqvTKsRCabGNEj1tvddjwEotOmgxLwqBRjIIpY4k0jwCOGGcsltvfzBgey97ryOri/T4sT/F/3rsv2RwWA8tNNgBbHDpBbIrIS4bkC8jZku6JStAkBjSdb4W2rJDzRMZKNeMpHo5wAPgiPHrGiRG7tplr6VtcUVpIt0n0GSXm5Ro0BPJheKcPB/1qAeXVdVa32VQwZDCDgFDS2BoQNn1ULIC2HqMkuVhRaUfqoED00hkEGSZ8Qa+TFktGU3jX5gaS2v8IdMRRQbePOt67HPvVDQWe5DkuAPBj0zROcWzIFsTCAHAeq+AiOnwY25y6pohvMiC7dbgxdx7y4ssqfdj2zwosTJlT1NLoBvpdeP8sEguLI2OJ8t3BcG3GdLcjpjpkrgM8fQNQATC3CiBcjsU/JhaIoMWCoJipuf4O/QE32x7PIsjhBJ5cJcR7dQTtPkuHCOS3Ul+bMI2eDs9dStRFsHWI5h6jJLlIxCkcbJxoIXb0BPA4DwV14xQiywZREWJLo2DLWPDe72vYO+7b0DRDRBGaZBXsEP4kYEFn/kRDnnku5wgL0Q4TSOWvCHKwABpKZMyZi1OHV5sYm29iAZxnxgiE1h2PNQjS5ZjuSI1V7MumgFW1xs32n2WZL4rAB4kr/OKMpvommkDAZG0s9mmgJlwRVk/0vrm9drZoYIhhV5H5w4mwmGPfIcTpM0I7Z4rVaYNjYvsBbEBy4oQJ6mXkKYJcmvCtYTaKwW4TgjbSq0c+rJ67/bipVP+98fajwjoVD6KGDc8XfzBYClWeebcS7E06I8o1lFyuIcYlTvoyZr4NdXAFtdRQ9nyZbs7dXbpGu80GtTYITt4KIMC8Afagh1KxWHahwKYghWiZAaIGBcqTJghS2iuFSISQQqLNXzkFQFwk1A/NmUWh1SNiWRLwowA98uikgvBFmJ/kWYg0BgKBl9ATS2BrvGAaZ1flFICJTOAqceohFxHiBZYLzLlghtGJt486/qPdc16E1e9cjbKxd1hmxEqzEHJ8XNBzafum4oGh0kifTab5wo9KyC1NHGNCK4ZYZ3Hy2imkH6gMmjZ9lE0A7QHLppsD+v9Apps3o0XJTpqkSVb64PYkNYnG8s2kd1KUXiXkRI2Bae24KfRcZoc3q1ZD3jXWWNGYb3bwbCdmaEuG0mfh+IMKeyQOHPupdA0oOI5qAY2XDNt5wZ49scx8wrJXMaff0lpGu9UevOs67Hwc9OwvrVhpyFLdwd0cOsOAFJzqL3uyrIYwDMiJceHK5TBdbDckz4Zsn5Ubcjp/VQiG5XQRi3iPmWVwMHfjr4FrrDicDIt9USUNjOfS7wnstzYmOidNGfVufdaEJlSGoDsH6jcRhkJy4ilSSjpDpEWEXF+TPFZthHB1vk4XSOErUdS1sExIrgGL425GXJta+DCi61c+YwyTXReK1f0395L1+MYc/cNmPfRblIKgcQsKRAifiCZCGdNanUtNVjlgpa+nGsqI35QK6HV5+XJiHFvsUpow9R4yWq9z4nYtciCn7nOFBi5ZoSSlUpMdC7BZblDUjtKBNkUWBF5O0q4f52lx3Asnr3Mlju7HaqbrMugMkMKOyT+OuEXOGLONagkNiw9QZxosEjxVTxBU0pb04RRa6IhYAYWfOZGHPvEt3KO7W+f853eOpVPBJ48fibG3jMNus5y85rFu5VmOEYkS0bS8BIJEp3rtQA8kCmKxYgWubW1BvQr1PD+umaZCWkp1gAIXoh4WreNGIHPv7YoeKEMDsADpgYzRBAbaE1cSeymIIcCOR1pKVXyQYTgZBCZaLB9menRNQZbj2E7PCvQLjI5nHNiwtYjGdyVRJaL0M+uoR6nOkS0uOrgx/RiUy68QWKgZPkoWQG82MScY27ulmvZ3YijtKNTB4NuhwgiE3am86pc8LDPvVPRVDRyxqYJ4/YYAOQcE+hahEyHxjRZguTdZBHaQxcR01EwQ0lY9wWJnbpMTfEdUhNK5LrGpB1Ni1NHe+hIza1sizxlrEjDir6DKCCjDreI6bDinZOP2NehgiGFHRquHQmdG02qRXuBiQYnQD0y4ZixfMDxAgtvnMmzP/847ie9OexPJBafMWWz7z99wo9w7BPfkoRlIrf6ov3dEJyhfm5dLibtgcO1j0ID/zg1f81c4RkGQAZN1YzOD/HESEiR0BE4uS45IBXc1DUGpjFAS32m6HdLZznfK486hAAUzQCV0EHJ8iTZ2RSLNTmjU0AEQJL667EFL7ZkizaQZkJktkMDikI356DmdzFv3QiZHemLGDVorSxrahoXsQy1NKvI/eD4Q0wtsBCbuix7WhmCMgC0h640ZfVjU3Yv8m6xSAh5hjzrI9rxyWYGAIp6wKUdROmRAl8vMmXnGZHVI6ZLsUzKAgGQwSntY+qJzDLR9c7aqhg9aceRJJDR3MfeXwFQwZDCDoqRv5yJgSMM0bZqwNIT1CMTCz5zIw548HvC8iB9Aq9UClh6tsr+7AggngwA2YJPzvQUlJQsH+2BizjRpQI54cCHvofBpQ7YeiqPYOtpmSRrtQFkhBT1BBrTkDBDljWkmSy1YYuSCJFoaTxxoiPWdLhmKHlBcaJzflSioz3gWYd1fkNGD0gHtARebKFk+nJsXsIzQe2hK/kltYQvpiTESOUWPzKxttoAw0hw6vBFmLrvfV16LXoDc465GUc9fjUA3hVXFKVGupaksWSbEWwzwvpqEYtOm4r97p+CvQes4arbvgsYXG8oq/lE5cRqyAOmUPB+6iHP9JRsXwZO1D3mGhFKZoCPvCJikTnKktUB5LKAlIH0I640Tdk7W3QuUqYyYLwTbWihDR94ZSnvUNTDjcxKN0F1k3UZFGdIYYdEYXAVhnhSr/sWnps4Aws+w4nWXsDVow0twfqOIvzIVIHQDgJdPPn7sYkPayXeAQZI3gYFJ/SE/uTxMzc4xsCGCgDeeUUwM2RZ+hwCaRBROSzaDGeDuEMb0xyizE3BDNHkeJKgS5kACsqo1EUcoaIZoBI5qES8fFY0fTg65wnR8WnbkukLThEPkiwjxqDGDpRdD898uDsOf/STcR+vWDJY/l4JbRkQuSIQihMdDUKo07Ei7PHH6ah7Ftb5BVRCG3Em80JcQceMpDgiBamUqUmQdhmaQheqI3AEyT2UAY6hJShbPoqilCrb6kVAHQmuG+kHhXFqoEvcIi82kUBD2eYlzbV+CQBQtjyYOremUeh7UJkhhR0Su7Wsx+qORpScYIMOKMeK8PlRCz4RT9GfNDx+7E8BAEfMuQYxS+0XHMGnSKBhrVdEm+9uEAiNvWcaBpYrAEypsTOs1A5bjzg3x4jREadmmVR6sg3uFt9o+WgL3DQLBJE9yqqSi8+ixY+yFZbBrThsI0bJDAQhOkZr4Mo2b11j+KBegmNEqIQ2bCNG0Qh4eUQsrLqWIGE61ocuimYAL9ZhGxGixECzU0clcnJkXeKfkP5Ro+Phfz32X6gF/PjPTZyxybn+4rOX4PUPB6OjrYDl513bJdevq7D80m/jqMevRtHkytCmybWD6iHXXIqYjlq9iEbHQ8EKETdo6Feoo8N34Vqh1PMJMrpOJKAIQApfEm+HSrBk+ZJV8a5FNkqWLwPQSsTJ1qaeoGQGaA/Ta5IVvaQALGvQSoERkd3pPvIiE0UjkO/3GFRmqMuggiGFHRJ/O/qWTb736mdv6LmBKHwsvL98AHYZ+RHiREc1sFGww5ynU5TomPTChfjt4b+W+1hmjEaLt+RHwqOMP6VzR3gKkChboGkMjs7LGWFsoAqesQkzwQ9lf4KIdxjawp2e3ktEJsnQE0C0tXuRiUGFquSQAJwT0h5w0U7bitFse0I/yJLZoyAxYGgMgciCebGFIDGko33R5A71PHvESy1EvgU4N+XDegP6OVxkshbY2PvuG2CZMRZ+bhoAYPf/dxMsJxKL9S7c36uhB1u5twH/PP7HAHhnaHvgyGwLE2WtZrfOTU/1GP0KdYSJgQbbl9kjboOSlrKyAcvGOgYTaJKoLRXLmYay7UkeUi2yZPlT15iUVWCifJcwDW2By7sIM6bBYZISvalTrQYLth6jX6HG70+RnWoL3O6c1k4nzbBd/fFKgVpCBUMKCgpdjuUXXY3DH/0OLCOGa6ZP0P0cH7XIQjVwcoHQ6L/ciCH96pK34YnOMxIrJE4HmZjyFmYTMUtSE1SkdhxhkmZ+6qEpLT9MLUGE1FiVFl4S6qNMA/lbNTse9DglW2saQzW0pY9V0QwBxjlQ/HMN0SnGs0FRoiNIDFkmop/2wEVH6KDR8uHFJsLEwCC3Akt3oWsMDVYAU+N2EXGiYdStP8Hg0R9hUAvQr1DD0jUDkCQaDB1wnRC7/+ynePuKb3b3Zd0q7P7/bkK5XEezW0erV0DJKaHDc1C0QzhGJL2+vMhCNbDRLBTGyeuuHlq8K0sQnDsThG09RjW0U69BEfCGQgxUltAE30cHQ2tQkPcScZbKto92xonqFHC5RoRmOyXJB0KZ3NFjqVKebZ0vmiGqkY2qCIa8yETYo5ShBGw7nOe3Z99PGlRxU0FBoVvQXnOxck0zvIgb6zqiO+zDagkVz85tO7CpIruxvMiSonttgYtKaKMjcBAmhvSUigVfxNJjFKwQrhlKDao40bhZbKIjTjQkGb4SBVlUJqHPIZBTPfGV2gMHldDGOq+YI4EXhegiQWrWMD1n9mnqicwIZYMhnkVK4JoRWpw6LD3GGo9zT2jRtowYphGjve6ClSPUQxP10MSaagmNDR4G9+vAyP7r0K9Qgzuivasv31Zh0gsX5v4+7JHvYHD/dpRdT7ajU4D67Ik/kEFxGPFuMEuP8WGlhA8rJayv8ywNlSQByGwMkZcBSH+6rBcYSSfIEiqR6xMd71WbUA1t+HEqZmkbMdbWi7KrkYLgIDFQiyyULQ/NjiezdkTCz46DjhUkvFvSi0wuAooeLJMpdBlUZkhBQaFbQMrUAHD4o9/BR+tKePtLGxKEj5hzDefoiCd6WiSJFxJnlJ+psycLW48RaIYkRqcq1XyxdBFCy+wSRCZMK4AvjkXdaK4oocVMB4u1XOYhjA00ibIOMoshILIKRsoBSpiGdX5RtlpT9xFtT4FREJtSwK8suqCy50a/F5wQpYKPAcWqVMGmQIpIyWR70pP44rOXYFRDG8beMw2Lz5iCAx/6HprdQHp4AZDdeVGi44AHvwfbMDHv5Jtw4EPf4/ILTppRIzHEIDHgRRZCxktTmsZkZxfxiGguQ5GloWtO1igUqFCgRIKdWTI0HY8yixQQkUAjAFSFmGMCoMWto9V3UTR5K39RcJnoWrpmiJilY+oRsO00W1WcIQkVDCkoKHQ7NiXUCHA+z6BiRfKCaCGz9BiesFCgNvi6yDIVrUAScmsi20P+Y0Ss1oUGEJFhgTRg8SILcaLB0Jn0xIpEBokWRJZoKDvcw45EIilTEYhymCyniFIYfQaBt+U7UrWac5oM2dVWDy2u1C04R65wc6eASdcYmt06Gqwgd55Zx3YgVeHuKex+809R2H0I3rZb0FKq4dNPXoX+RS1VHs8QjjXB8dE0hmrg4D/+dh3GtKzHOqEUXXJ8GbCs9wvo59RhGxFCERSZRixVrCmLQyKcBFNLZOciZXdINdzQE/SzfWmrkVXDll52QowxAQ+2yJg4TnRuCWTwLkJAdDayVDSzFlgZbpoJIEKPgW0nZ0gFQxIqGFJQUOhVaBpXF/ZjLpfQ4bsIRSnDMmIYgFyoAMjMja3Hkh9CQolAmiVIkG+zp64xTprWoWkpwdqPzTS7kAmm6qGFBBqabI+XvURGxotMeKLsAkB2OnmxKcUUKYOT7XyqBA4sPYYhvLYAXgpkTMspJQOQfKYo0dHqc0+uohVIfgvp6QSR2aNNBSNn/xDaoASDGjtgCyIyOcQDaZkrq81D2ZhGx5NKzVnbC2gMdKVsI0YJ3Feu1eMBU8x0BHEayCRM435lInhc7xfQ4tYk/4oHvxEabR8dgSMDISLhA4BuxDLwptb7WmDJwCerj0QZoLLtS6Vxyv7xcquGauBwXprRg8GQQpdBBUMKCgq9iqpvo8H2ZWkFgLBgEURnwdsg/SIKjEgFmDENvghUYqFhQ27zWT87yhDxBSvlpZDqNP9c/lk6g2zRLhgRgsRAPbIkr0nygmJeBosYJ0rTQkzGwWQkm4r5RTLIocUWNmTwBPDAjz6bSjBxoqN/oYq2wJXig4TNZd26A7oTo1Tycpwdkjeg4CArH0DIKkDXIitnq0PzT4a1thEDMVCyfUlcDhNDBqWM8WM0Ox7aA0cSsyk7RNwhLyPF4IrrGIMHyvQ3EaIpIAI4dwzgHX4ko0BZviyPCMIYumgF0umermOPIEkAbTtI0IpALaGCIQUFhS7H7j/7KUq7t8ILLMShsVlRTCOTXUmYhv6FKlr9ApLYQBQLQrIIUuJEh2WGSMQiZuq8PBLFBkyTH6cgxPyyHWDUPi8DpUwmSdO4oWzBClE0Q6ytF2EIdeMGwfch3k8sjEGzxw8Sbi5LAQxXR0+kEjdlFnRRJgLAyz+C30JBUS20eaaL6UCSlvTC2OAZFTNCNeQBXjarst/9U2TrfXdj5C9mojA0RP+GKld/jjXZwk72GwSao+zfNB+ShKwlSLQ0GHWNCLXIgmtESHQNfmDKEqNrhvBiE76wSbH0GK2+K0tnFKiGsQFHlDWzmbZaZPHANdFREFmlIDFk9oqCM65wbed0hGiuXcFto8xRJbR5xyEYPqw35M6/R6DKZF0G1U2moKDQJdj9Lp6h+OKzl8AaXkEQmqLrBzjgwe/lth39lxsx8nc/xFdfvACNbmplQRou1GZN7cp+bPL2dxGkZLNIsbB2CIWnFC222b9dM5Q+ZoyldiG0eFGHGOnFEPcFECU0kV1yjEguqKSqXY8sBBHnEPF2/ZB3uZkh/NhELbRR8R34kYmisOMo2b5cvKkE4xiR1D0KEx54hQknbgPAOq8g54nGw8+/5/hCWjnEbi3rZTZNB0PBCnPlQtlZlxljlp9Ti6zUWDeTlZOBIyM5ggAFMZfUyeVF3OfNEiVSsuPItru7ZihLa9KcVXS2UfanLCQN5D6i3BYlupxn8iOjzFUpE2TT+67sdovkvUQ8M4W+BZUZUlBQ2Gbs9ef/jTfPuh5j7uZcFQ2AU2AY/dcbAewCAND1BEmiQzcSOJlupzF334DQs9DUUsGyjha4ZpgjxRKJ2rVCeKEFxpDjeVAphrIxVJJChrRr6onsEmuwAr6ogcn9E6RmnjqYIOua8piWEfMALLRQkOPjukbNtse3F2Mrux6cQiQzB1n+k2uGYCIwI30bWkxJkNHW03btghmiJspPEOdcZ9YGZTza3tJjuHbPcVT23m01vMiUxrSk3ZRomixnZsteADbokstmtch41zJiQOfWHc22hzX1BpQtD0MKHXinox8PLIUSdMR0GThaeiyNWOn1WmijaNb5vIpxkrYUEau92JTyCWkAzsdP8guxlmb4okSXwZPO0nuUSqQA5zqFiYF6aHXnJciBJQnYdpTJlM5QChUMKSgobDVG/X4GTCdGwQ2wz71T4doxkkSHYSSIYx22FcELLNhmDMuM4YcmisUA69qLmPjUlWj3XYReGVYhgqYB6+tF9CvUcosnE4uPI1rsPZF5oYCIeCSkREzlLrK0CGITjMXyWNXQ5gu3lsin+7VeURKlqeNsnVeUnCJqu4fGswbtgSOzOu2hAx0MjY4nOUIxeLkv0AyptM1YGiAAPCig1vFsRoS6mWjRdc1QLshBZMCxotz5Aqk3m6kncMzuDYbOnHspAJ6ZKtsxEkODH2kyE1I0Q9iMi2JSaTCb+aHxUtmJuFA0dvpdR5qdK1kBGkwfa/0SClYoAzDijdF14qKaVk4MkeaIiOyuya8ftckDQKKlYwB4sB1paReca6bKicQ185iGQYUq1tQb4JoRypaPRstDPbbQaHqoGNzWo4P1YMFFlcm6DCoYUlBQ2Coc9sh30K+F+2gl0OBafBE2dJ79MGwy1ORkUz9Mv16aGuv4oNIIABjQUpGWGgBfMKlrK45FBohBlrpskQWgrFE9slAPua1CbOowjTQgso0ol/HRNAadiQ4zxjMDYZJvy44THUxjsMRxwtiQ3V1+bKIjcOTTv2tGCAT/qN1zpZhjyfFzXW/EY6Eyi5YprwQx56lQa36284qyJa40NuVjMPREls/oM3QwXoYLuicTsf8D30e54KFgOpIf1ea7MnNGmZfOZTuae+LiZA13S2aA1sBNA8GsrhI0+d4gp4K1fkkSnHm5i98HBTNEPbKgiXuCMm6UlaMgrdV3EcQmignnDzWIYFZ2j1GHn+BqNdseEmjo0B3UQ1tmHQEeYA0pdqA1KEh9p3Wiw4+38qciotl7S6HvQHGGFBQUtgq7lttgGzFMI816WJnOmjhTDtE0rt9TLnjwQguGxoRSdIRYZAaIwxOztPuqs+igI7gclpG6zFPHmC1eoywBBU9A6kBvC0IykXcpmCAYGl/YDZGZoGxDg+0jFF1LmsbgGJHUPKKxAUCj7aNoB3LsWa2hbCdYzHjXWyW006xPpnuMFlAvMqVJaUks3iQbECc8UKNzjBifh+7SGHKtCJFwbSfiOXGwTFGuqoY2WgNX2l5Q8OMJQUni3dB89HcqnBzNNPhCmTpKdAxyK1JGQNcYarEts0g0BzS/CdMwuFDh96KeyDIjlbpsg2epaO7DmOs3RYkueUl+RgqA2uulXQdpSUVGjvTdHripKa+WSJ0hW+cZqKIZYEihQ+7fI0jY9v8oAFDBkIKCwlbi32sGCasLrjBMwU+2NZ1g6QkKVoQo1hHFunSwpyxOEBup6WqGzEzt8Y4gu4ZiMW6wAimgFye6JMNSMBAIPkmW4EqGr6aWwNASNArSMh9fLBd2IksTGZfGRQEdEZkt0T5eE63WDXYgjwGkXJlI+G6RQKSh888n1WLZaSbtHIxcuz4di/zODGEBUrDTQEtHOldeN2SGTv7nFbDNCAUhbknBpZmZY3KUpzFlz4PuDfJXoyDn3Wo/VEJbXmOAZ9tagwJK4hoHsSHm0JQZMym2KIQpycOOODsUIPqRKTNvAwpVFCx+jUj2AODt+51d6FvcOrzYlMKKmsbgWJHMLrqdAhziHGWDqI+8BqyslWV7f4+AMd4e/7F/VDBEUMGQgoLCVoFr91CQkMjgI83Y5IMiytQU3UBmNuJER9EOEMdpeWiAW5OLaMEKUbJ92EJxmIsf8tIRdZgFIkACIAX/KLgKMl5jOviiXLD4gl0R5p4ANtCCocWeSiOkM1MwQwSRiWpgS84SkXc7t1FLOwcxtgaLW1PQZ1mdWrVpsQ9jQ/5O3U66xhAkpjwucV3Ibd2PTThmhHpg4Y0z851624u9ZtyMNdWSFIpMmJbr3gN4QOGavD2d7CeyAR0FOrK8KFrSAR78SCsMwfnhmRxDZvo6zykFIwnTcl1gnbv8ZPegEaFk+TJTZGasWjbWLk/BGv1QsKSJLBgRvSmbRxmpSEgtkIBmyQowoFDrqkuxRbCEbfePAocKhhQUFLYK9YojNXxoscjCNPJie7Swx8Iwlbg6XCsolotoa+DKYxAJNsgEEJQJoZIFYykvg/NqIjjkK5ZosrRDwUo9tGTJi2wfKENEQojZEpneaUGmcw1jI6elQ63blPWhhZnKaUTcpnJZmBho9QoIhFQAHYMEBQHIkgsJ/NE5UrCWLSVWAqdb9IXC5hjNbl2KQ3b22iLRR+IKUeBTDW14kcm9wbRU1JICp7JVl8fQNSZLijS/HaEjy5IAvwfIoqU9cOQxZfYMqW0JgBz/qhLaWFMvybmkYCeIDfiRmWoTZTJwZMli6gkarACOEUkOGWWXbD1GUbTuU+aRAnISjKz2YDeZQtdBBUMKCgpbBSYDnEj6R1HQYwgfKMbSxY30b2wjhmPyshLA3y/aAXeWz3BSyI2eWrFDke0xRbaGAhTTSGAaMWwzzRZQCc2xIulllW17Zp0CCgCypEULML1OiytjQghRtG8DEN5VPJApCP6KqScomCE6fBfvVZoQxbpcREkgsHP5jcxniawdxZwoHDHOhYqZjnpkye10cN5S/0INlhHjo7YSnvn0D7v8Gu//wPexy54fAkBOu4fmiwJcmlf6N8utoXkiREyHa4QIEjMnjhglOmwxt8QF6l+o5cpi2WwNBT5ZaQIvMuFHZk5lnOa7FtpwzUh2iAGQIp3ZcmoldOTxqXRJn6NlslwAMKjQgRanBjvT1UdBcLYzscewXSWyRClQZ6C6yRQUFDbA7v/vJrBYw4S93sad4/4PAGC/ke+jTZBIO0TWwhE+UwBgGjEMnRSf+WvUeWWIxYdsE8h4k0pZlmiDpuxMZ0sHyuwUrQANgrAM8LIRN9OMRWYoXRRpXMQF0hhvlSd+EfGSqqENZAIWIiRbolsqTLgStqEzqW1DmR1LZAq82MyMJUkd1iMTyNiC2BnuCWMamJYnotPCamgJLF0IQorx2HqMdV4B/zz+x112nUf+YibGfOo9tPsuWtwa+jdYOb8ungHJl8CoTEXnTdwgiC6rrEI3BUm2HiERYoqSJC9kC4LQQLvwbGsPHJSsALYeoT1xpPJ3oqVq3sTXCUXw6BgRn1sRoLhGJHzjAtl2X7Z9rBfdX4aeoCNw0GR78l6hMQeCbE3+c2SOS+djaAyB4AlRlxvpFBXNENC2q9F9m8ESBrYdwRdTnCEJFQwpKChsAMfl7fIrq2WMvWcaHDvCwAb+BB6Q91anchl1dXGidCIyLnEmU6TDhykJxE22lysvZbt7sshmfiJBdi5YoRS3I7sN8iOj49RDrlYcMkOKA2oaV6OmTqXO2Q8KWqTekGixNnQmM1GGnkhBRMoo1MWiSccGeNmFiSwVObfT+dHiSkazlHmi882SjklX5x/H/eRjXcsR//fHeOerV+deO+DB72FQqYLxB1f5uIU1BWW0AC6aSZkzaCwnYkgaPtKoVARIWQkEmh+uKG3C1iNeigIntVdCW55j1pQ2baVPUDQDeHGRZ2u09JiUkbG0NDCthDZ/T09LqjSmIONrVg1tSfy29ViWZCkj5GVMe+k86XM/9Ery/LK8IboPSlYAltEoUug7UMHQFkCRc3t7ey+PREGh56AHNcSJjhXvu9A0H4XER8AC6CxEkHlajkUgUrACJLGJSAQuVHoyM+3vpp5w/oURI9ISWIUaNKaj4rky2DH1BLVEh2PEMlujawxR4CACZGdWG9OhwweDhlBkehgACqPyHlkBNDAwPZFdbQAQiYCDyl60D2MaXyRDhihiSMQ5MtGCn4C3+jtGDN8zAD1BEiaIEgNMjM8RmYUoNqGLbBAt8PXIlMRcmf0Siy5lZSh/xMuFDB2e+7G+g/57yRkY2HIAJtx/OdZVG+DaIRptD41Mg+X7WO/xdnUDEWpeAQmLpWxChLTbimkMsRnBjw1YegKWyR55CXeIz5aw6HwTjfvA1YMYdWjwwhCWnvB9kpi/L8qgBtMApkGLYvgAojhBEnkIvLRDLHfsmH8mxGf64JlCL9Gha/z6GBpDEJnQjRgB01CPNARRBMMOoBkxPmIa+rsVtHtFeT4JAC8TzBFnSNcY2mWGrM7vHaahYPqwAMRMQxjEMLy6uI+6P+sSMX+7Sl0RVOBG0JjKk20W7733HoYPH97bw1BQUFBQ6EN49913seuuu3bLsT3Pw6hRo7B69ertPtaQIUOwbNkyuK675Y0/wVDB0BaQJAlWrlyJxsZGaFrPGSJuD9rb2zF8+HC8++67KJfLvT2crUZfHLcac89AjblnoMa8/WCMoaOjA8OGDYOud1+Pkud5CIJgu49j2/ZOHwgBqky2Rei63m3RfXejXC7vEF8O24q+OG415p6BGnPPQI15+9DU1NTtn+G6rgpiuhCqtV5BQUFBQUFhp4YKhhQUFBQUFBR2aqhg6BMIx3EwZcoUOI7T20PZJvTFcasx9wzUmHsGaswKOysUgVpBQUFBQUFhp4bKDCkoKCgoKCjs1FDBkIKCgoKCgsJODRUMKSgoKCgoKOzUUMGQgoKCgoKCwk4NFQz1UUyfPh0TJkxAsVhEc3PzBu8vWLAA55xzDoYPH45CoYCxY8fiZz/72RaPO3LkSGialvv5wQ9+0CNjBoAVK1bg1FNPRbFYxKBBg3D11VcjiqKNbktYt24dzj33XJTLZTQ3N+PCCy9EpVLpkjFn8eSTT24wN/Qzb968Te53zDHHbLD9JZdc0uXj2xQ+zjX1PA+XXXYZ+vfvj1KphDPPPBMffPBBD40YWL58OS688EKMGjUKhUIBe+yxB6ZMmbJFxd2enuuf//znGDlyJFzXxbhx4/DCCy9sdvs///nP2HvvveG6Lvbbbz88/PDD3Ta2zpgxYwYOO+wwNDY2YtCgQTj99NOxZMmSze4ze/bsDeazJ4X+pk6dusHn77333pvdpzfnWKHvQgVDfRRBEOCss87C17/+9Y2+P3/+fAwaNAi///3vsWjRInz3u9/Fddddh//5n//Z4rFvuOEGrFq1Sv584xvf6JExx3GMU089FUEQYO7cufjtb3+L2bNn4/vf//5mj3vuuedi0aJFmDNnDh588EH885//xMUXX9wlY85iwoQJuXlZtWoVvvrVr2LUqFE49NBDN7vvRRddlNvvRz/6UZePb3PY1mt61VVX4YEHHsCf//xnPPXUU1i5ciU+//nP99BogX//+99IkgS33347Fi1ahJtvvhm//OUv8Z3vfGeL+/bUXP/xj3/EN7/5TUyZMgUvvfQSDjjgAEycOBFr1qzZ6PZz587FOeecgwsvvBAvv/wyTj/9dJx++ul47bXXumV8nfHUU0/hsssuw3PPPYc5c+YgDEOceOKJqFarm92vXC7n5vOdd97pkfESPvWpT+U+/+mnn97ktr09xwp9GEyhT2PWrFmsqalpq7a99NJL2bHHHrvZbUaMGMFuvvnm7R/YZrCpMT/88MNM13W2evVq+dptt93GyuUy831/o8d6/fXXGQA2b948+dojjzzCNE1j77//fpePPYsgCNjAgQPZDTfcsNntjj76aHbFFVd061g2h229pq2trcyyLPbnP/9ZvrZ48WIGgD377LPdMMKtw49+9CM2atSozW7Tk3N9+OGHs8suu0z+HccxGzZsGJsxY8ZGt//CF77ATj311Nxr48aNY1/72te6dZybwpo1axgA9tRTT21ym235fukOTJkyhR1wwAFbvf2ONscKfQcqM7QToa2tDS0tLVvc7gc/+AH69++Pgw46CD/+8Y+3WKbqKjz77LPYb7/9MHjwYPnaxIkT0d7ejkWLFm1yn+bm5lxm5oQTToCu63j++ee7dbz3338/1q5di6985Stb3PbOO+/EgAEDsO++++K6665DrVbr1rF1xrZc0/nz5yMMQ5xwwgnytb333hu77bYbnn322Z4Y7kaxtfdvT8x1EASYP39+bo50XccJJ5ywyTl69tlnc9sD/P7urTlta2sDgC3OaaVSwYgRIzB8+HCcdtppm/y/2F148803MWzYMOy+++4499xzsWLFik1uu6PNsULfgTJq3Ukwd+5c/PGPf8RDDz202e0uv/xyHHzwwWhpacHcuXNx3XXXYdWqVfjpT3/a7WNcvXp1LhACIP9evXr1JvcZNGhQ7jXTNNHS0rLJfboKv/71rzFx4sQtGvl+6UtfwogRIzBs2DC8+uqruOaaa7BkyRLcfffd3To+wrZe09WrV8O27Q14XYMHD+72Od0U3nrrLdx6662YOXPmZrfrqbn+6KOPEMfxRu/Xf//73xvdZ1P3d2/MaZIkuPLKK3HEEUdg33333eR2Y8aMwW9+8xvsv//+aGtrw8yZMzFhwgQsWrSoRwysx40bh9mzZ2PMmDFYtWoVpk2bhiOPPBKvvfYaGhsbN9h+R5pjhT6G3k5NKaS45pprGIDN/ixevDi3z9aksRcuXMgGDBjAbrzxxm0e069//WtmmibzPK/bx3zRRRexE088MfdatVplANjDDz+80c+fPn06Gz169AavDxw4kP3iF7/YqnP8OOfw7rvvMl3X2V/+8pet+owsHn/8cQaAvfXWW9u87/aMmbCla3rnnXcy27Y3eP2www5j//Vf//Wxx/xxx/3ee++xPfbYg1144YXb/HldMdcbw/vvv88AsLlz5+Zev/rqq9nhhx++0X0sy2J33XVX7rWf//znbNCgQV06tq3BJZdcwkaMGMHefffdbdovCAK2xx57sOuvv76bRrZ5rF+/npXLZfZ//+//3ej7O9IcK/QtqMzQDoRvfetbuOCCCza7ze67775Nx3z99ddx/PHH4+KLL8b111+/zWMaN24coijC8uXLMWbMmA3e78oxDxkyZINuHOpgGjJkyCb36UxYjaII69at2+Q+nfFxzmHWrFno378/Pve5z23VZ2Qxbtw4ADzbsccee2zz/sD2zfuWrumQIUMQBAFaW1tz2aEPPvhgq+d0U9jWca9cuRLHHnssJkyYgF/96lfb/HldMdcbw4ABA2AYxgYddpuboyFDhmzT9t2FyZMny0aDbc3uWJaFgw46CG+99VY3jW7zaG5uxujRozf5+TvKHCv0PahgaAfCwIEDMXDgwC473qJFi3Dcccdh0qRJmD59+sc6xiuvvAJd1zcoRRG6cszjx4/H9OnTsWbNGvl5c+bMQblcxj777LPJfVpbWzF//nwccsghAIAnnngCSZLIhXBL2NZzYIxh1qxZOP/882FZ1lbvR3jllVcAAEOHDt3mfQnbM+9buqaHHHIILMvC448/jjPPPBMAsGTJEqxYsQLjx4//2GMGtm3c77//Po499lgccsghmDVrFnR92ymOXTHXG4Nt2zjkkEPw+OOP4/TTTwfAS0+PP/44Jk+evNF9xo8fj8cffxxXXnmlfG3OnDnbPadbC8YYvvGNb+Cee+7Bk08+iVGjRm3zMeI4xsKFC3HKKad0wwi3jEqlgqVLl+K8887b6Pu9PccKfRi9nZpS+Hh455132Msvv8ymTZvGSqUSe/nll9nLL7/MOjo6GGO8NDZw4ED25S9/ma1atUr+rFmzRh7j+eefZ2PGjGHvvfceY4yxuXPnsptvvpm98sorbOnSpez3v/89GzhwIDv//PN7ZMxRFLF9992XnXjiieyVV15hjz76KBs4cCC77rrrNjlmxhg76aST2EEHHcSef/559vTTT7O99tqLnXPOOV0y5o3hscce22QZ6r333mNjxoxhzz//PGOMsbfeeovdcMMN7MUXX2TLli1j9913H9t9993ZUUcd1W3jy2JrrmnnMTPGyyi77bYbe+KJJ9iLL77Ixo8fz8aPH98jY6Yx7bnnnuz4449n7733Xu4e3tS4e3qu//CHPzDHcdjs2bPZ66+/zi6++GLW3NwsuyHPO+88du2118rtn3nmGWaaJps5cyZbvHgxmzJlCrMsiy1cuLBbxtcZX//611lTUxN78sknc/NZq9XkNp3HPG3aNPa3v/2NLV26lM2fP5+dffbZzHVdtmjRoh4Z87e+9S325JNPsmXLlrFnnnmGnXDCCWzAgAHye2xHm2OFvgsVDPVRTJo0aaN8i3/84x+MMd6SurH3R4wYIY/xj3/8gwFgy5YtY4wxNn/+fDZu3DjW1NTEXNdlY8eOZTfddNMmuSVdPWbGGFu+fDk7+eSTWaFQYAMGDGDf+ta3WBiGmxwzY4ytXbuWnXPOOaxUKrFyucy+8pWvyACrO3DOOeewCRMmbPS9ZcuW5c5pxYoV7KijjmItLS3McRy25557squvvpq1tbV12/iy2Jpr2nnMjDFWr9fZpZdeyvr168eKxSI744wzcoFId2PWrFmb5BRtaty9Mde33nor22233Zht2+zwww9nzz33nHzv6KOPZpMmTcpt/6c//YmNHj2a2bbNPvWpT7GHHnqo28bWGZuaz1mzZm1yzFdeeaU8v8GDB7NTTjmFvfTSSz025i9+8Yts6NChzLZttssuu7AvfvGLOf7XjjbHCn0XGmOMdXv6SUFBQUFBQUFhB4XSGVJQUFBQUFDYqaGCIQUFBQUFBYWdGioYUlBQUFBQUNipoYIhBQUFBQUFhZ0aKhhSUFBQUFBQ2KmhgiEFBQUFBQWFnRoqGFJQUFBQUFDYqaGCIQUFBQUFBYWdGioYUlDI4Jhjjsn5GvX1z7zgggukd9YnCcuXL4emadJ77Mknn4SmaWhtbe3VcSkoKPRNqGBIQaGXcffdd+PGG2+Uf48cORK33HJL7w2oD2LChAlYtWoVmpqauvS4mqbh3nvv7dJjKigo7HhQrvUKCr2MlpaW3h7CDosgCGDb9ha3s20bQ4YM6YERKSgofBKhMkMKCpvA+vXrcf7556Nfv34oFos4+eST8eabb8r3Z8+ejebmZvztb3/D2LFjUSqVcNJJJ2HVqlVymyiKcPnll6O5uRn9+/fHNddcg0mTJuVKV9ky2THHHIN33nkHV111FTRNg6ZpAICpU6fiwAMPzI3vlltuwciRI+XfcRzjm9/8pvys//qv/0Jn68EkSTBjxgyMGjUKhUIBBxxwAP7yl79s9ZwsWrQIn/nMZ1Aul9HY2IgjjzwSS5culce+4YYbsOuuu8JxHBx44IF49NFHc/svXLgQxx13HAqFAvr374+LL74YlUpFvk9lvenTp2PYsGEYM2YMAOCFF17AQQcdBNd1ceihh+Lll1/OHbdzmWxrrs28efPw6U9/GgMGDEBTUxOOPvpovPTSS/J9mtszzjgDmqbl5vq+++7DwQcfDNd1sfvuu2PatGmIoggAwBjD1KlTsdtuu8FxHAwbNgyXX375Vs+xgoJCz0MFQwoKm8AFF1yAF198Effffz+effZZMMZwyimnIAxDuU2tVsPMmTNxxx134J///CdWrFiBb3/72/L9H/7wh7jzzjsxa9YsPPPMM2hvb99s2eXuu+/GrrvuihtuuAGrVq3KLd5bwk9+8hPMnj0bv/nNb/D0009j3bp1uOeee3LbzJgxA7/73e/wy1/+EosWLcJVV12FL3/5y3jqqae2ePz3338fRx11FBzHwRNPPIH58+fjP//zP2UQ8LOf/Qw/+clPMHPmTLz66quYOHEiPve5z8kAslqtYuLEiejXrx/mzZuHP//5z3jssccwefLk3Oc8/vjjWLJkCebMmYMHH3wQlUoFn/nMZ7DPPvtg/vz5mDp1am6ON4UtXZuOjg5MmjQJTz/9NJ577jnstddeOOWUU9DR0QGAB0sAMGvWLKxatUr+/a9//Qvnn38+rrjiCrz++uu4/fbbMXv2bEyfPh0A8Ne//hU333wzbr/9drz55pu49957sd9++21xvAoKCr2I7Te+V1D45ODoo49mV1xxBXvjjTcYAPbMM8/I9z766CNWKBTYn/70J8YYY7NmzWIA2FtvvSW3+fnPf84GDx4s/x48eDD78Y9/LP+Ooojttttu7LTTTtvgMwkjRoxgN998c25cU6ZMYQcccEDutZtvvpmNGDFC/j106FD2ox/9SP4dhiHbdddd5Wd5nseKxSKbO3du7jgXXnghO+ecczY7L4wxdt1117FRo0axIAg2+v6wYcPY9OnTc68ddthh7NJLL2WMMfarX/2K9evXj1UqFfn+Qw89xHRdZ6tXr2aMMTZp0iQ2ePBg5vu+3Ob2229n/fv3Z/V6Xb522223MQDs5ZdfZowx9o9//IMBYOvXr2eMbd216Yw4jlljYyN74IEH5GsA2D333JPb7vjjj2c33XRT7rU77riDDR06lDHG2E9+8hM2evToTc6TgoLCjgeVGVJQ2AgWL14M0zQxbtw4+Vr//v0xZswYLF68WL5WLBaxxx57yL+HDh2KNWvWAADa2trwwQcf4PDDD5fvG4aBQw45pMvH29bWhlWrVuXGa5omDj30UPn3W2+9hVqthk9/+tMolUry53e/+50sdW0Or7zyCo488khYlrXBe+3t7Vi5ciWOOOKI3OtHHHGEnK/FixfjgAMOQENDQ+79JEmwZMkS+dp+++2X4wktXrwY+++/P1zXla+NHz9+i+Pd3LUBgA8++AAXXXQR9tprLzQ1NaFcLqNSqWDFihWbPe6CBQtwww035ObwoosuwqpVq1Cr1XDWWWehXq9j9913x0UXXYR77rlHZs8UFBR2TCgCtYLCdqBzYKBp2gY8na6ArusbHDdbrtsaEDfnoYcewi677JJ7z3GcLe5fKBS26fM+LrLB0vZgS9dm0qRJWLt2LX72s59hxIgRcBwH48ePRxAEmz1upVLBtGnT8PnPf36D91zXxfDhw7FkyRI89thjmDNnDi699FL8+Mc/xlNPPbXRQFJBQaH3oTJDCgobwdixYxFFEZ5//nn52tq1a7FkyRLss88+W3WMpqYmDB48WHJNAE5yzpJ0NwbbthHHce61gQMHYvXq1bnFnDR26LOGDh2aG28URZg/f778e5999oHjOFixYgX23HPP3M/w4cO3eD77778//vWvf200CCuXyxg2bBieeeaZ3OvPPPOMnK+xY8diwYIFqFarufd1XZdE6Y1h7NixePXVV+F5nnztueee2+J4t4RnnnkGl19+OU455RR86lOfguM4+Oijj3LbWJa1wbU4+OCDsWTJkg3mcM8994Su86/UQqGAz372s/jv//5vPPnkk3j22WexcOHC7R6zgoJC90AFQwoKG8Fee+2F0047DRdddBGefvppLFiwAF/+8pexyy674LTTTtvq43zjG9/AjBkzcN9992HJkiW44oorsH79etkltjGMHDkS//znP/H+++/LxfmYY47Bhx9+iB/96EdYunQpfv7zn+ORRx7J7XfFFVfgBz/4Ae699178+9//xqWXXpoTIWxsbMS3v/1tXHXVVfjtb3+LpUuX4qWXXsKtt96K3/72t1s8l8mTJ6O9vR1nn302XnzxRbz55pu44447ZInr6quvxg9/+EP88Y9/xJIlS3DttdfilVdewRVXXAEAOPfcc+G6LiZNmoTXXnsN//jHP/CNb3wD5513HgYPHrzJz/3Sl74ETdNw0UUX4fXXX8fDDz+MmTNnbnG8W8Jee+2FO+64A4sXL8bzzz+Pc889d4Ps18iRI/H4449j9erVWL9+PQDg+9//Pn73u99h2rRp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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ds['lst'].sel(lat=slice(51,59), lon=slice(-15,7)).mean(dim='time').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9bbe250-b900-4049-a0fb-986a60f42e8d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "build_venv", + "language": "python", + "name": "build_venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/builder/showcase/notebooks/Kerchunk Parquet with HTTPS.ipynb b/builder/showcase/notebooks/Kerchunk Parquet with HTTPS.ipynb new file mode 100644 index 0000000..fb8d5da --- /dev/null +++ b/builder/showcase/notebooks/Kerchunk Parquet with HTTPS.ipynb @@ -0,0 +1,157 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e95ead92-8178-41f0-a97c-09059b645dbd", + "metadata": {}, + "source": [ + "# Kerchunk Parquet Store Recipe\n", + "Requires the latest version of fsspec (2023.6.0+) for some of the options in the LazyReferenceMapper required by Parquet stores. Parquet also requires the library fastparquet (2023.7.0+) installed into your Kernel/Environment." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8f87dbae-9a47-42d2-b396-25707818c7ca", + "metadata": {}, + "outputs": [], + "source": [ + "from fsspec.implementations.reference import ReferenceFileSystem\n", + "import matplotlib.pyplot as plt\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "id": "5f2f464b-bcb4-4d43-bdaf-c57c61f7feb4", + "metadata": {}, + "source": [ + "There are two example parquet stores in this repository so far for two ESACCI datasets, these could be Kerchunked using the standard JSON format but for a comparison between the two methods, Parquet versions have also been created.\n", + "The directory structure reflects that of the Kerchunk pipeline output, which puts all files concerned with a specific dataset inside a single directory labelled with the project code. The kerchunk file revision is set to 1.0 for any new dataset, with revisions later on when fixing metadata." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "fa66871a-a8bf-4d42-8214-075a286c2cbd", + "metadata": {}, + "outputs": [], + "source": [ + "pq = '../../examples/ESACCI-SEAICE-L3C-SITHICK-RA2_ENVISAT-NH25KMEASE2-200210-201203-fv2.0/kerchunk-kr1.0.parq'" + ] + }, + { + "cell_type": "markdown", + "id": "6db58d77-092a-4731-8790-97f0ff84b197", + "metadata": {}, + "source": [ + "Open Reference File System and use as Mapper for Xarray, with the Lazy loading option set as true and remote protocol as https for the Kerchunk file links using the CEDA DAP service." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3b28dd86-5cf9-4e08-93ad-62958c62fe7a", + "metadata": {}, + "outputs": [], + "source": [ + "fs = ReferenceFileSystem(\n", + " pq, \n", + " remote_protocol='https', \n", + " target_protocol=\"file\", \n", + " lazy=True)" + ] + }, + { + "cell_type": "markdown", + "id": "3d321498-ed8f-48c1-abdc-3c171c915bb2", + "metadata": {}, + "source": [ + "Now we have the fs virtual filesystem object we can get a mapper for use in xarray to open a virtual dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "08042522-5af9-42fc-8451-258b33326c4c", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(\n", + " fs.get_mapper(), \n", + " engine=\"zarr\",\n", + " backend_kwargs={\"consolidated\": False, \"decode_times\": False}\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "20402ef1-f665-400c-aa1a-9f5127c76dcf", + "metadata": {}, + "source": [ + "The __ds__ virtual xarray dataset is then used as you would with a dataset opened directly from NetCDF.\n", + "Note that arrays within the virtual dataset are listed as DASK arrays, so to get actual values from calculations, the processing must be forced with methods like __.plot()__ or __.value()__" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "683483f4-69cb-4725-8bf9-989a5770183a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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zYa///3vuPPOO/HSSy/hn//8Z42jEb1790ZSUhIuX75c5evdunXDnj173I7t2bMH3bt3V14/d+6c2wjPiRMnUFhYqLSp7rrnzp1DTk6OcuyPP/7w6DPWZM+ePZg2bRomT56MXr16wWQyISMjw62NRqOBKIpux/r3748TJ04gNja20qO6XZG13Zu6SE5OhtlsVp7/8ccf8Pb2dhuRrOr9ExMT3VJl7NmzB0ajER07dqzUvnv37tBqtcjMzKz0GV3v07t3b+zevRt2u73K96zq3jW0X4SQ1oeCM0Ia0bPPPouioiK88847WLBgAbp06YL/+7//q7b91KlTYTKZMGnSJOzZswd//vknvvvuOyQmJgIAnnjiCXz66af44IMPcPr0abz55pv473//i8cffxwAMGbMGPTq1Qv33HMPDh06hH379uHee+/FyJEjMXDgwGrfd8yYMejSpQvuu+8+JCcnY/fu3Xj22Wcb/Pnj4uLw3//+F0lJSUhOTsbdd99daTQmKioKv/76K7Kzs3Hx4kUAwIIFC/D7779j1qxZSEpKwunTp/HDDz9g1qxZ1b5XbfemLmw2G6ZPn44TJ05g48aNWLRoEWbNmgWer/5H5COPPIJz587h0UcfRUpKCn744QcsWrQI8+bNq/I8o9GIxx9/HHPnzsVnn32GtLQ0HDp0CCtWrMBnn30GAJg1axaKi4tx11134cCBAzh9+jTWrl2r7IiNiorCkSNHkJqaiosXL1YZxNW1X4SQVqilF70R0l7s3LmTqVQqtnv3buVYeno68/HxYe+//36152VkZLApU6YwHx8f5uXlxQYOHMj27t2rvP7++++zmJgYplarWZcuXdiaNWvczj979iybMGECMxgMzGg0sttvv53l5uYqry9atIj16dOn0vumpqayG264gWk0GtalSxe2adMmjzYEFBQUKNc4fPgwA8DS09OVc0aNGsX0ej2LiIhg7777Lhs5ciR77LHHlHMSExNZ7969mVarZRV/BO3bt4/ddNNNzNvbmxkMBta7d2/2yiuvVHvfPLk3nm4ImDhxInv++edZYGAg8/b2ZjNmzHDbyHH1Z3DZtWsXGzRoENNoNMxkMrEFCxYwu91e6doukiSxt956i3Xt2pWp1WoWHBzMEhIS2C+//KK0SU5OZmPHjmVeXl7MaDSy4cOHs7S0NMaYvAPVdY8AsJ07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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ds['sea_ice_thickness'].mean(dim='time').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0373539-c8e4-457a-b889-f6afa88be3fd", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "build_venv", + "language": "python", + "name": "build_venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/builder/showcase/notebooks/Kerchunk Reading Recipes.ipynb b/builder/showcase/notebooks/Kerchunk Reading Recipes.ipynb new file mode 100644 index 0000000..b1a6777 --- /dev/null +++ b/builder/showcase/notebooks/Kerchunk Reading Recipes.ipynb @@ -0,0 +1,221 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2ef50b3c-05bb-443c-a50e-0cb9d8a6c777", + "metadata": {}, + "source": [ + "# Kerchunk Reading Recipes\n", + "Here we give examples of different formats for Kerchunk which require specific Recipes to open.\n", + "\n", + "Access Control:\n", + " - No credentials\n", + " - Certificate Credentials\n", + " - Token Credentials\n", + "\n", + "Link Type:\n", + " - Local Kerchunk File\n", + " - Kerchunk over HTTPS (Kerchunk file itself is HTTPS link)\n", + " - Kerchunk via S3\n", + "\n", + "Kerchunk Type:\n", + " - Standard Kerchunk JSON\n", + " - Kerchunk ZSTD\n", + " - Kerchunk Parquet\n", + "\n", + "See https://stfc365-my.sharepoint.com/:x:/r/personal/daniel_westwood_stfc_ac_uk/_layouts/15/Doc.aspx?sourcedoc=%7B1A4A6C96-4291-40D7-A6E3-4665AEA57EF1%7D&file=Book.xlsx&action=editnew&mobileredirect=true&wdNewAndOpenCt=1696858849368&ct=1696858849741&wdPreviousSession=d8a3c4f4-b716-409a-8793-00cba44b2d8f&wdOrigin=OFFICECOM-WEB.START.NEW&login_hint=daniel.westwood%40stfc.ac.uk&cid=d063908b-7e3c-42c1-9bfb-f7c700f38fe7&wdPreviousSessionSrc=HarmonyWeb for a summary of known recipes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea29521e-3a06-4048-ba6d-685b4bd3729d", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "import s3fs\n", + "\n", + "import aiohttp\n", + "import asyncio\n", + "import requests\n", + "import ssl\n", + "from fsspec.implementations.reference import LazyReferenceMapper" + ] + }, + { + "cell_type": "markdown", + "id": "f5f3cb6d-bc57-4e72-a988-929e8ba2a814", + "metadata": {}, + "source": [ + "## Access Control: No Credentials\n", + "Opening sequences for Kerchunk with No Access control\n", + "\n", + "### Local K File Opening" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f1db789e-6922-4f74-8568-f8ac291c6da1", + "metadata": {}, + "outputs": [], + "source": [ + "# Standard Kerchunk JSON\n", + "kfile = 'kerchunk.json'\n", + "mapper = fsspec.get_mapper(\n", + " 'reference://', # Required\n", + " fo=kfile, # Required\n", + " **get_mapper_kwargs)\n", + "\n", + "ds = xr.open_zarr(\n", + " kfile, # Required\n", + " **open_zarr_kwargs) \n", + "\n", + "# Requires get_mapper_kwargs, open_zarr_kwargs (consolidated=False, decode_times=False, decode_timedelta=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a8239a6-c2ee-4ff8-a6cc-3a0da74ca0fe", + "metadata": {}, + "outputs": [], + "source": [ + "# Kerchunk ZSTD\n", + "kzstd = 'kerchunk.zst'\n", + "mapper = fsspec.get_mapper(\n", + " 'reference://', # Required\n", + " fo=kzstd, # Required\n", + " target_options={'compression':'zstd'} # Required\n", + " **get_mapper_kwargs)\n", + "\n", + "ds = xr.open_zarr(\n", + " kfile, # Required\n", + " **open_zarr_kwargs) \n", + "\n", + "# Requires get_mapper_kwargs, open_zarr_kwargs (consolidated=False, decode_times=False, decode_timedelta=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fee36aa-0efc-4e14-af56-a054a07551de", + "metadata": {}, + "outputs": [], + "source": [ + "# Kerchunk Parquet\n", + "kstore = 'kerchunk.parq'\n", + "fs = fsspec.implementations.reference.ReferenceFileSystem(\n", + " kstore, # Required\n", + " remote_protocol='file', # Required\n", + " target_protocol=\"file\", # Required\n", + " lazy=True, # Required\n", + " **rfs_kwargs)\n", + "\n", + "ds = xr.open_dataset(\n", + " fs.get_mapper(), # Required\n", + " engine=\"zarr\", # Required\n", + " **open_dataset_kwargs)\n", + "\n", + "# Requires rfs_kwargs, open_dataset_kwargs (backend_kwargs={\"consolidated\": False, \"decode_times\": False})" + ] + }, + { + "cell_type": "markdown", + "id": "11bce8d3-05c0-4d34-9662-362dda85e73e", + "metadata": {}, + "source": [ + "## Kerchunk over HTTPS" + ] + }, + { + "cell_type": "markdown", + "id": "ba309514-4e61-441b-9b04-c720611dd012", + "metadata": {}, + "source": [ + "## Kerchunk via S3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbafb600-e121-485e-afde-c489858bc2b7", + "metadata": {}, + "outputs": [], + "source": [ + "# Standard Kerchunk JSON\n", + "kfile = \"s3://test_bucket/kerchunk.json\"\n", + "ref = s3fs.S3FileSystem(**fssopts) # fssopts - key, secret, client_kwargs\n", + "ref = ref.open(kfile) # s3open - compression=None\n", + "\n", + "mapper = fsspec.get_mapper(\n", + " \"reference://\", \n", + " fo=ref,\n", + " target_protocol=\"http\", \n", + " remote_options=fssopts, \n", + " target_options={\"compression\": None}\n", + ")\n", + "xobj = xr.open_zarr(mapper, **_xr_open_args)\n", + "\n", + "# Requires s3fssopts_kwargs, get_mapper_kwargs, open_zarr_kwargs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48f88db7-885e-4bca-9339-3e5a08ec9d51", + "metadata": {}, + "outputs": [], + "source": [ + "# Kerchunk ZSTD\n", + "kfile = \"s3://test_bucket/kerchunk.zst\"\n", + "ref = s3fs.S3FileSystem(**fssopts) # fssopts - key, secret, client_kwargs\n", + "ref = ref.open(kfile) # s3open - compression=None\n", + "\n", + "mapper = fsspec.get_mapper(\n", + " \"reference://\", \n", + " fo=ref,\n", + " target_protocol=\"http\", \n", + " remote_options=fssopts, \n", + " target_options={\"compression\": 'zstd'} # Simple change\n", + ")\n", + "xobj = xr.open_zarr(mapper, **_xr_open_args)\n", + "\n", + "# Requires s3fssopts_kwargs, get_mapper_kwargs, open_zarr_kwargs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c284564f-fd34-4e58-8cd8-3f9917259faf", + "metadata": {}, + "outputs": [], + "source": [ + "# Kerchunk Parquet?\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "build_venv", + "language": "python", + "name": "build_venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/builder/showcase/notebooks/StoreSize.ipynb b/builder/showcase/notebooks/StoreSize.ipynb new file mode 100644 index 0000000..613f836 --- /dev/null +++ b/builder/showcase/notebooks/StoreSize.ipynb @@ -0,0 +1,1065 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "id": "70c74604-24ee-4407-a788-07ac13dd6c32", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import matplotlib.pyplot as plt\n", + "import s3fs\n", + "import xarray as xr\n", + "import numpy as np\n", + "import zarr" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "9cba2403-8b24-4884-ac3a-6644da3bdc69", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'xcube.core'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mxcube\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mcore\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mstore\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m new_data_store\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'xcube.core'" + ] + } + ], + "source": [ + "from xcube.core.store import new_data_store" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "08f08790-c78a-4e8d-b949-5788226cbe38", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'new_data_store' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m zarr_store \u001b[38;5;241m=\u001b[39m \u001b[43mnew_data_store\u001b[49m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mccizarr\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 3\u001b[0m zarr_store\u001b[38;5;241m.\u001b[39mgetsize()\n", + "\u001b[0;31mNameError\u001b[0m: name 'new_data_store' is not defined" + ] + } + ], + "source": [ + "zarr_store = new_data_store('ccizarr')\n", + "\n", + "zarr_store.getsize()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "581f3323-ce3a-4c1e-9d88-e6232e2822df", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_zarr('http://cci-ke-o.s3.jc.rl.ac.uk/esacci/ESACCI-BIOMASS-L4-AGB-MERGED-100m-2010-2018-fv2.0.zarr')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "4d35c558-999d-496c-bbce-a6be60de92e8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:    (time: 3, lat: 157500, lon: 405000, nv: 2)\n",
+       "Coordinates:\n",
+       "  * lat        (lat) float64 80.0 80.0 80.0 80.0 ... -60.0 -60.0 -60.0 -60.0\n",
+       "    lat_bnds   (lat, nv) float64 dask.array<chunksize=(810, 2), meta=np.ndarray>\n",
+       "  * lon        (lon) float64 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n",
+       "    lon_bnds   (lon, nv) float64 dask.array<chunksize=(810, 2), meta=np.ndarray>\n",
+       "  * time       (time) datetime64[ns] 2010-07-02 2017-07-02 2018-07-02\n",
+       "    time_bnds  (time, nv) datetime64[ns] dask.array<chunksize=(3, 2), meta=np.ndarray>\n",
+       "Dimensions without coordinates: nv\n",
+       "Data variables:\n",
+       "    agb        (time, lat, lon) float32 dask.array<chunksize=(3, 810, 810), meta=np.ndarray>\n",
+       "    agb_se     (time, lat, lon) float32 dask.array<chunksize=(3, 810, 810), meta=np.ndarray>\n",
+       "Attributes: (12/53)\n",
+       "    Conventions:                  CF-1.7\n",
+       "    EPSG:                         4326\n",
+       "    GeoTransform:                 -180   0.00088888888888                  0 ...\n",
+       "    catalogue_url:                https://catalogue.ceda.ac.uk/uuid/84403d09c...\n",
+       "    cdm_data_type:                INT\n",
+       "    comment:                      These data were produced at ESA CCI as part...\n",
+       "    ...                           ...\n",
+       "    time_coverage_duration:       P1Y\n",
+       "    time_coverage_end:            20181231T000000Z\n",
+       "    time_coverage_resolution:     P1Y\n",
+       "    time_coverage_start:          20100101T000000Z\n",
+       "    title:                        ESA CCI above-ground biomass product level ...\n",
+       "    tracking_id:                  def2a99e-4abf-48e8-a5ed-6677d5f5bf6c
" + ], + "text/plain": [ + "\n", + "Dimensions: (time: 3, lat: 157500, lon: 405000, nv: 2)\n", + "Coordinates:\n", + " * lat (lat) float64 80.0 80.0 80.0 80.0 ... -60.0 -60.0 -60.0 -60.0\n", + " lat_bnds (lat, nv) float64 dask.array\n", + " * lon (lon) float64 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " lon_bnds (lon, nv) float64 dask.array\n", + " * time (time) datetime64[ns] 2010-07-02 2017-07-02 2018-07-02\n", + " time_bnds (time, nv) datetime64[ns] dask.array\n", + "Dimensions without coordinates: nv\n", + "Data variables:\n", + " agb (time, lat, lon) float32 dask.array\n", + " agb_se (time, lat, lon) float32 dask.array\n", + "Attributes: (12/53)\n", + " Conventions: CF-1.7\n", + " EPSG: 4326\n", + " GeoTransform: -180 0.00088888888888 0 ...\n", + " catalogue_url: https://catalogue.ceda.ac.uk/uuid/84403d09c...\n", + " cdm_data_type: INT\n", + " comment: These data were produced at ESA CCI as part...\n", + " ... ...\n", + " time_coverage_duration: P1Y\n", + " time_coverage_end: 20181231T000000Z\n", + " time_coverage_resolution: P1Y\n", + " time_coverage_start: 20100101T000000Z\n", + " title: ESA CCI above-ground biomass product level ...\n", + " tracking_id: def2a99e-4abf-48e8-a5ed-6677d5f5bf6c" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "315c6336-5b63-4c85-ad48-2636628ba7da", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "build_venv", + "language": "python", + "name": "build_venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/builder/showcase/notebooks/Untitled.ipynb b/builder/showcase/notebooks/Untitled.ipynb new file mode 100644 index 0000000..f01ddd2 --- /dev/null +++ b/builder/showcase/notebooks/Untitled.ipynb @@ -0,0 +1,632 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 7, + "id": "fb676b02-d648-42b9-9853-77e3ba9d8b36", + "metadata": {}, + "outputs": [], + "source": [ + "dates = \"\"\"11/01/2024\n", + "12/01/2024\n", + "13/01/2024\n", + "14/01/2024\n", + "15/01/2024\n", + "16/01/2024\n", + "17/01/2024\n", + "18/01/2024\n", + "19/01/2024\n", + "20/01/2024\n", + "21/01/2024\n", + "22/01/2024\n", + "23/01/2024\n", + "24/01/2024\n", + "25/01/2024\n", + "26/01/2024\n", + "27/01/2024\n", + "28/01/2024\n", + "29/01/2024\n", + "30/01/2024\n", + "31/01/2024\n", + "01/02/2024\n", + "02/02/2024\n", + "03/02/2024\n", + "04/02/2024\n", + "05/02/2024\n", + "06/02/2024\n", + "07/02/2024\n", + "08/02/2024\n", + "09/02/2024\n", + "10/02/2024\n", + "11/02/2024\n", + "12/02/2024\n", + "13/02/2024\n", + "14/02/2024\n", + "15/02/2024\n", + "16/02/2024\n", + "17/02/2024\n", + "18/02/2024\n", + "19/02/2024\n", + "20/02/2024\n", + "21/02/2024\n", + "22/02/2024\n", + "23/02/2024\n", + "24/02/2024\n", + "25/02/2024\n", + "26/02/2024\n", + "27/02/2024\n", + "28/02/2024\n", + "29/02/2024\n", + "01/03/2024\n", + "02/03/2024\n", + "03/03/2024\n", + "04/03/2024\n", + "05/03/2024\n", + "06/03/2024\n", + "07/03/2024\n", + "08/03/2024\n", + "09/03/2024\n", + "10/03/2024\n", + "11/03/2024\n", + "12/03/2024\n", + "13/03/2024\n", + "14/03/2024\n", + "15/03/2024\n", + "16/03/2024\n", + "17/03/2024\n", + "18/03/2024\n", + "19/03/2024\n", + "20/03/2024\n", + "21/03/2024\n", + "22/03/2024\n", + "23/03/2024\n", + "24/03/2024\n", + "25/03/2024\n", + "26/03/2024\n", + "27/03/2024\n", + "28/03/2024\n", + "29/03/2024\n", + "30/03/2024\n", + "31/03/2024\n", + "01/04/2024\n", + "02/04/2024\n", + "03/04/2024\n", + "04/04/2024\n", + "05/04/2024\n", + "06/04/2024\n", + "07/04/2024\n", + "08/04/2024\n", + "09/04/2024\n", + "10/04/2024\n", + "11/04/2024\n", + "12/04/2024\n", + "13/04/2024\n", + "14/04/2024\n", + "15/04/2024\n", + "16/04/2024\n", + "17/04/2024\n", + "18/04/2024\n", + "19/04/2024\n", + "20/04/2024\n", + "21/04/2024\n", + "22/04/2024\n", + "23/04/2024\n", + "24/04/2024\n", + "25/04/2024\n", + "26/04/2024\n", + "27/04/2024\n", + "28/04/2024\n", + "29/04/2024\n", + "30/04/2024\n", + "01/05/2024\n", + "02/05/2024\n", + "03/05/2024\n", + "04/05/2024\n", + "05/05/2024\n", + "06/05/2024\n", + "07/05/2024\n", + "08/05/2024\n", + "09/05/2024\n", + "10/05/2024\n", + "11/05/2024\n", + "12/05/2024\n", + "13/05/2024\n", + "14/05/2024\n", + "15/05/2024\n", + "16/05/2024\n", + "17/05/2024\n", + "18/05/2024\n", + "19/05/2024\n", + "20/05/2024\n", + "21/05/2024\n", + "22/05/2024\n", + "23/05/2024\n", + "24/05/2024\n", + "25/05/2024\n", + "26/05/2024\n", + "27/05/2024\n", + "28/05/2024\n", + "29/05/2024\n", + "30/05/2024\n", + "31/05/2024\n", + "01/06/2024\n", + "02/06/2024\n", + "03/06/2024\n", + "04/06/2024\n", + "05/06/2024\n", + "06/06/2024\n", + "07/06/2024\n", + "08/06/2024\n", + "09/06/2024\n", + "10/06/2024\n", + "11/06/2024\n", + "12/06/2024\n", + "13/06/2024\n", + "14/06/2024\n", + "15/06/2024\n", + "16/06/2024\n", + "17/06/2024\n", + "18/06/2024\n", + "19/06/2024\n", + "20/06/2024\n", + "21/06/2024\n", + "22/06/2024\n", + "23/06/2024\n", + "24/06/2024\n", + "25/06/2024\n", + "26/06/2024\n", + "27/06/2024\n", + "28/06/2024\n", + "29/06/2024\n", + "30/06/2024\n", + "01/07/2024\n", + "02/07/2024\n", + "03/07/2024\n", + "04/07/2024\n", + "05/07/2024\n", + "06/07/2024\n", + "07/07/2024\n", + "08/07/2024\n", + "09/07/2024\n", + "10/07/2024\n", + "11/07/2024\n", + "12/07/2024\n", + "13/07/2024\n", + "14/07/2024\n", + "15/07/2024\n", + "16/07/2024\n", + "17/07/2024\n", + "18/07/2024\n", + "19/07/2024\n", + "20/07/2024\n", + "21/07/2024\n", + "22/07/2024\n", + "23/07/2024\n", + "24/07/2024\n", + "25/07/2024\n", + "26/07/2024\n", + "27/07/2024\n", + "28/07/2024\n", + "29/07/2024\n", + "30/07/2024\n", + "31/07/2024\n", + "01/08/2024\n", + "02/08/2024\n", + "03/08/2024\n", + "04/08/2024\n", + "05/08/2024\n", + "06/08/2024\n", + "07/08/2024\n", + "08/08/2024\n", + "09/08/2024\n", + "10/08/2024\n", + "11/08/2024\n", + "12/08/2024\n", + "13/08/2024\n", + "14/08/2024\n", + "15/08/2024\n", + "16/08/2024\n", + "17/08/2024\n", + "18/08/2024\n", + "19/08/2024\n", + "20/08/2024\n", + "21/08/2024\n", + "22/08/2024\n", + "23/08/2024\n", + "24/08/2024\n", + "25/08/2024\n", + "26/08/2024\n", + "27/08/2024\n", + "28/08/2024\n", + "29/08/2024\n", + "30/08/2024\n", + "31/08/2024\n", + "01/09/2024\n", + "02/09/2024\n", + "03/09/2024\n", + "04/09/2024\n", + "05/09/2024\n", + "06/09/2024\n", + "07/09/2024\n", + "08/09/2024\n", + "09/09/2024\n", + "10/09/2024\n", + "11/09/2024\n", + "12/09/2024\n", + "13/09/2024\n", + "14/09/2024\n", + "15/09/2024\n", + "16/09/2024\n", + "17/09/2024\n", + "18/09/2024\n", + "19/09/2024\n", + "20/09/2024\n", + "21/09/2024\n", + "22/09/2024\n", + "23/09/2024\n", + "24/09/2024\n", + "25/09/2024\n", + "26/09/2024\n", + "27/09/2024\n", + "28/09/2024\n", + "29/09/2024\n", + "30/09/2024\n", + "01/10/2024\n", + "02/10/2024\n", + "03/10/2024\n", + "04/10/2024\n", + "05/10/2024\n", + "06/10/2024\n", + "07/10/2024\n", + "08/10/2024\n", + "09/10/2024\n", + "10/10/2024\n", + "11/10/2024\n", + "12/10/2024\n", + "13/10/2024\n", + "14/10/2024\n", + "15/10/2024\n", + "16/10/2024\n", + "17/10/2024\n", + "18/10/2024\n", + "19/10/2024\n", + "20/10/2024\n", + "21/10/2024\n", + "22/10/2024\n", + "23/10/2024\n", + "24/10/2024\n", + "25/10/2024\n", + "26/10/2024\n", + "27/10/2024\n", + "28/10/2024\n", + "29/10/2024\n", + "30/10/2024\n", + "31/10/2024\n", + "01/11/2024\n", + "02/11/2024\n", + "03/11/2024\n", + "04/11/2024\n", + "05/11/2024\n", + "06/11/2024\n", + "07/11/2024\n", + "08/11/2024\n", + "09/11/2024\n", + "10/11/2024\n", + "11/11/2024\n", + "12/11/2024\n", + "13/11/2024\n", + "14/11/2024\n", + "15/11/2024\n", + "16/11/2024\n", + "17/11/2024\n", + "18/11/2024\n", + "19/11/2024\n", + "20/11/2024\n", + "21/11/2024\n", + "22/11/2024\n", + "23/11/2024\n", + "24/11/2024\n", + "25/11/2024\n", + "26/11/2024\n", + "27/11/2024\n", + "28/11/2024\n", + "29/11/2024\n", + "30/11/2024\n", + "01/12/2024\n", + "02/12/2024\n", + "03/12/2024\n", + "04/12/2024\n", + "05/12/2024\n", + "06/12/2024\n", + "07/12/2024\n", + "08/12/2024\n", + "09/12/2024\n", + "10/12/2024\n", + "11/12/2024\n", + "12/12/2024\n", + "13/12/2024\n", + "14/12/2024\n", + "15/12/2024\n", + "16/12/2024\n", + "17/12/2024\n", + "18/12/2024\n", + "19/12/2024\n", + "20/12/2024\n", + "21/12/2024\n", + "22/12/2024\n", + "23/12/2024\n", + "24/12/2024\n", + "25/12/2024\n", + "26/12/2024\n", + "27/12/2024\n", + "28/12/2024\n", + "29/12/2024\n", + "30/12/2024\n", + "31/12/2024\"\"\".split('\\n')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "45036c15-1108-4057-b95b-b296829940f8", + "metadata": {}, + "outputs": [], + "source": [ + "pattern = ['Evening','Day','Day','Evening','Night']\n", + "starts = ['15:00','7:00','7:00','15:00','23:00']\n", + "ends = ['23:00','15:00','15:00','23:00','7:00']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "a8465327-2c8f-426d-9342-708b6b1cb8ea", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Subject,Start Date,Start Time,End Date,End Time\n", + "Ellie Evening Shift, 11/01/2024, 15:00, 11/01/2024, 23:00\n", + "Ellie Evening Shift, 12/01/2024, 15:00, 12/01/2024, 23:00\n", + "Ellie Evening Shift, 13/01/2024, 15:00, 13/01/2024, 23:00\n", + "Ellie Evening Shift, 14/01/2024, 15:00, 14/01/2024, 23:00\n", + "Ellie Day Shift, 19/01/2024, 7:00, 19/01/2024, 15:00\n", + "Ellie Day Shift, 20/01/2024, 7:00, 20/01/2024, 15:00\n", + "Ellie Day Shift, 21/01/2024, 7:00, 21/01/2024, 15:00\n", + "Ellie Day Shift, 22/01/2024, 7:00, 22/01/2024, 15:00\n", + "Ellie Day Shift, 27/01/2024, 7:00, 27/01/2024, 15:00\n", + "Ellie Day Shift, 28/01/2024, 7:00, 28/01/2024, 15:00\n", + "Ellie Day Shift, 29/01/2024, 7:00, 29/01/2024, 15:00\n", + "Ellie Day Shift, 30/01/2024, 7:00, 30/01/2024, 15:00\n", + "Ellie Evening Shift, 04/02/2024, 15:00, 04/02/2024, 23:00\n", + "Ellie Evening Shift, 05/02/2024, 15:00, 05/02/2024, 23:00\n", + "Ellie Evening Shift, 06/02/2024, 15:00, 06/02/2024, 23:00\n", + "Ellie Evening Shift, 07/02/2024, 15:00, 07/02/2024, 23:00\n", + "Ellie Night Shift, 12/02/2024, 23:00, 13/02/2024, 7:00\n", + "Ellie Night Shift, 13/02/2024, 23:00, 14/02/2024, 7:00\n", + "Ellie Night Shift, 14/02/2024, 23:00, 15/02/2024, 7:00\n", + "Ellie Night Shift, 15/02/2024, 23:00, 16/02/2024, 7:00\n", + "Ellie Evening Shift, 20/02/2024, 15:00, 20/02/2024, 23:00\n", + "Ellie Evening Shift, 21/02/2024, 15:00, 21/02/2024, 23:00\n", + "Ellie Evening Shift, 22/02/2024, 15:00, 22/02/2024, 23:00\n", + "Ellie Evening Shift, 23/02/2024, 15:00, 23/02/2024, 23:00\n", + "Ellie Day Shift, 28/02/2024, 7:00, 28/02/2024, 15:00\n", + "Ellie Day Shift, 29/02/2024, 7:00, 29/02/2024, 15:00\n", + "Ellie Day Shift, 01/03/2024, 7:00, 01/03/2024, 15:00\n", + "Ellie Day Shift, 02/03/2024, 7:00, 02/03/2024, 15:00\n", + "Ellie Day Shift, 07/03/2024, 7:00, 07/03/2024, 15:00\n", + "Ellie Day Shift, 08/03/2024, 7:00, 08/03/2024, 15:00\n", + "Ellie Day Shift, 09/03/2024, 7:00, 09/03/2024, 15:00\n", + "Ellie Day Shift, 10/03/2024, 7:00, 10/03/2024, 15:00\n", + "Ellie Evening Shift, 15/03/2024, 15:00, 15/03/2024, 23:00\n", + "Ellie Evening Shift, 16/03/2024, 15:00, 16/03/2024, 23:00\n", + "Ellie Evening Shift, 17/03/2024, 15:00, 17/03/2024, 23:00\n", + "Ellie Evening Shift, 18/03/2024, 15:00, 18/03/2024, 23:00\n", + "Ellie Night Shift, 23/03/2024, 23:00, 24/03/2024, 7:00\n", + "Ellie Night Shift, 24/03/2024, 23:00, 25/03/2024, 7:00\n", + "Ellie Night Shift, 25/03/2024, 23:00, 26/03/2024, 7:00\n", + "Ellie Night Shift, 26/03/2024, 23:00, 27/03/2024, 7:00\n", + "Ellie Evening Shift, 31/03/2024, 15:00, 31/03/2024, 23:00\n", + "Ellie Evening Shift, 01/04/2024, 15:00, 01/04/2024, 23:00\n", + "Ellie Evening Shift, 02/04/2024, 15:00, 02/04/2024, 23:00\n", + "Ellie Evening Shift, 03/04/2024, 15:00, 03/04/2024, 23:00\n", + "Ellie Day Shift, 08/04/2024, 7:00, 08/04/2024, 15:00\n", + "Ellie Day Shift, 09/04/2024, 7:00, 09/04/2024, 15:00\n", + "Ellie Day Shift, 10/04/2024, 7:00, 10/04/2024, 15:00\n", + "Ellie Day Shift, 11/04/2024, 7:00, 11/04/2024, 15:00\n", + "Ellie Day Shift, 16/04/2024, 7:00, 16/04/2024, 15:00\n", + "Ellie Day Shift, 17/04/2024, 7:00, 17/04/2024, 15:00\n", + "Ellie Day Shift, 18/04/2024, 7:00, 18/04/2024, 15:00\n", + "Ellie Day Shift, 19/04/2024, 7:00, 19/04/2024, 15:00\n", + "Ellie Evening Shift, 24/04/2024, 15:00, 24/04/2024, 23:00\n", + "Ellie Evening Shift, 25/04/2024, 15:00, 25/04/2024, 23:00\n", + "Ellie Evening Shift, 26/04/2024, 15:00, 26/04/2024, 23:00\n", + "Ellie Evening Shift, 27/04/2024, 15:00, 27/04/2024, 23:00\n", + "Ellie Night Shift, 02/05/2024, 23:00, 03/05/2024, 7:00\n", + "Ellie Night Shift, 03/05/2024, 23:00, 04/05/2024, 7:00\n", + "Ellie Night Shift, 04/05/2024, 23:00, 05/05/2024, 7:00\n", + "Ellie Night Shift, 05/05/2024, 23:00, 06/05/2024, 7:00\n", + "Ellie Evening Shift, 10/05/2024, 15:00, 10/05/2024, 23:00\n", + "Ellie Evening Shift, 11/05/2024, 15:00, 11/05/2024, 23:00\n", + "Ellie Evening Shift, 12/05/2024, 15:00, 12/05/2024, 23:00\n", + "Ellie Evening Shift, 13/05/2024, 15:00, 13/05/2024, 23:00\n", + "Ellie Day Shift, 18/05/2024, 7:00, 18/05/2024, 15:00\n", + "Ellie Day Shift, 19/05/2024, 7:00, 19/05/2024, 15:00\n", + "Ellie Day Shift, 20/05/2024, 7:00, 20/05/2024, 15:00\n", + "Ellie Day Shift, 21/05/2024, 7:00, 21/05/2024, 15:00\n", + "Ellie Day Shift, 26/05/2024, 7:00, 26/05/2024, 15:00\n", + "Ellie Day Shift, 27/05/2024, 7:00, 27/05/2024, 15:00\n", + "Ellie Day Shift, 28/05/2024, 7:00, 28/05/2024, 15:00\n", + "Ellie Day Shift, 29/05/2024, 7:00, 29/05/2024, 15:00\n", + "Ellie Evening Shift, 03/06/2024, 15:00, 03/06/2024, 23:00\n", + "Ellie Evening Shift, 04/06/2024, 15:00, 04/06/2024, 23:00\n", + "Ellie Evening Shift, 05/06/2024, 15:00, 05/06/2024, 23:00\n", + "Ellie Evening Shift, 06/06/2024, 15:00, 06/06/2024, 23:00\n", + "Ellie Night Shift, 11/06/2024, 23:00, 12/06/2024, 7:00\n", + "Ellie Night Shift, 12/06/2024, 23:00, 13/06/2024, 7:00\n", + "Ellie Night Shift, 13/06/2024, 23:00, 14/06/2024, 7:00\n", + "Ellie Night Shift, 14/06/2024, 23:00, 15/06/2024, 7:00\n", + "Ellie Evening Shift, 19/06/2024, 15:00, 19/06/2024, 23:00\n", + "Ellie Evening Shift, 20/06/2024, 15:00, 20/06/2024, 23:00\n", + "Ellie Evening Shift, 21/06/2024, 15:00, 21/06/2024, 23:00\n", + "Ellie Evening Shift, 22/06/2024, 15:00, 22/06/2024, 23:00\n", + "Ellie Day Shift, 27/06/2024, 7:00, 27/06/2024, 15:00\n", + "Ellie Day Shift, 28/06/2024, 7:00, 28/06/2024, 15:00\n", + "Ellie Day Shift, 29/06/2024, 7:00, 29/06/2024, 15:00\n", + "Ellie Day Shift, 30/06/2024, 7:00, 30/06/2024, 15:00\n", + "Ellie Day Shift, 05/07/2024, 7:00, 05/07/2024, 15:00\n", + "Ellie Day Shift, 06/07/2024, 7:00, 06/07/2024, 15:00\n", + "Ellie Day Shift, 07/07/2024, 7:00, 07/07/2024, 15:00\n", + "Ellie Day Shift, 08/07/2024, 7:00, 08/07/2024, 15:00\n", + "Ellie Evening Shift, 13/07/2024, 15:00, 13/07/2024, 23:00\n", + "Ellie Evening Shift, 14/07/2024, 15:00, 14/07/2024, 23:00\n", + "Ellie Evening Shift, 15/07/2024, 15:00, 15/07/2024, 23:00\n", + "Ellie Evening Shift, 16/07/2024, 15:00, 16/07/2024, 23:00\n", + "Ellie Night Shift, 21/07/2024, 23:00, 22/07/2024, 7:00\n", + "Ellie Night Shift, 22/07/2024, 23:00, 23/07/2024, 7:00\n", + "Ellie Night Shift, 23/07/2024, 23:00, 24/07/2024, 7:00\n", + "Ellie Night Shift, 24/07/2024, 23:00, 25/07/2024, 7:00\n", + "Ellie Evening Shift, 29/07/2024, 15:00, 29/07/2024, 23:00\n", + "Ellie Evening Shift, 30/07/2024, 15:00, 30/07/2024, 23:00\n", + "Ellie Evening Shift, 31/07/2024, 15:00, 31/07/2024, 23:00\n", + "Ellie Evening Shift, 01/08/2024, 15:00, 01/08/2024, 23:00\n", + "Ellie Day Shift, 06/08/2024, 7:00, 06/08/2024, 15:00\n", + "Ellie Day Shift, 07/08/2024, 7:00, 07/08/2024, 15:00\n", + "Ellie Day Shift, 08/08/2024, 7:00, 08/08/2024, 15:00\n", + "Ellie Day Shift, 09/08/2024, 7:00, 09/08/2024, 15:00\n", + "Ellie Day Shift, 14/08/2024, 7:00, 14/08/2024, 15:00\n", + "Ellie Day Shift, 15/08/2024, 7:00, 15/08/2024, 15:00\n", + "Ellie Day Shift, 16/08/2024, 7:00, 16/08/2024, 15:00\n", + "Ellie Day Shift, 17/08/2024, 7:00, 17/08/2024, 15:00\n", + "Ellie Evening Shift, 22/08/2024, 15:00, 22/08/2024, 23:00\n", + "Ellie Evening Shift, 23/08/2024, 15:00, 23/08/2024, 23:00\n", + "Ellie Evening Shift, 24/08/2024, 15:00, 24/08/2024, 23:00\n", + "Ellie Evening Shift, 25/08/2024, 15:00, 25/08/2024, 23:00\n", + "Ellie Night Shift, 30/08/2024, 23:00, 31/08/2024, 7:00\n", + "Ellie Night Shift, 31/08/2024, 23:00, 01/09/2024, 7:00\n", + "Ellie Night Shift, 01/09/2024, 23:00, 02/09/2024, 7:00\n", + "Ellie Night Shift, 02/09/2024, 23:00, 03/09/2024, 7:00\n", + "Ellie Evening Shift, 07/09/2024, 15:00, 07/09/2024, 23:00\n", + "Ellie Evening Shift, 08/09/2024, 15:00, 08/09/2024, 23:00\n", + "Ellie Evening Shift, 09/09/2024, 15:00, 09/09/2024, 23:00\n", + "Ellie Evening Shift, 10/09/2024, 15:00, 10/09/2024, 23:00\n", + "Ellie Day Shift, 15/09/2024, 7:00, 15/09/2024, 15:00\n", + "Ellie Day Shift, 16/09/2024, 7:00, 16/09/2024, 15:00\n", + "Ellie Day Shift, 17/09/2024, 7:00, 17/09/2024, 15:00\n", + "Ellie Day Shift, 18/09/2024, 7:00, 18/09/2024, 15:00\n", + "Ellie Day Shift, 23/09/2024, 7:00, 23/09/2024, 15:00\n", + "Ellie Day Shift, 24/09/2024, 7:00, 24/09/2024, 15:00\n", + "Ellie Day Shift, 25/09/2024, 7:00, 25/09/2024, 15:00\n", + "Ellie Day Shift, 26/09/2024, 7:00, 26/09/2024, 15:00\n", + "Ellie Evening Shift, 01/10/2024, 15:00, 01/10/2024, 23:00\n", + "Ellie Evening Shift, 02/10/2024, 15:00, 02/10/2024, 23:00\n", + "Ellie Evening Shift, 03/10/2024, 15:00, 03/10/2024, 23:00\n", + "Ellie Evening Shift, 04/10/2024, 15:00, 04/10/2024, 23:00\n", + "Ellie Night Shift, 09/10/2024, 23:00, 10/10/2024, 7:00\n", + "Ellie Night Shift, 10/10/2024, 23:00, 11/10/2024, 7:00\n", + "Ellie Night Shift, 11/10/2024, 23:00, 12/10/2024, 7:00\n", + "Ellie Night Shift, 12/10/2024, 23:00, 13/10/2024, 7:00\n", + "Ellie Evening Shift, 17/10/2024, 15:00, 17/10/2024, 23:00\n", + "Ellie Evening Shift, 18/10/2024, 15:00, 18/10/2024, 23:00\n", + "Ellie Evening Shift, 19/10/2024, 15:00, 19/10/2024, 23:00\n", + "Ellie Evening Shift, 20/10/2024, 15:00, 20/10/2024, 23:00\n", + "Ellie Day Shift, 25/10/2024, 7:00, 25/10/2024, 15:00\n", + "Ellie Day Shift, 26/10/2024, 7:00, 26/10/2024, 15:00\n", + "Ellie Day Shift, 27/10/2024, 7:00, 27/10/2024, 15:00\n", + "Ellie Day Shift, 28/10/2024, 7:00, 28/10/2024, 15:00\n", + "Ellie Day Shift, 02/11/2024, 7:00, 02/11/2024, 15:00\n", + "Ellie Day Shift, 03/11/2024, 7:00, 03/11/2024, 15:00\n", + "Ellie Day Shift, 04/11/2024, 7:00, 04/11/2024, 15:00\n", + "Ellie Day Shift, 05/11/2024, 7:00, 05/11/2024, 15:00\n", + "Ellie Evening Shift, 10/11/2024, 15:00, 10/11/2024, 23:00\n", + "Ellie Evening Shift, 11/11/2024, 15:00, 11/11/2024, 23:00\n", + "Ellie Evening Shift, 12/11/2024, 15:00, 12/11/2024, 23:00\n", + "Ellie Evening Shift, 13/11/2024, 15:00, 13/11/2024, 23:00\n", + "Ellie Night Shift, 18/11/2024, 23:00, 19/11/2024, 7:00\n", + "Ellie Night Shift, 19/11/2024, 23:00, 20/11/2024, 7:00\n", + "Ellie Night Shift, 20/11/2024, 23:00, 21/11/2024, 7:00\n", + "Ellie Night Shift, 21/11/2024, 23:00, 22/11/2024, 7:00\n", + "Ellie Evening Shift, 26/11/2024, 15:00, 26/11/2024, 23:00\n", + "Ellie Evening Shift, 27/11/2024, 15:00, 27/11/2024, 23:00\n", + "Ellie Evening Shift, 28/11/2024, 15:00, 28/11/2024, 23:00\n", + "Ellie Evening Shift, 29/11/2024, 15:00, 29/11/2024, 23:00\n", + "Ellie Day Shift, 04/12/2024, 7:00, 04/12/2024, 15:00\n", + "Ellie Day Shift, 05/12/2024, 7:00, 05/12/2024, 15:00\n", + "Ellie Day Shift, 06/12/2024, 7:00, 06/12/2024, 15:00\n", + "Ellie Day Shift, 07/12/2024, 7:00, 07/12/2024, 15:00\n", + "Ellie Day Shift, 12/12/2024, 7:00, 12/12/2024, 15:00\n", + "Ellie Day Shift, 13/12/2024, 7:00, 13/12/2024, 15:00\n", + "Ellie Day Shift, 14/12/2024, 7:00, 14/12/2024, 15:00\n", + "Ellie Day Shift, 15/12/2024, 7:00, 15/12/2024, 15:00\n", + "Ellie Evening Shift, 20/12/2024, 15:00, 20/12/2024, 23:00\n", + "Ellie Evening Shift, 21/12/2024, 15:00, 21/12/2024, 23:00\n", + "Ellie Evening Shift, 22/12/2024, 15:00, 22/12/2024, 23:00\n", + "Ellie Evening Shift, 23/12/2024, 15:00, 23/12/2024, 23:00\n", + "Ellie Night Shift, 28/12/2024, 23:00, 29/12/2024, 7:00\n", + "Ellie Night Shift, 29/12/2024, 23:00, 30/12/2024, 7:00\n", + "Ellie Night Shift, 30/12/2024, 23:00, 31/12/2024, 7:00\n", + "Ellie Night Shift, 31/12/2024, 23:00, 31/12/2024, 7:00\n", + "\n" + ] + } + ], + "source": [ + "pid = 0\n", + "count = 0\n", + "word = 'Subject,Start Date,Start Time,End Date,End Time\\n'\n", + "for id, date in enumerate(dates):\n", + " try:\n", + " if pid == 4:\n", + " ndate = dates[id+1]\n", + " else:\n", + " ndate = date\n", + " except:\n", + " ndate = date\n", + " if count < 4:\n", + " word += f'Ellie {pattern[pid]} Shift, {date}, {starts[pid]}, {ndate}, {ends[pid]}\\n'\n", + " else:\n", + " pass\n", + " if count == 7:\n", + " count = 0\n", + " pid += 1\n", + " else:\n", + " count += 1\n", + " if pid == 5:\n", + " pid = 0\n", + "\n", + "print(word)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ddcf553-1b1e-4129-895b-453d057e81d5", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 + Jaspy", + "language": "python", + "name": "jaspy" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/builder/showcase/scripts/ice_thickness.png b/builder/showcase/scripts/ice_thickness.png new file mode 100644 index 0000000000000000000000000000000000000000..cceab3456d4059ddf4a6335175f823068235a6ed GIT binary patch literal 59666 zcmeFZg;!N=`!%{Y-Q8?j>F(~5knZj->F!V|1rd>ul9KLD0hR7frBk}k+RyX8=Qqyz zzH!b!@G;1}*I4VWtLB^+uhm~FV4{(s0RVvcLQz%|0N}y^0J4UH1ir#IzVsXXA><{e z@1^Bt>*Z_l$_7xi@N#!{^Ky2ur1r6S<>}z&%EKkR+ zb~M({(UtLNYm~w`>VAYU%Wsiv3h8S z!j2L^S1218C=!EBg*6h$@%Uba-oijPDak5>K5u+SLm!t5hXyhSpOKNFuBSJ<`U`f_ z5^2cD$+=$r9yAs5;r`T@tk2c5c6qH|Ute!;Z%>V@|0NkXfINTx9GD8-nwXdfF~tN= zDp#_Dlaq{ziOI?GIJtgWG<#DM9G&^)m!H2Py7Gq?EewcIyWpY`%&|`U6p8?=m zkCVycP>QisiTsgh3^=}r{AFa1BXL*9NBQUE_fbdEhQW+L!`vOoUJQlzRTym;A{MG7 z%t#nHdHcUyP)~mg&tyZRP=et9V=WlmjBtuDt3iyJ=_RQ0IZun*RIX}inz3XJ)8TeKl zT%=}KUpF=6--jXbh2tPcI>M#|zKKLi0QvVK895;EJsdq6#sA;k_u%NUkp4R{KWwe8 zR7%#M9iIPX6yQ9OBN3=!%R@ji1snJOI&&mB;C1AGJOvs?DdgGz+?n^B6OJ)yK{F15 zHvP|{AV~esiXk0aprv1})%R6H{yUO@B?Rf)%C%eq&j0s@oHwDTYjz=G|M$v&*6@Eb zmclS_EdO0-K`XHi3apEZ3-kCtOGNC(>Ap`2l>X1`R_%EMc-gZAW&g8zvPphd%f9O^ zt|xvMd(+o_4C3LVA(yqw9bfC}2=-^n(J6V}2wyV&bA(Xxy3EPoHx<~6vGn3~baZS) zAAhKYM0jlWub)q6?ES{@urx z7U9$n9}pWwj+!>VRQm7a#=1Y=Y+GHQtS=w&_#PP>dweHM=dwb2De>SX`fxs3Tw2;w z8TzoF-yF07VE93 zXM4!x*}lKh*!*t(d_27X2T?WSM1o{HlKC2woF971haWo-Mih43 zamOC=uy3{*h5vGJF67~2b`!jmB|GTvi?+wxeb6!W6iGbnuKCY;SDSakfj**fB>=ti zZu$5G9KhP$>QhLSnv4uQ5vzU}&!{Lqi|)6s#?A+qAn=|8t51(t;;rH^1KYt&)WtM+ zaB%29G~Zo~r3xXLo}SjPGViu1pY=BRW>}Bb8-ppb;Y5#>1YrS0goWL~VQ)%2ok?hD zXy7`#fjc9EEf$sYbiXaQ|E<=2<2A#^dMs7Hkz0Fo<7x;waI*21V-OUs#cBO z-<*xl%n*5zvKiDo+nzhy9>q@l$6N=P9%hq^V4D)ioi)vN;wZmsKx=kV|_ zrz-xRKYvIUog5vAWbGBnH(xJ3p8R)aj{1+=ZKHpiQ+VJAtj^t>2;t`#?W zI1E3`E+?2@x7;wAkVO}vG3BK&D!6X`?yH;_tfp;(e#2mpuA2>Ng$U>)&3oFnj8glzA<<5=oBQC2iL=4Wy-} zn(s}OkS=bV3dUfN;yHKz{mJ6diz)D>rUnm;iq|uZ9nsC6+m<7lLVz{}Y%fj=If7Ar zSNs_=K7aQ3#nxyJ9uFz>JBi0li4AZGdwo0aOo9%b%z9ZW+aegU{oqC=o`P0Q|Ml3i zRIp{sbqC#Pq-UZsdou#KH{b~w;0V3>wdSund9vg=y1rLd*}v56iJLTV`iCQwv~k(T zsA?2+Jty~Pqno$;l>=f|OOfyB6gC7pZ!ot;b5^N7%EC5QA>q*;jwX>U{h-1oR*(^N zjf^ZTGEPn`g^{q}4nIM>O8O{dD!5C~cR`nQ>LrXdV%Ct_v5J;%#rMnL%t7WbIU!6!qMO7jUXD~7|bJ$-_vI?-uS^34B<)m)O}SK$3jumi7jfiNv` zypo1s0B|zX3T00qS-V!H7Hh_h#w-j2hmXYA!w5&F7w$n(lBlaF7Gdx3{9CZ9dBx=F zFFGV{F^X+@rnQLJXW~)>j3s)MVtKR8pY@>2(KrfG(>3UAg{X$hym5JGoU<`A_1HdV z@|*(^ym?iZ&iQrV&L|*&aZ|7#cYhV*s5PN1;x6DKF0y0BKNPp`R>0!W4Xa^(e^sOf z9onTI*l=-$*Ai`D;vS|%qZ7hk#$pp+s)Z3B2H_3Wvx3&bj zN#VD}nz-HoM8aTv+|XCxS*r+!zZ4k-5;1*$DK%mKqKTRDB}XLqoYuWugZFCA1Lu$p z(3_?Pmusz70u^v?2%S?P9t%yEQMkM&@j2_yufmgbHqJQJ-=BjIUey(p*~?WG#hl4@ zF)w+^DFPvV9mw&DhVD7eDb1MhRnN-2yY`GU^o}#(>RO(FAKcGAuK0E*o~3IX$)>TG zsR&f$3D$_X58cHS$SxDc1;U2or?HFXop-F6E>7mh&SB(Ka9a!JJ&+i+Fav&qqqGm4 zrTY*jYW_CNm1gXt1%cZ;JY-S%!>0UKQ1PSGwGi%i;66ePA22v)HC3tQ3FL=Ky1c&} zFJss~2P&i-h0oJmlH<#^!5zhdfN7XVyao6yfbctfDlkr;18J-yGKaFxW4Zdmmc#j2 zmqfJ;H!BG3cT)=Wo3bzU{8CPM37kmCayXSP@oedF76fEiwA`DD1e+c^Bz0@xc1V(5qZIa~?GzB2T zQE`1qO1vqI(5C)?AUZVie}5APp@H0<$_chQtQlEppkl&J`y;ZVlqViT_EDE+OaFv#5Vwm?-g}Ls!OAPe%piuB;WZI7w4r!Emj#%6S*3bd1X5e48s9UWyDtx zpFPtRE3Bp{u&F*+fzxPpX*m(Q1EzoMI~zql<9X+}7^}~VX1AEpR%zt}XJ}OW_hwSn zo^27bE=`~#Nv0vm(`Af4rc&RT0_T|pFAx3RlwzTab$ppAyDrTa*4O<-Eu9*PI>eey z)9|&TvE1sC1%5Y6DGjZMzMD7%FdrC|+D3mu1UP-%fMdt-i~h~9ln8NutiH!AX2U+g zbgS<9YEo9b=qWGiaU>>VP8LX-rezE&vf(0ooHc{~Hw0EZtrGcun&I?4VZ@W!PsDT= ze|y(n>o!rfA?<91so|fE1S=fszuVxJeY@eGbEeQ!xNsR>9*AxZwK*kOQ#h{4^L{xg z41{q``)obyK6tito$OVM3=|cRiOyrC+3WO}3WgB?vuBB~@js`Pc!>iVnv=EY^eB02 zFfRz7JY%C=y}d%tBfyR2dGvhD@Uz88E5VRb*ztV)&W=Z^4~H&N3HjJwQP*-O`8O*n z{R_q~o)YI41L5xAJNDO6SFX%q(|eoC`RVkxjKy3c1K62r&y^!FA%e; z1L5Q6i6a?w5N1O|3rOLUD+s4zsVXm5YjK0_p5o=|a{)-his^`s^9V^{7&H_ioji< z5;$JKmYhawG14uq=P!>GfAwY|$wQK-TZ>}s(k;?RGylNMc=67-6sX)3m|lS^cQqU# zlYcysSl2E&vewYdYGi-M=uBcK)&a&b*p$sh^|^4}hO%M@(_eSsV?pgtW%icWa zwkh2HFoQPp-z63rfsUe}hj^54gq3;w{yO_#-OLbOpRe({MYo^3btPhs#bCwOvBlY= zQX7AGOem(u^JSx8`gF@AUBMBqKmkrZBGlGE1@j z0-A|=jO=uD-RtsT`SL(uaEGo4fnxI2sE^`sl&%0~H99fnxJP-K3G(v5@sRvC0$_~@ z`+KsQDOR;diE!uxM$?L@ncZD%at0O{v=!-)!0+Bz18A~&M!IFr{-8s(#V{OjB}}-; zdvl}N2_!qZp~~i%NlW4&;KqQZG6rYGLMKrXn?L@RLk{xVYY8TEU93^gTbF=K|2olY z4ge4jU`|hgGbVml;%R|J8u5EEG_u`WO!gaw$|O$fbpU9xvWwzXHI9Gi2AWFgCNZg} zQG@N-mU6AS^1de<$If)%k6{o}Oz{qGD7mvh9-=1Occ}F=zFRZU77fMnJ757iPqr9k zv5)UEH1RI+&$SA~o-bzihq{5DxZA-HdHX?bt^OzR=yE5z;X}NPaK&UD*3sVgJ(6QF zs!SOt2ecNi*2pBW7g?3B2)@mTCAXmd@D?Pb!(}Ru0&)$PXWz&f4|EHGg{OG0#}L1LgO))Kr-ax!np=CNMa|)ux226THJyrnJglB>j)7^yGRAN;c zu13gP3&~Gc%p}`8x04i#;%CZLxC6P2MA0+N#J59d<^paQw6Dssm+|zMuXl~gt*|u@ z*-H6c=R8Pf9j6ktnAH1ehAgXGsEUP}fi6Me9DjB1G1n&)*U1=}8c7SVGF=ep62z{^ z;VYN<`#rX+Agtc*Gq;7fb`z3QXzgDE*76wMH(djxkXk(Vj2T2+@gLsP@hSEimH1e7 ziOb#Fw9Q!gj;S@_xNsA3rB^1u%B>FWHf9n53nsi2Z3op6% zK_NHkGgf;r@%0a4i=7|D5MW7S32D4Vz-qOE;aK)}>WyR@Tr!@f0QE&NH|dNQVR^(G zQ?81V9nwvyI-CmiaRycRS}mMvZbAqAihwNJ2y7~38bnzI^vqI^xNN8f)6R_Tv+P!? zg_0c2yFFakukNe_s$!_uYdTFj`P6%MlFo)mq%2w&E(UzABR};%P^ZGt8s_aSwH4cg zqr(;2f8(WH=L22p*BQItdgEGk$rt{a%e_-eS1^1zfvb%Y4~5pN+v(DI-{-Gfob%a>igjw|#m&Mk1l8Vm95X@5N z6^`MtnJ51FB+2q5(K%9ik!xg*MT)0Ch9j%iem{s@bpoqg;Bh2u0yzyocE-MW|B590 zHKroh4lVm+l873n&rr?|??xMw!rgPdi*enDUP`8)N?yOdaFZtZ(EFl5UG(f* z+c7DZphad`Trjq&+JCABl?&gaAGo37^3#lAPMq?Iv8|!R1y+#;s3`f2oH%LmWn?^E zXE{8e8I0n|YvD@HYEX2`5i%)e6 zz1W>4;Zht{6!30pDBb7DGp|U<(f*T)lmY*_miM^hNiLBB42{=KQ*LC?6Lg~EKT&i1XLtIz!pfuP_R6weyC1tGq8huvt zB3Ku0sGjBxvvyG>rB2@HXP%(~bzJ6kNk=3cHdK18IDOIrD;ZvaVpQ4yf{D0dCL&#i z^LJWn{H(}t8LRWvBm@q_eN%DCS7Jc-dpUvx?t5{fjTl;aFvIT#?==&)G5Q>|XA5iE z@d#8rn72omd+k+tIK!CkKCa;pN3~!w5iuh1I46<_3BGLxOGp%_hr8Xc9~yIzYVni~ zJSc`#ybu8c)|Az%WD=EW|1}3HW&98VhUGB8WmUHeQ2#?`I zFQjFa*K~iYDd0zbr1S;?1@fw32rhx3RmfNQ@2{81yMLBNA|X(Vsp$r64Qldy;N+zZ zJE09W2A7bToJ4G|(5V?uIDpq4`VL%~I7vtPbW+6Ha>+S^z=o25-mRpr@c1bQx9WYn z*<3#rinNtef~}=TZ~M)!Qu|BjVD9R=tbL-P1(Yej7UNj{-tP3iytV7?FP&MhLlT=$ z@YEsmY!VnY@huajcE3uO~SV2p3*3yz9iRIliPb}@UuD~o&0A{h|Z*XNL)wXZm z1FU|qFfA2P8`z5HQ&HHWCWgz%C$@Y*lUXN_)tEGu-@U^XT97V5PLlDp4|7wp4eA;c zN9Ip&yfZn9IpPvPx1E`l5bV?LV~2+W=NamQdCpWMExUnJ9theqw&5N7NyP(r+K`== zQFn0D3G4SBUNl4wC{OFR{oOmSkHLi-*T)#e`us-rkG}n3D|McY`%f`!3Bc8%9xui8 zTy5CuWl4*~ERu44Ain;2UD%`-p;SU2SnxrN7x(XVQuO^wDTekU;t9$wgkYIATp3x! ziA5%I0=0ryK3P{pthhx42?FoRt3t=Q9Y@I8aN!5qxGhNb8oYL?CQoD>;aQ9210zv^ zqQH9;2=41ZlOA@z8Vaz;(a_HJr2w;$gUB)+jMn=ydpG;2;Gad^-=a!6GW{umuK6as zpd}_n?*onb1#fP3mp`}a>;WWdn3q{0TfbLA+HqD(`R0G=ukFTPX*gfEbK z4CPcYy;X+8;`^op|19i1OsGuT_ckfz2YP=R+SBymbP<`lDGZzGK-c71>t~MGWep)1 zU#S;Lhf0HpR58d7#YuG~+F*`t7u(`)&9@e?nXCK}*;e~{f{-&sm)x>D3?VXAHJZSW zNfWMe*Ab)HHrFlM9wtU-wYf!i3gx-J79t5)f6mDM=1)N;-F6V+9o4lRAN{aSR@2bS z5=HvWwUR_H)q;J=v{~Bux#07Og;fkEvy|DxvK0l3KJAuSWh&)i?Qw}=_4@E^K`-Ul zk_soYxc%&^OIrb+*>EH6+=;G?ioSxJnprxq;^bWKa$O<$R&4Zm=R4!t;2+Y(s-rsZFe>`$IVL%EbQH2xl|ie9LAi(2L6d;=200Nj5z!V)3V9~?_+p(?HS61G`~&m za_e1@8-;c1CdwuWY?tn!`R3!6ar&QH2z4Z9m}{N$eV|}9P4!6r0!Ox62Gk9pK^rZE z)J31gd4=zX?MF0Yo#TsRffXqCL@bbOd`^Acq@|57eIk6ZAMt##eG7+Y8Ta5d!*%`? z333YDLZ8;{x#2^_X5Q#>&{(h)u?e}#nR&TL_dzP2qr%|C*+@if8LsO*N_`q`%Gkx! zD0MSdna#(5$|!VuBrt+%@k3PvnJ4UuQZEt<L>nQ@}ONK@~ zLz}k6^G(lpNn7z0$#DZ`xQ41}5){X{zU4*2srY4e``gZ7$^I>TgZ)v9sQrD&nkv?~ z+LLIqBdpY;)y&I~E&zBbM8`{=O}@PZ3sP6_0LnKjisBV4ozh~Zwvbk=Ca}~$d}sN^ zsgrDYd%=2@Ukc2cAD+4v-e*U(pux(#hZ_6}0`yTGLNb?whbGc3ye zfGfOB7!70d(If_>2H}ZK{b(oy54enjPQUAS1POh8nH3-la$DFSktiE((S9n3H@Xai z5|aJ4TuJij!K_qCU(xa`*O2LN-?5F(rZ7 zW3WBG+Wu%`7>VpoOX9-9!WzHV&Y0^}`*wDq`-=be`q$5{Jq0gPPV%W9P(Wg`C-`c4 zHkO5Q3Fc7YBIVwi&!{21C8Fc@X1De)|EL=uDU?>j5I&2EQEZFNQX;J7Eu;E)(srEw zAx!94^Q4+VsxLOo_aL0#5>9_tosT6T!O{)RNt`?|=5@e9+pOjOC!nOfr@2 z=(c~{b&T}+3D%&l9)y0SCVb~+8p8oxze_Bbj;ZT>!R0L9+ zM?`D*mCW7J28Q(fEL(585>@I9Fba@H<=PQ6WLj%zXoxpro(_(EQlJWsTJMduI+&|& zy8rvD+IxS-^~$8i8ucH3&jm)tynn8oI6^K7B>+KS4Qep;>T)qgG}VM?h+%2+Xe(*x z(amaOekmivAknkL{y9Zjt!eY}!2cJQ5h>9kRXY__0*?cd!-);TPheIaZbYHf1V}v? zu7wL65$w>>hlAL`@^PVt+W;-dNq{~^h8wHg~m({Qi1zYq4AR{AlUvMbOZEqJlegrAR;*yddbGlku zky~3^`FHX-%OKSa5T1{&i zzSOz2KJmTj?v{<)${@Bhgvvuxw$}wEAJPa3GhD6{Z`rUS?xY`GY1f%P`5s$58pky! zLQXwQl1V{@I3tqq^yo(7Jy{-yAwikuR5F6I@3a$`&KfS4ir|R}&3qsXP#Y_uKe~l0t+# zUP8uYi8R7PUTi_TeT}}xU-1*i8r&D4)JWIa7;O%<5-FL5&YpUCIS}WKxGxV_)W`W@ zVgrl|Ug;<8Mr*oBkp>!XwFA-LSZe6&qDJ9@f07>vTpkTX+^rwp6t_IO0_qz{Bz2rK zJUn(=52qR+wMheDfB5_Nl}b7%gq+`b@Gi*3h0W(^=~K1K_DEK7x!6gk+r|!z7-Pg~ zS@9z>oDH#e8HOPy0CHmgi(E3?sIsBlW+cTD`ObMJMINkb&ojs$ z^21kbkOat+JAE`J(g4ouF;(~}C@AKdJm_LD$Bkh zrh3t!PBlJ-4?0g-#AXUW2G)e@xN5bxOTMybS@w4w5P*M~YbOXh<69ItP=JdO+wKF$ zSt<`wUU6`Fm56J;9cL6U?Z8}{KhH|QK3mY9R!+oMho*y?UjU$I?1AXoA#^zEzwAA0 zF`g&av|rI$<#T9wzlJQ)Rb%tZeVA_+I(-$sLkSy+44E zUUa9T@s$nUE1fL{EhCd5Kn7U}?l1tb*dC+_> zEUWCHTj!JAK5iI^GB|x*1w~nHVux__Na7&*m?t?-pN#}&9qB3B`3vB~*)f0&2nsS7 zZ849D+ugN!P&Sz7yT7SbHrZ{3W50bH$e5l{% zuK*$H@WKViu(pQex}PdFf5Cak^QML?TFiJBjX}XtoLI|;&ta6|Dn7t-8R{$NSn;#A zj&@KS_V-mCeK<}uIt)jbwfCO<0>J?b zIee?aFsn!n6A*SLN&gz|WS9hlGoGEITH^G8VB2CV;ro5_3iy&wAe!yq7rD}$&7~om zu{&-(R7Q9%68(vw)B}OWi4>fKrKAiv36cVPtHG!=sixY+Yj~oqFTK$H-90k8+Sc=;xv$t;lMWrYT zA{n27K8SJ2dU9x+M=>|VHTmCYxKrd2oq{C)*OqGcFH|2E)F~ry>yzAwd;J$&W4ILQ z;2J$XI6^&~6_;V`8VHtBaWPqmfnb#RBzK%5bff{~JfZU5!DelQpa>xn3p8#n6c61F z6pV7MT@#Lt{sMKl5hvi3N+zzZ%1X2<0Rl9+3Ulw^3x9nw+?oTdq~3gDSk%dwtIkdM zROn;!^mUKdhZPJrW!|n&>fX$r6d=9a;qQr(2Yexu+%O+wP{E1B86VF(x-K#DV=`A; z<6;76+P-3sGWV~l@z8klC|*T)fCrMIFIzoTUfY|<)8z1%P=NsgDT|J0ENLt+Ex174 zj?3`lD|vl|#Nh`4dv@k`pS!*x_?5z2ZccOry+zqbkMWqPC6gQh`RzE>E%9()X%Jz6+~0XS~j z#L5i%`-72*Ny^)skGhMV#~o~8b)^Z{^uW!BS3kL?LjT5g<;jN z0_5c6iYqGmRRxw227a)zhaT3?ayreh%F^P-Q%O)JiT+h|GozHkKv}v>^V*abL_DCg z5k6#@(2$mBDZ0e%4%z*RE2c=}WO64KDy4OJj6QtAC7Mnk6`(JNWEJLGY~{bXSAeUb zp~Qm(W^RWfT)UTx-SW^?uIDpsH_#_#U1@e~x~bT_zU1|Bu< z92{U=HiO~gbhh)6P)+>inQ7>QH!mOG`ee?d*Gb!c3ruIl`l|<~{91iD^7Z@uPT}O? zI8v$u9dfCbKas#{}+%_8JQWr@E+i(l{5Ya4H{1ju6PXiAln&Stte7 z)AazT%6kLGBGJn^tLq^zHEER#=>j+M3RD4(Qck;YA`I<>x#bn-7D|8V%Y_}UCy%Gb7 zt07c{a^rLoFZJ+xJABB4I|(`A+2PVvK}8V&6G#CkD}l$bz4aUs>J|qJz`kOQ{3`1o zct97JLUXz-)Jfh$y8hL}#qc@JAlyYItsievMN*?B^m$&vC;mYdB*pW4DO`hWEsxkv zpX~mI2xS(DdzyD+c}Uf**F~T5`su|of-#F=>{NTIyWlcLK@NHrdBq2z#6*w!B-c`d zzHo2Vy`4@21dngM_1UX&5w?~b>-`;fDDJWIFy3z!Skv`Pa)U4^k zq~FT4agmnor%l_{+w*mbC66t{yRNHMaeqa^J!NwS-z=b3qV{>yw96-8^xz_>T}O*V z^5g}EEC`UWeAE#@nKp-G0*1A5Ux<)?n|1i_ zbya&q15uhyZeihbt0&NxYQ+59o6tEy=0;!rC8BP`5W{-b~+dwHE zsOePcKLb^Cv>3fz8{gkXx`1-yUNGh30tLB17budecAREDSg2>2+b;ZQD(&FFM6Z?& z${@vKI+H@&|7W4FY{3QS4#S8UXJzd=xeO8#s8vFnG(6k;yu5MuPdSXH|Xy0hH2OKb$-3S!u zYTnL%`y+*6Q`zhm@2KtUC9i(>ivxp#s}tlrL^0P|7p<=!My&dyu1`e8C|ZMe7$I zy?6gD`8&FvhC--PoE!h4;Vz%G0(>tKm%(BorA{SgQ8YZuC$H4;`BM$f<|qS`@WOcU zS3fnLpeUAIJ^rJz&}o236#gY3e$oXGgz=0B(pla0VoStV2K`|H!dj0z$TK~SU;TKl zSg4sU0m^kj)h*JUV@3>!FktDK1@moH_SXgF8w5SBF7j7V4SVFaf3opYRj%W0Lyw1IeEuLv+@CQyYqrMV(actv+kHm zw=v7I4mv{KYXcMWm&`Ivi1~~6Pk$eS%_Mi_LBP)U7^&XZ(ab@1f}&^TY)EzV_(MF4 z1&Mf)+t$HqPi@Qvt3?_cQt!Ji*3~W`G|-1&+>QA(F(13=HI3}k#7FTkk(@U4Lb;p$ zdF)+56V$1oOZnRn7IVgaWgPg_-+9QnNuSUh`hkkF!8CX7_|L&KU*kWq>0ocamUxbH z==ChV+RGCunaEyzor(I9g#TC+&|dyxrc6TQVETrSV%N%{dY4Kd2P>H1w_T{J@Oe(8C|lg*kKal_lw&kCDW_LSW5*zd<9Z6 zH4^z{>!@^DF;Wz|hA6?@eAwWN?P4z{#VJtP@u*lY>Fkif?Q=egf=s*+ zYcq>_E3MhY>B!Aih?19Vk$H8kYkz;_+xg4=_8R>076ct&?G1A^Hp&te-$EJN{*ld% z{3NEqKLh}ae(eRHIl;<~B)hNt?aeLgWS!ia080M=nnqU=_+)9KaKY-;18z*O|mq%>C?yKNTs{Kg1zM{dSI5Wd{~6-Pb@SzL{{ zuB4wmzHElStUhfDLZUN8%Ae|osu91%J08_SjP09z2Q&h~C$<^MSHf!|*>zo*tl z_}Bb^x)!S_g#O}O7JaMu)OJ4RSGf95eoOf@{a-2E!>2RwsfvH2@zD7^e((3lQEGgw z7R)x7-R>k(AD5G$E#BQdi;^{$k9FfW*x)PL7qW&=X%8WN19vOE0Or*3y;|DIjQWEp z!m<7R@~|WrH~~?CwfD;G-8yTu!3uc@b)aLBymaz=Wb8 z*HR;gfrC;&Z9|5q5+3)H$j0I{Eeq{pV(_NF%0?iv%KafrO<&taZ4;$1wAb68bTqp4 zmCRktcc-yosCZ}t%Ef2Jn#q1rjh{nWM#8V6+{U>@Ghn}Y`?lKm z*c9k`%h3_17PNs6gxT}Hk)<8aQQjv;JN`!(RK{aRce?bzJiU*er9Q>Z(7xZ|*k+KX z|C9K&m4B4s2qRy=4llciG|9?r=+5i5O#5t(Cafuybze%mN~Yff#BtJF(@3^~Sho1$ zx{8WOxE)nru-fTyQbUA=yr5;?YFD$8II>cIU#kVdnLXXk!n#T*_Gc>x5Q#xt3f3^Q zx4(bq>+t}9#rKYlp>WH|sl>fV-J8-(`L|U~mWhOMG{7gmSC2;>7w9-~&`&16wy6Zl zq-Zx8l1V?H9}^QhMf7R$!;%P}~HAI{h4X>d1fFN;9lb7!(V}A9n1dWCtrJlJaRsy^o&F zXit)Gnsf6xU3Ge@?|~@S_qwj2&?ACc%s*`xAWv_9C^G(d>&e*qcR*+qzb`EIEW6MH zofFa6)HD(7ui&t|!w$Xf4bfM9((=pUl)})yKXoxJeczn;_s7{WywZ7d1=&N4m#PVM zfWG0qjaLiYr^VWQ-}!fpy~B-OkKOHtH52*e@uh!YZN_rwhg8T<%@320`~CVr>NL6F+p|!I zB&Vg;BT;i3ltV9t;e6YK`a4nNsOtwqPW=1#c-ne;n_%lre~UMAMPo2ni*=FwYLd$z z&o;h*7}VM0K3;`B3HSwp7H$Ow@9Q4oj=*gjG%&((=etWjR;&gwS%#WPeBYb>VIzljCbxz| zly4zLDlP%YZjfGt%wN2{aU_m(0X2m*rg zfK5=KZZVYzPcm@ALfo^`P6$dlEDoI_jQF9qbxH8~Me8f=ZtqMmq@Yo-0uGkK!NA0i zrU9r8E}LNgg`Az;HpEQN(D0wWoW_;&&DPzopW&8kz*KX|Z!@83EdqUPY%Gl2wJCRY zL`40^pvZ@hA0usM87Y8%l9@`gBoL6Kyoko_tBwZ=)FzHM%y940_?fqq(m9D#hEPT? zhH+JBy1y5wJIuTP<}mxsde_W3Z&J5T;ND?nT~5>c>O1kL`4ao(L9@3Ea$Brx-?n@2 z5HX+M$j?JQ?OF{Wf%WT2W~+_O?ZaQWdQjvO;d=yMDqo_kRwpg5JaupVRBc&kg|UZb?Bc zOS%Ea4?fA5eOjTVjoh%W`6o)7uOp%^s*pHWpB8(+)YlUNSfvcY!or*Z=k_QxF!*CB zW{bWZ|vI{&p$m)3KiXn7a{=x<5M%35wpQ5{G6>X4bZve4qJ}73b~`4;evll_I&j ztC*-lM2d52J+scn?OKkWgU z(oQZBj3pzBveG!w(hZzoyoi&fMGi{9fm?mNY~*rV5mm_&u3vmelz8;JzijOMj>?c3 zHZ!Ape_$ukTT+z$2CT@uz9c$zpPFIOBL6yHvh9KuU*aiUA0g+;G0=zhu(<5 z*pKVs)v+=6!3}Icx6(8LYy->hV2lu)8TWA+bgnpAHziP09-T*&Uas+Bc0o)jLX|#* z;wjvSUSVAd2F0H|1YLO3aHYL_PedCG&wc1{|1oeDcWV1)`?LigK1cl1ek5b>v577( zce?OKr9j*gSG~L#T=k-PPAk3{)A=ZLIXI` zogh7ko-QX3i`v07vunCj6n@fZQs;CbXrN>Q0NY1p3=9n1TQ?I$umX-?uo>9D>UV!S zfZenT#uKprPtP3mT!LUX=PB5onqOLq)(L`2Nk0RVhe5^@*<|)~TjGfn#+u2;lR$uf zfEz4$4F%nifl6(CNd{2HE`hH`QJ~ zfDelKJD|m(cQxdTEk>utGZr>z;*w3Wj$3-LF}<8?!HApV=^p8Wi{@nHV76hP?VdnW z%)wO=dAfU>J<}-31yL6t3L9L%w|!P1*zLo%O>%@>8U9HFgp)0-rwzGhA?bv1%0JpP zf>)a5ZrqPE*}LkOz7j-`FkYuf2K)^uK6L=Q*}AtP<(?{o^En_6H7^B z!awoYS%NK^v7IY2=2OKQeqiy^n@8MRi3B-FZe#=!AhX;MSPTh3v>vx=yS2B(PTdBBD4>(x*eiZRiWYulk z)N#_VCO{d$CpHyt^>(K517Aj5>oA zov@G>O>Ei)0$Bm&m+oJB9;AnzVeSvcF=9*HbEdHw#ayk1N;H-0SLeCuy#On+*_RpU zfRqd*3f@5$o+gEBx|f*6cr-nU#ha%}7qv+F;o^#4u+H@Q(s9TR5 zuUycDNukZv8l%$sg-k|=syzA6%9;Ca8m;_pt{Bp;O?ep`ducbnF-rA$yBzGC>gz9D zHZ2vm!~@-6vdK>>oOl^>9%YlFeQQ}DSc8S{IbJWOSj_AT6&!f1Rg@Nn#$H%&;x&k$ zCJj&qVu1f3z~0qW-qX{wKYp2|q6rSxetB};u;|(g%R5y+^IP2f{d2uR+!@Da)UdV> zrhyuP@*t6kQ0Lg8|*+DVY_0Uj?a~n)@TLMvJhu~ zH42o!o%=M+f7jVw_xXrdjf+)6icB<#Fg|+jmASayaT$(G2>_WM{iLLeR3X>vk_yht zErg=aSpVCh3tL7xImDNur?PDqGe+S$zs9#<)^xf_^+Y1DtXT zyVLa;w*5AL)s6j58oRE;$W5+Rhc%Q80QLF)`;hrnD!?|oaD;+o_}ub* zmKEyGp~H6N8XK|^v2>M0jU>c<=PN~N8hBVAKj6C>?3**QS`M~wgUqV_$R*gbelTBK zG&;kjzUJ0`p}WFR(fJs#6#DcK+y;#hY;Y$}>n+YH$O}%);upN6({;5Sa2sP|Sz04u zO{K?NtU#Dyq%G6pUqby{c>}+D+ug<&wvO@{XLl!yDede>&W)$H*qlbB zS@GH9{>wP6vC~Jn2F3I5HuCxMY1F@*wl@qiB%89oyl>u4p>1C|;ZIvh^EfzQw9>!l zO6&Ma&CNKO)w^zWUHPMfl9KE#@f(uc1fH>>wTqBvADW5qMpxd>$<3CIy8qA`i%Ec| z;z4))zgRlUsH)no3m>|>OG-jeDd}!Rx{;P{knRqprMo4hL+MTd>5>NN?uPF^&-?vj z3}bNi+56sWtvTnlHcAc8kiZyRKQ!Q%1I#R9wum;)I&p3hO$7vD6}+N6{*w^m6@^gx zh=Z}+&qugVGmpI)SVLaOIWHi10}*I_TGOBxs-94bhmy~P^8_-Q)cvHu&Wbe#uE!KJ zcp4@PWYFjPo}D^P@vvcSeGGu9o@x=UYKfl9z+5Oh6s;R3^3zY_AWoX6_L2iU*pi{Lph+kv0kR)Jv=zyy2iMTis z(Udl+2u+%)aCAs3B7AgZ+_12h)4jUDDM{UZCol_n?6@KV>=MI_pi4ts8AW}5rN+mr zg=&X2v8n0lP8U7!U6EAmucH~G&rm&}!&k4#HxIVHwc*CN`3B!1t{ z#Zz%t4#;=}vavD{$d$<4KRK#v4%81L$Gr9Qxt!4H>7fhpxr9Dr{aZ=Tm)R?0M&AV=U{w#`qL$$d z6;dOTke(4XHJ6qTy~MHMU;(~`mAM7KY81Q~S*`H3d0dzwekVbct1~+Gz0kRDUS3|C zE}rNG*;4|tkgtO00tmc>QWmA57X-hf0e%5wj!Af}J;W4aaS#j1`zztxl@ygRJKL$k$oc~GW zm?&?4>{jl3?UhPpOR@aNqe+3KMQG(JG;BD%5I#6_{MA8GAe^IZnkYWooZ<&Ex%yGDLUZ(aWmkEjA!9H0iW+N;5kf5QQyF@p&|kxP~anoSpM*@t|w~h z?-nIqVu5c4pbm)0xa}n5<)M=hr!gW(joPG|`bI;J}v*3ItmXYr8 zFWZVR%$BR^)pg_aT#`a};``zu)oRQKo7(m>$8NNp-k#8*k1cju@KAVL@{IiogEQsd zuG>#FRt`=nFY8%@;^_Xpv@-U#$~U-9MklwX}6WOZw9u zJjIK>;zr{yb_lBheR=b(>D6^6^%^Cw{q%Y1>fdEZsAU?lu&=iti*d);A;SaE!rvXcwwtC= zp`vcd$F1_^q=Fol%!q%z+56=s$+FiQj#qM8AZYqm^@s|d!&xOjt_jBF?eorQr%H zyEK_P4%vr2Z+-jkn&@ZjU<%toYnBI&CODIQy2aS01Fod~V!h-+){M~(j7q_bL=eB{ zY=;Z>2K=)4iHV5~K&uO~1?Mv83K8*7KsBK7__V3i=YfxUmHRxeOCOBGqA6R1=3#8l zNWz>mA)vvC-;CtA^7|bJFYD}r zjZ)wW{W8D1{QftGQK(j^rooWh-o zdxeY9Y*bu{<0&@GscCN>XHDj9a3c=CHGW;nf=WXn{NXvTze41J=R+*r% z71~#^%BXL}jW24fSc3)(df*j7vI(d3nHG`0EzS#ige4>=Z>VP9sr`39l|uw>|HYq9 zsVc64#~j>g?tp7lWz>xbReyo=b9V@cxs^1feX!|CLDSIz%QYCpY5d$XVGIjcAJ91; zZ>-SUHv=MVLBA!w^nI_L$|*DFG=T1JV4N|qtTC}87lcr)etB2WoAx}(5VLchPR3rQ zcE;&*qxwEL-Y9G`J-D~#`N>4$*t@AV@{~3-H{6u!Zw-G^5YhSK_23Hk2S(Wn^LJla z*F;EhI$YN5v^`|}u(9FC+o4U_V{0%>FN|>usH6#B_*^JM)5YsS6Gi>BnEH} zYQUi=_aXWh%o}TlBjGg!W8l;fS5>MwJUajV0lrq{M^@GR{Xct-tr6LUP&qmn>B1L< z*i1|*iWe|UA!J$0IMJ>ML^x^o=}Q-D(hq%^6XxqIWIjDFL9F1q$)~o0C8hc`yKks; z$8CL_hz65@7rb7>3wC!!?|chpP4c^bXCFVQX`0H#O>SB>d* zO(j^G?5qPfBbQ*D!gs6ya9E5iEd4-rAh02`Y5bgbQpHss!1kHk#N$ofj2Xy;X(}2*{}T2cCm?Px^=1`m7cMxuz>mi$5jnhtYP7$Hh8%&**4(BYYT5xF1-FHV zkHsd)9l)f}!atIoP1XyzN{Lgk_=YP?L*I>n~9tMnc3-U!nCp~d#g5D%T~ z-5Y#}xU_z}V_ov%xhVk_$i%ORTj`GI|DyYbY7L}R-)q2g(aMwCxejKb*%Vv81Xe~J zHyCj#kv-*s?=DPMpgl*hf*k}HqZ_!l%?IrN4L;`jg%BbCk$sA?eLa<~xJ-~me#hVi z1q^6w791xhAYG5-(o%DAQYLOhT-uk0;{2hmOTi_PdM86GJ2H%o4xWYSt5*3{4{KU@P;>l=d=bsSi3cL&FAUu5^QPrhqi8fV?XDfJ zESh6)&~%zjobN(OMLyF9nYd{o>4yr~vgE@Nvx{Z+9R;#RKn?8f9t0o+;(3}0ER-_Z zz!?SA(AV=K-gbdgDLCwfC-U>-%5xNSFoQ=gw{yIC$*a~PhVBV+d)Tka;UNvD)JSh5 z1tFm5aPBEC*8L*n*H*^x0va>4dBz5X3Q6TO_-1O)By--@<|jyQfE3y^+?p64VTxVp z_t-IA!>!rhw=}G3wEa9-^dI5lL@O``!dC)L@&kb9k3^n>_XbCVIw5q3&{u?SbL5ep zoO$UWS9&sYI+s+G6Kf7#E|+eD)vCV}YW{|aPC@o%yb^&QCsKlEWibG10f0jVdYo_N zf~i|2xWRHb!~S6VL&FBZ=%K9aXvmD79piIg41LE0#)igj9WZaR8j4 z#~y?*A9BB|N`T=hu=_{+>fV(aOiQG*ecuA72FU`*ZaE|g6vAiNl@91%z1I6f-Fhdo z+r*?o{Fk9})AEWfni^aS5EONZYscwp=2FDp&eUGi({#8oa+RHncp|CaNSKTH56jcH zvkPVzou23IM&4J=f~^99JbbYbc*vqdH-^VAO?7oB0_z3}YqGfq!|`R!AyRDcm;k4m z;pXqe;yJvKbGOYkLrfFt0+VCg;{txU;4p_lJOCDn?<)EW>v-lDbO~dH01r;m~q5qSj;>%muGo?z$9O$h@qhulp z5qApVI56^GWT_Ky@h4e`izYrZ;fIdQ$&!$^XCVz3UQ<7l^uqr<@IVZ=Ggrh$+@3dz zfprdBy6^tDJ=^Ubpy#0EGJ#RlvFj7Vo$RNJA`U*!QK9<-@fY#z#4D_M4$zo(5nnDA zKPGT9u5N6TC$Uca4(<4R;x`t-)WLrxBK0-#=3FlG5jg?m*~>8-08NR}NT}z#X>6o8 z=w!jiWRlm>#WW*!pdfRwk?9Y_XFBU0W`wxo2v?qS>O9=Wv?70^4i}~b1hKN+&AXOAEVgSH?Re6Hj=vQI({%L)}q| zxb0a)(xvBnR)scX0K6IlN}TpBja9n~TFMdvz)y^sXU(E%%43H?3jLh`xG-eDiC6oN z&;6C?tP8L+T}}SJLlRuP<@dZ8zZ9Vj5BS=Ag^?)4`L#oLzu2WSjiA12wjG1l3=u?U zY%eAwJn>7el5)l{zBQDmXg=DZlB>B-3*iYGu!V{K znk&0DI&klQvcj|F+(0diem7x$9m0>3!lpKU0O@yfP&>K~r7;SZ18ai77e#EOPLRg~ zQDCX{RSl$+!R;+ch+XAK~xLF3^WWex!e&p-z}*qjZz?Bwzf?ZTP44r7axo#4AOT0BIoH0@t^CYmpz50$*;I#@;r4fsV7I)A5h&meAP-Zg+qxHj8Fm(k{kA zp0=o?n8Zn^8t^fH`-l~WBW(3K7trm)Vjh^Jb)t-8fWsf6Z@@O>VMfkSd83hv=QhNe7;i=eVdJe?%YFvpgSSoK#%X zMpX6h)Zkbax-GQ!DvC&lsgZ?QyX85eA%^h$4|DCn?2919lo+`2?+@`WTe2@b0dO!O zGHX6v@Q&CLFDq2M(@?fvPS-`}(i*nj!XLP0hcx@SRaG{d(iM;dy`zzp00u5YUMg`X5+@GVmnBvT9V6*t`3L7-cKb;23WR$)hFFSj1Q*xH+Kz=WM-a?%?|n&AKpl~-s=$kY zC3Iu>=L*Vm`7L-()Bn;xuQgvuzv@`0`(IpQd>Qt@ z65Z-I1RTcHxS6T5d8VGL@B1}M4F6Dvplu*OpvRbkL@4aq!R+av!w6-pHX8BX-AEP! z5Yz44MA<9S1o&Jh8@Sg~0?c5x&!EHK?F=VOjSAf_U>Z&asd7L4)B;3*_tRb?th2qY zjaYa?rbNK_+&!$vmZ;2!Pn#8OwnuW8#8_NfprSzYoJJmy(RJBGg&A+7Z1H@TlBv}7 zI~;tfa2bIrq&O*bdwow%p(_Jn^~{zNm9{p7FNq+wuM6U@o_%~;rEutw3uKeh51g(y z^nFb*$hi~a3Vd|K@8q>R=k(QnpGdWt-aeMtE)73ZympTl@fR>KTPg_hsG$H@4xtqj z{;_FTpEHs@BGUoZ3@Su{$n8JFLW{FR#84Y8F!G#0TRlaAQ(%=PRsf+Zfr~M59*{7* z^YZXfSO)%6pqc=Y#Wa$FpD@%Yr??myC{F(=YtK(B&*G}8ss@$uRMDuz>hicUbpe`F z0Dci901|PW`4GW8l_pR4;m80CVa!jngqIPlAHUg=p5(m;Ap<;IB89Ys5k@O*K3c7w zocg}ErVl&P!d;qeX9Un6#6a!uSDs0QneM<)2I`fI-R)AO#O`S#pZymnDsT?AtbLuO zQZQXGPT!Eq3O6TwwyGP97tC-I|M_&yQ$JZ$FXte9gOBzkoqcdS<~PV&P8&hFMBh3DO3 zjS+aic`}Ss)$?fOVbF}DXz1e|m?vR`%$@wSl5(^KZ&Jy;*q;c55#mYHr7j_RHxGXd zcIOPo8)Olj-V`GwRG@vgBnfn8{WKLFRBJ2m8D#(TI)iF`n>*5E7!|QYH524rc@~6U zo=TH9$Kt$$ikJ;n_;ygy z(^OPq4ZLs=bemVCV=0D1d;5K_wNF6(KTMpG+&BH#wbPY?SUn%}&a>@QFUJ$Vzz+V> z-@B`&<&qHGoCIvn86AC+pyE_v5ss9}Dxt{Bmz-}xhT$Q63F*_5$t`5?o13afrP?{d zfY*0_nIXJOJL*g*bc7#%NGWDTf3Ot=CJA{)1Q}c9jCTia_g0ti;~X*&ScpDw4}+P1 zRLIc3*k*sd+1^t1A5cGonwr|hR$4eL&FMjFxLhinWe;G6fJ6(Ju+Hhsh*1jBpET^- zW_)*v^@Nvl5rlBMac8sDoIlZo&$O;q^SHmmERm+>B%oW@yN4myh3qlB^>6lM(`pgp zbaMVl?%-#}Fp&HJwFQJl%Y9LAQY=BqtjxeFN-mz^d$;RxjE98n|DQF% z_U}8WIod&w2sB`P&>SH?0l^xuM0b;zXN-ppy^L1>I8!EmSr;Rk#x|{P2_6sPd;@vx`;!&<-Yzhc<`P%9u&_jS^*WAX|u1K_yuN~&l&OPhCoQ(rf{k(0xY4Z;Z z;k2UcGvZ_^UFqeRbOR`BBk?3NlSMy)3=~p`nN%*!h^V^e!j>gcJa+JGZ{x zWy}RDMB8KcHsz@Y4XQtWtc8yotW6xRLHgjrgqGOR77SN`w)Il|>vT9H*3Sw;8D^dGUp>NQg5SmW@@KxUd_T>n4VCb`uW}pa5NymQ{X5m= z>p@$s3h)nA6n{P5a0JvxFM(-pi{};5$rr4Z{pm}*5NQK%^PBCtdfN{%e?b2gx)+y^ zws&va6^sIPnmK?BReo`CaeMOQu`}~206m{{B2jj@=t1+`*#O24fdI(=Se^KLkWLOk z(bPr$;esV`s+6L-Et# zc&$xlV8SZ>@~J7SZ1CpJlJtV;mEkwgm)V1v|1fqkXiF-y>CU`F2B# zC=_}5pkZjU(nbM*=Wo6U$AHH{v;9t8*K@Zph0leF*q8@YP!Py*%Q+^!LdKjq+JWs+ z`?K%V>?|#5)TgV1dGJhG`myY$(9X{lPgqr8;8dcwNi5x9kNU}%W>=KMXHS>(P~}Wy z4Z0?Nn{<|;Mg3KPxYhFE{yMK_?y1{e%trU?K*ssnyYirB56SN%GF&Q%aUzt}YqsGS z_Oy*mwF~+-x_@o+!!LsM{*^If^KN|ZdD}z?QF0!1!)|t<{zRnr!^W6KIqe}1OR>k& zWfHUPhdl(NIK19rs@;0!1FK5eQ*1R}l^fT^UJXiK|3y5`#hP!C5SYQH@Ho=sjWd3i zPY-Q>JhYc~UKTfcdbrj4X`@|9@vN1=SzQ?1i~qsSQ$VQS7aSsn(Es9>9YyJnANO7!{pjOOd<2K_u&?J)8?Bj@1W^U% z2_yB+X#?bVV$IaP2({;mHgxX1vFxED6Aq>&-|4=a$y@@MV*qx$NaF*?g5mKpYL*Rx zE>XRvH{LhvfcI7JXqKJ=>)g2ftw~?XO^eXz4yfURhhU-_CzFfY*e}&0Y+)JqT?)X! zcH7zqSlBD$bO%8%7X$)@iH=_q(R_0x4m&v>@H|K1#ORCo&K{?>v{HfhaM5oys8v#G zO@~Yq)cvU7vtRzpVcs-(4QfCI#bh|tvqEIx%?5dFy6KP9NUFUI0>CKFO)TJ2+CZgGBRus^}NdRS=5+Z^e0LcE(^bOz3INrKOTZbC6L8}G zL{u~~xrC)3v}1E#rYENk$6G*%Z721n0Pty974IKlX0ttSjU@iuT4Ak(baesp?csw=g zbL0e)l|4X|A+ky5Fvo=zU&q3!CeR&mVUe-ByMO!44H;G&{{QC3{2hRBnF^^)t^Tpa&$Q0 z>4W?hlcE$N%rkZC^F_k*gXF}J`|S`3X`K}LXz79Ux77MlGT=lcJ=~i{2)7&0xlEgr z+R>l(yLxckDDx861iqVm&}|QzO8}5}6Pt99Ov>`uN~JY$ zBb?V@kw^mv(vsUs6v$=f|MbuaK2@L@|@Pz4E>um04H(g23Uj900bhT%qx+U>csWGk=ChExdEU^?{_~V zu$04Bk|rt~q9DmN_?vaSDH&WC8^7(Rq~+U&6=5>A9CYD)6#q)4=gvCZnA`!ThmcZn zt&i_{M$%)75o;>t>SJED`01!j!n}~anDSGK*Yp<1H&3ZvWclz4QXwvpKh|_5F7crQ z1X=jCIH)feU#5!V!C`O0x&Mm->jG-qSD>CBD9vGD{#m9?H9bB3{Aguy(Yt3~2s=jT zj#22kadZ<|YpCV~Xa!h&WGQy-g;4VxG{}6jlOIzBQVs`8%|y^(0q_wyf&~PIAkbG_ zUQVG_>u=w7YX-;+h`;*!`kwSv+EpEA5cVS2#}Vs}0&9)&z)J``jyfVyhg zmoq(jLMlXKHB*s^+ULy14+DBcviu)1G#jx}I4PM28V`qU_jldkhRTUbMX>z`AO6!v z)>$^UZzd``zwcKRKV9Vwod1pKuj1L5)WW_#6zOTPk0`ACiM8!o&-4dwSpi_eL9%eU zW*p~!r7zM@<$4^buLD^1GeH$gR`V`%v-~@;G)q05fNhpm@$|+j)$iF%;-=-u$glYw zO~=ujJtMm6f?Auk5qtZZ!$jSg2-3ld1SMuirB+Cpu;Q19X7VRi-R_53$@co!)8QMzio z!?2{iyu6OfD~Q2&Efrjx-hD zM=DOZ*B{Z{&QS>noG1Vw+_ne4l3A-Tpm8bj3D->5XV6n0yh8z@?L>_sW#1prbfw^d z4s>2Yr{aC`+=6G{6)6Kl_@&c#JGDizx!fyP zJ*wxZ84H`2DCh@vqvq+8&-=dV1A}98*8~=0feb~SiS6T}R8iYR5ELrUc}G*_X8VWd zQm4r8A=aA~C660hayMl*QvfOG*?Ir z1`o(6ihhmkv&se?Khq3hhr;8`aQ7G#4Exum%#JsP*Hr~^pyBI^)C9#XX)A08M`18c71cHEo+ya3V~_c zuV%s6L{V%W6m*|@%G-sy2rxd21^yv&V;^-|do*o;6VR18j*5kYY-vHT?aI2k%SD044AvgQ>nXPi!76N9#Ngn z!g;e1g_=M99r6_-r$#RfcY@EyHtbSy35fh5b5rFBCasV`g#inczGpJdD4fS2iJh2C zTJOiT&sE1$KmQ9*Z*3cY4R@CHGGko!HH@;tfkxt^1h3Hhg2Ji|&Y z-Bil<+!%a~g!#h7s>kWT`bv#yu71)f;1S0`1!TT|YCGBx5L~o{OV+^yY$Xo!xi{=| zLxW8-1~Bqlc#%>?FgrcWfxItul?E@i*HJ5uc%>kpUk}i+CT3qr{<@;Vbcwn`0c$uq z?7!6?1#{h^^T_W{#rxV)&Q891wwve#IHv}Hz0Et6hHnj}^ow@!7ZwfPUj?~rqOBWV zAD6)%ND+$<qo@mrhcea2+E7c)&%{+1>~GjK-NREx*!{OlG1Yw zNsBdYCgRzu!908$xXU?pNEAADE+qI zptoMVb*B5aS`8O=B4*VmdQIyoH8&ID;a313MX`o&Kfpv!JF?#nB9X|9 zv`%XxdrW^vptHhn7rX`jk>s9tj9|%wg?1Y`=gMPDmOhs#M2Y4*gP2)WcuuF>FTV_Z zw3sYLg z8*j(K{JSySa+#hsyBep87RBnI>r1>ZK^4}^;=+Mo@T-z}$ha49Q|kuybXmg?JYH1t z%5a+$E>9AW3kBdv2DBfRpeG1hlK!Lr+z}Xmd1DO)FEIF?Mqt+ zDt$9Q&krG`p5GJO=lo%h=PzLY{!?Z9cX00M+6s>&HUL-{UEddwSE0ujbPExYu7jvS zMHunw$tgoA3#ahMejY&LLtYsgt!@qfN>;K*I(}R23 z8`*;D6%Q$bdWOX7{C6}=BfSYJXnPM0h?aeUu(yWq(zrvYvE7%67@bu1IO7_&2hGJK zKm%A)u~l1R;n*}tLm7#*t_WTXK!#oNJf%1xHF(^>Y2mO0-hsV{l?d1-u%G9Da-@SM zODHhww*a}Bijx93Bw>`Cyf3Ni$HHb17re8`gbri#awG^dkmRL@T@qX(C{yFby}%Jf7*pkt;AVf@5X1Lc`a5_ zw%kNfW2d4}8v{J_45jU(~VKhjYL8+Q18iF5U=I?5}K zJ}Wxl)!qU#=RJC`YvOb7PI%buqCOp-{R1@_6!VHa4%_auZ~Pmg0>`{}Vr z?myqc=v&QIVxglCb@!hh8n&Qt3yh;$kOE)qb>9XW@Ho@_d1xGh?$zwK?f?JUj-#kUVHLv5vUDc16LZjnk8+zXlxy8rs7k{ zS$3s$!_0D5ZpqvON7rldxo!cixr55r+wV`i2`AS=4LL z;LFlXJ4b7w^*amk+Z%Yn!0^21{uumN75EV$?`N)o*OO=eBCx1Ej}lv-^s(XNwxCQG z2LJ`lDJw%y=eF&-i)-#lS z$E`b8hf3ksfYF=m_guA124=r04xJ!1a-NQ)tAip>MezosatY7x$rX@O-(f(Ppn=F> zr4FL)g>!;|3qLpUD#Xl+Eaj{C_A0gR`0!l}O1azYpaMpKyt5xV< z)YL!TS{lW6f*WuPhK3H zJ6v-y!|l}McD}?S`68ZX75(azKTGgMSLSOjA1YAr#vn=NJwJzSUAD3Q%lRQUO`UTCi; z&qrb*{gjgn?5ramvuYl#O;&$vAjvIGM>wuyRSJ0$$zd;1nU30r^g;8M_P*!oybIEi z!~uZI>Z_&v{0#>tgVUN2^s|v)zoHIj@SgjRP!1)t97F4?2%PLj_!g@Kc1s0UktB_h zflTf***#@-EDO3oWqaS&1XlI1w@wr?OUPH|3Mz$edY7A}Js7I-?}C+7MIZQ>IiPEN zfXsZw~+HaBI&lq!Ugm6^2HNYfcM zbv!j(L-H11Qms4!?=zCBWp7w8+VA9gE4f!M4DI9#%qFw|or0Do4jCYgKmV*WXnz58 z_s6QdCpvM6?^%4d#7kV1Bh~BURpWcC_AfZUo=E*=d4IOv34F?z?oPR413O=SRBNgD zORxLmV|(J0BTG>FJDUuhpT(~YM9eNiAj5}BqfUCgd95s3J{NU{f`As-@gZvdl|>1C zL*{)T{*Q$g5;^YiyRA=Z8PD3`NlUWck{??5cy%OU9-CMgM>&D$1pJ~sPkO8j!@)Yb zAxl`#6t$QCD)ZoPs#x)t7k^@QwT7|}`2{L8o218;6DZtom9g6kOzeyw@2pC={0{;V#~$sW$+`n z*+J&nPZAZjODe^x!?iNe%(`s`&m)P%I273w$MIIU?i!S!AVzmC5nQU5(Dd~PfxbtC zir5>h*8QSu>b(&qvH)059TVd|%=QGE9az1vGW3=l)JAExJgx z@w}fV=AVr2M0v^&;<8A)rk*iIARp?*!ImGDhShv}ILPfY#;3a)w40#NL%}21ECDl# zPVaUY5rE5s?xHoEuQ9a%^S+a{?(xONNPy^t+TqC7PsJ%$w2+;3;CNgQw7_(f+uZBJ z2eiIuiiIB$G0I*N+NqhctcQA|J zG3J0L_g|}Tc^>MIx2kydn3@l-D8-F*lPH^ClRD|u-9QT=eVXXs*GEGdeIl86A=NdGcMPqrRpzR%v3jgc0Vv4riurL*m3!l>cSsJLmN zrUuP~)05IKH1<-J;79m!|LFa4CI)MfO0Apf_=qKuscd=vc&rW)yWiakMLo%LP?Lly z{|GJwI;WJawJZLZ{nt+#G~NB|WM1Y$r4dm{A}hZLChq-K(X+o9`M=QJxWam6rA2jN z3h!{K91c-q1V+=uM%)V`;tV&yi- zq(=<|8^>NW+fAiK>a>l&FviRGjiS>a`rJ65`=uJ*qhTc|_DsLAhNI*HIZ7kj8{r<7 z=FO@e;2w|m5oyuYUb~s?N&H2v%Uzdme!h-kNb-UfakVGxcxXjimK?jtQjcn;Yg}cf z0hO^l_;rO`M7zU9%()zg1$9Tk537fVZwSq3!+Wr9Dv*`|8spR~Ki_vsJbNpyV|2rq zJDnC&k;>z}BhO(yTUbDzBCL;G(t-JhDuV0R6Gt^(tFSCqhS7ZW*P6}u!Ceek)I@#br&w*JTzFvXJAyv`3e*yR;YO2zf1Xc>E z8P`or^i$N;zc2<{%U8EFB%~A|WPG^2wHpoV0gSH8w{Or>pRphiul>7Kv>OM9WdnG^ zQ<_W_`0pdJ?1GzcspIV;&N4U!Xh90QkMdQQjFF^w8+%G8)-pcSNy;p{Uyd`XgPxqy zlGtz+NXK)e)Hpqhkt?P~BKbr>vC0|qH|BE~{ZE-2ilgtP2%I!X_yIuR8|xbmGg-hFqZX z3IKI60p7;QuPl*Awm|w-1FM%R9ixMq^&rL_@B#U)4@Vw^7SdI=MZVs(s|K68#tiAgqLHh0LMS1CNvE*^H_Th+}Fl?JL=AJwqdSUrjGrGT^GWo?F@b=y5!eSIiyEu7bs%X`dzJ zLe$nN2MfQg;<~~zV$AaT_na))OY6Xv{mW6E)tICLA!`r4C;PtB8f*lFL*_JfFAjYv zZcDW6O!!L8$4Y9XRCdrTGAL+I28;VOOxD1Z{N*IGaqP1BTUtjtVk|sx_l}Fm%x~!A z0$ka0WZ8E`z}p0-jQ{-4O_}f$V`H(k<%NX^Aamc^_#!VEI-$?o%2R|n>ma8zVH;V8BikCIMz#aJ3wkyuPFLAC>E=q;8)2U-d>)St{Gp2^&nx(BPKm}^*xqexme%tw|0UM! zind0U3Pm7V`+^;p^%WMROjM9N>fxHnXz;-Oq#%K*B(-9~gW`vv%hMM<_siV@Dex3Pq&L88M+oYGApxi^A3v7L(OnJ5)1GF#n4TU5WECJ^ zyM|cWBY||X26m(O1M2mZIoiu;AxZt7NVlUP@WJfn9b^PyahO$0{-&{cq%%Vd=SHr( zeK$rOn4~*jscy`Jki-{??(;nkV^9eDTURarAutb%m~LX=p|4dfov|8q<>CL;@wbkY z`RQ;w%)4w?v1M!n$MQAdbzYGIUsrz$d%J6?*(3-daOCx8Z{KU}~QkPpvr~F7yryqfO#|#R7lDIegz(=m-*HETxBoxq&W`2iWaiC}kGBGyuD%d6ZCw+~?zq2O|z}8Vv!d9#7xb$~}N#by%*k{aE zvv;_ZEiuaG@`tCqm;}|9sio4+;yA)0UvLd>Jbc5^?Y1Js?`2qi|BE3*3y#dGdvO z9p9wlee1%YLynL;=18J$7X>}0w2PFJv?gq?WOcr)K%W23uD}XxBm}kt5H6yia%QvJ zvD9lqaYsi-KbDdeAj)Z|spV8xryl|s2U({nF@h!c zN)Fs6itp#VR^-EDC?a+cr2WQPkDs@}94V#`W-TyT4OS)RUu1-mYl?AwbTC*M2o_8! zsl`PzHM-grmF$1FhU0uAh!f(NNPi{W6GA54Vtgvp5FPLpB6A!1frC9| z7->lR@j9bU&5XZ7y>GWfCSyx+8;k)aDUXl9LPVwcah z3|Wn2eXoe%30d1xkYZ`!gW{a@_Y5>*LTha?{zXR_>IRYXl1zkm0JQ|5vt+1Ok5&-4 zo=m_xxyJm%8md!i=P>`^oq(_VgVr$!h#LnhHcbTn(1h1%2#YsNKZP6l)zMM}fRIx{ zP5^Gv7+^2Ahk~6FGk%AZ+5az<}6%VqL18a=y zEWR)uVX64K@;!!~5Vf0AugCl}-iyd~Jmxi+3hv4NT96j@rV9-QRQzC!0?%CeK8(3w z*gIQ-u?DGsUqZ34$RYU9<>B$505{GRmHi{`)HYkcMxgFw=W1%){U_bxG&xX*XYK81 z_ygZw&^0vMJGOqxgJn8 z#O4@*MS>)jqQ-O`&TxO(c&^@D{>~o@of6CTJ)&;!1CDbGg56y) zPx;KRdABYJT|;kW+@lCmL;sRwHtHYhv+B{2f4MY&BE@0-@d2eRM@W%#`Gy7?60BSx zMd%3@vJ}L6*XAzyj2O}~tKoeS?xbhFB+G(qJbT4vv8v+?Yps5HMWX3aSN|JsqLN?= zv-)Ka)fu%{3hY~aq7+3i7YUb`%J5v-PEm5^M~&v;>Az!aFh&6GX@3Xmp)dqOvK^a2 zVhp!BM_2Cx_<%&{`o4dR50aEeu+vd>b3yFbX0A+!D8ve;o}>5U5`!-O`(e6%ysZX)Maem15_=YxZ$$7cu3#$2b>8q?f9y*r!+dFrn6|D@ zv+5EN^Ks`KLs0VX zG2e>lkbbpXDDeA}bU3AlgsECa$|i!PlI5~Ea@mb zlPc&-+HiF>>Zw`faT5^e9Cn%dKe>VWMqYeO$swGf^$7E^tao#L=cM&%bYMTQ}$PANyB8D^Nr^xURMQ;;jkEc!`t zCs^7-4vGs;jP_2&4X`Q5KRl(Z{_OC2Q`Cx^h+*UW=&Oa`j)0Wiln1i!q2L{f2>h@s z8q3JrWC2)0(CNyZ=E&)fcGQh`ENd}Pqwh6N#|mU#=$9A-3E{|UudNOik%q2429O+P z6VFzlIN#a*G`{KvNa5FE8=t$$P^3TTT$r;b6bt7uL$liEdPG%I8p`MdH*8En&%g_Pj-GX z)+iArDdBkE(?Kt(=pU6o$>We!sWV5Lzb3C$`qk&`=n?!N`ibs9zJQOka4S`;oT>ie z+%I^|&9`Zm`Y$-89|{O0Q)E1L3g+Y|nC?1tIwUH1ZC#R7k=*U9y#KZt#i!hvtC8jz znoTUfq`)BUISpmH}hlw$!y5im(UKs71@&${1R~E)G z5GVXTB%%B(kmCn(o8r60Ip*6$+g7o&y|+XD#*^kBu|NRT(=hm(!(4l@VM|X!qom}V z^igrF8r#AM5yLI#nYWuktsi|}MJZzw5u|^v7#|cXtvR8NT;0J9C2-r)d*~tqLlJ?p z>QO!_=pk3UJ!ajV0K@y**WG>g@y38}mxU9cGh`hLi>e&XMoMMS19xO*bP4xwjkYib z?caLPrrB@(Y@}bTJnu@{gFRStyM^lB9X;#F@ptJjf#3`)l7;QBHafx9sW>2Vu}#Zs za7tBRy2B9d>tO#%Pc-P)dkU{t%D+5cTx^abn_hp%8m7~x7JMrB`LVDGP)B>xuzj15 zL4qQ~4K=V|75AJFjg~2II{yB}^rnz9DG?70P^-8HJ!Liyo)S-8j%aSy67$m2_F4bF z(_sorK%9ee{Q7WjtTxKc?e8)87b7$R?_GbDS7BJNQi_rj$0W8>%0J zSrydrZ5{&pW>|>RYti_W$)L?ag)r6YVhMTbK0*D^%0hZwVdQs`1AoD+V>3d}DIAX9 zD`)2_pX9%Q*Tlxy$k zhyg`2O49=5;^v!i(vUZcT3@p`n8G5Gi0S| zme=Arxx-T-BdfGlfbcF%)QfP>SBsh_khw{@F_=lzuL=fBCQJHx?$d!W*rSgg0{1;EE*3URO?(z}yyM8F(SSD@}6ypHLqJ_XKYIC!SY80R?7HUmheGQ12 ztLLT%YS1~G-z3pZ1IA+uC9-FBxRx`u9;4qY(Lq0jw;@6l4I6$7{P+chb$QGRpxrqd(z)VaB-tpP$`P9 zKIXp7idrCPU~~n61i;UQE5)8a!#R5xrl`&Li7oWn|0l$mW3`!CMC`V^n72n%Pw zj#=t2Xq2^Uy?EV1hxrRXBGj^;b5*)JMIIHmTFQ9Bk@+3_y(qW!k+ya4eUH8O(M3yQ zXEVYEH#zb)U0<3UiD{6gnjo-~8&gCQTdHYZ(4$xz~=YTB$~->?m5xlnk|ADuVL z200KSdhn6!>e_!~Y~q%J|AE6S*y6&Iy0D9vk1E+n)t#`MDYv=zIJUDpX!6-b7Dbm$ zM`Xt6Abv0@LiO@e-~wRLsA}i@B>|afP<%WBC|FXL8OV=RWdwK-2XkDhXwI5sV9(NU z4*qnXUiR~DwcTre^J=|M2G&1>!_TWSPjp2zz_=28Gl^0vY2s~q+EP|aP_KiEqo(@2 zS72%bU2Z~GvQQ0iap4X$R36+MC8~zBuR$3Y=d56h@f5e;6a_EzOJU$SU zEhFyZ*V?kwEXcsY2}B^?_PI|$a`x^`CrR9@xf?#1`F%~P9IljJ#8Wk8O|HeT%@}(IQRITx9-{(<!<5m z3)vV+3H8p@>@wOJW=?9o{=@U#$-UN1)nD2M?{=!9c|kgLi_x+~$c?2Bj%7bZcR#?s z+95;l28$QBxU-A#FMT^16o-B3h3bjvNoI|4xNcGw7JRKY*kpz>zQ1FoTosY@(^#at;Kc4+aGEd0!gTw5 z#G8}f0sZn9ud3p zdlYmqC0n&5C02vuzk*n6U=3Ns-t)m^E%};xpk&VWBJwSLe$jX!Yn#6nQ)t@k5Mibs z&*?`O6SuEEb;QmP1jqY>>@dT9Rs^9624E=hBZ4k7&GtoN#PaSCi)ZUC_6j<}ZocQ- zWqw2|NnP7QcnO_w8DrMBX zv@Sl09@HtwW2Y&!=t&4Z;1nCiQ^`x6{Iw$mA9%h=cR@)y!Z~i%qA~3k!x{Ck$_g8Y zh!*SPboBhZWn5Wa(H*GKYo7%j$bjoT0NCNOFQc9L7tv-u=o&y)CW6PWm)#j`UR20-PVMn{;oz1N{mcv=D!pR zr37%*wjmcmSQxWChQgyCmoTv!soanUMY)@I$cnqM>M7NX&K6w_U5@UO3Prg>dAEsoCn z9K|z9R(FW+Eh`C{W6v5t`zj(bAiW96-DvOfjC#Rd)XL#Hw5J2g5fb5%FQl(elo1D=%U5vRC^gXyGAr4@n0|`JlUWX!0PhtS)fU zo6MRF3|$~GAmLLu?zptH)G|1zH65_qbYca<=rUdL5uv&$*TBR2dBUrBZdHiA)ng|# z!`{$6aP&OrEF6}(kh3FBkusQt%Z%$>;qv_Wzyn{CCxA*VYKBKZ>?h`xD8emHVdQm7 zHBQ|?W}ufJZbxZ|;B5TD4*SXyCEb|6WiV~R1O%t8SE`U$wK#GlmWw$u+uqUVsdnwP zIe?>25dN;MGc#krFc%Vug!wcvg7#b|n9*@8 zyM62nO7<9CPZ@szjE$fEi8)YKy8?{H*0YV?+C_S4Qr@>_1FoO*nm5ukcur0v1E?Tu97 z4>SZXwccm%wMsH4+a0EdU8Kk5^{ zO{bHIK0|&nOTv7QEcPFUkMlok%{ABC2vk!mq-F;h5DlYWAlDx1J&fPvt0GtpKR(2r7m+Aj@a+joT1volKau#HAf)%iD8%3@D~+{6q^)FW zSNmNE1qEO2u~F|&>M}_9Meyz|ta3Mwq(})vmaLz6MO!RhZW!^IIH_g>Iz>@Cc)m(p zdN5>pNQi`^xjXw`)XeQ?W!0QdjoW84@7rmf`w6dh|R1)@f8g}2R zrSdClX?6WxAAMBykk<4ctMlLMUdPkD*J~BiV&gO~Uc6YFF=33g5~0;GV81p)&$2E8 zuy=hAhr{&-5yVHOmML%o4%U!k4WBXB$Wt-hX4vGikDPn3+ceUg7pp=Pnz&W}j!op= zl?|iiGp$c3=p2H-nrXo-6bWk=xUT&9Hg5!mtU5TA8ivgp@Z<72*7q8WoQ1d}yk7 zGTjW#_ery9br*`)x5wN`V>aS*{UUp!>ylxxTD9Y%cv^m^#ajkfK}ksO2z!v9!_>QL zUg8T~@g9vgM;EMdUcgD~a_-U%E-@SJa$Dqu3+!9(_UB&%4?bm-28ykBM zcmXSG>*0DgJLlQP8$g|->kB|R{A2pSg?bO&Y_RQL4*E{tC7-|w^d0Ddi1L%<9@4o2 zaQGX`2-V-cu!jdB*lWdvYYd*eaI1LNGtHgE+BXgh+1#^Tb31N-oyvvlr_biP8Snd8 z|NTg}_k7*lJBOzNJmCwx%E|BMMSR4eGV^UkvYG4T2Vc6a2bYdalYa{)_~M{E?)<~R z&nWqFD0i~9VV)$uLF@6G*#;@6n$JHbGZ&O{b$fe1?_;F(V;Jf@nV~KXkx(a|csD1N z=w{(}s3J}jJ%Ba)BnW}P0O4w!K((O)cLQ?(2Y-0iNe}o^<~vxuva$yCCCS!gB4!ug zK6*W-jE@=&_B4>EoFgx9QHIB46qyN6=0DUWq@qDqaO$FH)ytB}Q#_+Esi*L^+Qh}L zvwMl*7@-FWXRGYnA&0y0b-|vV9$Ha6>+SC~a3Uh53iGB)KuxTtuWvT~9IfN# zJj1Qk?F$AR&>BO`!1O$Luik0_1a+K>eSJHtd<>*D!Ffp&vL0#<2yp)Ki3puW$1+HU zfs^!TvfOO#=j#+9ZUKS&a&i#(s`=gB-R+HPUl9J-AY`G+1$q=tK*Z{xyzqhyI4ePj zY3#RLgvAL`-t-S0s(y;nlVQVyM=H8{UwG^^ zx@y*YL@u`K8MD2rQ+oB2t?UH%fkRHz2Jw#-lBDTwt7pay#_LGmt8CH{Vc7Qp z>74psjLNTlk;z$x6MHtA9BI9<71!X&8~n8gMPsho?~g)C1Wg7`JSnZOi^WgMx_+@$ zSkHI%3cq7udvV~oRT*5O32j$?n|mchgIKyd5^cz3R;v4z&3nD2MKI#MrYiw`S4agX zP9kgF!AE8+kKidA_?Qw0(x@j$6Yn6e&hGqn*k%jPp8T)CUgB>8h`y#Mc&{W3ImLU; ztG~*uR|M0+TK#}rohz|q6vt9eV8(hO@76AD_@`X?VuH3=xOlhf*N}@~o#EkUs+1`F z=-t$apFd6GK0DTYw|&ef>9#_MLr4>d9>D+x>?j40{hlDGsl&UwmFdM@vCx|EIr1TU z+qHA%hfRRV=2d!nRDM3|CG$qr@$o2@Zm}_YccJ_S|It$$~F(H@Q?!~XgA=o-eU0J~F z(qeWm!gvI}aoL#;^lo;1CO?k~L!6yA;wvb<@>717$dO!Ft({EWBfcB`Xb8*9m-@w> zCE07Zo&*s__$<^*EKSwgOGRM<^@27dr4*IXHN-2QwwZU){WKg_f!S+Cvq^{$L`o9h@oDO5Y8~ z_|NwY388PvI?$94Fr_x1-Y@o%7UoG}zSs8lt_>XO#h&SPZDqLpws`8^BLE^HuLkV5 z7V-4jpS#M0GF6EAl~RAsY?>d$B$~QjwQgB!e?1BH+M%e+m!GGnipy^Xp^T*?gGf;3 ze9vH^r>Tj_vV(46^5q2b)fg@}@Haq&ULQdFXnXrTg6B;Pr)!RzjCHN%r$V6=Ns8~=*{7c6mxK|Wg7$ytcEZR$5_9t;DZen9@5f{89ek>ufN9v&+(p~+ z_&FKE!Mp4RR4$o@7gB`>v$VlxKi>VhM%4oL@*?0@G;FlBvSJaT^}eO&?=N#NhV}*E zg`dxhlfei`ZfD`8B8a|s6HJ{hRiTs=0eb;?WZMF`>~dYemj7!!nT3}IS%r7OIqpB(=P}4K?$ZOmj1Hdrk0i*5n+}n z?1C1$OJsUmt6_3CUr?u@=S%g-#;w!|<^m_uvDAjwGn0?#<2H^Sv&NV|`TA5`=hZnm z#(U`s_jU6kr_>5=7=~mG@EVYw&J5Cq2^*?Y6_973CDtr^mFit0P8v#`gvZpkoHX}( z0O}+_8JA~hzC$Yf^gv||!cyxERWAEg_|g7JqcxtJpDQHgbq=h}Y93!j?~1Hs`VVi% z2{;PlDs6v4f@tSndijNakYa$&BzeU6Qk@F3cBtf#I}#{jo;1$j^%zS>Nc=t$>rE?0 zpWIU_1R2}lvuD+DQt_deSdBNkAm4cx!M4#ARfLsF2;6q3w2$dLCeAxiEKQb}` z%@_Ny8kQNqKv$pvm;$Xa!~8iM9~%c}p=Q#269voZGWpBDI;2Q~=9fCk(gul106=7| zjh9e=Ia_%{Rl&TTM*r@stG}3zW+SgH1D1t8#_$|(#WHsx5+@Bwxf*D*g=4Cz>@V;7 zojQiGv3(oVM9zQl@$eIGI`CQ?7 zal6$In|Z^24@*q3WSrQ{Y(+sDf!br3>a470UZUX{)Ustz?>qVk^P>@SdK;o@ugs@n z?%_t|LpgT^kryH44Dmezt*<=@L2OxcnUFD8we{AQ^Lts|Q`#~u zj^1kT^X#{qe@Rs1CCET;g(%dud--~*njWcLU>8TQ+RQl28n3+i{W^YvS+(?=iJF+_ z4n2DFPE9>5eOQIDI+%U`(IX^20fBT6FcsFj=JnLf!ouWW&KwMpi3M(LIRi~2Mzl|k zxicFf^ZZ=oe3r+syrcR0j|*Dd1o2bt8AeM>5av@bXR_kk{j4nydk;)v{}uiLstSq) zqmNnwVG+^Mp_&DXpduX0BpVCFqH+VSuO5E!6GvCcUB=&>ifMpdZi8*PWAQtXA)|>* z$~t~vHEK zfrs`EhCziMvtG^>Iz%)iz&E$N!N`r=<&XR5_HFmYBKEr@t3CC{8EvK za`$~FX1%O%8U)_teiK50r6q&dn;nG;ZESpFOh94dUARpIfKJ3HJ(I98{9^4GP(CL!+!JGprH8ZOmub z81y9idYW$4iU;lvfkYUM`2aJBEBgkoz|7WIg%3>OpSQ4vXh?v1q)r z{=Aob7OAsfP^6StjCmGb*>H%tvIJVJ#B7M>3|c zSMz4!%tqXh8umkXlBwFVAjB9RuT<`AvK8EcizTu4ea5a6TKM;dux*R&#~`7wCf}0< z05EL_>rw7Q^+BM}lMSKJC@=Amu5p4{AbGhIW3@84HmRrAOW&+*n&~8W^7}iGpkpvi zYh;P{(4-+D(*r@lVLYJ|PD^-@@P(KjsC`ag#=4JOxKA$ZyjEw3+^_4!SY z4P5$12s5$Jt3&s?{GF)S%MZ*+%Zf8cI4IoPkOZddM5+8(=)U&)U@(D@VlnRv%Uv%s zwT_E?_Ghp=%RfJDpi#)beWa=Qj6;D)JX$L!A}Xp4aG0Y7AqRhqJ9$t*3AbMq9mQ9( z7fOC@H%h~^*Fc@U$^ABq%OyzmO-q`1GKdJ#KopL$#6%2Z7k58FC0isMVlw_9ezeAl zYTgb{lA=-g=MEgA=Oz+qeItD$|Am}-sx z`NCzM!N9wb?I*cZwS-`ak|r!~1dIJYs%9fi*~FYC2h-QB*UM zIy^8fAn94$|5*~eH*pKDpZc>zwlFB3llcQrbth0fkH%efAN)x%7PzLJvYGH3X6Y!s zm3&||r|{LAZ7{=r150CV`T7@w4fTAFB#zvZ@gnbk9baFiqAnTz=BKC~BU}(?ilsgn zNL+IbbQ_GeekT4(2tr9!u#WF2^W_me-8v_;vZP>EsoXxrFUO>t@9V{a_8ciiZtk>C zudal|<+Il0AJvQ-wakiuLunIf65bw!)`hKTJirG$R1u&z?p^<^EDl3%#J280IA>#o zMBOPq^-OoORgV_+`T`spyj*bD^ozPanDwMdhp0UHRU*$o#Up@=1DXr(N(Tn#bu`Hl z#jGC3U!nT}UA*=hK{dyRIElW&G1z_PYyxL1?mdaJUW|=ghztXg!s>W;_PCBotoR=O z&xcy+ImB^6jxAm`Y!vPPct5jBz0(|exOTlKNWJ?tJt4O6GeI5Kn+kESJ?6hEb*BJ0 zN6N?;`_XRDsy|&6C|2HSG;Nr;4`X&9r)PTs9E{>EtPnSGV7R`OJihA@ets^=3~EAO z4w=302`s(N9p6fcGM+3UCKCpv_e$oGReW+LnT3}&GAIvTzo5xnZO#s4|3}(4vUTiN|V}M{?6v4cnYujU8Sr03%i0Llom5jjWUB+?N zv=P z8z<{lF@nUo7esER?HLvR{il@m`_K=5g)9k4%-ReSw{^q45}#jFp}1o*Zt9S=mQw9W zV744uzJ((>35PCvH@9dpTB~vJ&1soK?#aPTy4_SjKZxUhbqg zpq3dzBv{PNCx{>~d80*YZqc+}JlmSU`V0gS($cYMWM&6!!#~@?jd~ZKDqOcePKo+q z-F<^O(cS==%Y7|U2QK~BFs(9tUk0>A{QsN>tqO$8hTsq>xVnCzc3Nh5%nkJo40KjI zjK;^uLrvy!1DTT6-xAnRV)Ts5vGn4>fMZ^+U=+#DjsvFZDm=<6zMSKK`}S>U-F*#A z<=lSqbM0w{P#6f)Z?dpp0Ot(izOR55z{xCJL{{iI4+scA1sFUArbPno))iIk1Ki{% z#xhTHQk~XKOxGJ)SV=SP;TDQmKBEIZTdWDz*lJHnjD# z6vAmfB5cbtg_#{d8FODSJ86VFqIB7kiIHU*jti%<<}@mXvu@vrGA+T&Bu%8(~D)4jzWuD!U+jGLP&bJX#D>i8KTv+ zdQ1IfrIPYY1+#M|3I}5(Xpam`s3|g^Y~sZ#j#N4ZACjDO|JQ@Vlfv z4>xEicyhKUNE9lB7%#*#VHv77w7$VW z>L&%?!NzFBHDw1=7%6Urz3e)z-E;oySrQn7ryN;1{T6a!0eA<5KvoO$? zVJXnI2~B)zUIuiLH%bi3+FY8y&4i%;0AkLVwl)QO5n8APXt`BBnUTlT^E*Bao{;Iln(^`kRq*Vjd^M*?3n58c#_TLkSUP;LrR zac#4+t^FpSGmcT0F(1;lTz=Z3jCw{O_H9{cG+iVs?F(hb?AS){@~cl3qW*SzbJpXr zfSIl0`DIbf2aLGr4VC6OzlU!&Fv``yEK_huNb+D&QBmD~CtWf~6m@lV<6pfB0;0_C z`hc9Bba`SzLh#s_9wcXAK=n7@!NS6_1cpHM#>lNxenphS3pE^ zqL(vI?t6RJcik&DpUN;?Hfjz-c)ue_CDL6ncQGuPd2mFBdvxR}$8ck}O4jkRU;Dl% z4!IHp6$}SOvWR7pCRi||i|ok)wUus~bb6CBEUR!POs&zl(AtVvdaGT|Vd_F=1o2 zpXcQ31Ve#AWj$}z+em$)4;IL)EsEE&5HXKbow$*q)%s<(@csc^DL~-3LD|d7&dwb$ zFgVx+RE33{rvw{Mvg~NFfnj?4mL=}_cy_<-A!YBFlzEc?3rky`I!Nm`%NE;S5D0nh zm@d0{dy8WS8G>L7GuKeM%gU$yDHl^lJN|o;!1w@+9K&he%j*MPD97vTBK&neM!~qe z>!9*-wFC<4NU+*_&uo)nQBgzJX!wZf=KIGlBFcI`w}g6yM7%FsLEbjeP&OIohFLy* zNCVy(t^P6Kk)o0I5kc2KLE`1Rv;hmuRSZW@xrdFehZ>jRK+e-2uxCDdC~9lR>)Ha) z6X2fww zRbc~37{W8Nw&bpaSUR>k?a2F)mJCTxV$exc0E|s&84ged&ruBRaM=Q z7SMXJTIh%@JMUwN0icHRKu!?n?hSCmR|Zhie6!^SiOal~1Z~t!NZGk{MMSWK{0IG( zgPx|{m~K;+o^kS&?zHxA$pQ32PJIslnty6iUgbY_`KCPu0?WOSotOCR_X)^Lq4PuvY#mP3U;KfPwYN#sUlr^wkGPD6od zP63?1GM-Z zY@t&-mfZDfnd^U$Nz1*v*^4l9Y~a8Z?#(Q1J0=nr7YTbiP*v_a9eP7QZuMY#9nn)C zwA62by(;$Y9hSnj(YIo3K_Xh%n0;;tt3u)!b)PZJw-dSKGWRm{Y_R3Hc{gWMn&LQG zaj3%+*KQBD>(G+;4SkLZ3$u#qJUeJj@QMo*I0>ckE(3et|A=#JCwjEKKcvDf2OqagFZq#+W8)lC?L6t?)Xvbw!iY-d=4 zs}%|$9b(PQf-#H49uZ+uFr#C~ZZ9o;E#I}MLlLmA3gFHa6<>e#NncYHG z^$m=2OSoaHA6lQDQd$i-TmhE(uJaFHB&U?`OlyUL{DDxHPUk%mSMSUiAN$EOu@UYb6sLMeJ)=+`` zzH;{=L9)2P6PUaBFR71AjY31uF^Rk$2+|i2%fp2fK|k%_38V?yK#`agzxv}lQOkC) zGb3$}b=)PU7jr{DENk`THg{YTZ=GPgCHI@8Yczc@q9a;E8D|VVXTlC#D&7a-aeCjL zFm_LCPEOFFA2H|+Rd)vZ431hzVRn` z!77+&OHSn)EUeL&mpvBP*);vrRI}q&0%As`vybkM)U0JNzvRZ!T<$L%`G?}5@Chr! zxj$B_zqL)8diyr=*VK>Hs$k0M)#D07(7qk>n!!yi6cz)*wb$X887;(LL zG{KFgY9p^A0k4{vj$>y}{Ow2#IoI*A%!OPWZJU~)RsEqGnDg9q@G>FD_X%T6tI4NH zZ^j4f^AhI-=x#*O(fsSnJJIZ7Wbjz$uN?ODhOe;k#&?s`u>LIgHi19iWq+u>ttLm{f z)=wgcM~sB&K+5H>v#(rxGBzmLa9pN|?@wbF^4o@J(HG`RJ*Bb<0yj~?MAG%nZ!P#H zOm??MxBehjo^s|e%7)(8A0RC;2Id2nElVgJ{)E7CTF>n_;Dv|T0a&oiJmY+GhD=Z> zWeZ?`jPC)0ENw_RJ(Hc80uEQ&kLn`*T`-MGq6h|U_1s~UX-|c)n8RbDzk4t@c4tBS zOGPF@^X65_#yNXvwFTJH=-)Svc34qE+z2Ta(bCNFMUtcst%Yg*X0g+u$|rADklY9| zU`U*zIgZ045KNkW z-@|rC!fHlp5eo$Q?4KajF^siCkZSg8MywNolHlEIIBF-7aolWM*YfIJYCx&sfdkqO)q?HR6*8!X;+ofZ*=>Q{VXkWYB%NlqBSdUA#XE1mC*Phra&qFc!bNZ213{aCyzqq_)&@Av~xf{I0`8*2y~Yx;hS zBlFvRz$)lyYv(uv4e}|<-oe+xxYqyzwh!k0eywH)+yf2FE5Nv1t^4>nIk>S9cCdLeLW~O|cgb!z>E2pR(ZqUu>$TIDJy+ngK-R3=q3mk9_6azX3mqLl5|uV0+Jyw19261VUnJfuwj(-pYhj^5q!_8+;Q zpH!zh-Bs>&DmQAWudm-bIWatTs`)O_EAapJ)~$Db*7tk?Z85pL;dzkawSltyMw5(# zKd5gh_@!^8G%JuJ@S&j?-=W?bWWI-pA+!b%Dx}ba-T%ydCh7w~CW@*z?H(AoSNmkf zk>Sppeo$uNbSkb^DCJtesaT%I|OUPjas7V6g6KFmQx~~m6mAl;s zRZe6_K|LtaMwQMKqslT?-4Ms~ep5WEt@X}Bgfw%`lkEBR5$eI5DjE{aY~Y<(ft&@M z0jaZ->pplO1hAcG0nfYI+6ZVKog9HG77+Ifkq^N^GBZOUwrvMLC8eh)3s)IdTs${t>W7?$K)d^^{g#yRqW2Q{um=8 z_Jrt{Ag+p^TUNzi19GtgyEo(b^6nGfS!o^!1%&{6jLodq%E~6}s)T;R`9a7pFOAW= zw%6PrFFoh{Fm(UZEl}lM`jBi>Y2;K&;>_i+zCo%GF{w=eE^G(9meV#lK*|Cu52>Q; zOFqc0W-aMx0QBlIkFqjBE|uH}*rs?$233ze!^D9>ZKv!-T^Z0CDbrz7NN2zf%twx4 ztHY5V^LMG~*{X-6kR5k)z@_sQi>E0~Q#W3J5p{#eM$D_n?+)c}=Rm;cBF(r?4>=8W z2n`(=^@gQQ>h6V#FzHy$7ZRkI!aQK)3d+)^AWo-zg{AL4$g@Jg8XA8bh9Rc_FVgao z0yYGKM$Ioi7>8Eh?xaZ@3ym>|Jo5f~4@ZU5+nb2$A)hM#P*WlmD-GJN`__L0rclHP zoOb2l87167q%(aY>ONoKm$=V?c*uOxYMjK{5;-`sKMcKYp$Mi2(kT^OtK@U{!1fPC zELej#-~dP8791JsE{L{d$k0<7cJwd<#~0vZ!OuIohIlPU5E~fmp$G-|x@94DJoxXv zkO*F=Na%lkLYtQ6KR+R=;S9s7fzGASOANmIrVvg!p0GDtI`$UY`GTwY5n5}|V=BXP z2J?i#1_NKlKv)Az2plOBhA!LyYybCtR50q;mtoF-gDmuefsabipv@!t5@qPr-PQ!! zekOT-yiE|h7@v}|@^q{F)lC{9D=c>j1}iJ8O24xMEgY( z#b_ZkCYY3zbZGO4M)Dc2X12^sLfl>Owbl6SqR(%BDeK1x)RI1;03B?nZ2>@l$XEL_ zxUNo&UJL~ZG+*9I;Wvu{AaE_NL(rCBsm8<-3Pc=!yYtf(xq`9 zXV!a_0dy>IaYA6AgIzi8Tz261_qk_B*fCp}{7+%%_C^#Xk0XN#Krqu2Pc)m++FY~jtlyyqPi^5=80`ZZG`!t_O9~v;ztG{k?V)>-m--j}$Im-n(92bzNUJ1_A8XkoUo% zSO4J#_k&bGo(&AA+%$My?`p(Vi|ju%fY% z-uHN`^=6#Z2z?x|U7=nYCT5@rJ#&gNvpkB99#j zEuEcteU3KXIRpI)Y{-4*=M7NqfdWBkoQXCD2kp+Pth@HUQd`V}!dDk?ZONNbSEq|p z)ehvKTM+PT>09F8q1fHIxYxpV7?4WJ7$-o#SwP9hGdAQ|(~vBOfq_x!eF)gkg)o6z zm$SF$MAIAMGWlt934^Ms-}!n0nzG>vsLkC3U|LXoR0NRQq+95N3qWd&etYsj5Y_5* z?-%-h-6b;bFup{egWJ)fRoFu_*q0a1)cw*F8zCeza;mCPBi#?O(GL!&A<%sQ03t*e z{r>sqpZOmy&5u8Qb{C<~J2Edf0`*sLX8>k}1AM%TVK~@;bpL{pzB;YF#x-}_wq9br zPwDS_9anQKVDteCpm)n^0$PKyz1H8QmV5PsJ_@tAxY1cgYHB#JDSjX-OcQY!(I0mK zP(^e^0i1pa=s#JE*WaDk`IikJk#Kc$lMWs~H@>Eooc{P8M5H%aS+M{>xJ!Ss#K#=M z4x9w7y}y=QuyZJh_{)adpFe--#*L?^zGaD4H2WMm0x5f?*F)Z-Xk1y#%|zUKiN}s) ze~(;xdD#lA^bT? zE(-LH-)d#c@EL1a+~fOe${qC4fpZuU-HH%NNxbBPbBI0Skrm@@p`N zVb#+`@Lp2!Ic_^%Q2g6bs1VvK@MMj(@dajsL(tTzNZYaVd;F(}f3J)V7Wo?l zbo&<=eH@}e|4L{)@xQ%f`$O_B=$0ewH-KFH%Nwx=#fO10XS7jL##Q|Lgb{K79X|l) zrU>%B|8%6PSQ@kn|K(~~Rj|?#AoT>^4+I1M`(}q&5&w!r{(Yr?-FOA5lHeCS`3&G8 zEB@0%R=w}Xu#E;q6A-BU`!TDb_ygc^|HE0AMn>kKYn7l+4!(I`$d!7p#&c1Z8vKOc z@_#?PqFGBm^54%5vh4r#{0XeVc~o+)*#G`eBw33n5~2XtulV=%|E9Jve?9d72pPb; zn!r{EQ48aL-El5Dd;K3C-5H~k2Fht{{MjoCmU?7D|GK>JYGybgZFHjAKx%l}FB$om z3_DOmTSo^5MMOsKyJ~rMZVy-2?{&j{7i zQqe1}g*;Xj1&{=S0A4Ki@R>(?KCqQSLPFjB{V$rEn`=u(ZHIjwX`1pnb5F(uEqw1s z3jq!g=3BSOq~=_2RyyCNqbI(fSdlkupEJ6io_jB!?=4je`@AR4^viz(DW1|6WD(7XSMa|381I!~~vr?MJPESgaz@%j>GT zc|Xil zKX+G?(ftT=v;XXc*W6n7T=H}mMQbtwWC0rP2r{{;2G5Gxk}(#v4k`$S7}*o?G9^6P zfI`8mSFe8QblQG=1hDRKJiMS``;L5-L~T92B^`DS4qU)|6`q~V1Uh1&9NB(k{HeWp zePGxDJ^KLG#(jMRo9X#)9W`0=m)@W}(E5}fD0h`@<(=G(pcWi?)R!*$at4q=5kivg zYw;hNOG~3)gol5`W%LSsS5N>@V;9luM?S}34vE_a=q!H4lD7nndpppgwgZO8%CRP$ zLE1-;>u}+vz=yy<2>4ftXQz9Qo&mC(%Fs|O+Ztn&L!pZAB(j$+fZ@N#|8oC+%InwP zzFh1`P82=hxD5h|ck1^8?#CPfUoISTuN@t;J=>ZRx($|)iiV~e2tzfR)!3#cB(wqO zUjNAGsFATTZ3Ey+eF&UxNolEGkJRN}J1;wX*yEYc$=h?y*+e&Pg#zTGy7-Q3{X^i& zra&`y8uZ(yz`HU6?$4wSm8-h~X0)yS{r#OmI=%(ar_Mk_ULAq;2@J>?JfB@bt0+-1 zF%5zMq@6L~@~Mq%6NiE^sIW40psxZfIv}rkSO%fz6>R0@<@=u0@?5M8W)FV$*nIEz zWi`up3S3mW8~}zaj{&GysFNm6ihM;3|OK6HbFV)}VE+%{lH>Fed6KgroO1zA2(M}R$U(Hz9t0w5-JSikRR0FFE_ z7gyxt=?^br=*4yMpmk}|1%@%~pD-X2`UpJp=~ANB{OYRVrWXLCKWW^*2ipHO7OJZF z==@n%_ifS*$!Dcq-XIQF*3iI)fV<1BtQ^Wy2NN|Q1}jZ+&;o-s2zvTbzxSSFf&l3S zT%MN{)8HXU6H2wDEEK_CLvm;J;;4BjL$jdk0;CrAoSjP#WI%afxWUsUG(4Qg1~lZg z&CSu+UoM;S-)`gP=okj<_lhIl-&yc|VtnX1y*1&30?n^ra4{Nu$Ar;)a2tyP22juc z>XthQpksmm?x_Or<&Lg5nlUIu zyy^Kt$vkQMKWjc#Ag}@JT~?E_0^rm8Etn)|>4~su=W@}-^7D_=&IVT|hOg7RN=}sS z-t|ga|53ZEFKgjuza?3mlARqloOjXF+uK^L7(MZgndSIr*%`03Y!5+dTrbnyooS*Dg zY>_LGHeVhPpi?L`ZVUZ#a9l_fSotq0LFF8Fuak%R& zSSKe9R2?Y3NS8~4@{%z*x_6vQFTlg&bcdY&;Nak)t}Yqi>b^+pT`u;>0LGn=RwM%4 z?t?SlD3+H|Q3u~tm=jphC#Dhv$j?Ce%DAh9J-fIN ze$x+5BF7yNC-*LX2Y>zKP9hzUFqXa|mH=TkI*+*kz3Og&Z+@g(54YhCdex-o%#IgY_)H2u)-jUJX!TCxan5S46)V}UL#$*sKk~Qxnqzkp#4WB z9yxpUO9~EeZ|_nN!a9RJ45R?!C@Cm7O=@DVVre%)TxMrnmh$}f@O`u;+5##_{{#gE zF@C)B{3}RB+CZ2*1uVLhzin}GandbdO9fxX#Mpq%V1042Yo{1aYy0nc$kdVU?KBs7einJXZO6fQ>T8A)F3hknDmQp!Pn?q(PTPl^tp;=KGWo0%} zwwwkrNgCIVjt+y#`0m&4AK$-U*VT13>6+f(`+MK#xu5%a?&m4Ax!<4d=>hxL1*8t* zvWUv9$B@Q)vNE_Ec0_*9wfCkzya8PI`O1_Ci||?Tsg}fGTSt$D-e^6zclT~(!Xh8K zBta$6UFh6bz$Tv<9jvzw=D!KscR_y?n!D1^pUFS&KoZ--(a~|s+HD*%kXv@UkhaSy z*2&!um%!B8Iy=Zp-TJ^^I`=SyDa8HOrWP@k1N?kFwe?^CnPewFckX^z;6aqN4v!_z z@=FZ}4CHu*aI@fXRMpiR-apU%6UM=bg{YAONhMhd;!gXIFSRDuQm%R4$-`#E zP=tsQ^T_bo3^(>2FJ z#<2k5ptKTR3^3!GrZ*ZkfgVZ`3*xjpR0T0|@!1|xXRE#oVc`EQ zR}>XLRPc_QEO&|_dQk+dOR*0YELXCe6;vu=lnKQ#20WA*Spmni`eD4r?e?2H3dk}^ znFewQFvvXQ6-vg6K_l*{s#3Mo^(ynNoqdB=)PZB{0e`Z^)z$x}_l>tIqQS_J4|6U+9+4AWVh?M8Oij)EJ1lUD-4ahIXX{`1_Z}O^Un;NSAejcy5#3dJQ(KYya%)DTT6T6eFIGAp2oAwv zcKoE!VahkvGCM1)j#3I!0FEq0M^h6cBcEBbW~Ey4;C^f8&6Xvsdk5ys@?ls! z9>q@b$s3G`oX^dD`*uHyKW!tRA}UQxoI#`0>B4a7H=zTy;N{bgT(MX7<;yRsr=(G; zs;WFfRhR@|a&mZ-t2);#R?5=9+!<&sqZYIWd+Pd^!&ur%7H`+m_U|} zoT;Iq)2dj2;@R;Zx*uM&gnSdgTV?TLlK=v!Z|uCq2gb;ZaR7EMnDH2KzsssXeBV3@ zht3{ZOA5w18nR5Xn!w2nB77M!qGCM!DEjf880^Am%f92)J%? zI2}3p`S}Z9w?~iSoltpd0Nc8Nwmu5U1w9Yi<{2$1nzUbe!wZhlA9Ezdl`nA6n*f}> z(PupAJnuJipI5$Y$jr8WKxVPUiu*hXU$lV5Ukiv~3;eAclg3zn{KDbSD*Jc&U-I8g_?`=I8!dHePs zWbFKxyhBj4;N(%pg}#U_w->d#PtJ4qEcsQSrxSOvRiLMvw9n+%nd?{IX>4?TClqeD zpzj|TSb$SAlHDpAVed3NS@TzL`|TxpyXP#qpf5uqCF-Pp5EB#Ep+xz&c2O8Q?j27p zEZTwvkao6+@`~EZ_9)I(u5!0`A%J~30e-5QQ(KWp<^V2Vi z>x)&&DHjy#dqdwaql7fu`Yo$qK=k@+$C{i_^)mc9mBqr9cnjc#ypJpupXWu zvk&-A%WMxKM5myjTRU%5i!fUS>C|-{70CTM+V^E)Y@IyupqCQjqCdL0*VT zXJynU4Gav>`=f>jWZ1Nnyu3VmlSfQG7U~23Ep+vz@E%TaWP8gArS;A~A?yFMGYYY- z5QBV%3nSyb2QW!bI??{9%`+BR2sqpvOcKX8pAy7M<_n^S<|8bTp}(BPVO#}x6fbzt`_j=poAr)gW-BY_cB1wUMuKlLq; z2-0BgpP;z9`<>8j^X5Mgj;7#@lOMp%#<6MF;p@I3SS0dG^L>>RN)F~I6TgnBG>d|Q zg1|9YkuVw`IXzJ;u}Pp&G+4;Zm;SjJIwhysCFRDoN9=N%pG3Tcn> z0=CMv3R*ZM76+0L9FQa!HmczZHX(PJfx!wyw+|vdG$8lV7bb-h?^qi7x(5D(%5oiq z>tz6rHGEmNCA$>JZQA+qc7mD zSY9Q8Agu;*5B-S+Vme4Gk8VSVD?+9RUf|AqZxy_^0F3IUQq|KMeJo0GhDy=D{z{Ly zEhn;>@1g??;{)2A0d02U0js+Z14Oy@j89T`ca{0gc_^I_k!3JAtmpX-`KvCyptlzr zxGco@fp(0L@6MsK8NR;0rpuO{nnWzQnFSlj@jP<>)cE+gWk&rI;$(p{miT>beE)ak z%=p8CYHpjjCFexzh+W!ochGu@>17PpI5#<6vunkzD}Q~4)Pb(t45?sB68AjzFlhOd zoB0WfuYB+CGuL#8)x;ec=-?Dq6m5{xWfL^)oSX#-17hW?XxMXXtT&m9U{fw=<#e7D z-(N%0zyC0`|HHHC9)1E%#!I+v`gbhPE;zfF6(Ir|S9o4`!)NT~zB1QoybS!NHIlnJ z+!%^3{$ThyCe!_+JDuJ+*lw7l7=oL3-uf-(&Oc82Zjqw4w&0-nooz9Vo<)Wy0x}*h zUroV`vXoMvnnXvluuTv&+vEI?Jf3HFI5 z1P-7zRPaRF>ZTeC7rrtcK?Jk`-Oy45NG?<*;Nd&tF`^9#tNl;U>uO1wo14Q#?211Q zSfRpRGj5_eKQo|%;)8UJ+S+K_8M3lU3l}C549H@!8p1$gAUA_F)(kLzaHJmhf|pQ? z%+exzjvLyh?^-)mEnoQ{B^;`dGiT1Mb9R713&GQwv@{fPZ}RuoM~d=#-g3DaMBp5a=yGf9MdaZ&po*MKU118xk%?2%(2$3Z z0-jL5YP5g+Yd>t&K+CN~UQkaP2#^@+ln1>ZBpdPZH3=4u4Favzp=Em##5%rH(n*rS z0i_lSoMjY%><$r%0z3L4>jN?t&rH%C5#j_Vb}vMbj$5P#j!}u2#{Mzbyz?L%mad6-lN(Z9gEk+@0C)XkxKk(Hy<=2h zdd!IlK_}oV@M&6NHLC-PSnlzypGrCbY(s(X`^Xu=@ZYRSY(06Sr9sUG(I`=xe({*+ z@vgt0lqK=DEawslv@fj3)&~xR%{C5k#|(-*`zTc`T}whJ34$A@041|xkR;YcND=yX z%YT0U(5aGPu=T605Zuv5>@iW9dvQOoEG;#tE{_WeBx6|6xbRIWG>L!3^ zdvV~CbmTx;@er<;g^Oq;32f+g`3byAQjBEO7Y2gc)s$318l%~#yIe>@Frx?}n24ESy~w-3`AtNT zj;L)u8g?usyALUm_Xrn}2A5=SIw?i1b1!WZmVJUjHr^hw`+$0?uThjjcg4^H_Lk?iM`uch44I@pP[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_(?P[\w-]+)_kr[\d]+.[\d]+.json \ No newline at end of file diff --git a/builder/templates/phase.sbatch.template b/builder/templates/phase.sbatch.template new file mode 100644 index 0000000..ecd9149 --- /dev/null +++ b/builder/templates/phase.sbatch.template @@ -0,0 +1,18 @@ +#!/bin/bash +#SBATCH --partition=short-serial-4hr +#SBATCH --account=short4hr +#SBATCH --job-name={} + +#SBATCH --time={} +#SBATCH --mem=2G + +#SBATCH -o {} +#SBATCH -e {} + +module add jaspy +source {}/bin/activate + +export WORKDIR={} +export GROUPDIR={} + +python {} {} $SLURM_ARRAY_TASK_ID -G {} -t {} \ No newline at end of file diff --git a/builder/templates/setup-cmip6.sh b/builder/templates/setup-cmip6.sh new file mode 100755 index 0000000..b7b57a0 --- /dev/null +++ b/builder/templates/setup-cmip6.sh @@ -0,0 +1,4 @@ +export WORKDIR=/gws/nopw/j04/cmip6_prep_vol1/kerchunk-pipeline +export GROUPDIR=/gws/nopw/j04/cmip6_prep_vol1/kerchunk-pipeline/groups/CMIP6_rel1_6233 +export SRCDIR=/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder +export KVENV=/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder/build_venv \ No newline at end of file diff --git a/builder/templates/setup-metoff.sh b/builder/templates/setup-metoff.sh new file mode 100644 index 0000000..ccf62dc --- /dev/null +++ b/builder/templates/setup-metoff.sh @@ -0,0 +1,3 @@ +export WORKDIR=/home/users/dwest77/temp_netcdf/ +export SRCDIR=/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder +export KVENV=/home/users/dwest77/Documents/kerchunk_dev/kerchunk-builder/build_venv \ No newline at end of file