From 2631242990ccb73bae2097a344fcca7f2c5da39d Mon Sep 17 00:00:00 2001 From: pclittle Date: Fri, 8 Mar 2024 13:41:57 -0500 Subject: [PATCH 001/131] fix readme typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a3579e10..d7fb56a7 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ python -m app.main_distributed \ ### Local training If you wish to debug your eval code or setup before launching a distributed training run, we provide the functionality to do so by running the evaluation script locally on a multi-GPU (or single-GPU) machine, however, reproducing the full eval would require launching distributed training. -The single-machine implementation starts from the [eval/main.py](eval/main.py), which parses the experiment config file and runs the eval locally on a multi-GPU (or single-GPU) machine. +The single-machine implementation starts from the [evals/main.py](evals/main.py), which parses the experiment config file and runs the eval locally on a multi-GPU (or single-GPU) machine. For example, to run ImageNet image classification on GPUs "0", "1", and "2" on a local machine using the config [configs/eval/vitl16_in1k.yaml](configs/eval/vitl16_in1k.yaml), type the command: ```bash From 5deb714c90c7daf6faf5ca17808d17bcadc698fe Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Fri, 8 Mar 2024 13:57:16 -0500 Subject: [PATCH 002/131] fix README typos evals/ and k400 yaml filename --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 929ebced..6bc3a92d 100644 --- a/README.md +++ b/README.md @@ -353,31 +353,31 @@ python -m app.main_distributed \ ### Local training If you wish to debug your eval code or setup before launching a distributed training run, we provide the functionality to do so by running the pretraining script locally on a multi-GPU (or single-GPU) machine, however, reproducing the full eval would require launching distributed training. -The single-machine implementation starts from the [eval/main.py](eval/main.py), which parses the experiment config file and runs the eval locally on a multi-GPU (or single-GPU) machine. +The single-machine implementation starts from the [evals/main.py](evals/main.py), which parses the experiment config file and runs the eval locally on a multi-GPU (or single-GPU) machine. -For example, to run ImageNet image classification on GPUs "0", "1", and "2" on a local machine using the config [configs/eval/vitl16_in1k.yaml](configs/eval/vitl16_in1k.yaml), type the command: +For example, to run ImageNet image classification on GPUs "0", "1", and "2" on a local machine using the config [configs/evals/vitl16_in1k.yaml](configs/evals/vitl16_in1k.yaml), type the command: ```bash python -m evals.main \ - --fname configs/eval/vitl16_in1k.yaml \ + --fname configs/evals/vitl16_in1k.yaml \ --devices cuda:0 cuda:1 cuda:2 ``` ### Distributed training -To launch a distributed evaluation run, the implementation starts from [eval/main_distributed.py](eval/main_distributed.py), which, in addition to parsing the config file, also allows for specifying details about distributed training. For distributed training, we use the popular open-source [submitit](https://github.com/facebookincubator/submitit) tool and provide examples for a SLURM cluster. +To launch a distributed evaluation run, the implementation starts from [evals/main_distributed.py](evals/main_distributed.py), which, in addition to parsing the config file, also allows for specifying details about distributed training. For distributed training, we use the popular open-source [submitit](https://github.com/facebookincubator/submitit) tool and provide examples for a SLURM cluster. -For example, to launch a distributed ImageNet image classification experiment using the config [configs/eval/vitl16_in1k.yaml](configs/eval/vitl16_in1k.yaml), type the command: +For example, to launch a distributed ImageNet image classification experiment using the config [configs/evals/vitl16_in1k.yaml](configs/evals/vitl16_in1k.yaml), type the command: ```bash python -m evals.main_distributed \ - --fname configs/eval/vitl16_in1k.yaml \ + --fname configs/evals/vitl16_in1k.yaml \ --folder $path_to_save_stderr_and_stdout \ --partition $slurm_partition ``` -Similarly, to launch a distributed K400 video classification experiment using the config [configs/eval/vitl16_k400.yaml](configs/eval/vitl16_k400.yaml), type the command: +Similarly, to launch a distributed K400 video classification experiment using the config [configs/evals/vitl16_k400.yaml](configs/evals/vitl16_k400.yaml), type the command: ```bash python -m evals.main_distributed \ - --fname configs/eval/vitl16_k400.yaml \ + --fname configs/evals/vitl16_k400_16x8x3.yaml \ --folder $path_to_save_stderr_and_stdout \ --partition $slurm_partition ``` From d545b7b19b43ab82a09c6170bef9a013030fa1b7 Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Fri, 8 Mar 2024 13:59:43 -0500 Subject: [PATCH 003/131] fix README typos evals/ and k400 yaml filename --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6bc3a92d..a054f7dd 100644 --- a/README.md +++ b/README.md @@ -374,7 +374,7 @@ python -m evals.main_distributed \ --partition $slurm_partition ``` -Similarly, to launch a distributed K400 video classification experiment using the config [configs/evals/vitl16_k400.yaml](configs/evals/vitl16_k400.yaml), type the command: +Similarly, to launch a distributed K400 video classification experiment using the config [configs/evals/vitl16_k400_16x8x3.yaml](configs/evals/vitl16_k400_16x8x3.yaml), type the command: ```bash python -m evals.main_distributed \ --fname configs/evals/vitl16_k400_16x8x3.yaml \ From 1b3392a5bc84d6ca376ab1f80d810a22d1e4c2ca Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Mon, 11 Mar 2024 13:13:56 -0400 Subject: [PATCH 004/131] added jepa. in from jepa.evals.scaffold --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 1f332a0b..fbee1587 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -15,7 +15,7 @@ import submitit -from evals.scaffold import main as eval_main +from jepa.evals.scaffold import main as eval_main logging.basicConfig(stream=sys.stdout, level=logging.INFO) logger = logging.getLogger() From df85d19c4fe797d855337cd9365d8c32eab9652f Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Thu, 28 Mar 2024 17:41:44 -0400 Subject: [PATCH 005/131] updated vitl16_k400 yaml and main_distributed files --- configs/evals/vitl16_k400_16x8x3.yaml | 8 ++++---- evals/main_distributed.py | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index b7bcf052..b680abbd 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -1,5 +1,5 @@ -nodes: 8 -tasks_per_node: 8 +nodes: 1 +tasks_per_node: 1 tag: k400-16x8x3 eval_name: video_classification_frozen resume_checkpoint: false @@ -34,6 +34,6 @@ pretrain: tight_silu: false use_sdpa: true patch_size: 16 - folder: /your_absolute_file_path_to_directory_where_pretrained_models_are_contained/ - checkpoint: jepa-latest.pth.tar # name of pretrained model file inside folder + folder: /scratch/ki2130/ #/your_absolute_file_path_to_directory_where_pretrained_models_are_contained/ + checkpoint: vith16.pth.tar #jepa-latest.pth.tar # name of pretrained model file inside folder write_tag: jepa diff --git a/evals/main_distributed.py b/evals/main_distributed.py index fbee1587..5cdb1870 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -15,7 +15,7 @@ import submitit -from jepa.evals.scaffold import main as eval_main +from evals.scaffold import main as eval_main logging.basicConfig(stream=sys.stdout, level=logging.INFO) logger = logging.getLogger() @@ -91,12 +91,19 @@ def launch_evals_with_parsed_args( slurm_max_num_timeout=20) executor.update_parameters( slurm_partition=partition, - slurm_mem_per_gpu='55G', + mem='55G', timeout_min=timeout, nodes=nodes, tasks_per_node=tasks_per_node, - cpus_per_task=12, - gpus_per_node=tasks_per_node) + cpus_per_task=8, + gpus_per_node=tasks_per_node, + setup = ["module purge", + "module load anaconda3/2020.07", + "export OMP_NUM_THREADS=1", + "source /share/apps/anaconda3/2020.07/etc/profile.d/conda.sh", + "conda activate ./env-jepa", + "export PATH=./env-jepa/bin:$PATH", + "mkdir /scratch/ki2130/peanut_butter"]) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) @@ -160,3 +167,5 @@ def launch_evals(): if __name__ == '__main__': args = parser.parse_args() launch_evals() + print("made it!") + From 14f22a1c3f90d7652ffed580c93b02a46080db5c Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Fri, 29 Mar 2024 18:18:30 -0400 Subject: [PATCH 006/131] edited config data paths and main_distributed parameters for child job --- configs/evals/vitl16_k400_16x8x3.yaml | 6 +++--- evals/main_distributed.py | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index b680abbd..b0cf1730 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -4,8 +4,8 @@ tag: k400-16x8x3 eval_name: video_classification_frozen resume_checkpoint: false data: - dataset_train: /your_path_to_kinetics400_train_csv_file_index.csv - dataset_val: /your_path_to_kinetics400_val_csv_file_index.csv + dataset_train: /scratch/ki2130/my-jepa/jepa/mini_train.csv + dataset_val: /scratch/ki2130/my-jepa/jepa/mini_test.csv dataset_type: VideoDataset num_classes: 400 frames_per_clip: 16 @@ -35,5 +35,5 @@ pretrain: use_sdpa: true patch_size: 16 folder: /scratch/ki2130/ #/your_absolute_file_path_to_directory_where_pretrained_models_are_contained/ - checkpoint: vith16.pth.tar #jepa-latest.pth.tar # name of pretrained model file inside folder + checkpoint: vitl16.pth.tar #jepa-latest.pth.tar # name of pretrained model file inside folder write_tag: jepa diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 5cdb1870..386eb51e 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -91,19 +91,15 @@ def launch_evals_with_parsed_args( slurm_max_num_timeout=20) executor.update_parameters( slurm_partition=partition, - mem='55G', + slurm_mem='55G', timeout_min=timeout, nodes=nodes, tasks_per_node=tasks_per_node, cpus_per_task=8, gpus_per_node=tasks_per_node, - setup = ["module purge", - "module load anaconda3/2020.07", - "export OMP_NUM_THREADS=1", - "source /share/apps/anaconda3/2020.07/etc/profile.d/conda.sh", - "conda activate ./env-jepa", - "export PATH=./env-jepa/bin:$PATH", - "mkdir /scratch/ki2130/peanut_butter"]) + slurm_mail_type='ALL', + slurm_mail_user='ki2130@nyu.edu', + slurm_job_name='child-video-jepa2') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From f0bbbdf790ed87e882f9313f96c82f1e081613c2 Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Thu, 4 Apr 2024 14:53:31 -0400 Subject: [PATCH 007/131] add files --- configs/evals/vitl16_k400_16x8x3.yaml | 6 +- .../video_classification_frozen/eval_pegs.py | 561 ++++++++++++++++++ src/models/pegs_attentive_probe.py | 136 +++++ 3 files changed, 700 insertions(+), 3 deletions(-) create mode 100644 evals/video_classification_frozen/eval_pegs.py create mode 100644 src/models/pegs_attentive_probe.py diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index b0cf1730..60288eaf 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -4,8 +4,8 @@ tag: k400-16x8x3 eval_name: video_classification_frozen resume_checkpoint: false data: - dataset_train: /scratch/ki2130/my-jepa/jepa/mini_train.csv - dataset_val: /scratch/ki2130/my-jepa/jepa/mini_test.csv + dataset_train: /scratch/ki2130/my-jepa/jepa/p_mini_train.csv + dataset_val: /scratch/ki2130/my-jepa/jepa/p_mini_test.csv dataset_type: VideoDataset num_classes: 400 frames_per_clip: 16 @@ -14,7 +14,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 20 + num_epochs: 3 resolution: 224 batch_size: 4 weight_decay: 0.01 diff --git a/evals/video_classification_frozen/eval_pegs.py b/evals/video_classification_frozen/eval_pegs.py new file mode 100644 index 00000000..f81f526d --- /dev/null +++ b/evals/video_classification_frozen/eval_pegs.py @@ -0,0 +1,561 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# + +import os + +# -- FOR DISTRIBUTED TRAINING ENSURE ONLY 1 DEVICE VISIBLE PER PROCESS +try: + # -- WARNING: IF DOING DISTRIBUTED TRAINING ON A NON-SLURM CLUSTER, MAKE + # -- SURE TO UPDATE THIS TO GET LOCAL-RANK ON NODE, OR ENSURE + # -- THAT YOUR JOBS ARE LAUNCHED WITH ONLY 1 DEVICE VISIBLE + # -- TO EACH PROCESS + os.environ['CUDA_VISIBLE_DEVICES'] = os.environ['SLURM_LOCALID'] +except Exception: + pass + +import logging +import pprint + +import numpy as np + +import torch +import torch.multiprocessing as mp +import torch.nn.functional as F + +from torch.nn.parallel import DistributedDataParallel + +import src.models.vision_transformer as vit +from src.models.attentive_pooler import AttentiveClassifier +from src.datasets.data_manager import ( + init_data, +) +from src.utils.distributed import ( + init_distributed, + AllReduce +) +from src.utils.schedulers import ( + WarmupCosineSchedule, + CosineWDSchedule, +) +from src.utils.logging import ( + AverageMeter, + CSVLogger +) + +from evals.video_classification_frozen.utils import ( + make_transforms, + ClipAggregation, + FrameAggregation +) + +logging.basicConfig() +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +_GLOBAL_SEED = 0 +np.random.seed(_GLOBAL_SEED) +torch.manual_seed(_GLOBAL_SEED) +torch.backends.cudnn.benchmark = True + +pp = pprint.PrettyPrinter(indent=4) + + +def main(args_eval, resume_preempt=False): + + # ----------------------------------------------------------------------- # + # PASSED IN PARAMS FROM CONFIG FILE + # ----------------------------------------------------------------------- # + + # -- PRETRAIN + args_pretrain = args_eval.get('pretrain') + checkpoint_key = args_pretrain.get('checkpoint_key', 'target_encoder') + model_name = args_pretrain.get('model_name', None) + patch_size = args_pretrain.get('patch_size', None) + pretrain_folder = args_pretrain.get('folder', None) + ckp_fname = args_pretrain.get('checkpoint', None) + tag = args_pretrain.get('write_tag', None) + use_sdpa = args_pretrain.get('use_sdpa', True) + use_SiLU = args_pretrain.get('use_silu', False) + tight_SiLU = args_pretrain.get('tight_silu', True) + uniform_power = args_pretrain.get('uniform_power', False) + pretrained_path = os.path.join(pretrain_folder, ckp_fname) + # Optional [for Video model]: + tubelet_size = args_pretrain.get('tubelet_size', 2) + pretrain_frames_per_clip = args_pretrain.get('frames_per_clip', 1) + + # -- DATA + args_data = args_eval.get('data') + train_data_path = [args_data.get('dataset_train')] + val_data_path = [args_data.get('dataset_val')] + dataset_type = args_data.get('dataset_type', 'VideoDataset') + num_classes = args_data.get('num_classes') + eval_num_segments = args_data.get('num_segments', 1) + eval_frames_per_clip = args_data.get('frames_per_clip', 16) + eval_frame_step = args_pretrain.get('frame_step', 4) + eval_duration = args_pretrain.get('clip_duration', None) + eval_num_views_per_segment = args_data.get('num_views_per_segment', 1) + + # -- OPTIMIZATION + args_opt = args_eval.get('optimization') + resolution = args_opt.get('resolution', 224) + batch_size = args_opt.get('batch_size') + attend_across_segments = args_opt.get('attend_across_segments', False) + num_epochs = args_opt.get('num_epochs') + wd = args_opt.get('weight_decay') + start_lr = args_opt.get('start_lr') + lr = args_opt.get('lr') + final_lr = args_opt.get('final_lr') + warmup = args_opt.get('warmup') + use_bfloat16 = args_opt.get('use_bfloat16') + + # -- EXPERIMENT-ID/TAG (optional) + resume_checkpoint = args_eval.get('resume_checkpoint', False) or resume_preempt + eval_tag = args_eval.get('tag', None) + + # ----------------------------------------------------------------------- # + + try: + mp.set_start_method('spawn') + except Exception: + pass + + if not torch.cuda.is_available(): + device = torch.device('cpu') + else: + device = torch.device('cuda:0') + torch.cuda.set_device(device) + + world_size, rank = init_distributed() + logger.info(f'Initialized (rank/world-size) {rank}/{world_size}') + + # -- log/checkpointing paths + folder = os.path.join(pretrain_folder, 'video_classification_frozen/') + if eval_tag is not None: + folder = os.path.join(folder, eval_tag) + if not os.path.exists(folder): + os.makedirs(folder, exist_ok=True) + log_file = os.path.join(folder, f'{tag}_r{rank}.csv') + latest_path = os.path.join(folder, f'{tag}-latest.pth.tar') + + # -- make csv_logger + if rank == 0: + csv_logger = CSVLogger(log_file, + ('%d', 'epoch'), + ('%.5f', 'loss'), + ('%.5f', 'acc')) + + # Initialize model + + # -- pretrained encoder (frozen) + encoder = init_model( + crop_size=resolution, + device=device, + pretrained=pretrained_path, + model_name=model_name, + patch_size=patch_size, + tubelet_size=tubelet_size, + frames_per_clip=pretrain_frames_per_clip, + uniform_power=uniform_power, + checkpoint_key=checkpoint_key, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + use_sdpa=use_sdpa) + if pretrain_frames_per_clip == 1: + # Process each frame independently and aggregate + encoder = FrameAggregation(encoder).to(device) + else: + # Process each video clip independently and aggregate + encoder = ClipAggregation( + encoder, + tubelet_size=tubelet_size, + attend_across_segments=attend_across_segments + ).to(device) + encoder.eval() + for p in encoder.parameters(): + p.requires_grad = False + + # -- init classifier + classifier = AttentiveClassifier( + embed_dim=encoder.embed_dim, + num_heads=encoder.num_heads, + depth=1, + num_classes=num_classes, + ).to(device) + + train_loader = make_dataloader( + dataset_type=dataset_type, + root_path=train_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + eval_duration=eval_duration, + num_segments=eval_num_segments if attend_across_segments else 1, + num_views_per_segment=1, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=True) + val_loader = make_dataloader( + dataset_type=dataset_type, + root_path=val_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + num_segments=eval_num_segments, + eval_duration=eval_duration, + num_views_per_segment=eval_num_views_per_segment, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=False) + ipe = len(train_loader) + logger.info(f'Dataloader created... iterations per epoch: {ipe}') + + # -- optimizer and scheduler + optimizer, scaler, scheduler, wd_scheduler = init_opt( + classifier=classifier, + wd=wd, + start_lr=start_lr, + ref_lr=lr, + final_lr=final_lr, + iterations_per_epoch=ipe, + warmup=warmup, + num_epochs=num_epochs, + use_bfloat16=use_bfloat16) + classifier = DistributedDataParallel(classifier, static_graph=True) + + # -- load training checkpoint + start_epoch = 0 + if resume_checkpoint: + classifier, optimizer, scaler, start_epoch = load_checkpoint( + device=device, + r_path=latest_path, + classifier=classifier, + opt=optimizer, + scaler=scaler) + for _ in range(start_epoch*ipe): + scheduler.step() + wd_scheduler.step() + + def save_checkpoint(epoch): + save_dict = { + 'classifier': classifier.state_dict(), + 'opt': optimizer.state_dict(), + 'scaler': None if scaler is None else scaler.state_dict(), + 'epoch': epoch, + 'batch_size': batch_size, + 'world_size': world_size, + 'lr': lr + } + if rank == 0: + torch.save(save_dict, latest_path) + + # TRAIN LOOP + for epoch in range(start_epoch, num_epochs): + logger.info('Epoch %d' % (epoch + 1)) + train_acc = run_one_epoch( + device=device, + training=True, + num_temporal_views=eval_num_segments if attend_across_segments else 1, + attend_across_segments=attend_across_segments, + num_spatial_views=1, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=train_loader, + use_bfloat16=use_bfloat16) + + val_acc = run_one_epoch( + device=device, + training=False, + num_temporal_views=eval_num_segments, + attend_across_segments=attend_across_segments, + num_spatial_views=eval_num_views_per_segment, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=val_loader, + use_bfloat16=use_bfloat16) + + logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) + if rank == 0: + csv_logger.log(epoch + 1, train_acc, val_acc) + save_checkpoint(epoch + 1) + + +def run_one_epoch( + device, + training, + encoder, + classifier, + scaler, + optimizer, + scheduler, + wd_scheduler, + data_loader, + use_bfloat16, + num_spatial_views, + num_temporal_views, + attend_across_segments, +): + + classifier.train(mode=training) + criterion = torch.nn.CrossEntropyLoss() + top1_meter = AverageMeter() + for itr, data in enumerate(data_loader): + + if training: + scheduler.step() + wd_scheduler.step() + + with torch.cuda.amp.autocast(dtype=torch.float16, enabled=use_bfloat16): + + # Load data and put on GPU + clips = [ + [dij.to(device, non_blocking=True) for dij in di] # iterate over spatial views of clip + for di in data[0] # iterate over temporal index of clip + ] + clip_indices = [d.to(device, non_blocking=True) for d in data[2]] + labels = data[1].to(device) + batch_size = len(labels) + + # Forward and prediction + with torch.no_grad(): + outputs = encoder(clips, clip_indices) + if not training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + if training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + + # Compute loss + if attend_across_segments: + loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) + else: + loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + with torch.no_grad(): + if attend_across_segments: + outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) + else: + outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size + top1_acc = float(AllReduce.apply(top1_acc)) + top1_meter.update(top1_acc) + + if training: + if use_bfloat16: + scaler.scale(loss).backward() + scaler.unscale_(optimizer) + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + scaler.step(optimizer) + scaler.update() + else: + loss.backward() + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + optimizer.step() + optimizer.zero_grad() + + if itr % 20 == 0: + logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + % (itr, top1_meter.avg, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + + return top1_meter.avg + + +def load_checkpoint( + device, + r_path, + classifier, + opt, + scaler +): + try: + checkpoint = torch.load(r_path, map_location=torch.device('cpu')) + epoch = checkpoint['epoch'] + + # -- loading encoder + pretrained_dict = checkpoint['classifier'] + msg = classifier.load_state_dict(pretrained_dict) + logger.info(f'loaded pretrained classifier from epoch {epoch} with msg: {msg}') + + # -- loading optimizer + opt.load_state_dict(checkpoint['opt']) + if scaler is not None: + scaler.load_state_dict(checkpoint['scaler']) + logger.info(f'loaded optimizers from epoch {epoch}') + logger.info(f'read-path: {r_path}') + del checkpoint + + except Exception as e: + logger.info(f'Encountered exception when loading checkpoint {e}') + epoch = 0 + + return classifier, opt, scaler, epoch + + +def load_pretrained( + encoder, + pretrained, + checkpoint_key='target_encoder' +): + logger.info(f'Loading pretrained model from {pretrained}') + checkpoint = torch.load(pretrained, map_location='cpu') + try: + pretrained_dict = checkpoint[checkpoint_key] + except Exception: + pretrained_dict = checkpoint['encoder'] + + pretrained_dict = {k.replace('module.', ''): v for k, v in pretrained_dict.items()} + pretrained_dict = {k.replace('backbone.', ''): v for k, v in pretrained_dict.items()} + for k, v in encoder.state_dict().items(): + if k not in pretrained_dict: + logger.info(f'key "{k}" could not be found in loaded state dict') + elif pretrained_dict[k].shape != v.shape: + logger.info(f'key "{k}" is of different shape in model and loaded state dict') + pretrained_dict[k] = v + msg = encoder.load_state_dict(pretrained_dict, strict=False) + print(encoder) + logger.info(f'loaded pretrained model with msg: {msg}') + logger.info(f'loaded pretrained encoder from epoch: {checkpoint["epoch"]}\n path: {pretrained}') + del checkpoint + return encoder + + +def make_dataloader( + root_path, + batch_size, + world_size, + rank, + dataset_type='VideoDataset', + resolution=224, + frames_per_clip=16, + frame_step=4, + num_segments=8, + eval_duration=None, + num_views_per_segment=1, + allow_segment_overlap=True, + training=False, + num_workers=12, + subset_file=None +): + # Make Video Transforms + transform = make_transforms( + training=training, + num_views_per_clip=num_views_per_segment, + random_horizontal_flip=False, + random_resize_aspect_ratio=(0.75, 4/3), + random_resize_scale=(0.08, 1.0), + reprob=0.25, + auto_augment=True, + motion_shift=False, + crop_size=resolution, + ) + + data_loader, _ = init_data( + data=dataset_type, + root_path=root_path, + transform=transform, + batch_size=batch_size, + world_size=world_size, + rank=rank, + clip_len=frames_per_clip, + frame_sample_rate=frame_step, + duration=eval_duration, + num_clips=num_segments, + allow_clip_overlap=allow_segment_overlap, + num_workers=num_workers, + copy_data=False, + drop_last=False, + subset_file=subset_file) + return data_loader + + +def init_model( + device, + pretrained, + model_name, + patch_size=16, + crop_size=224, + # Video specific parameters + frames_per_clip=16, + tubelet_size=2, + use_sdpa=False, + use_SiLU=False, + tight_SiLU=True, + uniform_power=False, + checkpoint_key='target_encoder' +): + encoder = vit.__dict__[model_name]( + img_size=crop_size, + patch_size=patch_size, + num_frames=frames_per_clip, + tubelet_size=tubelet_size, + uniform_power=uniform_power, + use_sdpa=use_sdpa, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + ) + + encoder.to(device) + encoder = load_pretrained(encoder=encoder, pretrained=pretrained, checkpoint_key=checkpoint_key) + return encoder + + +def init_opt( + classifier, + iterations_per_epoch, + start_lr, + ref_lr, + warmup, + num_epochs, + wd=1e-6, + final_wd=1e-6, + final_lr=0.0, + use_bfloat16=False +): + param_groups = [ + { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' not in n) and (len(p.shape) != 1)) + }, { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' in n) or (len(p.shape) == 1)), + 'WD_exclude': True, + 'weight_decay': 0 + } + ] + + logger.info('Using AdamW') + optimizer = torch.optim.AdamW(param_groups) + scheduler = WarmupCosineSchedule( + optimizer, + warmup_steps=int(warmup*iterations_per_epoch), + start_lr=start_lr, + ref_lr=ref_lr, + final_lr=final_lr, + T_max=int(num_epochs*iterations_per_epoch)) + wd_scheduler = CosineWDSchedule( + optimizer, + ref_wd=wd, + final_wd=final_wd, + T_max=int(num_epochs*iterations_per_epoch)) + scaler = torch.cuda.amp.GradScaler() if use_bfloat16 else None + return optimizer, scaler, scheduler, wd_scheduler diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py new file mode 100644 index 00000000..ecd9986a --- /dev/null +++ b/src/models/pegs_attentive_probe.py @@ -0,0 +1,136 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# + +import math + +import torch +import torch.nn as nn + +from src.models.utils.modules import ( + Block, + CrossAttention, + CrossAttentionBlock +) +from src.utils.tensors import trunc_normal_ + + +class AttentivePooler(nn.Module): + """ Attentive Pooler """ + def __init__( + self, + num_queries=1, + embed_dim=768, + num_heads=12, + mlp_ratio=4.0, + depth=1, + norm_layer=nn.LayerNorm, + init_std=0.02, + qkv_bias=True, + complete_block=True + ): + super().__init__() + self.query_tokens = nn.Parameter(torch.zeros(1, num_queries, embed_dim)) + + self.complete_block = complete_block + if complete_block: + self.cross_attention_block = CrossAttentionBlock( + dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + norm_layer=norm_layer) + else: + self.cross_attention_block = CrossAttention( + dim=embed_dim, + num_heads=num_heads, + qkv_bias=qkv_bias) + + self.blocks = None + if depth > 1: + self.blocks = nn.ModuleList([ + Block( + dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=False, + norm_layer=norm_layer) + for i in range(depth-1)]) + + self.init_std = init_std + trunc_normal_(self.query_tokens, std=self.init_std) + self.apply(self._init_weights) + self._rescale_blocks() + + def _rescale_blocks(self): + def rescale(param, layer_id): + param.div_(math.sqrt(2.0 * layer_id)) + + if self.complete_block: + rescale(self.cross_attention_block.xattn.proj.weight.data, 1) + rescale(self.cross_attention_block.mlp.fc2.weight.data, 1) + else: + rescale(self.cross_attention_block.proj.weight.data, 1) + if self.blocks is not None: + for layer_id, layer in enumerate(self.blocks, 1): + rescale(layer.attn.proj.weight.data, layer_id + 1) + rescale(layer.mlp.fc2.weight.data, layer_id + 1) + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=self.init_std) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + elif isinstance(m, nn.Conv2d): + trunc_normal_(m.weight, std=self.init_std) + if m.bias is not None: + nn.init.constant_(m.bias, 0) + + def forward(self, x): + q = self.query_tokens.repeat(len(x), 1, 1) + q = self.cross_attention_block(q, x) + if self.blocks is not None: + for blk in self.blocks: + q = blk(q) + return q + + +class AttentiveClassifier(nn.Module): + """ Attentive Classifier """ + def __init__( + self, + embed_dim=768, + num_heads=12, + mlp_ratio=4.0, + depth=1, + norm_layer=nn.LayerNorm, + init_std=0.02, + qkv_bias=True, + num_classes=1000, + complete_block=True, + ): + super().__init__() + self.pooler = AttentivePooler( + num_queries=1, + embed_dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + depth=depth, + norm_layer=norm_layer, + init_std=init_std, + qkv_bias=qkv_bias, + complete_block=complete_block, + ) + self.linear = nn.Linear(embed_dim, num_classes, bias=True) + + def forward(self, x): + x = self.pooler(x).squeeze(1) + x = self.linear(x) + return x From a9f0ba27d2a7dc6353f1ff0579a76ff762ae66db Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Thu, 4 Apr 2024 15:05:42 -0400 Subject: [PATCH 008/131] add files modified --- .../video_classification_frozen/pegs_eval.py | 561 ++++++++++++++++++ src/models/pegs_attentive_probe.py | 8 +- 2 files changed, 565 insertions(+), 4 deletions(-) create mode 100644 evals/video_classification_frozen/pegs_eval.py diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py new file mode 100644 index 00000000..f81f526d --- /dev/null +++ b/evals/video_classification_frozen/pegs_eval.py @@ -0,0 +1,561 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# + +import os + +# -- FOR DISTRIBUTED TRAINING ENSURE ONLY 1 DEVICE VISIBLE PER PROCESS +try: + # -- WARNING: IF DOING DISTRIBUTED TRAINING ON A NON-SLURM CLUSTER, MAKE + # -- SURE TO UPDATE THIS TO GET LOCAL-RANK ON NODE, OR ENSURE + # -- THAT YOUR JOBS ARE LAUNCHED WITH ONLY 1 DEVICE VISIBLE + # -- TO EACH PROCESS + os.environ['CUDA_VISIBLE_DEVICES'] = os.environ['SLURM_LOCALID'] +except Exception: + pass + +import logging +import pprint + +import numpy as np + +import torch +import torch.multiprocessing as mp +import torch.nn.functional as F + +from torch.nn.parallel import DistributedDataParallel + +import src.models.vision_transformer as vit +from src.models.attentive_pooler import AttentiveClassifier +from src.datasets.data_manager import ( + init_data, +) +from src.utils.distributed import ( + init_distributed, + AllReduce +) +from src.utils.schedulers import ( + WarmupCosineSchedule, + CosineWDSchedule, +) +from src.utils.logging import ( + AverageMeter, + CSVLogger +) + +from evals.video_classification_frozen.utils import ( + make_transforms, + ClipAggregation, + FrameAggregation +) + +logging.basicConfig() +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +_GLOBAL_SEED = 0 +np.random.seed(_GLOBAL_SEED) +torch.manual_seed(_GLOBAL_SEED) +torch.backends.cudnn.benchmark = True + +pp = pprint.PrettyPrinter(indent=4) + + +def main(args_eval, resume_preempt=False): + + # ----------------------------------------------------------------------- # + # PASSED IN PARAMS FROM CONFIG FILE + # ----------------------------------------------------------------------- # + + # -- PRETRAIN + args_pretrain = args_eval.get('pretrain') + checkpoint_key = args_pretrain.get('checkpoint_key', 'target_encoder') + model_name = args_pretrain.get('model_name', None) + patch_size = args_pretrain.get('patch_size', None) + pretrain_folder = args_pretrain.get('folder', None) + ckp_fname = args_pretrain.get('checkpoint', None) + tag = args_pretrain.get('write_tag', None) + use_sdpa = args_pretrain.get('use_sdpa', True) + use_SiLU = args_pretrain.get('use_silu', False) + tight_SiLU = args_pretrain.get('tight_silu', True) + uniform_power = args_pretrain.get('uniform_power', False) + pretrained_path = os.path.join(pretrain_folder, ckp_fname) + # Optional [for Video model]: + tubelet_size = args_pretrain.get('tubelet_size', 2) + pretrain_frames_per_clip = args_pretrain.get('frames_per_clip', 1) + + # -- DATA + args_data = args_eval.get('data') + train_data_path = [args_data.get('dataset_train')] + val_data_path = [args_data.get('dataset_val')] + dataset_type = args_data.get('dataset_type', 'VideoDataset') + num_classes = args_data.get('num_classes') + eval_num_segments = args_data.get('num_segments', 1) + eval_frames_per_clip = args_data.get('frames_per_clip', 16) + eval_frame_step = args_pretrain.get('frame_step', 4) + eval_duration = args_pretrain.get('clip_duration', None) + eval_num_views_per_segment = args_data.get('num_views_per_segment', 1) + + # -- OPTIMIZATION + args_opt = args_eval.get('optimization') + resolution = args_opt.get('resolution', 224) + batch_size = args_opt.get('batch_size') + attend_across_segments = args_opt.get('attend_across_segments', False) + num_epochs = args_opt.get('num_epochs') + wd = args_opt.get('weight_decay') + start_lr = args_opt.get('start_lr') + lr = args_opt.get('lr') + final_lr = args_opt.get('final_lr') + warmup = args_opt.get('warmup') + use_bfloat16 = args_opt.get('use_bfloat16') + + # -- EXPERIMENT-ID/TAG (optional) + resume_checkpoint = args_eval.get('resume_checkpoint', False) or resume_preempt + eval_tag = args_eval.get('tag', None) + + # ----------------------------------------------------------------------- # + + try: + mp.set_start_method('spawn') + except Exception: + pass + + if not torch.cuda.is_available(): + device = torch.device('cpu') + else: + device = torch.device('cuda:0') + torch.cuda.set_device(device) + + world_size, rank = init_distributed() + logger.info(f'Initialized (rank/world-size) {rank}/{world_size}') + + # -- log/checkpointing paths + folder = os.path.join(pretrain_folder, 'video_classification_frozen/') + if eval_tag is not None: + folder = os.path.join(folder, eval_tag) + if not os.path.exists(folder): + os.makedirs(folder, exist_ok=True) + log_file = os.path.join(folder, f'{tag}_r{rank}.csv') + latest_path = os.path.join(folder, f'{tag}-latest.pth.tar') + + # -- make csv_logger + if rank == 0: + csv_logger = CSVLogger(log_file, + ('%d', 'epoch'), + ('%.5f', 'loss'), + ('%.5f', 'acc')) + + # Initialize model + + # -- pretrained encoder (frozen) + encoder = init_model( + crop_size=resolution, + device=device, + pretrained=pretrained_path, + model_name=model_name, + patch_size=patch_size, + tubelet_size=tubelet_size, + frames_per_clip=pretrain_frames_per_clip, + uniform_power=uniform_power, + checkpoint_key=checkpoint_key, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + use_sdpa=use_sdpa) + if pretrain_frames_per_clip == 1: + # Process each frame independently and aggregate + encoder = FrameAggregation(encoder).to(device) + else: + # Process each video clip independently and aggregate + encoder = ClipAggregation( + encoder, + tubelet_size=tubelet_size, + attend_across_segments=attend_across_segments + ).to(device) + encoder.eval() + for p in encoder.parameters(): + p.requires_grad = False + + # -- init classifier + classifier = AttentiveClassifier( + embed_dim=encoder.embed_dim, + num_heads=encoder.num_heads, + depth=1, + num_classes=num_classes, + ).to(device) + + train_loader = make_dataloader( + dataset_type=dataset_type, + root_path=train_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + eval_duration=eval_duration, + num_segments=eval_num_segments if attend_across_segments else 1, + num_views_per_segment=1, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=True) + val_loader = make_dataloader( + dataset_type=dataset_type, + root_path=val_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + num_segments=eval_num_segments, + eval_duration=eval_duration, + num_views_per_segment=eval_num_views_per_segment, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=False) + ipe = len(train_loader) + logger.info(f'Dataloader created... iterations per epoch: {ipe}') + + # -- optimizer and scheduler + optimizer, scaler, scheduler, wd_scheduler = init_opt( + classifier=classifier, + wd=wd, + start_lr=start_lr, + ref_lr=lr, + final_lr=final_lr, + iterations_per_epoch=ipe, + warmup=warmup, + num_epochs=num_epochs, + use_bfloat16=use_bfloat16) + classifier = DistributedDataParallel(classifier, static_graph=True) + + # -- load training checkpoint + start_epoch = 0 + if resume_checkpoint: + classifier, optimizer, scaler, start_epoch = load_checkpoint( + device=device, + r_path=latest_path, + classifier=classifier, + opt=optimizer, + scaler=scaler) + for _ in range(start_epoch*ipe): + scheduler.step() + wd_scheduler.step() + + def save_checkpoint(epoch): + save_dict = { + 'classifier': classifier.state_dict(), + 'opt': optimizer.state_dict(), + 'scaler': None if scaler is None else scaler.state_dict(), + 'epoch': epoch, + 'batch_size': batch_size, + 'world_size': world_size, + 'lr': lr + } + if rank == 0: + torch.save(save_dict, latest_path) + + # TRAIN LOOP + for epoch in range(start_epoch, num_epochs): + logger.info('Epoch %d' % (epoch + 1)) + train_acc = run_one_epoch( + device=device, + training=True, + num_temporal_views=eval_num_segments if attend_across_segments else 1, + attend_across_segments=attend_across_segments, + num_spatial_views=1, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=train_loader, + use_bfloat16=use_bfloat16) + + val_acc = run_one_epoch( + device=device, + training=False, + num_temporal_views=eval_num_segments, + attend_across_segments=attend_across_segments, + num_spatial_views=eval_num_views_per_segment, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=val_loader, + use_bfloat16=use_bfloat16) + + logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) + if rank == 0: + csv_logger.log(epoch + 1, train_acc, val_acc) + save_checkpoint(epoch + 1) + + +def run_one_epoch( + device, + training, + encoder, + classifier, + scaler, + optimizer, + scheduler, + wd_scheduler, + data_loader, + use_bfloat16, + num_spatial_views, + num_temporal_views, + attend_across_segments, +): + + classifier.train(mode=training) + criterion = torch.nn.CrossEntropyLoss() + top1_meter = AverageMeter() + for itr, data in enumerate(data_loader): + + if training: + scheduler.step() + wd_scheduler.step() + + with torch.cuda.amp.autocast(dtype=torch.float16, enabled=use_bfloat16): + + # Load data and put on GPU + clips = [ + [dij.to(device, non_blocking=True) for dij in di] # iterate over spatial views of clip + for di in data[0] # iterate over temporal index of clip + ] + clip_indices = [d.to(device, non_blocking=True) for d in data[2]] + labels = data[1].to(device) + batch_size = len(labels) + + # Forward and prediction + with torch.no_grad(): + outputs = encoder(clips, clip_indices) + if not training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + if training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + + # Compute loss + if attend_across_segments: + loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) + else: + loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + with torch.no_grad(): + if attend_across_segments: + outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) + else: + outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size + top1_acc = float(AllReduce.apply(top1_acc)) + top1_meter.update(top1_acc) + + if training: + if use_bfloat16: + scaler.scale(loss).backward() + scaler.unscale_(optimizer) + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + scaler.step(optimizer) + scaler.update() + else: + loss.backward() + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + optimizer.step() + optimizer.zero_grad() + + if itr % 20 == 0: + logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + % (itr, top1_meter.avg, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + + return top1_meter.avg + + +def load_checkpoint( + device, + r_path, + classifier, + opt, + scaler +): + try: + checkpoint = torch.load(r_path, map_location=torch.device('cpu')) + epoch = checkpoint['epoch'] + + # -- loading encoder + pretrained_dict = checkpoint['classifier'] + msg = classifier.load_state_dict(pretrained_dict) + logger.info(f'loaded pretrained classifier from epoch {epoch} with msg: {msg}') + + # -- loading optimizer + opt.load_state_dict(checkpoint['opt']) + if scaler is not None: + scaler.load_state_dict(checkpoint['scaler']) + logger.info(f'loaded optimizers from epoch {epoch}') + logger.info(f'read-path: {r_path}') + del checkpoint + + except Exception as e: + logger.info(f'Encountered exception when loading checkpoint {e}') + epoch = 0 + + return classifier, opt, scaler, epoch + + +def load_pretrained( + encoder, + pretrained, + checkpoint_key='target_encoder' +): + logger.info(f'Loading pretrained model from {pretrained}') + checkpoint = torch.load(pretrained, map_location='cpu') + try: + pretrained_dict = checkpoint[checkpoint_key] + except Exception: + pretrained_dict = checkpoint['encoder'] + + pretrained_dict = {k.replace('module.', ''): v for k, v in pretrained_dict.items()} + pretrained_dict = {k.replace('backbone.', ''): v for k, v in pretrained_dict.items()} + for k, v in encoder.state_dict().items(): + if k not in pretrained_dict: + logger.info(f'key "{k}" could not be found in loaded state dict') + elif pretrained_dict[k].shape != v.shape: + logger.info(f'key "{k}" is of different shape in model and loaded state dict') + pretrained_dict[k] = v + msg = encoder.load_state_dict(pretrained_dict, strict=False) + print(encoder) + logger.info(f'loaded pretrained model with msg: {msg}') + logger.info(f'loaded pretrained encoder from epoch: {checkpoint["epoch"]}\n path: {pretrained}') + del checkpoint + return encoder + + +def make_dataloader( + root_path, + batch_size, + world_size, + rank, + dataset_type='VideoDataset', + resolution=224, + frames_per_clip=16, + frame_step=4, + num_segments=8, + eval_duration=None, + num_views_per_segment=1, + allow_segment_overlap=True, + training=False, + num_workers=12, + subset_file=None +): + # Make Video Transforms + transform = make_transforms( + training=training, + num_views_per_clip=num_views_per_segment, + random_horizontal_flip=False, + random_resize_aspect_ratio=(0.75, 4/3), + random_resize_scale=(0.08, 1.0), + reprob=0.25, + auto_augment=True, + motion_shift=False, + crop_size=resolution, + ) + + data_loader, _ = init_data( + data=dataset_type, + root_path=root_path, + transform=transform, + batch_size=batch_size, + world_size=world_size, + rank=rank, + clip_len=frames_per_clip, + frame_sample_rate=frame_step, + duration=eval_duration, + num_clips=num_segments, + allow_clip_overlap=allow_segment_overlap, + num_workers=num_workers, + copy_data=False, + drop_last=False, + subset_file=subset_file) + return data_loader + + +def init_model( + device, + pretrained, + model_name, + patch_size=16, + crop_size=224, + # Video specific parameters + frames_per_clip=16, + tubelet_size=2, + use_sdpa=False, + use_SiLU=False, + tight_SiLU=True, + uniform_power=False, + checkpoint_key='target_encoder' +): + encoder = vit.__dict__[model_name]( + img_size=crop_size, + patch_size=patch_size, + num_frames=frames_per_clip, + tubelet_size=tubelet_size, + uniform_power=uniform_power, + use_sdpa=use_sdpa, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + ) + + encoder.to(device) + encoder = load_pretrained(encoder=encoder, pretrained=pretrained, checkpoint_key=checkpoint_key) + return encoder + + +def init_opt( + classifier, + iterations_per_epoch, + start_lr, + ref_lr, + warmup, + num_epochs, + wd=1e-6, + final_wd=1e-6, + final_lr=0.0, + use_bfloat16=False +): + param_groups = [ + { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' not in n) and (len(p.shape) != 1)) + }, { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' in n) or (len(p.shape) == 1)), + 'WD_exclude': True, + 'weight_decay': 0 + } + ] + + logger.info('Using AdamW') + optimizer = torch.optim.AdamW(param_groups) + scheduler = WarmupCosineSchedule( + optimizer, + warmup_steps=int(warmup*iterations_per_epoch), + start_lr=start_lr, + ref_lr=ref_lr, + final_lr=final_lr, + T_max=int(num_epochs*iterations_per_epoch)) + wd_scheduler = CosineWDSchedule( + optimizer, + ref_wd=wd, + final_wd=final_wd, + T_max=int(num_epochs*iterations_per_epoch)) + scaler = torch.cuda.amp.GradScaler() if use_bfloat16 else None + return optimizer, scaler, scheduler, wd_scheduler diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index ecd9986a..3f90ab27 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -18,7 +18,7 @@ from src.utils.tensors import trunc_normal_ -class AttentivePooler(nn.Module): +class PegAttentivePooler(nn.Module): """ Attentive Pooler """ def __init__( self, @@ -102,7 +102,7 @@ def forward(self, x): return q -class AttentiveClassifier(nn.Module): +class PegAttentiveClassifier(nn.Module): """ Attentive Classifier """ def __init__( self, @@ -113,11 +113,11 @@ def __init__( norm_layer=nn.LayerNorm, init_std=0.02, qkv_bias=True, - num_classes=1000, + num_classes=165, complete_block=True, ): super().__init__() - self.pooler = AttentivePooler( + self.pooler = PegAttentivePooler( num_queries=1, embed_dim=embed_dim, num_heads=num_heads, From afd3a0c754270ce5a2864cf0354448ee53240326 Mon Sep 17 00:00:00 2001 From: pclittle Date: Tue, 9 Apr 2024 12:02:30 -0400 Subject: [PATCH 009/131] test eval directory rather than csv --- .../video_classification_frozen/eval_pegs.py | 561 ------------------ src/datasets/video_dataset.py | 6 + 2 files changed, 6 insertions(+), 561 deletions(-) delete mode 100644 evals/video_classification_frozen/eval_pegs.py diff --git a/evals/video_classification_frozen/eval_pegs.py b/evals/video_classification_frozen/eval_pegs.py deleted file mode 100644 index f81f526d..00000000 --- a/evals/video_classification_frozen/eval_pegs.py +++ /dev/null @@ -1,561 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the license found in the -# LICENSE file in the root directory of this source tree. -# - -import os - -# -- FOR DISTRIBUTED TRAINING ENSURE ONLY 1 DEVICE VISIBLE PER PROCESS -try: - # -- WARNING: IF DOING DISTRIBUTED TRAINING ON A NON-SLURM CLUSTER, MAKE - # -- SURE TO UPDATE THIS TO GET LOCAL-RANK ON NODE, OR ENSURE - # -- THAT YOUR JOBS ARE LAUNCHED WITH ONLY 1 DEVICE VISIBLE - # -- TO EACH PROCESS - os.environ['CUDA_VISIBLE_DEVICES'] = os.environ['SLURM_LOCALID'] -except Exception: - pass - -import logging -import pprint - -import numpy as np - -import torch -import torch.multiprocessing as mp -import torch.nn.functional as F - -from torch.nn.parallel import DistributedDataParallel - -import src.models.vision_transformer as vit -from src.models.attentive_pooler import AttentiveClassifier -from src.datasets.data_manager import ( - init_data, -) -from src.utils.distributed import ( - init_distributed, - AllReduce -) -from src.utils.schedulers import ( - WarmupCosineSchedule, - CosineWDSchedule, -) -from src.utils.logging import ( - AverageMeter, - CSVLogger -) - -from evals.video_classification_frozen.utils import ( - make_transforms, - ClipAggregation, - FrameAggregation -) - -logging.basicConfig() -logger = logging.getLogger() -logger.setLevel(logging.INFO) - -_GLOBAL_SEED = 0 -np.random.seed(_GLOBAL_SEED) -torch.manual_seed(_GLOBAL_SEED) -torch.backends.cudnn.benchmark = True - -pp = pprint.PrettyPrinter(indent=4) - - -def main(args_eval, resume_preempt=False): - - # ----------------------------------------------------------------------- # - # PASSED IN PARAMS FROM CONFIG FILE - # ----------------------------------------------------------------------- # - - # -- PRETRAIN - args_pretrain = args_eval.get('pretrain') - checkpoint_key = args_pretrain.get('checkpoint_key', 'target_encoder') - model_name = args_pretrain.get('model_name', None) - patch_size = args_pretrain.get('patch_size', None) - pretrain_folder = args_pretrain.get('folder', None) - ckp_fname = args_pretrain.get('checkpoint', None) - tag = args_pretrain.get('write_tag', None) - use_sdpa = args_pretrain.get('use_sdpa', True) - use_SiLU = args_pretrain.get('use_silu', False) - tight_SiLU = args_pretrain.get('tight_silu', True) - uniform_power = args_pretrain.get('uniform_power', False) - pretrained_path = os.path.join(pretrain_folder, ckp_fname) - # Optional [for Video model]: - tubelet_size = args_pretrain.get('tubelet_size', 2) - pretrain_frames_per_clip = args_pretrain.get('frames_per_clip', 1) - - # -- DATA - args_data = args_eval.get('data') - train_data_path = [args_data.get('dataset_train')] - val_data_path = [args_data.get('dataset_val')] - dataset_type = args_data.get('dataset_type', 'VideoDataset') - num_classes = args_data.get('num_classes') - eval_num_segments = args_data.get('num_segments', 1) - eval_frames_per_clip = args_data.get('frames_per_clip', 16) - eval_frame_step = args_pretrain.get('frame_step', 4) - eval_duration = args_pretrain.get('clip_duration', None) - eval_num_views_per_segment = args_data.get('num_views_per_segment', 1) - - # -- OPTIMIZATION - args_opt = args_eval.get('optimization') - resolution = args_opt.get('resolution', 224) - batch_size = args_opt.get('batch_size') - attend_across_segments = args_opt.get('attend_across_segments', False) - num_epochs = args_opt.get('num_epochs') - wd = args_opt.get('weight_decay') - start_lr = args_opt.get('start_lr') - lr = args_opt.get('lr') - final_lr = args_opt.get('final_lr') - warmup = args_opt.get('warmup') - use_bfloat16 = args_opt.get('use_bfloat16') - - # -- EXPERIMENT-ID/TAG (optional) - resume_checkpoint = args_eval.get('resume_checkpoint', False) or resume_preempt - eval_tag = args_eval.get('tag', None) - - # ----------------------------------------------------------------------- # - - try: - mp.set_start_method('spawn') - except Exception: - pass - - if not torch.cuda.is_available(): - device = torch.device('cpu') - else: - device = torch.device('cuda:0') - torch.cuda.set_device(device) - - world_size, rank = init_distributed() - logger.info(f'Initialized (rank/world-size) {rank}/{world_size}') - - # -- log/checkpointing paths - folder = os.path.join(pretrain_folder, 'video_classification_frozen/') - if eval_tag is not None: - folder = os.path.join(folder, eval_tag) - if not os.path.exists(folder): - os.makedirs(folder, exist_ok=True) - log_file = os.path.join(folder, f'{tag}_r{rank}.csv') - latest_path = os.path.join(folder, f'{tag}-latest.pth.tar') - - # -- make csv_logger - if rank == 0: - csv_logger = CSVLogger(log_file, - ('%d', 'epoch'), - ('%.5f', 'loss'), - ('%.5f', 'acc')) - - # Initialize model - - # -- pretrained encoder (frozen) - encoder = init_model( - crop_size=resolution, - device=device, - pretrained=pretrained_path, - model_name=model_name, - patch_size=patch_size, - tubelet_size=tubelet_size, - frames_per_clip=pretrain_frames_per_clip, - uniform_power=uniform_power, - checkpoint_key=checkpoint_key, - use_SiLU=use_SiLU, - tight_SiLU=tight_SiLU, - use_sdpa=use_sdpa) - if pretrain_frames_per_clip == 1: - # Process each frame independently and aggregate - encoder = FrameAggregation(encoder).to(device) - else: - # Process each video clip independently and aggregate - encoder = ClipAggregation( - encoder, - tubelet_size=tubelet_size, - attend_across_segments=attend_across_segments - ).to(device) - encoder.eval() - for p in encoder.parameters(): - p.requires_grad = False - - # -- init classifier - classifier = AttentiveClassifier( - embed_dim=encoder.embed_dim, - num_heads=encoder.num_heads, - depth=1, - num_classes=num_classes, - ).to(device) - - train_loader = make_dataloader( - dataset_type=dataset_type, - root_path=train_data_path, - resolution=resolution, - frames_per_clip=eval_frames_per_clip, - frame_step=eval_frame_step, - eval_duration=eval_duration, - num_segments=eval_num_segments if attend_across_segments else 1, - num_views_per_segment=1, - allow_segment_overlap=True, - batch_size=batch_size, - world_size=world_size, - rank=rank, - training=True) - val_loader = make_dataloader( - dataset_type=dataset_type, - root_path=val_data_path, - resolution=resolution, - frames_per_clip=eval_frames_per_clip, - frame_step=eval_frame_step, - num_segments=eval_num_segments, - eval_duration=eval_duration, - num_views_per_segment=eval_num_views_per_segment, - allow_segment_overlap=True, - batch_size=batch_size, - world_size=world_size, - rank=rank, - training=False) - ipe = len(train_loader) - logger.info(f'Dataloader created... iterations per epoch: {ipe}') - - # -- optimizer and scheduler - optimizer, scaler, scheduler, wd_scheduler = init_opt( - classifier=classifier, - wd=wd, - start_lr=start_lr, - ref_lr=lr, - final_lr=final_lr, - iterations_per_epoch=ipe, - warmup=warmup, - num_epochs=num_epochs, - use_bfloat16=use_bfloat16) - classifier = DistributedDataParallel(classifier, static_graph=True) - - # -- load training checkpoint - start_epoch = 0 - if resume_checkpoint: - classifier, optimizer, scaler, start_epoch = load_checkpoint( - device=device, - r_path=latest_path, - classifier=classifier, - opt=optimizer, - scaler=scaler) - for _ in range(start_epoch*ipe): - scheduler.step() - wd_scheduler.step() - - def save_checkpoint(epoch): - save_dict = { - 'classifier': classifier.state_dict(), - 'opt': optimizer.state_dict(), - 'scaler': None if scaler is None else scaler.state_dict(), - 'epoch': epoch, - 'batch_size': batch_size, - 'world_size': world_size, - 'lr': lr - } - if rank == 0: - torch.save(save_dict, latest_path) - - # TRAIN LOOP - for epoch in range(start_epoch, num_epochs): - logger.info('Epoch %d' % (epoch + 1)) - train_acc = run_one_epoch( - device=device, - training=True, - num_temporal_views=eval_num_segments if attend_across_segments else 1, - attend_across_segments=attend_across_segments, - num_spatial_views=1, - encoder=encoder, - classifier=classifier, - scaler=scaler, - optimizer=optimizer, - scheduler=scheduler, - wd_scheduler=wd_scheduler, - data_loader=train_loader, - use_bfloat16=use_bfloat16) - - val_acc = run_one_epoch( - device=device, - training=False, - num_temporal_views=eval_num_segments, - attend_across_segments=attend_across_segments, - num_spatial_views=eval_num_views_per_segment, - encoder=encoder, - classifier=classifier, - scaler=scaler, - optimizer=optimizer, - scheduler=scheduler, - wd_scheduler=wd_scheduler, - data_loader=val_loader, - use_bfloat16=use_bfloat16) - - logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) - if rank == 0: - csv_logger.log(epoch + 1, train_acc, val_acc) - save_checkpoint(epoch + 1) - - -def run_one_epoch( - device, - training, - encoder, - classifier, - scaler, - optimizer, - scheduler, - wd_scheduler, - data_loader, - use_bfloat16, - num_spatial_views, - num_temporal_views, - attend_across_segments, -): - - classifier.train(mode=training) - criterion = torch.nn.CrossEntropyLoss() - top1_meter = AverageMeter() - for itr, data in enumerate(data_loader): - - if training: - scheduler.step() - wd_scheduler.step() - - with torch.cuda.amp.autocast(dtype=torch.float16, enabled=use_bfloat16): - - # Load data and put on GPU - clips = [ - [dij.to(device, non_blocking=True) for dij in di] # iterate over spatial views of clip - for di in data[0] # iterate over temporal index of clip - ] - clip_indices = [d.to(device, non_blocking=True) for d in data[2]] - labels = data[1].to(device) - batch_size = len(labels) - - # Forward and prediction - with torch.no_grad(): - outputs = encoder(clips, clip_indices) - if not training: - if attend_across_segments: - outputs = [classifier(o) for o in outputs] - else: - outputs = [[classifier(ost) for ost in os] for os in outputs] - if training: - if attend_across_segments: - outputs = [classifier(o) for o in outputs] - else: - outputs = [[classifier(ost) for ost in os] for os in outputs] - - # Compute loss - if attend_across_segments: - loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) - else: - loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - with torch.no_grad(): - if attend_across_segments: - outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) - else: - outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - top1_acc = float(AllReduce.apply(top1_acc)) - top1_meter.update(top1_acc) - - if training: - if use_bfloat16: - scaler.scale(loss).backward() - scaler.unscale_(optimizer) - torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) - scaler.step(optimizer) - scaler.update() - else: - loss.backward() - torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) - optimizer.step() - optimizer.zero_grad() - - if itr % 20 == 0: - logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - % (itr, top1_meter.avg, loss, - torch.cuda.max_memory_allocated() / 1024.**2)) - - return top1_meter.avg - - -def load_checkpoint( - device, - r_path, - classifier, - opt, - scaler -): - try: - checkpoint = torch.load(r_path, map_location=torch.device('cpu')) - epoch = checkpoint['epoch'] - - # -- loading encoder - pretrained_dict = checkpoint['classifier'] - msg = classifier.load_state_dict(pretrained_dict) - logger.info(f'loaded pretrained classifier from epoch {epoch} with msg: {msg}') - - # -- loading optimizer - opt.load_state_dict(checkpoint['opt']) - if scaler is not None: - scaler.load_state_dict(checkpoint['scaler']) - logger.info(f'loaded optimizers from epoch {epoch}') - logger.info(f'read-path: {r_path}') - del checkpoint - - except Exception as e: - logger.info(f'Encountered exception when loading checkpoint {e}') - epoch = 0 - - return classifier, opt, scaler, epoch - - -def load_pretrained( - encoder, - pretrained, - checkpoint_key='target_encoder' -): - logger.info(f'Loading pretrained model from {pretrained}') - checkpoint = torch.load(pretrained, map_location='cpu') - try: - pretrained_dict = checkpoint[checkpoint_key] - except Exception: - pretrained_dict = checkpoint['encoder'] - - pretrained_dict = {k.replace('module.', ''): v for k, v in pretrained_dict.items()} - pretrained_dict = {k.replace('backbone.', ''): v for k, v in pretrained_dict.items()} - for k, v in encoder.state_dict().items(): - if k not in pretrained_dict: - logger.info(f'key "{k}" could not be found in loaded state dict') - elif pretrained_dict[k].shape != v.shape: - logger.info(f'key "{k}" is of different shape in model and loaded state dict') - pretrained_dict[k] = v - msg = encoder.load_state_dict(pretrained_dict, strict=False) - print(encoder) - logger.info(f'loaded pretrained model with msg: {msg}') - logger.info(f'loaded pretrained encoder from epoch: {checkpoint["epoch"]}\n path: {pretrained}') - del checkpoint - return encoder - - -def make_dataloader( - root_path, - batch_size, - world_size, - rank, - dataset_type='VideoDataset', - resolution=224, - frames_per_clip=16, - frame_step=4, - num_segments=8, - eval_duration=None, - num_views_per_segment=1, - allow_segment_overlap=True, - training=False, - num_workers=12, - subset_file=None -): - # Make Video Transforms - transform = make_transforms( - training=training, - num_views_per_clip=num_views_per_segment, - random_horizontal_flip=False, - random_resize_aspect_ratio=(0.75, 4/3), - random_resize_scale=(0.08, 1.0), - reprob=0.25, - auto_augment=True, - motion_shift=False, - crop_size=resolution, - ) - - data_loader, _ = init_data( - data=dataset_type, - root_path=root_path, - transform=transform, - batch_size=batch_size, - world_size=world_size, - rank=rank, - clip_len=frames_per_clip, - frame_sample_rate=frame_step, - duration=eval_duration, - num_clips=num_segments, - allow_clip_overlap=allow_segment_overlap, - num_workers=num_workers, - copy_data=False, - drop_last=False, - subset_file=subset_file) - return data_loader - - -def init_model( - device, - pretrained, - model_name, - patch_size=16, - crop_size=224, - # Video specific parameters - frames_per_clip=16, - tubelet_size=2, - use_sdpa=False, - use_SiLU=False, - tight_SiLU=True, - uniform_power=False, - checkpoint_key='target_encoder' -): - encoder = vit.__dict__[model_name]( - img_size=crop_size, - patch_size=patch_size, - num_frames=frames_per_clip, - tubelet_size=tubelet_size, - uniform_power=uniform_power, - use_sdpa=use_sdpa, - use_SiLU=use_SiLU, - tight_SiLU=tight_SiLU, - ) - - encoder.to(device) - encoder = load_pretrained(encoder=encoder, pretrained=pretrained, checkpoint_key=checkpoint_key) - return encoder - - -def init_opt( - classifier, - iterations_per_epoch, - start_lr, - ref_lr, - warmup, - num_epochs, - wd=1e-6, - final_wd=1e-6, - final_lr=0.0, - use_bfloat16=False -): - param_groups = [ - { - 'params': (p for n, p in classifier.named_parameters() - if ('bias' not in n) and (len(p.shape) != 1)) - }, { - 'params': (p for n, p in classifier.named_parameters() - if ('bias' in n) or (len(p.shape) == 1)), - 'WD_exclude': True, - 'weight_decay': 0 - } - ] - - logger.info('Using AdamW') - optimizer = torch.optim.AdamW(param_groups) - scheduler = WarmupCosineSchedule( - optimizer, - warmup_steps=int(warmup*iterations_per_epoch), - start_lr=start_lr, - ref_lr=ref_lr, - final_lr=final_lr, - T_max=int(num_epochs*iterations_per_epoch)) - wd_scheduler = CosineWDSchedule( - optimizer, - ref_wd=wd, - final_wd=final_wd, - T_max=int(num_epochs*iterations_per_epoch)) - scaler = torch.cuda.amp.GradScaler() if use_bfloat16 else None - return optimizer, scaler, scheduler, wd_scheduler diff --git a/src/datasets/video_dataset.py b/src/datasets/video_dataset.py index b05cc701..bb5cff46 100644 --- a/src/datasets/video_dataset.py +++ b/src/datasets/video_dataset.py @@ -142,6 +142,12 @@ def __init__( num_samples = len(data) self.num_samples_per_dataset.append(len(data)) + elif data_path[-11:] == '_directory/': + samples = [file for file in os.listdir(data_path) if file.endswith('.mp4')] + labels = [np.load(file) for file in os.listdir(data_path) if file.endswith('.npy')] + num_samples = len(samples) + self.num_samples_per_dataset.append(num_samples) + # [Optional] Weights for each sample to be used by downstream # weighted video sampler self.sample_weights = None From e0a5ab8e8d29682507fa8f42141097c291234bec Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Thu, 11 Apr 2024 13:55:06 -0400 Subject: [PATCH 010/131] changes from 4-9-24 --- evals/scaffold.py | 2 +- .../video_classification_frozen/pegs_eval.py | 14 ++- src/models/pegs_attentive_probe.py | 115 +----------------- 3 files changed, 11 insertions(+), 120 deletions(-) diff --git a/evals/scaffold.py b/evals/scaffold.py index c816b874..b2f10404 100644 --- a/evals/scaffold.py +++ b/evals/scaffold.py @@ -19,6 +19,6 @@ def main( resume_preempt=False ): logger.info(f'Running evaluation: {eval_name}') - return importlib.import_module(f'evals.{eval_name}.eval').main( + return importlib.import_module(f'evals.{eval_name}.pegs_eval').main( args_eval=args_eval, resume_preempt=resume_preempt) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index f81f526d..9b4ca05a 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -29,7 +29,7 @@ from torch.nn.parallel import DistributedDataParallel import src.models.vision_transformer as vit -from src.models.attentive_pooler import AttentiveClassifier +from src.models.pegs_attentive_probe import PegAttentiveClassifier from src.datasets.data_manager import ( init_data, ) @@ -179,10 +179,8 @@ def main(args_eval, resume_preempt=False): p.requires_grad = False # -- init classifier - classifier = AttentiveClassifier( + classifier = PegAttentiveClassifier( embed_dim=encoder.embed_dim, - num_heads=encoder.num_heads, - depth=1, num_classes=num_classes, ).to(device) @@ -330,21 +328,25 @@ def run_one_epoch( clip_indices = [d.to(device, non_blocking=True) for d in data[2]] labels = data[1].to(device) batch_size = len(labels) - + + print("training",training) # Forward and prediction with torch.no_grad(): outputs = encoder(clips, clip_indices) if not training: if attend_across_segments: outputs = [classifier(o) for o in outputs] + print("outputs shape", outputs[0].shape) else: outputs = [[classifier(ost) for ost in os] for os in outputs] + print("ouputs shape", outputs[0].shape) if training: if attend_across_segments: outputs = [classifier(o) for o in outputs] else: outputs = [[classifier(ost) for ost in os] for os in outputs] - + print("outputs shape", outputs[0].shape) + print("labels shape:", labels[0].shape) # Compute loss if attend_across_segments: loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 3f90ab27..163d00f8 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -5,101 +5,8 @@ # LICENSE file in the root directory of this source tree. # -import math - -import torch import torch.nn as nn -from src.models.utils.modules import ( - Block, - CrossAttention, - CrossAttentionBlock -) -from src.utils.tensors import trunc_normal_ - - -class PegAttentivePooler(nn.Module): - """ Attentive Pooler """ - def __init__( - self, - num_queries=1, - embed_dim=768, - num_heads=12, - mlp_ratio=4.0, - depth=1, - norm_layer=nn.LayerNorm, - init_std=0.02, - qkv_bias=True, - complete_block=True - ): - super().__init__() - self.query_tokens = nn.Parameter(torch.zeros(1, num_queries, embed_dim)) - - self.complete_block = complete_block - if complete_block: - self.cross_attention_block = CrossAttentionBlock( - dim=embed_dim, - num_heads=num_heads, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, - norm_layer=norm_layer) - else: - self.cross_attention_block = CrossAttention( - dim=embed_dim, - num_heads=num_heads, - qkv_bias=qkv_bias) - - self.blocks = None - if depth > 1: - self.blocks = nn.ModuleList([ - Block( - dim=embed_dim, - num_heads=num_heads, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, - qk_scale=False, - norm_layer=norm_layer) - for i in range(depth-1)]) - - self.init_std = init_std - trunc_normal_(self.query_tokens, std=self.init_std) - self.apply(self._init_weights) - self._rescale_blocks() - - def _rescale_blocks(self): - def rescale(param, layer_id): - param.div_(math.sqrt(2.0 * layer_id)) - - if self.complete_block: - rescale(self.cross_attention_block.xattn.proj.weight.data, 1) - rescale(self.cross_attention_block.mlp.fc2.weight.data, 1) - else: - rescale(self.cross_attention_block.proj.weight.data, 1) - if self.blocks is not None: - for layer_id, layer in enumerate(self.blocks, 1): - rescale(layer.attn.proj.weight.data, layer_id + 1) - rescale(layer.mlp.fc2.weight.data, layer_id + 1) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=self.init_std) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - elif isinstance(m, nn.Conv2d): - trunc_normal_(m.weight, std=self.init_std) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - def forward(self, x): - q = self.query_tokens.repeat(len(x), 1, 1) - q = self.cross_attention_block(q, x) - if self.blocks is not None: - for blk in self.blocks: - q = blk(q) - return q class PegAttentiveClassifier(nn.Module): @@ -107,30 +14,12 @@ class PegAttentiveClassifier(nn.Module): def __init__( self, embed_dim=768, - num_heads=12, - mlp_ratio=4.0, - depth=1, - norm_layer=nn.LayerNorm, - init_std=0.02, - qkv_bias=True, - num_classes=165, - complete_block=True, + num_classes=165 ): super().__init__() - self.pooler = PegAttentivePooler( - num_queries=1, - embed_dim=embed_dim, - num_heads=num_heads, - mlp_ratio=mlp_ratio, - depth=depth, - norm_layer=norm_layer, - init_std=init_std, - qkv_bias=qkv_bias, - complete_block=complete_block, - ) self.linear = nn.Linear(embed_dim, num_classes, bias=True) def forward(self, x): - x = self.pooler(x).squeeze(1) x = self.linear(x) return x + From 164b0ac1c38bb3ad95030d7284bf0fc49632a0f7 Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Sat, 20 Apr 2024 22:48:49 -0400 Subject: [PATCH 011/131] troubleshoot pegs_eval and linear probe --- evals/video_classification_frozen/pegs_eval.py | 14 +++++++++----- src/models/pegs_attentive_probe.py | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 9b4ca05a..7fe835b8 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -329,24 +329,28 @@ def run_one_epoch( labels = data[1].to(device) batch_size = len(labels) - print("training",training) + print("is it training?",training) + # Forward and prediction with torch.no_grad(): outputs = encoder(clips, clip_indices) + print("outputs with encoder applied to clips and clips indices shape:", outputs[0].shape) if not training: if attend_across_segments: outputs = [classifier(o) for o in outputs] - print("outputs shape", outputs[0].shape) + #print("outputs shape", outputs[0].shape) else: outputs = [[classifier(ost) for ost in os] for os in outputs] - print("ouputs shape", outputs[0].shape) + #print("ouputs shape", outputs[0].shape) if training: if attend_across_segments: outputs = [classifier(o) for o in outputs] + print("outputs attend:", outputs[0].shape) else: outputs = [[classifier(ost) for ost in os] for os in outputs] - print("outputs shape", outputs[0].shape) - print("labels shape:", labels[0].shape) + print("outputs NOT attend:", outputs[0].shape) + print("outputs final shape", outputs[0].shape) + print("labels final shape:", labels[0].shape) # Compute loss if attend_across_segments: loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 163d00f8..8ace76ab 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -17,9 +17,10 @@ def __init__( num_classes=165 ): super().__init__() - self.linear = nn.Linear(embed_dim, num_classes, bias=True) + self.linear = nn.Linear(embed_dim, num_classes, bias=False) def forward(self, x): + print("input to classifier x shape:", x.shape) x = self.linear(x) return x From e4a1bc8ad01d76d0a3f293250e7ec59f2123bdc1 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:03:29 -0400 Subject: [PATCH 012/131] update get_item for pendulum csv --- src/datasets/video_dataset.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/datasets/video_dataset.py b/src/datasets/video_dataset.py index bb5cff46..33ea4651 100644 --- a/src/datasets/video_dataset.py +++ b/src/datasets/video_dataset.py @@ -158,6 +158,16 @@ def __init__( self.samples = samples self.labels = labels + + # kat + def load_label_from_file(self, label_path): + # Load NumPy array from file + label_array = np.load(label_path) + + # Convert NumPy array to PyTorch tensor + label_tensor = torch.from_numpy(label_array) + + return label_tensor def __getitem__(self, index): sample = self.samples[index] @@ -173,6 +183,8 @@ def __getitem__(self, index): # Label/annotations for video label = self.labels[index] + # kat + label_tensor = self.load_label_from_file(label) def split_into_clips(video): """ Split video into a list of clips """ @@ -187,7 +199,8 @@ def split_into_clips(video): if self.transform is not None: buffer = [self.transform(clip) for clip in buffer] - return buffer, label, clip_indices + # kat + return buffer, label_tensor, clip_indices def loadvideo_decord(self, sample): """ Load video content using Decord """ From 7ba87e7250806c74f04b579fcc943b3fb5fe975d Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Sat, 20 Apr 2024 23:10:20 -0400 Subject: [PATCH 013/131] add p_mini csvs --- p_mini_test.csv | 3 +++ p_mini_train.csv | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 p_mini_test.csv create mode 100644 p_mini_train.csv diff --git a/p_mini_test.csv b/p_mini_test.csv new file mode 100644 index 00000000..4c93f812 --- /dev/null +++ b/p_mini_test.csv @@ -0,0 +1,3 @@ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-04_11-09_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-05_13-08_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ + diff --git a/p_mini_train.csv b/p_mini_train.csv new file mode 100644 index 00000000..1efd76d6 --- /dev/null +++ b/p_mini_train.csv @@ -0,0 +1,2 @@ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ From 1455c5c9f4ba9350e1b35a50669f446168c3cc01 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:11:41 -0400 Subject: [PATCH 014/131] update p_mini_train.csv --- p_mini_train.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p_mini_train.csv b/p_mini_train.csv index 1efd76d6..8080d8b4 100644 --- a/p_mini_train.csv +++ b/p_mini_train.csv @@ -1,2 +1,2 @@ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-04_961-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-05_960-541.npy From c8e4463d5c051e96d0f05744f1913794384d2811 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:12:19 -0400 Subject: [PATCH 015/131] update p_mini_test.csv --- p_mini_test.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p_mini_test.csv b/p_mini_test.csv index 4c93f812..0563c66b 100644 --- a/p_mini_test.csv +++ b/p_mini_test.csv @@ -1,3 +1,3 @@ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-04_11-09_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-05_13-08_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/ +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-04_11-09_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/2_09-04_11-09_959-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-05_13-08_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/2_09-05_13-08_959-541.npy From 4b96e0a6db22cd3730dbca8d16f56ae8e8c93c4b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:28:19 -0400 Subject: [PATCH 016/131] update num_classes to 165 --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 60288eaf..3d434e29 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -7,7 +7,7 @@ data: dataset_train: /scratch/ki2130/my-jepa/jepa/p_mini_train.csv dataset_val: /scratch/ki2130/my-jepa/jepa/p_mini_test.csv dataset_type: VideoDataset - num_classes: 400 + num_classes: 165 frames_per_clip: 16 num_segments: 8 num_views_per_segment: 3 From 4c57830861f2d3e3413932f31dbf73a1a8ba7042 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:38:29 -0400 Subject: [PATCH 017/131] remove extra dimension in label_tensor --- src/datasets/video_dataset.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/datasets/video_dataset.py b/src/datasets/video_dataset.py index 33ea4651..3d046369 100644 --- a/src/datasets/video_dataset.py +++ b/src/datasets/video_dataset.py @@ -167,6 +167,9 @@ def load_label_from_file(self, label_path): # Convert NumPy array to PyTorch tensor label_tensor = torch.from_numpy(label_array) + # Remove the extra dimension using torch.squeeze() + labels = labels.squeeze(dim=-1) + return label_tensor def __getitem__(self, index): From 0c5a3c51de95ce4e3185235653fef277777da323 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:44:53 -0400 Subject: [PATCH 018/131] label to label_tensor in squeeze --- src/datasets/video_dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasets/video_dataset.py b/src/datasets/video_dataset.py index 3d046369..405c96c7 100644 --- a/src/datasets/video_dataset.py +++ b/src/datasets/video_dataset.py @@ -168,7 +168,7 @@ def load_label_from_file(self, label_path): label_tensor = torch.from_numpy(label_array) # Remove the extra dimension using torch.squeeze() - labels = labels.squeeze(dim=-1) + label_tensor = label_tensor.squeeze(dim=-1) return label_tensor From ab63f8c4244d7644b3a3352bc6b45ff032531d8c Mon Sep 17 00:00:00 2001 From: pclittle Date: Sun, 21 Apr 2024 11:55:38 -0400 Subject: [PATCH 019/131] function for plotting model outputs --- evals/video_classification_frozen/kp_utils.py | 29 ++++++++++++++++++ .../video_classification_frozen/pegs_eval.py | 7 +++++ .../reference_with_border.png | Bin 0 -> 412528 bytes 3 files changed, 36 insertions(+) create mode 100644 evals/video_classification_frozen/kp_utils.py create mode 100644 evals/video_classification_frozen/reference_with_border.png diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py new file mode 100644 index 00000000..c98a2544 --- /dev/null +++ b/evals/video_classification_frozen/kp_utils.py @@ -0,0 +1,29 @@ +import matplotlib.pyplot as plt +from PIL import Image + +def plot_guess_img(input_tensor, reference_img='reference_with_border.png', output_filename='guess.png', scale=150): + assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" + background = Image.open(reference_img) + + plt.figure(figsize=(background.width / 100, background.height / 100), dpi=100) + plt.imshow(background) + plt.axis('off') + + start_x, start_y = 520, 228 + spacing = 63 + scatter_x = [] + scatter_y = [] + sizes = [] + + for idx in range(input_tensor.numel()): + row = idx // 15 + col = idx % 15 + x = start_x + col * spacing + y = start_y + row * spacing + scatter_x.append(x) + scatter_y.append(y) + sizes.append(input_tensor[idx].item() * scale) + + plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) + plt.savefig(output_filename, bbox_inches='tight', pad_inches=0) + plt.close() diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 7fe835b8..fee05f22 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -52,6 +52,8 @@ FrameAggregation ) +from kp_utils import plot_guess_img + logging.basicConfig() logger = logging.getLogger() logger.setLevel(logging.INFO) @@ -351,6 +353,11 @@ def run_one_epoch( print("outputs NOT attend:", outputs[0].shape) print("outputs final shape", outputs[0].shape) print("labels final shape:", labels[0].shape) + + # save output and label as images (comment this out when done testing) + plot_guess_img(outputs[0]) + plot_guess_img(labels[0]) + # Compute loss if attend_across_segments: loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) diff --git a/evals/video_classification_frozen/reference_with_border.png b/evals/video_classification_frozen/reference_with_border.png new file mode 100644 index 0000000000000000000000000000000000000000..9a2b696868b2674f894955dea7fb6f4cbd0989fc GIT binary patch literal 412528 zcmeEuXIN9))^3odC`FJW9Sc~f0-+ZviqdRIFM>!35PB$qfJhfm*+>aZ*n-j#AyPs> zx{!b(gdS=D0|W>VYI5T~-?`^}-}c-!Zw#%EHeA z003BT8R*>u0GJ~H00!mbOf<>TV5=_ei^1i(@pS;8>sr?>Z#@8j&dg0$_s%U{UC}$f z;3sY#&H%urmrf22R}3UCbwA>CaOg%~z0BeZxfd7r{GJ1>wdJ$u7XVXyPX}W%9i65q z@c9i!T!ozM)1}@9(Hhx>jbm$ne4l;H#B_sAwDCfH{yT>53c3$zy@o8>D~#H82B!z^ zYVYuHs0n@6q;r(GJ_2cR*Lj*9xx%guw72wCy(7cb4UKC0qfcFQ9MD~7sBEox6 z4;cHK9%~3Oo~J+0#l&>SM*9JbjUiU9aOCVW3(7erro_rqr~0@!9B;{=<*P$nlQo#o ziF*%ddx46Md^El{|E=KKyY1)CaeREDGYm7jvmAYnEgdn>F7jo_$x1e3S~%{ZTc-V9 zM?S(!GBMREUVf@U8t48hp-M~t6w90w{i}#SNaLJ^@f}fJu&=WyP+C@6 z_M9e*sHmvA@8c(`_w;W3S9RJijdQO4{@$uGG7tzv8X_+Z_H~hwQ&CZok-a8!?V1#= zgp^;fm;a+6DKEeC|7hf&?dUoCIr+MI`@4a?M1QvX$PpaiuW|0&&yN20=O21H2f6*L zCojMM8WwGUGCy-<gR zYMOGg%ChQz_4Bu^e`)$}RW1Ils>-$hR`uVq{;ldyT~tkd-JEG=`e_VJIdz%8$^NUn zy39{Y{hQ_f;g-LoG{0!FsLT9sA8WGQPj2!B0JH(O^sYY$qFb4?TrV>Vpi(ux1@HJg z%+^qzi=*$(zZQ3n?cH?+adGkbYqu_@-8Nf8cH3T2dVl-vwY2vM@wXH>y^k@_rQOnd zd{6u|1LI<_P9&AQedwM;^&49w4!Go#*ZNCBO!{$y1mv(?=xXf_X{#<2`?S@;t#HT`h;?{m*tqH1+Y(Q-#7lgRsvHpFD} zTKdCxYG(RyvFh_;sZngIt`q^%?f*HBXWC?jZ-BL__Perw(=s1&3^EyjonLDt<_dbZ z&>>6tkN!T5fTAy$)|nzUegEF{uO%OKL{W4T32!$wbboV&IMCB(JQ#3ECiZWB_#bZh z=g+IOL3wrD+splhdww+!#H#2b6(W=Xf29AePWjx&#+CL9$P<437{m&~e!oNQ(Y(p8 zNBmE%{*^0vHqsd4KX_<+t#^U&_v~LwTFyjzk}Ggw=B=>|z109q+2_g51HAMfei%1Nc0xf8`EX%J4`}byAsOPJe zOl)?w?jr;i@Mh@p|#gzDo&mXC9b~} z*~(`&W>cPy=-F8vmmoLdjsmY-qfB5V1W8CpB8g$(by!`o(l{wHR&(o(pBAp|yQ}%B2MNRh=zhwsl!Iz8Cas#2Zp|8ze!6Rkr2LDLJStZ?M@X(pye3Ndl5etXzj zBG-?n44>lY-BXiyw9+HjB`6=rY#Za3#4m=pYFUb*iGKncJ!CeKBvowyUMFtC^$Ntf)0=O*(jQ8s-jh zi5%Z*U1Rf^?$V-cOpj+d3>^<$^UG5U9vjRB27kGq`=JXBwFhQrZ-D2bMkIJ_XaQFD zyp8Te46hT#vOi=vzcD5VtYf;7%l=(lRCN<35V70T#>D58e^U-S3OL6T7Y)>@{}z=& ztUBE;9%uI!2neGd;6xm$GO)egM-z#mK=skBp~6qIj3~r%{MyzN7g7$|1PF5&sF?^q zSZ#~ptsj_#;56n#D*)$rG70UGx%!y<=Amy&_bL{zBFkJ11@b+hC8d-y@>CPge+V;G z6AXdCh@91;QBYYV&8xQBCtD1{1LR;Yfss9fb4W>>+aILEC8h2@)cJ&5Ww=W6swX+=Pa>W_ClC+*gsu2lf?>0A#<^a22d>+RZTaK9S>^lWvc z+R63!&K4KIAGumL&O|LLO%hqDptFL*m%_WnVvTaiO^X2m;!wq-WvQLFxHjnSO&*{p2*X0MD0RJ%#OlFR2V6fsJOJD<#_d`iZDtKS^8Kh#r;wNu+W zT-4H%TO8t+c^+C{o)jJ{6gaXDz3EOYNNCCvSr2HI;c4jKxhWFnk1#)cL8?XtoEpcP zPO0yIO%Zm4%G6IvcM5AbKxWcn9~K}xjVh4)bPh1D3v)c z9mh{VdaYc|A=GUOz;l)~D3+xmrj-a_uoaF=#Uur8=`w0!+?(M7f~SX~Uhy(*Dmjg3 zV-|1OqCJ8J_Ou+cgD3GrW?VbK;UqBJ!d!nzDlfI4k5K9uDmOVc6jZDRAGDu*!mWqC zAp{?ojAub624wL`#MV5TtY#r)H6>M&{0I*~0rjAvk`P3rilCef17>Elo6tkLtwMFXpOwJCM-FL-U}UJ*i5lJv2P{;2!Fx*wW{dGT9R!0(Xj8 zIpC*R-zYWBu%?If~-<1i@+y7o1b0b2z>g-F`0qQm_ygZp|{!aAiB%gK3mfQQx z+g!Cw+^c{fK~-VwtYST+QI|Z8J~~Xet!aDPPiN{nwPa40C)Q{w9w|mDd4vfLj2*x9sQk(7)NQ?>5R7#y7x zmk7jitQofl31~bICJ2JGc81Q}Qz$-|i4~cGk40(vsyW$)cj2KeA$h1lOQ}L&*fxW9 zHlpG*>3e{J&X9Z`h^2U|uIGK%jj9YUCwP+drcFriBgN=4+ufs+_Pd{@=R!RnYaDG2 z#+I6A&M7?g9IK0YIk+{(cLq04;%8j(^l}2BkNF5k3F{j*ZhbS1-OH}P2cX5!vhcCM zGEciF2g1?loEA}pTz~w+tWcP3YtMxA)VBB*(z)C#c*xA0RbXgOHIKI+y$B>WguGb{ z<*ZMvw_&?lH)z_VR9TG-CSH^Y?y2%=lt3!hZ(rSQEIsqZt#4+ZFDoAp+Uws-nrR9pCPBQ)_m3ND^_E|%Ns3$qs;fHyWo#O_Q_6#iB0;Fh4PJ8Gp@Y&P%miE z`n{7GfsCs?%5=$9X;&lI?0;+26E2LI3DX$O4hQa9U^5qs2uj1Mvk^@3d|hk&dKz)c z;^DoZB#>i{$!;?%yU6}PY)lf21rLVK3B+PUc4KXm{6MOH*{Vg#u~DkFicE?pc0*0g z8wSo)C)Y0(B*tXe?I#dBk!TxyctGzkh{wr(=*$dZ^X$f?YVxFE*{Dr9TAX(d3O@9= zJhDI7f4D}WJtum+vnTDjRd=2q?@%#cB`kQj!t2{1bC!1UQg}sDjtwp=X)=@}xYQ=v zwoBqi#-fMsG(Fn}Ms>2`EwfzivJ~vC+PKNdF!b`Ul%tTa#&Ho~aq0Dp!6L$g*{1BF zv9-*8D4v55I$({tVeglv+*OHoN*f&MUXabREUul15*SYe!@IWr>|0iZ4Vt1Yk8Y8y zSp!YG1F2^v2HngVWM8ag*ZB3pOiGleo2eFbcj)^bf1xW?TiqVkn;U!t@R3$q{L-^@ z4H@)8JOW5G%A_&yIBB0BcoMNa zUk(l<LhwUkJp9mfLS%m&>Ni znx7D#8(Gv8@v-2&lx^*rbzsE}5=^2C2TP_KEjIDwn>on!TQ6=^jo!?L)JFN_$`9wD z)cQ`aY4+n5LZnXSC@@kMVH6jMdC1o)UNCTCWsW&ef2fbW%gMkQr3upmtTa2zji1bcv6Nsm?U}u z(`6>-U1;|u*pWcJ4N@BWJ|`0+|Wud~f{z!3un4 zq^j_QYq&tKGV1i=dUbeu@4L|^ykg~96td@FlSHPysGv^cy1q60q;BW z8_pm-J$%zt&0YWKs=MNU8auQ+%q1``=%{u;+8!pGscy_{gm`9GCN4ViBRe4QQ7e=ccTSl`IcmOWE+Ayow#J%h#{Ml$D9}8H zsR|$aImPyc;O&A-*GpzCCihb=vSra7GiEQ?lW;J2F37`itf<}MewBYQVSH+*PFgzH zCQv?qsdwiolPx#uish3z_vh8foT$K5vzJvAlU{_s*?{@?hb#95z15^(yRk53$rr_W z;G^nWT=XF+iTO@Qqd%pCCv?TU%hC^k+8M4_a??O1|!cuv{4IfK`8kel3YR>O>a37T@vjnnbUt;Z!1__92@}?;5AbRPT8)usgL-+nHVt>9)`bO*c?RBj_LalK?7342Xg$pWk>Cb|WTHBv_=%k;$3o*tHGbTL+uhgpv8d`K@QOn#m z97(*lZ8&FBXd^xMXWB!3;rq3(tx_wC6IG*Y6V!+C#wyT6$DATDgOns+2oNi34zEro z*BF;4Y`A*?i%qc?iUVGerqB2LIj6qvLRe+Xc}4An6zsTrK0#K5mzyBeJ_zZtJ$Z5K z!WnhRpd)5+7BZt<$FZJQc(Ba5(+^IyMdb4HCtQC7zvTu3XTCmkcM%U&FJ}pj>a>*;|SKn!3d!@7xu2uJwFFkuM za4g~aVe`W5qPlf_FlM~~meUhY4--v*NeewDJFustvhfbzUdp<~#BV2vn;pJwyz#C^b(|6^eG0f+wHGpHOZQ0d{10%Q zf9acxKKMnBM&#J3mdXW2k3Mq>g-8t_82^O0Ri;0w z`1E;j(&=-UBMk8n?u;Wu2&UJmHeepH20~(yy zWbP-J$64LVbixn$>5_=6@%PG+ug*!Mk%+PK6cfNz@Nl?bp?j)EN=V zBi{Q}NL~5oIK*L%@bD5_b#60Wjda!?vK{q>*ag679<0o~qDm=6ELYR!{DWSQRL}?{6%lK78v7OYidBE)mCj5x7-KHb6&sqooaXVB$&puV+#ZYOnb6 zDW09PL1J!5oEqlx`($I1Jtzvg8%`y|V7p@;lCQ^?C zs1dMWK}43GM|<~$bD8{I&<@U%2I;CAfvcR?vKWvoIP*(Rp?<=!I|}!-RrlsoL(M`5 z3^%o5@ozIEC~-I^L**-^M213 z-5l}h^b1s_>yCoi*9<&;b@-J-nAp|8Tyq~ zMMTyk{EhlZChx?#$uSIGyxEJs^4vS|rJ$z7h0cf@O16q!BRTyR^jW;tXY@JstA1`S zM6r1oS5{Zmvq~pi0v_*<6rAc>RLbJ&gn=yA4k+Q@I(7p)q(SB#_L`n+oV|)FIjdJX zM+NWB);NlYxZQ<>44CQm*>vQAJO+ih;9Bke^^{NVuB-)DZr}>4GUX%#NuUOjlOI1% z=TpUUrcc=jy`LR)>(dyF(+XiPklnVK(^qiGG)nNzX(bFwQ=kw?BKxu+n_OiLq`3LU=S=mg?uv<{liYu--v9d<^m)CE7(-B)~a!>xxmzcf!G4*?NVw5e=51CvsWB zW^?5nIPWrWP(4Ci_g*;&$mJhMfqDviZhmW7JJgo^&hX%pr%&X^ms4|C?pVcVXBs=y zeY8*O&!HfbijnO>`gSA$lDpg5B%`a&me?GeyUNXZCi=M_FfV{97SjdC z7dl4ZLOrUhYmdX6nxq*)_u)xlos=i~Hm=oY^|b19V^GItszJtY%KN~YPS6Yqbb5Jw zeexuCYq_(+v84|$`Of=_3e3;nl;Y_>6M-gIJT9PXI*XJls=lW5CDz*WxEtl$WRWzb zg0Jr7rE?afFNy89(BQqhAjfb-tL_}+JTeLF^c0zM*%T7{WbDbI^XQ1{X4Tw{>MsXp zcoYp+J}YT`PmFt+$HyMy9IahltXu(r`WH9cQ*^+!r$`Z<5{;<|@xHi+0=k4z!!<|x z<41~=F2|-p%WPNU?4hNyPx^Wjsi>N;L>K+=`ST)Yhbt17FvMla%5hgan|UIRH*coR zofm&iz-IAiCGyY=3i^t#`Sfi(b7ku_;(-x7Tt;m$_+}w%t6Nx^;gZyoQd?Cw(CcY2 za2mEY1C<;wi}+FP?gtDgu|{*%s&6DAt#b$GD||Ug=~>a+WXZcJFHuWa+V(r=oHeJ! z8_&S|rrS&F@8wK!`hJL`L$Oq`7qth2VX@D$yv1+nfeS{@Yd4fL-dT=gWa2p~#s23v zmtm<%?plUZQ3eh^iHs-?b=ESwx6mnuM;sgUNt8`kDyZM_!#jDqWpESe#J(Y?6x#&R zZ0VueToV2D@5xuAKfi`4Imz!7gmSB%`C^p2QrV50E%26CO~DoN<&Wr}2|uIXuFfdu zln;5+7$m`@EXf&?0&%`CAoOL2wk5y*!zapoS*0Amc99cy;m2=?zXKzCZ zDFVtA`jeM$EZx0u7#Pm4;Kkj#D(M3{eKBH;aRQ{PeLW?dTXwbL4MeeRC1$mD&z53j z-&4i-#xdSO2j)~j7SGo?k+avB#MarM*W<+a@?j#sKi2Scj9M<5l{)fej;glCMJwf(uOaWO4KcTeROg_%>1g9<-$+y58=Z6uGrCc-Ru z6=bh=h_4=tWfj?MHRDKES|pee@0_&w4zZebMi-uSH~F(t+@Tb1Q}=oD(B*kLtdux9 z@v)J$qZ}H0@B;~>Z9Fs^t`%BLxu>=$+dlZNp0hRJ?qnd1P;+cTs3JW7Lu|s5uSZ{Xeh1KEL zMsZ^x+2V!SC8DJf=dpMnQy636hl4fota5KBm|XwUmYI!$=$eQA6~vz56`A4q=)-Wc zmE_0`TYVpWuk>yOT=~-~f2izlJr?nKPxLX8EeLKk+T=wa> zvfIx^2qrFbQ0~o!>ZvvJYQ$#K1|fkF6Y=4NyCu+wmu0CH){mkaXR4j$(98mV+( zNgM=trA-zz^q$C8yaCq#XvXOhE+C`9&8Fm}B~VayWNu6xTL+hYzr_xp8QKr^*sYtg zRD5|bI-xWF88Q{@lA5lDE1CSR=;2UEvaqr_=yu~d-S8!nU@;G#z~+s1+nM!ec6Dc0 zOyNqEt-Xi2SH7!StLu8#1oBh;uiMskWIyp^4=n|eFPT_mCcAC@(Pl;PQn0gf(vhei zD+|dH&fPAxz>V`k7%MC#uD)ATUg~4VcOacV*4T`vU78oQepzDKIJC7ew}tH*E%7jC zczxzF%jj9gg2gy(N4f8y_5AZkar1fCPn|PicxO0wW@W}$h*CK7hR+0sX&?3{hq{&X zXx2H3hxf0E-&VWzh3v_&WV>5`BO)jNX)IIz1-CSQ9cbRe~TOG9+-Kj5 z^5nZIOFlv;l&G>QsW!GWbB#L4NVkUxUd&OdpMPZ-(`3Kq6zK^Gmide|m&2@{IH-m0 z5hl+r0-0@TpffdWSLjpct1w-YC5wx4G6|vK)ZjGyjo|zmog<#A?Mf%J_MyC`a*CLe z1^3tE$o(Isu~2Q{l`^s!M^bg7bc5@s$A7994;`Y0y{v091M+mGUFr1_H(#YUJ>ErQ zg9U2ZeMrqQi)Fn}OCZ~l_=>`0Rrk#fnQ$Lo#i6>8;mHhdZY5AAr=k=oli$A5QBsX` zuurHIIkXc>U8k=O3qfM(nI(!x^Mmo3E^7~Bn>&#K!uCt$uPuYKaN5F&6VX*_)^M!V zX`C&4OnIH}+lxe{x=|~e`~6(wJU!#Fs}4MBnky++UMZK4yuHJncqZng?^OrHrpEPo zv&e73PZJftu&x={Zu?rS~md|Co) zw`67pGtk}l{lU1sCUGV`+hfL1%12w3{hT>bp?<^exuDpOtO=T zFns)&A}Tj+4)jOu*j8RKv23x6&^YUW96z{`@}WEnC^FDHL#SO2<|!4qaaFeQ1uvguhiP{$a~tLKm$&e0gE3qNXqui+e04 zR#d}q_iokG+x-pc$xq{jqF6*Kj)^jr-KNh7+tY-@?}SXPT?`i6PV5bm1#M-ueOsL(=}(iN zwUlt($+oC%ia;wyFEzWLBCvzr)OO`E(-;A^6gX8=vLS%`Xs@s$)FJqmATw8nC4RO47_)f*r3apM@=yqt*DNj)70vlC_C_Q4)= zC9vmt*3k#PkGe|Yw^JI-4P8=JP6${M-6;)aD_7zbr6+SvTe!4WBv9Pp(k~mQEdP|M zy0f(-FkGA$zF&l@kgM1u7>&H{Xc*d91;Y-MzE{1@Geh|mWf*oiM{(Fjs0UoEaFIH|$?knfH$kR3wjj=!OcRv#B46Y1T3+pnU@6fLN zVpEYkI%`uw&VK~f6t-^;%UvCMPgryx@|`C%4i-*aymtJI`0M3KT~f1AN`KTcV01wN zFw9}aD9)4-WpT>Pd-*G-#{bHsd98u_tZaN)0Uxd+$N@Wj<@vUofFVBwaxIerFIN}t zLOyIJ4QQn zlXS4afxuk3U8{coOomhPS>V?0iIVMh{DXb$2rz|cvesZoAB3a^4cX0k1oD(w`Pu{) zHJ;}@R;uS<)}eEkR3&LQkrX~UFl z2VTbX&IRllf<9$ahU)vtF_9HooD(?KccZEyCMLi0j*J9kSSus1ktXeAYt7Ll zUH_s-`3B+DSKw}Cg0i8>;P_XNyvJ)PA`R9P-*&cuU$4~r8oNEDv++hoX9ij-3#XB& zctrpN08#2oqMp1<>eC>5C^U~+V?Iv>?9Gh<20oxYe^g)gEM$^Jj!tr0?=@;JtaaDb z8ct0S*vr0HRy5LI&13!Vm^0VB2>peh5IV_RTN9(1#}M9!tM}uX{son+I%Kfn-1<>k zDU3Njyfn0%)~j;BK>rNjWnYU5=@i8gbp>Qux5nu;qO?B{yFA zN_o!qepNbJNMO{2M80aj_oZr7pWfp9z}pw0yn)R}JLAmA^8TDjuc(_K)PY*R3I7CQ zDum!Y0VSc^h~tg(wMETxEwJsq`rsiEX>wXEj{iX2Y1sW2YlmFr`0O$V!8OtL^ zt8wo8X67&3`-RX#hla$Kd2@F&?H7pFUv}bf`ezLtsl4ANQ2hU4{KD|RTp0hadZP;W z6Jkn(+J*A$d1(HM;_&MzR;9*0i{xzwl)hF*e{{>kjN|`hs4B?udCq~*SX%J>wNC%8-#^kTe#cbk zgYwSz!+x7B5E`q^-|~Oki5r0EH^0aJySxbpA_tB7Li9%4|DMfgYaz^p#>QJ;6^(QN0GfL#p!4;r2FUFp!z8*;<8cfr%XG~Bj|sl~5;Xcnn|KOz{(K`t;9?HMg!Z&YG-{?E5lz=t=ZEl89(vXfAOSj ze^6=s0q7fPK=+*q<~reUSnobqrr^{gC@^veMgrsJeot;3mo#Ks-Cy~i_)Xf%80zG?VoYAd;; z+3H^N9%h%9zT?2)|LhLypD2FCpyrJvu+d)>i@y-(KTj=t z$jxNro6{wijLtmGBV{k1>Pi+;ixGE_NxI|Go}^_gWBj5^9WNK9 zMcV=qOQmO5uWIa!U}fJz;j=*E>9&ER&rBb19al-Ja?v1IrlvQ|U*y{9%9p5Ko-?%H z|2AJzTEXu{Ls3U`JBb{O#4|1ZWNbu6CIK`OXlKjzv^}&anjNZB=$T?g!guFsES->) z5_Xq^#G~Y&I|IH4s|a?uL+;MUV&hyIuA8kog-VvJ2yvL}MJwUd+hIYAirLa116J?jo=9Our1Z<3;0ew^WegsNw9-wh@JTVLyJ}_iv z@3FJ2h%p`i0BouXU4R0$yZ6rh$0a{-h4zTpQ4z{b&E75rlc;FC4ZiV{&-)^h90oP#3|wx!!cUa!$*RB^!Z|)JAVPh zlQ@tbfUhg_RG_9S#T|;~MCbn`D{L0?7W$HiDO+w~xxYgX>qw+Sd zN5|Jp73=qD?JpI^s+b-U^q1V5vAaNWJe^bZUMsiObMh20?CW5Y#G>C-_RSg*e2_ri zyb7>M5W3!)TCBcs*-3J8B7JdeMU0%v>~se{>9HHUnVP3Q|EU7-t+1*QovU1hM4NaJ z-L;s7{0FL*ix<)CK#gzdYmRRY_^BH93$Y@Dsgs`2s+q`)McUCd(J>o7=LuaPd6*FG zHb=Kty6|`ngkCnH9>V=>Ds7yfGz>2FHWP6QgPO?$5%urWw+ZSvv+;b$0;#hh2|Zk0 zF+W6_=)`(H;l(XmH%p_IC)a>J-{7lB5GPv?L?&X94{SF_0(yV3^mJ9gjAmDo)e+WR z-A>E5O%Zx!_e)oN%1Eo#DWQ_hnS&EwW)^@*7MMBWE^3*l=szkP z8?JuXQBPMB`#Kb~SJRYM;Xjr7!In-B@RPj~qjRa7lZigz!K^yP6lvc&kv;>Jvgbsw zh_O&vT95VK__OPSlpt5=Y$0KbPy)2#byo+slieVRD zSY&9s?1k+`GmK}>*1juQv_`(|U!+m);_)duK^HL|8d4r!ciq0#whWx|vNftmxAEdAQjd%a?!l-cH_dFW*al)nv7`Pj3t~k8*iLNCza0 z8rYR$Vep)bbw7@AHcZjb?&ya(yKyy7Kn?}t&q->gg;loTh=P}Tg;`?T;jH&&w{_Vy zKEnSb>C%AMFC50U#OjhdX1@k`LumvpxS(I3Tq>5vaGT6N;k6M&+t+5hB`)L=A8bMz zj}h?;lj&e^%0|mHEEPPGHaFnFf-tH6aNN=N=pYwTSFTC3%f^&>|JQi*C<=490~0vt zRQ}3PyWAF2JcVIEd}?s^oJ$Bc<|>nDY( zlL3Vk|#C=*TNv zzB0%A^NG~+$;t&1wajoz7Y$r;r{;c_dDmsRPPB{3oeyrPSgy3&h=!r4T^c`3W9!`f zn$t^Esj*ch`E}QqnePrD`r=RGFodRJ-H=Or{nWE5ydvBi`1zmz3xL$HXJcaym+w?O zu+16D7SF2=B0cwuDvP)?;?MXne+rD^@p;GM{6RO{y32~DAywSHO!n(?)|Qg zl#H-Kn4*?sLg^(1Q=;Qf3J=?@X#Ho=e!Y&z6ocIXmyUZB(V5tryxRajO>-Fa94;_; zuBcSP_r%ee8m#Hy>+@aIfBb`i;0WbDjaD>G-2zt6UNbfNATD^_z<2b+@sHx>I}%UV zLL4_=THKah174Z-iI~m8a#67mXBa8XUO)Gu*XkYVyAMfcZ?nri-8J*?rk-MX= zfGKx5lREzqzc2g@1>)!%pU}VQV|?i3N15`~vIH zXfDNUyDVLnBHBKr)f)@)!_`?zGT|jZXFav~S{hhk-Ig7` zznn^Yq~jVCrzCaZcOXr3LT%!9BwNBJjD`_RC1EQbyu14$7X`d5@rs{Mdh%v(YWAN6 zB-#|EU;R+hWnElzuoV*Bd^oOZOr@=rjva4&W0L!3pa5|DaWQtuHz4F&W}bC1G1((s zU77v`ZSpY;Td$v##W2lyuOT$wTsrn}!@9tgOl>OQ+vR+s?~v$xOTX7qDL!hzx$p*0 zS54yg*`Bbd0k1RkABUm~^%B^Ql_#?GCL=j^!3Fl-syVHX9Uc7t$=aN_A%`wom{9%x3znB!!;rFobv`<1xc1$&LV zT}mU_xWuzkDX=;vazCd^k`HEW)`t6};)xE;je>i!tiu>SSyTmv!1 z!8%}QJD}NwJgn3hXIn9G&*diiL!){Tp5fFkG6|`XeY$tbOjf9CZNAz7Y8l9I2jjJo~Q9R{Jz2&RN11-ts#x)e&&I9=^eG0ty=}aeW%U zI(&iTp)qVM*{fEJKLj z_3~UC4nY@5t3XRXcP;p2JtaM>aNpe&YWA`NAN{Eppc1Us*l$%i?Z}pjh^PB;?Z>O~ zyyyC0l@r#O@sWGAEcJFn^9oOS(^ef+uekYU)#`orGjKpZJM=gJ;Vt^_G~$&2$XY3uRyR)E8tG zWhWYL5oask^7-^h&DCjUZs^K|Qu&;VcY|(SN)kxyc`fiLLAX;hXY`ew(`lQW?Z<<$ zdQaDmRqi^_Nj>~%CHY8=>%>uMwc_w(nA(?ijc9F66LZa|sQ&fHhpVPAR)QCxG zYY@UAgNH_#gxpe?OxjL>bS50s${VYD7`MwrhtFmFf!?c`9~Hxcb`rpB#MZuDZ;;$K zclok}<}HzfsvGQ+qYuK(<>+Mmnm1;SIENl4-sE&;gqb(-jZcMjfL%VpNxSMfy+paj zh1b?GL2q7&Qfe>FBBO_bQVU1Ab~?k7T=r|!9tO^SsFz=MzptIxK!Rv(JI*B*jXY`J z*WQSnl9DM~AYkI|Gf2sSNzTDZBVAMYX9=tPRL6*H)IzVv<$`RV&a+XghUA8YgDo!X zRUE_~IxU0OCc2r~%;;^H(>M8=0f)9;4#qJ$$xU?t2{tZgK1xc*{`euiav7{tyx~Ve z)O$!eY8>=JnsB3zm}QOoiEP#Wof+16|CEy1hn0| z>q$G*E61I!r8`a7irZ;oq7UM7Yhi8J1+TWvubN0G-&e`8MYfBlpyO2Rh&PU`JavpL z^y*H&&`wUw=e&7B?xl99@wIZ%ie9^uv#;S={_<}IDqlJG-{L$~n>F z^TM21%SY)~PObL_S|ZSfl^fHc1Z$kC0*ssO)HR~~l0tGEYVZnI;`wv$y&YP2wjlO1 zy%j3qGCm(}MGRz4e=V^%^X>k6S^gIa_esfj3P;?rQXGtDo!Z1si*=sFx!rBokc*f+ zL6tu8Ja+f6CS$5PaHmvRd+~~>L#Jtb%R_y!CQSHH-z>e^nd&Z^&WflFrePFKKUQevAw-M7duljfSK@ZUoN#)W+%#_|-K3Pkl^Z<$553Uj!(3s! z{2qIl)VsaLPK2_ndffkF@4Um={{MbYwN%xrS+lL8t(n@pT69>|VQ($9_l~_c)s~7- z6fHGUB~}tEp*3QQB0);5B6bK){LVSox$gVi_kF&9pX>fJNb>O+@A-N>o`H(DXeYQ? zg$@{xN!qRyAi9g`_S8s!bP`VGL7VDB=)ZM#u2FAg?u35Wa7J z&FX$c$ae(yb@gWVmx1A)bALVz#JYFK5r=1lOHuma4A1)dQY4bkH6e?YrYt>+`qH;} zLWr(S;y6?%H!)nPL&B9;uz>tWbfcq$gVtUl%x$k&rG=N^AFSvAUZ2lvto~^0n~9!0 zh}5if>dz%qknCuLc$5F8o3A!jWC4n(iay#}+j=^^&oTzJjh7|gw$FQTStf#aWKrH# z&{gAtJY2I&Ap_Q39a89OBzrF`!nMJCByn|1;RcKxaP8+UHN*9IEI?y3c<csrh+q&JO5p zMw-Wi7yjC-&EZgWX`c3$lsaTI_r^Rh1(Ef{b5Cv@DPMnk)!+Byfhc95^HcaVF^YZ*q1TI2@mT1aDBI7AIl zoyH8&*AtwO9zUA?-s;E%&3awek2}Po6u|u(WFYILWa1Sn{+EB`6BDDHDC|X>;%Jbx z_pc8Zf(EoT+F73-&fR1Gb@OGOZIwv(>g2<@5}r?{+=|f&#hC(Tk|mHoBN8ZNfGv!3k{Rt_^)s^exX8nX>LDX+z-v8hmTNejbb-3IkBn$!o0D zb_U36={*8caW#9g=jMRvr*uW8w?dWivw#_nZt>~^1wq!0E_%9Si0jx1yv6Y%rNvcN z-g5P}exNnnBl^p*6>1L;F6It`%gwcrEsM3-W7*>-ZCauC{BS|ii_2EN#rvU_jQ2Av z*cfOYe}9#NNIBjKXiyOW!tH5{U%PJLw-@NDC~5{MkJ@_Xg&!b|C0#m7 zVMS?G9**czV}cacNv$_DB5H12(Rm%}dwr^|#d5GpscjWcd}^6DxrXS>yg&7uVk%xrOMa;dn;Oi8eCk>K|YqvO=%xe#lwP3g!3 zTXLz)RQ5~fe!8O(A34HLJPs~y_31gKtsW>NAl~l%Z`r5PE?%u>O z_~iZRn{z4N$t*rG7UOwsz|Sv>TFTOiF8Wf1ti62;u{GOaBt&#`=OVX56dG^G_d^6| zm0IWV@)iLX+dsoKfefl4CY^z=Ghc6j<mm_yG>RM#xQTm#Ix9dKd+xJ}U_3Fgb zNDbZO8FOR3ZPgYRfzkIi(r+0;YI1SK+%;POhxeX!(54jJNU!3cv`^WZ-^kN7N{z3z zw~M~ptd-U#Wc~d}E|&#c!1P*aVY$D|02t6Mm6|f%^*hcc#b{x5(GMV)bGG>1nXf*s zJ1x2x0H~o9sqr6FLtKEp3*W3Jw{fS(IGE~lueaUi+qI#t_5unCDiqDavkxObJuPow z$ZEP6OUqHdY}`*@b2jDg^_JS-$`AlowY%6J+40_d6W*YOS_%2c$tg=oI+;MTm~YVb zm=n{Fr+o=-*x$|CYQIpeRhPh3W8cOgS9qa!I)y)l^&}i?8oWq}ds0UBZhvrNEc?+p z{cA4=OQ6?QYp>Nxe}Z;3&mN}k?_N81*~*E2M&hmh-F1fhrBDm>N6XF4z-dqYgO)h9 zB0B!1d3ap5R%h{BTu$LZABM|(B$ymFnU%g{hlbqB)cv5RY|ZtmTm9NosN~LdH}~j; z4Pe_<@3&8&u^I1bjxNtYvfqs6a$_-r8XVgP@`YtBk8@xgArk2aR77Q+9aK@{5RPEZ z9>P6B#;JCvUtwm9po?fr#D&fr31j^@1^KFe7cjZ4e4^1X(UQjY`vW^d*)zI3)?a(> z^Gk4|mPHtykd2|T?XKge?fdlXW>bpdpZS ziS~TScq~(Z9xnlC(LVCJP~siN1Xxn&oe>4FaiZV8&=h6*6jCR5Jjq4FD1o%4(56e~ z!7RtUCmcfk^z)z7q!sILja_zluzK~xATXo1ygOuQ#C1{2mHNU3hZ60g7KnH`D`6qT zuTr&POlAq&KL3Oj*cqS2i41ho1%)oX3g5<pyBu@_3mwXW&lXk+>CGn(6cX~Xm zdE}$JD@}y^&MX~JOR~q%oL&BhBg9xPXWPH&$ue5Bb)B$!aDc%sDivl=aMM-&EM~NI z5G>^3T||87GAnEm%46hdUu+%kqPP_<+7O^_x66_yfn@SFTF|=iL-BC7jKUC{I$@SzNVe-uhPOEZX&xO(=6R=p7 z4Yl5H(6Zei4{TrHg5W&ZJU;i96SQHb!VQX{c{<$VOorSEXZX%%m}#WAi7kl5%CVYn z+Fb+OJeTo#$js=RK@xiB28W)0s&IV}i<_P_XAil(?WPEOOg0UV7gL7CySzujah#8V zf^5o^A%AJ0#7*z7kL%xNjf>=b=V%#1ce!-UgIK}c?ty5M$bkkTZ{cPC5 z6S|7C{-$IQF!@0?kWZnN4du+o%RS}GDKUVWH@6nwpR8FOwru!*R@YE{vnDA2rxREh z0iqL67Q+VXKhw04mxQgV3mp8oPcA9d|xB<>yAEl5tRJ_|epF=r1mt3vc8A#C+OB-Ie zAs!keGd^Fc4sjt{n|6jI3ntOdr23-q3&-cBo>6S3Zo!DZ~qaLksBF9w6_|}L*y9je2xjWns$2Fz=>aaqqiNg z-#f8f={0|h(yvtaWXhQuOfm2yObCoLnQju3Da#0#xNKxaRlL_e5^y z*pqeW2lV>-e*I$Mn5uc~0{kSElwzZD5ZN?UmFraHf-kTPKXg%lzdiaFeu8Z|I{i74 z=Ik&T)^vF$Ep#>L_^OFVot?LNmx7!?p|jD_BTqUoQWpJl(sCizLy}rm7f7q1KAd-e zbjv7QM#r87W{Ev_Ydv~a(nBbOHI1FtGc90iwoP#fFeHC`F%q7L6DRU%Lt&e zhQmx2w@5d>Z9Bc%n+sZ$v(zmD z7Kn3KG8E=Cy(l2S@Lgnli7FQ0^Zk#h=Lq$7u<}Qw}$Jen{>V zj>o7?TFx0dM1q&sVW@DmGL-;{sX{B)HL(y@WzZ`U{3yDv)BZ7#odL+iKu0U_3*!L< zhq)SALLxmMsq$gbdw$(T1vUE(s7U?g_V~3vX7V-_^=Yg)*O(Z3nd`Qe#Jo z2j3%9WaDJDmhWpQ=Pd$a)&a5MA_Ne=@Z6N#;jQFbXeuyrc1$h=t&pOKR10}R@6M;f zBR@%4N}Qsttsg~ zlrrNdFMzRVA3X?IG$lm?DCe?rQM3WS%5l`Ch_-v60kQ=5bzpZI*4d^~G<6T_Ai-f- zIwCgZb(R7(<66_d`2q6g90B+da>3s_4X!S{1eXsr!Tqix6E+dYlHpbX@=Pn9Kf3Oz z*3>(NdGe+D<1LOCDFV6NNh*0A43JM~)$@l}@A#Ury!dG;;xJnb+V4u0!pf~=&PHtc zY%dEQ`+Lw7jy!la=r`6)Yz9`3lXex%o8$~rHs<*X_f6sUY}sOmeMkJSNW3aXZm#g~ zvyF~=!ib?pSfUlE{yiXyZE7Txb<%_7@eM^w#=A^TpPF_pg^k{8Np1;B;GJ&98Wc5v z^zL^>E%ij57r4J~t|w8#)N%x7KT*oUJ-U|Majx3d;i34k?k|c@E2s)sh8-D};J4&N zGnc#4zF^DU5c@#?qf7BqDCEn{)OCqfLqP`3oS&bB5GI#dpB|{rEScBLA*H%575XFU zZB_ORA%@=1hf?4ixC4#jB?A-h_Ns0y9%fzRElnx(o-WVs5U`r8eanzU1H(+usn5(9 zyLC~=eAungN;)Pf!PE%qYRhZa7Pz>RXgC-S?p1aWkSY*#kOJ406vhB4#I55c^~JW6 zs!K3_doU>-4$K=&sb+dcteS5{vjELG7cGf-D>DZL3J+w%ne@Zm4`9 z%XYyHX^patZ;A#sXp=c)JUyUJn>e!&Oa>R$onq2~V5!lAvX+tpUkgAnWn7nEEmt%2 z;IdQT-hM05QaOau0OYWZwqo+IsG1Ffnq@$L11jk8a?}6B#=$Y@dsf7ffkyKv zIsO5%X>0qt(lIG|w;=kfxx7bRb_Naj3vair61@LT&Heh{&#iDwdDD*Wg8y$MgRJB61MK zV0037UNl}O3mpUwig3M;7>3U00%p|(jXP^Kch8C>JoAs;T0^Ul-U9}1eS~GhKDz=o z!p!f_&U#17m*#^vN^5uwD?>nae17k;6X$>vzH1U6CJc{k=QEFTnfvL}jpG>KxCTRuFI{xF%MC{LpC$4p8kqOavsE6kh zWa!HZ=stLT$Htz}GQb#R6Q~`pT?Nkmwi>K_6j@1fo*ixT#eGiF6y~Qj5!MG5k&9o; zpVJj)IhSR0t=;Vd92=xZq_AEGT&`0D5uBFh8bYK-%37wnqg4**Xyq?m0epWsbP>Pp zqv`;*j`bXA0k)zdyLSan+6~Re3d2Yeg_3Hnk|ip)DIH)am|F(bI>o8|%^{RQm=E)| zh7B&Qd(eU`+lRDJ+S5b_KiLmr0~5Il>*dVKTg<`NG^DNnBuZR@E#H55&CI~ppDTSm&pk%CI-E;oIX-XZx8@k3Gl%c6@)ONO2S za)`9;iNjQ2Bo;#%&Q$V!Fenw`t&?bP(>#Fg2lbnAN;0oCahCdR%`D5NyYA$SjMU{O zZY-YXoguX-KdST|AZyupe?zG>(J@OK4Ci}JAf*v0u#o*XzdIPGMucOVwLZ1{_i z#@HY~&`((N+`F?NU5HoUpdRGaBivUk0Yz~ z_QUh;X}%#tNowWp`ZX~V^51{X>;NWV+C?RW1x;t=(UjwA|gM#9UI2?j%s}j4h%-c5`IhwI!|80rk2J2p zI$u)jeAI+0C!JbZ3-|IHvtJv!-NP+pkVdTvOwHt{qQU%w-WvmAe#%n`{L5ODaZ;_4 zP2gxy+aus6$r#CDxTLkDtI%8rD1sg>Fatl4KXHEOB2n&{d*Z(Ci7nT72XzOSlLO9tcV z(~Tih=X%XH>otARkYvv;JP*F0yppfXMbyazsESzxNuR1u= zkQ=`x7%*{p$1-L98N$Rmc)!Yp35avr@*M0XV0=LaB}TjB_IBjn=veE?~LrN8t>}{Y7RK)@zMdqhxFa1F0g7dGdX2G&Q;`R z)jM{IX6(M>&__0A)NsCcd(-Q#_I1rMyV~IDz&RRPW+(g5sQ8&lTy)f5NNwUQ4U7~O z^|?(ukgdF3I}qP)U!-XJH2S^wP;)H|Vu%@YXotG>Q6#F{rQ5kN6Bdj2xRTCUw6Lqf zCa31)nnyAU?1hM!SEDhBp|3lie8(UPe0$eFlke;0zkdboc`(#{08L5m*Inv6DOHg# zMPN+vC0N{im16mjrWC#<)?+RGVVb-5plaJjXfB)Z;M=k(j}~`R)1kUWRn^p^-|W%4 zfO)aTdPzT9Lb9`4FWplAx(5kPn6!@WUsqeI?x|vZ1l`&l#yK>IEF5vaKelLS$?dNm zaFK)S1~x+=K~9$&ca@2GCDyKH5#jD7C4id5E(DQ@?;`|q!cD@}Lh#p$BT&cgBL5kD)guzq{cD7d0_pRfDtZU}(_x+`K6>;OF z_Ztlrr#t)IZN6@liW<Ma#MLh;AN5udPp~Lm-4)gGdWsA!z5W>NO)%(oe)oX?tbYFi?RB3f?S8-{T z|9#yGdPMRU{;*RY`Az#K42BX#0qhPv>kmw)%Tl)8*(5DuuPag`qZ9>1(f|zI{%lL=E^O@B>2{2-_3oKA8hV~o zJKK_5&iky!`GkBI({S_*;n|nN!cYob3cOJjD7;&bz#?=Q4DN+1)+)&tbjF@^l?qu< zYWhw=Le1gANkidhqr=fbK^gfhlP{Wzsz3ReKfgAbU&e1X&6 z{RPJs%EQ|E@VR*20Qqw(^=8m5D4U_Gw<1l@_^O0j_d2kdoNt)oAU8mYW-K@Z>sfGe z_Y9R5-YqIL)@CVs;O|(uejAzDUIc`ws60z$BUD-B-_}@ti;Zb0ZExVx^A}5Y0|Yz}t5`16 z5}F=l=?k8iEI_L`l+n%fdjdfN9QbADd|rkE8BSG-ch<;uU9-YVhpWNQcJ7OJx^5bM zI4(pcwc4IjQ2v8hcM)%))M*X(HKxsA8CR3U)^>gXr$`pw1Jiq}=kNOy^T$AZ4QEKetiZ z60I0UQvMpWu5N+9F;MxpN&FiC*IWzbCan0^$G1m$tQpv-9>nYqO}VeyhkpQB0f|W7 z3ZFhe_vL=vIPXd67m=Kf(}f%xxJ>wjE8c=sAQPXVez;^Op%Pv-c4VJV;oQ3sY2I)T zK5l$CY7iZgw94~|45RxB(c@AM6)(KLxaAqX4SHayP(A`is~k1a0Zd+E?|bgaXShbY zgrtP#Mdd~270K`K)H>GiXitK`V2(b-vXo6}UBARU^-Qm*Ikbi7mezq?lnR;JnRiKx zh4oX1|B5`>f*T`q-)CF;4QYd(X-0fsr1G6D-lc3=q}Q)zM7ymZ&>-WeNbUO<*kZh1 zY7Kt9;Jb{t(>yYwr6PIwlEs>XR)qKR`IpeQ89gqnv)gZ<*o%LA%e)yJO>HLI#H~I( zsKNPuUOm*}RdsP3Z;ARjk-J~4yaCWq;@ zQ%J8%vXMqXNncKk1& zaAw(6gucgaafGO_jq?$LUFDin{9#Gn1Ly@A`7!F7<0qqb)H%IkhOu<0@}@7pY?x-IQ!|}D>5DGGVnp# zGd@jO#&V6mexZFKMC=-?ep>N$ZJ|doZD9# zTwd)KkIv!EHY}dI{AqP!#iME0ZK(K9g6jh)r21;HSHqp+$8A_ti+&ZXd;cY5RVO4J zB+LtgCQS4%=e41r(M=tV_epnB{k{83y^uaisg@`+@0Jn1H$O%H0PJ~NS`c?Y4==D>=R%X()b^+Aa!!0s-2Tr;{@;Y?|N2Q=1uG_CBkx<@@Q}hkB^g6*X39i{ z{&4a8hY&plxpStf`8-+T_YV%}jBCuGoa6POilP5IJMBM&7;S~m&hT5ujNyNHzSOQf zqG^0ssZ;)M$iV-c9(;es)<4Npd-Crd$^Y!E?mVKvp#oJr|11lNq8xckL2t#J_ip{e z`*u)>a)bQ$1^5pU*n1br5o7F%YNsAlFTK_?mngcb?@pen%AE$zl-`WUohRI0aK}Gx=1bkmw)zeKJ7!# zJ<-UVFJtz1{=pag&v(w=yE{lfOY?OvnsS`~&x87(@A>b4hxWg(4(^c=_BGTsRlg(BjgHxx1mHhK3m$RSptXGy&VRP5)^tLhCp?SQdIpDUNFR{*g-f z48&cb1W;PdP*Ml1X4V`PEF{8iY?f;rFRwhL1c6 zX`}ANzKy<=M5-F&vtSP6vl;jb7bP0e?{tUxlz-hTVXVr-zj99c??U|PW`f4I@Z(jR zn((73T=f|zK1N9?+;(PdJ6rPP-&hFT{SCO98!;1BcqsThK{RxN6V5`~xR%r?g|#5x zTzvU&&hCHk!d8{`#Eo;L3kRiy500HNm}6(h?R@Tq5GI!3?io5Yc9!fib|x1aVM&jjru;Ii}4!S*UrKojWdF}gp4V1i!|krqlM=bmeD5?;j=W>NAWu?(+iRh z-N5S`6zP5SI>l8hMSsXDZr^ss$B$9s81c^3RG@1jTAqO|Q~Du@ZnbsqKZnBnXS{Xx z=?Lrsl|8SzI2G%DSL9iWVhWhuVIN1a6_}XVgzf$~i1Lsjxf8p=>we|8*Jl>xp=NJ? zXV_At{Ndl5=aa=mX7C-ZfK0^5F>Kwx<~ElAsV$lbL&|~gl#ZQAr<{v&etMEJswJX> z+h_!8Lnu1rCX8q20ZIW5m{gy(hc^18`CVr|v3wTW@->291*WlP$83Rkl~t2Acc2uypP628tjVIjZYO~^Cc1w; z{_1bVQ@8T64LGRfHc|ee7emsVzi0WpJJDSi6r=nm0I1r!BMzUu%N2U(=-ES&$g_;g zZ)Z8W&gTZtCq^oBJ=T8y)V_(5_yW7jS^)?tJeqc59T3e0Qj87OFoN2KSs3MFf*%xK zVK8tLxp-DiZ>aB+eNH#)Y>wwoTF9wU--BdSVa~-&-4vleZ$rJmIq>RMiDmTQ>6!Sz zdCP+6c0=6$+0EkX{|YMH#dNC&JW`BuI}2;^Yld#@yjTnHz0;Pk0d!YD+1Oj#V& z_WnbSlWBsw!UFt^9DImWC#+Kv3Jhs}K2%#V8i{5hdC_+aEF9}f!Tj>ba)~!Z&Jpal zENFht7Yc{b#A?24J-h!rI|@BpF9sk#C=)m+`2NaJM)*$F1=iq*9ks9#1O^H}h)LV_ z&ptH_TY1h^y1$fm-0Oc9C0DMUv4*|>aBm%?@rNWl8R~`J=TzxCo>4gF4$8e~^Mr!I zTWL7bd?cHoUDyRb$9E_ThFQ`6YP);&QOPv4QR4MlxT^lw<+J!veFlrM(5;pWYn%a6 zW;@OV@M0t+Q#*X3rIm7_ly)V?0(7lLzr>#o zCaC|Q=oi%G#=KTSvv1Z?LL8BmqUyw?6yDCR1hrP;9uyI_<)1C2#du12EPOiPqe-^e z@IuN3DnE(y=9_ZF@0?ItDBy~PIHX`Va)8pXo;X)WgLymKJlf&<{D@KR8k6n`ncJTY zL2Crma}Z>2YjCHs z79h2bSkjitp~n!xM>+J56h%h1aRezRLWxB7m`Dr2-dmCI4DNk# zYPKWF+;_o)0X*7be==Nfj%)SwEL%#L&?&XS`-1yv#j+ixBt~7_-RtW>oEaPPoCXoC z6!WWP=C8-|2ki$sRdrf+tD6=F=j!^;34#D=hXM5Ue??}Jc5B%H_k@t=qkse09P(#w z3pCraIUUCG^m5N^2VD;Tf;e>-b;g?^jtrc>$$xcIym#IJWWqof9kw|SD|}_M+(NF3 z=zLJr{AA>2>1xRg&0hq8_1Jrsw|?UVPY;%_$Cpl$&$6DJeY!9n*?%mi3y!7}@Sp>B@(e6%eW@jCtB&F;d zutl|`IgI(Cq#K4pKls9qDd&K&a`sI-X<^&jN*@TRR+P%j6MLh^-IXv4VUP`1Kz01W z>e}?5*=Hy2rK%q39bM4Jo~EQmNXp?$w~>-(y+6Hm&6aL>Mo?OOGppw9Ptg~wR+(?j zw*~3*m&Zp?;(wuut&YVe$BXUa{;81W!?^jYMdK2?@UG~yD|(8c|ixj}C&p_;>uoGg2Ht~?Y`=gt+G zg@{mb^j*;tIX?b-OrC*Z3Cqm|10z(jk5mgDRq%B3ye`P(NY&Y+-mi&laFJ#73V;>Z z67Qqe3NjwucY8>E_j}uAglGhk`U=q3azOavNW_(mB{nqZo|A#7B9O{$*T2r_jwJQZGmrlK&$KhBCS%`UItEv zq>r>bLfvW@33Ary^P@hZiZO7Gnr{9x?f0^|E1Y3NU+2wdggyxBj%ot6F8|ncr;mAZ zV0SkYTZN69I)A-DJd>P2N!~)rURJx_S)g`ZmW$zroW47)#R^bqo}%|5+KW6Ib@wx@ zF&^$zhEgjhm{kc8q}=Cm(I%AyIX29_oBpjBNo-vNZu7^@p+}^B3OfE6vC>H5Hq3tN zYbo^lF>dpI#5{QMIvGWFYvYbbR4(h0J3PE6-tzpZ1^wBLeFsR-mFL2Y-ID^&F_@qu zPPVz^s6DnOIvkbHG%YF#YI1Dg&GSF&3U@oPU;;@I~P=h9Yb)5ce114uc|5ADZ{-6m+djyG9vuu`eMlp2-I~)#a z^V78O1Y~nhRl4s0)G)8ZJ3IUt3UoNV`xV~(a=lvfEn{Xu4$>doPz^Wh_yZMyS@y5T zgjMVARh894yaS|aN}UuC0iPZ4FW3-nYRAF*8WSzeC>lM~U9VN6p`)JrXulK6D9HPl z89CS*(Jq3;w;%AY3#Y!^6&jV6X7x|)KS&d-3p=SY)@a>kYz@igR9`b;dL8%WT9Q_! zBN^g9M1C%9iD<$cy+rRi*PgUAEYwrcBWR`X+daE=4T$CTLZtpJl?q$lVbAP} z7VC$&v+mak8p-lrb6M$ZO;1nRFzn2iT>!bM= zy4_VyRdV~y@W>y!>RG|y8(Kz1Z)|b2v_YoKKQ_fa$s+YaAQ9O@NTDZ-k3J z@qAnrkTQO0wnHsi=p@=WY}%HSt5lH~L3^?LaFM3cQGci7=Z5$FeV)rghE$*~IqG7J zDHnIuoo&CaIj|P5U|_+C!>JPDgybF}f#p?o9O@*8BSVxEEG$hdQ~Z;qG5lgLy3PYr zZ;7buhrfw0*StulCqi|Z6B%&e#WJn9sbo_n=Q0rUysqaDL3LcI=DNxY*!Re&!@TVk1%HP@){~%j2S|LvQpJAdcD_77?&qskZA!C&%mygKd zql)vO=19*?|LLBXl8Ced)xxBR`V)_NWsu`r&z9OvJ3pfdQnFTmoqjeAIeK5Rmf6y}g`hZVwrxx?KYqJs^M83wN(jfD?co=V zRVO%jR}jB=gG?m@c_%8&CgNsz_bdDt_Kma$8We}H&;X3BNed)K|Hf%u7+bfhbV8EZRNrL_NbZfHgi|+KbiPC z866nLjKEYI0=9x)@+D|9r3ltIfDy)>^S>H*Dbvcmtfo|woDg4Um1vD2#DXa%Mxw_T z7^S~tXxgP*(bG+~l&F*3L=uqdzE8ip|M99{4gd4>vaT($JF6KUa__ox+~@b3(aEmt z8F^YBjxVA#iJ*8YzRhp=z<=e2j_z>0kUa)ZajqS?Yt_&_3tDZZmKnKL%vZai4YX_siz&-A9*ub5U5+*Wv!{SqLn#DqY$FSo;wV=DymrJcfRb^SGk8HX2#eu9e%agRBn<*blk}>6PB0tWc!vsVw zH1v1SDH90o{d8T1Bq6xW6=r)I5h~k^Hz)0@r!6WC?Q~)@_@07{S^H7PqWtbaeIH@$ z)oW%;Z4(5W3rU4uuh1G^v%V!v;!7C@1o=YG{Xx~3kxxS?V@tXkRVOKr)QZqFwiN6l zgP`r=YC<57{d}vcXgP!xJ|KUfyhe8X^Y|%^GtI9h0b_tbIBs*Ue&3dWcTq>mgL>>W z0|3RjJ@O>xhg!f9#f9y3yX=Wk8hbdV#voJdvaHUx-RQAb@bcGJj(oA|49a%tjRtl7 z6Fq6ttXZoXc1~+GU5MZePtV1dJP1v(S}N$FY}vwkBSaGB zpj^1bxG4Lg3us8na$0+M+biuRolA&P*K-=*lA^F|T<-Q=XU^g|#9UX$d$B;ypdlHR zy;mxaPaIcy^tDR#OLD;$2hv+m;NaIoCP#nqX*WghH2uLkpa&bT-i@!ze-K$=V1Y3? z`+B6g^pHmCihzTae9>bbR>B|EJ?X9U(xC|^{3Qi3N_bfZ%SM8sR;LtKn`f%V7F*FK z#7g;Hcb9^HsGmpi#et?xx|A@?ub-;gGN)jtLsP3uH5b0tcIt1OSoI52{86upoaTY+ zXpGJF^q;{mC-9TMa_s@%U;sglcHRLU_LRnPcT$kzR%QxvM#wOBMXlC^n5@s6(PPze zys8{LsAxRE8$5j{{pVcB5D=t3_GQ~V+=IqNk(|rk8x%h34N{dUeS>-pj zOXx$#a)P%(IN-EJLRR>ktg%ACOby?Co(DpgL_Uk%QUuvgQkk(pu09Gv?_OdoZsU7t zD^2xGRz>H_jb8#kX_GfyA}_Ym#$lh^rcJXa!f!t0C4X%D^VHfY^40u^$xY|@+6#L{ zw=04SAW4<1!cm>ax_70oUM!*JQc@{*CCneCKOBQK>riv(?eyXnlxP_DswHbhgXX!C zB6bS$oSSWH1$i_sIW|b)c(p91%cD@7OQ1vsdsTAdX5PT$z!$c*&CM{z2WjU`8L#MX zCPhhqX9$g9Rt^L=wt48q&cEq${Hj{T>T)4WE3BMVqU zCP+4|!zmi9fiiY6jg4Ll2HWRNtSQS^HHD2=NvFbF7V3KF%?c+B0IY0$)K+Cy#&z$M zC#9fxr|MyeWQZ-no*%fCM-OOXqSJDJfQh;wuyQpxy|D5~^#b_k)^bNw_?z7J@`4ym zwQlI#vzDH@m2d~LUU6+`+DicSp3w!`8}Oe5uR7o6I2E|qWL9iZBzvSx&@U&Q8L`yFuKUBAT(%s;d-*;0l7&LRI$j4K zeHD)1MulIL=4sChuhnMHNERa8ygHDp`RYmyEG_jHwS~!}-*v75RH5hTE~VTYz@(@R z9Q^D#M`Lso5{ID*`yTr9Ih*PH9IxW{e!8dX844R2BI{Ekk421rk3eao+q2HcmMft! zYAT6;Qxk2nQyF!C_%XLM>JUUUNop1>LQ8x)s)~+uuhyl6mIV!hhFL~;j4X#?(Va)N zA`?S$FuV{^QeNiD`gA2NOJANa?ZrHegwr2A3E|l|uX|n>0;M0GlEQ@kE_l)0kw=e@ z$$w<=mQ-gH0^@HqCkQgH0=(GC>lTnl?7!UFY?EtJF0AGEKSZ>z7Cc)IDDHjPOgn9E@^95zB z+i^+#c~J9^Eyg}OZxzlUb(-E^gWrND#f@HA-N@L?TbH|nQRd@Rt97PK%caYzU+y=K z2h+Idb9xVxSdr(cr=>f87Q`3|uBhpvK=l#EU{#Se)cHF$xnk#ZQjs2OX%+8!eqA!79^L$bF>8z~W;F5*S0 zv7_Zm^-7scpM-C3!J5%ZY$y?C&rOp{^uP>+43& z-6) zV<5XGlf|}m@y&TUWAGy$H?7*Zu=EK4+zUWyylAMKIc4d^8(AV%`Gs^##7%|pz4U}pBS!Q<_N6_+ zZ{3m{F{;?JC(Nj>o^dL2ZrNJ1pULfZfh~$dC2?aroArXEl3{C!#bNn2dq38R!8tKD zMrmB1u(;v54Vd=pLCN+0X~eXcUW|xMo7%MVO_hR67x(!3NpVFlzv zO^I3)dyuR3_rkj$@eQ`LUsL62b5RL#B9M8kn-j(s`M_+-`*5_1Msd%+v%s5Z(TNoI zAtlRN{LOIN4ABM|7q}Bzez)@Uy@Pk5qG65*{ynak#VQdp5aRCe*2gu7EEsh8& zn3BrhQRCv9jZrifE!4xipR}M+01zeXRNY@KY`AWJ9v@U>LCg&6*_h9NNub;-ok$xs zIa~4UiGlWh`0~e^6i+YFbqE_|fGV_$-gbB9y$YkWLy)q*B@~Tna3@dwVF7Jw+z1;V zp&dv|1RH`dc{Rxi9|!Dy47IqX5|=I6C<(TzR~6^a*P0jfyp-N@Y9z7>?(6KZi!# zE3uYK{_Tm)K*o1MPXR_kI#>umtv=P!QL~l{<8JySC?*=xQGcJe3&1mIkj_9x{lAz6LOG9Rv z1l}*RkHN~_!U_0}X!*l|AgAztdBH+GCQgP~tmjM!TY9Y5+v2RE+aj`^?$PvfL6=9I z+_YE(UY>tREAq5!)|U7?o`&&RYa4w;qYtc0=5+dvY8yvukhJNdURNmXBey7N+2#yJ zuNQof7*+@DjOA~elRL)8eeQX+8ry$fMW8FDwLp^l&qFewv2v`*NcXGU z^U2JZ=aG>dDv`X*2R^FBwP7|{C0>z$a9b&+K?RF8Hc4C2Y7PdZW^@AU1p|!gp)&3L9VIa+b`l}gB2uIU1;Iv>4oR>e$fAk56s3cT z(wp?&I|@rc2ti>juo93(uc3-a06`L@B-Bs>A+&@fB==>Xv-UY>pL6zp?w9-Ne$11% z%=ykS+nD438_sO+%BM9O)iLe3Tq=xJ?CCPPzpphJ0_Q$vm{hDX``RqZdqDjld=U48 zz0jR##L3MZ>5lADPR?C^rOE|@Nqdw}Hs6K9kuMg-<udO8J|b;dSM>(g|#0Ho)KA#6myh6Dpl^t6jD8yLnZMP zd9)yBGKZh7w!@{K8e-NRHl*%xsmd=sYuH|3I`|TPT1QSDNClH!$^1fXQd0H#^NfL` zyE9EGkqkL?mxBYZsP!3?=J z{)=qUyeogD=|yRIkwLh_Q&_a#^lq|B%^B?S+J(D@5h%h_H;k)yyE#bnJ>d-}Epp7) zy*wQ*nffn^1j=~MqSo-*Rg!*kvrG%FCws%t$gV*!mP>e^&tRw;1M@J0_A^SDpGZWHJ{MeJHL5ZFvZO(D*-a%0ClTHgl02nVan_`i1c5}d|>VuDK*U=|! zpt6W;5au{!le36o(u3|z?FD=KqOLj3^LWnaQH#@uCX-86IO7jucpQrKqg8XR{4unZ zypYn$$f^ldo_tK&nCxxSI?&i4NBN>sE|6p2@^|xV8)hfFi3~X~wLfl5%UXu(QsZ2Y zgTF|mfZxV07-KTZNt^RC`%UV^maJVEbpBLSY>5gv`v<^sIxW%%B!COcbn3|;TFDE2@aE+PH!}(9Ks(Y$z+^Y>v&?u z^v_ZaS#QB~SNlM=M6n_M2w*ow)1*nL>5C1FQHW47zeD3UkJ>gL>Swk%AL*HWMYwh1 z;HauOW5#c%fcm(E+!FDcNg1<)>6{O0Sk?#v?QicQK^*(cYw>B84laM}3O z?5b?vnt$7fl{Tv{i!zFQ2_Jgj^_x#dYKRc3t zdg!IMf0+N_xfQ}R^xTm)jEyvk9bKpmF~)7(r^c8>UMSyp{8E`(#TWX#q@v^%#TeVg zp>*&wJd>YxugJEc{#;P=Os}!=SYx=7uYO(^@AQWu<;_i>U&fC(FrTksaJVH5?Kxf4 zHGuUwNqO@bWc|AL9H&5H8CFAkA>cLfh%6yM1sSP*baDVZUGAZm+bJy87nc?q2-k4QC%`@^QJl_uA9s7HlNK>+5W{n;X>>4FPK0;R~Cnc0jp$7Q&ZS?5q3mH~+ zUE6_uW^M0&lqlDsC1?oxNH{0z=?7UfyrD~H{~k>FiWarj*0&N!(9LS?!=-beF| z>z9S^Hzb#>6)f?Q7DS!gvGW{@7e5^3bz z{UsmEI2*&e$(_rY{ZJC5kI1f;UURHv%KX?^)fl;!qKPYG*$jFeCg zM6fv%s?<9XUh-*;6~Y@clznlh-@8XgO1P^>RZGe~9BfFuoZUrtzasLcEb9?|hh%_{ z%l2L;U+Ls;rXcKYVAIOgOTgC4-iA35y^fojg;n#pFEZ#>OTq9@LtpQ2fO)nGQbp!3 zsT;JUc+BlLZH9L87>m>)dX)PYw*vh|iM;_u%JKd6)U5* zu53zca?wb4>j!Hum*6=a`VyzC-Sc*xRBSJL-9)4|EaHcsdx(CbZR=;#O&8Qg)OKe% zF0>qdgcQX@{N&b2_(c3w=o}l@t<;fnC*IVIFN1pGj~24|^c%gA(Sb#k;&K8}j8RWr zJ;{tZ-RDjm(K#6uX~M4d?8HFpFjDmPHrxDmPDW-_{0|4zZvn8ikcUDiSaENAE3d?3 ze9bOptwh^Xd`0RybpZNUD=>+sj>O0Xm6WH%q107!V#edmaxwr8g@pC;-K(KHWnkz8 zo9z;R++PN*d;OzLCSJg2-%@KD>_i|O>p!bnDVrO$OKwXy zyQGN*BzS;K=z(KW@obj*mKpIATIA>>yKk>+We^c)uQa7PA*qsjkR@c6JqV6BK2?tI z9Zbo&a=O`VQq6?o+gtCvNS}jztVHot8cW|Xx_8&Q7qh;vH>D8XWVud|Rw0tFQ>wEW zXzRU=;x_0$$8AsDIxn#ODD+JLWM6uc%tcN)jTykKMn3al{DfU42-A8Kp^U-|BCIWE z%@{lI>)bQR1*NbdBD7Q1_*>{mNyFgM?dJXiVlm8>b7u%W&*@o$te7~VVm#roF{#;~ zOPVrhsncZ6{)s{|`IYv7nz{&dJ)TgD>@=wd`~q2y^Rf22B&|0AT5;9nl&fxY(wDc6q`_zbt$;d7NRk&LCkXGOZ#36+h9svZxSoD=0 z@XAtTfFlvXW7^*H^Lx5-VNM9HJh1WL`o?qvRO_hB=((cgd}JSJb0M7k}x5SaIp2*1%F8);_T;a zW*6sy3H~L>f;X$F;|Q!^;e5zqrQY4$%m|Y0Mc!s{jFUFnS*o{bYwE_;A>Yv&!Hvf3 zq1}&nYi>@=*d)*V@Z0WTlXnu&F4_96!jpkp>}!t3;m?uMeFD6*D2*-AH^?WhU1>9Q zqH`T%zvon2k-~-HLNH3LDbfP5n|xKKYJftRJB7bNCP0&c&69)o$lZJ%YmMK$^E%)z z=ur%Buy%Z+?&7jEuVh?#EQk4V%eK2*bx!3zi9A{G+~;1E;QQ2QE?Eed(sY+3J=nZu zh&#`TXC%@WCB_oFsiC$+kLaRT^X*;omp(y{c$Ps$v*b6cJqk?c;#?c!pj9t5@58~? z7n%6A)C09qzoRM=d<@+*!Qo~vL%v|!5Pz0S2^ADfgnK(DPH3U$6RP<8b}Bn$?|(cl zwx*edPspDs?&@P`S$Yz=cyy&|t#7z(p1ddl=`imD&H}2RNp}o@#*DQuSP5P-5u@EE z^!B>q8jj&iT}mWUrSz^qA6`~=%Qy=RTnI+Y$*Ax>kg8O&At690XiC@T@(NA(dNHUy z5lk0$R8CGGQTTwLXmJh8>+50HLPWYqdu~ZWw<9qp?K~h^7uA;fNeep6V?|bjpqjzZ zMmf8T6#MuuSH*3pD$!Y%J%5hTtH>+e?8qM7!I}}t8ym&l!zhE@tlkplueRX*NNz$H6pz7hxd#)W^+zM zSC~S8K4-@>CzR7}yWgSmW)Pvw!MfA{?P^p)z5We=6KmbQ(@t-0w*}zc2a^czl8p)a z7gq@ue?YrPhkuiWKRyh7sYNxhjN@O0f!hrDlhLrc>AT&Ze~W7h%%r`E1KncO7q zM(G|S`l_Gh>q+8~u3`_Gt!?$lKOJ{;N}I|H{UZZ7A$GSmBXL57pLPDRQg{K=OU-UZZj| zDy8gCr2EdYqn$DYhZ`x&aA*iPi1UeE=0(qGxlR!)1)F_+cxvM2s6k8B1#PnW=Z?;$ ziN@ZO#8kh{;{+Gb%;>{S1WFWUEb2G#I%nfHsVZ2ac%FwlPuE{scHwdZrTKfH6g7vi zJi@wJ1VUIX%m@r44v216jax>QxH=DPQ;$k@xZul$(6B$;!by{pSkBh;TzQ?L<*N*_ zHJ8afqJhM^-|KQ`r5O>a&87Yq!t<@VUK|o)OhGg4kY$`h*Eg-o;9^W~i%ZYjP+2ir z-IG*{^u+}Gnx|4KctwYb*@w3lH)p%L#_M;^_l};KBK{Qni0(RHGU39BhAydRzjB{V z{f#|(7%2g6srs%=)F#byZH%eAylLv?@^x=#e`7Uotv+DHmN91&_-&m0yrs|B_X-6O zWTmWj+M5E0iOO^#bioY8L@L*}EM<=PgCnXTs8x1QNXOf%3Obte;yYYUmkZrDE#Ci% zyWz8`w^n`E@4NiTawDF5D^g`dWo9OoP6&+IepBIH6>j~ISql9 zC5<5+#AigDN4x+=`HE9U2N-ImM&=_K4Bg%2Xvdg6*E~wqGq3jOxn6kP_j|pEv(B611cY5ds!DV9CRz~Fw|uyY{1*JfvE&#zOQ8nd=p zdQKK?OmJ$8ITNZ%25Z|%*mU~Dym^`se}=bNY(Pt78PV1Q3q^-}a*BtjcLX9x9*P+k zeI-04j9zrBlU4i-Aq`?tbtHYNNu&$c-8%jIrP)B!+u+>YrfqoLL|-G#@YK-s9fDFeu9%5slf^SE>R=38)s4%iuJ7O z6jGhuikCLX1`(EVbQgId%;0?$d8{hc2W5(x?GE>C&KssgNu8hU5Y5;u;Ckcv*!RC$dd+k{BHN;?v*23A8=OV}BYJt2eYjz@g1lKN;JnYXUgx_})SStnpJ zbE3Wx1~- zMcAHeR4;DID{daY_t61}njNj}JL8_N8dE%!HtAxss!MPp;N0z|Qg{?E9|rwesr#in z7Y~0rlLst##KF4HNz28`%R_Hn0dV5fvbtqN&6((Qf*LA|KizTXv8R7YgIq;6pl)0^zn!Viuj-vYo^lp@V)Dv2Z2C5#$f5U zI!C$C>N^}YPymaB6}&jp9-uvvb` zkdJ0bp`hMDy6%L{r$12e#N1 z=bKI;POomgxUO9B)WyyOIVTMal`Uw}EJd~%faJf(J4SLoj_Wa?X1c9l)rEK?4VHMc z_1#3u(v{+qGXhK#YxadUgCZd!Mc z)i27XV^yn?R#vYBEI~>VnUe=T0l6_uo{gM@Y{#I9M<4FBuKp_J{EDb8yzJ4Q|9IP7 zQZLJ=#;Z09*-`&4bit2SH|+YfRVqplS@3xKlQEF|s6r72IpzH(-sjI_Yk3NRD!pg2 zht_Ph<&f_l<&7hs5B<>C>^fI(@7E)0LY(SWwI3kJt2#_Q{IGiRnLv@w<9mH4k)Pvt z&W!nHnTUrSAXzkIrX!D6MotAhvQ{rL{JU*rjpKwaJKQmk-Nhl;ky}WTGY(`ptZDt^ zPTmk(q=x`j+V)pVN})UtiaV~j+?8H<VgnkNy~7ov8qY7AR(#eECYA+MEnMQcheyzt>Uk<$SO z^umV2q(Gx`56Z^a0&-gzi>f7USCuV(SYR>&v+U^))GbD_`mO1qJIXWZk&=(I1mEZ9 zaB3dI>W#=H#c6C1Vs+zko!4L^2h@_Qr z<`u6pArNDbqk21{OvLSxuypQX8!pt438ld^@9MT zG(P=ow0^p>h-+uJ&rEa|Zpz6oweo<~`w&?n7umCae6?UY(CtmKq=~&NQDwZ#ilk@^ zIcPR|F?q>*p3qNrnVdC@JRl$U;}L;w2V)n5wB>q>7!D8CCBFrl6MWZ3zO1;P^qY>? zBOW|d-9O5{)*p8K9uu3i^y11(40j&)uV$~PQ{63B{z!cRQC^VD6m_||a_-BS z$n||L06L>-p?SiyTj7ndUZj+-%KFn6hA2dkBKMZj6UDaeoeJ)>@~eshOC`3Q)k=>c zrmtTdC*Gf`uqO7Wp5ZUS$So1(Y{i-`K0B_~^l&?s>=G`frCfVoa%!R`IM1hVLbXz zLsw0Ahn_)Z8VhrZHY)h!>J!M_{}`e)hB^*21^iWV-l&AMtHWe|k@*1t7GzF_%cpPrp(faQSUE+&aNMmhZ_U_hS*ZzH2`)?zv2&Yc} zz4wb3zHjX&FIN0tjCD7;dtLC)`J8N-gejYPT(k1Oe}k%v+_Y$F-XBAy=l;38AO4hE zXc4r>VkV_-{8evHan8eB)_0RZV29%1nb6V9{lX{w^{4$q6tf8X5Q2a4(8D4}0?x1@ zs7>Nxy9RJpvQHZDs~os@&yCcg9IZ;h2Q>ETVTg*MLnOI1Wbr_F7O;wFB~Hip_$ah% zloSW38Rkd7e9*wb$BBLzcP2KzF5mE`cPdIISam_S+x*rsgH&{_$FEhU&{`+SO3 zAUHxP>_FSDzDQ*+%x6}Uh9)4}nKXG?Fd9gJ4GZ!sWe^ZEF0L?K zWeUoJe@He_V8sM#N) zX%*2AildqP+oMX);O(wCr*c&k3pDzDZ?(68RXBNKVm&GwAMXNd|FCDMBjV=i8Y(TD zot!aE$Np-If1^cou-x!}^L!kNoLPn=|DiB<@{m~O+8lpds&nh#EzfCNG z`S9_*SIBw)oHO#ZgLx9L9A@L1(qEq%ev4awKm3;!qUygt?0+k=^bMfa5pq8qhJgb} zb>BfP%*V>+jiylw53OjRBkrUwFpX)KuCdr=ZkSp9%W`mY3wh~cZvV}OQe(~a*B4pY z4u>3qh)PZ1W?y%Sw^qfHvUJ;jVRt;Su`u?CV}IIZJaQ@#nDXrsq|+806oK?UJhV5L zs%~;e9N8&H##UM>-iX1XZBNZ zb;zhgIOJW#4dMbRb$k56U$*+!ZU0mCF8S6;EYC+s6;Qh84|C%F(8AbhSVV$J zf8%ZdpokewJ|I&hE2NOo07#kZn*eWhb<=h+sio;)-KV_?U~AMWEQ^TI5^=v1b}^3a zTQAELJGU1qQePJVzN8NZQ?o+p-Pv5y44_K)4}e2y_#WNL7(O^)5DZI*cmQ`Xy};VU?bX#o=jdj&(dsd6+lDsl(Ezgp5Fl@=Dld6`cCNN! z4CUg)*r&Gg>ft*+?RTp2CN1widwES&lP2*}$;oxaA*-8oWL z#>Ah5up|4UXyTk$&PHJ40F}A$aoKUI#_^Y_qT3fYB7scyw)Ro`i?;=KWM!Rn_WPG+ z4>1}Li?l&Q0~%TMo?SKVC#Fq%g7pJf_HGK4hgsv4z`8}0P<^I0F@kmI30O|A*m4|MAu1DPtr*mX}&Y6Y6>tYtjwXdy9SY6 zNJkIpYm^-!$|%5{xNadk{5J%PDIpB2eGpbH6Seg>0LA3gZe_52&R3<#Xn;t95F<*p z8@sI0Gy$>dZL!AXE*pC!kk61d{@aj6+Hv(P9~|IEdljZ*X1iIc`Zu=4cPN;!*1Hn+ zn@cO~rL2sjW6ttO%39zCyD0P*^0aO-8U%(xcF$93ISU#k``^ZjzUNlp#(dl*u*D*n zi-GskHXnsfDptOm*p;7XOjMpLk~EIc0S8?2f5?GN<1l{2k&ruKd%adgv0tHB;m4U1 z&$*2iqc!%E1BLofOQ*4FHwsR|6^azejHZ#S6-2e^d2Ydm0<%IC+RrGLBSRDN4JosW zeH}Xu%yeJ`2T@VFs)*5*@A5OoosZ_mQj8H0^Gf?-(W#>FfG?R<6K$284ak9!iJ+rT zVQP+E8iZ3;@fRQ`?l;)P*({*;1Q91Bh>$@Jssb33LQg#ca4|3jo`FLYi->bo(r#O$ z^aSYUiwnVuyb~~??%2_Dp&XG+ohAKOC5EqDGf(NQXZl3UpP-DhjQwMMxNd?%B&X)G z&%{+@*#2SxbVFN4J`^TR53sfzyTj+Crsm>XPhaF*v(wpvr6UA>_v;uUl)id?W$!lN zg?>uLF%Cwud$jkZL4l0@q39_00fn!s9j6Dl509u#VV1=}W~g^IZjc(IS&UeX6sAM9ZL}tFO3mZ9LIH=;6t6J7t!5~3 zuBi7-`5Se{G%!^4TuBC$DUqZ)XVRuy~W`GER02@K*1QY zn|h{nTzx}?mH)XRJL-^oWH~Rc?%kR!KVEZ03*n~%9yXG-@AjY9R!7fJp$A3Fb~xjY zU9knEQ;0vtbZO53^X=;EE4$sW`vk7zjTv%?Ljz(DWZoc2F-&u{xdOWW^mYqwz3Bxy zeLavF3yN@B#hhsyRF~)ryJ1$+%SFAlsvnthI4$006wYV18z{A%Y)j0yk)8Ld zSNa&XC36qOLZxp>yL-~g6xq1MQ(aqyAv$NfH8dxePsf}t<~%200l=HclJaYvcrNjH zz9T)$s9)pmNSsHU$m}Z``y4m?)pYMoOs}=1+nQbG<^yXZ*3qM>qh#;WE5?*6vu^GJ zv$Jop2Ymo6=v-_^ZP63SCwW!EdqXB!qDnz@=wzS+V^sQ0bYBriC0*-D5-#DGp}O$G z?lMz#ql?fP+o&t=Noj5qo*j%Dz>g~z4~SRx zy-@tV@-?uPAvp5iR1?r=eHJ9lwWHF|&N1ghM_ z#6W4LeMt-XilG;(%5Ud1y9PL@6QSF$hU|>mvJv=Xi)ky?(}Kmw+Daej=7~RjB5iU~ z{@B8XSJ@h%Op+GA*4m&wo^{kpilrdCG&!kXCjgWsK+=tluNPJiv`|K`7yE|Yzl~+Ce1u|U!;BLk!BiS*s28OWs zRJJraYK_ZKDO~6caCya0L9VTRN)OP+NcKH}XJ7O!+7X>!tlfWj(-+9a1ubgv`Aqd; z?fFzVI8>hW^Z9;n=zF)7Kb2<0N8J1xN}PUHMsF_tN}*>oy;(w-fj?kAUUJ)R`$ zw9+i?do;g|R7gC(63}-3qI&j*;OP{s`j%51$*duw0JhJD;-oJT+O~?L z-9|tMHKEnFzWvFI54=G&lxYW08u$q=IRgiAKg3|s!ViT`5GzK8M|bqHWbISl?0!$H zi1XU=o<&wgY^S)7dpcy9MGfDPI_PItpGm08{1yN!dQ8`DjNJ@?y>|F+WN05`cu=je zdF_+O>nF!Aw)NIc7~tG^&b{~R;-Ma$%=UuEPC~q*J70f)UAVrzNDXR8Y4y-<7^jy_ zGT`Q66;>91Hm0o2mG-_+M?1219j$WZsWx$MclTR=KJ9kJEwmY%e)aJtEk}mX6{+7{2mKfnv zxp)`vw}9s0%v6ntx0Hp(GrV@IMbk#mvZrtRA4@-s$cNWYy44*(ra$|MIQh3o8k<*y zhq!XOv}Cp#_+;obNn}?Cq~9C+9qhk9Suuew4E>Y7*%^M^nBc@G_IAq56i8Q?xNP!w|YrdfZ3T9oHWe#uAnLq zI{oLNQgR)wkHKB-dsLy{e-!LYfxx1BRR zIy7yVb6@IOky@%>#MD)Bb)P%xV);1gM{@nl4;uAR*5K}{w0iVITf$J-v#p;20NahP zwCQ@pqykN3l|DkRsY)GnX<~FIEdp|eao<+i@@jr`4y71uify1if^<3(YH5nnTdc$64A#q?JFXfjS86>zC7UvH2z6BdrXJohCnM8t`E zu+rKn`+QZv*^o2Bna%~$O7G69F_(OpkHc2^?vf1p@Wy>eU9lS)ZyHUra|X=-F2^}G zDd}c0ohp7^-3b6k4~))R(#f|aX5|E9ETVC&6Pt$FN6N6RYtn9)JVyz}x_yNGjxdyN zd$1MkX~tQ}l?NKBOh0bcTNqpNi&SEd*Jb-3qSSpc;jA!=B}o zPNr5uk9sBt-^a(JH;y0?;hq+9p3RWhGl7V44YeDAhP3@-AMs@5~o$edENa8 zMZMW)nL|}F?el?rm6*jlLSuqL%SAF3&+9s_hzvVjiISg*&xan{8(I=|ORMzNXw@4A zaX!gq_mtzP7bUyPHPw=ZnSvGDsllsfM2yPPVl{{^z=^S$IvY=6$J03a`FGSC?$-xJ zOHPU!;urz?zB~~x})7~LTYIL zvyfOE7rTMAd^$*;zeJn7*6&E|38p_2rU-mwSoxBqo@BOQ`C%~RsgLAA9_*j}Gnz;7 zCor>hYL{E)>19a8WP9o80o$2NT8X1KG#>Yd2!Yi;JXIF>eq;0D!rMWv0(tibxh^{( z@JD~D9k%%aHoV~$DVw=&ycyUUe6FO}u)f}F^IvX4kkTAiHC^|pNL|I`ccB&%_}Gw3Q@e=5 zYV4V6->`t!V4}_ZumnmGNp{@xp1O(wxHd|zc0oS3C+D3I6rMQP^m&#xnIDa@&oFL0Ek7a51Z{VdTr__OcGEpy)vg6Asgh592I&)I1z?nR{T)=L9`A#W(&0*f^TFi7! zfQ{%0&qUp%a82UqAc+y9N2?(1nkrjCkygw(HgT@tC=+UdrO=kV2&B=zS}ye^Y@(Gr zEiTt$xR%nIzji{Y%#tlVTv9f~i6YGT-Ykea@hER&Oy$bSs3>n&jiVO{uKfE9Ui$KJ zCbhW}piN!)bDuLJP~bxU40&Z|e{{cjy4fX_DR^-i1Ui~(?w^v*kdB&*!d?wTG@x{h zMfQr0s7Bl)-kTh5jxZrHitHsID6i*&2C}|!CDzyBWzjGJgKv^NM{fW@&_#V$R`uZ{ zdW^l)XnB9OW+glp3Q>eAdnS~$6`PqKV>uJ}8Asgq0Q?i60(Tk5$7cDxt`j9WiP9&U zsJt~HG2s2!!7iA~{Mn%Q`v)(8UHXkS1BA?IJ)f`M_p6sbRGFNh_{^EK5J;;NT?T{l zL7s6pJYBaHc{!R#SG z&-9X%1Hslnhn0F`)u$Z_Pnq5PKv~##qR56Hqx6IaX_Ri-QV{C=LMbgvEfhfUcOso% zxDnlLQ}|ZT@GC+leSUMq&$osLo9VM9ib1G+ZQy~mxy<1Rt_EfJpb~!!W2Pqrg2khf zsctA+Bf$Xza_U{|E)W}%p{Ta$(IybU$SZc6&7rDLko?76K8EfxV3~B1T1aNRn<0H- z^s0(h8^cf>IYFB(E*uJZtm#Z(+?SQ#v7~Af+sHuj)5eZ;`5=y(DV@R;S7LG2eod?X z^%m`*&~*>TX5k#&w?cEAiozz}JR%@u_{M%6;-V0Qz17qXS?~NJeFjb*NXc=ycu?c0 z^)-S#uCKV8K2=%gteP6XhVfeSAcsvyX9pu2)Qv?ayV)B2YQ^;wgw-_LV{X8?`8kq{ zj_aB;FF{au@#-nZQY6lpsuem2>~IQ6=>2AK1@)B67LJv=@sQ)D->X5lS@GYF|Hcy+ zwQyJOZbqMJ>?J|p*wObkA50ZM1t(>k-Qnj9>;c7&rL&1-w^#~df9s4g5vYUfx7RR0e z(gKcaeu+EJVztwZ(2DGPxT=3L)( z%()c(ECg)tpgD2XgGx)PqWZA2r) z>n-a0n!vR9%=YqATdB3RriT<4yY#CNot&uA=x=L zCT#g@aVoo2?<+=c-;>kGYS+_2e`J||`Z`YTK#;Fe6gwtTJoagC^^@&Cjzi3+IdTIw z)16)5c1x1_Nw{z^m<`)&+#6YG3n27%O;0dLf_#}W*Hln(|NQt1YCA03OEb2(15}}Z z)lnX9x^Qckpb|0Aa+AG2GsWi}y%vEJ+F9s=H0GMN8C(KfzFH1+t-L9QiG)7{U_-sXA_D))jXx*^V)xSt!g#sq+Y+W zgGQUc*^)GhLLRrgS8=811Kvc%FS(UJG1hPbu%eV&Le2fb!rW`qadh=Eq-k_9A$u2Gt3fVI)=Z@7aP%7d&-Qf2E)te%% z@UFv%#gQ2+?|tHU;E;BUVg54WfGPtJ5%5Pfop)|N<^Eo~wmcEutrwT>8R`?}8Uv0fW>O9O%yEiF=DcK1?D7nvq-&Xm zjl~JiaK|v*>UrZi&T%07pLZLmzd*;oY(EA;t=AsB#Z zxEi*rgE0GOh+#*JPerFT#7HF`iGmY&P{jv<|LW|PE1YmG91tgZx~ppaVo%6hq_jv)Gp9RB0Jc{ zVHFbZ6@Rfr#zNpZJ{!Gg5YMw`h5sYGu487OtF>ztj(UkAq+mynIj!xy+kbjl(5jas zAksaF(0>nJ%~N;Gpun+ty-zaA6T%<5B86Dc(eFzQki6g`1*iIDme0Q}W$$*-I^L}r zDx@9J(TgtD7{ATgm=`^7G+%(s&}IKt>1-x)qa``su&Z~8>{Npv+C{y8wFNj}+_3$Z ztA7!Jkkg^_r)?u%wJCf07WZ4(rSOY2W$3eC%s%6jeoxJW+JM;^lI_;fi)~HMMo4}? z3;yJM)X}$77EWZdqy;0Qoa=+3V6{`7vI~jU*CPPPh4#T{vnv+Rd86+yl)YJ%47&&N zxSZ8gm6^4Yk9O|kjNU8MRdi|h%i__;HatkO=;Q^p&{hG6{5~CTY-O%Ep%+ES7KNjPake^e4IfaO*jO65M zM;PAEgUN0fpPJjbFRDo|*fz91NpxIGJx_RDX%v zOqY1We*DPq1-Bqds7t?mb@G)zO62aAPUlF8L8ahN*l6)+sPTGZX65;=%RR1=Ph)3? zmh&e3ND@i>C?cl#>3{ePf=;J$ryE@zqMADK35CPC zSo#~n4qZ<1_XMi$so@i*ZMBx9iRck1xFZ?LYylTZux~SD14y1S+`b0tMPV z{EpOY&w4ZI#s-fkJ*CBtC^+hzVl$8#;zv`D%C^)qnNP6Os^&XDo4s6S@d3uy-Sxr!iB8`waz_(f)sinBcZ3w5vQN>FE8gFC1n& z-;g~TR?S20-%Bj2gfZnzDPavTqVI!9PX~J9`sz=S1G~!RRM4ff@p7itaZbKb)sb9{ z8QG&f=Wd(-%s!jJvy_54r-;|Od{c9lYf1Mv*SKaqlYMA~M?08PZ>F^&nw`^FKRLhV z(d|2Uj-c3=*go!-cH8I0I8~n7;-lnnLVI|7yNGc^={>tDo``NRHprK5;M=tZAEZ~T zM(w4~KZGT7a@3bMTzUTRs9`E%zt=9hsw-22G+~^JuTCx|c^sd+dQs7^2i3{v}~CJnEROuRReeotaWn>9x5TtbLiPIsKED;oC`k&^NN5LiXmU-M)sf zitHoha$;My=j6U^l}ao}c*-?if-D4QeXg)oAL_-;0%yxS&32b@5gi`K+np{j6yTY0 z1{6Lefh`D}yubWojjAiu(#zhG8t&4WQkseRRK-O)4xAYI$aszJvJpI1@Z0RX?8tbKGI&O61Lk$>npv-LH}~R6(v2T zR^B^H2|32Uz+UU4KvqYZ{HzJkPyC@i-NmC5TePvS$?~-iM9VsX9OY+&kQ+rav%h!- zAe8500qM9c2`QtCNu=3;}Yl7kkXJ8QtD}>9`q)-;WV&- z*siJx@Qbu>4-4O#ew(A4PbX||Dn-?Vi^K<%h;6qR4#fl8=x_;ny`&*^!{H${vR96$ zif0TnV4cw_oHcFO+Q{}{p3=5nQ&Bf{N{sVCx& z--z;ydO<0!ski?6g(KZq;^VmtKj%^D9S3U4mCp2?V?KtLKvi?>4v-Fxdb!iS-!+JS z@1>i^t387Gt19BfqXSymut-5;R^imn+m&lhzdqC>kWkLq{1Krzx9MafPS#3ClcSvy zO)um`+_^M-;t=BZjuSR`rJ3LvSb?7(gj~NBo*lgYD$Mb!X-x@hp8YQBHwkHXUX)}} zO+~Z~es3mF14og;f^X4cG_ znas@pw<3_}6qX{6{Z%E}mLEx4*oTZv7%tL%DoeRswPb9y;=xVug(lfF(Tb5X3QB+k zVR_}~{*g-*#zKZ-LtaL8iCj{!>-fl6?)U9L+0D_I1gL81iI4sblnLdiqQI)hei!{| zOFKgXSif8Ee)Ob$m;Z_sq2>B*0-b+1cD3I9X4Bz`55kL&i|NE&=t2rp^ln~i=>k&+ z`T#g7a`cf)5A%CWHr&UliS4*r1hkJ4^~1j`++8owBhnT}T?cm+k;g6*O47T{HE-`b106J#nFreaEw61zmM1u_q?ZvI34> zu@XKCrGp%fE{#9&eHFtf=A}y!t2blCIIsN0yVk)$^C)^yPN)qnY)?olAXLtlXv9~5 zP7q;?SHjC(fT+=fQb*S2k1anwBTlRfHOGG!ldAs~61f+kRoMgUiuGq3Qem%ODe~Nk zKt$@kO9+3#)58%qiWeRSF1N@^u!3oeaN1w%sG>oUdBZ2#tafB)#JEy@`vOZ=pifws z{hdI)tySb9sO;R7kzqj&sI5yI!XpoYFOC%lsk@lNb-pba@qPsbzGieiXpWZTW6qYr zax+HDza#iNpkNnyIy)UwsCDliKF9<&nNdP&vMP!+c4aN-DG>!go~H{%Ok)SX$HuRl z_{dPFsjlmzGEy3o(Bz$7cY+FtISfGa_A#YGlPOft1a8;-j&=8XS%;B z(e1r``~Y7u+G5Eg=spbhF2vnq;Gf+WUB&3#$ae{qZTl${&5we(~d`!z&xTs#U(o=$td<;LKz~P$M z?T%V4cFkQvMpWJ1!`m3CUi5FcloRN?{sUDwPhsv62JK}kma~W_>y8m3_S9yC7|W}$ zB8uYiU*A|QUoQII_R)Wv$NG;$CUv2}&X;|`Nkw$#3RwQ@&ka4v;_CRL-0F190CjY?h5b`1SFCMy&19_~_=h5Lc^mr+zMua@k^^5k;+F z+i{^?JNBwYH|%#4Q&UUte2&-=i>=Y%539MFg`l#XYdMxSehan5;t zq^jp5dGe(4;9?_FXU4=h3R54M?#D3jE4RTeKqt=le~fPjTT zmFd1Dzp052%0PS40(q=(#Cs|^aUN8lX%BP>b4ehfcHrm&YY6?DaNjYca-V)6KP*)3 zdSz-x)SDEwUH)p{3-;}BRY~sdHaswMv7zK%+_^gPm+oS_{kMe+MvKNW_m>Lp<(^fU zdM5X4puT5D`6uFR;~HO(imw&_z;F-bUDwC8M669rB~M6a-0_$C- zUFEf1Q1b+d0Dc>FKLU66{HEP@aWfWHz)iY(p-{@K-lA=dIPraPq^TJ>gdM$)WyarO zjsbZ{n>Q*`HUL+r%}^r7bVlR2T~NM#@R2+dd&5 zaRuoKF!gOcnNd^Q`}Ny5Tf!Ee5nsBtV`wnrk$`s1T>Iy5Xch1o;!usO%itD6 zD_R>)uD3ARA*RuASyy(9m;wN8HHjN%S%KzOLLy{+>Nn_&`TB^D#C_| znP5F7jyeFy1>K!2DG0M}T%k6ivn$V=snmjA@u#63b?#r&&Bpk&y)^rF`W<)`>N4R* z$BbugBBs{|p4Gpe@SS&Hc~h+{q85^2dwsvlT~A)+N2W4a)Q>39`Q#sA6@4OOWjo+H z(xz6Wzf$q2#NJK3319Oe-DCG8$v@}06~Pt8t=H4^#jMD$;m&0@;O15&p(G%Llm811-U<=t2MAIT{hN_JF zz1@?u6uS=r`p9@^>SgeF^&Sa-D+M*Xm0Et#tBTro^WvKJyBwCWe0hn5Z*&P2Hdlg% zoQw-x`{}J+GgI(j!YQGidfC)#BB&{*el;SoIFw>2R`ZMPC=IvcG?LTK26OWO%T3_=j4MXS+&m-bWNSMzOuelU;%)>HS?T0k}tG zUb-2H9*n+PTG{)B=W`A0TO(Jd2b86QF|27VaMLrMm;C&QyYK9LIesy6wPvmq)aEqr zS2*{%C~v4gAe}urnjaIVye;r#!q=TK`2ke{#_+(`FN%^`ySMkd`7hP0)Bgf=1?KHi zc$OFB|5f0I^d8gk^Wf|k79n``r7q5*%o<@EcBj=}$74S1bNcf5d`Q$g0lQPrn;_2< zejG9B2WtdcD%N%s9=el~|1_>7@&%?}X+vuhL8hn+f?4=eSX3O&5GHkQzDt;B-(3>g zfJ24Ie@?V0_%3X^@+2IVmzcObydKsZtQzS#Les1zA9_>D=pOKHdJdPO@Jsv7_~`d^ ziLc=sq*pQTGyH}O$;=VZd?fAb<$cQA*BiM-fH(0TzHo@ zo7a;+%gp=ct_lKKeI2InIB)NBa@uzHUb+G{JB7^5`>h2S!xkx7<@nVuR9f3d;Y(8q zq3=yT6ICwVt|hkIBBdavIVyrIlXu=^G7AVI*@ua%u&=_MpA+j9ukZXdt_Z{BGh`>O znc~iZK2>S+SU&CJ8?1UvBJ|3XUf#qx<_a?|nH{m*=n+3&CoQxUu5ghdeQV}p#)HvM zz@`_lB&z^>GNE8GPA%>UV}Udj=o_uQcOeUJU;9bnlX-4#xgq#Tait5=5=5Ec%C#EI z%+_ZqtQ{0)`NucH=hD)H_Th-xBkVJ}oq^n_DSh@iU)QKYtBQkjmK*A?kf%xC%#@4Z z6d%x9@NPJ+wea^x+j`dLg1zt}dsOfm>d~ftO@x*GnkN{|O_M@tu!}&6TJwb|yt%Cq zQuPa%NZ0JvvmpLCP?ME|aNj$50gSb&aRq2a2*#;eJ=b?lQiJHUTW6=8sqdX;UHzar zNTsJM&so0+G&oe4(Zw7-a$C9QTiFTHH>2ShJo;L*i9a4-lr%AAFdi|53ik0%nk9_q zsPkTgoiI}$>2a+cRaN0mUC@l@B>?8Hz`}dcL$xh?*(R2gC9NeY&$al+u&3wrht!ol zZ-vwE@{(d4#kKTt-JqQEABEWba&wY=`fYxXNo*a->jPmXpnxu5vw@Vyyq|0Pc?o1f zlutWhP-gpiY}+H#II$ASsSP{vqkesGphv#z(G5(iO5$Cxzpvd3;=V^^Xm%{!cqitC3uH9w)#%?t^yy8cW*9#1H!fCCvMh|ihOtd zD6xr_E_Kv}TkccN-H8jcPRx+a^~5q(|{i#h9aeEg&;wqKIs`$XUWf-Q4iL^LuE}3$)3O zE*(0fI2G-qE-N$fQDwe0sx-3H0r&ADi87(@3+L8*de@iGA4whMkn)hK9gw_k$cM z-EM!;ljCRGq4kb0)Q_*9=FZqgSrNSETEkjCvMUEv&r!8XL6c2b>Q#$1lq5tunbt0# z&DYsYbM%dKg9q-EXZzJWf^ZhlAt!qgLAdk3n=DH4JQZO^YzcGj?FV?(eSdjU-{Ai7|Ihn9ep8Z&* zGX1)Uj^W;OXi*Wp&@u^l?qBzfw2b}M^XNr{Q;n@b`!2JdJdJ&SU^+#h`vZL{Br3IC<)ZL@SQ!}P8WHUd zpS;<4T;h{q8+mFM1OC?xbH=vVb5($m7PJC`P?T@=W$zgzO=4ruhSNjBy@i!pA~hH= zxus<83U_$PNdLZvF8-J*mO^7xDkse%=9|1v`n%qJW$j~Q-#C3iw*iuKE?9c#1+IdT z#ohfyy3JW}T94D0f`~`5*H6S57A?7AtnuH>pezhQjxoX8@37=-z8_!>4$E6}IZuh> z4ndKFvu(5N5pL9bG{(vAn#Edwo>`G+ETx}pkL_kA7?*yqfTle?%%vVl>$?SCL{U;F z?3ZuD-TulCz8iwf9agVIdiRI4Rk|NiVhpHSzJr}k(|w_rh{)*5lkPL6Yz_(3ON%2j z-fL{g& z%B~C#tlEK0CSISeiONbqR8MDloR`UEq4#WuR-4HC6sd%aKHO$jI@^Ri`RVFGPVR{r z+x;ff^LFz)6mv{gbAX}kc_DkUf{vl6*U{Ui}&fzJ6B{W9~(&doAxLMO{8!ls{q z>o__xSP=q27(Q)rk%=v>8js_jE@gFjSTAqIFrME+mLv_L<+W!zgl7#*xkTz zI?Vhik9MP{d)saQyI03Ig{yD26|O(nf&6~V83bp5?x`Y&-zPy_xHadIp)|AcYSVNq z$O<6sAJGj;98t0Zc?SA|Hd_h0*Da;Cqn@v@2EYl9m4W8>xcEThxjvn}6BVqu)%nu= z@r)Cfhxb*k7}o4#Dcp^y@e*^d<3*ipOw#lTG=D2+W1%lgQODgfylrZGHoI{WOopg5 zXtH(E2-DO~yomVxLR;AhvEdfIqnA1WFEI-b(YW^!smeA;*QketscP=Ce~_v zu~aK?mUGxtDlR|hejlIc7S(|n4tOmoPY~>uzi|MGcTc`l`;G)%*L{~}Za`&PXE zJIqe-kfGe}u=>~He|Z?&7t91=Je;46^nY^Hj7ncfL*8MTD_&#XUAgZ2E-`cV=y3bm zt$zPx7brO-hmgJe!JItY7%}Gu6G`>O3R|Ui(_Z42nA`yvkWrdbG(`gXrDiwgcQ)gU z=PL}|>(-H-6@SRrp=TG?mm@+gEFc3r zKWYR8XOr6IoR52!eI_GJae+P`WyG8`3#0R+-LEg)7<;esl1L^dk+b(__ZA4F!}JC{ z$Kh|gY;~sjM{S=;-hC`lx$t!Dn3nRC-U5+{8Lk{cc+k3ozUQVSV8GbP7m zqCCPjx1(>ML|eJRnbToFq4S5fuF7j}xiSjA>9zo6K@+R9U1+U%%$Mt!zTNg*j^(qg zU31G#yvoiiR&UETZ>zri zs)Uv_-;uI;@y7i&spEQ*@2`K#?HfLp4?%RF3LeAzMPN&BuDRNC3qy82JNustBm@au z4E`)KTKQNpqEb{|1sZz}{?iSyko0Vu;PUhJbGx23oRpNS6?E8?7J0IF*OR@(1A?V- zPM)7*@qm~b<0>rpD&A^W=7y{1joS`r^<6}eI7&+_Vqg$k81bJ}{=R8g7D~(7;e0!^ z^k@GBHXOXBLFaHq05uF(TIZc<`+u3`yql4rhy6B!tyeqrLZay3De@Eje_jrrf}O4c zb@TTYzu`*CPhVvI>oKmXj=n%$hkFqhNYCNt|Gx_Rf895n-0LtaI%=+(729tfwBqv5 z13rljM9q8y<{l&Ce`@QW%>7++|8?({E8-I&7@9j~{!h|-iI28&Ph)^5Isf(8|MAw} zA3t6@B-PM|@;xK=ci|qsX&?$cUaaiNKOES0c(34pdzIM;of4?C8Ksy1^N7wRHy^?E zW+@v5lQaKAn&(Fi1yeG&VK|GmNw@r}nsnP03^trxUjD&A|Jzq$LMpm^bH86SWBxu} zJ{(MN&fMkq-6Sw^D=TF$gc22uzP)g?nEHR$*1xMT_lQoch?`CtYx9){y8riyH>|vW zULcAH%AD9UHTpfK$vI5%zqi5P<|+I;GaZxK3yPlmh?_T^)=n4x`WCn#QZ>85$9;O^ z4{zhw033{8M#)v~-(Ni7sApPBPg8l){==1%+V2=nXg3E@MoE z)PA}mznD-#K5WF3i4bLTO!3kU7moZ7`P4~jXdAxuO{IU{xLF(~#26{`Ll@a_}yvq0Juc`u4 z4Lqyw*ZErZys^?c@&CqU{#^+-1XHrM>EC&{&rs@nVP#j>ziL2Q_4;N}REy2&BH2G$ zzpPP6MNi;$V5yw*U2ywntF&lySw889FwZyqooL-V>J~`uu~FD|i$D9odA9?C>P%pC zx)C)Y@#nFnOV3uKcFk)%@d{LV8dyA(dp{d2CLq-6C#HDnpT_>*IR@Ve0_?XXoydg# z^I*5A0Q!ki+xM6hCxqVZ(})ZIFCY9*?jX@;RiZ<-xnta+yCz|lV4peU&*B7N>QVj^ zaScRU#v^-k)ucb?L0L%1B7%!YH3rku`XVWpW_pQZn>dzUH3$^It~CbpMCewpVc1Jwd~$EpOBm<~84@oW;Jd2+ic+iI!FY4|e`skPN8gByhTT)CA^V0OJzSQu<=Cf8LYLe^ zIF#Itkw|;~m;m23DLM*7{wV)Lk@#P=2(194W$Br}Ypcy^la@6I(L2{4ul!WS2Lz8} zvJL|=JB4~%2O56d(EXEVLSAjv&#rqI6`_ITvoia?7WNkg{$HK>|JGM+4O>z_gqBW% zR4Food-i=Iy{^5#K-@g#d;LRBz^?fd0%+T$KMf81Uu&=vndIXyQu${w1rO_7ZLs~W z0t;*(x?wtaKu}CX!8qt4WPNFDBJrnt+{BxE7Jtl8gMwhSV5oS;Jl`{k#!oEmd~=-v z)gwZ!DlkI!HRIn};7Fmk+#HT0)CaF7zr+~y*6 z!J_kDPxY%lUK;(rL7VS4xYeceC#&0K@vUw@WNK9XuQ!8_>OjO+k6I*tm47iK|K|?E zoS*2(k*Y|Ie`h#`KfW#T*&EgJz*O4qKbAJ*&=bpTHr=0YocR0Yd}l#naRtN0Ng99P znpnI4XFH$W^;(i&?Q*H}{~B0#J&`{0xKV^!YX3vQDD{tqdL;N+4N(ym5b!TYpSv`g z7qNK9Ahi(u=b9DY$4^kavBUoP|Iq^fyN?Y~TW>`5;=%t6y$#U~#7&Ob)Z1G-EvD}O zF*SbqwwkqJ`uv`MjOct^N55xIn8shZpNL}e2T$BWd*Yu8%I}Qij+T}1UA$!usoaM7 z&$E1H{uT`l!e^u;j>~bB8&q?HdS{UQ*8bVaL8z$sO+-%V1=r9yCW}=Q zE?jB}myc7G$on#jn>o%y0(Wlk-bp}bCZTY$H+_DSFXyfz&1`Pr$k(2!n!fXBkoc&< zpy2>DfTbrAIc8h9=q+*yQL4X%tUI{Cdx0nO`8wsw+!>2pTJ}1O4=m7);Kwx?YQZ7{ zvwAVE+*$i!XS2sVE)7ODBaqEjl9O`&%DP4k;5XhbpMc!U|6eaM5sKntEFfWDcYFvw zhig(=D}(GOwr29_{=l4J{w}JsRSJ(;OXk)fHwyVlPP7KhI^Fv0`+01O&{R(HtMzT= z1=&;dUcmTP{_RU@sQIR>=f~r#=}vL@;2Psv9(&F+Dg0MqjiX{M95VE%oR2remT$J5 zEK88Og}_ihWi~l#xwX|H)O7A^`2)|qum^<2qE8{z_i($E0eeK#^DDMVb}6b}DPBun zJwq%Ar9j;7#$YpITlm)cveY))U2FVE9FcO7eXJD&~vJ)wl2i#f62t5Mm(fq(A`G&vHx(G`N}8|1dT@&aTxSA)CW zsYI`a4Lw;mNIic=x4bHzw=vv|5cm)kU78fu;b9DurK2`KuZGDvtbgBRJyEzW@G}q! zv*Lk-PWPX)WeL;x`u`k!XaR_I|W%PmUnHhA02L=$m!yjLm&sIl9MsUdxP^wQ{hjJe?Z8t@0JXUaiw!;FYi8TBXS)5pE*tMpiSBP` zOEw&e=Oc(p)qeC;(wkOui&q}5?(g2G_A}-DjH$rp2W{vhLUo2**3(@&KH60Q`T!l9 zV>cKEhkI?*9F?vQ^n;CMisNNse{QyG)qVvD9omc1+Sy_ke|7(H85IGmZ3(g4j_q`? zRZG_Yl=bu>U7rW;Hv9;5#`6ydl*T|u=y@TpY3R1-h2Sqk7`gRWKKZAricDDGvk%W1 zgsy$s?&myv)e}Nk+;fZ)d#vf=QoIYJzz;QCHvw_q^md_V4Q_H^o3soBdu#o4P<~|T zg~ysN^SQv=C>kGyV~JjW)Wf{PSlW{6t~JVH9`D20*z^72y}tI7x6I4$Umlsh_I1!@ zTu(Zgz8n@Nv58210p&9M?eOKCEg}&QloDEc{ejyF-kohnRQ5?Vunl(z?P&Te%GHcK z#A8;uzjLy_doH_d$=fTY7^5k@Ga>kKeyzWiFL&bOy3+`#$zFe z*Ka&iS8D9|%gYB8pVNHCJ}F~wHhWwpC7-Ro<2cVcB*lfopC{cz#GPibmXlz0pzfm9 ze%a-PMltQ2Er{x{`x-Bz1ZdxWqJB!x;|N?&`Lrjq+KrWV{?fCQ_OBA& zlq>Ik({eF+-<)>!s}ss*j>R7~ z`55^1IQ7z*R)2ZL+F4rsBR&F3xF+^2#c`Fwb4nnpAbPOH_Hwm0cMq3m@V2NK&bg4I zCOx2%^P2-TKS(?Zj91i7ZVl3PIZf5X=|-WeEI?qEwX)aa$}L#b@b7190F~*Z9k|S- zeCF-x38z<=D2~5xu4cNsEn2zS1z$l?OMaZQ_HcW@SF1|x=^dk93ANQ06_H~Sq8_$# zr$nxs7aEtMEE0ECTK}3%fBNHye_i{MH2*vaqjx&~I6u5Vb+65v;mfn4cNML$hMz(| zhI+xS6&!MN^XZ?d6S(E73@Dh;yYg_`V9k;zq=-=P(>1(z@O|>L^Ebxo=w05<+z9(# zWIe>pX1%h@A;SN7{-`%UfXmJ05upr#o5mt@wa>a4CI*}#e^Xlrojb7x+Zudz7UyJ} zMRD1?hdZTTL`Ys(Ka!KP) zBA7M}@OPDe!`YqE!FJX?mu%i4wS9O;6pS6E<=VkSnDV3{cd|U zJs8h224-Zv8uOFzdZNy)@PB@qn}O*pnEvc6je9Xv)l$Fl`v`0yx2qMgMkUXfeR%Gy zQnfV;3XwX>D6Y*|g*tLJ8AZV1DQIx8(xc3x0e8PJ}6$%x%rWj6ME3#q>7do3#lS^=> z6aEl`J7JLs7yUZTLu)Z4ctkuX`G81NvOj z^=5tlhL3Rj!nfoKjTO82EK{wce$Puk-jcfC9{E5z=|* z{=(QczPfHXR=-rKQ0p{8tHovd=wtU`9V*YhhpddERSu?EN$&rZpaPS|1|L%qJhspHX3Uk{ zj{6~}S$){xwj*XUrPn{X`A9}zj8lHQu&2@#L5RnAOOM=I@7sAyWd1Y#_O3g>cAhcx z-C?j}tfUm9)Wo24bYKczBD_r zUm7bqHWdBLKkp%P=s8|Zp&RtFkc(D}!)`dAw_+xY0~7~ceov?l#mXVmrOuBpT8lW( z`0hP^qx7QxSMIg1&E`j}tM*uxobd_Um!XyFHrK={fD@D+Q%@t0NG7G%O&;%5$@-wW z>3L0IIu>H15x!S-shezbSJ1(KBbOHGiC!vUc!E+6Z)Cp;*%wg#oxfuZ!*78&KFT}v zFP8w?IL*sw%xa0)L==_z#lHRv$ja~O*WeqMd&u4#(H-uGl|06+m1SKc{n3pzsW}kK zq#@PB?4_GJOP`!2p64wF9YzPHIu%1Vu4{WpvBb06nYfEEm*Sr-)t`4o!1(jQxs~)V zs1iM;X4oO6P$8nb9E^x?rrS3j?8}goBu{F}uiCE+@sV_2 z<~FDFT0=_Wo>E`(nR=yBKNn|H+T*TNq^VxszcKi`>Nd~IvXxgE*2rAlY&BZ+8u*gI zsC<RvOPoeu6aOp$ro?LhdiD@ zmqzzL&}@{Q@Uex@kZSVU7y83q&vn@Q?3bMjEMEID!qCyZR21fs#tUl~cuk+Am#i%W zxzWRnB3#MgUCNek<70iav?|qBZlZ)&?TkMQB(iEkinT}2m%tRD zcG@1_6CWQD7%~LM>?9B10?GMQhlNHVntiN(3K~?I|ES#Pw}|oX6t|r?!DokzR216# zw;5aKCUre~a@BFq7nM5c^XJ~4y{uF`bEhV3|JgGi*<`rFZn53_-#AJ`Dux>0E6HC~ zdKm+=B~$Ip?%-YE^xknB-~%5((gOAz{vNm? zNn7gTv0j;k86U?qP@;;+&htadm%^FcEN)9;nz`^z#XTg_bnN>WM45?ekL!%Eqco*! zI%q^q7h*|XoA>K>RtJZ~oU=N+ij5e_uY`4c!?*a!D-!==U|nHFX19R^=AP}M3m@-q z5@@lUAzktskpPD$v36j?2(=^qd(MIqIYFpx`S7L$mUWBp^CL%q^PEParz8Ia>vomx z3H!ni+%EUu^R3xf%1!UpS4;t*kH33}nlO)#V%JpnXBB^$G%bmL`gFY{RE?Qj-X#_F zZ9dn38j3r)AWPS9x-EoS2U}JMw8%(#29Z0X{N|Y<-pa5dPC-<>>nqw8X0jIf-7mM@ zB?{5_G*+oa@RT;brNv)G>f@0}B0sDxD`P3xpG?H}--ut_c4m!b``bb_sw;_;f(;-> zDS;?m6s!I5A|>&$0`U>eLGh_&#LF|Z)9j~d=8+RvuQS;vHoTNqSZOVSve4ju+9bXG zRSn@=JT{$$sRy*O@A>NEzmFmKN5CZ3&sEmoZOhS&zYHPySWw_Y1=bXa9bnlE{G%(a&1Md*f744CqcG`u(5d;> zhy5YifdDozP-o+Jh>xAPVAq}KV)s|?-;s6g+){7P`J6f5x@@%Lu=)q-pVP= z!>#QFh*4Kww6+TCNWRs%yO|alopdc~Fe!oB_##N*s;f4h1rRru<&kHvo@ZY>=6y41 zWQuTMCztT_t<|Ykrorjac^EzlAgjYaioHKK*mS6&ZnDb#2nTdm~R(`{sq$w3BL8 zSz-aKKH}0Zy~+QJOU4DA z(r>)vM_$Rbo>8$u*Mw(^0JsHpX?W~%0(ic)&Lh&1NQv{*Eyg}BWN#qpl%q1?Kjs`U zr#jZ>HNj!mWGCA3tAVLa%wU2rQA0?Uz@TbwYU}EU=pEY$Jv@**(5$@EaNWab z!jY|A{`fOHVgnLrYX3Ea-4mJvP3R+%3_k|gV{HLCYqjIKa_{OZh|^Q|*+J}L;7_Y5 z4QMjKc7sMMGQb)wRP<%FQ;Ed$vhlx&gwTtAUXfk_=+^ScCL~l+*>d+Pu7=CB=dv^{ zR3Ed7!=JUh9*P`HFI|oN^wJ@}gcBm1v7DLqtaHX~-c~nWd}!&&jbbSYji7-`vx1f8 z@H-!v#5la2R=HY;VxB=gl|1WQJb7yI!I2lATYg%tF0^_WzGj6loW@9rIZF9DY?dUH z!y#IgNFYdSAI|$|q!TaER=q$Ro4O+-D2>UkqhzN_MejsEjXUz{VwDPX#~yPDj$xki zm_yVr4=9A#J3O+}pFXN5dCZXhTxQi1d-Wg@&Qp5%^9cdflZy{MCg{672RXxd zx#xI-(jbDd$T1485RlJ(dCqosL%#V~t;(6*ysN?r$GR`a8fh(E@_P$*<^>rM%}``<5ryX`CO7tqqD-q4y+5;GC79xFDxD1 zZ?M}v7z?Si*VNIBeJwXb>UC~(e|tst5IJ2N7Zds;<_q*TsoQ!TAYKv&QTI!tVlS)0 zvqMOu=5Wvl=H!=FW2GrGpU&waNWzoWE`pE%7Hm7IA^Kn*eSmyFQ0(}A5J*PMML!UI zkU#kwx1-Bfj`zuUA;Ye;Aj8ep)Qa>nZ&!B_b&D}JQD0^TY2~OV3GY{n53`DO698A0 zu?Lnj6GYpxx4P{#gm?LPD0#6xN7$|;ae_+u?Y&&8@PQ1$ZD5pzCz0$XZNUS!CP`oJdAG zcGMY;I)tM?nE>rW`uql+I|w}Q*I#_)+YgcwMRIYoVjj5CUI3*t&&%#U;oasz#Pa65 z{Zbv1+!E1jtuI!I)Z>)|(@r9%xDK)LmP@Rh-LH4az(Uuic}F;U2tj9l0p5m|dRcRM z5tgt8k8&27$edpVuwy+U(;l|3jg=*n<9CeL@XA`MM(~6BO^ULCH$ll#XWpEA_R#48 z{=40}!LsL(?zZjb=M#E_qQyTwMWzfiI0os5&z;>NWo~`QtO(oOJz13ctV#`IV%Ibm zqI1wuudPJR4G3&{aPXkwv70J2-urGhEDw1-#EfQ$p4`Ykc+B<9vr6J<8D;zYPo9tK z8nfo9hKvgV!13MKffcpmJZdl5(9iB6AFZc0l?q8kfz^iKLppS~I_IpHmJG%g0yb#Y%*iD+%? za7#4U<7|b9yh+5boj%g^Nn<~Qhfm*|OP0@c!KkP^%SKXHhb-d@u(GvYIk%$fleI)& ztDHxA-_QsMTrIYMu6IWnGUzqEH{^9#zVvE-zdCI;u;US>ve}?TX0u-C(G;#`O}jG1YS@ZVU%fc?xU^b`*6Wt_ekI?HU=&N>+U<=u8Zz6R<_WQ(i94XdjSe%GW(R|8kBpmu{#qgTrYd*i zy=%fX$Zqtk`ND|cnwG-j^>a>EJ`SU!12!_%ue?9d9KJo1RndH z4Bchhnus%(zYu(eWswK~iA-(`Tq~|him7xJGo5MKY?p0iEN6O2c+kKhWd7bLguh=9 z1}RkiY!R!k)n7?XAl7Sc-Zl1-|7RW+7I_Wd;v+9Uu6zQBpon^TNbMThsig89-;Z0eD9|!=WZOPv z`)%Ohfcx06%>AdA&1|MwwG-0&^-ueo(hSx-us^@@E`9_=s7-PDE4}y0r8sKnY;=6V z%8)dB4>P_1NFHYJq8Qz1$j$1px(T~rEZ}pH7HFV)2)G|i<@1Lk?l>_6gGrLuU+$$%kMfjedXpGZl&J@{ zG4G{d2;b1fp-SfCOx%O@Oxy4h@#(t3Bv*+*IVgmz+}c%d9?=(*>)Vfr_4X)J7`VID{>gq-FhE4J{?{C0F*Pj1sl(&VfWqWdZY?`1VMsL$8B<slE!nSsvjthx=qx{jGxWsY0Kc5e94 z(}UrKfi0i>N>Dw>;x$0M)ufZTW#1{f^UE!_iMiu|9&>&u79AF?nmhXwtNV9H$-kc zY7$3v5730#$jwu`*2SPDy?wZlw2o84vj`qJ$dz_#y` z*G0KX#iyrUyIj+^lw%_HJDXS0yJ8bX$1XhnP>a8tFF78QN;s&z{+G9S@vSe>rZlvj zKhTV0Z)k*@)iK={{tf7?2as2a+$NmRXNL<>_L{WWA!aOTy5B_TP}Dh_@II_^P-N+Q zOd%FA0$Q~Iv?D|~kA!`G7KzB)zf%^IzssDBuHZ)998m23p&ahj=cAQ~G;wZQyMHT3 z!9MEg0XqQAVSAE{xhkl|Y;AH*CFXeM&fEL0E|5KZFPP2Io4CcitXyRd5eL!twBXs` zRzjePCh2&I)iDXtric?J2RsHbY>lX{O)8>O3W9PKwBx*}VOtg#45!gnpgb4dJukxn zzYzO;07qF~H`XOdw)5kZAf=Rp7x$2*)Teb1D%E-+s9lgDeR3ZEuRPxy*TPumz0a#c z)7NpE)I;L8{VbGuZgcTW|9uiC_1DPYF(c>I{-ADL=B`oDa==D8;i^ zdnJzg^VxC^xRTkzy0@AvC^?VbMeuh&SZ_w5L9rRkYFm=4hmL=)Qnn<({WLFyfKrV1oy;ZQ0wJS|mb${d;t!^`MsnmkqDhSt{?Q59-6)5*K|blBZ}>^Jp3Ut&?BqBn!f z3(}SeYQ7RN$`mZcdjTV)i*xAKarC0V<1HUthxNUs3Do4yEB!Y&XC?_7aD>!Cji0a6f}5o>ro6wPoyg=5 z43x!9m1Hk$5KZ=aU8!L=5Qvkv^y9Zb7$M4xvWZ&1=0xD{z$56r`mI8;P>*=`=mr>7 zBM&ddvuWL_;@b&b7I;-@ndujlbuX?Ht^1 z3++z}@1nprHz*%MMcmt?Yni zhn@v;OyjspB2bVLwtMVrc~{m}u!H&5veaz+9IZufdHADCSeFsSN8OIiu@a zKthQKQl-}ru+wdTNJj2o-=3OGw+;vW2kz#aA7eBw!i~VFFrw|x!mATnXadh!b6K<2p*^XKMGtS46%GWq z7>oB+cEqd5+l|jJbfBh#!b7167sq%ve_EL9B5Mf>haKIwKB2hY{=y?EIYMnzT=-|4 zGOTSY(H2SGNPg*|_A&?C6%%b+fRnI1!Y3tlaKDU9U!+^P;#XJyr0e~kBPYZ2w1zVd z*u;m+VEx8|C_=NjS1*KvUrvZ#ywf}T_;GrPmS8;JuABdQ1T2Zl_4dhm2w)^+Yjsat z7&Ff^ z6+SPA^GEks$aSYWTt%D_*m`G7=LSJno(TGTHqQ$@XN*p~;kj8ztFD2fdM?^a%sp)M zJU;ECXfR5=@P{JT>b+8Rw&Qc-b zP#DEmv8u-xB}RJvD$FI?$VGZ0+AK%jhJ;6&WL|PQ0x46bJWgeRO8qyj+kzE9!k=9g z)zCP&UvyjpYhF7^y{RK)(!f~kC}=6(j~9fGhF-vH=xs{$nml=5r}6AO;aom z(lQ${vN&HeTMN2l2TTM)PbKz2>^{Zj0vLjO+;OnN@{47wLlJ2OlQzMZDP`RaNvxp` zJg@<0ojkUeJ9@J0oA|CwUKm#uJ-t&(5t8Py|@5qJ@ z*UyZIBi#c`!#8OD-d5>#Xs(7Lad3b!`kog!qET>ach`ila(JUB%hVTQ;~=Vi>+7Z>z1VLE`j<95?h7Ca<+Ymr3)s7fJa_Rop+?#hmSeo;pccj9R?xHh!iYWCu0jZU_ zGj>m0Rh;Q{BCd0xtH#+~3pOq!T5q3G$S)#j_xNg6k>Suynfu?9m@$q6GnCH5vn5ZJ zHDASkpBZw=A_9K{``irg<37lg8QLt0G&PNM(lcSgQ=v8`Y4S-q+gNm%r z@FSFU0dr0uBopD~$Oo^O<GUXCquY!VuS+H70Fs ziNxLC_USPYRJA>ycer8p*UX_)P*|?wS5TwRIVXdP^6f9q3|u(w8mR2`HB!#2gK%sa z6?X+w#^Z5^@CM4sp%!9KDbRS>H$yv!m_;FqVsRjvy?bsJuvibD6d@K&Hnwh*)aRA) zHPC$lCRW#8;u@mut641SSJ$*c&7Ou5Lf@=kfRN)4hJ}?42RGznQOJAO-`2T*vZwt5 zCqz@i!6cV@Fr%KV?{hG!!%C)vgQy2+A^mB^IuMgGCuK-|@<=>R7c=hG^wHYYG)OaJ zYZu7#O8<7S9)|wG)^ey~(Lgcu4k}&@-vkN};v=C(ecOFJ!^dc`QNAC+4Rcl*9W;a3 zCUU%iH^8S*Ncr?M_(qE_h?GbH;I=944ZG8d%dMA*-{YB%`mkysqhe|7v`E1n7+R0D zu9uY&wp1%3hUr~)$F@!_InACC@cig0Te{A!Op;c66_x@C99r0m27{YNj!us;w@{=s z_kQZ0OmwNU3cB2KHcMUeGjaV9Ob8Vim<9_$hg(IMyD+}A$xPhVB3z(loVgN9UP5YL}0ino=_e*8BkwMhj zjAfK-aHxpiPYMuu_YQz-=+4?qp7hB~OndtMnz)PE#BY_Z`k+hoszh2zx+a)sog(nAU9jRPBx$BgFvWPo8($eK_5M*nWxFmXTPH ziQQk=$XPFS?T+QyzGz>gtAkVI0z>xFA~u_Y(DGSJGjQUGhjgDm4&0NfkfQImbS`VP z)yS!8WPfTb%o%|3a}cr|a#a5K3rpq?oVOLo;1b)`$|AE)1P6*ovVO<3|h#!8avntMe@YQxI%?#Yvp=kW5e zYF$i^jwR_9sX^&OEpQ!=;e&UMzjwGk#3hK4v+D(xJDFjwYcY1g{as zUP9l6o%u4oL(6+f_dfA8V(fb5m{z}CSWGENtYr8zlE@V!1zYGw{{{aI^UY0wW%^WLQgP%Zay~c`*(%-p_Yy=Eca?Q!hocg74 z<1Ba`%o6@-aykOB2}TS|>q1c%!y)M`K&q)yxId%q`ghAa-^sQoD>A+Iq_ik2sH{La z@|%5#xPR`b%l=5{tP7}c%S zuULs+drC0{ynD~gj_Pxt(D|_U<jU~O z0o=5Olh;A*DbuRH!amsRI^{fkd7T35t_jJMqO6KH)6(oguCXlf$saIJN?XO#CV zKWVFtrzNpl3J)pdO|n&fzPj`nH8a$CT3OzlncPtA9{5myF*SZDh1Kpu81b77XggKr zI$y#?>>s5xjY%`7S3Kmf%{V_s?eJ$!VN9uKwZiaaTT=LX2l2X68Z0}Dk3_&q>laC6 z>xlzD)BeKgo6bEmLq$(4uzgK&2brbwvD*lMez%6BeYYayPw;^fo(JZ1;RkK)(upX( zh8CX)KoKWG>F5lf=-2D~zQzIsa2#g|oROlx@~&jFzqzh`>d;rV&(w3gW=@<2<4>f6 zXO*HX_ch`6H96$!S^INC6N0$aN@B-zR&OQ`jeaURt0NueEsfT2|^w&6Hg`6Tn3$Th_ZbKe5E?3r%+T|tor3+~dEP*f*O z-G5|Oo2E)cvOSe$mp-%9lhuHX{S_v6U?u!wQ|UzAhqfhPV8kcXCW$f{mcLy*V`31* z_@-9Y^+{c~DDsM-aw+K;f8t(BlAu*=z@bC2hq@$aKMa%aJzo-tT(IJ{+i6h?$&MI3 zkfO#MD2qVStF1|jABXS5vv#|z?yhAf2MEra_|KB2zqKC|R>W*iC{Tx_W|Fi<`RT1l zU?VIaZ7tJvTD3-`s%Tr1bSljI%X{0$mz)3R9d%F1&zxy`Z@978~O}z+-lGx%a!% zxikZXQt`?krn>@okG1dsVan)bb~w&7b_B zu$AkY8AgM$J(g(i=lDJHkFBR5XekiwKo^lsn?>7E^*e=P<+WssLaQI{E#9zzT2V2` z(UOQyiWbdZ|4 zgZ?o}2@k;f0Oz|ys$qgcKO8Z@&^cE3wN0oqY@-EGb*wWMr<4yT1iqzOx;(nQ@KP$_ z3YXjo*R<~^T#B4#-%BItX8JDA_sh*fxTW~6pWvv!HGVc+%wzI~4Z{C| zAECR3Kv&g%zINAuRlp%etG%UYi$sLRge)k0fA2uy%DcFrSa4bMT8oz05)>6;P#lC= z&uDXqXwx3+;YTG5)ix^dz{+`RjrO$oSRxnoQBq#r?_L_D7 zx07i~fkiiAnS%x%bU=5kL7x!B5~i!+@Tskx$d6LKF9pF*K5~0PMvra(k}cC&N;m@x z?FqRE{@raZzP=}w-`ZTTAlhq11p&5%eh;y`fDPrnduD&rcMA?}CK; z=Mt=5TNIInuopysO%w0(u-}E9TC}-3pl0<3Ka1b=T#}xuT}{*8P7n3p?{D;u9j0d4 z+{c{0W~mOzasQlE zYss@kce%P|y{fnN`GG3a!~H`3Fb$X*4ff zCY9Ii{I+bJ5~(O#Kfh6G69r?Q9{@-Pao=2<^BlHf%=utE@geCg-AHcUUq z2Gw-2HsRTlu+YjqQA={JKEFqv-I0gpJHsapjDo&D6w^v6p!scZM8zL@wa(vHxJdtP z=6^|q5jduo8CkSwvb}|SR&HB<-ka>S`DVpcm#E=`yV*Il-;bhZsBj}AusI(XfuW2y`Uv9nNm;0Jy&5bR=v0p-PBs|981m2W~#_a|f+ zZbr47zvvDIe*NT$BaG0Mzetve)`F8RQym-;sR!47Prbfn4vzn}Kb?%9WOOdkp4jk zj|mE@%pFaNEIomqo_&@*@_Ee%r4}?@WT0Sy4uFz^Oe1U0yw4gbgy5~17T=m0%9d9` zOqpvTXE5{l!5nXq${+K9XN`CcunQBX)4cy_VqH8wyA)vkE^UOCTM$tr9X9V%7@7B89xIgYl zQEwyOjg|%%7m1sOml{JK=K2+aH+U9D5fIj|oUK~81H=94u=;=@7-U8>!pAQpYtuZg zpI`njM1#f+4$+0OBg8m#>iJRblE8$HDR1o>H;RcYv>#?n&h-1IkrKF-3nzYH15+D48=g<+uz_r|L`OJPcHo9`(Xf_ zLg&W0e{v`svW~==?j!lMiP8PlXhZ+$Z~V6hgMfGan`-QIxQu=yYeO_`HZ|_aod@QC zA-{QvV@8+$reZ{ozPih^sH<`{;`~3a@Zb6RKgs|Na>i8Xpv^glHEMT`e%0tO(u%9J zHDo<&&%WIHb4o5SKGK@^A3&4;xk#Lkh}z9$i}C?}dhG+gn=?y~A^F~WHr>Hn#Gmt_ z%T$0QPbAcBSlrttXMT=rN$f8j8*OaL=ggBXmMBLI3R@rQ&a1en%c0 za{Gr3{jd9GNWLzDQ=f)LsQg`t=IQUzN-CT$|D(h{?2D?fy&?e^;P-ztc>Zr|^FQBg zkOV5DAv>J}{G98@Mq&_&xIrUNjQ}=u2PRCPelPCO-(2qLa`nBNR!?7-1wM6@@A2le zSkP!s`612C#Q*2d{hI@V{r=j|t_T_#4?L5?l8<|D$#k?zPYY{o zraL{|V;lI6-p>kO`}u$JO#?Thd~xV6JcjOmrp!En<-90XnQZQUR|lNGR7_h2_#2ZL zB~&En*sZ|7=L`Hk4V+BVp;G&=l6O#!GTBv_sTv4!cY+sXb&>y*PVsLK2Gg!E53hud z=nem)vnv*gGAS zN_YIf-jkdG@C{?fUsv}|qXZCVNO0;#lE;LuXZf zt@HF=+qxIo$RYFD*qTk{cPl`2_*3tD>|d|&zaM)Zzlp>i)t;97#~?QN?5{fS+jwtb zrs-w>zclM-jeCtO@y^eGf(5Kk??22VZkJQ_v*6#9=s*4bz`u$w?bS6m zGHa}(>i7q>C=;d`Z1^>>6w51?!P%M=iZ}|MBZgA_th<- z-2-R4a}FBLl>A2l0hlltnEp_?wX?hf^>_8&sC66wTI`nv^Nz7#zX!lvSEm2t9Aal3 zdhSU5-M9oa?iwRWR3!9DCqK9bXq{ie>>j(0{SzDJ$tP6Ds8U28zwlqDUH|=N+K>O> zZ{#{Z{fl()@!Gw=p47&KzjzS|2p7!XVp6U-H0+h@!L2|pSKM|0ofNwf$Zu1sVLL7w zBD;6-0IUVQsaf|-+5W#xCf%=I5nJX#Z0m!Y>jCdGN<5|G#aOxeabLnZ@?Vd1;8Nge);#58CxUXSqxzPJL`|=|0J#&285sQmMRSyF75zn zKJVi@aa-@qv>t7BzXbVjH68{%uGFeh2?K|few*=;d9ZXqiSVR=Wnhi^Ts&UMr&m8m zT1_MEKHLIq^p#I}YD^vA-A~1<=khUU$%aAkaS}&LMQ@)$8nL)iy_Z@KG%PbV%MiMK zwdEm<7vy;*Wqm}nlr3p*KE#V~TQrt>ccRdZT9UyE?4<5dEdDa`Q~9;B_SSh-Z8|f` z?kcZeTc5gp9Q2q)Cn2@~f;C)1~&1X=`HUvH$IyMt-_OLTx;CfccTADUmN%`lvY;M?oM6^ zpDV}@^b9xh^YbX#Vgku?KeyXYJ-)tlCOK^b-#M*3(i3+1tmQs+wta#8P5hs)f{#!q zEf!5?jhFY9r&YjqnNMJ!sd@lkmjB?lOkn#k(9GqMzgrXKz+D5xQM0?JQ;QGo)9M9E zjgrBjeUFG~ymH`aM*4fzRb#4%*Eh$ly&#VJv+!$YHovv$mU2}JXW%VPe!nO4>1jcr zS5kcT*_@A+UrSAi>d5lyzgn@FNe$hS@hV1o{%Zm=EJLiOn>fgJr(&fIx$vS|P zB3+k7>spq6vWc)b3D2mp=cxIh$ks>hAzktPC3|$pl2x``gfri|AoYqhF@`SwT6&eA zarQrZkwspm1eMGx3f^@8FYQ#i$ZWl(J+ya2&vS453STY>$lE*=AM)+iYi z6bM8bgWer#rrN?iFTGmYBQ|I?3@Fpr0OCPG5ec*$(v{XQeo*m4+*0e;@cNB=SQU=1 zVqfvAK70@7IOYTaG740}xUUPh4n!+;tIPpp%qNUlEm?=GNo>LH#0$@yd=|e)U|8tUd6(`fZ-=9xp+%GpC4cXpGn8-4U7?arvzCCLcrufXrh#?3|y-ggOLkIvX(WOO@flTN>J@Z*xG zhO_;U(!-*9Tc%J0544hP0xT*VwXt=aS@VzURJsYbK$pCaNK81Pz+9YjNeh3~ImXA=0*}zc z)ty;kV`Mh*LN@6Wk&LB%jWZ`aV;$w{r%GSTmy(W%pPpJ(jhLU8$!86s zFah3+oxu+|&$y^?Y%{4?Y^-;9xJlgRDlb*+Y?(J?1NIlE0oUI8c>TKEarW(fb+K$E zvAAQtLY|OgviaYi&Q9uWRU`)ZKow-is_KMakmX}n3pfyb5muih`pC(jz%grnnwcCu zgYH`%o^LQV12=L>VE{#G3`g5T@_cFrGvV*D_uTsrJ+#cXF&fsjV?_XMDCDJDMb)ehGcRx=D7NC z+;nbLQe&j9qJNH;^q;GPMm7scJytSs07u1}?pNAx$Y-6N{$v(s2!4xH$TohZ`L>88 z^-8oz5sIJ6rb75-qcWR}xH#TSRBu4mqy`1~j6+WXvr0?oicwoI`s@@%~e-huB zv@H92JO@HBnl1JjmJ&nGeIE1Pe3P&XEmwWqf9$4S#R-vD-_NEQpVz4Y1rIv9;qM8b zx{RJcoW~tLd*+RlfPOXfa{mlJ2e&9WI`<75JF7fZDGcCg43?CpQ&aD4&37qn1LN)J z(a$e@up6&$4@)`iWeHx`3%Hb;JxMg(*QJfpYAewZzPSQt#~Iw+nLNjVtPJFQu3yn9 zz0_yC&{mtp`Vr7_FxEiaoi%+VbWsyC?jSiIJZ8(nPUb zigfBp3BLzWBQEB08)R*-rC{sZH}lGKgTH3shmqgB%5h8&1;tBWEib>BpQi?1S{Bw$ zY#5Wt1e@hM-0Q`T#LC{t3vR!;Gl!?uZz;B^yh`pnbsMIH#EA>2z9RdADmt6gQRaSD z*77Sui#W(MER1$Ovu|j>y6tprYnfN#E$Rg*|09pGnw%@8O4hJ6C&kRzMd_xz%IqqC z*z#Y2Ef+wlRCn!-PaV@%4wc3w&IrxvyAG4F?i)6_U-E%)Dn{PAYl`-9E$&dZd>?NSAo%RIAa+hyM?^iDnF54)44RE zF7~oXZ??D#FHybr$ zqLG@Mywk0yVpPOO1%==qyGQ6!9Bmsk-+{){!HAgjka@(^kuzb7F*td?{)_ZN2 z)&kVZf_3x!5LuHrHB}v0s(@#wJ+WXyY&qCau#CRb5vCxp5=2X*edsXTpS7LH0$!i} z#xJX~HT`T%mwED)?Z9CRDZ)ZxCw+`TFbA9I2i?lqr!pA5)zxw3O+|QTWZ^XbI_DWJ zegn4WW*GTtd8p23oG_>KH|IQTot1A#u0 zc|uD03U7HCib{W?e-0Adjqs=}WTjd~lv>~BvafatB;7oDn>)RQZ4v8y=j6KwHw$qa z6@iLApS|^ZK5JvWL#{o`vemRJa#fEBTlh`J9ntYe*9~ly)vx_hpi$_9e@P-x;}6{r zp50kzIDdY7+u-S-Or)t>+Ac43_6uZw@(2UX^Dzq zF+gRz(75cN_9A1tT2ay1Cc{HdfK?r2C-Df%q-?h=HwXkcXVOaPUZrre_4_ zHFY1e(?6d`RHPF<1@wNf>!NLL$EnxwvfBzOo2J9efvjv$O`R+?CNI6(PuYtz_G9}) z>F2u=@*$-hJvl2JOnY1<@fZ08wr-?sh%j&|X=D}VlLqH++FV@=0pf^j_i5==TY*sb z$%&8Y2Hf^i{8ZCtsIjs~G@mg)DYrZH$Y(ldeXbo?Tg-@I9j+rDuFfdcfZ?HXStxUzlk-Tr z06lndI5$A>oMjvze!67+x`g6VpKY->GVpB8{K%~S1~IAYcON7j-*%rsC>)#M4{ImV z%F%V8BCIw1D|R>oR=t|6IOua2Bm7i2wt{-bzKu1=$h5SV59# z*O2`+=K#r(&Uwp*eCy9QzutV2_U&|3vL*83p~zuS#u07KulhMyGlSPP4z1UC*;1G# z00B_LOb`ve`pj&&J|g>rLpH?0;jzpT&8|q6%UcueJ2=k!)TZUG)|RK%Xd9Kk>l`>t zlLP(kRxv33=q3rq9K$2F)0ZYPquw8sl;_MqhAe(t%ZOoV@Ju2o=b;fBvye-pTBeo6 z%A4hsTnUL*ICpjQMdA0EF&=MClUom*)@PvZUUFS=cP zo=<{LDjvP42*f!WvO=(K{g%U=MBAS4YHr(mJ3~N zV%n$OJo5FX)_3$7w$s-GJd6`tU8Hwd3=#|8+^5DwjEsy8QX+<&Q&dT!uku^uRk1c9NP2$J z>d2WMru+$|1W(m`-ZFvB>GcirVc#p7EAvn)I^<=^M#L)d8CK06v~&m5wIxm0Q6KwW zpt$vjzO>Nm^gUf69K0(nyc46LIOV!%doJDInwAZw9x8{MSuc^XAa+JtpwsWMkKN|l&fcMw0XU?i zxIKE6*QcA_{@Z1Me2>y&7blva;HyznLn)iplg2f>Z0kVRMv||4Kxa6qIc9DuJF9La zMtxB5!pbJc{z5B1ty>BAx-b6V)^kw$Ei~;Q{9)PE%3tabMzR-j_ja_Uz0A++0m8z` zt+T=3qyO0OWqdwlb+z9Ct96HNyiml?|Mq&3k#27W&v~I0v7>%>BukfVk%kcpkG@*@ zOV`cbd-{Nn856Oa`@{&c`7?-HQmxJjrYQ8=9otM2@Mu5mFS;HB*?mr`sv>XJqHUap zNFq#T1U8RrME1Z6IRvzzA!dx^-LZ|&cOc}Jr+k~fqmyrsCH55r_a|LtJdq@+uM~4U z5ja(z!D?v%lkgTob`nT4Lr@x7>Y>cShsrEymjcqbhAF4rwf8D%ji!U2iAolC5z}2 zy-8XQK5qE@p;-Nw5hG^!P#*10j^frUZ!-vUv{F$KfI~L8O zwq}?xXg@oEud;kiKGkgb=AbN>R5kUU0d&czyW`c!cXx@BHg(wD3OF>a2J4$118-e% zy4J2~I_+n*Z=UYGNfDn9A*s(o7*`Pp*)I7xA7ovq9Zr^JYx+vQSHGtkdn6Pv)oo|) zoJA~;gr%+*Z=E(Pb~@^EN^DA5P1A^Ck=UxX={xciaHV~53>k) z=0#{vdx^y+vTc0OaGmy(8 zHo2s4%-%8jdtFEMX`};}(2*NLLXOYCW8+_f=JXt&1%>7uxq4jkDL3blOI`XZ>X*B3 zp3UZV>f>W%n(vfKn+M)oEF889Bfq1g&iJ}m9kZ&%xbLw!Lod1W1;ox_XG;_CWp|DS zye0pl*pv)agis)ARPm>C>uB~vi2k5xv_Y&>oWeaTNG2wH)O2>{Osns3Z=YsKtGaSb z#{5;T&_auWyIKh)#PhcqO$6oz?{{sFiu}Qesub_|=0d`~)yy$|k^Exv%J2p*%?KIh znbxuSDD6jx*$OV*lsrzpcCyj*5JiWhJm&h+iDD;ZnfH$eXt0bGX+dAnHuS^qZ>nam zXozOK%y{*}5Mite%7~x3+9ZDkDPT90${e_@ahGC-P(zigBg(t3nUnuG-;tbP4{uv7 ziI%Y;^k)Bb=Yq`M*w$zmz4eplfQ+X>+k{39e#Il@nYjVMP0WWlP^*=h$!Lk`bO!Hi z8MMuH%7GdcAA8)I?PLx0vW~tsk)zj2g;L(TJ@#}k@a9$%3pR`5wY}ix-tMtfdb1*) zWWCPTG$UYFSXGfR=46lL8?iaznZ&>;+&aim?h$B>A>uyyUk)jCs8PH>{jzS`?CE*W zWCp=LZkgxev7KZ1Hee(p(o|XM<(DL(_!O~x*J^Y6a#~USO9qgBQmsKr^L(b}GO*bQ z4_fcTl=<0bDK6QE1ZGQa@vQ4|Cr2}H$K6&ssRulu66`)E+;(8X*t-Dvc?HZoc9h?I z@DWwI$K=_?_hoB|0h;1%KD$HM|5xqEr#__@==WR*oN}jSUg~O$UHrBL?myoL!VZ{8f8%jUNFCI`RXtjo|HcY3X2_@1;eqp|l zuDUBjv4d_|UUF5QVK^g3l@%6@aH>18v$3c+7R&GozQ`(rl}tyLm_^{F9&Qrne6M4@ z>|C@3T0>!*N}y&cy&lcuI-a;o)cEY}9qQf;n?x}QV}y*Z^$dY8t+F0ANH=9sE|YuF zcI8$Lvi1Xc(V?QYeIl`#_}Hk`LXOKJ2tBiYW`*Qq`5W%D-19lt7|u{eu11@=G+r>|7kkt-f4KmMMbiIdq*n6D5!KSkt9z z)eOrYn`Z5X^Bv1PUld$kHb06duespOT+F|(Zkp~Wl6SCgOIkq&2N=oei5)mhfJYhj zwF;WzE+@Uv4z1g@!$Z_-%i*{u0hs1m&e9Tr*dcS}D+|LdK|`YsHa$Hq)zbdXDz$D9 zteUx7gNY1zz%-#fA$2W~4|@pzB?z|=6STA9jA=BtkrS^tY@0@S{Hf9|g-1e4W5sXF z%gQ@+FnCcC{*pd@u(gU`;w3$wiD3o}=ix7qkll6CC)62nlR8k5LG_Y;$5-tN|C8YdiYtJ^C{P38RA-18H=Vjr~ql@=f6BEDstsGPx8+=w$I2IR$i5c6l zZ%f!vAbFbx)xb!?LCGEMHQ^EGeRF@bp)f6Tt_^}WZ0C8L0Q1x;Qo6xm~eo2J+T(B?ba(9G8pee{0 zMC&rJv#RAPr?2*FP~b7pq}&Fx$&TA7SK@Qmpdjo#)c~ z8tH)*BYX6gwlMpR-sQNuqepjn?c_@#XQT+_2ny8fmOUHl&5x`ubcA7qn0H%$ z;!C?-k^V8Fz4WCRO$ScMN~}UXhtRGrmL;T&0j@&ayi>(OSl+h=k1xck(_+Q4sd;J7 ziAXLVwk)kKHIq5U$pE_m)6z5sLvf_HXZ5X-$+j*W2M;~Q$1}p6op5PuajmWpTPVf% z)U>5hST>@neSUaK_?VvuOK_yR z@*k&LgFPd8+{pqAD2`e&?_YeYF@;G3p`XneNbBP zbcw$LFI{ds4hau+7a>#+cBQtca@eiLiQS5Kj{W|)ql;mZo7QZzn}y$yhrC3KZH$HN z)R?a4JOxp|Zq4KINil4}Kc7=dJmq59=OdPUM8R6$?i*-}b3(+bOw>JbidsluW(9_! zoG-;K^RLeZ!y`TAW4=LExtU#^^G2roY*6QSO5QTvM_S6=xIS2x^kSS^6m14Fh!BL{ z%c8B06nX$!xUH|@y27VHAUVfqj$RtrGtcb$>s~LFr9Uy{UcV-E< zmB0++Y~uaG(;8%x@$M#ti|gwcV3<_wt{ZOEO3(A1kJnJRz7VC^w{sX!Ng`pX8)euM&v=w``{$XRO+qE&q?1{;8AVj2tQuxUP!@`yTs zNb>UNXj}Y*`f{%4h9Zd0n#Cto>SpM+IK+45dG5v?Iwbr9%0AzG`TTO!#<1Elzgdau zb@JmIWbYHt@K$SI6WB|%p8JZ5x)sdtYe-oC7}*uPiAl)VL5qG_xENh{=tc_XhlHYI z22HoQ32FA0&F-eGN}ddwA8Tjm+Y^t2!Xu)FFW7!;4TG~rnm&5c(eF!#_tl*UwQ94W zXISJu{a(t_M0)>n$9GWOyY0lBDbQ8ZdOq^WBSwf&O{mECavY%zIuJ<7)%ZQ=Y2k@W%NVks8N=+@(@tK$Sd^^57D<;yshWOpw?ZQA;y!^;k#muxAau?H;){YuttL zMj=}q3lv~G^ zlT$3SEBR2;Km?_U+O`lEWf$2{ln6W;xQjO|h%%*B8ERciX=cf@vM&}L3xR>@*1=lClXm+$diH=Cmg^yxw_UY~r4?uoAr#5*i#K@kE9<1;j zAfIB7K}vIW*9!(5UmXGjpbYbiREqM0K z$d}APv3Kw7RGovjJaJq0uw9Mogy*Q=kmt-&EU1xlDX9OlmE=j=N5R+im)i2}l-DW8 z?ua18@cl`d}D{geQfmuhX2n2A@F}ObGQGx$Xn5 z3+reJI+AB3-ThI8c@Se*mZSi0Z}p$y*|I9GGUfIcr?g?b^v@#to%X_oL6iPFb6tfz zlk@&+3039`RpusNMQ_;29*X}uO3P1MZSzGci~ZUPJ`QpaN%KDAQs@&k*Ityfp?&zE z1c&sv!_(3zijF)KrNMjqn1$K2uGsg_D%k>ef%&VIb>nZoaz=bjXMmVE&lX9&m)2B4?Uqk`>n@2%Xw>M*NUUx9x7ki zH*jo+k4@wJ`!&DbME)^%nG=t^G*C9zUkclKg)W^;z(*7@z!C&(sT)sC{ASd|)SVG50{#*%zx0R|BePTG z+|(J4S*9kaX1A2!F!l(0r}96nYrJX_e8uT!6}G^sXFqs#4Nqba#IwF??wRm882ujP^2(cbt#8SV)&Yu(|(0*m57!(B@rN@vce(u znoBF_>BH??M-wxK!&ZM+#uEt*1I&0`dac`#fqmd>`9(nqb@|WzL84Uj@cfFFQP#!m zL7$Bh&+Q)^Q_oAHx8z<_z&XTThK}G9-8aY7)Hkf+zIM4fcf1(Z6iL>dA8sGq#9)&T zSD|DW@h@#ovI;xm)4|Y?>8QoJG6_=mAcNB~_T5?k3t~o!$e6ciwjXriwn}7RlX>+i zbDLGV08VIXqRQN~$0EZ>ei$vmUj5uLEW0Q)W%!HMjo93h!M+BDPkVVuyWh}I(~NHp z5ZS~K?^aZtW8h>}gIFl^PB2I@qR%^ZC2TRh45dTqa-l%beJNP{=NkNuf6X*?LB3UY zPxmqW>k`Oeyq|_*sOl zSM8YEg5_e_G5)8HN|lJYYvx+M;zvEc$`FhGSiP=@?+*;+x|F6xd{3~v{UvtXNZmu~ z?KuxfgrhA@OMxe}`>DWRo?t_v8mZD07FVV}?`^5$3&o$19d|KHn@XtyUum~va~Ubi zgBj0i2KGHs+<-kX`{ERZ*K$Im2t(z9b+OArhKbA3U_MF2!v&936N&=u`|FT~tGm1xLz8bdGtLdutt|M_Q3On0wZ#69&vg zuMHhY#xri~Z6AvB0 zRLmEFd_73-Q9nH)VfHW3V5ZGt_VW4%%hG;UTmiN;;=RI}@RnfvMKADok0f!N^MJC& zsLYL@;GIA_s@Amj#Dmx-@K69Dfu=q3E@zp#c~XRSE7nPF2ME2d3Z$5M`*c0KGF^VG za5bGEdDu51wh6imKkrPAc?9#kuaKS4=LXVu39WD+s@f1+Tgg#P70Eki-3yoPVrMqax3~ z%@G#jkk)!HypOtEQ}DgIbvC^9_4S(bqMZ)lYu0Lb0^viZ7EeZ@=hjFbZ>V_?=*;ZO zVRH3(|D2aEoO4p1Xu#d}-yT^Ru4qAX8VhHrMZ#z|j71L^FV-#Oi*>VeEncC2&DSgJ zyTA}Vd#HN&XL%T;4xe=WmESN%wa2VJAHkngjrd+O;iCNLk^Frn+RucId)@7;>m7ncT8VX6oBO4&8z-qaUFGtfLyHIB?MbX+4Rz=47#4=o#uPB` zOBVn{Kt4}-$%f9XHjp#t;-WvTD;@Rc7CmGxSMvqUVI zxuhay(Jq!%Tk}Y9aN-R1PPm)ZN%mRy958N28D6c;mE{wDZrtf=Y*U~URqJ`LGUFmy zWJG<_bH{_rc91y5aEJ24ki77Tyoy{Ft!?vTV*B)lOS}Knh`%Twqu$S!FECF%%}Ni- zs0S@e@=i``%f~q7{A61Um&+^by_F@|i9GMMpdziJ+$~s(A;=)s`w2pPZPj*CGi3uQ zBKgS)NmzIG&j}Ym9`ae90Zv!alHci0o#vr%=6y-|FqrZuY&EK^kNE6%QLcH-H^-#% zvJV~jms;x_6?XQmORc`&ka7z_t3&x$O&_FFYj0Eh zCqL|oYlvk-Kb(;aH&$y+D|G;63o}^WQ?P;Z?gM!$jM3H+(?e;eXra@qNkx{W4~v@z z*Cc7Ay%Zj2C9umUDnB@{G1&pRgQoe@W7wxW-C()bRIA0jfi%?6$_4WfBXAIGWY5_| z{%W^*eloNPFD9e57R0bEQq_hhMc-x>jXiL+ZwY3Sys2C5aGbtzkyCmJ;%*`x$Sl%J zyQE8L&mSOHykS31-|!rMg)s#Y3cpr-?ddOj-}A|B6B;}Jj1=p6eE}8(*DpF_wtBxd zh9*>l`T?WZaHZK+`)mbf{_JsMl~5Gb7-P!}s32-|ROKWi!}^9{MO-H{;ItkgPdq3y za_#|_tML2mM`t2G4c+7Td}C(+(M$f4hwfWh3PD|EmmvuL0F9*a9JU^j!&hH8IIOgs zmbbe8J$HIv^HTb&PJjICi?=FE58dP77nhDNR}NOnPIl;L-dlj;?}IvCER^YXzhpGD zJuR<&@&-5c0j?!|^bHTMi4C9H$;(6N6H~pZiTG!?agn`U75fu{Bf&*Y3DflO93fZ1 zt)y~IfnAalVm?Ezf$}@CM1FVd<09pe=e|d$ot{kwfaKeB(XZ(K&c^d@RR1NxBj-Ns zl5!cwH?lU1UBp8EI1mm|%1eOgziwFUYIsxwo_EwnA+GPvh(O&2d?Tgn)%5(UpWf_T zWR#r0VDq-Fcr(+Tke{Yx;n2h6mypUWF`5paUU#aiQIejx%3-#1q@rvfA~Dm$Jkj&| zh_@9rW<6=$D_1WADY%+z;6vQ;TnsX~xLjqfM-qfTD9SB~vGVVI`D>c;>HKdAIeoY> zn2)PfL!PsNpL=6H?Nvl00V?w7PPK)y+j$SUh$`|WM4q}m1@-(7*@V_G`Z@E#G#Os- z(|+VdtyBi?#sA~$Ou(Uf`~ROMC8DyHtraO-W#8IVvQ`Op6jQ z785VYNgzMO+ORS)@>==_+u{5~d}r}!Y_nWgihg9{G^S<5*DqAWw=niXUeLp^XV0d$ z%sY;zteyM(&C%af<&-Td0@U>j1?qX-IodknDQmkqQB9u%TuUk#@nD@~g1kp{&*+yy zS8V+9wz<&gR&fv#-yXIKwOe|8(`Y7K)uI&I@ukf(MgG!L4MqP>*RpHO4=Cx+KKl;J zk`C>v&5%T83I~W*+2oz`nWaQzp$e_{ra;VnSrv%z^#NGExxvd!vV&$`YSnqpp%1oj z!aGb*BVE2y-apYIP=j+zH!7dzF*qycdu5r3710 zKJT4}!Gu-k?52lGb>!22pU1L~^ddfRnT2rKOa?R{#Y5LW$c>JEQak->(4)FEHxc&) zZcfKnv4;(pY0-xleC#p{gv7Oq?8OYv?_#Ui-L;H9M&!MN8EeEDF7K7jTFaOX3?X>M z74Lxt9u9n|W}EY)>&`xmOr#09Yje0!XhH`_wdCWC_OyjdSkHaRsDwX(1_r?O)cAcgQC7U8tj>h{B*W}zc z*!f-fO(o6s17Q<*6t7-O9UknnkC-LWH97rG7j{N_5^+u80&=~ZVxsKd!kp3}g?mbE zH25s6`C52e_QT=t0dzMUQ(+|lk9nGo9OoUrA-6CyquhU&Z|iDex5e}H9X)w#A%eRR045^(SDUIl zFWM7S;Dpj_DpcrxB5n`Q($~WEr^-)E>@Z4eFjAvPa zr%|A@d-R7^oZYIu^yxrbY&l8ts`5Ku?WzrgKEZq>_bKdpR)Il3GLxLLE3*(>KG>}T z5BPbto<_f zgQBaS8P(;cS@t#m^k2HSxdvtKa9dGwvQ0$iT*q!iyLK7R`HVG5@JelJamBV&C2MKi z)6jl??b=7R?7Y~Sv4)?nB6JbQp20YMn>@FfWGDaxQsK@S$ zGA-lMh+92|g$ss81<|728f?xvhd?+rdp=Aom&AZ@>KJde>}!{epqc6Ivz6igmc;fb zqaVgw=SBq;$%T#O)pt^~gf_>cUvnoAjGi7(-And-|Is-WTjC`|7eydkC&Y zz`Blyn#Y~)?-=Vdmn){I1fP5c3cLjwwk(h>8;1CLF*< zF}t+rKl@*?pvsMdm<=~q1iv5F`_|F!e6$m!d{C~!>AdT*(N?t4ortMpa&}t}ZZA5( zEd3-CLY+h|(x1G+waOykKqy@FIa>6n>xS>9){4W#X5;*!fc{KQ!BupjWC>hiGHEoan^vc(4k+-ifLT?Kj@NrlEZo=jVIu@?2ecMUwN*`}|hZ%KLyk8lQaoc{cX=P%!4m+gpOD z`u)cx5DDFHA5CcXHom#)Ln zp;wO5GbO3xA;8L(!x~)u{mTc&BI@Ta9_g)^bA}*3lvY~UAZC|!rRz-39PbN|(iVbT z^Dw@pWq4a^klM>qR4@duB-oz*1>{pB1HybC^&`ZAhO7wlC%GOz+5FPE)QHcOlffr? zDS4tnJ1_LG(AW|A`^)l}R{fo^wR;s4qxqdhE)8QoCGZbp;t#X35b&89oe%($&SE*LFyCHHMIyx0P90?=cjZ$#7oi<7g9(*VbzN_Rth;+E=^j>OiWgY6M&;ClkKa zBIg9;)gsA0!TIb)6ar=;Mg3Txcdx+*G<9x!5m5r5(p6tKdxzOhUpJTX@KR?1&ZePw zq;L=(mFS=K#$`=sdc)`b?DDFP7Bp^|9!N{PGs6eg+WpmQ=A)L>8m$|;6aaEe>+W}8 z7cAe>x4LoLS%f&NG@;*^M8*YfDAk&JX~aVok73eESa>4LsmlS`w4Hv8+x7_zum}ZQ zcq&831;C+QRSo}AFW)ggZ*WW2?O9#np%ERCrj3mQSB&LMD!y6bxWI~U&)j%^&0*#= zpQSw4obNtD>a0jtvD$WyqaPI=!nuE1 zU3BWU^Az+t-Hu9fpP3?ccwYriN>biU#mOoeAmh?MXi(ayI!q*yaC&XuA^zI6{;xz z{-zNN2rrvlfXi-`@&>^EE_zDSDyei4>LHJPq;`+pcX_cSan!IpD|h{}vFQPl?>GC} z!F}nfQSV;8L&f$FcoU`G=N8^9@je)p%1qp~T0Z!&!aexMW;B2LSoM!Z6H@d!t#1Z+ zg<)IrQmlBQ0^Ks_I41LQ;nmsyt)k@O?GlLHCwYM2jwbRJ)KlW~9#G$m@Q}`zl;rZRtv4GTA_>$_Z%84GhedqB~PWiM#_3GutTX+A&7RW@6TmIf<`qwx8 zZzuD<=v<79{58cB;Jy2>T0{bYF<$ljPd#DHi6}Jx7#dQof7anYYO?>wK_f01xxe+e z-}Zgxq!~6GCjMJ7^e^eq|9Vj>6vgCS*M0TS?5{#fAB&=(uxv@J0r(%yuaEQ`0F<-U zcZ(gp{;aSf{tTV7Y~;aJk)CqR@K=9Zq5tn%|I0r-bK8vE!hfdaui}sS@wTzS^n9y4 zA!@eHAL8^w^1oA&%)9;o(nz!Df{MX^mSiTs0a_sCO$bK$um9T|kVNco3cDEmM_>EF zAD6godFN5${`0>SXms1Ued*3j>i?+8KNOT^V?rS{Ey+gea(^iA|5vU3A^%?6mi>ki zwTAyxexJKCW((*jl}ol7*7`ss?(3TWt-b#|{_Mat<1o<FJ*Z@irf8lk#;;=S}|S0z7G|+7^~8 z*Jk|v1@+|pW`4Xi_R$_z{~6)Sd}?}OT|+#XD9bGD#@$k`+M$ImrV(Y@>5 zFHik3TFm*kI9Qro6XI6K%Ky6P|5r9Bw}(Zh?m%NVudAHt-@53gUJ*Yl8=yO7g=5tJ zb9ei*kIY;iGn0qS-tC(EQ{vlmCdv!d7#zqQx`5ZUA3Tef{U^2fky0b>*~R4#Yv2A= zM#MgCKudU4*a%8rpWF2Q#})_b;s`MCgyX0F3{*fA5{Y6ewW~*Uo2XI>-O|P^lX?-Z7x_AHv!ZwGi$?b}?ZjCp2^fSA3y_EKTgDhK}OJn&*)%}Se8%2fF3iT_s6HF?0JS>lI7 z^L-%ll)h>TlMnUk!{3w-XWSBLWkJIJdE)t>T@mOY9&`~53mJ|XDE854EbJ8fi^I|M zgMXbdaZAGpZ*{y(=&yO_-+|wo`^M(g*_C=B%r>^?kK)yzP#fe7n%mX0awF{j`=H#uACl(J(7O65$Lgf5nBSw(Y2|UY7Cq=NL!E z$Rx8JzU`aa^VdWjrG&UNl_B;|Vd3mi;MxZdo-O$E{1xWTLmYZ%>x^gpyK|gvY#nZU zmmns7?Akwl_l&zh7%p4w{d;cDz2fYBU@KP2Cw-*p?PEnN`(|kXecXZbspzC6@j5 z*Wko(=2Bo@rn7d-3w@oluju^7mi?FiJimoF7c}yO{Yj`}Dd#H&|X0(9}+ zHUY+~r%(+K0msG&x8}`xBCz8rBY~wMu(dTD)-twco8I6s3a52|RoH7robrBRD`8u? z?sM_k(wka3#$Jfqo?Ti!4oiMd^-gbVC2^pohiOAYAjpyfi9R@C#GW(~2lxoW z5_qR@h=(tP2_Wz+@q;w>$Yn(C8WrGS;8~90yCU89+bo1`*rjKM8=Wyy_?`62jb;YKzO!mAsRDy+C*gP9jvX*)14x%HAwbe-B_Eu6}gUN3Wi;P>QeZUONFA#?*A-=%N?MLLsHlzROqw^mE|ce0pv1^r9_b z=rC~#OuKH|uAcP*a9ydLHCV0<9pjPHrbKLRyUXv%17?p|U)k~k@CeXlmgKL>{*K%g zC=wk|Uhm(rO(^hj{W^t0>toY8q_FR#!+<5TA#=$e#aS&R60oX%xv!wC#qM zh>K;!goxg#`i+kCL`f8E+v7P<(}%GXf+gbgCPUdiwObR35-DLn+{9C0>mO!wg7cp8 zqkUm(2vCMq`8^;3YQw(D7Bw(P?wSe6A5HKL>9qaYCR2#Z@1ijr zFDq|u8_`Yxrc$>&sM}g&t-`h{x~4#*9A~S&yTE4!pc4eILXYmztx3VUFGz^4s7yTMae?Y9{cc<{{YK+pg+n*A{-IEw;0(`>{m7LrzqO%5yx>El;h%6)m+Gf>xlLgfqqMo#4#49F0iT;|)m z02VpVw~zaDef|FP4(XFgJ0>!cUw596 ziLc?j%F}mWd7_~2va(GY(aiKFw|6Z`ic^bl2GJfochM;%EI?eC8ytSD7f)4ov)r*9 z(A2d|_9+%tOILB>Y{U5zpBgNWm+d#+bI?*-{;UTMl023eTicGmS{EIW{U9m9UewxSQh0~A9r9N3ttKMkdoBa^H34C zSR>mPYxkEQ!dJ3>%Cynzbp$e}wd8ll)i_xScG@lXB_XA#KZdZTc>8*UlTY`c>+lGD zwJ)INO@I7y+orbypxfn2Q%lAZACSL)7q5|Y_|L3uE2ftTc~pMo~MH|Gk7NRm>lhzM}P>n<1%OS zqk_Q$|CI2N52p@wPtRPzO>76k(NvcSVtT0O0tt}XNdOdiJFP7BlDE-4EP!nvjvs7a ze=*reZCqX)=HYBFMUw{3v?oIzATT2zdyH89MnUQzS$uV4!yw@blQDPIs4jFR5j>JK zU7e|xen1Mn=*!vk)f=?|rSYFh{WNdu!%gszaUTd;@Z4t1)Z!4o)^k5SN{pUB8Y@$P z!a0UaUZQB)rn#FMqHNqpC7?+C_AkGDo`eGVFT+V-MtkL^J!am-Lp|AGC`55J3@SHj z{^U?~mEqMR$*fKi(>yQ4D0gpA+U)1vN7rpK?K3g%E-gUup@~4G1$;JEF&0eXQA{D| zyGQlG_KcfzJ$~BHb5K(^JzU=3MSN0K>6)Ao2Zz40G~PhD;ZZ>ueAjHVGPiidc}y;8 zR4F}Ie0=C!FWe&a{ZdhOeZ83{cTsoxsIo4|2z5AW^Q_3re4X8lKJfET9JQWzqP^Kl zvHgtg9iMU=P;hG@HH5!K^`p@d|bO?;#)FMt}JzOv=MUVsWrXSY^AbLh zbqPj;3ac_Gk)WtaQ02R(Hv5xWjtWI3QAh^Hhvh|gu^x|H8?jQ$VO(JSG90qf!=a-0?K%SuK#O>OL%ULDa%*!0OZ%10NOa6zCdF)Nrw zv&eZ8E;qH=Vqmk ze{t7~gx`}QHNpGiY~c5r{tUN=e1;r0hXBPt;SKD4@(x6Dp$_dA8B z<&$kux5|COk{@>$n5=*+6($F)kMh0K{z=uND$3f}1sOaY$`d~p0=ha?J&_?5mISt! zL3Iq#7PlANgMKb0yL$ux4x@;w<+Jj6=Z+@3MIMfFe0{!Fn@5R>*` z?C6U-Vvgix{)3tMxbFN4m30*N=lWJrcv^f^>fz(NPrYmaR@pt-$x3yD$0MVn_%!4X z%qod{eqPcH+vY0;->=?l%m20#z{I@ac2G98)Sr+!z-x5G?Z)TSMTHkZJaO^+Ld2xh zl=iIg#J_4j+h{MoXqPiZwxy@UbH8cIVX>s zftSz2@kzjb(Vv_r=N`^YK4!c2j?`bdI;3l1;U-N5GKn6F(=q@tDS&DTKjbIbVd~)( zrZ3+XJ`Yv}?r;^L(ZQVIv_>23%l7$>xE$=K`F*T4X|ETYuO9X)qWz|FOD12fD?2dk zjo~L~siEl#<;2Hm!$wta-;6J8I+eX;!}=1w@?yFAw2$ZNlM%J2cAru+z-UL#lEPyL z(b_tgx!w}d2HJahx9r1u%$#sVYGOD0aw+mF#JV+#Xiim^W9Y zpK|LlZ~dqaZ_gW`?J>02RVPV#8?I*P@0Nz9rO%O)hKA|~Rsai$>Q%8x;&_txrA8d@ zf;mQ;fVFzHMQg<@=>hD&7~_g^r~PhWN2qMXBy0QH*4&LbiG)P zpLNCPTQI@47TC>76w6e|?YVQQYUDhCD00t%9MN~&8LqdQ3CGiu z@0%U}C62Te@Yymqu7HLN?LIo_T?fb^D0fJat-)F^x;2p^)G?ug^3CmX&-oHV7>P1iBkBDZ!GCqD1tYeqclq6gQrRThNohO&wIsdNNwVFw3zQ3<|wf;Kd2URRULQ0c6->1qq}zq zL}%Badc>)P`hhtEUaVa%si!*YXu85$3Q+0FHArMom=ObLq zeA{`uy(4k)Y}31zCxK@#2eFZjsf3#{!FISN{V(IqXcWXtdd8Y!T zVM8G*$z`;(g|x98F+|8ErEJ)J^%%0h={VwL$81>KeliQ5?8nH`Q7)XBM*q{q{>Eu3 zdh5eQL?ij~v(DC#mGHOs8Oi?TriHZ`hW4_Pe4F##Z^(KhPLoh9caLX-RsHH^l)nkM zHN-!~X~FwszW+1z_upQDQYIZ!(AHolz))p@DX*J~WjYo0w-usPK<&egUT1>0#1r;c%!z7Jpm=JRu! zg4km;E0q-oF(=qzeUiC(>b~|*6)_zQJm20H6eT%`E)utHCm%J!U+o_%yS~12Vh31) za#}f_kPALLuIj7t)|6^pE67@yopseU+Rt&=4=VzET8X!nmdXP*q9_q<2SZF0*^$Zz zZ%K~dKO~es@M7@kkWX*EV^~$>gpX(v8khXU;-$OH9*`icarWFBmt*DTIj#Hmmhpag zSYiHNqT^(dn9khMujzsxKDd7ME4?o@sw2ty{5XChAM!Ha{3C&mnH1I3I-iUEk`jBI zAoR%_9DNFM-eFwtaS`>BzYsY8@(G zl4#tPA)nh(p<&AcNV@h~;BzFe&xX%Mdgw$WU_Ga(p;)3(@6c*!%)_y|hmUR_*I1x5 z23ty?uhna*DH%MCj}5)wtGVD7u4N=M4Z2tVOfCZCstk+g`sli<^y?w7`gufi(E#$h zXm8CPO%%N;h^sCdP;5WLTdKWR9| z7pdNSSGz`3btL=bEUs{xpgK#%e*9kDF8Nav-F&&3(JgMjx51oUPxDPv&&PNnf@q7n zv){)>Z;rV9po(2Mg*upJX;dc_7p~k52`ajzmFl?B|9Mr@& zU|cyn2=yH@fMs%Su-+kCd~UV|xvjAKZ#dyYb5W@f-0rim<=G47LKTExTvKqN*~ew*{e0iiNZlyC$)oZ zGj4ryPm}!Be5@%EgXLKRNuYK^w*unS!v&k5>p^+!J2-|*XI}bYI?{oiF!B$MucEmeCF~QX2=YK=nR&l!4Nm zgJ_G;^+N^P@^3fGzcF5pgX%FJY3iw+Ls>HFl8NDNb+6gOnB$PlkKPLb$>9h?%U@se z$mepgQMfbym@ngH1nfe?Nr;D@?qJikt`^k_E~2t)Q+iE3xVI>X#bDQ)kQRijW6tUT zvNO`H%R2WD>--0-(q*!T+fo$2Vc+$!@D zC68>QUd(i*_`>Pc9Tb?6qI?Yx)?IxZg;j9xj$T)nF9OHv%n|aJX3Ha(hx4l(tF&?* zH0@wL9_B7s=4FVhmAZHzs#0uy&QJ1_vx<| z1#!HN@1FJ^kd$r5VU}ana1ciq(vl~6P$0~;VZx0=5O<;=*T*d=2ILl7j2k`ek|$#|VX8}&iV=2Bmu%UNZg(feC&S8$u(QjQwr}}p7b`;tNa$w; z7H-3R;~^9X3SW2YVW9KySCGp&pb9CJ=9XUF5R>04;b3$$pj7ckAWjU zor0I%j~w_dJsT<@^jJyUEhI;off-IdQPQqFklzR7J$m{>0zGxR))6ofeSB# zZIV-cF6M^4I5o@3UCCP8j3(i))ubP!5qqqDyh%m#LT8OAx=%S)aGnXCa?t>s- zs9*i(B_3DNeoY!)eWrOOsGsizBW}ZIQ;abc;SEBUz#FTob&q`YSrtWR2s^}1N_hr8r*r6zT;=@msgiLuQ5}m#xg`WWe6slaKvk{Hh5^gX>lVx`gxyI(_XK+p z&tz6WbgS<_~hasnXom$b&TJHuC0H(wv`@1NY*baU@H(jpNAhW4Qm=59_AhA*^1+5p7$tHzAZ==@*K0oDF=H{TyLg1 z8M@R5gV~gZm-!Xrby?UZqs9xJx z4S{69=)3D4sT!RL^L&XrU!jpLm1(*Ra{%WiZsis0T_veia##%ubqpd%4>TRdbV6FQ z-fY=wE+ef_SRQ`NM%n2AIFLPUxbgXS-zw^7MIh5<29w!r6T3|)xZ zz^wGF;iO;iD^$;?j}H%SyVn@D+nk;~TU;5i@)qTD>NTU-%5ij4Z!;`QI+pcj;OLx3 z^Y%EJmfBNj%^8~206HM9pwGR3S*_|O54u8e-Ra&MEF7HcfTKZZ%8Zc@!@p3CfJoISK?e_963CrnpB_U^L?&m#w z1^ToS#_YLXm8@&>E0$IfvU^fkaZ}j~W*kqyf%r0mD;l(E=-xNlhybc`36A;(NrT~` zk~e>*9!3{-yIEcMa7eVVVRmh^{_IFd9Ur76b^ptgA{P;6k#aNdLc)B^w|@5f2DUuG z=q8uJp$aN2$W<3AeF=m*(e9e5eMJF9 zSueR9)qKJ*hY8wL_dc~04;ZA@@x?FrHgk)tynktlcSEw#IOKDstiZlEI0KX^br?)3 ztENIpO)>1(!arAvi#8a;*x>Fo@}Ngk8?$)Ai9F!D+(l`BqMI9|0k=7>^_39(_$nvP zD)CFnC8AHxQ~f!$S>IJqy}nKO>-IHxh;3pxodeUOW+A;qtZ%HmL*6M+B}@m&;5>R` zWCvz&zsFOP11aU7@xx)$30M7#>zP8Sn;YxC=FBp^=1X!n{6`p=xnsf_R7P!3cjgy=dIde^u_s{binYBN z2T{)_*wAv-;hdSclXK-u0ROabPjjK+RYvPb-Yno$8cMAvjrz|Kvkcw6 zP~`l3pCAk^pRT-WJV3axhHmEKQ)2Wn1DGV4N}_u6N8gb4x$c6L4|*gCiLLXA6Ei#M z{Z@;~FmIioM9Gxo*T5j1aFf2_4+x-#K;avzTXF2`($#U}bd2XL)8Pk@Z>;l>d%<3W z?Mdd?M^V?^0(3=|Ps!gtEjszLd~VdW)1tWRj7`XX9tO>URN@{!yBamvs*MY>eRcp# z_*rJ*bIQ=U=Uoq@tV4wY8@im)S3)}ntyqJZmjt$4(-#rIX&bFzJ3AvD@&K7Y3s0L=6f-lSkNS^rU}z@h8o$d#2^5!4R&C6a~1bDLXc=G+i($Ud{U|mvUhi@I>b(Gu;eK$X}_G` zv-d>Ldi=dpCUezbNYh12o|DF6m?Uc~w8H){g>jM?f6^QFTv#u8)Ku+7L~h3ao}sKjcvEip4>Xq&k>@a(#qt0}BBk)o;SWnIB>J-h@^9>qmG z21px3UJ%Z#_Cn&(kT=BMOc-AWCE>AyflS?!j+Ksuokfqaqza4xcQ|UmXft+ z@YhFF>vH`FA>XbGRMp)2a2^KONqhUX1q!`xS4|ASeS}vI*TG8Z7irH9^{91|k!Ppz z!VzOUdPc!4dZPrVgI@W zhYZ^`D_Ge!At)$NZd74OA>ub)ci%?Nd`y5!#>Ke9bt%WpN_!gHFs9i1kM#Gb< z{A)(TvA3w(MhyPIZW7AD_J^EaZ~>8EPPz>l-1>3+EewHmcoPrnqAAaubJYv)we>!W zZ_O**)YKFT8UZrRkzKzgco+`8$5`5Roit)rOV>cvwEM&xWAAO&_Q15~>y|AcM#cx> zSp_CY%GcbH@j;F?m!#rA1hiECRWquHsnS^;!ciJ(B38Jf^C?BUfCoL8J|EgF9%_68 z{8FHj(4e^BZ~rVRccH~6>EL4&^D*bD4*}%M!umxFT@(2^Q(wox z(!s~KSB9%~OP+!v@+ceh(un{9$n|EOiO^OfbTFbNM7J#`)G_tkYj2sK`(-wDsX>OU zIrFP9M?=*iMa=~VOr)6j$Aw0Kv1U}`jOCr*8!&V$`b2WM9KvQJ*OZ1rNF3jN zK!Bewvy}(t>_DqteB&7~!6zQ^!TKa0UD@!4p%a}jm$Ca`_6t(v`-CESc!#!AI*1*S~!T&5xeiUM@Ljo zG_p$;N?6NYr^|hF9})^of4f5&7mga<0h~pio@OSb#kbnvP*!m(m+WRJLDG!1Fdg$k zv{U`-b~16u3fU#s>bKZj_1!~h7L7y|j#ucebjQM?ik2y#kkD0G>=XY1Yulhy_u*aP zg%t860ZNQNf`n(}6xWU8wq8R!LQWy2>NVR}MHX2u!r=tMkyKJ!YzdZGs}fq2sTbQg zI+Bw14Q7-=%=zuEdpn~aPOhHP?O2u35d?>1N%3t(B<2{26zY>LeKp;EHEQV^(S4?J zO>KnVL8$7^2N9@@_dd@Gm$eHj2_S62b=Ad&VbnL!>1QUD{5j&^+JGb%kJaqKCxBTZ z{%u3aW+x}JyZa~@i9MzClkA#T1iVdN~0#T;e~bmR_&k9-!eY1iTfB4<+CAaSf2{Z78U5g z9Nhhguy&!Nq_xs?_fT4<*S^!~ib88#-Vq8ipsO@P3vTnB*)Z;^LJE;O``Zm>ZmH`Q zc~*vID6^=*Enu^ND(6j=FSy}$eT0dd_voJjUSa>sJ}x*G#3^xpGf9cR>yNM~q; zfpiaPd+}^Mx^!?f-fK?@DLcPzwPM!1%5&JqtOX!(&jdtc!$F8(s4SRXwJuxqr69#(z;w*E*Lg(P81ZkHF;89$L=iMg0hr|O0qgw<7}j%w}ZdWv;h&;=AU7U zcJfAX;02?$K3*VTt@N|oynSWjJdc;dDaw3zVP;2IMGy4>Dd20su(r3%TZ00Jw!Oz^s9MByfbaMR|e{OQf#+V2QRKazjK>idyi8R>zVgBG? zv4vpo8kcbBdE5FmRaw9!cR8@25PW;D+t)AYqpgp%k0_M-SUc7uBwFdwFwNTtwfv)b z(^Scd^!`#YsYBrh%lqS(WU?=PWjS} zXJzDfInmt1f1MQ8Xg*;{1CoO3YgWIX(sNjIW7#Ho%z5ZLrMfNvzr}+m&F%pZcPi>W z!D=xdepba{4RTcYOX3o}3evtszltn0oGMRwB>leXt|J}bXEugwU&t);R30obmp#U( zn=D7L@QnblnTrPjvmENjwKFn=SV;UkHIjID;hWlp2K1uGabewE{72q5(Ye)hQoo$n zDD%9(aUt1d2eSEsprO6U@4$q>JS`}sB?`8A^7$LWmB6}9^(Skk4{pNaQ9@|$J)m=n z#Kt9Id8OUIpRS5TL%6=6887Dv)Nwam0k*1N&ufsF`R;I=<`n26YV$qB`7qbO{Y*FH zB=wss{u!+}ZVEWv-s=2mOe^{7FGq1QZCvZwj?Lupok&J?$uN#^rx5Faq$RZHs6+N`L| zYPhqZ)81%_w#^>Fek$NU!b+DOb!||>T9bO)3S(WkOWl#}qkD_?Yygz@D-RK%y6JLQ#Z zBnD9InZQ>{g2K82vihgT|F93CCmEKk>ad(Q!XhqpS;E!7Jb6zb75wbBE$n|QD26}n z&iUR;E@-;|rdMmK>p{Oksb|EL*LU~)nrN~+f0At zUKwW{%*272pCZ5XNShpS{QWas`@DH**rAtPO{nBcyS`uB1}x#<>cY}2Pwst9Y7dW! zX74euUO*>VJ#cjD$8)d+&TdH(TL%=c1bF)owFfP&oh4tgbcLXk3|~&Wwp6{o;dhzq z+EMFouUL#yxOr?%76@)g?6+QNxoAt=(gk%aR|=3)l4A3?uB(WCp+!}VH9#FF4I#^Q z>eJnyuvD>Ko`=bYO3{s%U*IAgUKClogk#K#aF{YIHC;Pa?#_23L1_m|`BP47cDS4I zWqO@k+NAdEJ$$(A1?INP2kkLGNbT^;jD)jHaJJ-A^_$YrUu#)-G2v3;Q^_Af%c~6w zWgT^)<%P@r?TG>2r0b4oi0g378SS@+G4}Y|_Pn=Hg zrx~k0x=F=ektUV>4#IS^U3UmU$3=#lOO>zvFxdHPp0_mEREw@8+J}^T_N`}=9=DCI zIQ4EdTRetT7pxUtlj?-6GUH%iuCZMCISz%G<+>q|ULKiks08z8fM2+R8OHG?UlMt2Un*ihfCvCG=DxNcWhlW=Pgrb6uMZ$Z$MnP!ipO_);#Mydt4jn zA2)qm;JR)fd_QQh{B@pf{VL!}IMRN^RSTXgg3L>eVbP)>PI?x4BwKj!tGfPpBY>EP zbeQXCi^#yFmsaZ#Angx4&K1n7Mg4rB7&;jF&8v9;x4Se*9Rq-yBZ3e7@OX7I`M^&V zOrn$Z?!3Gy6NQU&$6r+3cdqJ}liGXnOtVho;2nE0JSugcS%YTiE$NmonrxR&_QpHR zQby60IRnm6+89Q4eC?$x=}6O_N4k4AXQh~5E_2C#!p17TnBqjl5wMngKq_C^dy!uB zZAM;o^YKyICG$A+S-IME@9b7kHJ_+*;$eHku36fS`pI#hvvuXC)Fb6fY2hJsQ4XV$>tKuU@Zwy`JMg}5U`GP`KoYd=BOL=p zZH%wKSIC4@s$qroLna(x85cR6k0~v=1g9=|7}c9z^K$6$LZ^&YhFJ2}^_uEa`_Iz# z)Gr90-cL1;1)LQg55@p2r9H00M&TVH-@r8RoU3I=xFyg~2U zdWifr`^^wq0s)r=BadyfF;?roFSbec5Rc#Qz^GsYJ|sKdOYb;XD7YaZV)kqcX|GHg zJ8?CnB}4j(p3$|bpoh9zRh261J!yy?;7|4FM1MyEjoyb06~x<-o;)D!$`?ax%N_Or zX{gjC&L+f0KvlkMwpF+?(=h9wd>n0ciX6M|q+|~GOr7zW@3omZJYj9_mk{Eqvual> zguGGMw_L81**K{1!+35Y?>#Ltj|aD7!{OG3OkD@aA$hT5!QCte)sHQ-Mb~eZaPEZ% zWxZ3ovw2Y22R}G{Qa*lU>qzy@?)Rw5(D%hs{ndAnj`u`1U*mg|jLK`(rT0&sZlkW3 z99k^v_IyyUUBYfk8*&(JlYG-it0UY)-ihnYxNPW^EoGF}P3gcHLNeHIbZB8imJ2`z z3VRZlhGkAK@!f+sIL-=tuBLx}Fjgwi{9I1PLoR>R{+a1BaD^}Q9gcuAgmus2YISxm zwUGn+^3dhX7)+qM@8Ua9MNCV@iqGJI%UrFyxE2I>#dh9ERIMEB_1pdb7<&(Bw%`8$ zAJrOFv}Vm#m8!irt=*#9>d;y>TCGtdwuCBb@75+dwN*mZCbm$kYQzpn2o;iukx0ZZ z?$3SS|L^>K|K~VIPL6lH$2DHLuIKadg!!wPEd{3eHg>#uZ<+UpO;AtnVxZ(iJ_F=x zc)I0)QPkD04`nZm#5DvQWUIE~3pf@PClGGETlnMFV$I9K%B= z6VIVtI}xSTS=Z+t3h3C8D%pG!f4J5Un-ThUFQ0K;ls<0#Vo5_l#-11fDx^z7b&4Sk z_jlpvo7dbB`}gP8R2R&>cgQDhZu@I~dB+xYU+p(dc4Zd#jIk|Lx$NcHgC2w66&9>R zoaDyaq)Ri5^9RTn!BPY`IROwk6n(hf1(Q0tdU>-@VPmhkrZ{r;#_QK5 z!1mZL64@H6EVtCo;JW#byVW^MvB&3@6f0%y)hTSQOl7XMhmYSiJYfpt3@5sT zl{>rwi>onu8x8UV1bmo`8{T>lzK)O^F!>fz6Jv+?{&ZHVse9)rwhz-?_j7%Jzq%fJ zC2h7TkCj|wNU7;LGH~=9DV#srTpjS}4my}|*bh>s7n~rU+%7s7X1REC0`g^gb#I#@ z#Wdl+TRbB6QE}8!q0I1byUcK&@8t3iPc39#Tt%&K53(^)CB(c4>& z8xab}$Dju!WpEw0SC4I2u}J*J+K}PO<()_D;9R(%rO?<|By?5CeLR^@XJLrHC8#oOyOwyiWDNVz!XMpC+fY*@?kheTjc!<#7K zHoN4tEy@L6Wi+JFH?OOxt7$j0>;c*@Any-sXSw;$$c^HIUjW*4smYh5N0TDS zb`;m)UYWql>>f_IE&7O5laAtTj?Ph%ebqeh0yUbQcTRr()Vme6rfYN~=1C3*o)3HvP`{FTOE|--zH(iqWJVu!jm+4p>=M#c zPere*w668hW?BVHVIY*Zfi2=23yeb&k-bbs*xy3;HUc!L8r@n^_QT z{=t2Ya$LDcsq5Ri%F-uD-%5XHtm<0DJbc9R84IvOG*RlrH_YWo^5PL0V#rYRa@+g1 zyime)p}{JoK?SDKj#qyaC57)_Giw5pTvqZx4^43zYCY9s8u8 z{#100(SQg5RK38Q7z$~F4^KNdOSh?Bb4S{5s!F?fw1py{urv|1FkSSM!*pp zo~8Q7BY{+UdS?_IHij69{kcwRB7A#U(66f5HE2!s;?b;5B5diPbTkCU)2lpuKti}^|X#U zwvsIwC_Tw;5;Sr}xjNl9Lz@?7iO}YY(m|m|%$Pmt#T`D(%inL)_4j?O=2^4u=0@va zad+b$zg-U;>eu|CUF3lMLcs82x-1pq-16rxM90H^0h@lMEov4~Z?&Gy$3C#f$I;q* zl_P^VotnU)CQGy%MrV)a8+It&ag+bO^g@SKKg^#u{E;ygRYZuA%UR*1y?wJwp-Ju@ z1AfDK1hi*MKHt?!6E^tNK84O*{*VM_tt&D)OC)Q<+Oq$w2k2(E=ForBJz-eHN4LrU z>W{q1oO6Q#&gd2wJ(IiBe@;o{5*)3#VSOi$w}fKN2&nndjIeyQTd{HEkQCuM0xLuo z>X(%Ntp7XT^cB`0MvL%t-@1UF#$h+Krbf^LzW5EMb`0vOS~ zoNrlEYCHC|XN*C9H~tUL>1k$8AQQ>tW;h+e``T4 zy23}`jQ+byTu0so)-?SC+>{@cBJg;mY;TuqyGzO2As$<{ZS zBk9_9g%y%4Kivw2@asDDG5Ei=jDJ~O|9O&CS#)Z|ePsXeUlz7pkWqh`7oT;J?y3olGQ^|$6_*68=={5~CC z#1!X}7Y))|=*@0QG@7Q!AvuXn^D`E;FaKAw>VNc4Po0l;D`coFV+^^wS~;SdFjNV}mE!to^kV>Q z<2)&~1|hx+|FmWQhX?uJA2Xd|qix98n#`qFIb!E=yC029)m&)6$4<~q=KSkL0Ec~a zgz=*^<{ynenzbKl=xijtFu44G#jMAl_w%-4Xnx95ZLWP5-E2kOU!Vg{pp^U}z0*L! zz5d4YRcE8$d*ccnAEa?cKjX2O&94Im1pVFZQo6_l(_s9TN5?g+U3l#By*_Cb1CEN+ zWGp(Y5B(t3m;2Ynid<<=y>6@xc%orArF=&o_itPI|JWCTtrn-GUW9yu&4_z2HL$Na z74mAZVLdd7YWNvJz@vY3k9INERWRMuyobL_?)$q(!Wx}_M(b8O@5ES}_XCJEEoU2i zqVk~D7rb5&YVZ>`S7t!Q{&oBY+Xuy|634&CjBsn|a_R7~N?rAm*e>-F(jBhzDM4-+ zKD#UGi%R?#3jmVdMB1dJ?dx*67X5QLfEk}V=pguw{Ot(a?!ap0$`tBt6e8L_ybfO9 z`4mU2Mp3|x!$Ii0e_rGiUv$&iFNa~8bAHB$KK~+i{BMn^{WeqfKHDm7L|L&FS)*$; zGfCHhy3J0xZ+;#50xGisL&-$%*Nd#Qihn=ex%1?8^R%mn>F$n? zsSv#Z!{0}~>t{pDSKXaisp5>9PUAxYF7y^j9|nJKrlkczW&ZB-9!e{Hk$zF19~+d` zNz%Y@rq(Bq2u40xh;J`q{g67?UoiUkEAtjJ{*HY1`d>Vt|Jd#R!)pyzDcS! zE$*Yq=jL$8KRa@}5cBhfrB|j>FW?MsjQ__r{_i()jwY_#YJX9Z=v~d+a&dcYET6&P zA(~wGcMUsFG+Ijf#liNLLS$r^09aW!J>h8Jr2oLo7RSHXp0t$wyQ`(2K;1>ZC$l{1 z#1`W4>`=>&iy@{8BQD(q4Eg^z0kuDX}xov^iJa5}8;w31Myc;6Z=buARm3*`d zxMl-`Zuz?#!y27!`6!F0-R(G@&MJZIM4hG>4mg0_kPTAl6bf9Kf)B-cJ-|@^ji^{Z z(?F*i!1dK&fA^H>U9A05^tBrd=}v3Ysa^e3k73hJHjMCYh)-b=j^y)Es-#}u5c7Y0 z#J@Xgy9V>HH{dsPWO~BH$C|eJhd4Pw`P}9^zy8zzuge{i&L~Xy0Eo^;3F;vY}nYMy+Yh5D=Q zeX=>1ePOKrR;3cN(IZu+0RKk+`Mk#IY3={5(0L@x1fwzI)!`0fj`d|sp5KGtNU&S5 zh~AHr;_0|Zi^o@@OTDyK_k)8(r3rwlJ>o+156m^RU@`qHKV5q?&Fr`T=GlzweL7FW zPbr$tba>>F_}^!~zuplMjdr6qiKSP<{BY-}gCi8jdI_sizQ=7G-O#sjeMn!Mu9*|L z!yA@)KSOWEdW+U4{(XNPi#ri=f$PE%cYcsH8%tJfT)Plg^fmnrq=$JO$L=kO22 zuz$9v|6I-d^GzjZCUX@=Z{#L@4d=0DSO^`v6}(8t_N{pxTP4)W5hb@;s}D;ihZK{OMlK|5qXQOS-C_?NN`X z&3*x?Hgw+EAyzul7f?7Gm>tT#khAn*p=y;L&sun`&1ZNm<|}+1ID9i+CuE{&+W|x5 z+84=wFEzA&?Yj@8OzHsz5i+&D9yO@}0U3fEX8oN9G~i&s(L<*fsq}#*;pXn&mC{#O zze!Z>u{|;*I`FjZ1VWIz70-jpdp4ejG;gjUR6T|RZD?uMtJ6 zJeN=>uNOVGxeB3#^^~U}a&kxf9S3OQkLm8tihELBGbqRdKpUQ1xr3wEuR&a+;Tgg9(*w+Y+V9KEwLPqPA4bfCY~J2a zUwd%F3(U6Fb>nv$C?2P{;zqHb*Dx=BSZi8I=f6FQV%|UKra>=)|8wz7l)Opa{yH-# zq7ErEt5Cj~t$QtQ3ryQCOFqJi%p;?DOvjq%mK6YMJK8$=)Z1z_IyIuMp-Xi07vIn{ zZ8!u`$4wPC|+sr}JMdwq`8Es@IQGkR^BxBTcjM9_`Ph;PZ)+I^!av&nSSqbGqL zzEKs?{)Y})K_KZKSuf0&G{E#XM|&E& ztWvBeZdKB0l08R;{zA}v&>#5f^^jfY>bvA8n&;&z59ttshd^8eVjVeq=!Uxiu4w$a zA1$86V#4dse3kXQJA=x|c~wc~H|Jj@87K1Q_=291C-2`Q8$NwwrxNqxB?qHQW~|ah z$@A`yLK)7Q9KY4ejNSu2gdc2_je&0LHG0f|;9vjDVz$>dYv3WN5f$^8tso1-%qYX9 zSe_>%^leS43FmH~ zjO1df8Bk!I^SYBEsNW#V*d_%?EJS#_7PRm`dpWJ493O>F&-~f zwB|?-Q`1bBon(UaWS&3>LkO8Xa40gdMs-Aw9`TE#3+SF+@U@O=s#LZRn9_l6*y!(! zn{5`pCO5UMyNOfmY|C2?c4s~I<^VQ0cyZ9=gBpRB#pBsaVBaGgi%!Ibm-8&PSrCJ( zY+NarJ}%(!YZVCBt`&VhCgd7|0PSIqHlp7XeZ;zJYeo#3m&iZHZg}yx{}}nQ(b{t= zo=d!>8gS~-DZGLXrU)RkK-M(yWtYtDXl~d&((UYiq=VEi)vaoa=FV>U+lC4Wriaq# zXp=d$sB~9SpKw!pH~t7(lIom2M%Z!tT*D~$;77ie$$5u&tW)QEu9!7#B*rPrS@Pca z{gmq%PyErs^AP(?ZvGeJ(#Bv z74TI=p5xP*JI!eG-S|VrU)L1~!z;WjHacq`q<*n#*j_B};p1>U?$gap+iXCkd1>(U z1!YfFt&v{b&xYCg^s;y|5f1_nx5sRJcinhWg4}AqQdkbzUnxC0L?$-a9QHfEd^{US zwdYGu-t40F7jxaYLKHeg7Ej^&8IS*v(LBj}%32LSa+nx&@8Lt2q{F+*g30dHsUzxC zGDx}or)~E_g~DC6LKR#fjYh$N_3`b;tgj}51#s4%;|Ig)&O`13F%|U-GrYWm0CWg? zbL}+GTCzgZ=db{GK17Yz-Y-dR%ye^6+BYBDosH-=s+5L`W<3%`u0O(FTffyBF8*y$ zl5hb48QRF$Ke52a(I4d*I3EO8C#Sr;CHDk_Ap^pS&A4f0X4FQl-~su1?1aixoetwW z;wpW|tVHI_NV&Y4^u6tPn=xuvo7tmlu3GxiAzr=&>BznmF32tI^$Tcu(*OxZl|H>Kt^sRl6h)(#yh?T5Wx6YM}|5j`gK~ z(db3gw#A6$jS)_+)MA~jF9f~^(eq#XDUP`C``H6{!sFDW%2^4-X_jss;`B_STtD>) zD5~na)b;+!*h;G5_IBG!DcND;!wr|WG2|J&-%77Xh(xrLZsId^Y82T^U}=voCb^@U zn~C`9I6=iTA(q*0>WHMaDL_S4qwcnO2(S3@>r7aMa{~qR;iTu9Q3R>V1g`+mt(=jG zIc6zT;q#_1iDRx4dbi77CJQR&^!x9uzWVKS%x)3?SjvQBfSHZ-G9G=E@g^aihwl-! zrSsQBOwm>ok2m5pq6QnXWS>>a%4B!lbV+iEWI#q|7hdC`EuBwHNbJ^Ym${haZ|ZND zHquPz09+HZPU#mONf|bgDCl_k$*5G~^Mre#3r}i$yZ32MrBo@u)vFF;k>ap{R=}!( z`LSc!tXfJ6VE;>KoX3erE@wV!dHT2WTC^*jFWr-}Vft*!eKjd2(#dG)3ePX}v&*Rr z!`aZ2MQ1o<*_IZykeFfpy*V=)dQ*QIP-mNW<(IFHBK}gIg~p8gZ_*q+8zEmQTR%#R z?+iulV6~O+zT-9Zd|CdYkcBX7j;Y?moWzD|&$*tK+2_p_4;=e2_1A98H0sd#mmWuO zD@m#Ji|NP%(B3@!+hretL8PAS0N-_&b0@4So_b37-2Rw%<*?@Eo6Iu}Gsonq)+yg^ffwQBaAt8d2KTF-)~%M{h( zYGiSS+i$tlZ4SQ9n|8H{6bdC$hcP7es8%{{Yrys^sN(5<6TG$Zi`%eUrvq5g1lcNm z%u8CYby?o`*$S>Bxu|szC6e9(Tzgh z1?`@EwUeIPqC>{yz(`BbyYxX{U}gL@1bHXmycHs-Ik?C&A4GyOMIoVbpmh@B`wrE z6k@Rgs>gj#_vzEWaNgBB$>5&-O+C(T=4e&_G+b5B-YK7#y>_nNy&|wzDZa%R!IKM@ zoOv1g?XzM-QvJ<(&Z+lw_WLPBnte&;y$Qcati+w1jtBlckSOXu1KD;s^Nh&DLkbc% z!ML1ne0P!*Qy9nKbAS^l_%K&pf2 z3GWcR_2vTXj|%WN07tek$f#&fUGRQ?x`7=!5RuU;k?;ConmVzaV#X@`j)&=+Thb?E z{J>_y~2L*~b+3%V8hr^N-7(V+-K`&2_SW`PUR82;!(Ch3jhT&Q@%9F6_Qa zW&}PeePG1(>B^Q~52HU=p~^Qbwa0PGQBvwxRJF}qvXRjSmAJ=lfkk-H6az{YQx^&a zGTItoED5J-dBVa2BmxfX@O;4PW58_f$g)n&uyB=|Q1ee9$-|vHKkPK)dfV&-4EZi0 zvIk5$UVw-orH-1sK2EF8%LeK^XDKpv+MLdaWdy-ou}GFH13@6D^BB+(^qOimDS2(* zad?amboJGU{APuICCW52uX4;6phgtbwkcd~(2kPx{5lUQ>`Gkb57=1?ON=JV0p+Nl zK?-G0i1ex-;Ct03wnICcVakvLF@K~b`5k})FR-Pfl*I@iE?U1miLtS3wyZ*`02tM$-Wglw%<7x0mjgDX+kYw&-VW94U z*M+cr;H%Wa82fgad&%}2`zH7kT(!d5r@+slPKARL=j4BS!zEtApsm`LgVUtlw;GXH z@WC|rAdW4jGnc9Kh3l4VCcmU*6S&^{Vo@_ z;?Bo-kvIAarQ?$0nsCADLV zH&Dgce(i)|3j;j6bVmZjFYUwi=&FiCf1gtk);7sNURHuY_w&^dZcz*m`Go)ZNXECj zQW=RRa{Ef>Iom{lxe+?P{=6J`>pi~V$*cEt>XOe2wUO)j6XUd0=d+LZhI95tQQJ;@j;+~!S>6Ap z2>0rO4R_x&3G>C-*&(L=4)Z*Rah*(sW!d;q(p{x8I1%eyIkK18#&mtd@O)XnN2S}x zA0nUAyN_ktoRWl)^@E*dN1dB0AL(=>su>AaJHGWA8TDOT_?owP?LL{Jw*ZoYW%Bg$ zbohg3cCnL1o8q)3aUIN$i-tgP!}j6ndS}X)H+?odFF9gnXnJY0M9`KFQOm|^+!F=N zCl5Lw?l|N63)^za7Dq)YlhL%T#)8A1li~+Q%qW>0GZ7rJR?kd&(938g>6Lnx-mbN8 zxNS|SX_1QI8`N;&$YOQ{3X$#dC$u)p6v+Rb;Ov$FzNxoE+^fx^b{p08A=JZv3Y~zi zUbPpPVm-i!Q;~7nhhIOJGg80aZ}nV0^+@|$W1&doQ=%q*aec^{q?b2g=6QEZixw%C z=_M19w^W=)x?475@ogVNXNkoDLkOnB?$0^z&mQBzP86A@Hu)eNTXJCN`60SEq0Lf)7p-yL7u73>em}jxx(CSa)_kh%J7fm%Z?Cv@Li7&>wmIW+(=U9 z+CTLS6=83>M*Y=i3jP4lGHGuB`~f0H;oKV9dd-3la}CX|!ld#nB+d#xUJp=8Dq${7 zDD{6Ay1LWSIhxUd!xXW4XSSG}IXP&00vVC&=zrzRW2OW!^jcPIfpK*DOY%FuZAai6 z)K(L&xv4VMEwoM^;4^n&_so?J#>2pN_fpG}EcX*n#~5<7ykf5z%xHD>*Kxcd1v(;V zm0B?W8>9R>OFI%sD@l{AB#YAK$_}oDuFTGUa(p^(7lx0!d9&6M#@o7PC^B^ue?KkL z`dW@rB{1fNoYLso=uc*@hTC~VV{30s;G}E9^IzUfX;bJkz{45u+4@CogAgcNeZ`2F zS9>h>o7fY|cI4Av=tI7{v!`b6Zi(3C?qPNAMH=j?&)(&bHa?|K0G%E^YbgKpjD+*& ze7wZU7)CjK(Bt~xvSF=lw?4u9Qipt`O6aP3bGX=aZuU=86tDDDN>Sqz31i>@Y8DzP z=Dg)(kd6ENh6IAnO4fV`qunhUm+Orfa<7h0+!0h^6j)!rUYn&?j75JnJ{g6T;P0ON zshKZ-nLC8gt1)=e^I~LpiZhpiu?-UB69Gi{xksB{OBCzfTh*`p;1@-3L2l?q{3c{2yH}(4aes>1GyutU^E21FitAWrb)2P;>WRr?duRXvD zeR1exwY|Z+&y~dsa@*e6b+6muwSATCikg!nG;~LtS;TG$D~8=9s_dOr#mPbtD_#U| ztWmlkx5 z`p>b|ez&;H0O^YLai9@lUFe#%b*v_e^Dx$CXF3CbZ4Q0Mm5B=mK?h*yih=!$jrw5D zdSz(!Glu4jtigz^ROH%MO9jD_=*tY2ML9th<=n3ppS+h`CcS5CSk<-KlHpiHet|>1 zzRCGHr|~{Xayf%L-=F>D11_LdKIyq*MXtn`g~<XR(KGXgR4sSYE2(rNV&Y0DN%c0u|VjeDsi&g|pNT&V35 zT36LQiHKBh9l2kxtv46hz-LSanJ2N%=N-=Im>i;f9h&moaiqBR`7N;OTJH@;%yaRd2~*z5GW^H)dY1LgOQYkq209#%{XD6VuJe} zQY@61qYv%lQiwn_r0I{%XNb=`Z*Lo)E&o>M>~T!5w{cjXMy9nt8Vr$XvSa9qn!HXG z(9eNw^I3NZ)P-%2>xtUs((2oMMRDY)?`6k~uTg8RkB#^}V6cQlLT#0J z_q+=2P8e>f$Gr|7)eR`rg0#lJk^bc6NRn9ada6(p%6Ko}qfkF}{CWV9j}~rqdeBH9 z5_<2p2(0U77UDduIK6zLt+4#(dhhMVDiF4|*$*10y>VO&S)>;t)~`vpai5>u5wb#)8}!x;p{Q%FKusqv9Qdn)c}8XTjL~S7bM?;s1@#%7bpWonui6N)k2-@GgmBo`#wODdl zUh#@?yf&B@UxW~u* zp&0BXedt@DymiAiNjEmaBHuW0EAQSk_{noa0}2maLg@{u43DogTZ`yjMUf&eZTlJS z*{wVT#sO}rwHrFthjAraC@nE4y7d^&`&WQcV?zQiMCc*YPlf&lbFH4#3+>UAlZ(8` z?fBuaIl-ncRTO!*%EdPH0zGw2+dU1DRb+m+r^+actM7-Clxdei7)9+Ye)HtQ4xLHRiQ3H5D9C!W--UC^>Y==x6&hxam15FsE+Wb>8*(DCdn zEM-Un7A&T=vhP#u<+QN(`lbNCYj~IgP%!JHcXC@8LRPVU=slFIDf|qxPu#4r1i#r5 zR#kvrl`F+$3Zyhf&SJJ6WG3&@+n}ad6D0Hrr-LwIHaW7@L(GP-ZmzzS27%_Or($MbbvlM6VB~ zsfvJy$}RGoJiR9>iPHl)gBD$u2) zJ|EFEc~AI@C5$S9Q`Q8?rR@hpHbZ2nsyN)_uoPDZTeARSWW|bv>QYU`fPwxck{@Fe!+mvDZuL4RMjEVGIAX9!<*g+0^}go`X}K-k zLCe*SQS#2K*+D7AIGBBRjFuQBY@eI{S5B&aqqZ%e#=HUGGd0fH!Jpx~N4Y<)6(Fz9@K{y-}5G-kRNlhQ}(y2kp|N%y($ZTFGVOF1aU z?{4hZ3QM#|3sX5gDSAGe#%o5Kq`jF}AxV7wZ(E1dcbR_i(BmG=mKM)oQbldQRQ3Ll zBS-FiKQ(a;z92Qv+s6gYb$v~if|XaL1LrJl~bES4HFi?nT>h`bo>{ABRgQTW<0gdFH?K! zX6vR<$*V@YOX6QMNh^p@2qfzPeGhUjhW+Z72J1!is+Lq^ zl)90kI-KVS+L^G9a?P9aC+Wuo1^l>*piklQjiSG4xoJB0nS5Z+TI{gbThQqKBoqe3(rpL$_YP$p;=o zY4i=Al{3L22dp5?o%n#wO-a3Ew$PQa{z58!dF%5Gd)q~`+%TWjuzns;x=y7-hD6(rO1o?QAoXarr&fL|aP_}R zfj&MnPV>e_Xeit=LO&O_#KJywwt7mUG?bATl2UbwSQWwIGe3bZ(rq-Xc~^U3ExfxD z&*%nwW~4Lzq<0}=9z$f@(uj136tEdc3^K+t2G?$h8AzeU?O09_puY4h^h2Sa?8NY6d#gsVu> zn(KO5vJ1)M7YU!iDaaaM<*G?o~d4 z=)Z=3_gL)4D@W~uyi0q@fF)E=YS<}*VFLE5LM>UUVW|8T7xy%FfzWX?^uZC%{8tqr zIm-VjLOaMXNYnkUnKEbmtUzHR|?gvxq``~0x5umOSF zCWgL@Dw#FP%yT4lC>U5@!y7eOLTK&A(|ETlpF@ju&bREI2?4 za4vLp@;6-(f49UJuq!5$Hu_eG=kisPj62*DgRfYe7Y`-6E|54QV2Vy_$3$On9RxY1 z@?K*`n3pImV(=R1YvSMI@28rizh5(r%wikjf*hYPP34ZBRG-CD%G(PglPSvQOV_g$ z*aQ~3+V(&KDZEY&wz8u^ktY>Tv*_!0Ln|sBOscX&CoSC5efw1$+v`mtIF{Oajl%GK zQG}gPyzQi00-}xX&F*#hZj1SC-{fnm*VyI4;Rq!3+|@Wnu<*6cS*3F8D*F5TRP?yY zc2<<;;`+Q`+|H0kmsTdss4cFEu3z-xA-TjK#C-)Q$)ZOJ`c5OOuqb%unYEL2Wk}Dq z0SCS!l(~5(!B>}N!2@^brFwIW@|=1jB%rgXTJmH&svMSaBFjvW<|RqwR$eQK*gShM zMx(x4@vmsf7C=zxyP_ex?Z>!M&WM*RGn9NzCja^@jBW4#BXESQ_s~QDiP$3y(&A|X zmtV5<&lAoKZqi>7`t%qiFg@7=7hz)Ctyez)D+lFuJyd$f<{Vgt7*nTo4>f^ zq*g1GbgKg#X+{e7Yp?{rg)q#}CSBmFe>S9Fi1XIEigWzg>100jtgvM5LM_mGMZE_3 zRAWd_c$odT6hXc>G06X$295ko+gpv+su6WRMpODDV)v4#&K4*VI_X^AdD4D@x~o{f zs@guf;3DeX$y@R9Zj;`jZI2*x)D9>P}=u-g> zoN^lD76GSeYkYKUI~GdW^rBe{$gOHb60UDzOXP`hE4o5$8ZBedLTg{kD?O2+TO$D0y=ueO~TW^^g`>PjwMA?)Iy)r2geAf#>OGz8_LsxF=N1@&PdaqE^Hasbv zGjnb!TfKs=xNy|HIj2DJ@0_Sne1PadT}O=S>6=>oah+L@R#chGq3)d_azf@|2r0gV^MvW;KW`+kQsDMs%;6yd&d(aw7|A{=4vS6(f+ zuws7Zt>E+bhg9*_G9IEu$Kap!f<(?5KudPL563f(1TOWgP}t#U6x1o^#T=cL#2RVc zPHuach$U@4#tP!pHDB~wFH~NYJj5jhfdW8u*xpSa0ILnjfY!%68XN9?%&wzq63o-p z{IcEwv+jJje=96yWF>QAs$AVrx*}z_df5O? z+z2-XI&G2-pwUpfIUe=4t)c=a$``A!!Cxn;r~Ff?p(y%pcF_^(Y}S7D(dOll zF4dQ(^1EWAAVF^f`jR$0Um-J{%Lew@_SLJWVv2mi{r*fljfL1(n7k?p6(~d#{_uK^ zE)d<&8zK<03XtW{ZJiMBz-@i`#)X7ij1QPxa5YcEwP6fe_sl+(e)nRNG-WG*$9C#I zk|}&y3SjiM71=opRkz?x>Y9=~GpzaS>vV?&?a~>iOZn|Dog;L(wJr;3i@g$l){jCDTCyGhG|OF=iNXyUnV(+M;&IQ znD&mKK=;$Q!bO*9+#->g6Iz(EX4EGJ>4<pMS(}TP(*(s>HC($XvLFvIJ7x}e2ik+?NMMyHoRRckh%;6mI@9pybrxpk2!4W zd&iZnlKj|HN-udC+1gWN?5=ok(RuLO8{YPA9ql4gB(8N&!M#U4=|-(a{8U}&#u{TB zFR)%h@OEatmgoKD&bj5mp-VTyh|ccaBXeX#ITmW z9TLFi)+F@71`T4Tr61L~G*Nz;#8p#GzdP)0t@#dR; z-x=hnB8JYoOO{Tb_}69pY~pexeed!LbS<}#H1}?GeJ&nE44O|oJrbyWI_)$(D=G~L zD?DX}G~S@4&5`tmn1ZM*;=ro@C3$2nqW?Z&LuB_kPEY41Af>BbtBi1HPPYrE4i4F` zeFr)@r5gtH8kQK-yi0>4q%D)vC!9$EHl(kP1@+Ycb)PVszth0P z_$q#|4F-JUKo}O7Sq<9&Y%dlY6gL0z2iEw5PU>y>ZV5DG7&>BRSEDw%J^DR*IHaZuT&!~6?J4HcC^Y+y;s-SKQ_Pj4;;=xEjE)Fqe+`UsM z$C|nfIg2kc4DGxCyZQ<3_%m*&Vu+BnDA5ty(b5m- zn+!SLQytm{)^B`xr3xH@vs-}_Mm3|>%IQR8(iWBz}F+1)!ggqzcM7=7nKEf>Q18y51qHi zUsD&4l6@wul~uAKPqEd$aTj`Am8;V62lS9k$^=CR>KMa-z_yIEv2c1HTvQCZR-+`9 zHqih_E7f;Uj#B8%(bYaBgBu6fhf@(0V!;A&)S3MAenD^4pks5d;-O~x4)58ho4N#4 z0TWQ0W2&L(lO*-$5>-z^7!t&3zlE-CN)a3yd6p13-Iym8CG90RUIeQr*Jp6ql<@A; z5h4-e+0k2i0lD>=jifS~CLglqNExo#*eH@i8#~Aw$xtm>dfzUjeRzii;|bf^S@~R# zh>So{rt89zN6`A)h?aP89{bXeYnt8aV_M}kBTP@Ewj7WY|E0fpfx_mO97g@k0v%eL z*d6rg4h&;h=m%Xl85x=%G(Y%iJ?=fOG3c|Vbs)gC+HuFCHA(yeU5wB-&t%@z4xM<0 zFE5iMEd*Vw{^q-PqywfUss1@djMriM?t&R7;8zz z*6rVByXu4~&3oado1veG=oIJjA>Irs)r>pLKKk>`OG=PzUX_J|%@FY&z9^z*)Yvz? z;h#nJ1(VFzhWHvI;5ld3lMv%J`Q4ii`0lpfv*vKrmr%bTz<21q@B+_;I`F#mGdk^qS& zoBqvYXMjcM(1oX#ID(5G$v$~W2qh|oeEFt(+X*T=a{BO-Nq~?})WHs1vpS7Fq&Ga5 z7{c@ex+xEdEec_o>du&cHsJ%9X5#>+&oNSV5)S?K5e@bs`Xr&KMN(StSP}-^oZk1T z@rlR#o?1MTjHjj&pH-815J+v^`xeDnC8%r=ah)oZKY&|pESjX6X5YDSq0Ty$6s)6= zs|luK+G3Xpe>4j7nthJh24KdH(&eR~anJ$OAfj&u_~a{dv?V0`u`Y=2b1w5G=k zJbU4Wsl@rj9IJe}*_`u<{a>F=M<7oc?rQ91s$Cb9va$Km5=DD;stVa?$+s8=bjE!y4qE%4|_2O5{)@vUu49T zt|0?YHj9RDT(LwI@=~X2V+|uI)>jVpaMo+z*A2%WS5@~g#|a;lMo4ClxtA`RU=xS` zdhSIO^wbIW>rnQ0fzj#pzY@7_YO&i-sht4+*0BJ@A10e}d5bGl{o+MqruFUp6om7I zOm7$?eB8f1;@}CbV%azR_{75g75dvHZ^)&}^Uu#SxQhFgvebQ1GsE{neL^t^`Iqg@ zJxWN4tvk2$}zP&Z3;t=no?l$7OcL~Ie7+Qu)>xe_Vr`Spm z9Ojbk6n2mIhp0sn^wlpPv>aC`;YFc(fRU--+}Rry|BtcnfNE;n)}~7D2nYxW2%<>u zgrZ1MDJm)`(h-o}I|)VU9hF`z2UL)H0BH$5ASEDT=%ECHQbH0S2?X*7-#Pcc@7;U< z_m7b=_DHh#+H=jd=3H&g?>l#?^wF2z(yLw#b?GBNzpP6`pbQOU87|=N)euh-_E|Qp zAzF=-2zyCjw;Nn=9Sg}ynje~iZPfb)YU@<(+Qk?8~_CLpWY0ovEzt3zB zyc5*cBT5s#lo)z=N`MQ=L^ zKu>o9sK^;JtBH(PyYOy3^#_3gk@99@?;Y;Vk!6m0yIj#NuLT!Pm!HZ)w!7z8H^5AL zyvX@Kt}EV^0-eYQokuI==aAY7na+DuXTlPwPl!h!zv>XAKv5DvDhL7LQjMcvhhZs^ z<#~CLdo7@&mc~=A>_{|xpN8z$r5#yV~N)~95mNYbQoPTQRMIBuh+&Z~bG zGEUx4DssKU+sD5UHdSWKr8U5dwmQ~fj%L1aP@1+Ijj=sYD8$~9Acb=q1!@;A3YMoJ zVh#A$ak`sYpc3dom4qY9!#<0G!L*XR8)Irp93ZO1U203;xGp+$v)Xn}Mhmq07ye0_q1E@B#q~FIVR{PfB`WkG67x6u6cc*bjN=7%Z_2nVzZb zUN`>|`Cl#yW^@s5$IRu-V}ds(Bm+zXM={>220xBF{XrcfFDXo;y}ayASW%_oilLg< zRb7{Z%ByBXQPl@UI3G$`<1b?R`RbS6k^rfD7X^u06h-}|um5y$5TWU0bKrlKUKZ9l zx{d}IVH+u_=hy{=E%sL-rx?ziB-moe(fppG^l3R7TehX`j7t!m|GnIDDY|vF7{#|Y zUygPc-p~S8x69d^-6AJG3=Dt+Uk3wb+k*`Ubr0HA+l0-;{dPHbQ-y5V9LQCQGXHzo zVq5}oU5W-qn1`M@6QMP()35U;)jrBIqH+nkim#!DX|HMlgA7+q)yVz+d{&HuIO%XR6n zl*F{$M;RLbCEn7KSe71jw4aOZ)yf&d=Z8U>yOdg4bJ6@{u%dHWl=@%Wf;L89Eruf| ztFp^UO|L?%A9;cD2;T*V{UA8=FA9x4`BBg_VClbT`nTS_cw=jbn??*-_OJi%4V@J6 zzwj55{!#I1S(;PQ_D1TCM}xSzf2;1-H_A8d1+Ioyb;$l-fgh$(B(q|5UzGd%H*3CF zuynL)LhipUgge&uwE5d5(}i#U_9he={ZwdXsB{H0qw@Y1(2MP~8Nc9|mPn62e@>Q! z{H4f$i2JVw_ltAzj9;+$F!f)4N?3&s%d`|Pg+Z$SE!n?5^jF_n;~G4(i=AG3^>;_@ zy2Z8o-WLwj7u5=K{{xY$e*0fr`G3liFGs^rLtR~0YH`oZ>P>Fr@3K9Ny2uv44qH*q znL5p`%>i3~zu~`J>0jR%=wfR$x2YXPX3MZZMBNe+=>rWCW-sj+zyzyUVNl`sl zWrnU+(No$l=_X){zhD0!+Ky7E4TB|pm6+S>$7!x=pxZaF!GE{nzZ&|#sjDe{EbRo< zSOWU~cU9u=_HdYG?2~`^XDewU6Zl>CC7S2I2A=;c!0A)wbl9?`ke(cdf80GPv1E0* z?Zp0`T8z4UDrw-ami^Bc4?{{fY`P@}E%`4UDrnM)9B&w-ATs&I_jBL;=Li3iOf9u5 z)}0D}{C?f_&6w{$`p0VnG4iYKfG=wg{!Q)wxs|dQg>TTY-=NiCK{4EI%0>Nt;V*-7 zdAt4dwVA!b{{K#|T`#!^Ll!`#rw2JLe@j>{cv{RC!DmSQzqG-wLK6+K_TLzPLz{kE zsqEkNkvj}DlvGgsF9G)qrN7N1UxQ+XrC(xlJO3&=f-`L6O`;aVTxbUl3CRC< zF~t@`e3%HN*?$Q1g5nZvVvuux|KMQ57)JADQ)a2gc}~z7==<+#_TTIwxywf)3nJ4x zhn*p8sGI|mRz+beWxuZ&d{>&RFgjyACS%S^`;yG{>J-tjH;g)ir=M(_Ni z_x^YBy(KtRdjo_Ysmo3b!vB7I*8xTT-Ge&BjBf^VG}k@*&u1qd`h7>!XjvZ3y59v{ zHWZ8U)1-g|3w&MuPm_{qJ{sG=2P{SZ!#_}FBS^*&dTO(UutQTCex@S$MAoiW5u{zb zUf7tTa8rsy7Kw2Gu^$Mt)nn07UCb@}?=t`O?T{;svhir6$1`;8?^afzK6S)QjQ+1= z-FHMN{a`0yAFy-(&|7?B zSFATxUjN<$-A8NS(%0!OZm;l*&m%mj^wt$KXFRDqPX-eBJC^I!z-qC!z|)#Y(i|Cf z$;$^3;e@jZ$BTNk{~tatUzdhqN4i{9URCAnB>e83%rnp6ox>G4xvJM^ZjeTBy&QUg zMtYyv1-VQ;=pN$Xp`qpK72?hR-KARVoQ@pAoJPvcRdsw>4qkg6%~9;e7ss;(jZceak{Wal`8P z{;MOI@1YB!59p&t;SUzB__?DO5cn`bYgz%l30XKDyYBGjTbYiX`d5g8+TV)K=cbAB z`OE75yP5vaZ*`({>`!Pl1dA|1ln8Yd&39b0Q*^eWxWKcch&SnvJA}1@K0G@(p}+z} z(A}>R7?$uUWcV$!Mi=95yDdwSY{$)iEIs~Tl}Qlu`+$Bnc7Y!rG1g!<>t1Z+uPfMH z)N=t0f*{lrK&SyegeV-U8#MT3Wf}<0hyOJxAb}|C3na1x@$%nJ@1GpRzjWvgqa^{0 z5ZB2Xq2hzP8n0}Qa5ebC3c>difNd?eK}CF00uG2)MIOzf+;zh|W?{Lrb56p#sr5~@ zse!XlT(me}Gw58NSy|@7$zTB8-$wmE75GnMXnR7JBJK#wAm=h71s?-eyp?em>9Nq60s%`n81UWbZTdUO*et30&9&*uO;LBG(Jt z&XweSJTD1+qgRhWhN42*jANoiaQRSHh!|{MokDn6kPeORZOaitzJ2woD_{M$kvLQ_ zlJFoh-fKfRtcrG2{@)s=#vR6unJ5axg?B`~-oB-ts&>%EIG6zHn*xh9H*A!d6|VUw zlt_o692o;u(8UA*a&k)2-KW6-#D{4#Fjx>`jvDsI4^;r%&?_l+TRntON7l2+vWXE? zoQ&i}S5=`*?;F_YzkOGoFb#zz!x;xRdmS%V`_Em|p_0=b?icFe=P5XH%6l;?0wgTY z7;xx(S4jZwpnyIVH&ucUyE%Xgjaj)P`;UO@ZorC}iV^ik6ub_^;?cf&@Lm~Z=3b^l znRS=R&g~si03qz&A%NNU$eX7u^M#<>hZLj@pM&?(I?r77R1Z&8GXo+)K`Laq+!_!{ z8}V$5#1CBNccny~ObUVX)`(ne4k>igH3Oz9JyE6o8;)5V{Y;B@3Fsa$shKcOEM>O& z{zR^JVcl~zow6MwoC{ z$-in(JS2{CEp)@5Jqg8JPuGw74J}d_cN&#g==c?7uCe@l=8;>;)L_w~Me?-Tv6Qdk z_9?gn4}zes1o~xJrlr01($ZDBBcy4OykH^J&qPQnBiTBMJj z7LqgFsVob@6;J8D#XnB6bEBQ?oXB@|9yF-4M@<*T?vu_Pbq?>&;HGT!I)=@D>er{oqh z%B7gJn^-gG+2P-ZeSW<4$6v41dZieJm5E2M3L)|rfJfVn9F$Izp2-92^M7%dUYWl4 zqZ;iRhA&K5H!AD^lL_ib{u%Z_vQHgSb56rB2kOZTprA^mf5uUEIMIa{wu;N*`+08y ztQ5fHlcS=zR+zS%)uRyMs1mc!J(k%QlebsqZ`)yW1{Q~59?@p7Q|u!(a0%HJ z6+|_Y+eDucpxb&rvg|rg!YA38FLXS#Ry8J`5R9=KHOhE*;qg(i?bbR>_cSrTgTA&N zPG=lY7+uYDt#2Z?p)V_Y!FTBWD9qe6dv|2r?DY`B^Szi?PFiRP4E?!C#a4a$O1~E1wwC1N zRw-G5T}j>XPxaVRrJD_+QM=u)tMZtUor_j``f;lL6X+)w%d4J}_oJm?L0 zZYiQEUd~>yV6_avgY$9$%|5FfEj^|HUDn?A@&JA|i9z8hAx~!6#l`UiorVgue8fa* z;q~iL506SSk4Pvz1TQy1v#Kh)N3k{4m()p9@AUKj!*94X!s+~HwpvR1=-xVs^s%y3 zivq2KD_kevFXhaIUJ^b%bT?D3lNFwze-U^>qOdm>orZ{|m(|)rok^vFVX(->Nfpp) zeuv02_TA{Z3C`A~IF^H7TK+ztBU{trG(_>ILxpjDEJ%0Ji7I^bG)z|ecyCguNbgr) z3Sw}1@PSAb5q4%4nVjvWv-!x(tZVaQmbF|WWV?B;FzR)5D3_kefgs(=Ja5uG0{gl} z#Vqc_@t?#M9N@ywC#_pea0>KDN5W|1Pa&T#j=my19eIZ^>DiIcwV;(J+o>Ht38z?F zuKt$0^NTpVn(p1=b_(Q{)H1q1I5pDC_J%xCi?Xw71)UVAD(Um-7`9REz|2TB`!q6s zee#g!%R$s@-@HZ;QbP3E%HsmqD-zDPIUhQ;vwGF5E(tv#wq!I_Ftv%Cc$Z>b-F`UsCj$N-b!l~4kc>shz@;7$Vs>k z*Yw{}!w)q1m z9ivbG7s-HI9k<0c+K{nZ7X>ov`Rg;ltB90mx(+;5Ztc5lwydqy9+?*XeiRzNG%3G% zgf)Q6wWnIY+E3x)98_8liYl-+Q5t?53%fWMRffDLqAy)>gW!e_b7OHNV}+~CXP!^j z-Vp&iTqfCUAcqu4I8eZ%H5E6YFlHjsf?Xzmn6^@%FLF21MHZ#{(cPjh&LV)kO_|3G zsoX?ckq!AT_>OAHtnna#7FBP-H{ada3VLlX!j~Z^BW3cQ)I{q5!GT* zwWDJTZCTN?kw<}@#8&X)9LQCjV+#fksgCFso-+3^t4nK>qqYRiW}oGRokEY)-p zu_?FbOYve`+N}LDp$qyL>q%?S&Z0RjFZEdnR@D-OR~U}Kq|?< zviYumzZKTqLLBC7(C_Kt3=|-Gjov{0Y@dB`^4tve_V&797azlir*8_2y4E-DR&usX z1$q-uIEg&AnH3$ZZg|vZix)ZSIxX4tTJKw#PYz9@GW)BeQCo-p^-;0jGl`GcbkH6-=(djZOwm<%LKeWv+g!xW z2g=X-`L5^@zcHg9?-2jMq`cG+>nI&{c?va6#rt#9;OFlqgbQhw?R$A@fx1XqQG&j* z<~SowU0m!^vTvB85`B2WH1Kii+k4}Rh5^>i=*F8*%+3tKEiPwu_T)#aTtD~rdOlSz zRr*u{h%K%r;RU9b*|#pmvw6r(v?A;qp{wQ917@kM*qTW;!cv*#3u+z4L}Y1dSjxKD z(ztrY17ZAm1$CnU8Hny#*Q=3Xwoma=>?s%Hq)z|6+0sYyEzgtFy3r6N!4CN8B&cC(x~azTH7uaN^L zDRL}KK6_yika;~HnX`afz7WZjA2^fJM?>BeKiD5o2iIrcB%YW0m4c~~Y%|55y@ep3 z;MH|&OP*jv_w0PSIBtECW&DXFRtY28&@ZeM$1Fb22ThupEt`1x<~naZ7cCcBDZL?_ z&2MjWrQil7G(!|(Z(hF4b5dHH#Ssp}%al%ysE1F0!pF21F&PP<`txPp0V6k_m+@Yi z0rB$8qJCgSL{H;u@h&h(Vs(31`B6~(g3Z&%jazFGr1S0SEpHh9m|yNf4`B!ZdZT)~ z*W>tsJ=p||jTX^2n z<9GpaY^z+x)%X=qlggp_Ip6nM;HaTf$B+%;6i5Z@21R<>-1zm_%ho{FLp-%+rXO~7 zFKljZ@yEy`V#Axh6IGLkCBxwT&%V(&ln)=&Moc~C_PFP zxL^^lk5i~l3csLN06|xG4ocJx_8}EQ!t4Gp%7J~HDs05!yx<+rEzpgTZQW`}bU>Tn zwyimi5~A7q@qwX^xzA;*UiD72I3@-{AwmUQm=3P>7VhN_ud*m?85|xpUaQ{{2qx+P zv=hN_4YxlUgGdxKR8K5#RD+{dt=f!n9VZ-6=c-r1KNSiy6M+ha&r#w#D|W9|)^q5I zIy2AUo;i{);4~@|bWSMw>XgOBr=Oba=ahk?lQZ;3uc255gAet>F}DgO4N~5uJkj^% zfevNgxoqS{Z`3OICK`AZt$B~RqV*4Ij}`fk?zsb;hLeoDjo0pSX6yg?%&XhML{aA@ zaIke7BO4*lrGioCl8ihYH{|_}Lc*BNr6T=BAjNe!2@}eOP!V)+_WcZxLdp%>j#b62 z=iP=>DUz2TBKI)$Hy5L=(h|WrcO|vG7rIlao^cCX81G@k7#rC}m-xZEFU)W)>(`ld ze<}b~T6Pf^kGMHVw*eZ~W=pf6$2Z2iAck@&OUur2Zil0K4UuYZmtiQ}v2Int22j>- z1L$w+exGOUcJ2d&=*Yie2lO!> zh_&)gNsJ2NW$GKL(4~eE> ztO?Zy6g<5Y)Hy(-2pnCVs#Rea;MC?PZ+l+EsdwO2sSXKBnzu$H6>xXl=NE z@xmv^w2K%-@A+S#rrD0-m!ljQjCT}Lf6qt`Uc=S|TbRQC`oULmuvWY7=Iu3Td)`>i zrD_885ngvx-)B4?dT`J4_%c>A^0_qDcepj3%|;QGZXe(U0&k*6r}}^9e0SQ_s|9wS z8NqJ=^sHol8(qZU~%*?WSgiPv6ho%;&#%L<> z_D6&EgU2T|qSE|ObtTk*MOhh#$OcVxJ#nh1&_u*J7HS=rN3t?4SB`k#<-&FTt;s{W zyGr!HE2f9cbZKU9xoGZ~mb<6Krlz1$&oqp}sQG#H#-@&RxdD=9VOE@&8+`pL;d0Mx zhh8R##M`YMo8?Q=rClur%7!PyU#9plN~I*!TmT8Nwhi!(4w|XyJ9iiyxR{|;PljGk zG9@OLg^e0_YbBNx2fApb4 zI*mZxHnl_lV#wio);uaNj6P( ztShR=z4hixBTv;HK`5e*{rog5-qrX&w)h;b2tt+^F;F%M*uUzSbn7Lq7LA=kgYt-qqSK*2;~L-57? zFbRl0&`#J$Bw3HZNi|p3C;eIScwqzF;GtRAHTZzKU4N*e592EmCfT{D(g5siiAsW< zkbheDv=mPl*BBwpf2@&{g?jZsm-rh74evIoDS`UQZ>9A4?Q3ulzpEay+vS_{wg5gB zeBy}X>?%q^)+6!+SB5zGkb=i*gjW;imEM=SRZT2nhV37{Y?b{8S^~YYh^?Z)myPrj z55v>Pzlqjue~2BT9X-a_+q|P{9uQ?|9&ktped!({bq>sSh8JOmpH3+ZeR&y}oEYvA zC6$;5cW3zh&MAqdf`H?Ora7^Ycd%li=Ma}gHkD%t+B-1q|r1`)KQ>pNk?bcC#p=B77 zvI{w`3xY3BV(RxlEK#e~@J~9ZzNe02U27oTi(HyLyd-Q~t-E3xJtHo$)sAS+wB(La zwz-U`Stm!_q%6AIgKu5o(ps zZT#X>qUc*f8h)VD=?zwTO)ySf^my4yN+>bPnCy={hreYnfP+5``eQRvEj+E%ruC+AO^Oy{h$ymj{TD!wyuN|B;IWwAS>ZY zy;r-8pE(%Yicpd^!p`;N671e}tTogR8i1~sfcD4P|=<3$&O(!{zhFw+&&(c^9ytB_WtC~^B98C>kn-!wP@XX9i(t~O=+ zUwPi$?I{p+k(-rWN|+-}!{!W=drV%g7b@){JP*IowkR;)ZtBoBCKQ+^tZ7VA7VePQ zot5BW*2Aal3Npn9er~(ZY3X9^l0V88vdbZhk$2pG9Mdg-LfQDb8YV4WOE22Nq1t@j z1@cJoYOGrFTYRYpc5*$M=cd4nqyv`;@w54M>F!B%S}j`_+6t;g3rr_|FC>(aFP?t*{ux zL>HUAx>3l$pl?kTldh}maPe*5vquCU|B`K3k$w}Tw<$`G^$Fv1{?!+?c2Ei zwh)Z_Mt+|`Lv8lp?Oca*(Rr&fZNY1_?HTmp&uCg?0%i^{SRLTipz3%~SF6_iFiSLc;+3iE*3WndK^db>O>3BS z8wLpTwXu9*&y`sI(+>d@fRDbOup1JJw!<3jcc4MdyW$pf5!hcAeAjhjw_ zNG+Uo+u6~b`91Jg)@nWR?WMTOl9ozm+L#`%;cqA?_*{F@Ff)tPzQ|lRE_v_Le&dD0 zrx`DDpV?c1%cP6L$J#rfpX^stw+2hPnG{N&BVD{FIGOvOTbfHNDi|CoN^+HE*;N)GbmQo9x+hu+a`riKF=Lt48-+wiLs= z0<9FhamMz8;2&ogK?Zn(A5o91buR~Zj)oG!t|v1Ql2$IhMX0jd;Ld~+bcRue*u< z)F1bts+}diTX9vEFA4Xe4H|v&_%7kz_0nfv=6xZ#F09JsDsAiC;(^0o?y5@ zt+X(aEz#1(HI=~*Ep{8O`cBJS8j}B{OLv8x& z&mX%|ealhJ_te)N{Y*77tj+pvnk2-SVCJps-rsoc;H!Lx+6tGHbF)KT^U;>lL3r9h z^gw}t`nWiglL_JA&qidDcmxOkt&2%reV%1dGHCmV9onmiPoFzJ(k%)_90QFiSa0b^ zQI1|_RsO^zOGl>gQV)cNds`CJ?267f@J=0QmzvpIB&OS5=VF%*5|JWsKq-my^Y=>Y z!<@FJTP~mv1Td7Ofp`vqCHbvu5?|f+O5!o$gE~7?`$2|L%~g@QtfB-LXq4^lApSyx zLgq9zxutrtG!z{SG8%C4?A5b{f(GHG;KZF4=xSTt@qwFaN982acqdy{HYc>G_HkKK z4~3;ZG*W0L5#))R*|!5P@rxbqz1u9b)iMfAFFAiBPUlBv`?$8B|D<9x z_qq-5e+|#6t$-HBSmJxi-iXeDsWj{YJv$IlIVLisVcHsqX)vA49y>4J^ zr~mme^4eTq%vPT5E?0fl))bA$`wvzxo!uBF6fR}v)h@e=SnLcRreT3=n;~8@dNymG zs~PpM;UV#iBcEELR#9u_e7VuRmM{uIdEkBBmO(Q8!)1BT5zoPt5kh2xN*>drLs=KI zW=gDhN#yo)&!D<}xA;h6|S8Y;a#^d)E_FM(CgBn31wRVY%k?8~j#hA?6^j%Ky z*J(`BV8{2(^(FGLBMZ{Yd6nesePe7u@Ab5LiNhSJ>yD7#KyplmxLAzl{S-GbsnNn% zAM*kg)^|%NK@=qzg;5SS>EwJa82D^s_=&w;e5IdA*t(d(%nBezOU}I~*0Ec^fsMB8 z>RW~RgU;d2_2`GCEnnf;D$5swVsr&=n=*=rJ->FD^?75m$1BR z3>^uH>Cx_4GrjMFY6kcS^dim!?QG#K&_q!!TW-4<-IMrQ4f!C+vBXzW?&s208*LXS zpGKHLF?6)px@ANp;A&2GW!FYDq0e@`Rk-NAetnW}uLNLMxY?|h*rIz9T|xa7FK-!i z3EGejCp1p@12Qj$eI7Ef#<=TRl zxQWfJ~U$&5XBqw}us8Z0A8cLOSI6 z-OJiN(L9l^ja7ZCLF^{faAo|AFY$EVKRATfqd zs->xGDaarP*@E^QJ(9<(<1B_dvtPPyndXr{#8kGzfmY^A$aiey>;-8SUa0NV($fvcNWT1H#^SE==) zLWbTIL!)@n-H_;wB)AvQvbptE^{x$85DeA{Wzpua>!%Nl(n4E%OG-@yuI6PLcV5_2 zUrc2ClgJYNOcb$?M-D??DRGFzqjDGysU>UxU(TJp0rGd|{$oENZ7)wvnnS13_-0pRCl`aQ@ z&krz~CudVNb77zpTzZZNjpA51^3Yb&IWwj_I}u{So?gJNAvGaR_WROpv2mTQ%ogdt zn7=!ASE11F(-_pkls(EwbUHS$!%D;Wk9ZIE`v-}O0m59uw_6hyoRithcR5CjBtX;0 z&nioPY|v|ee3AC5H231-#TRPUb>Ty2=NQ391SbwYaGzva>6Zk%FNhlMV>KfU0cqAH zEoGoidt(Odkkl_&BOpXRV=wRnwaJIvdUM-H% zwfQlTg6#7?=KG8IOP?l*0nB(R1knHf}%}2BDhjv#IHl!y# zzXm&PA%jj34yEXA#pMNuh0<~ zRT^37kM*zrQt!LuG{YoaT!*hMIUJi?TMb&UxB%KP5cR;e8L~xb`i|gsVYR~yo|0`5 z2QzN!m@6mpzr=NSe?3zQuj>r6mawH9wx!SWuX%ObjNn#pwmo*%1P+?A#fg%;7<9+K z|9WeFmeh<7vOS+ka+H?)aVxA6;tWhq&*T;D3nHc&%Bz0!hn`p0#*HYuQQ}C@5()B^ zY&uC1YMoX`oJVW1VYLtNYf@Ni(maJ3Gkp<kjQn0Po!TmIk0u4@&Zo#eym@+( zn_EN>9VA$l@j-iPiEF_HnW2p9a>sF@$dgl8e&d z1RV&R4_(CPm0b-q3qMw>)f{Tjh+$|zQBZmdHH`0$yVQAQpKGohFTSNfjs-SIU(ppo zELWYqAt{tP7|hLa0AWwTRIe`XB)jq0Go2BZe6{Dmr3sg6y$ASEuyK{#kI24QlGzu* zXkU7n0xFVF4Dm$OQR}iJDBEQUeJFa--P|y^J2}juonZGP;U|P}S3>6Xa5%4-cR=eP zejVfd?ahWuTz}$slQ%712=OtogYmJz=^N)*PBStqlDOgDo7FXW8~gcN$L?rtRyP)I zCX`ZM(YZt~@1C$nfjb#F4M#EBS($$Owl%7JU89mJ=HrZMk zy)FhKB!V;|PnnkQ>rVD-l^G*`rq1*G?16tgF+YhurE%DAv55X#=O$}Dh#jLPQlbB@24Z{Ppm#`{t@1r zb$C5*EabdIDCXA>8(*EvdZBXRxwZ2;>uw}KD~?O;&|YFW9kx=7rhuWmvlc_uIa?b` zn4~9;PM-Czd6<)X(k)8r-lDKl83%g4llc*1k!$2|dg0*n1hXL_{pB6P?0HiL&` zv&TtXrHxPP+9kf}S{TL%O$4gm4zJBe1$IynwN9b%_vB6as=rY;R8+{ToujEXx~Ae3 zT`(GX^R=1(bH_r-c2_+l5DZ()XZ();oV&Z-9_1^^Okhwj?5SE^wx(AW&@`eNQw`^J zFLoa3PV{dFGF}ZF%{r3Pk`^p-5p{+#ob0+jQR8jkco%4@D8sy*rlhd<=;{rIB?n)F zZiu*y=I!FalG47#@I5kAG@XJqe{M4Ra1_Q=ZX)sBjSzpE5Pwj2@fAtrNd758*S7!<#!&#!C%3v8L;=6B zd7WENM|s$d&(A}JqK<0nKtmG5#IaR9q^P~YK}PsDC$9!B{PZ8ueL5kWCsa~gxWj?V zdS9@EmPP?(kCSzBRe}AQy0yOjjzz{dE2LMe!S+oQcw)~I^w2pn;k8N2ekZzJl|~*y z!rmPUL3B0;KiNqLRWsw*P&q+4mM7`2tLmP!UP-e$F`rj{v%-Lk@s6{|V)}8#4wLeU zKYDPYUrlWok{Y@Q!-dvHtz9Wvx%*kuXAouwL|N%pUq<0j+1Gn-+aG?Df|P~Yv6U56 z<_2zP6miV?W+FPQ>^v`Oo&WfXHyq<0Yqgus-D){ccDlQ$=@jMgNi!s5k z`KaY_dMKr(rmU)Ij57o_hxwg6QLzrUUSkjgfmsB&tKTfxocV>M!VE$&X6q`j&!mKJMxX8arTMwNVCG%#!4X7&;42&XQ zK8RyjG|LzF4?<+gzk4UNXCH8u=d#*0eusyRjc-=>&ao4qqH`_F6aG=RSFWos8|Y2z zFg)?}V>{PNRl6t5XP0}Wvm8$dsouLy!#-CVzAxKuMYTRRttLLayXKPS%XGaNAP)^>X=jJ4o)!!*@Q-l0eo)UIw#$l*^9r^M(NRS$r9aa@S>K2RTArZlO2 zPYj8OvL-EydNduyrFZ6qorUzrUSdT@Ph;XvJQJqOrC7a|J?)PkD|g?~f5xBL7Iq(i z!2z;yK_!;G^>x&S`j~l`Z2fWgdv{mNFmFmlRDM1`nO2LW&rf#Qj;gN>;l{1WKb#o$ zojwM|RvPq;Hv`FRDW-V4v?Yo6u8O{D zqK8yODu4K*cgsREUUCM1#4*ca zduDGg#Idd&obnI4QOq$<>(L5}?8@2UilsS%YRGMbZwF>TC)!t89;Obud+7!B`41(1 zPs5oyE8!9k<6BPAyCn0to5N0_L1yD z4Y_$Ii|Av!M!)G?r(Xq88sWpC8|`QE^J99@{rj7XwSneWtR{AsaHpsM6^a6ZTFr7h zlN`4Knyv^{=({9}2JEBRH(I0QD18E$ zo~c}hT7`cE74_XOyS8A+nyUGwRU0t|o&jxn?%aHtpK~76p9qb50O(bJ%MkW-laM%i zf3O${qr@Hy*HG2m<+cNM^NwXK!9rb;#XA9&Yvv`&PQ9tAYjQ#WDv-PjM z{}KXuKa{|PaPt-3l%f)Bk5-Anq=BrLxWYdxQdM@P1lE5_Q0NiED=#jA^zZ_aSNmgI z-q!Xoj&!;@1ogUQiwTK(dHKZ_z0aBGes9!M7Q>Z6n|UcHQ-s2aI_udcYQ|-5tPl|W z`Mws{AqNLwcDGU>1KptitMfV&bgQ_K#c)eRZ?7PYGLw#%4si&~(0L+hTPW%RW1s{t z<#Ap)SuL_#m1cgQaw*J*=R~#3LtZ%l(o)$x<|}maSu==yj8~^_8EwY{BTTYy##HcE zN!@qxU;Wnw4uYgVZJSS zG8wLGG3KnC{o4JT_eqV}DN`qo99AI)0;D`;z9e-HDk_s@^5@yRU-O~z-`MCa+0GiS z%4CTPXs+1ic9E@nAfNY+u}_2$(ugve?Dn!BJy$^dMF1072eQ-i`SHHFCvKPf5;38C zyO#@z#6D}nYUAKGZ-F?uj0U}R+ydNeDFiS;5QG8s!Z3Ms(@^xF&1#;vX>6#Xjl})x zJov8XdKk9&($`*k1ix+2gyhQOjm!2|2O4c5AKuDH{TK>HT9d$*RBP?43b+?%CNnk2&c=$=R(iVxkOJ zL1VDuNSs$In~k(*V8jX4nS-e4zSxfrOG9?8tl>D!*7-~dOiH+g8GOcX#2)FV){$5| zbHp31T{7i%FR~$v0kXdF2JNEzf_N*>`zsu&>ai0h71$=CWe%%!ox9+x#6O8icLS!6 zSY1oJly;T-{TD@vN!C>p89`}@0#*s0JC}-?o_95*Fws#nKYZRMgDnYTlTPNKzrf5l z6v%t+oeXck6Sd(|>;zEeWlM4O7QWP=Cb0=q#Cb;{*TA_;Pe~4?pg*l)ZttMKgM`i0 zTt6`wXwL|wOUq|mnYxj@`Jasi}t@Yq1#k=NfO$BUF` z_C19f#DCLYh5R!HzNgRqnR6@udJaD2T?)%0+f!J4*Mj;bS1D|7(>5;z%0379vJN!L#8H=t(9<3)b*`M# zgQC0RYXInQn5Uov>FKDhUR^(}-R=N986=1(blk1WDJ|X2E#=+I^$&8m^+FkA(JN6% zgZyl5dLZ@vO==xB_d{X1Um-JQJ1C~u@fy5e;{~r4r`C#$BO860S@H&$WEBO~K0@&z z^;X0ld7gX?uKX@`!62Ze-p%m35Nn*N#?R-jVv+gW%fl7E|=nwsk1)wj{?GPsQ z(y~C|${F{ACHbIh)LA~`w2}pqfm-^DPnU?Gtp#FZl#MNdECF0n8mxY+Wb0CD%w;Gp z<>7keY?bL{z4tlyiJm73Xv8x5<9+({WJ8rpUzeW8nJRq^qCb1~+L>j$oflv6IQMAV zA8wNimF*UxWsA{vRUTzJwVjKweLHm1kE6~|QTRlGCP&Rr5IDkATdY0yy`f)P@tJQy zi*&2Pz{l|?lit{846|B99x97F*2lTF&?_cVRKlIsULynxm;12U$o%&^GYQk3fq?=O z&tgS_%{h#U2IW44HfWD!yEui*g=Busv2Ry@^!?0t$Tp0E5SY5;SNv3faF|X?H2u|M z5#C8*0|u`uLUvgoei)n{85b%%hstPkJ^Bf-`Jm^3`ZGMDyBQI!y$g%2DdW@#Jt^is zvv+Nw@kR5{2hk;yay)7aUBnR)$I1>>-tOx5|HimNw{o{DT-bn11>BMKs3H-cW$)x@oxG0dp@=t#Yo=A$gYt z0vC#T&Imsdj@Dp|(Hx-mDZ}w_JQ=(~*d%CbUe^pCdRH?f;}4w4pdC@=+xLB=ev>ew zGeO-D5cSEv&4Od_wRfAo50-_o#NgKPC(mv+a|de0?z)Y*5VV%Jt9}pOM?*`!zc-nU6O19gGnyza~Ifsc~bwZ4s6^>k>1;tus1p+w=_Eb^(Cn zUPTu-w~P{QWM+CL&$K)G$5-A3=&ka?Q9vbck&l`52F*FeR;HV_lacZ*Yfl-yV>|U) zLLk+;Q`)w0j`7d{Saejo>DW`~_rOJ2yO5I#;o&a{B6UQwi+5=L%}2qFhQr85GlX74 zBSiCXb@$?vj2S-86|rT`&JoQV&xO!W$+GX9C)K3OYe@rC0&ZgAt5guv1It&T4_XI# zQ1)P~P4ITZszmQo6e=K%c0Pb7w^<)@bq`d?&C18Ct$v(Y%|!K-EcLm`@mg(B;a>Rb zX~O18`FT5Is{9VSsQM?b{jkc;sKUWebNMiD8;hR|&7ElB8aD>mQ$QePxm%)C*Z=k7^5f=Q&dRIVis zfsuaCCSS;PJdKeDM;-aY`~hSv2$_Nd_+E^G$+s%ZBzC}FRtCIm4H6ZJe9{syQS+Ue z`A>cN+qd`CsRkF<$v583MSrQ1k8TYAq1JdVb-vVNsqC{GfNp)Cl)f(Or@!!!W>oo1 z6($T3JT!wt%%+q6`*-cWoX|1khC*MJHTLdEEYT7ith+~8C(g(Gm(SptiX&W9ui?s@ zNaxIShA!Gb!@kBK07$PYOM8veR`mOb)-N(2cn3yhZmiiAIXTGeC%~_AEaAw^Y~qp( zjKx9lE+fI;bSTx#kN>3|&QHq%N<6I?r4x}|VkUszSbZL_P4VX0IFLXzR2A#L+WNKc zT0FrYjUg4kon)pLcGpiAVoHy_XLh3}3l9{>kHzb=z`oHEwV`bMFKhgp^!~C>BY`E8 zsf&>PwYB`|)OhUb&7rDS* z?oMP7)zLLjVmMsjMXUdj@gRaTX?Qg}U|*5tf2+Uvf2#jqA9}J|joJKbWv)fW1m{g6 z4!)y%--RboV3g85x3o%jAf%ecAqmFKeM$#|v3%r*tuL;`?mt!F-<7voDsVyGb zXDClDezt@#9~3_VqEy?y1jWpyUdvf?C~pW!Co?-B=~UXQ|1SCyBfm$3e_1Y1g0~(XWkfsD>yx%aO_ z_QX43#eIfY7|ugZBrm3?cGjOAq|nz_03bN$Svn-SPtx*S><${>5K*x3z|P+s{&KAU zbg%#T#-|uj%c*w7sgE7Op(~3G|8%^8NA$(HY~`N8_qrZCeE+VATi`;{bM6hr+=!hn zDRT(gYv?X>lK5S@1b1&1gC}253?^dm8#LlS)XSS^KBTD6;Hjbe{i2os9GY=&9y)1a zX}6sAPcK$%Ifdj}`}B_I5A8}>8TY)xLFb)K*utwchJnwb;KQe4jDuwiUdv0O{l zk=@;FpP&r%qKmC>v7MydrGCSOjVJPR69=8D0P%G5v=-)$kU$Sf{*l`b2%uMk!fiHt;3O-QDpeT0@XWGV<*b zZ0|(q%g90U$Q$XqnS)*p;QvJn{wW;!3IxwOXaz*2*#GN4e)o71(a~0GN^RKrF-L(a zXZnNUz!vUXGf8_F!1$-8$P}-bA)D!f9?WiU>m~PUB%q|$w4PEWl}))jnNfW(z-3qS zwN@|E!hHpDq+>V?vg~Qj>5V~iY|Zt*TK#8)sW=?7eYWoN+surAy*nVGwR9df;1ARC z7}FHUuqr1J_J7nH7)B5;JE{8VMJ+chHQd8tsmkfSn>a6QB-TT<{ zixc0aiRY{H>ALmUCQ6k-SM|}7`VIo;zM#OkK2POOZR?F&PCVN2t(+9hA?uuFKK<&M z?MlvV?cU=}Y5&uSf7|vyx&?UJdW}~g^RW8i!N@xe3wvj8Wlqh0Fmk~(SaJnB`PxV` zEYUwlu2_~!^pOji7Rw~cLD<@=B)aC&b2@$f;&|No!Pj}l85J^h$LLKI#{)6r&Z*T* z;KF^-9P{+k=iv~FKvbl+D&n1w@G{J&$o{M8e>Wsy>wMT~`{fnUzY1MNc}QD_*Jwq& z#3CH$J|U2&sXMkmEF(HF7K5x;Y#aXwTXtWZudYqKOvsy#RF4gmSJ+eHLe)CTYF=*RcHmB=Ulz zjY|9cYlfGbZn==z70#K~v43D5Sw6Qh(gq*#4Jh|2JJC9u1Qz?~V)yJC+EKwSmS2Du zM-Lrwp#{%`K_e+ntaQ;v7OyylE#Yx}&{*h%{&h!dA~43;Iiart{8 zOusRDVoiBS`}q!7d^cdtX>o&&#g5VbW)dgz!H! zfc<#=qU0}s+bi&fJ+g;%arl=n`ac>Xo%6$48wpMcoC`2i49$wB)cF7>ZDWg>=dS@4 zQWwA91?Y*KwjJisw-Hs6$`U>U@@gmEA(O5&IP(;n zo>5gwmS1!nl1=vc&q$ZU6NA5J{rc4XXMfdfZ{_OA6}s~l2h`1+dJ&L!%fWY|A;_Pz zNvq5=E)ameMMM^A!n=xi=WYbL4Mv1JAIzWxlu$;hg1^Yr{RY4PuW<7>!yh-xH!RW% z3oQT3N~{uEI}b-6Gw>U++wY{l;38;8wYMTy#PiGD|sCN6P|{(sEvKOZ<#c)sZJd~Sh# zX}vQjs>|!SX8JQxom%{)-}tXBytU^ll(_bieIp?y`r-cni=6)LBU^jrzjLj{P2y!7dQ6&BQ61(|-SB3w44ikOM6*@^L3}m)i@$UY*V>J?PBLK*W zHd?LXTC0Nat6IqXAC~c#IjWiS9Obh90L^S2QDIm}k4^m5#%Fu_rIRe4&s}%^tA$lu z;K)K-erWMO#q__IOnnu&!WB9F>yPPw#*A?Q&oK_g!rcc<(eLJ!G}r$wuM?cks>Tdl z`>XSQQoOw3b}S)U(2L@K&cpvxLVuNH$;3ErUfQ5%h6dspY_4K1^6wt%Kc6Gc`F-NZH2*!M__WbIE$~A)H6)5!_j<+JKT0x9`oFHp{@pDdZl1aW zFX6IX^%xv8!fVx;5ee(5R!VFAuo?Tl-p7CX75mM{u9`m+HqszNJ6@+A6ywq(Uc^Us z$C5h7=>wtG_#o$h3<<}7z}FwQ=%XC}o6K@9$Hb3w_Rf#-xijS7alOC7$1kcjPPn|4 zYu$zGRN3|f;cN{q1(fN6ipdb?3k+T2ny1=BtC~j4$AfX%6;$w0^%6_(Zv2Od97sj& z5YNH>wMviRtN(R~t>RiOY2Om<_BfX?C%%DMLty2-lhb!B8;^gce~&k$O%In2weVWD z@iK?uM_-wybY*cBKw=X&Dsoj3u$0B3He8P0aJW)P7lT8Z!fGpz#BI#pAIBRgGk?k2 zE57YP#qVcrSOz&rrRah(z5&A@WKU|l5SIT(#9_zPY{ht^M%tyd%46$3ak}hye61jU zhy7uF-!{8<<{>NsW{-T+xYFQN%7!SMgWj{iU*15q3}JndR_IU?oS~fca*Q$_K1)CT znFA)02~4ZrJeYWum8%ifW?EQdEzR4b1Wawkrdx~Iaz^Q0_K65KhfHVX^pmO2DSHcc zE#d1s9N5})B8PMRp>SN=W%N!@qN2gP8BVz)6}{zw*zynq?{8#^(Usc}QJnN@>YX|dWU zwfYqy^2j?x8+bW3>Wy=cX>7(PUW(Znc)z|m=`JTw^~6MTB~+G2adsaS1X#qOXm%6$w#-oiQg1n2}Fx%+?3gy;unMKIjTN( zRWgrajl=RbbH42_U8JY+NVXh|vx5?Y!vpj5#sGs=h@hpYxNN>6D8;^}+OCdn7aP*w zKg}BqqpNxz3gIa8w*yqfQ%ng1c8ilp9)S^W#QZ$!Yv1(ZCC0f$X^z!IHSj&odjKT} zvW4baGCA}i;p>wOOh|w2P)ohVi7}HcJIuyQLC3n@ZH2I$=~4ZsQk6R!nJu0>~fc zyQLAJLM@iSI;a_7yb(fj$g%D+gDv$qSNB_0*1VDyuQr_U~?3yr%wKcLvx5)R5>zYDD%WByz);H z6nXBPi*gNklWQ}8JxFK-K1j~u#M{!D$Uh-=Byw~xuhuUo7d6-;H~RbNm)Bo_7yJE% zPg*?`4j7|O8=aMLU~i|eLtn23=55|I$|6VS0KTe5{uC4oUU7<@qC5utM6B^6{MKWR zMY{e}(roDj#1CfeaklBa#PG7qET^=}9vN1@j56S+cm%%k)0wlr8_Ogz6%M<1T*l5i(YQ~fzH~QB7SMjr| z6Ll1Q1x8lVq6?#epbWtAK&WXWjR%uHL1Odx)5Fd;2NaUXyjU6xs||bHeSz)n6{I{> zx)7RNddsQhoMx25CXjW?pzhJ?2&-O^&f>sh=+k5lsNf-9x2xS(_Ka09S(glgpkU&J z{$);3B02M3?G$H!J>RmP`za3Ak(yzfGJ^V_zYK38^cFWwcg#P_*Eu%*XzY*KCm&hvFa{synve)0%@!82`V%Mx`@bW z#ZF#ULOS9v+$bNC&#s9GsOIJyjCv%C`~pjh$X0S=h)Txte0~QLE`&+wsHOvPI`NRr z&eE0n=7edWCiHxh0PMArtT7O)WqYy_p6SE=Gfd$DnnTe!nw~O zZPG6+gGG9--(4H4ZJiodw1te(O)5J-X$lLRm^n?i-Y2x|(-XBz`fhB6U^a6F;=bH@wcZpihrpcpL^1ja5EIwsFU}5@A`)R{AZf+4{oaD*Y6Oq0_r$npHm~vI z!Gt8|kxkeM@#E){Ck9*4adBA&Vj?1Y$vLATCnU?!qGw>e*84NoE~k(Du<8k;eqWVr z+4i(h4V62i!FPl=rg`c?e~ZLe?zQF;60hOrqA<3~lkpzmrR&?&-S_iSCF~{u>l-mP zCJksYDN1_a|Gn5@a*v{|iaEC_PXk6C{b()9yG>#<5vohMT4lYrMoZzfMq?tJgQ8jL z36b20bKT_}`UMy9!Aj4W*^;|`W=k?~b~0%@`G#aa|7ijqm^y#Jmnat0m6z^$@5`*R zZ&>%km4&Cp^~`{dOBJjce#H$uBF?pGxU_Cu8&3aykHY&A3!oq!${3|pn~_>iBCbf zZM@|AQqkLni+6Pwg9rd}&a-cRYG(xaLRIRkqa%?mmC_g?p`8n^IkIllBkP;L{rp??&0m)e?PaZ>re|Uj??s<=A|sv-pp1D;EJg33h*(@MXABg zykmSqG^~_}_;QYL|9EYHyWZF78|&8kvE5y81YxBv$|t0?>_qw6F$3g26Pz->FmYc} zu~GZNJZOh%7?U-8l>hjS<@2MTNA$Ev;;orHIc;u?;9NsjVPwVoq>?Ss?IFt1+K=jL z6=^@3_w%ad#;8+(V<{bdD`D*~M4=W-F|+J_61y=pV%+Ud@{H3`ex-2yYfQ>M>Ix*y z4bXaOnygzDK_2Mlf>~p@hE{+nNfD;?okcPg;+s!4G2#)#ZkO6n30Hj8;vx&Mq`E(? zs={NmG+s6Hc`IL4E&hQZRa!)@PL==Dd{Bbn-T;U1ZaR4r%_5?mX{^OE5FLiCY1z2c zQdO~Dxm+mwP0P{Me{xh^cmv3pj{ejUJbcYGY{+hFsAfhvBKWz~TF{&Qs4_FqK8Q_a zJB@7KdB%&tK`44Toje@m{vfE?Pdb@Ot%U-}v&imIoqAwmgXEFQhIcoy#r!K#j0?)d%2J?a^J4=9 zJ>*lPcVWT`d-jpKFw0%fnBD_Aw5Z#>8)^RcZiyVNtKZ)^1m{ds*{nqN7HNMh?%{{N zATv_*uTpEX%ufa%8yPR~^W~pl#^2S~ZEjFuIncT_@~f7LAZ#F{N0E@XI~wZLsEK$@ zqCBJ_yh(*Z$m)b)N|_5S8933NQVr`>m+1QrGt8db`VefT zIH#FC-xzF&<5B|-)n)2+w3rQGlOwj}=~M@mMn;CJ<3pjqBb-DIUfFyNXQI8@hCCbM zW!*;eqphRJ?GxxTYw!7b&kNlc47JD!6i-6Nfbu8RG~R8=U$;-v$ZM}PiWbH?4(7a8 z*O@7D;uDH8G*#n`gWVD;t@~3cTQ02H>Wo^a$w;8lY*Wz!{ieh zFf}JF3OpPY$*my%uC(GXEbC-Sz{gQrD&Q=ixR5GSTVdBqapdN5Yk)9aT7uXZ;e(K9 zCqhwDS2~ca5WKpmhq0?ZUcNG9AqNl3NsV|VBzH82Xej(3_>8ZZReAFQrnW}uE!!!0 z1W9VWM3+Gl;AV$=y_#cuhmz!=MDk(|Ym%+kWuQT^gSfRpZKB#(2J zgn1Sqy;8Zp*YizK&~j67%y9z`S>SET?m)V(cF~|uW-_!xPj_&H2Yl0O^?eATN7=nc zHv^S3TGrq`STjEoO!pr56>|G{nUD{X5hCJTJ33s6wHRxz8){!OML8;|vFz0FG1=5a z_*_WCL$JZl^ZMtedA?c1`(9cyEGxd!^~U(lmE8B88u4qN zAl&Kew5M4SyvAxkepA0m9$PkF|Ddo*TvgWj(|%!&rvzi3!)^-6*NX%AGG$#)^U4() z*X|OI3-ZDgdL{(C)ovrUU`iW7**ukY?#k@#%~bjV*MEzH83 zN77h(q_qP?HIv;5%o_cK$L7C^%=vxLjF$++(gYQRqfY(9MK2lbG}DaAbPg2<%qxyu z55B6mrXbG(T^AXNz5xbW#?N_lylEk<9M!iyTK1y_M*DI-wpZi`nk@HZrb}Sz?J?n2 zPXx%t1GTsGyW3LxexJcSV?MgplC5nPc=(d&CGK^gqOgq+Z?LxI(o<%~N_Td>rP{gT z^)mmZ5BaytBnen<&H~~a3|?Z7=zG>rQZKE7m-$;szGg%z1S8pcDZNE?-V<60$SHXd zeF9fSWvRc{Ktlswb5|EUyhldtrHHY{0f$<5wKq?bYwsn94rM*E@Xis#>)fX3U>E_o z?R&qu$x_cR1~z%D$ogqXu_^n&kI8q6HyM^)&=rW`>NgkF&v<2t!qYg@Ez8kRw<~N- zVL3(>aN>O(H+0z&@dw`ESdsREb3OhMp zGy#*eNponXd{7VPE=4wbRP4-@TAt&%MzHR8Fch^NsDxeJ%SJV+RW4r^hO>TvLmXP< z&tG5drH=sN-vDv!-4ER^q4ro8_$Kl6vD1BFsbN-~I!;rLd+rvM;Jv$purhPC?<|-Q zm!S9j7!5`#S+I;4QmqENEM3-?1kVY|R8=!5jW9tj$@U7Ui;-18k`&1;GVVD0nLcH! zA8DVYlM`Bay>326Q%_M^dngDZtuc6P{o)qX3e26Jn8(yCfTjl<_w6Y7_v65)xrTL| zKKhTt#<(r|KiVCAb3XUh?c2|;lLu2D|MBAPpRq`uneou2leI4e&;MDFDta~> zdEWKg5%tdsM|q69PY-MG6`xtH(s<`36=(HwZ_q?@GEUIr!p@Htu8t3#1ygB@S4M2C zP9t^2_Nt0V-3r!$&JXQ{a<70!@#r$6>#KGXP zyXZl#h!@u)9#Q)>U{n1ZHH%5| zeUOQ3E1%Y(=+3firsN@IK`vhusj{44MYn8}BZtRaS)NFA?q2$;vLn4I9aM~HRLZVS zC44Dcl>9`$#%dUFpC#hLg34Doe%+DsVP;sdB9#Ke#=-#Ism9JLX=+o2SM~`j)Hz&# zUHL+bojPaKnsf<16b@R!V?YbSNacSNi12|Blc*g91|GtNM=PL#;rG7uRQ1$VFXY(( zrI|fqQj$f>8`n||0#qd#pE*;cEE9ODs-ZSC#HLxS@Hl`pWa6TzU1d&la;&i?%>xZ8 z@)UAt0u;)M88gcz(+!ySh^l@6VnSGMc`BlJ5 zS~tHq200tj?0MW}WOU670R*s&Wzm?|I{PyaWI1w29X|%j9iT6vI?R*PTOeQf? zo;P_O?zS+l<(^#vx0WmA{Bqmf;)A^%c4WukHQ zMIEqs=R+b~VFPvhoi&tTl;~5w(D#Y`;w&iJVDxu*#kqVdmJ2*pf!MpgjLCDhx2yV5zb8RTR|G z3 z^J~SzQIG+vkQ!g?<-kW}WQSc{C~54+YhCK0@7j3v%6q6Dl8Izl?izRl(Ni-y^lQZ1 zNt5``^-gKQ&SuF_l( zrjwr#&`_e?9EA{#pps3qHAIfSR5^Kxwc0?6j zW9uKxh8@d1*e$Q1UX|6f4*e~UnM_gxO++M!k5A-u!q?;2RwdXU@Bg@>Ly+`aG>XBu zSGh2zY=HbHh@GxyZq#qII2Y&sX<{0Mzl!}W?n?BP&{r49Mai2Dz;_V=m&(guHK|V* ztD6vWFXz8GmLa5DVZ)AX>%J@Q*1Ys;(GZ(2&V}NgdR~W+g>-4ZG=`_M^2WfweV1Y2 z)w8z+_5^tz*U?6=PQLH4*>PHZEAR}bf%|$VHU{}}B|`8w{;G>l1x>n_$RC(i>pD#6 z?V69!OREjLRPRo~%f;u%+}$-|zWWf>=)Dx*O?la1Z?;MXt3*-$ePXE_r^1`12BC;~fmr2HY=ry5Uu50}tL)kb_2up^!&WR#Z9^Hd}0+*gIN; zY3^8=U9HDMI=YaH`jH$?98nS8bG-Q|gp;$MywL)_bF z!3TBW@u>*nw#qU>7q9tjmORwbt1J=!Na>c3#v`;;Vf!LYXIamiA_p4#mHh%^*^Jy6 zps(L3?x2j0Y`<5Td1d2VGRC`8rz|U-&|Y=;L4^uB{;|DK!PBa*Y5~8*=-pG1aJ-^$ zv|G##@Os1SYm}9*Thw3+ZfM z{K5)+oX)4+OKxD)L?E52-d&10(VUWr74!}h;xD}uo;Q&L`4UrFSHujPceio)!Epw2 z`$b{WOx*_6O3#wf9e4ME-~yXW=ZITWPVg>Z74?ydRMZFU-hg!Ei7J-_Cp1?ehms=Z z*E!J|=YzZeuMN*MVZyVak1oyQ-3htp#8{~HCja`%eJzdeuqxj{6RU)_IdRE4?F$f! z`q6Bx$G201t1x=V#wU`C`7y^n1qK6xbu=Y_2n zG4i^C>}o7w@V3JUcZSV!<6csE{V_OLo22(r*X15k2V|EE4&q!xrKlIOpA6L$hdV_K zp;O3NmC7Hh+{?62X{e|n(di_upa+2N_&TMZ8b_a7G5z)}8mj;7uZpyu6?fPsrRQzD zC>~dr>G!o}`Y`N!!ic-uOX)bkFe)Q#G{xN;BGp0w%t&>2fV3BA=OL5=8>tWkMZXr7 zyIe1~tZx>P+^iiBX`D{EGAXs}>ef4=5Z2>f8nr_vKHAp}FjZLW#@0t}4!l!@r5dP~ zzgd}AJ5{KX!g89qrAM%$DAf4_^f1tKiq5VwN!;W0(yf!zD(8cQhBRBt8+tiuZfd@K#Z-gFZFT5 zEAr$~QGA6>$S=u3Mz+kZo(pPPY8oZ5qrGQhgyo*voGv2U_e+3N6=of1KQ#{b7!Ya{ z8aK>mrcX+>Ed3T0Bt=|KF}bmpxwMjaZN0&bI9osSC0e?;lx(cp@y)ntrBq$2#|fce z1y}#<@QM8%Z=GG0N*m+4E18P5I^O_lUj4BJL7Pt4u}8Ux9md7VivvY5(KgkGM=Ong z-MPFYm>9Hyq|Wu7Rp^yyP3o)4-46}>*BKPhr&%s6OW!>Et^8(e~rt%< z%_!pAJ`I!6x4i&!Y*1f+U-o%r^AUU7`KMy;d$)R2pzg#?WS9l~h7Y6xx{#au-P#A% zr|#~^P}1t^hK?@QCP;_&A8Jezt>u_+nO$(htIEl$0Jk17xVDyG^Dee`#MLJt9kwS^ z>-HU&I`rz}DO_d^q!xp&8vRqBlBL6% zt5wadwZw9}QK_fldSeurGojj!VzP)WnCGmmlg0+orJMdUc{a|24sC4rV3$Uh;GDgz z?-E+y6CZG9q636E?>*m94aqz$^aJ=}N+f;4-0ZpPo)tLiJmgn#?VL!8~qPJ;y} z4R-FLc$5RYe}3I=yeKMx1~v5dXMfoD|FzLZXQeQmYOoq+&RX!~U$7su8o<=>LlES1 zwNX9^-rgsHau5LBEc0?k_9zf~RVtm>%$W&%yr8$!Vd6O9&#zMO}Aa2)uh2Yy=d z=_cRL4*zry>ggST?%Sm>WJ1Bl2kjWHPR#|Ps|NC1+@C+73qmP!zHgs{Jy6DF{LQU#oJoQK&E&vp`R3xN9RVih(6&m z5-Nf^RdGB=ygS`5gt-JyRN~X`!AnB4Ty_eMp)z86aekyK=oi?ahE;ju@}uf`F1)mYB9NWt-F;zrSjH&>;ghxK zeaE?{WJ(R-_yO&g$4;6J2vYd6hCcnhwewub^1aPF ztmY_3na2`P(ja=DM%2AUH&u;VPm~G#{ei1@F5?yEoiHe;3DWpfM^EL9DHY|y;vb+f|CA|Pt;@++Tq@N06?+7}KM8b7} zHO|Z77J<>M#GWPDTr{L$F)$;^yB>21GCHEZ{K|09KXJEKyzc>ZWIS!Rkm_cEfJUb8 zC;52c+}fYzQ1o_T)VXfJtk&x8Ynk2G<|TZ$m zC*EOW=MME;(ZLOd=~C|}KC8bdpQ0Zz6x5AuRAi{?adJcK`28+<{wANu9W9NUJdtiS zDZN=vk}ku8o8+3}TFbmO!e`z9iC=N^#z`N-znT>a7T-BV6*BDb;X0w1$PE0kNOSF> zHq^e<18Df2Y0<4aLaR4%HeD?O2zeh<|7^gQ-hnpLI2C9_HD(Mg|5odF8#59kgh{zW zfg8kqbdyz$GvgCJtM$O)R`FsE+8|R%Y2;=T<;B43i%rv>I>Vt!~sTWBjpD^)j(q)LThx&%(1U;+UFu@;sKSKF}L%0 zuvp9IMLay83JI`~w#RFxCQRZ^S-6j1FSA)C*>xKE&hJgsNr87m!BxKLBgR@_Lzu;` z(w6Wc)?U$t;InW_5hHgXh;y`Wp7Tv+yOsY`&^u-GrPhm%(b>!&dOOsN4(OMg$UUXC zB8{xaf>C|Y9MK&e-i{XNK#P|w%IaNRFZ(+o9VPk){BqGCE+wItK$ScuH!n8-M+Egg zDZ8Z#DuI4dJsP}Q@9$(DETkha6heu8ppmI5Wk(wH-)-3N0DRSIn*O!iUMGFn8S#Po zLxP&QuOFVbPW)6>tl^haxm+I=zW;+UzcTWy?t&j zCl6^1C+F?zdpKk- zFk)tFI;B1*#otz5*T{!11)_iOvflZ;?`*JJ6YpR4&`DIUXb;P?@apLIa!)FcoA=Ck z8YZ`AfpLI~D%ggArN+{NC@>BSM?@LKfv&K|;v^y6Fm}w_Z8vIOZ0vZ2>8XVTI)l`3 z*R@!u8>L(1*iGuqyZ6vbdJYh(6q|#hY0fJ5RP2ufc9!@4!qvi|<9BlOhC0I~Te8c| zhBGXws-zw8em7!=eg02;s;pfR->p+)t$YP=Lg?cYvR}WeVfapZz9@6fIB_zGe0zUP zfkD}au1b|>nqtOhL>}mO6d9|3bW^+SH(rCkP+kM4UXYZZwfNEoB$(pY!%AxF>Vxk| zk4Y=?13OFaB>P@X(Rdd@m^LmukAj95;+qp_1DTk>e&W>A+*g6SdZI3K-|8#I>^U@FF$Nk2kL&X20sA#Ty@bXDpNmm$>6);kD$AOvP{0a z>uHf{( zT9{`e@L3%6qg-xJ3!A}?dcc0j5L0}#X38$Y024dR`9F4Q!P_7&brepr7r?BN=40>X zN$hPIHkpI+-~K9L!?U#w7 zKXIHacVZ1Iqd*1n<)8(y?Yl-x<~Cwob^lwzB=7+xtH-RSKWUQ))B-yX@{_rQf2Ef@ zXLVP34ex3hvw;e#O3yji0*u#KAUrp@{r4VK#7?*B3dW!a?e%ah$$jM0yfqK54w4gh z;}m_b5VTt;2*MWO3vI}S&Zv}1J1jj?azP(5>KRsMJ?e@c`dsm%}|fXG|y4` zr%BW75e-90EB}T9(B|8t@$*jUm0^_fg&Z($JlG;oN@gQ17Y~!(oM3&m-upU9^(R*! zYc6e;%;cntT8*fXDLyo+G3H@eH{ay7JSa-G+rLyBfSwmatc$4{ZnqtqOr1q+A7ek5 zEx$AF|1(36mhFU95IEU!6?HSf3UpID>Cg{7gSDaa&3&I$34QLC!QmebJM)j>Vv}gO z<4dtohWiFybjv8#3?RLs$No39EQ@j&-DqkjW?;s7ww4M4~r&D@W2_(qUC#cuwz1Kz+;uI7hi6dT9 z)%d_1`J=uQy>BM-0V!WAB^Xdmtv#GLub;hXeh*)dNDsUu^)%7FC*NM*!o#e-Ah4|e zdjKB8%qy59{JMlN<)2ZO#rL~2*v9!4cy4^HRf76~u!8{q2*c2G-N@jLB*rdKl+ywiya zHW=N0?=)%=_^o*bRoI*2G^z<4QLTzR$h13Wj4yYDJb0+dc*FV-;hRoQ-E~$JlTtrE z8gnP6EdCcjS>@V{{HRt73x!tnu{vO#fdHrJ1>Vl2$C%T+6w}sOJW679(GJx8{h}&zChEBs|=n%6XY{ zYNJ0a5uVfo#-B~SCTWW{9Cz*RnUL521lw|MF7aZu|YD9Tyqeoc+>qM(!VP;11?6&7+A9Lq)g5a^;0J;wXr4=P;bSReVMI}UI zz12dz^+%ZBb9+hG3qtK*@-J2}DH(xsF9eLRgV6#Vfvh`t$Ra>f>zpBqEUtzt~k*p#nx!zk<@;n7FndVj1 zoE)Ht4)Qu`!s>@{tL8q|J;4BGl(#RFH8O}?qjJCCJa5%AoGJ6L;0ZglK;)%MM1YOU z*sy?b|1q;%o zVPU*7h&yJc&C|_Dmuj4`Rf4ba4Ia<$4>h^{2l-0eQpZv_-O{eZ=iKx@=e$^C%Un;5 zkCWQdu*SZqWl!zp`T;szdlw`>$h3l@r6mu2N6;^a}#r1lY$qpU)`$Gox z@Z+Vd>chJYl`ZXGtnrmhg)A6gHHF@}#i~YZ^_^PYK0rQyJAfT?0J~gToE!~g$*s0g zd;gWrP&$d#h^YG>)S~fomLJKx)$0^(=$Dg4aIj7GrD9{8Ks)K6dcX4(>wx%$@ex&+ zm?GB?zg+y=N>N5;ibLneqvCY`+MvgPkvL*x$y1Fx&Tj z)h$DNw9u%#aAOfKA^h2XXX8jRu;nh+xC~DWf}9Gn*yoK-IyBc-F9-Hd=VWe??5^+~ z#x{%|a;SlZ=O5GOZ!BA(-8luW*?r%mW6|sXLl5rCukI&wC}#%^NHa}a^^hggbw zOe;p;+0;JO!R@CCP^U4ZcjdgB7P2iG?~C#YyNS`!kho&}-IHRB|0eLp80hn5={`Z- z=;U3_I>xQQ{$vm83ZKPPTJLF^&Q~3Q_O3HLfrlQ)nTM=iF{d}$b(c^J);q7g% zx0@~aa5J8%Yx-~BI4!(HmVl~$`uHQq6}tGkQYUmfQHp%0bU3jkWySGs-|&nFSM@S*&S(fNb7=t_ud5)0b*<1&w$!pxew#l2sWkg!(()B(EBl$#OPvII z*wW>JTCjwXe$j^Q+taM#c@I6T;B@hXY)Pn7l0XW>E2!n?<_%FAwVpTa{dGbxTP;B*4T5R>~?UryqXC=;nG}o5n565?)D!KUo)ar`~6t=4N zvn9pK&1gr_t5E&`X1V3#v8Ah6dcE(8*A_lgmg2pu%6;wvWJ*V{?|oUPX)zr-GmO}| z+acJpko9rFu~`q{V>YH~<T;@K^p)Dh_k39BO&Vg2nCYjgQE4dJ@TC4b=dPFLU;r$@knR82&+)tI2(& zb!3QA)v-hHW?cfcQh=(^xYKjss%|tF`Pwk{Bu685gO>N7Lk*+8R{CU0N%pNmP^C6? zE}@lQ5gs{(y(O^S2b0!f_zRvS?1vdSNyJggf)qa|@srmNbi)<92Rj>*$mk9C1qiBlhqo zdxTy#TAOH!(IAB7vio&xl32 z$oxd=+t`$EcY#BVov95qx%t|}W%I6I3!mscdnWrLb|vjxbwto_Ga*Sn7tBuw@*$CW zs>DgVbB()pxXDlX$8>E1OvG{+r|My8XlwP(-FXhw*0+TD;*xuB)G$*iVq-kG)Z0x~ z(Ntstn`5X`R_a)S5Tw3qdkINPs4+Vg@3(Nly<;Xo%-L2Y{JCx>^=w!wksXcP)Y|}> z$nZV`6p9J(`JXuLM?pkOS4BPuf2X+vKYY!QZt@7%q1+##YYdt*bavf@3t+Q@e-VB- zYw4JHGATj@xqbevgAgnB5e-OS5f})l|cKo*%QcEGEhh+LZ3h$U^ zO4vO2Ts@a_A&EL(M!k1A{!*#`+ZX%eTZTC|H?psFQ#KxMLFXjVlF=`2=f~bIujQ zUdaBK?v;$G0P211Fpctknl0|o@kIT>^vQGp^<+TvN&bYo;~7UaDgbfziKyYd`Z56l zV3TpG@i_@#oQ6Zy>gfQ}C_)J=uG2ZL<@R+7uP-)8C;mZMZ}`!!Qfq-Hp-5dtS$;nr z1P`d|o7orcTdV(%u=kE?GVA*OsUm{{qC=6YGz&^oItdO6Dote&5C}*Jh;%|gN~oi# zH0fX0P`9m$yF7Z@O8d?-Tw^=Y0T5LVd6-^?p7snydzxz!qJQPE<`x$>Jt&1*Gk!ga>QiuG|Tz9 z2#nO`A9zqlNl0hT0f&L2uw}+1CG-;6jDXufV6RO{aIEf`nJ;j6sF=z7S{|QkM^57enl{|E0#|H<`(}v8AP2ft_tX=b6%_>OFg=PlHtJp=CNSYa$pU%NMNun-&|l zh*r#j1hSRQ$kzU=?F)9d@h;_&=LB@r%gNBynr-87bMF|VI2{XL8MTgci~I1C6~6E7 zgko2Q$F=eM{2fYY}X86&|QH(VTl<@$PwQgi~Dn$}c>s__td(n>flfV0by#?|{sd%*5! zc!30m-zQcczZ~DSs`aqggkv3qM#{@; zoCZ!Chx6apNNVo95eZ~}fc`A_$CR~1RHITet24>5 z#LTaF4L4=ua1O(73&%x7vvf>Ii8pe=7Z&fbqEhG$G^~Pu7uzRsiMB+2|tMC${#Xy$=kaD5Evsx0d z?LV!$`+Q0a+o+6wBIZF|znnaBelHni_tn|E_5bJSRxNUZw6L z|1B>4Dpc3rjqUDtM>)lLb!x2>H!U`A3wG+0-U`i}Ym})~&iNYIH275_+QBDRJf5Ye>Fc6SNsIe=i<9P*jrMtIT0<{dOWPjWyLf?Hv3uk^uV$$*?I) zn5`%O<8Qi@mLx|l*CQprt8V&ImiC>{^?=tAV=101T#oZ~gwJU!>mv8=R6LY{Ow}L& z$~Z_xhTcf^evlpv30v2m)0x+rQ!jff0&?gyQM?)($^V!+G2B>{7V7 zNi>bLe;=a<9j}+@ov7(aQF~-e{j&B6(p%jC(2H7Rhm$FFj`ud5qso^@paaqvxxXk? z|FH6ZTl1tTM+B3OWy&C zJuJ5f`H{;1-h=$U+RnWb6I?41V*L+mTFq=#L!Fd%{Wr9SMVYfL&NdL+`7@LaxS zmT6q^Wz{EQ!_n;Nkv-RJLPtoSJT9)x1xcEAs@>$VM3$AC8-xy|u0xur zKcEcw@3gkWJiYWcB%v;xL*S0V%WBXj#NNpG^O_RQaaGsk-6{$B02rGBE%CtW$QSf1 ztkhP6Mi-(B`BawbV9Ob+gx{awn$1*#5pHD-qw3VHTcl46pD$a+`pfr4 zk|G#HWhq*hF^B~WcdXxI$sX(WiZ-BWQ+y|OGN=Fcn`|7QKmPOJE<`~UD*8531^5SS z*L(ivsz7BnOBXlfKTKI~uBCMD>|7Vzto~6b!RDZm)pV(Vk+xgr&$qpLcCo&v**ZNm z1V{^lsPubGW)?bS)$Ajxs!+-bg`^aVM3PQt67Bi?xw@NZ#OLrYr;)x}ES0(U7MXIy zN*>s~?6hAcVD~mtsz65wab17<@16VKNd$FQSx+($&b!|5G!Ogt^VQ|`lwceElW$S( zBh*bp)5k*Q68k6kot6#8uGLlA8L?6np&c}`r{W-UY*>{RX5E^P0vy?ElS2w;DTdQW#)Fdv|q-!zBAdEnH-O> z0V9YXE31TkiBR-E*`wh*=*U-Jud;u=YxxQRj#`cGxycwSgi6V9Rg0 zBE0B725VA0xSmzFXzd9^JWvFOieZC7rMRTXS)KMaiMfkQ2UJ4K_sYW)Bb7_k;Qx9S z{||fz?#7G@XDjbj`8}wlFaJTGs%YS%o5OV`c=Rh8`?}2Ds$=WWt5;J3=@U5N{ac+GOT>$JhiID(opO51?K+`A9bX;BT^0m658;vqe8%C0g`~G^+ix zO>4>j1)wl5(z;^uU!Hf;hQnBZjc?C1M!$H`g44CQ%nlZ2}QI`nyNL{J%ZszqeRjeCr~;es$vCP(2|niKx6|k=))wXFO(HgFk?HGFP50 z_%C5ME}(gx6po+0Sjhfe!V!&O?J|+rBj`?NW_hY)2e#ho)Uuur&VJAUKPS%<|F$ISCIyLV}DKY zwukSNU$dova#4Qo5br*a5<1s>KB2%e!)VlJGYnWTV2Gg?in|8zv632MD_<#~&Yxv& z{O%N|$Ge(XC9mbV#<-9dDro{L?inJ=t0-~|GTpNacflbT`v0$G7@uSdT@-D-bM9g3 zUnNrgaP{MRMNa$vzv!rEoMShwaSAn!evde&?BI51I{F63tzFH2aM&&c-=okC#9w4y zGpOk%Tdprb$q|pYnPKy5!Lu6EnWRE{J_NZllSSY3G|0ErFrXfXZ=Z-66vNt#qCbDYTnq3 z)n9#VH-(QAFn03vi4DCA{a;~3LR!`w0@~JX19!^IqW>toup!!{8$jEhU&Ns5lNek| zr$3+h_IV5&BBD_rkr_($!|q-G3Ar%_BYpjPU6@JC^1Q?GnD@mkSJ?S6A0R2M^XHxo zdQRP8BM(#OYOZ&1Nj<}%cCFGq8{HfcasVKI^>y%t z?XP<6rbFj0-fL81t0~eO@-JAQ0_tln8}`hM=K(KR``@`scV)QFvhlz2cm&<$J0s_mPPzUo=|`u+N57@#waT|;WId>Lj+@GDy$nVP zl=jPg6$^hej_164SIkRj>Hv>^h@0P2O9i@MpzWqLW?6lH>~opD=JNe@3+<6VBQfQ{ z`nVKQU1s=A;|Bz7VE^S{bJndbq=_zHq0Hf~9ssq2+Xd>|Es+K{SY$Z(ua&g_X;S~^ zzRbB8<#RB)oc)WIVr9p>v7!t+Cue(&DJQsBreM{174EM^-zA(MXGYa(pf7++uw4 zf_dJ#3mC^%OJZTsju^(2d;)Fblj64MP#G;gIDp>7yJ~6tImT;ZEI73^;D7g4E5~z8 z*`A>iw_zNpo_bXo*d<6qqW|%yAL(1Y59qV0GXz*#DV7n)QKalPd>=FXYlW3h@v=t= z0fH;>U?MA5kv_^(+p=KoOvlQ@kMs{s@7}-y0uHA1?KtqKM48I_fkC^=|KpYX%Uf$* zjoN#jNFN52at*|=Nq=u<#f2>vgJoZj>(d$5k`;|-TsT@4ja_d=37t60`EZ5f#sEY` z?zV!U>)KcY{h{9Bg;?wEtk@*>2?@MQZWwf}%lGVzICg%&xXe;yh;<|&z^7Ug0G`k_ z^t{PIgED?+BoNcrUq6@2=DXWTvDqLVu$mcnFW5~ag3&|a8iNA3#3;95PcpY(Pp;a9 zytU7cbg=Cj>-=rS>-ipU4L92O8zB4Ne-2zw6t2+iGhUfU; zB2ldV>adlYwMS;)WWnX_!lo6KyW;yMz*8c zQ!17j8nA$L4^4P@9cbP*b4oV@GAXrz*p|eWPD}>~$@ql)Dw&E}vuZ#u2iFrUNJeg% z^QQ{HG>P7W^|l+0H3O7lB%UZ=aXHFr&1+=K0X0Pbk0JisOlLlEW%OGSP3oUcvo1>m z*=&TLEa+$LCJexs6#%;3zs%xmwO$vh^JAY;^#vQGL=F_dDm-7NghiX(57w))Jym!A=qIR;rVw$b zy2f|v!S&n)WoIRBhp)IGk<}==kc2qX`h%Lhfe5-=mI?uqssjNef3Jc0IyZCd{98Z$ zW(8^z&a^gNU(F2L?-k(^yjT^xrhx6ML8Q5td_4+$LBn*lDJ*5#ceu@y#Q5Z9(VKAq z!KTEL5nWBo!TKPMmE$*=qYgvRf7p$_ziOsg4&cR>fB zKpL5Pw(+cV&5Lr57CSq3SU{>`rAt=h*m6MyPy&fSaL2SSSv%G@6exT^$&^lQ*X?QiX-wcFkO(G`I3 zpLom;g1`FNN_x^6?%x6X$fnN7^{S@s zT#wR1oMT73esS5I>5IfqD;ep>*!}RDcW*7#aobd^Te~M~O%H1ChHozGt?9np*-3$^OZ1|>L({ybV0a|n z8q>`~_6v0gE`X)cJ3`-YjP@==PmDd44nFnR76itO2QrTU!Lv-8q~Li*K(jk$h|Xdt zb|5~thsaRr2o9w{8d+T;p zQ|G&knG^%uwJtdN$y;R$r%YYt9E?Kj$Xk0vov!&786U9f6XKN^lTs^HBtkaCqgUHu%&3VN^L{>`b?s zqW=o}-shvlslZ68RX1;-yi7J*8L?P`!W*s)gt6u(b=UMD4AR#iR2_g>z1v%#GLysN z0a8Qn=(<2m(Q0r9BsdK`EUk0`5YZ8}urfwb;sUL`^U zh5GdMR+V0AEW>}g^1cymLCm%hfUVXy+dfMUoDN5-HXqv1k|L_NPO?H^p}Ur7V{ zc@|tWQH~qUrEnlH=zf;d4s75#1sj6ycD`fHz~Uqd_SLI0CG0YAJ2o89AtIiYpznhO zHv-izq#hhO^Ej|edI|T^!)~O(CKPjmG&PqGsDY48RVu@mI;=n$NK8J0zw zP22CQT$;FE@AIoQOtP7n{fH1Dp>S~#na(}-DV6ej-p z74V_{ANI#zC5fENEU;)$i7k6EmmEa(q=I}!%~iV9jdBQ8&SoJy!;Ir`_;1>6Sa&2| zFEnHWu)B3ftV)V}65EvxCDzPJOVxKY*AsN8&s>)wdPsW1bi9G+3y<~p98-)8{Pp_(t4xyCTE@DBOs7w-(K}{_KN)yb zp~7pjRtnimVNvQNuA5gLgrC*MisE_{Hej>_oKHipUiI`2#-ZHAKsBcTYqp7l9bq+p zs^+a)(rQnZ%+(Kt1*Vg7*2PzTUJ4tX($#kZ!dOBR8#D}eMYr}UbJ1eLr$_w?sVXeA z6U64 zoxt0bcw-uJBcCf_4iR~u<91>~n<>3Gg%s=^eZRP@SN&lwVOJ}gtbBRXk@AyE}3fJ(6DB zL!g_mMU7QlOn@&@t`UyX2YsoLhwDd86V74a#=l+LzYdROF$Q7UxUE&dzsp5V`mEJD z)h>NI%_h$2wNkB@R9(ywp5rOY=jc)D-^A;3Mf~^`KHvGVsukn+o&0x`*AD3$j%RMn zXwUbBDB%n6L!tUHli_bU@vDtjOEO1d$=ZOEiShIRE&EPA&5IjZ7D(2lFgnIniHRYD z(g~IGW^mAa{jv$%*ymw4dbN)914g|R_hD&+cQSONIWFOd+R|IfnXNNAyx)BEGX5k_BpcPTTwmGU83ksJrXwY@g)!gWg4yYH3}^SuOxiAc z#M6mEO-9gbBO2d0pnmiA)50uu>Mf{tUL6=jDgw6tf|o^5tRrAstYLwEr-ni%iBh$1 zXrV3CP-Q7rN2ZTM#?dPU2F!s4Jy#U_=3a=VggG>R8tdgS=}jzcU{(=lG0P20v|_H_ zhx)Rer+3bwUI;tfJBFRIz6%OYr2IaxmCYi9NNdOA@foU+ZuP2Z4V0lnxl~tZ{O7y7 z#hc9~lf}sTWlW_KIxnxd%rR)Pc{Wt3W2FcBl(fSsyJ2~mP}u{0a_lfu+aad_(pi8D z_`5iQmUmjsOCkiGK(9eV4p{SmSoz`onYd=L6~K0Kl0D zHAm9;$=T}gziI`IE%Ziid-Li}z;0zMC)`=P*eB62@e5)`F88ORZew_Mghz-Y^(g$@ zk-?M%XN1>2;EO;0h6Q+ZwAl$}!A|pp4<@N$SgI1ot;YF~i6EMY0Y}t+fM5Jkj$l^y zU%7u)SKZ-fzKG{P#ITHU79`BsRDE}?qcZyOK8^MKUs*r_EvAM&bw=n6-AQs2d{>{N; zhxT8b&^Oe-`Uf2u?T)M=FC5drO-`Wi))CWJL^)(I?kbYivcdQ(8DDC+BVQQJEH(8`y>zLiIbFWg5W(W z#c{{IFCte14ksmIa}-$Y*TSn>_q1LvwS*^peTjkQ_!ZblKQ#@K^twIu$;TghzQ_kw z8qN~P6)NYrPUzHQRg2sPe%l{-Tr$xA=eR~-0z8jQ${N$s+3*l!DxAmsTJ?$fnF>wI zHJvM@FXv9B4!6u7;fC9fSK*JBMN{y{6c0`ju0Cc3lh>dXV(f zP9+V7+!u5%D>I;Oj3FU^z%Zp(@sDGY_-Q+>su_ru5!;QL1?-gXI! z!$t^B(mA^jz-rcRe0H?SKKkgWQ0G4IQ@k+yEUvG!YKHm?lmg{|m4yvIb)ww>2&CpC zyBSAh&bUB84_HZ>pT+wniTES1Pe_Q4SEI)wVP_QtGqm!xzvb7Pr*x@ZiHOeaoj&_A zXO2JS)-hei9gyy1NSa;69kEK$;F|&+VEUyrw?wSDSjK!g|NEHU0Y}Q%&iL+?v%}B4 zCs_$Z&1P2R{hKu2>||#FWO}~A40bL!*2HBDo%@s-@OqWBu*sKKT;iwA-CXzj1igtW zsNt*RxD%}B8fw>!oF*LfAJ5YIg{{N(nPmVfukU>2E3{vicsj3;r;%T{wb(uATQSoW z6FDz^erRGIlrKI%L+iHL)n>DSSCP+^znLm<-R?3wG{j@lNLe2K2>VA`zpIVQvGNv@ z&v#H?_x|z&uLAq3B$sU^@)a_2<|gW1<%>u!hDbc0V;*S;pqg1dn~2Wc)!<@zHTf#UUAdo)R|KZZrYiJU{u}7(UIlB{T{;boJ{(Fd@}yL%I+v$8J+!g-daL7FH**6 z^{_rn(tW^r(%gH^0c9T89k(CQ$``(h6gfB0HeI>I0iG*Z=?F{?s`R5LwN_+Ke1;S2 zk7B0V*89wTE8Ief)<^ISpE#FQ@8tJP(Y}LQuKS4AT8$D5b#qD5RnHb~KB5jlNjaon z6>>r()I88jo1&M_D*%^bKKCohl;8RVYk#SJW#)#|E2YM?SU=k!6m(_4 z@s=xuk?G$xJ_BzDN%wH&^TE3bYXdSbQE|srA?N0QXz3x#!kd{^7lenEZQT+W5BshP)QH# z^xGy6kC)8ScStuhu~LC=T-((2lj)^|h~ek#J5#lsH;xUDt}K&8A^P9cO)oUr?k5H{ zfmQD-G`{*H@ZI`S%PaCx;A(H(mzXX)VGQ$OJ2+%$VBna8_ei!wX?<6r*-EYCh=FqOhl7`yI>%C zFU6@WwP(0^W`mWS_qpQYOjO7A27B)VI6;(8){>qKAb|P?pY!uC(EIU_YFI~L z&P<0^-s$IGqbB#+!EBC+eePj;kdJ1}Wfs%*H>s-9y8+W8+;bYoeoT)yXe;jKm>y{` zGhd%_OYzvQku$y+yEHkZOP~$J9YHQZTruZOc5G0YnV>OFurxm;Y6cwdXNfc{sj;PG z%Lvl1qkXWZx-$l&0=G#*Tn|yK_C|#8!Gu=gpDW7`@qza678V`Wb}Z2GPOjmP2q*`$ zr<~Cfb0ZSsU-@b^w{nUl*0jjIb?;@4PXryW98L|22pV)N_JNgPmKq~J%582a%5q1; zRRdm@p9i}M3ov4VVezr1JBO^16~x~j?kb_-VFloh{e_@1W-W`oiEI}c1nmTGgc2Ix zTts`N>Ebyq2$Qv;+4Vezgk5y)l{w+nYe+kd4EaXPKuy5+-kfMdC_EdNHDzMP;k;iL z>dj+FA@x20Jp-?d8KJ!gTG$L+15MvK!rd@v)4{FRcTjgGP6;_z+PH_>fsu>~utzPTRxTsNDptYvwm zVAE#nTDq?jDUIG6`#D97xly+6%gL6xp>eJ_H>FhflGHhmT%tC5b=pu;wsxTX%bP_5 zt%I&|+51#z1meQ#;^xi=_HFgwGByi&c%xOX#+n8%d~&Tl~jm{PJa+peW zJdh@?2zqU2y*eFl`OT^KkMl9cI!<3&Z+yGaaZciZ@EI;?ndpGLwbAWSdj2ujJD}zb~uCNAc1PQ~%ZM!wm zYxl$P!R&qZSS=qsv+#QVh7NVSrgr-97bSit$T{G6AMvvntp85O`VxI-3$&LVs`A|= zEVvD#lbF{#NbXxxbrw0-@X9n*>!UC5&@OYs0l3s{XN3lkCB4*wMH?Ro1hjzM&Kv&O|)ow4ytQk`cS4lG4g) zZ*+|RtS~3|$2-gG?*jTF{T%X4!V8-cg&-A?+`eZl+@fMo-|l{4<4fqd$s4C-=HFkJ z5fQ)rENn8+jN{Sr;}Cd{mOfzNacIfcrFySjvETj0?=4+xx?$+;)03M0z*dXLRN;#C z9Tx$nDoe=)vpzoK6Wf^c{0=SSlse7A~jsW+{wjpvi!k1eA0we zL+wJ<$}Pp@1G)y@`A7P{`6jbLq~YgoI9~M-z|WB$H4H3>iGrQJJGCb779vM#HRrh7 z7CFSVsQJ^U_dbvnZs}NX##bH`L4hY1FW)x55mQ!-KCpc3=6j3KY~~)Rt;74k2%d}T z-ydYb^tm}5Ii+;3RHxD}#ITL|FglpnY54WtDhUYZ^q*tKGOMvv-%Sp7q2qT%&;22D z{P=m_Q#Utx>WDx;W3Gi`-ka0n=bBD&@K1*dF5VU)gc~*46+NJuVoPkR3tZidc9z$d z{b{ZbS%1_LX}or~NfY9GwPGIpn^$g&89%>nP)MdiZ?ED<`?Sj{0p#8c`VY zhYM9m1w!={tc2yP-t~+M9>fk-q^@qPMmaNh!|0E0e-H3dwel0ZV6^APN2Nv7Ox8G% z$u!OA55gH9zf)v13~U|$*p73RJ5cmtHw+KI0Jycl$k(ktt0nM!L=7n)A+b197mdf?%6D;I6X1XTf2PZO%klVXv{l_w((PkiB|L&EcT z_%%)p@?x&o_r*l#CyqzE>bfEsmEL6kI7gVxd97hTK{}RNdniJ3BD%?kks;k#_DjEY z=+Pa#n)EvAuX%)$vRn2#1+=#EEO$4#}Vvs*7;hTJdwVIsIF2amdzGXdAF^4rNyd1vf)N#_upYoeD-TTT5 zbO%SfXCJRR=G$xI{eDoj6(eY0889!_*it}VFtnMEFu>-otm61AoKwPc=WWjWXqb7L zhi%`B-&MV5cp`2_il-;p>0JUpXS`w21DwXXXv(+-`-MbIo+m&}!JzQko|_GCWb&^P zaYPQD#FRFds3%{dcbNu%9ASe%?d8)H5g3jONQ!6*HWWM-5EX7kTT!kb5}-A687MY!we32l z43yHN*)-bX>0|qF#_{}W+MG8-@l9QM-*upR!Pd9wc}Ql>;TK~7Ig0lE{A+=0>b7To ztTZj&!rqToko8$GxbZMtNWyi2AW9;%mnAioP2ss%?Z2U(9N61)ZmXSzw#3JuV}w(M z!5kf+Xg_^%UdGm%v9p~zE(tp+&fIgOx=ykwm|zlAlg7MPq`={6PG#{|plJ1t zej^tte1^JI)ogu7Qd8J@_Mc)ToiMWP_Y}v|m^{ww0{V{?S^uvQv922rTiQ~^mA~xlAU;A!$Tnk1JXbN*L9Amc} zNDcCspV$H6;_Hszg4(LJxv`Z~CQYN)>Rzq&?f%Juq|KUOJm!6t&H{SI8?PJjd$SeG zAsjV=7&jwh9su$kfq5+~ODg}1H(^Hy)M z@$mX z>PRPYJX|aO3|=w!tJi};W%SI^4ANXsq$s{&r&*QxCAA%87D2jewXPtXDBFqPuMpE< z8#^4A=Ye=YFs;iKFA`_Q_*ncfQbyz=Uf&>snK zE3FYys2{ttWmrqLN(*gDVhoW~%|L;X4)#AzW6QI5@Ns7sG(IojMzk>tTesd( zN<{SBWc_>NR;1*8Zdf9GnUquLV=R>VF_50k6y&o_EtBF~^T*=9JFLrR&W0Xg}++N{F?<}Kg6vOSyC)DN2@_m#5R7W?@BJxRKFQjZFMj_{dB=2TBOY6 z>*s^iV)^RVWiiRx{^*lV#J7&8k>e_4`_++&33;0fg{GqccUpGUF^d<)GitPvk}z|} zpE2g&MMA~ZPubcQc18d{Y^Xp*FULM1{aSFp%^>v^zo@BS#)%x!(J=XyX++z!+UGZF zf`gUEmhSOjX?l!&bMx1SuIj0$A-{c#kQWb8%@}w_y2dspQn?4be*B|AV#CGKwHd7f zTzD?=tgMPAuX=WOi%4=F_=X_w`-==mg*x6dl^rv!>_ONusTD z`jq&Hrj|_?PE%i%wDM51&+dE#m7&Zq?K$SL5i@7((-unt93@c0SDn1+JS!{n8l{!o z9V_tS3}M+gATmnz;bMY8ksc}kk{hLCh6fiPXQ)?bu@u^)nCm4AJ%*D@ZT}6aoI6ka zqwSl*VhP`ZmSx2U!j7JKWjF5r{QAT>fzZx%+Alh2Ki*;w^RIFBNmmgqMpHH`x`#{6 z+K~?NUN*fErAr+;u~`TB9$ip;grjLSZ2<^qjdwv>s3^r>0Gm&u-N)$GEl>OClaVy|9mJ!H<0px@Ug>Dg6;Az=15 z=-G$WU>FA6DRg_h_G7+yMIKN+C74e@rIn34HRV+pzlSK`VbEuF74- zw}3Msi?Nm7j%K9y!K$}Pm~(NpIu?BAtwKRGiSq7Ad!TsomEfzi1H0gJJ`57%W$C<> z4k~=eo%qabfWDgPr?$*AB!B(@Cu;WrOT%*! z(QW}?R=-hzKA16vvE$ixPi$McCmxgyA?qD><Wf6>ZgO)yaoLL3&w*Y74akwp)bp zxa_W`0l;i(DgU6I{|Wv((pY3M__8^e7TZ*-pa`wfbe(NQwzbg&yJbP)$MXy+_WRnB zzuHyr{_Oo3WS>+{;RP`Oou)U9H+~z0!aTEMq%AMq07N;p8JsRKcZqpkWd(lB#v4Yf zzvuIXe$gqIo999y|7533F>Lx)vgJcKn_6-f!|_=aEwfutnbIG{b>rf>_UPp8o(JDW zT}a>}XGGPqdB}-CWG>zFd>Bu-Aj!4I?i?nNKLOtyY1zZ1K1KVi_uX5Hw(3`=ZMEEd4%zs zJL+}S-jTD2wN7=wl9t4!^4VZLzH4J_F4U{Eh+7#QJ!7?3s2y4d5Ykx9aO3kJint~y z>pW9TlWi-W*(F7&5al&Dxf#^-+=Cqub67p^86wYc1EhjPzIhtJANJM@ySx||37-`) zzs&5~J%cy1c0GCijWq3NTbR#@tf6l4t;cFSt3oe;$U*wDtblFV{-~ByHO-qCUA3=Y z87Hegh)_M4*jT!Z?8=Fk-Pl1e7sSqkaV{rh$+=O<_)8_e~us($9IqvWfhsByAtbN?i&v!;S}`5uQsbr~%uzc@F~g4wIUyw|%_9 z8(q_taz0^aMY6GTyb2XF0`2QoIb{cL6EuNVOnrEVx?aYpMmHFcuW6DckG+m6ZEJpc z>4g>iN7wI!1Rkw;QQOX{)2lx{#as7me^|SBaMT;MWX`$u&7i#d(CqdH+D(H{cRNOI zJY9_9fJ(4B6MCyQ>D;~)BEqyjw$G$+>+(W8VayM$*YvGi8m>>Hv32xT+UUz+-4P&S zzwIP%i>J6<;7jSr-(7u!4#aFhm%ffi__WI7@=uJh@Vh6cJQGv|GBzTyBQxeXRD#T>Bw1FHqO3pa9G&m zIy_$~1+U{9%&jzUTG3S$b>uMG0oetdQ!86b@!4sEinoRT0x<8o2(B27==KO3elAN( z1uO8osmT+Qm9oZo5VvWLb^`is$XJ+vQXeHf@umosk_&gDGdw5Yo@||?Yb#$J zkjX_cF}H)r92Tq784dlXHxbEW8ajQ){y=x>2j?ch`Gi_HRAgsSrRp8yt%K9qBD<&X zVs>@PgzErx%%%xd-3|2v`w3W>7SW~VS+iv~-*gM<$rYjE5feK%n}+V5))PT>jQ5uB z73r0Z$29JrFWjL?Kz8sG34LIaZ0PQH1`389Lk0x?yb6YtkRMRDz(1yiB`v0NXlfq& zZ}f11i2{$!f_}m7`~kd{hZ(X|E_lDVcL8-h_y=@%HjTm<>-exinJVAjyH)t@+7A1% z1^V4tRJ>%EfzIhh8}fj^R|!dkKYqNa^*mf!Om_PXt)|>=bWcWiTNAWml*NF7#CwMl z_QF>g@!teaZ&EBV&uXqp@+P^&8-w$l&nHX@EOpzEY9@(5wGw!WMuA&XZ)P1g#%*4I z_bgDh{Kq}d+)7sLerqw8mHcga^oiGWDr$18j1j-nS zVAX|fOI%_DYao=<>}8cGr}+<(CVS3VIn_%hZ7~E)!nfCV&agPLL&BiVp6sgea&Lch zrI+gJcZ+A*KdgPGc#&nU6X-J3@E%|Bkn zXVg1=c+F!n>c&Ja+EfKEJ~x6SkjGz^rPPyC%)x=y?yG+{%TZ9Lo)gd;a2hR(N7))f{$RcIES+&vQf# zp(JF3nAeBRTVIdse2e!w8+J5N*s|q`bRcdwJ~s|n=;P8N93w|vUSVN18$F0C_aYYS zi8k-W7aIG53y1wY5u^c&>A8W2L$t-_KzrqJk>IVn)76KKmo#3(6?9cu-b0#&RsB4} ze_EOIiz&-Ezo3ro5^ePRGd>n6_TdKF|MZeh)(Uqp{d&R=~Ks737~KTm>}K5kW7j`u)t+>jp*4L|VJ?NOsL7 zn}5$#s;f#)ajVX`a;91=66?ektJT$Z?AV1YtzKgR(FM!72;Q77t^Hf1%VI<0$BVW< ztnBe6UqAc;Mv5^(98utSoBqsg57MHaSLl_E2MycW8OZVv?&Z!x!Koj(o%gS22r%!s zX*#_e=FL1soNGoyS2M#0y#`V^g*|~Fi92zJ)_|GcgF8YyO!|YoaGoHSBIbf7L))2} zxo=PTjM=PAqfWY$hA%TxB{AK)VaZbu)d+~oZn8wFjIGB?N?NAEyy>H!2L0d@x00Uj z*EkYUtKE2;a{q4vp_u2+hP89e1$xgqYt^S5tGwv@9(^u;^~!`A0GP1lf=2DAhF|7F=9od1u&17Dc%4FgQ!AapJh*G| zY~lwHO#HR{S^H;%^V}7g)`yaY0c~MVBvmf+zHHj9DW95zL*G@JSvRS)vgBSn`i?-K zwH8>p!Jke);EebEqv4bCjse#ljoV{qv2!0OCSY82rp!cT-N?QaYv$gE>XA(Rgd&u4 zT-rksJsLrv^|>!RCD+@W`9#k4fLf2laNSt~*v)1o?^Q%k(ML;V9T}2-(oJ96CNT>l z@eqq-tx{{;V$a=*s3MN7t)1@P?60pbYxX(_0zAz6Q=}# zFot4+_Y5L8cFHp!d$_hx3Ac#nV^-LGS(vDlsm8KyDO25vhhJJJ*ZLB*FI7@K5y7hA zQ-3XZ`K^~TYU{PLad#Rv#s_zB788!hI+W*JccgM56_WhexwK|QOt(LZG)QFwv(b87YaZYW~8aZl}*kV;n zTbrVaXsbAFk&@bkR&A0N6|sU4BS;96NXReFxlix=exCEZUcbM-uY5_a^;y?-y+7|y z+B$%{;H=bKlD~fijg2M#RzP_Q;`VR4rPm~QSdcO{LLJxQwKQ-vI>LG^-TplFbu9OR zeF-ltfqH@^OP#h+UmrBdQ|0d?fy%d6W-vNNGD#vb_oFEZHV5+h74zItT*29ZwwMnr z!ebc0q#-^bPOX(6JdkP4@E`ouxO3kvFVHH}AiQQsRL&S9nJTAo?tw{Q;iMwQ_0wC% zvoz;cl|)}gl1LcsJ1S~LB?r= zN?Rs$NhcD5!G%Joxvkw72%YNS*53gqwG1pm?k-KfKoCNOtUtc|jlE{RDjJ?7*5H%x zce>8UU$b^Nq#Nd)Z^|Z6*PLpWV%q?myY|3=2b+RY0L{_v+I&DtvtbY-_%-%gSs&;edgBXz)FsCp4l>Wp*`22OV_E zjm1``25u#y77~NE`kUPQs~)pbBj)&?K~4o@|j-kmSZ zy_?g5WcD6E?q$FT_lx~6UI^hXHOz$HIf>LottB^ZVmYNf)r~hHSo+!zM89?T7hvCg zY&XRVMf3`$Zgc3FFyxKqZIT5mudO_e&z4`fUj%s=xPYkcyYp;9IVAkSbzHfR<4Jjt z6}#VSSLf=C7UOY6pHD8fEV_(3)jofkX{XyZMLJ!K*nW=)-{9qd_41}lR9M`A46%)M z4ltz*RaW=;^wWM#bFZATZfz2Mqs<=EkZSpa4QZl!c@)f#_*CKV%}<+5QeLx%)sSdt zM|n;oOGrunmD|o2_;j*kH@;yq*E-QpT4m#_oh&llzgMDG^g<_t3nKp%^DQiR!Xv#3 zIjW!M0H*MRKPF;r8>c#71pBZb_lHd3Mknp#Q3R0m>kU`4nL-L?cdy)aDJk$Juyfdb z63z1PMv^sVB&3c!c#&LY%6gNiW02=-B+X0z8Zna^s@<_Bl1Q)8qC*2ilN!SXGb7su z_Xw_3pNWWWI5=-xbu4|>s`q={$r$Z#z3~*upU%zi%}wFsKl9w^iRM*-CX%yAf?!4{F% zTGpf|#4ziFVytUzHV>{kdHoBd-_MNr+ zLUd$J*cf+&(o>qIxGkEH{Hxt?-#TRK%aJhe$ z6j3Z#gA@MBEIYN}?i)S*SOShFh2HIDgb_FCu>;+swufN;##(}JMkp7EwVY$G(y7!qYbri<5O7HUbXcZNlXJ+4(dW&$1%juY~I`5<0)G{R%nvz zKOJ3qKp4}&kXA~z0VYYv9hQM`Fr=XdzJvrPWEh>5Y55JeII_9F(VEsTq=oUCHOukY zec3BZ)M{FT5ay9{cC;6?ZoF+LyKGl@k{?Dr+__gF`C9n#Gx&+;AU9vpU*pk(J5ay) zAJsvg+mmYDY2FM#hoPMLJzl!*J@Jj$^4n+w%80+#@XifdV76F97n&sR*p<)rnk4W- z9F2ZulLyq;U+KYaydxvQQ^{pFhl6IVFt`W|q=2-b($eAaicUps8o(Fz>c_5YVKF_r zPCDkfSfq!t*IIZ~MV+j3vS0&x-(}*g9GI+TK)d1IEkh2w`4~<8tsBUi(dUy`3@mVZ z)SL8GjXJoX?j(_!-4U-(5fo~=CefLWjR*C;1sl5e-()_OSVs#j!NQ)0It?#sXo$NU zG;;a)+hnT9VP2JleR|*W6_2^|Y9472yd#%3uE4|;CkXX17^6=3BJi6*h%*DX{QTs)I z%ONL*tR%V4-f)o8U6$B6?YfiNcBw^{nXlqAa%tqgx7g<50HzxrmsTmq_#CHt3M%l7 zbEzTlyp;ACkF9{i_=UEi&997Jhd_@--L*`WB?bnYyfPB%(Sf^|Z}F5?p7shu=oIvOG#)Zq05X+B z?{qTN+9(OGOJ34oi~egkE)UuQ$Z&TL>n^~dRrKLIP=&eH(c;oN&w)~tz3XD?FULpE zS6zCz&%3zxR<|RLzR!YzFiu`>`mGO*+Wvu>xW0J6Y$TPXfIh&}t)nY)yYHtXtF-(5VpYJGx8JenYq==}- zxb4W|*JM*+n>&UrRKvy~8Toz|JelLP%Q^)P%Y=Xoa|^pRI6q(`x3f!T?-qgBR8X{f z_5wgSDTJzv6UrXd1JRVGB6MJ}(wf8^cVl0z7v-IoB;^SDdL{r+l((d5tv!n-5{X$}53q3K!mL4v=79zV5!|Il0{WMV9mIJ=q0>8-aJGF036~C_9s58bvS|Z4^J*gI~hxz5M zMYx}@c1kgJd_&+<+b)vyIxi|vT6 zomK~0B5=&FcUsA zs9mOj%SioS4iOv|bU9eleVyxCL@~3^v-#*_30;p|S|zViA0)C>O37a@zg0|sEG39Va>oU$Ok zvsrQsMe^8hjQH9;d#UY;lw_-FLk9HYJ9kV_K?4+6;#`x+lCnLj%v~6G5v#y4#`0?#M6P6m>wS7W#`gaBh6o zRL^vDjE$Rxwl}sNPjyb)Q9Z;yT8IIKeeNH%V)2O2_O7=3WhOZ5;SWd+2IlrPf9pV0 zrda34md#y2tZll?Zi_#es8VZ3Y~JcX`mg4OO|Z~%RcjBvuvJG4w^!J2W|C8oWIHTn zt)D~$?&b%n?~=X7@tqCyw5avp=x2x3{31yXAy{G~UCm8Q+Ne!{o#LRdr52?E8tzSE z>1uYWOqk62O+1`Xs{@Ps1b~I6cF%S zmd_oGs96=CO;LvCZAzi&$boy*ZW-~7!UE{{fpqZjTh5KVuVL5m?}D(*YEoY`l9~zu zpc^b#K1!UgdE zJzvv*|LqgXJay~2*JTItxvi()znL@0M86hQZYEF+J3o_j~$?nzX5gp;zY+r zM+WQ*1PC}rSS=pb<_8uF?;CBabrk}yCnRhvWf z&rx`j8ptI_ue=Zg!Uie!JZ$4R&i?K`mlagVmADEzRp>>LstvS_CY?}-xAEKneg5uJ z1nd|YDGaMR5wY&}fzpMleEQ&Xi|+4hVgdw(Sx7>YkI!=7HKjZ2ge%{`uncv9FL{qs zSV@j^-#ZF*OR2;Dk-;gXF4wX|Z}e4f8U2h4&dGkkF=Z1%3cu!hR;X@OJ$v?N7d0{_ppqmZP~*a!LIDW^pVGRd z1f}7a<|GaV*}@zBZuB)I1R(E`KYjr3)|DcSndMx&TnzrMWf0wasZdr!fl%g|M0FS- zpEF(8iISz)Oo|~o=tvWKAjSWeTxNk^RuZYfs+$hL%x@2e)^;zNRQkKg6hLSUWJh~> zy8eXvC(58^j>G(uAbsx_*ra@DtCkIc=cm>{RQmS~Fr`f@Fnh6Bk*OwZ7@+ zpVF4Y+fo^H@66NN8HP@!)LIWx%Z5cuU};CFE~*P#?QgxhHjjBn@|@2Pg5Q#;_lT2d z8P=df@C9p8iI)->I)QSjt83P)p%8*!7X9OzYrE3oJz}tC=@I1Zt?Tp)p$8@s9Od&4 zo=tw55j%TEQAF#d@cY=gE~!Rin2mijr0W&jpLUR}qXPfz03C zM8yb(umQm;9kfrpyD6U){j1^5Q{Yt4)%l!(3ho?=(wUB7+=jA6P3uV<)bI8T!Z+T| z#r}6G-QTvbt%DaLT^bdmxi3n7$VZRG%m;SO8sL zdm_J{z#ZWN{c5dT#oXZ92k2s*PvjCZ@{OIjArxO30r=$*{+q)Ojc0|t5)3T?G&-6X zQgu4SNE%C@B~|jTUx~v+HgBw@>CITT>cR4OlLZJoYD5#wmSd6fl^vkSU?Z$rtHa%+S!`dCwvbL_=;OH5Xp*FD z?-OgIqpIx@YESjq6F1MUHNFf^#ICtBC@>o2aT3Yl$<_Rm>P?1e$m-?D@25N0?#R)h zn3vW$bs|Ztwsg)2@0Fyj(EnNuzYcJ=vUBoA@Re+K38h)OE}x)00T z>X0^9%4f>K{GBl(M!Rcg_s<-ce~9-?9h^Fje;6z3d4*!4VC$kG{T1#XOJ|{mdEVm1my;6<+UqYDNRGO%R+ZCBau}lGyo`>!5nZWP;LP(8M;~4bTmsu za!P0UEYeeaKHj~~?rhgN4><(@LSKeq^gbR!$LAi|!Q7T?2WA*YJn*`N#Tf;(w@5T= zPA=Am#lZFOIg_AMC4u9IngNqI9##r<%yf$i94nchW&_6-8>C~+ULE?K?|7`)RKR}6 z`iRm=ju7aCtj~B2D_ZpIX(8>h}J!LL^Pc*>BOb!E4-cB{Q9TEO0b=WC&b$eUg z@7U=6N-4gCq>GZL{Fbjp5*fpl3gBu%SL13`Y-vV#_xE^Uy&>Oj@$`>F1vJp71%ZiL z!J~O$_s6imqF(@Z7rAz}Hl?Lzg>J$ktgwp$O}>vQao8sMFXVpi&_@Zp(|Dt)Cvd#L zK2N{0yoyQlMz=&|sFBh*V>KNQ79uD5IP()Vgq@Y?d4vKjat+d9y-gl zO5slu;j+3;k&->$6tORp?@3(l#x+;m_VTyts!kW^AE@ei9A7Li!#&ex*V~(*CH)G( zJx~tXh-8q`qd$@heA(Cs$cRuI&ujcoIv7t~ibc*-U z@*k?!vb<86QX%??EL#4gVH@bJRS?8T=DqUVR>7dn`kj^w-phtnC(2+OZF(0q>U6$D zM~zB|Qj+0=Y=>EWO*c$Mq-$oyq`;gi#eWI$zhwEZ$7#O9Mei`-vNyjkkbX+}^uZAyuF|m2)_Gh2L+_X&5w6%N89)!; zvvih@M%i`an(N!l^*@AuB;W8nn>pWjolP^JOn+~hQPoY5^8*-C?qw=V%cJ2}LtYu( zM(YR-;c1Ue`(JCg$^ZO z?+7Ep)x2LrH#{v2X<4PZpI3!&KAR~7SBH1h*=NnvbzWn@)}XxWT~eKqwO>Q_-=qDn z>F_dtg?)-ud%X(&mmVXNIM*=2<;fG?tG@hZE_!)-xKsV{cLAn{uit@8$c&E0!`=-B zjY5;Fu5PY2(pbrg846nw@FsGW5suGV!I3c(TRYzCz&lfqs4mI>GU& zuqy06^0EsE%$_6Nh{Rd}e)*w#1=V3;DTenNDe;}RM{mBa@(O|*M&dmd>c<-5w;wXk z8U%{$v^)k5RemgqP9M|@mV3q?op0Q@XgvR(q_(qAMK+6xVw}s~!6cdx_qSyG%WI; z2Fg?9p%SQk2y0J6>8k{6^eFW__u8kH;$+wLl+B6aWm_A(pSeO^YItpPJUUE}udBPx z`##^QG&l8Go6OYXN6b-{6Tx&W=hX<%r@T4T|7ld9^gnh4n`#1lUcU_!z1q-p0ydX7%fI;wOCZ+R?aJ$h;=Dim64!JxPT7@ z;pcc%^KPd{-~$3%)?i>qmwRor6KnOey=Oc>1WiWlW``UTKKrjV4c5~ zQJV)F-%4-=7#}$*dPIrw9HWm}3d18`BAgLf^@x~HTQx(?r>*A*FG$QX=8Gt!-ms#O zzzM7$x@gkxM;1h?lNf2mH@a^nXY4fPF4!!u$fnYg84-#q&6(PSHLtw<$4;^!w-ytZi1v! zH5xBP%rDWFH_Pri&B^07h+WGAtGl{9Vu`JzN~D*v_7*Kd65B5D?uQfAZ5HaA?KzE~ zzPtZJKYr))m542_E(&trb5lk#JbT%kA=0hkl&YNOnsp^2B7S9gkxtulZl@hbCm05~zC)}7cvQeU2NRu-WnA*73v*7`TPoL3QmzYuZW|kw#WZAAOEr3YQ<&Y}vD~A?v(QZk*GQ8@*gca0w@Z#2LVyeR*ITdDP zzt}?JYmNmYUQ(dWJ4IkhnmGkS$D4qIo2as+ebd9k+Rp%_Ez;ze5BKNxE-bA?K@7a2nPY02w?_=2Td zJ2k?VFaSuKo=<_wi-K*rrE%_!gkMl&%}RWu^({)CfnX0amlgiAuFEon<@$N}*ylkg zw$FYb((m7v^M4KD&r!O7c+?MhM`0T$tC@BlcE}5j>U#MQLdhzpY8XvBmICE#qivpB zS?(oB89nTN-9(_??oHm@h*YGc?f=9fFW#QmLdLW@5p$oVhRcDX95c5Y{$X7IqwT4V zgQ58%cvz6zZJU@8;{0pNg69(nSIdi{jGKa}^lwUjaBT3_CWM3>QelgquNiK9P9Bd0 z-!B^cdp0k-kn;7_6LLr#ce$8DcUTrtTj4V{LH5?W`*1KZQ4kW2W|!zDuQ> z0l)h!z5IjZv2rWK+rB5{_ak~2IU6J87LuuSp}*wwtH#ypI>uonC^lhKlG?Z$6^MHD~7)IC`Zxu_t2bfP##?WYIU=Ap&4 z4&q}!O?wRhY1XF0mZPo@D+o&7<;pk8d=9AO)hq?|_~n z!9ACys!o)y7DF5c27*J!Zj}(_?6#qd8-!QSvKz+P9 zt71=0|G_=f$@5KaR)kDgw>x?LdmdySw-Rzt8^w)003#|=77!?_j-t=_LPLd(Akg6J z;QMyQ?`nbghDtl#dtMAq=!3_{AE5D^dx`7VD(mlg{jcRsZgo1OM{AL2@``SN{XJ|-*-1(U zABTRb2q0aOTjn$B(N+ydUVQmUhwI1U6;6$4bO;JcbN{&IB|p4`%YipQJ4{9AGEj&V zudwVXw*G^9ad?CLzuF5ieT6Ox`S8wy<68c^>AybBUo>F_yv?2Y=!$2e{$858(|pbk za}6#uTD`(4eI#8c!soU*r_AA5BJQrZNPw=B-#c^Ewdxj~iE0QFp2{ExL|?;;RhN=+ zO~I(6>IvIF{&qa8^0CFyxvzd0BuqxDH$47Zzkb@n|2g@`V{;FU?C@=L#aNo><>^N_ z>z+gkp1)CGd5w_?-@dQlz!grw2ygD9;-JTgL9$gOpKLp_RLECUUM!N*qsQ5j{A^p@5h}qOy zooC)QQt+:+&1{Q$}A&iYx%0Ae#aEK`}=7s4p`QMj=&?Kr=2v!yyG*=uti=QMhY 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

Ko>j7{V^bbcCW+!rbBTfOu@)*gAJCUvjvMk4 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 >X#&$ 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 DjNLDq literal 0 HcmV?d00001 From 46fcf5958fbddf8c41a63303917e65477df522a4 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:35:45 -0400 Subject: [PATCH 020/131] print encoder output shape --- src/models/vision_transformer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/vision_transformer.py b/src/models/vision_transformer.py index a8748dfd..9518b3fa 100644 --- a/src/models/vision_transformer.py +++ b/src/models/vision_transformer.py @@ -191,7 +191,7 @@ def forward(self, x, masks=None): if self.norm is not None: x = self.norm(x) - + print("shape of encoder output:", x.shape) return x def interpolate_pos_encoding(self, x, pos_embed): From dbce99e18171ed633155879188e0d333b3d78391 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:48:19 -0400 Subject: [PATCH 021/131] update filepath to reference border png --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index c98a2544..4f962604 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='reference_with_border.png', output_filename='guess.png', scale=150): +def plot_guess_img(input_tensor, reference_img='video_classification_frozen/reference_with_border.png', output_filename='guess.png', scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From c09881978445fbed68d77f7fe139c74500c39315 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:08:07 -0400 Subject: [PATCH 022/131] update filepath to reference border png --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 4f962604..17590c11 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='video_classification_frozen/reference_with_border.png', output_filename='guess.png', scale=150): +def plot_guess_img(input_tensor, reference_img='evals.video_classification_frozen.reference_with_border.png', output_filename='guess.png', scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From fee87692731af1f0663f218cc05d770cf327b0f0 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:17:33 -0400 Subject: [PATCH 023/131] update filepath to reference border png --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 17590c11..8ed30ec6 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='evals.video_classification_frozen.reference_with_border.png', output_filename='guess.png', scale=150): +def plot_guess_img(input_tensor, reference_img='video_classification_frozen.reference_with_border.png', output_filename='guess.png', scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From c7268fa6984875b3bff3fa9b73266d9f9f3c88f1 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:24:16 -0400 Subject: [PATCH 024/131] absolute filepath reference border png --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 8ed30ec6..49bad4c1 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='video_classification_frozen.reference_with_border.png', output_filename='guess.png', scale=150): +def plot_guess_img(input_tensor, reference_img='/scratch/ki2130/my-jepa/jepa/evals/video_classification_frozen/reference_with_border.png', output_filename='guess.png', scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From a3d0db5ebac5c67fee1cf6fc919af5ef2ced6bcd Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:33:11 -0400 Subject: [PATCH 025/131] output_filename as parameter --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 49bad4c1..a41ef163 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='/scratch/ki2130/my-jepa/jepa/evals/video_classification_frozen/reference_with_border.png', output_filename='guess.png', scale=150): +def plot_guess_img(input_tensor, reference_img='/scratch/ki2130/my-jepa/jepa/evals/video_classification_frozen/reference_with_border.png', output_filename, scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From 878373fccc57e2b71a52cad10745ff2514e054a4 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:34:01 -0400 Subject: [PATCH 026/131] update filepaths for plot imgs --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index fee05f22..913b25bb 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -355,8 +355,8 @@ def run_one_epoch( print("labels final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - plot_guess_img(outputs[0]) - plot_guess_img(labels[0]) + plot_guess_img(outputs[0], output_filename = 'outputs.png') + plot_guess_img(labels[0], output_filename = 'labels.png') # Compute loss if attend_across_segments: From 1a3e2661eeb15299a16fb8fb7a1d3984236062f4 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:41:25 -0400 Subject: [PATCH 027/131] update path from kp_utils --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 913b25bb..9fe5ccd3 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -52,7 +52,7 @@ FrameAggregation ) -from kp_utils import plot_guess_img +from evals.kp_utils import plot_guess_img logging.basicConfig() logger = logging.getLogger() From 97743ad8cbc6b78a1b8884c1e38194710af05720 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:47:45 -0400 Subject: [PATCH 028/131] update filepath to kp_utils again --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 9fe5ccd3..bacd78f3 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -52,7 +52,7 @@ FrameAggregation ) -from evals.kp_utils import plot_guess_img +from evals.video_classification_frozen.kp_utils import plot_guess_img logging.basicConfig() logger = logging.getLogger() From 202a0728a1c43f25a949ce77eb3673708b1d3328 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:49:19 -0400 Subject: [PATCH 029/131] change to relative filepath --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index a41ef163..4d832d4f 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='/scratch/ki2130/my-jepa/jepa/evals/video_classification_frozen/reference_with_border.png', output_filename, scale=150): +def plot_guess_img(input_tensor, reference_img='evals/video_classification_frozen/reference_with_border.png', output_filename, scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From da7ff2675730be17de4bb1c357889b99f031e7a2 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:52:35 -0400 Subject: [PATCH 030/131] rearrange nondefault and default arguments --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 4d832d4f..3a249786 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, reference_img='evals/video_classification_frozen/reference_with_border.png', output_filename, scale=150): +def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=150): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From 3db2baf1345efcfd2c2292feea8ed517e5e3e6cb Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:29:20 -0400 Subject: [PATCH 031/131] comment out outputs png --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index bacd78f3..106849ff 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -355,7 +355,7 @@ def run_one_epoch( print("labels final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - plot_guess_img(outputs[0], output_filename = 'outputs.png') + #plot_guess_img(outputs[0], output_filename = 'outputs.png') plot_guess_img(labels[0], output_filename = 'labels.png') # Compute loss From 04ce6dedc565b83eaa4a7ef40b8766d05d88f8db Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:56:35 -0400 Subject: [PATCH 032/131] add third video to p_mini_train.csv --- p_mini_train.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/p_mini_train.csv b/p_mini_train.csv index 8080d8b4..4bbef355 100644 --- a/p_mini_train.csv +++ b/p_mini_train.csv @@ -1,2 +1,3 @@ /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-04_961-541.npy /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-05_960-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-06_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-06_960-541.mp4 From a240bfb12d6dfaf54bb64cda939e7eb8a4d7910f Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:11:20 -0400 Subject: [PATCH 033/131] print pos_embed shape x --- src/models/vision_transformer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/vision_transformer.py b/src/models/vision_transformer.py index 9518b3fa..7a14435f 100644 --- a/src/models/vision_transformer.py +++ b/src/models/vision_transformer.py @@ -173,7 +173,7 @@ def forward(self, x, masks=None): if pos_embed is not None: x += pos_embed B, N, D = x.shape - + print("pos_embed x shape:", x.shape) # Mask away unwanted tokens (if masks provided) if masks is not None: x = apply_masks(x, masks) From a09aeb727e7ebc59717a6892474e584d835c312b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:13:06 -0400 Subject: [PATCH 034/131] mp4 to npy --- p_mini_train.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p_mini_train.csv b/p_mini_train.csv index 4bbef355..981627c3 100644 --- a/p_mini_train.csv +++ b/p_mini_train.csv @@ -1,3 +1,3 @@ /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-04_961-541.npy /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-05_960-541.npy -/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-06_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-06_960-541.mp4 +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-06_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-06_960-541.npy From 23adcbce96389fba79f9379046ae9a4f068d98bd Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:24:26 -0400 Subject: [PATCH 035/131] add print statements --- evals/video_classification_frozen/pegs_eval.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 106849ff..5b2c0fdc 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -351,8 +351,13 @@ def run_one_epoch( else: outputs = [[classifier(ost) for ost in os] for os in outputs] print("outputs NOT attend:", outputs[0].shape) - print("outputs final shape", outputs[0].shape) - print("labels final shape:", labels[0].shape) + print("outputs type", type(outputs)) + try: + print("outputs shape", outputs.shape) + except: + print("outputs has no shape") + print("outputs[0] final shape", outputs[0].shape) + print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) #plot_guess_img(outputs[0], output_filename = 'outputs.png') From b27023d029bd21c3883805ed45c34495c98e0f9d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:57:19 -0400 Subject: [PATCH 036/131] flattened_x --- src/models/pegs_attentive_probe.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 8ace76ab..74978448 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -13,14 +13,16 @@ class PegAttentiveClassifier(nn.Module): """ Attentive Classifier """ def __init__( self, - embed_dim=768, + embed_dim=768, #note that the embed dim gets set from the encoder parameters (vit) num_classes=165 ): super().__init__() - self.linear = nn.Linear(embed_dim, num_classes, bias=False) + self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) def forward(self, x): print("input to classifier x shape:", x.shape) - x = self.linear(x) + flattened_x = x.flatten(1,-1) + print("flattened x:", flattened_x.shape) + x = self.linear(flattened_x) return x From 25c5e076f85c241b75b803a8e426240eecdae11a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:01:46 -0400 Subject: [PATCH 037/131] what is outputs --- evals/video_classification_frozen/pegs_eval.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 5b2c0fdc..141925d0 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -351,11 +351,7 @@ def run_one_epoch( else: outputs = [[classifier(ost) for ost in os] for os in outputs] print("outputs NOT attend:", outputs[0].shape) - print("outputs type", type(outputs)) - try: - print("outputs shape", outputs.shape) - except: - print("outputs has no shape") + print("outputs is:", outputs) print("outputs[0] final shape", outputs[0].shape) print("labels[0] final shape:", labels[0].shape) From ff4417618cfccc07f106f23861c2ac2fe8959bbf Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:26:55 -0400 Subject: [PATCH 038/131] convert type label tensor --- src/datasets/video_dataset.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/datasets/video_dataset.py b/src/datasets/video_dataset.py index 405c96c7..ffafb4ff 100644 --- a/src/datasets/video_dataset.py +++ b/src/datasets/video_dataset.py @@ -170,6 +170,9 @@ def load_label_from_file(self, label_path): # Remove the extra dimension using torch.squeeze() label_tensor = label_tensor.squeeze(dim=-1) + # Convert type + label_tensor = label_tensor.to(dtype=torch.float32) + return label_tensor def __getitem__(self, index): From cd8bb360cea0972e26056c1f3c1183d67d6668c9 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:49:10 -0400 Subject: [PATCH 039/131] update loss --- evals/video_classification_frozen/pegs_eval.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 141925d0..952066e1 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -356,12 +356,16 @@ def run_one_epoch( print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - #plot_guess_img(outputs[0], output_filename = 'outputs.png') - plot_guess_img(labels[0], output_filename = 'labels.png') + plot_guess_img(outputs[0][0,:,:], output_filename = 'outputs-0.png') + plot_guess_img(labels[0], output_filename = 'labels-0.png') # Compute loss if attend_across_segments: - loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) + loss = 0 + for i in range(len(labels)): + loss+=criterion(outputs[0][i,:,:], labels[i]) + # consider averaging + # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) else: loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) with torch.no_grad(): From 91f62949fc5aab9560e9316fe09881fdbceacf06 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:00:06 -0400 Subject: [PATCH 040/131] update slicing of outputs --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 952066e1..d272d709 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -356,14 +356,14 @@ def run_one_epoch( print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - plot_guess_img(outputs[0][0,:,:], output_filename = 'outputs-0.png') + plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') # Compute loss if attend_across_segments: loss = 0 for i in range(len(labels)): - loss+=criterion(outputs[0][i,:,:], labels[i]) + loss+=criterion(outputs[0][i,:], labels[i]) # consider averaging # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) else: From 75cce8221477e0a116d8c3b0eea4e7c0d2a3ecb0 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:26:44 -0400 Subject: [PATCH 041/131] return loss not top1_meter.avg --- .../video_classification_frozen/pegs_eval.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index d272d709..59fb8570 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -370,12 +370,15 @@ def run_one_epoch( loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) with torch.no_grad(): if attend_across_segments: - outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) + loss = 0 + for i in range(len(labels)): + loss+=criterion(outputs[0][i,:], labels[i]) + # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) else: outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - top1_acc = float(AllReduce.apply(top1_acc)) - top1_meter.update(top1_acc) + # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size + # top1_acc = float(AllReduce.apply(top1_acc)) + # top1_meter.update(top1_acc) if training: if use_bfloat16: @@ -390,12 +393,14 @@ def run_one_epoch( optimizer.step() optimizer.zero_grad() - if itr % 20 == 0: - logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - % (itr, top1_meter.avg, loss, - torch.cuda.max_memory_allocated() / 1024.**2)) + # if itr % 20 == 0: + # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + # % (itr, top1_meter.avg, loss, + # torch.cuda.max_memory_allocated() / 1024.**2)) - return top1_meter.avg + # return top1_meter.avg + # kat + return loss def load_checkpoint( From 412bb58810b8a502d7d637bf6f848b6a62bd8e84 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:00:56 -0400 Subject: [PATCH 042/131] fix sum_softmax and top1_acc --- .../video_classification_frozen/pegs_eval.py | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 59fb8570..523dd302 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -370,15 +370,34 @@ def run_one_epoch( loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) with torch.no_grad(): if attend_across_segments: - loss = 0 + sum_softmax = 0 for i in range(len(labels)): - loss+=criterion(outputs[0][i,:], labels[i]) + sum_softmax += F.softmax(outputs[0][i,:]) # no averaging (dividing by len(outputs)) + outputs = sum_softmax # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) else: outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + # Initialize variables for correct predictions + correct_count = 0 + # Iterate over each row (i) in outputs[0] + for i in range(outputs[0].size(0)): + # Get the ith row of outputs[0] and compute the maximum index + row_outputs = outputs[0][i, :] + max_index = torch.argmax(row_outputs) + # Compare the maximum index with the corresponding label + if max_index == labels[i]: + correct_count += 1 + # Calculate top-1 accuracy + top1_acc = (100. * correct_count) / batch_size + # kat + # acc_list = [] + # for i in range(len(labels)): + # value_acc = outputs[0][i,:].indices.eq(labels) + # acc_list.append(value_acc) + # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - # top1_acc = float(AllReduce.apply(top1_acc)) - # top1_meter.update(top1_acc) + top1_acc = float(AllReduce.apply(top1_acc)) + top1_meter.update(top1_acc) if training: if use_bfloat16: @@ -393,14 +412,13 @@ def run_one_epoch( optimizer.step() optimizer.zero_grad() - # if itr % 20 == 0: - # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - # % (itr, top1_meter.avg, loss, - # torch.cuda.max_memory_allocated() / 1024.**2)) + if itr % 20 == 0: + logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + % (itr, top1_meter.avg, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + + return top1_meter.avg - # return top1_meter.avg - # kat - return loss def load_checkpoint( From b4f6b6cf3e46aed5ea89722f4a31944ea179c36a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:11:48 -0400 Subject: [PATCH 043/131] change loop to top1_acc --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 523dd302..b7d7c0b6 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -380,7 +380,7 @@ def run_one_epoch( # Initialize variables for correct predictions correct_count = 0 # Iterate over each row (i) in outputs[0] - for i in range(outputs[0].size(0)): + for i in range(len(labels)): # Get the ith row of outputs[0] and compute the maximum index row_outputs = outputs[0][i, :] max_index = torch.argmax(row_outputs) From d802e3a0e2fd02947ac9a316f98a229f5ac6cf97 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:40:34 -0400 Subject: [PATCH 044/131] comment out acc --- .../video_classification_frozen/pegs_eval.py | 76 ++++++++++++------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index b7d7c0b6..405c0066 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -368,27 +368,40 @@ def run_one_epoch( # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) else: loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - with torch.no_grad(): - if attend_across_segments: - sum_softmax = 0 - for i in range(len(labels)): - sum_softmax += F.softmax(outputs[0][i,:]) # no averaging (dividing by len(outputs)) - outputs = sum_softmax + # with torch.no_grad(): + # kat + # if attend_across_segments: + # sum_softmax = 0 + # for i in range(len(labels)): + # sum_softmax += F.softmax(outputs[0][i,:]) # no averaging (dividing by len(outputs)) + # outputs = sum_softmax + # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) - else: - outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - # Initialize variables for correct predictions - correct_count = 0 - # Iterate over each row (i) in outputs[0] - for i in range(len(labels)): - # Get the ith row of outputs[0] and compute the maximum index - row_outputs = outputs[0][i, :] - max_index = torch.argmax(row_outputs) - # Compare the maximum index with the corresponding label - if max_index == labels[i]: - correct_count += 1 - # Calculate top-1 accuracy - top1_acc = (100. * correct_count) / batch_size + # kat + # try: + # print("outputs attend no grad:", len(outputs)) + # except: + # "not a list" + # try: + # print("outputs attend no grad:", outputs.shape) + # except: + # "not a tensor" + # else: + # outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + #kat + # # Initialize variables for correct predictions + # correct_count = 0 + # # Iterate over each row (i) in outputs[0] + # for i in range(len(labels)): + # # Get the ith row of outputs[0] and compute the maximum index + # row_outputs = outputs[0][i, :] + # max_index = torch.argmax(row_outputs) + # # Compare the maximum index with the corresponding label + # if max_index == labels[i]: + # correct_count += 1 + # # Calculate top-1 accuracy + # top1_acc = (100. * correct_count) / batch_size + # kat # acc_list = [] # for i in range(len(labels)): @@ -396,8 +409,8 @@ def run_one_epoch( # acc_list.append(value_acc) # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - top1_acc = float(AllReduce.apply(top1_acc)) - top1_meter.update(top1_acc) + # top1_acc = float(AllReduce.apply(top1_acc)) + # top1_meter.update(top1_acc) if training: if use_bfloat16: @@ -411,13 +424,18 @@ def run_one_epoch( torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) optimizer.step() optimizer.zero_grad() - - if itr % 20 == 0: - logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - % (itr, top1_meter.avg, loss, - torch.cuda.max_memory_allocated() / 1024.**2)) - - return top1_meter.avg + + if itr % 20 == 0: + logger.info('[%5d] (loss: %.3f) [mem: %.2e]' + % (itr, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + # if itr % 20 == 0: + # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + # % (itr, top1_meter.avg, loss, + # torch.cuda.max_memory_allocated() / 1024.**2)) + + return loss + # return top1_meter.avg From dedd29c95968806b7dcdb8e45f54bb4f5ac3a749 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:49:36 -0400 Subject: [PATCH 045/131] comment out print outputs --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 405c0066..16d68d2d 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -351,7 +351,7 @@ def run_one_epoch( else: outputs = [[classifier(ost) for ost in os] for os in outputs] print("outputs NOT attend:", outputs[0].shape) - print("outputs is:", outputs) + # print("outputs is:", outputs) print("outputs[0] final shape", outputs[0].shape) print("labels[0] final shape:", labels[0].shape) From c1487ecccab1899ee1857e28d71313547343ba1b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:38:52 -0400 Subject: [PATCH 046/131] avg loss and remove % from train and test print --- evals/video_classification_frozen/pegs_eval.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 16d68d2d..8e60e103 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -289,7 +289,8 @@ def save_checkpoint(epoch): data_loader=val_loader, use_bfloat16=use_bfloat16) - logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) + logger.info('[%5d] train: %.3f test: %.3f' % (epoch + 1, train_acc, val_acc)) + # logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) if rank == 0: csv_logger.log(epoch + 1, train_acc, val_acc) save_checkpoint(epoch + 1) @@ -364,7 +365,7 @@ def run_one_epoch( loss = 0 for i in range(len(labels)): loss+=criterion(outputs[0][i,:], labels[i]) - # consider averaging + loss = loss/len(labels) # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) else: loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) From 1ac3f3907e1bc64770bed058385e1e29f49e4c14 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:36:35 -0400 Subject: [PATCH 047/131] 5 videos --- p_mini_train.csv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/p_mini_train.csv b/p_mini_train.csv index 981627c3..18d4699a 100644 --- a/p_mini_train.csv +++ b/p_mini_train.csv @@ -1,3 +1,5 @@ /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-04_961-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-04_961-541.npy /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-05_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-05_960-541.npy /scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_09-06_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_09-06_960-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_13-07_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_13-07_960-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_train/1_17-10_960-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_17-10_960-541.npy From a11b1babae7ec9cef9e27d2b4eaaadb284caaa3e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:37:32 -0400 Subject: [PATCH 048/131] 2 one-peg videos --- p_mini_test.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p_mini_test.csv b/p_mini_test.csv index 0563c66b..a6f62d30 100644 --- a/p_mini_test.csv +++ b/p_mini_test.csv @@ -1,3 +1,3 @@ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-04_11-09_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/2_09-04_11-09_959-541.npy -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/2_09-05_13-08_959-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/2_09-05_13-08_959-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_20-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_20-04_957-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_21-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_21-04_957-541.npy From f39385e2d662d1106ae32479f8cab6a56ade908f Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:39:05 -0400 Subject: [PATCH 049/131] comment print statements in run_one_epoch --- evals/video_classification_frozen/pegs_eval.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 8e60e103..d740813a 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -337,7 +337,7 @@ def run_one_epoch( # Forward and prediction with torch.no_grad(): outputs = encoder(clips, clip_indices) - print("outputs with encoder applied to clips and clips indices shape:", outputs[0].shape) + # print("outputs with encoder applied to clips and clips indices shape:", outputs[0].shape) if not training: if attend_across_segments: outputs = [classifier(o) for o in outputs] @@ -348,13 +348,13 @@ def run_one_epoch( if training: if attend_across_segments: outputs = [classifier(o) for o in outputs] - print("outputs attend:", outputs[0].shape) + # print("outputs attend:", outputs[0].shape) else: outputs = [[classifier(ost) for ost in os] for os in outputs] - print("outputs NOT attend:", outputs[0].shape) + # print("outputs NOT attend:", outputs[0].shape) # print("outputs is:", outputs) - print("outputs[0] final shape", outputs[0].shape) - print("labels[0] final shape:", labels[0].shape) + # print("outputs[0] final shape", outputs[0].shape) + # print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') From 96dd6c6d39971105bdb0386774d48c9f2f48d8dc Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:39:23 -0400 Subject: [PATCH 050/131] 20 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 3d434e29..78478e18 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -14,7 +14,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 3 + num_epochs: 20 resolution: 224 batch_size: 4 weight_decay: 0.01 From 84931495dcdf33e7697893c9042093b982dcd70e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:02:17 -0400 Subject: [PATCH 051/131] take out extra space before labels filepath --- p_mini_test.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p_mini_test.csv b/p_mini_test.csv index a6f62d30..71e34e23 100644 --- a/p_mini_test.csv +++ b/p_mini_test.csv @@ -1,3 +1,3 @@ -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_20-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_20-04_957-541.npy -/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_21-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_21-04_957-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_20-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_20-04_957-541.npy +/scratch/ki2130/my-jepa/jepa/pendulum/mini_test/1_21-04_957-541.mp4 /scratch/ki2130/my-jepa/jepa/video_answers/video-answers-1d/1_21-04_957-541.npy From e3b3c18ac1ffef293894793e857fbfa00155b7b6 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:21:04 -0400 Subject: [PATCH 052/131] decrease num_workers to 8 from 12 --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index d740813a..0c5c5623 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -513,7 +513,7 @@ def make_dataloader( num_views_per_segment=1, allow_segment_overlap=True, training=False, - num_workers=12, + num_workers=8, subset_file=None ): # Make Video Transforms From 90ed9337f0426e77952e394e6c97506ea382ee42 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:35:51 -0400 Subject: [PATCH 053/131] 128G from 55G slurm mem --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 386eb51e..6e1236fb 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -91,7 +91,7 @@ def launch_evals_with_parsed_args( slurm_max_num_timeout=20) executor.update_parameters( slurm_partition=partition, - slurm_mem='55G', + slurm_mem='128G', timeout_min=timeout, nodes=nodes, tasks_per_node=tasks_per_node, From 1c621a5a7a1e6813009c3ec8664d90ec30b45206 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:48:40 -0400 Subject: [PATCH 054/131] gpus_per_node = 2 rather than tasks_per_node --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 6e1236fb..46e1afdb 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -96,7 +96,7 @@ def launch_evals_with_parsed_args( nodes=nodes, tasks_per_node=tasks_per_node, cpus_per_task=8, - gpus_per_node=tasks_per_node, + gpus_per_node=2, slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='child-video-jepa2') From 712ff564444e2c0af3ee45deccbb1bf4840f8771 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:57:11 -0400 Subject: [PATCH 055/131] sum across dim=1 instead of flatten --- src/models/pegs_attentive_probe.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 74978448..1be6c799 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -13,16 +13,18 @@ class PegAttentiveClassifier(nn.Module): """ Attentive Classifier """ def __init__( self, - embed_dim=768, #note that the embed dim gets set from the encoder parameters (vit) + embed_dim=768, # note that the embed dim gets set from the encoder parameters (vit) num_classes=165 ): super().__init__() self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) def forward(self, x): - print("input to classifier x shape:", x.shape) - flattened_x = x.flatten(1,-1) - print("flattened x:", flattened_x.shape) - x = self.linear(flattened_x) + x = torch.sum(x, dim=1) + x = self.linear(x) return x - + + # print("input to classifier x shape:", x.shape) + # flattened_x = x.flatten(1,-1) + # print("flattened x:", flattened_x.shape) + # x = self.linear(flattened_x) From 87efcebf74b11bac6651899febec9e7e373fec8d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:02:56 -0400 Subject: [PATCH 056/131] add print statements back --- src/models/pegs_attentive_probe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 1be6c799..21890d30 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -20,11 +20,12 @@ def __init__( self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) def forward(self, x): + print("input to classifier shape:", x.shape) x = torch.sum(x, dim=1) + print("summed x:", x.shape) x = self.linear(x) return x - # print("input to classifier x shape:", x.shape) # flattened_x = x.flatten(1,-1) # print("flattened x:", flattened_x.shape) # x = self.linear(flattened_x) From 373be9c30809cb4e9760472c653d73d89750fbe0 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:04:01 -0400 Subject: [PATCH 057/131] comment out pos embed print statement --- src/models/vision_transformer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/vision_transformer.py b/src/models/vision_transformer.py index 7a14435f..2ff5e577 100644 --- a/src/models/vision_transformer.py +++ b/src/models/vision_transformer.py @@ -173,7 +173,7 @@ def forward(self, x, masks=None): if pos_embed is not None: x += pos_embed B, N, D = x.shape - print("pos_embed x shape:", x.shape) + # print("pos_embed x shape:", x.shape) # Mask away unwanted tokens (if masks provided) if masks is not None: x = apply_masks(x, masks) @@ -191,7 +191,7 @@ def forward(self, x, masks=None): if self.norm is not None: x = self.norm(x) - print("shape of encoder output:", x.shape) + print("shape of encoder:", x.shape) return x def interpolate_pos_encoding(self, x, pos_embed): From 87d256c72088492e82ad3c95a24677fec99798e2 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:14:29 -0400 Subject: [PATCH 058/131] uncomment final shape prints --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 0c5c5623..7d3b52a0 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -353,8 +353,8 @@ def run_one_epoch( outputs = [[classifier(ost) for ost in os] for os in outputs] # print("outputs NOT attend:", outputs[0].shape) # print("outputs is:", outputs) - # print("outputs[0] final shape", outputs[0].shape) - # print("labels[0] final shape:", labels[0].shape) + print("outputs[0] final shape", outputs[0].shape) + print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') From ea1483e1a49fee26ca1cb723d5dba962413f0861 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:17:46 -0400 Subject: [PATCH 059/131] update nn.linear --- src/models/pegs_attentive_probe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 21890d30..9c3948f5 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -17,7 +17,8 @@ def __init__( num_classes=165 ): super().__init__() - self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) + # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) + self.linear = nn.Linear(embed_dim, num_classes, bias=True) def forward(self, x): print("input to classifier shape:", x.shape) From d12a038ffb3446c74c44135bad722731bcebaa03 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:28:24 -0400 Subject: [PATCH 060/131] import torch --- src/models/pegs_attentive_probe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 9c3948f5..7b9dfea0 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -5,10 +5,10 @@ # LICENSE file in the root directory of this source tree. # +import torch import torch.nn as nn - class PegAttentiveClassifier(nn.Module): """ Attentive Classifier """ def __init__( From b4cf5b4c673e8b1ebd2a09f9ea8b011cce2e1624 Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Tue, 18 Jun 2024 15:49:58 -0400 Subject: [PATCH 061/131] add yaml and pegs_eval.py files - stil getting Nans for loss --- configs/evals/vitl16_k400_16x8x3.yaml | 7 ++-- .../video_classification_frozen/pegs_eval.py | 32 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 78478e18..882bd19c 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -1,11 +1,12 @@ + nodes: 1 tasks_per_node: 1 tag: k400-16x8x3 eval_name: video_classification_frozen resume_checkpoint: false data: - dataset_train: /scratch/ki2130/my-jepa/jepa/p_mini_train.csv - dataset_val: /scratch/ki2130/my-jepa/jepa/p_mini_test.csv + dataset_train: /scratch/ki2130/my-jepa/jepa/p_dummy.csv + dataset_val: /scratch/ki2130/my-jepa/jepa/p_dummy.csv dataset_type: VideoDataset num_classes: 165 frames_per_clip: 16 @@ -14,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 20 + num_epochs: 3 resolution: 224 batch_size: 4 weight_decay: 0.01 diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 7d3b52a0..6bb50e95 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -313,7 +313,7 @@ def run_one_epoch( ): classifier.train(mode=training) - criterion = torch.nn.CrossEntropyLoss() + criterion = torch.nn.BCEWithLogitsLoss() top1_meter = AverageMeter() for itr, data in enumerate(data_loader): @@ -360,6 +360,13 @@ def run_one_epoch( plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') + + #print("PRINT outputs[0][0:]", outputs[0][0:]) + #print("PRINT 'labels[0]",labels[0]) + #print("PRINT length labels", len(labels)) + + + # Compute loss if attend_across_segments: loss = 0 @@ -367,15 +374,16 @@ def run_one_epoch( loss+=criterion(outputs[0][i,:], labels[i]) loss = loss/len(labels) # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) - else: - loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - # with torch.no_grad(): + #else: + #loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + with torch.no_grad(): # kat - # if attend_across_segments: - # sum_softmax = 0 - # for i in range(len(labels)): - # sum_softmax += F.softmax(outputs[0][i,:]) # no averaging (dividing by len(outputs)) - # outputs = sum_softmax + if attend_across_segments: + sum_softmax = 0 + print("output[0].shape[0]",outputs[0].shape[0]) + for i in range(outputs[0].shape[0]): + sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) + outputs = sum_softmax # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) # kat @@ -427,9 +435,9 @@ def run_one_epoch( optimizer.zero_grad() if itr % 20 == 0: - logger.info('[%5d] (loss: %.3f) [mem: %.2e]' - % (itr, loss, - torch.cuda.max_memory_allocated() / 1024.**2)) + logger.info('[%5d] (loss: %.3f) [mem: %.2e]' + % (itr, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) # if itr % 20 == 0: # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' # % (itr, top1_meter.avg, loss, From 2ae2bb7f84e5be189e1dc6e249ac21696c62b54a Mon Sep 17 00:00:00 2001 From: Kathleena Inchoco Date: Tue, 18 Jun 2024 15:53:02 -0400 Subject: [PATCH 062/131] add pegs_eval2.py --- evals/scaffold.py | 2 +- .../video_classification_frozen/pegs_eval2.py | 629 ++++++++++++++++++ 2 files changed, 630 insertions(+), 1 deletion(-) create mode 100644 evals/video_classification_frozen/pegs_eval2.py diff --git a/evals/scaffold.py b/evals/scaffold.py index b2f10404..aaac6927 100644 --- a/evals/scaffold.py +++ b/evals/scaffold.py @@ -19,6 +19,6 @@ def main( resume_preempt=False ): logger.info(f'Running evaluation: {eval_name}') - return importlib.import_module(f'evals.{eval_name}.pegs_eval').main( + return importlib.import_module(f'evals.{eval_name}.pegs_eval2').main( args_eval=args_eval, resume_preempt=resume_preempt) diff --git a/evals/video_classification_frozen/pegs_eval2.py b/evals/video_classification_frozen/pegs_eval2.py new file mode 100644 index 00000000..6bb50e95 --- /dev/null +++ b/evals/video_classification_frozen/pegs_eval2.py @@ -0,0 +1,629 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# + +import os + +# -- FOR DISTRIBUTED TRAINING ENSURE ONLY 1 DEVICE VISIBLE PER PROCESS +try: + # -- WARNING: IF DOING DISTRIBUTED TRAINING ON A NON-SLURM CLUSTER, MAKE + # -- SURE TO UPDATE THIS TO GET LOCAL-RANK ON NODE, OR ENSURE + # -- THAT YOUR JOBS ARE LAUNCHED WITH ONLY 1 DEVICE VISIBLE + # -- TO EACH PROCESS + os.environ['CUDA_VISIBLE_DEVICES'] = os.environ['SLURM_LOCALID'] +except Exception: + pass + +import logging +import pprint + +import numpy as np + +import torch +import torch.multiprocessing as mp +import torch.nn.functional as F + +from torch.nn.parallel import DistributedDataParallel + +import src.models.vision_transformer as vit +from src.models.pegs_attentive_probe import PegAttentiveClassifier +from src.datasets.data_manager import ( + init_data, +) +from src.utils.distributed import ( + init_distributed, + AllReduce +) +from src.utils.schedulers import ( + WarmupCosineSchedule, + CosineWDSchedule, +) +from src.utils.logging import ( + AverageMeter, + CSVLogger +) + +from evals.video_classification_frozen.utils import ( + make_transforms, + ClipAggregation, + FrameAggregation +) + +from evals.video_classification_frozen.kp_utils import plot_guess_img + +logging.basicConfig() +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +_GLOBAL_SEED = 0 +np.random.seed(_GLOBAL_SEED) +torch.manual_seed(_GLOBAL_SEED) +torch.backends.cudnn.benchmark = True + +pp = pprint.PrettyPrinter(indent=4) + + +def main(args_eval, resume_preempt=False): + + # ----------------------------------------------------------------------- # + # PASSED IN PARAMS FROM CONFIG FILE + # ----------------------------------------------------------------------- # + + # -- PRETRAIN + args_pretrain = args_eval.get('pretrain') + checkpoint_key = args_pretrain.get('checkpoint_key', 'target_encoder') + model_name = args_pretrain.get('model_name', None) + patch_size = args_pretrain.get('patch_size', None) + pretrain_folder = args_pretrain.get('folder', None) + ckp_fname = args_pretrain.get('checkpoint', None) + tag = args_pretrain.get('write_tag', None) + use_sdpa = args_pretrain.get('use_sdpa', True) + use_SiLU = args_pretrain.get('use_silu', False) + tight_SiLU = args_pretrain.get('tight_silu', True) + uniform_power = args_pretrain.get('uniform_power', False) + pretrained_path = os.path.join(pretrain_folder, ckp_fname) + # Optional [for Video model]: + tubelet_size = args_pretrain.get('tubelet_size', 2) + pretrain_frames_per_clip = args_pretrain.get('frames_per_clip', 1) + + # -- DATA + args_data = args_eval.get('data') + train_data_path = [args_data.get('dataset_train')] + val_data_path = [args_data.get('dataset_val')] + dataset_type = args_data.get('dataset_type', 'VideoDataset') + num_classes = args_data.get('num_classes') + eval_num_segments = args_data.get('num_segments', 1) + eval_frames_per_clip = args_data.get('frames_per_clip', 16) + eval_frame_step = args_pretrain.get('frame_step', 4) + eval_duration = args_pretrain.get('clip_duration', None) + eval_num_views_per_segment = args_data.get('num_views_per_segment', 1) + + # -- OPTIMIZATION + args_opt = args_eval.get('optimization') + resolution = args_opt.get('resolution', 224) + batch_size = args_opt.get('batch_size') + attend_across_segments = args_opt.get('attend_across_segments', False) + num_epochs = args_opt.get('num_epochs') + wd = args_opt.get('weight_decay') + start_lr = args_opt.get('start_lr') + lr = args_opt.get('lr') + final_lr = args_opt.get('final_lr') + warmup = args_opt.get('warmup') + use_bfloat16 = args_opt.get('use_bfloat16') + + # -- EXPERIMENT-ID/TAG (optional) + resume_checkpoint = args_eval.get('resume_checkpoint', False) or resume_preempt + eval_tag = args_eval.get('tag', None) + + # ----------------------------------------------------------------------- # + + try: + mp.set_start_method('spawn') + except Exception: + pass + + if not torch.cuda.is_available(): + device = torch.device('cpu') + else: + device = torch.device('cuda:0') + torch.cuda.set_device(device) + + world_size, rank = init_distributed() + logger.info(f'Initialized (rank/world-size) {rank}/{world_size}') + + # -- log/checkpointing paths + folder = os.path.join(pretrain_folder, 'video_classification_frozen/') + if eval_tag is not None: + folder = os.path.join(folder, eval_tag) + if not os.path.exists(folder): + os.makedirs(folder, exist_ok=True) + log_file = os.path.join(folder, f'{tag}_r{rank}.csv') + latest_path = os.path.join(folder, f'{tag}-latest.pth.tar') + + # -- make csv_logger + if rank == 0: + csv_logger = CSVLogger(log_file, + ('%d', 'epoch'), + ('%.5f', 'loss'), + ('%.5f', 'acc')) + + # Initialize model + + # -- pretrained encoder (frozen) + encoder = init_model( + crop_size=resolution, + device=device, + pretrained=pretrained_path, + model_name=model_name, + patch_size=patch_size, + tubelet_size=tubelet_size, + frames_per_clip=pretrain_frames_per_clip, + uniform_power=uniform_power, + checkpoint_key=checkpoint_key, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + use_sdpa=use_sdpa) + if pretrain_frames_per_clip == 1: + # Process each frame independently and aggregate + encoder = FrameAggregation(encoder).to(device) + else: + # Process each video clip independently and aggregate + encoder = ClipAggregation( + encoder, + tubelet_size=tubelet_size, + attend_across_segments=attend_across_segments + ).to(device) + encoder.eval() + for p in encoder.parameters(): + p.requires_grad = False + + # -- init classifier + classifier = PegAttentiveClassifier( + embed_dim=encoder.embed_dim, + num_classes=num_classes, + ).to(device) + + train_loader = make_dataloader( + dataset_type=dataset_type, + root_path=train_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + eval_duration=eval_duration, + num_segments=eval_num_segments if attend_across_segments else 1, + num_views_per_segment=1, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=True) + val_loader = make_dataloader( + dataset_type=dataset_type, + root_path=val_data_path, + resolution=resolution, + frames_per_clip=eval_frames_per_clip, + frame_step=eval_frame_step, + num_segments=eval_num_segments, + eval_duration=eval_duration, + num_views_per_segment=eval_num_views_per_segment, + allow_segment_overlap=True, + batch_size=batch_size, + world_size=world_size, + rank=rank, + training=False) + ipe = len(train_loader) + logger.info(f'Dataloader created... iterations per epoch: {ipe}') + + # -- optimizer and scheduler + optimizer, scaler, scheduler, wd_scheduler = init_opt( + classifier=classifier, + wd=wd, + start_lr=start_lr, + ref_lr=lr, + final_lr=final_lr, + iterations_per_epoch=ipe, + warmup=warmup, + num_epochs=num_epochs, + use_bfloat16=use_bfloat16) + classifier = DistributedDataParallel(classifier, static_graph=True) + + # -- load training checkpoint + start_epoch = 0 + if resume_checkpoint: + classifier, optimizer, scaler, start_epoch = load_checkpoint( + device=device, + r_path=latest_path, + classifier=classifier, + opt=optimizer, + scaler=scaler) + for _ in range(start_epoch*ipe): + scheduler.step() + wd_scheduler.step() + + def save_checkpoint(epoch): + save_dict = { + 'classifier': classifier.state_dict(), + 'opt': optimizer.state_dict(), + 'scaler': None if scaler is None else scaler.state_dict(), + 'epoch': epoch, + 'batch_size': batch_size, + 'world_size': world_size, + 'lr': lr + } + if rank == 0: + torch.save(save_dict, latest_path) + + # TRAIN LOOP + for epoch in range(start_epoch, num_epochs): + logger.info('Epoch %d' % (epoch + 1)) + train_acc = run_one_epoch( + device=device, + training=True, + num_temporal_views=eval_num_segments if attend_across_segments else 1, + attend_across_segments=attend_across_segments, + num_spatial_views=1, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=train_loader, + use_bfloat16=use_bfloat16) + + val_acc = run_one_epoch( + device=device, + training=False, + num_temporal_views=eval_num_segments, + attend_across_segments=attend_across_segments, + num_spatial_views=eval_num_views_per_segment, + encoder=encoder, + classifier=classifier, + scaler=scaler, + optimizer=optimizer, + scheduler=scheduler, + wd_scheduler=wd_scheduler, + data_loader=val_loader, + use_bfloat16=use_bfloat16) + + logger.info('[%5d] train: %.3f test: %.3f' % (epoch + 1, train_acc, val_acc)) + # logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) + if rank == 0: + csv_logger.log(epoch + 1, train_acc, val_acc) + save_checkpoint(epoch + 1) + + +def run_one_epoch( + device, + training, + encoder, + classifier, + scaler, + optimizer, + scheduler, + wd_scheduler, + data_loader, + use_bfloat16, + num_spatial_views, + num_temporal_views, + attend_across_segments, +): + + classifier.train(mode=training) + criterion = torch.nn.BCEWithLogitsLoss() + top1_meter = AverageMeter() + for itr, data in enumerate(data_loader): + + if training: + scheduler.step() + wd_scheduler.step() + + with torch.cuda.amp.autocast(dtype=torch.float16, enabled=use_bfloat16): + + # Load data and put on GPU + clips = [ + [dij.to(device, non_blocking=True) for dij in di] # iterate over spatial views of clip + for di in data[0] # iterate over temporal index of clip + ] + clip_indices = [d.to(device, non_blocking=True) for d in data[2]] + labels = data[1].to(device) + batch_size = len(labels) + + print("is it training?",training) + + # Forward and prediction + with torch.no_grad(): + outputs = encoder(clips, clip_indices) + # print("outputs with encoder applied to clips and clips indices shape:", outputs[0].shape) + if not training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + #print("outputs shape", outputs[0].shape) + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + #print("ouputs shape", outputs[0].shape) + if training: + if attend_across_segments: + outputs = [classifier(o) for o in outputs] + # print("outputs attend:", outputs[0].shape) + else: + outputs = [[classifier(ost) for ost in os] for os in outputs] + # print("outputs NOT attend:", outputs[0].shape) + # print("outputs is:", outputs) + print("outputs[0] final shape", outputs[0].shape) + print("labels[0] final shape:", labels[0].shape) + + # save output and label as images (comment this out when done testing) + plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') + plot_guess_img(labels[0], output_filename = 'labels-0.png') + + + #print("PRINT outputs[0][0:]", outputs[0][0:]) + #print("PRINT 'labels[0]",labels[0]) + #print("PRINT length labels", len(labels)) + + + + # Compute loss + if attend_across_segments: + loss = 0 + for i in range(len(labels)): + loss+=criterion(outputs[0][i,:], labels[i]) + loss = loss/len(labels) + # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) + #else: + #loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + with torch.no_grad(): + # kat + if attend_across_segments: + sum_softmax = 0 + print("output[0].shape[0]",outputs[0].shape[0]) + for i in range(outputs[0].shape[0]): + sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) + outputs = sum_softmax + + # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) + # kat + # try: + # print("outputs attend no grad:", len(outputs)) + # except: + # "not a list" + # try: + # print("outputs attend no grad:", outputs.shape) + # except: + # "not a tensor" + # else: + # outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + #kat + # # Initialize variables for correct predictions + # correct_count = 0 + # # Iterate over each row (i) in outputs[0] + # for i in range(len(labels)): + # # Get the ith row of outputs[0] and compute the maximum index + # row_outputs = outputs[0][i, :] + # max_index = torch.argmax(row_outputs) + # # Compare the maximum index with the corresponding label + # if max_index == labels[i]: + # correct_count += 1 + # # Calculate top-1 accuracy + # top1_acc = (100. * correct_count) / batch_size + + # kat + # acc_list = [] + # for i in range(len(labels)): + # value_acc = outputs[0][i,:].indices.eq(labels) + # acc_list.append(value_acc) + + # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size + # top1_acc = float(AllReduce.apply(top1_acc)) + # top1_meter.update(top1_acc) + + if training: + if use_bfloat16: + scaler.scale(loss).backward() + scaler.unscale_(optimizer) + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + scaler.step(optimizer) + scaler.update() + else: + loss.backward() + torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) + optimizer.step() + optimizer.zero_grad() + + if itr % 20 == 0: + logger.info('[%5d] (loss: %.3f) [mem: %.2e]' + % (itr, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + # if itr % 20 == 0: + # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + # % (itr, top1_meter.avg, loss, + # torch.cuda.max_memory_allocated() / 1024.**2)) + + return loss + # return top1_meter.avg + + + +def load_checkpoint( + device, + r_path, + classifier, + opt, + scaler +): + try: + checkpoint = torch.load(r_path, map_location=torch.device('cpu')) + epoch = checkpoint['epoch'] + + # -- loading encoder + pretrained_dict = checkpoint['classifier'] + msg = classifier.load_state_dict(pretrained_dict) + logger.info(f'loaded pretrained classifier from epoch {epoch} with msg: {msg}') + + # -- loading optimizer + opt.load_state_dict(checkpoint['opt']) + if scaler is not None: + scaler.load_state_dict(checkpoint['scaler']) + logger.info(f'loaded optimizers from epoch {epoch}') + logger.info(f'read-path: {r_path}') + del checkpoint + + except Exception as e: + logger.info(f'Encountered exception when loading checkpoint {e}') + epoch = 0 + + return classifier, opt, scaler, epoch + + +def load_pretrained( + encoder, + pretrained, + checkpoint_key='target_encoder' +): + logger.info(f'Loading pretrained model from {pretrained}') + checkpoint = torch.load(pretrained, map_location='cpu') + try: + pretrained_dict = checkpoint[checkpoint_key] + except Exception: + pretrained_dict = checkpoint['encoder'] + + pretrained_dict = {k.replace('module.', ''): v for k, v in pretrained_dict.items()} + pretrained_dict = {k.replace('backbone.', ''): v for k, v in pretrained_dict.items()} + for k, v in encoder.state_dict().items(): + if k not in pretrained_dict: + logger.info(f'key "{k}" could not be found in loaded state dict') + elif pretrained_dict[k].shape != v.shape: + logger.info(f'key "{k}" is of different shape in model and loaded state dict') + pretrained_dict[k] = v + msg = encoder.load_state_dict(pretrained_dict, strict=False) + print(encoder) + logger.info(f'loaded pretrained model with msg: {msg}') + logger.info(f'loaded pretrained encoder from epoch: {checkpoint["epoch"]}\n path: {pretrained}') + del checkpoint + return encoder + + +def make_dataloader( + root_path, + batch_size, + world_size, + rank, + dataset_type='VideoDataset', + resolution=224, + frames_per_clip=16, + frame_step=4, + num_segments=8, + eval_duration=None, + num_views_per_segment=1, + allow_segment_overlap=True, + training=False, + num_workers=8, + subset_file=None +): + # Make Video Transforms + transform = make_transforms( + training=training, + num_views_per_clip=num_views_per_segment, + random_horizontal_flip=False, + random_resize_aspect_ratio=(0.75, 4/3), + random_resize_scale=(0.08, 1.0), + reprob=0.25, + auto_augment=True, + motion_shift=False, + crop_size=resolution, + ) + + data_loader, _ = init_data( + data=dataset_type, + root_path=root_path, + transform=transform, + batch_size=batch_size, + world_size=world_size, + rank=rank, + clip_len=frames_per_clip, + frame_sample_rate=frame_step, + duration=eval_duration, + num_clips=num_segments, + allow_clip_overlap=allow_segment_overlap, + num_workers=num_workers, + copy_data=False, + drop_last=False, + subset_file=subset_file) + return data_loader + + +def init_model( + device, + pretrained, + model_name, + patch_size=16, + crop_size=224, + # Video specific parameters + frames_per_clip=16, + tubelet_size=2, + use_sdpa=False, + use_SiLU=False, + tight_SiLU=True, + uniform_power=False, + checkpoint_key='target_encoder' +): + encoder = vit.__dict__[model_name]( + img_size=crop_size, + patch_size=patch_size, + num_frames=frames_per_clip, + tubelet_size=tubelet_size, + uniform_power=uniform_power, + use_sdpa=use_sdpa, + use_SiLU=use_SiLU, + tight_SiLU=tight_SiLU, + ) + + encoder.to(device) + encoder = load_pretrained(encoder=encoder, pretrained=pretrained, checkpoint_key=checkpoint_key) + return encoder + + +def init_opt( + classifier, + iterations_per_epoch, + start_lr, + ref_lr, + warmup, + num_epochs, + wd=1e-6, + final_wd=1e-6, + final_lr=0.0, + use_bfloat16=False +): + param_groups = [ + { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' not in n) and (len(p.shape) != 1)) + }, { + 'params': (p for n, p in classifier.named_parameters() + if ('bias' in n) or (len(p.shape) == 1)), + 'WD_exclude': True, + 'weight_decay': 0 + } + ] + + logger.info('Using AdamW') + optimizer = torch.optim.AdamW(param_groups) + scheduler = WarmupCosineSchedule( + optimizer, + warmup_steps=int(warmup*iterations_per_epoch), + start_lr=start_lr, + ref_lr=ref_lr, + final_lr=final_lr, + T_max=int(num_epochs*iterations_per_epoch)) + wd_scheduler = CosineWDSchedule( + optimizer, + ref_wd=wd, + final_wd=final_wd, + T_max=int(num_epochs*iterations_per_epoch)) + scaler = torch.cuda.amp.GradScaler() if use_bfloat16 else None + return optimizer, scaler, scheduler, wd_scheduler From 0a3a595709d61d674c2d7bfe90274f32af98f461 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:54:41 -0400 Subject: [PATCH 063/131] Update pegs_eval2.py use original loss and see what happens --- .../video_classification_frozen/pegs_eval2.py | 79 ++++--------------- 1 file changed, 16 insertions(+), 63 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval2.py b/evals/video_classification_frozen/pegs_eval2.py index 6bb50e95..190a8f31 100644 --- a/evals/video_classification_frozen/pegs_eval2.py +++ b/evals/video_classification_frozen/pegs_eval2.py @@ -365,61 +365,19 @@ def run_one_epoch( #print("PRINT 'labels[0]",labels[0]) #print("PRINT length labels", len(labels)) - - # Compute loss if attend_across_segments: - loss = 0 - for i in range(len(labels)): - loss+=criterion(outputs[0][i,:], labels[i]) - loss = loss/len(labels) - # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) - #else: - #loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) + else: + loss = sum([sum([criterion(ost, labels) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) with torch.no_grad(): - # kat if attend_across_segments: - sum_softmax = 0 - print("output[0].shape[0]",outputs[0].shape[0]) - for i in range(outputs[0].shape[0]): - sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) - outputs = sum_softmax - - # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) - # kat - # try: - # print("outputs attend no grad:", len(outputs)) - # except: - # "not a list" - # try: - # print("outputs attend no grad:", outputs.shape) - # except: - # "not a tensor" - # else: - # outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - #kat - # # Initialize variables for correct predictions - # correct_count = 0 - # # Iterate over each row (i) in outputs[0] - # for i in range(len(labels)): - # # Get the ith row of outputs[0] and compute the maximum index - # row_outputs = outputs[0][i, :] - # max_index = torch.argmax(row_outputs) - # # Compare the maximum index with the corresponding label - # if max_index == labels[i]: - # correct_count += 1 - # # Calculate top-1 accuracy - # top1_acc = (100. * correct_count) / batch_size - - # kat - # acc_list = [] - # for i in range(len(labels)): - # value_acc = outputs[0][i,:].indices.eq(labels) - # acc_list.append(value_acc) - - # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - # top1_acc = float(AllReduce.apply(top1_acc)) - # top1_meter.update(top1_acc) + outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) + else: + outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) + top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size + top1_acc = float(AllReduce.apply(top1_acc)) + top1_meter.update(top1_acc) if training: if use_bfloat16: @@ -433,18 +391,13 @@ def run_one_epoch( torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) optimizer.step() optimizer.zero_grad() - - if itr % 20 == 0: - logger.info('[%5d] (loss: %.3f) [mem: %.2e]' - % (itr, loss, - torch.cuda.max_memory_allocated() / 1024.**2)) - # if itr % 20 == 0: - # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - # % (itr, top1_meter.avg, loss, - # torch.cuda.max_memory_allocated() / 1024.**2)) - - return loss - # return top1_meter.avg + + if itr % 20 == 0: + logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' + % (itr, top1_meter.avg, loss, + torch.cuda.max_memory_allocated() / 1024.**2)) + + return top1_meter.avg From 5cc933d681b0284433d78ef591d3154d4ddddde1 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:41:18 -0400 Subject: [PATCH 064/131] change criterion back to cross-entropy loss --- evals/video_classification_frozen/pegs_eval2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval2.py b/evals/video_classification_frozen/pegs_eval2.py index 190a8f31..efd1aa72 100644 --- a/evals/video_classification_frozen/pegs_eval2.py +++ b/evals/video_classification_frozen/pegs_eval2.py @@ -313,7 +313,7 @@ def run_one_epoch( ): classifier.train(mode=training) - criterion = torch.nn.BCEWithLogitsLoss() + criterion = torch.nn.CrossEntropyLoss() top1_meter = AverageMeter() for itr, data in enumerate(data_loader): From fcd9d7a73126621763700a730ac4c1cfab7ae756 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:00:57 -0400 Subject: [PATCH 065/131] check gradient norm after loss.backward() --- evals/video_classification_frozen/pegs_eval2.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/evals/video_classification_frozen/pegs_eval2.py b/evals/video_classification_frozen/pegs_eval2.py index efd1aa72..89b92816 100644 --- a/evals/video_classification_frozen/pegs_eval2.py +++ b/evals/video_classification_frozen/pegs_eval2.py @@ -386,10 +386,16 @@ def run_one_epoch( torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) scaler.step(optimizer) scaler.update() + for name, param in model.named_parameters(): + if param.grad is not None: + print(f"Parameter: {name}, Gradient norm: {param.grad.norm().item()}") else: loss.backward() torch.nn.utils.clip_grad_norm_(classifier.parameters(), 1.0) optimizer.step() + for name, param in model.named_parameters(): + if param.grad is not None: + print(f"Parameter: {name}, Gradient norm: {param.grad.norm().item()}") optimizer.zero_grad() if itr % 20 == 0: From 44763026b5f58993a3e06e309d55e230a549c3da Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:35:41 -0400 Subject: [PATCH 066/131] add debug print statements --- evals/video_classification_frozen/pegs_eval.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 6bb50e95..210ea289 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -360,17 +360,17 @@ def run_one_epoch( plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') - - #print("PRINT outputs[0][0:]", outputs[0][0:]) - #print("PRINT 'labels[0]",labels[0]) - #print("PRINT length labels", len(labels)) - - + # print("PRINT outputs[0][0:]", outputs[0][0:]) + # print("PRINT 'labels[0]",labels[0]) + # print("PRINT length labels", len(labels)) # Compute loss if attend_across_segments: loss = 0 for i in range(len(labels)): + print("PRINT outputs[0][0:]", outputs[0][0:]) + print("PRINT 'labels[0]",labels[0]) + print("PRINT length labels", len(labels)) loss+=criterion(outputs[0][i,:], labels[i]) loss = loss/len(labels) # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) @@ -382,6 +382,9 @@ def run_one_epoch( sum_softmax = 0 print("output[0].shape[0]",outputs[0].shape[0]) for i in range(outputs[0].shape[0]): + print("PRINT outputs[0][0:]", outputs[0][0:]) + print("PRINT 'labels[0]",labels[0]) + print("PRINT length labels", len(labels)) sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) outputs = sum_softmax From d4a6666ce8aaba997aee8bf0028b064594d6bac3 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:36:05 -0400 Subject: [PATCH 067/131] change back to pegs_eval.py --- evals/scaffold.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/scaffold.py b/evals/scaffold.py index aaac6927..b2f10404 100644 --- a/evals/scaffold.py +++ b/evals/scaffold.py @@ -19,6 +19,6 @@ def main( resume_preempt=False ): logger.info(f'Running evaluation: {eval_name}') - return importlib.import_module(f'evals.{eval_name}.pegs_eval2').main( + return importlib.import_module(f'evals.{eval_name}.pegs_eval').main( args_eval=args_eval, resume_preempt=resume_preempt) From 4a08333b456a8d3fa576a78a98d9305e2304bc06 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:04:20 -0400 Subject: [PATCH 068/131] Update vitl16_k400_16x8x3.yaml 1 epoch from 3 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 882bd19c..b1bc24ca 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 3 + num_epochs: 1 resolution: 224 batch_size: 4 weight_decay: 0.01 From dee13416d8923405aafd9e1754cb5437d54cda8d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:50:17 -0400 Subject: [PATCH 069/131] print min/max of encoder output --- src/models/vision_transformer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/vision_transformer.py b/src/models/vision_transformer.py index 2ff5e577..901f5e2d 100644 --- a/src/models/vision_transformer.py +++ b/src/models/vision_transformer.py @@ -192,6 +192,8 @@ def forward(self, x, masks=None): if self.norm is not None: x = self.norm(x) print("shape of encoder:", x.shape) + print("min of encoded", torch.min(x)) + print("max of encoded", torch.max(x)) return x def interpolate_pos_encoding(self, x, pos_embed): From 0266ff6524753f24b1b6c503c9ceba8325d3440e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:00:19 -0400 Subject: [PATCH 070/131] print min/max after sum and after linear --- src/models/pegs_attentive_probe.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 7b9dfea0..b2eeebb4 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -24,7 +24,11 @@ def forward(self, x): print("input to classifier shape:", x.shape) x = torch.sum(x, dim=1) print("summed x:", x.shape) + print("min after sum", torch.min(x)) + print("max after sum", torch.max(x)) x = self.linear(x) + print("min after linear", torch.min(x)) + print("max after linear", torch.max(x)) return x # flattened_x = x.flatten(1,-1) From 28096ee612bf42e0edda2d8b8435e1d9130e1606 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:02:09 -0400 Subject: [PATCH 071/131] comment out print label --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 210ea289..b3b106fd 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -369,7 +369,7 @@ def run_one_epoch( loss = 0 for i in range(len(labels)): print("PRINT outputs[0][0:]", outputs[0][0:]) - print("PRINT 'labels[0]",labels[0]) + # print("PRINT 'labels[0]",labels[0]) print("PRINT length labels", len(labels)) loss+=criterion(outputs[0][i,:], labels[i]) loss = loss/len(labels) @@ -383,7 +383,7 @@ def run_one_epoch( print("output[0].shape[0]",outputs[0].shape[0]) for i in range(outputs[0].shape[0]): print("PRINT outputs[0][0:]", outputs[0][0:]) - print("PRINT 'labels[0]",labels[0]) + # print("PRINT 'labels[0]",labels[0]) print("PRINT length labels", len(labels)) sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) outputs = sum_softmax From 2fdaa43fecf7063b647a6dcd103b15eec6516858 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:30:14 -0400 Subject: [PATCH 072/131] apply softmax before linear --- src/models/pegs_attentive_probe.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index b2eeebb4..11aa58e1 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -26,6 +26,9 @@ def forward(self, x): print("summed x:", x.shape) print("min after sum", torch.min(x)) print("max after sum", torch.max(x)) + x = torch.nn.Softmax(x) + print("min after softmax", torch.min(x)) + print("max after softmax", torch.max(x)) x = self.linear(x) print("min after linear", torch.min(x)) print("max after linear", torch.max(x)) From 01a34773a686209aacbdb04e9e8f4430fb024009 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:42:12 -0400 Subject: [PATCH 073/131] edit softmax syntax --- src/models/pegs_attentive_probe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 11aa58e1..ae57ff05 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -19,6 +19,7 @@ def __init__( super().__init__() # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) self.linear = nn.Linear(embed_dim, num_classes, bias=True) + self.softmax = nn.Softmax() def forward(self, x): print("input to classifier shape:", x.shape) @@ -26,7 +27,7 @@ def forward(self, x): print("summed x:", x.shape) print("min after sum", torch.min(x)) print("max after sum", torch.max(x)) - x = torch.nn.Softmax(x) + x = self.softmax(x) print("min after softmax", torch.min(x)) print("max after softmax", torch.max(x)) x = self.linear(x) From 45d5e0b4988cb121469d84ca47bd50c63319fee6 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:07:56 -0400 Subject: [PATCH 074/131] add avgpool(10, stride = 2) --- src/models/pegs_attentive_probe.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index ae57ff05..ea471ed6 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -20,6 +20,7 @@ def __init__( # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) self.linear = nn.Linear(embed_dim, num_classes, bias=True) self.softmax = nn.Softmax() + self.avgpool = nn.AvgPool2d(10, stride=2) def forward(self, x): print("input to classifier shape:", x.shape) @@ -27,9 +28,12 @@ def forward(self, x): print("summed x:", x.shape) print("min after sum", torch.min(x)) print("max after sum", torch.max(x)) - x = self.softmax(x) - print("min after softmax", torch.min(x)) - print("max after softmax", torch.max(x)) + # x = self.softmax(x) + # print("min after softmax", torch.min(x)) + # print("max after softmax", torch.max(x)) + x = self.avgpool(x) + print("min after avgpool", torch.min(x)) + print("max after avgpool", torch.max(x)) x = self.linear(x) print("min after linear", torch.min(x)) print("max after linear", torch.max(x)) From 3168f889401179afe95cf62684656a82553b859a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:17:01 -0400 Subject: [PATCH 075/131] avgpool1d --- src/models/pegs_attentive_probe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index ea471ed6..903583ac 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -20,7 +20,7 @@ def __init__( # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) self.linear = nn.Linear(embed_dim, num_classes, bias=True) self.softmax = nn.Softmax() - self.avgpool = nn.AvgPool2d(10, stride=2) + self.avgpool = nn.AvgPool1d(10, stride=2) def forward(self, x): print("input to classifier shape:", x.shape) @@ -32,8 +32,8 @@ def forward(self, x): # print("min after softmax", torch.min(x)) # print("max after softmax", torch.max(x)) x = self.avgpool(x) - print("min after avgpool", torch.min(x)) - print("max after avgpool", torch.max(x)) + print("min after avgpool1d", torch.min(x)) + print("max after avgpool1d", torch.max(x)) x = self.linear(x) print("min after linear", torch.min(x)) print("max after linear", torch.max(x)) From afadbd13efc57ce6e653a73cbca1effc39d3813b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:23:46 -0400 Subject: [PATCH 076/131] fix nn.linear --- src/models/pegs_attentive_probe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 903583ac..31a15657 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -18,7 +18,8 @@ def __init__( ): super().__init__() # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) - self.linear = nn.Linear(embed_dim, num_classes, bias=True) + # self.linear = nn.Linear(embed_dim, num_classes, bias=True) + self.linear = nn.Linear(508, num_classes, bias=True) # 1024 becomes 508 after the avgpool1d self.softmax = nn.Softmax() self.avgpool = nn.AvgPool1d(10, stride=2) From d4635e8111a04a259eea1e8b018e2a06e7427af6 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:29:49 -0400 Subject: [PATCH 077/131] AvgPool1d(20, stride=2) --- src/models/pegs_attentive_probe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 31a15657..ba238afb 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -21,7 +21,7 @@ def __init__( # self.linear = nn.Linear(embed_dim, num_classes, bias=True) self.linear = nn.Linear(508, num_classes, bias=True) # 1024 becomes 508 after the avgpool1d self.softmax = nn.Softmax() - self.avgpool = nn.AvgPool1d(10, stride=2) + self.avgpool = nn.AvgPool1d(20, stride=2) def forward(self, x): print("input to classifier shape:", x.shape) From 3be2477c814e5f71c1b44cb772655f2dba76e87a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:37:25 -0400 Subject: [PATCH 078/131] nn.AvgPool1d(50, stride=10) --- src/models/pegs_attentive_probe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index ba238afb..901f8946 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -21,7 +21,7 @@ def __init__( # self.linear = nn.Linear(embed_dim, num_classes, bias=True) self.linear = nn.Linear(508, num_classes, bias=True) # 1024 becomes 508 after the avgpool1d self.softmax = nn.Softmax() - self.avgpool = nn.AvgPool1d(20, stride=2) + self.avgpool = nn.AvgPool1d(30, stride=10) def forward(self, x): print("input to classifier shape:", x.shape) From 5b16a7c7fce974276ed3839be40e0ab6501f7f2d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:37:45 -0400 Subject: [PATCH 079/131] nn.AvgPool1d(50, stride=10) --- src/models/pegs_attentive_probe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 901f8946..08f0a43d 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -21,7 +21,7 @@ def __init__( # self.linear = nn.Linear(embed_dim, num_classes, bias=True) self.linear = nn.Linear(508, num_classes, bias=True) # 1024 becomes 508 after the avgpool1d self.softmax = nn.Softmax() - self.avgpool = nn.AvgPool1d(30, stride=10) + self.avgpool = nn.AvgPool1d(50, stride=10) def forward(self, x): print("input to classifier shape:", x.shape) From 19c33ea4de2a320c61b0a978fd4ff274d4c3ff3a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:51:25 -0400 Subject: [PATCH 080/131] 508 to 98 in nn.linear --- src/models/pegs_attentive_probe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 08f0a43d..97780a76 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -19,7 +19,7 @@ def __init__( super().__init__() # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) # self.linear = nn.Linear(embed_dim, num_classes, bias=True) - self.linear = nn.Linear(508, num_classes, bias=True) # 1024 becomes 508 after the avgpool1d + self.linear = nn.Linear(98, num_classes, bias=True) # 1024 becomes 98 after the avgpool1d self.softmax = nn.Softmax() self.avgpool = nn.AvgPool1d(50, stride=10) From 87f4cd535ad48a72eb8f06e1fdb9bfcaeb58baf9 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 23:01:07 -0400 Subject: [PATCH 081/131] 10 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index b1bc24ca..75704433 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 1 + num_epochs: 10 resolution: 224 batch_size: 4 weight_decay: 0.01 From 900d9af5a132d8f0879764d4a1b7dc13bf39dbb9 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 23:30:36 -0400 Subject: [PATCH 082/131] adaptivepool 1x330 --- src/models/pegs_attentive_probe.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index 97780a76..b9e98d29 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -19,22 +19,26 @@ def __init__( super().__init__() # self.linear = nn.Linear(12544*embed_dim, num_classes, bias=False) # self.linear = nn.Linear(embed_dim, num_classes, bias=True) - self.linear = nn.Linear(98, num_classes, bias=True) # 1024 becomes 98 after the avgpool1d - self.softmax = nn.Softmax() - self.avgpool = nn.AvgPool1d(50, stride=10) + self.linear = nn.Linear(330, num_classes, bias=True) # 1024 becomes 98 after the avgpool1d + # self.softmax = nn.Softmax() + # self.avgpool = nn.AvgPool1d(50, stride=10) + self.adaptivepool = nn.AdaptiveAvgPool2d((1, 330)) def forward(self, x): print("input to classifier shape:", x.shape) - x = torch.sum(x, dim=1) - print("summed x:", x.shape) - print("min after sum", torch.min(x)) - print("max after sum", torch.max(x)) - # x = self.softmax(x) - # print("min after softmax", torch.min(x)) - # print("max after softmax", torch.max(x)) - x = self.avgpool(x) - print("min after avgpool1d", torch.min(x)) - print("max after avgpool1d", torch.max(x)) + # x = torch.sum(x, dim=1) + # print("summed x:", x.shape) + # print("min after sum", torch.min(x)) + # print("max after sum", torch.max(x)) + ## x = self.softmax(x) + ## print("min after softmax", torch.min(x)) + ## print("max after softmax", torch.max(x)) + # x = self.avgpool(x) + # print("min after avgpool1d", torch.min(x)) + # print("max after avgpool1d", torch.max(x)) + x = self.adaptivepool(x) + print("min after adaptivepool", torch.min(x)) + print("max after adaptivepool", torch.max(x)) x = self.linear(x) print("min after linear", torch.min(x)) print("max after linear", torch.max(x)) From 241f6895d5d337d52ace4e1a4197a8ff31738123 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 23:38:43 -0400 Subject: [PATCH 083/131] comment out plot_img for now --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index b3b106fd..af1729b6 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -357,8 +357,8 @@ def run_one_epoch( print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') - plot_guess_img(labels[0], output_filename = 'labels-0.png') + # plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') + # plot_guess_img(labels[0], output_filename = 'labels-0.png') # print("PRINT outputs[0][0:]", outputs[0][0:]) # print("PRINT 'labels[0]",labels[0]) From e00493aaa79aa2e608f49a5c72d472c0ce2d0cc1 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Sun, 30 Jun 2024 23:47:49 -0400 Subject: [PATCH 084/131] labels[i].unsqueeze(0) --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index af1729b6..8dd25b82 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -371,7 +371,7 @@ def run_one_epoch( print("PRINT outputs[0][0:]", outputs[0][0:]) # print("PRINT 'labels[0]",labels[0]) print("PRINT length labels", len(labels)) - loss+=criterion(outputs[0][i,:], labels[i]) + loss+=criterion(outputs[0][i,:], labels[i].unsqueeze(0)) loss = loss/len(labels) # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) #else: From 94b1023640dfd1fcc18ac328ab98cef876a3e426 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 18:39:23 -0400 Subject: [PATCH 085/131] comment out print statements --- evals/video_classification_frozen/pegs_eval.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 8dd25b82..3e17cde5 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -353,8 +353,8 @@ def run_one_epoch( outputs = [[classifier(ost) for ost in os] for os in outputs] # print("outputs NOT attend:", outputs[0].shape) # print("outputs is:", outputs) - print("outputs[0] final shape", outputs[0].shape) - print("labels[0] final shape:", labels[0].shape) + # print("outputs[0] final shape", outputs[0].shape) + # print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) # plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') @@ -368,9 +368,9 @@ def run_one_epoch( if attend_across_segments: loss = 0 for i in range(len(labels)): - print("PRINT outputs[0][0:]", outputs[0][0:]) + # print("PRINT outputs[0][0:]", outputs[0][0:]) # print("PRINT 'labels[0]",labels[0]) - print("PRINT length labels", len(labels)) + # print("PRINT length labels", len(labels)) loss+=criterion(outputs[0][i,:], labels[i].unsqueeze(0)) loss = loss/len(labels) # loss = sum([criterion(o, labels) for o in outputs]) / len(outputs) @@ -380,11 +380,11 @@ def run_one_epoch( # kat if attend_across_segments: sum_softmax = 0 - print("output[0].shape[0]",outputs[0].shape[0]) + # print("output[0].shape[0]",outputs[0].shape[0]) for i in range(outputs[0].shape[0]): - print("PRINT outputs[0][0:]", outputs[0][0:]) + # print("PRINT outputs[0][0:]", outputs[0][0:]) # print("PRINT 'labels[0]",labels[0]) - print("PRINT length labels", len(labels)) + # print("PRINT length labels", len(labels)) sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) outputs = sum_softmax From 5bb3f21d837ad2d184ba70e2c0c37ee002c5b0eb Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 18:41:38 -0400 Subject: [PATCH 086/131] comment out print statements --- src/models/pegs_attentive_probe.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/models/pegs_attentive_probe.py b/src/models/pegs_attentive_probe.py index b9e98d29..ac6e5204 100644 --- a/src/models/pegs_attentive_probe.py +++ b/src/models/pegs_attentive_probe.py @@ -37,11 +37,11 @@ def forward(self, x): # print("min after avgpool1d", torch.min(x)) # print("max after avgpool1d", torch.max(x)) x = self.adaptivepool(x) - print("min after adaptivepool", torch.min(x)) - print("max after adaptivepool", torch.max(x)) + # print("min after adaptivepool", torch.min(x)) + # print("max after adaptivepool", torch.max(x)) x = self.linear(x) - print("min after linear", torch.min(x)) - print("max after linear", torch.max(x)) + # print("min after linear", torch.min(x)) + # print("max after linear", torch.max(x)) return x # flattened_x = x.flatten(1,-1) From 9d4aed087547700eaaf6dfa2854c5bffe9a88d1d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 18:42:48 -0400 Subject: [PATCH 087/131] 500 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 75704433..313a5cc3 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 10 + num_epochs: 500 resolution: 224 batch_size: 4 weight_decay: 0.01 From f7d1babe15808f5c4e79681594066e0ef388ec13 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:05:24 -0400 Subject: [PATCH 088/131] 1 gpu, 8:00:00 timeout, slurm_additional_options='--gres=gpu:a100:1' --- evals/main_distributed.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 46e1afdb..d3bef8b0 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -74,7 +74,7 @@ def launch_evals_with_parsed_args( args_for_evals, submitit_folder, partition='learnlab,learnfair', - timeout=4300, + timeout=8:00:00, nodes=1, tasks_per_node=1, delay_seconds=10, @@ -96,10 +96,11 @@ def launch_evals_with_parsed_args( nodes=nodes, tasks_per_node=tasks_per_node, cpus_per_task=8, - gpus_per_node=2, + gpus_per_node=1, slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', - slurm_job_name='child-video-jepa2') + slurm_job_name='model-jepa2', + slurm_additional_options='--gres=gpu:a100:1') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 795489d96a1b8233c5a9f6b573dc61c0658563c5 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:09:01 -0400 Subject: [PATCH 089/131] timeout="8:00:00" --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index d3bef8b0..c2bea9b2 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -74,7 +74,7 @@ def launch_evals_with_parsed_args( args_for_evals, submitit_folder, partition='learnlab,learnfair', - timeout=8:00:00, + timeout="8:00:00", nodes=1, tasks_per_node=1, delay_seconds=10, From 6e0ec230717f73a62c6bbd0d27b47b6fb23daa52 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:11:22 -0400 Subject: [PATCH 090/131] gres='gpu:a100:1' --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index c2bea9b2..0040d7bd 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_options='--gres=gpu:a100:1') + gres='gpu:a100:1') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From fb1f4d1c2f7cf35fcecf8d895a340005aa8222ed Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:12:29 -0400 Subject: [PATCH 091/131] slurm_gres='gpu:a100:1' --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 0040d7bd..7d0efae9 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - gres='gpu:a100:1') + slurm_gres='gpu:a100:1') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From eda3c70687fbe8c1f0634bb4b72f6fc16f814f2b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:15:12 -0400 Subject: [PATCH 092/131] additional_parameters={"gres": "gpu:v100:1"} --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 7d0efae9..721abec1 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_gres='gpu:a100:1') + additional_parameters={"gres": "gpu:v100:1"}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From d2785d1db4d722ea3f3ce45ee7bc79e2ee17faf6 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:18:26 -0400 Subject: [PATCH 093/131] slurm_additional_parameters={"gres": "gpu:v100:1"} --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 721abec1..e9785399 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - additional_parameters={"gres": "gpu:v100:1"}) + slurm_additional_parameters={"gres": "gpu:v100:1"}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From d56f9ed17997c56202d4dde215c880be68fc91e8 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:23:16 -0400 Subject: [PATCH 094/131] gres='gpu:v100:1' and partition='gpu' --- evals/main_distributed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index e9785399..e4d58592 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -73,7 +73,7 @@ def checkpoint(self): def launch_evals_with_parsed_args( args_for_evals, submitit_folder, - partition='learnlab,learnfair', + partition='gpu', timeout="8:00:00", nodes=1, tasks_per_node=1, @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_parameters={"gres": "gpu:v100:1"}) + slurm_gres='gpu:v100:1') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 3c97dd764efe24d563ff77e0e9bab61ac73a0beb Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:25:46 -0400 Subject: [PATCH 095/131] slurm_additional_parameters={"--gres": "gpu:v100:1"} --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index e4d58592..bbdb5978 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_gres='gpu:v100:1') + slurm_additional_parameters={"--gres": "gpu:v100:1"}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 174b121cdab6d930b4b19bcb6610a71f359386f5 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:28:27 -0400 Subject: [PATCH 096/131] remove specify gpu type --- evals/main_distributed.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index bbdb5978..27fc9043 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -99,8 +99,7 @@ def launch_evals_with_parsed_args( gpus_per_node=1, slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', - slurm_job_name='model-jepa2', - slurm_additional_parameters={"--gres": "gpu:v100:1"}) + slurm_job_name='model-jepa2') if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From fcc1e971d41c5afea0131dff3e250c9d50d4621c Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:35:19 -0400 Subject: [PATCH 097/131] timeout="48:00:00" --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 27fc9043..07661625 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -74,7 +74,7 @@ def launch_evals_with_parsed_args( args_for_evals, submitit_folder, partition='gpu', - timeout="8:00:00", + timeout="48:00:00", nodes=1, tasks_per_node=1, delay_seconds=10, From 06881022076362358af3599a5342f8f29f786640 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:38:50 -0400 Subject: [PATCH 098/131] partition='a100_2', --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 07661625..9a566555 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -73,7 +73,7 @@ def checkpoint(self): def launch_evals_with_parsed_args( args_for_evals, submitit_folder, - partition='gpu', + partition='a100_2', timeout="48:00:00", nodes=1, tasks_per_node=1, From 2e38d8c593e723a6b3b1f7d73c66fe8821629501 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:47:54 -0400 Subject: [PATCH 099/131] slurm_additional_parameters={'gres': 'gpu:a100:1'} --- evals/main_distributed.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 9a566555..e5a47f35 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -99,7 +99,8 @@ def launch_evals_with_parsed_args( gpus_per_node=1, slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', - slurm_job_name='model-jepa2') + slurm_job_name='model-jepa2', + slurm_additional_parameters={'gres': 'gpu:a100:1'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From e61f5d68d16e13916ad0b107355ba78fb20490b7 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:53:47 -0400 Subject: [PATCH 100/131] slurm_additional_parameters={'--gres': 'gpu:a100:1'}) --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index e5a47f35..c8f45190 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_parameters={'gres': 'gpu:a100:1'}) + slurm_additional_parameters={'--gres': 'gpu:a100:1'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 95d79632aa7fec9b64ba504151a45605b7a6cb97 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:56:08 -0400 Subject: [PATCH 101/131] slurm_additional_parameters={'gres': 'gpu:a100:1'}) --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index c8f45190..e5a47f35 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_parameters={'--gres': 'gpu:a100:1'}) + slurm_additional_parameters={'gres': 'gpu:a100:1'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 40c9f4ec9cfd1b6da65f68d369ee220dae24d082 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:09:46 -0400 Subject: [PATCH 102/131] slurm_additional_parameters={'gres': 'gpu:a100:1(S:0-1)'}) --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index e5a47f35..2cb31b39 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_parameters={'gres': 'gpu:a100:1'}) + slurm_additional_parameters={'gres': 'gpu:a100:1(S:0-1)'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 8c0f56da69cebed5f34993bf9f0e80e6b25fd3dc Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:11:47 -0400 Subject: [PATCH 103/131] Update main_distributed.py --- evals/main_distributed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 2cb31b39..e5a47f35 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -100,7 +100,7 @@ def launch_evals_with_parsed_args( slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', slurm_job_name='model-jepa2', - slurm_additional_parameters={'gres': 'gpu:a100:1(S:0-1)'}) + slurm_additional_parameters={'gres': 'gpu:a100:1'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 63bacf9ff1e00146b32ef5e8df7d1c91eb078c44 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:15:47 -0400 Subject: [PATCH 104/131] comment out partition --- evals/main_distributed.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index e5a47f35..780e4f08 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -73,7 +73,7 @@ def checkpoint(self): def launch_evals_with_parsed_args( args_for_evals, submitit_folder, - partition='a100_2', + # partition='a100_2', timeout="48:00:00", nodes=1, tasks_per_node=1, @@ -90,7 +90,7 @@ def launch_evals_with_parsed_args( folder=os.path.join(submitit_folder, 'job_%j'), slurm_max_num_timeout=20) executor.update_parameters( - slurm_partition=partition, + # slurm_partition=partition, slurm_mem='128G', timeout_min=timeout, nodes=nodes, @@ -153,7 +153,7 @@ def launch_evals(): launch_evals_with_parsed_args( args_for_evals=configs, submitit_folder=args.folder, - partition=args.partition, + # partition=args.partition, timeout=args.time, nodes=nodes, tasks_per_node=tasks_per_node, From 8cfb1f1312092aed77246aaeb24c4dff32ea84d8 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:36:21 -0400 Subject: [PATCH 105/131] sigmoid_outputs --- evals/video_classification_frozen/pegs_eval.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 3e17cde5..34ce26af 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -357,8 +357,10 @@ def run_one_epoch( # print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) - # plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') - # plot_guess_img(labels[0], output_filename = 'labels-0.png') + + sigmoid_outputs = torch.nn.Sigmoid(outputs) + plot_guess_img(sigmoid_outputs[0][0,:], output_filename = 'outputs-0.png') + plot_guess_img(labels[0], output_filename = 'labels-0.png') # print("PRINT outputs[0][0:]", outputs[0][0:]) # print("PRINT 'labels[0]",labels[0]) From 2d71e62c74dbab5cf31f5277739395a0d22ea535 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:41:01 -0400 Subject: [PATCH 106/131] save in checkpoint-models folder instead of ki2130/video_classification_frozen --- evals/video_classification_frozen/pegs_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 34ce26af..77d11f8b 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -135,7 +135,7 @@ def main(args_eval, resume_preempt=False): logger.info(f'Initialized (rank/world-size) {rank}/{world_size}') # -- log/checkpointing paths - folder = os.path.join(pretrain_folder, 'video_classification_frozen/') + folder = os.path.join(pretrain_folder, 'my-jepa/jepa/' , 'checkpoint-models/') if eval_tag is not None: folder = os.path.join(folder, eval_tag) if not os.path.exists(folder): From 95ca2bd1b1641ebaefadf0396c3afa83b58f03c3 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:43:25 -0400 Subject: [PATCH 107/131] save to plots folder --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 3a249786..acba93aa 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -25,5 +25,5 @@ def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_cla sizes.append(input_tensor[idx].item() * scale) plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) - plt.savefig(output_filename, bbox_inches='tight', pad_inches=0) + plt.savefig(os.path.join('plots/', output_filename), bbox_inches='tight', pad_inches=0) plt.close() From 2390a570c7b10106c37c8362fec64e14c4f1de8b Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:44:33 -0400 Subject: [PATCH 108/131] 10 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 313a5cc3..75704433 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 500 + num_epochs: 10 resolution: 224 batch_size: 4 weight_decay: 0.01 From b8ee4111746942f1e86b286be54712bedc8a9db2 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:46:32 -0400 Subject: [PATCH 109/131] change tag to pegs-probe --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 75704433..1207c298 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -1,7 +1,7 @@ nodes: 1 tasks_per_node: 1 -tag: k400-16x8x3 +tag: pegs-probe eval_name: video_classification_frozen resume_checkpoint: false data: From cc921705728b0abb613cbc9e7f453720eaa3479a Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:52:48 -0400 Subject: [PATCH 110/131] comment out gpu a100 specification for now --- evals/main_distributed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/main_distributed.py b/evals/main_distributed.py index 780e4f08..389cf8f6 100644 --- a/evals/main_distributed.py +++ b/evals/main_distributed.py @@ -99,8 +99,8 @@ def launch_evals_with_parsed_args( gpus_per_node=1, slurm_mail_type='ALL', slurm_mail_user='ki2130@nyu.edu', - slurm_job_name='model-jepa2', - slurm_additional_parameters={'gres': 'gpu:a100:1'}) + slurm_job_name='model-jepa2') + # slurm_additional_parameters={'gres': 'gpu:a100:1'}) if exclude_nodes is not None: executor.update_parameters(slurm_exclude=exclude_nodes) From 79df9a499864f4aa7cdcb29be417d0feccc3a8e7 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:12:33 -0400 Subject: [PATCH 111/131] Create a sigmoid activation function object --- evals/video_classification_frozen/pegs_eval.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 77d11f8b..42348bb5 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -358,7 +358,8 @@ def run_one_epoch( # save output and label as images (comment this out when done testing) - sigmoid_outputs = torch.nn.Sigmoid(outputs) + sigmoid = torch.nn.Sigmoid() + sigmoid_outputs = sigmoid(outputs) plot_guess_img(sigmoid_outputs[0][0,:], output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') From 35198973e1e38612ec6a9e16f77ada119dfaca6e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:20:38 -0400 Subject: [PATCH 112/131] sigmoid_outputs on tensor part not list --- evals/video_classification_frozen/pegs_eval.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 42348bb5..1e2d6f66 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -357,10 +357,11 @@ def run_one_epoch( # print("labels[0] final shape:", labels[0].shape) # save output and label as images (comment this out when done testing) + # plot_guess_img(outputs[0][0,:], output_filename = 'outputs-0.png') sigmoid = torch.nn.Sigmoid() - sigmoid_outputs = sigmoid(outputs) - plot_guess_img(sigmoid_outputs[0][0,:], output_filename = 'outputs-0.png') + sigmoid_outputs = sigmoid(outputs[0][0,:]) + plot_guess_img(sigmoid_outputs, output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') # print("PRINT outputs[0][0:]", outputs[0][0:]) From 3204299e3bc84b4ff3f07109cd14bfd46f2dd5d3 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:21:10 -0400 Subject: [PATCH 113/131] 3 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 1207c298..52cc6c7f 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 10 + num_epochs: 3 resolution: 224 batch_size: 4 weight_decay: 0.01 From 30435c5e0f26f4acc3704e38d7024463c37075b6 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:38:27 -0400 Subject: [PATCH 114/131] print sigmoid outputs shape --- evals/video_classification_frozen/pegs_eval.py | 1 + 1 file changed, 1 insertion(+) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 1e2d6f66..83cae7ad 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -361,6 +361,7 @@ def run_one_epoch( sigmoid = torch.nn.Sigmoid() sigmoid_outputs = sigmoid(outputs[0][0,:]) + print("sigmoud_outputs shape:", sigmoid_outputs.shape) plot_guess_img(sigmoid_outputs, output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') From 753cf8401510f32900c7e3d917b4b22e13caf74e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:44:15 -0400 Subject: [PATCH 115/131] print sigmoid_outputs --- evals/video_classification_frozen/pegs_eval.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 83cae7ad..1db4d893 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -361,7 +361,8 @@ def run_one_epoch( sigmoid = torch.nn.Sigmoid() sigmoid_outputs = sigmoid(outputs[0][0,:]) - print("sigmoud_outputs shape:", sigmoid_outputs.shape) + print("sigmoid outouts:", sigmoid_outputs) + print("sigmoid_outputs shape:", sigmoid_outputs.shape) plot_guess_img(sigmoid_outputs, output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') From 513c9c061c480a1ded9aec87afbe64bce6d3b741 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:54:44 -0400 Subject: [PATCH 116/131] input_tensor[0,idx] --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index acba93aa..d83aff93 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -22,7 +22,7 @@ def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_cla y = start_y + row * spacing scatter_x.append(x) scatter_y.append(y) - sizes.append(input_tensor[idx].item() * scale) + sizes.append(input_tensor[0,idx].item() * scale) plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) plt.savefig(os.path.join('plots/', output_filename), bbox_inches='tight', pad_inches=0) From 97c90b58e804ef5da8b1be87d1869bb74accc6ef Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:59:50 -0400 Subject: [PATCH 117/131] import os --- evals/video_classification_frozen/kp_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index d83aff93..bd85d361 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -1,3 +1,4 @@ +import os import matplotlib.pyplot as plt from PIL import Image From c6be8220d813670d50ca64dd6810f99d61124248 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:06:50 -0400 Subject: [PATCH 118/131] input_tensor[idx] --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index bd85d361..24591197 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -23,7 +23,7 @@ def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_cla y = start_y + row * spacing scatter_x.append(x) scatter_y.append(y) - sizes.append(input_tensor[0,idx].item() * scale) + sizes.append(input_tensor[idx].item() * scale) plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) plt.savefig(os.path.join('plots/', output_filename), bbox_inches='tight', pad_inches=0) From 464ec724c2c03aa570407b0a7e44e9e96ab8c461 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:08:02 -0400 Subject: [PATCH 119/131] sigmoid_outputs.squeeze(0) --- evals/video_classification_frozen/pegs_eval.py | 1 + 1 file changed, 1 insertion(+) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 1db4d893..9a043ecc 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -361,6 +361,7 @@ def run_one_epoch( sigmoid = torch.nn.Sigmoid() sigmoid_outputs = sigmoid(outputs[0][0,:]) + sigmoid_outputs = sigmoid_outputs.squeeze(0) print("sigmoid outouts:", sigmoid_outputs) print("sigmoid_outputs shape:", sigmoid_outputs.shape) plot_guess_img(sigmoid_outputs, output_filename = 'outputs-0.png') From e2e06f62dd6c7af39da6b06f9997ff64bfe25020 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:48:22 -0400 Subject: [PATCH 120/131] scale=500 instead of 150 --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 24591197..8fb969fc 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -2,7 +2,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=150): +def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=500): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From 9da3f7b1177716b371c62869a6d97dddca611756 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:54:07 -0400 Subject: [PATCH 121/131] scale=1000 --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 8fb969fc..f3b8fbee 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -2,7 +2,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=500): +def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=1000): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From 32c6d1a94212b70e76cb745b48e0f768b34e0733 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:58:07 -0400 Subject: [PATCH 122/131] scale=2000 --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index f3b8fbee..948f76ad 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -2,7 +2,7 @@ import matplotlib.pyplot as plt from PIL import Image -def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=1000): +def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_classification_frozen/reference_with_border.png', scale=2000): assert input_tensor.numel() == 165, "input tensor must have exactly 165 entries" background = Image.open(reference_img) From 5de24d665e0fccaf9979377ddf05223e32606e56 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:07:31 -0400 Subject: [PATCH 123/131] comment out min/max of encoded tensor --- src/models/vision_transformer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/vision_transformer.py b/src/models/vision_transformer.py index 901f5e2d..c85b150e 100644 --- a/src/models/vision_transformer.py +++ b/src/models/vision_transformer.py @@ -192,8 +192,8 @@ def forward(self, x, masks=None): if self.norm is not None: x = self.norm(x) print("shape of encoder:", x.shape) - print("min of encoded", torch.min(x)) - print("max of encoded", torch.max(x)) + # print("min of encoded", torch.min(x)) + # print("max of encoded", torch.max(x)) return x def interpolate_pos_encoding(self, x, pos_embed): From 4c01cc847be1e71dc19eddf247d6f5af0148fb83 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:08:11 -0400 Subject: [PATCH 124/131] comment out print sigmoid_outputs --- evals/video_classification_frozen/pegs_eval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 9a043ecc..1ee487e9 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -362,8 +362,8 @@ def run_one_epoch( sigmoid = torch.nn.Sigmoid() sigmoid_outputs = sigmoid(outputs[0][0,:]) sigmoid_outputs = sigmoid_outputs.squeeze(0) - print("sigmoid outouts:", sigmoid_outputs) - print("sigmoid_outputs shape:", sigmoid_outputs.shape) + # print("sigmoid outouts:", sigmoid_outputs) + # print("sigmoid_outputs shape:", sigmoid_outputs.shape) plot_guess_img(sigmoid_outputs, output_filename = 'outputs-0.png') plot_guess_img(labels[0], output_filename = 'labels-0.png') From 02f3f66f6cb2039f8cbca19a1414f1e389c1f4f1 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:08:34 -0400 Subject: [PATCH 125/131] 500 epochs --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 52cc6c7f..41ce905f 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 3 + num_epochs: 500 resolution: 224 batch_size: 4 weight_decay: 0.01 From bffc9a9a2db64e3c168bc57700d413d4b6a23a3d Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:09:02 -0400 Subject: [PATCH 126/131] pegs-probe-500 --- configs/evals/vitl16_k400_16x8x3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 41ce905f..4d74a3c9 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -1,7 +1,7 @@ nodes: 1 tasks_per_node: 1 -tag: pegs-probe +tag: pegs-probe-500 eval_name: video_classification_frozen resume_checkpoint: false data: From ba4a3a2000385381833e7636d7f218bbf6496f86 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:10:10 -0400 Subject: [PATCH 127/131] epochs 300, pegs-probe-300 --- configs/evals/vitl16_k400_16x8x3.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/evals/vitl16_k400_16x8x3.yaml b/configs/evals/vitl16_k400_16x8x3.yaml index 4d74a3c9..0bf44071 100644 --- a/configs/evals/vitl16_k400_16x8x3.yaml +++ b/configs/evals/vitl16_k400_16x8x3.yaml @@ -1,7 +1,7 @@ nodes: 1 tasks_per_node: 1 -tag: pegs-probe-500 +tag: pegs-probe-300 eval_name: video_classification_frozen resume_checkpoint: false data: @@ -15,7 +15,7 @@ data: frame_step: 4 optimization: attend_across_segments: true - num_epochs: 500 + num_epochs: 300 resolution: 224 batch_size: 4 weight_decay: 0.01 From d542e575558c8a257c3b49af2d11328fc14c2fa0 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:12:49 -0400 Subject: [PATCH 128/131] add subfolder plots-300 --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index 948f76ad..e4d3a066 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -26,5 +26,5 @@ def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_cla sizes.append(input_tensor[idx].item() * scale) plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) - plt.savefig(os.path.join('plots/', output_filename), bbox_inches='tight', pad_inches=0) + plt.savefig(os.path.join('plots/plots-300', output_filename), bbox_inches='tight', pad_inches=0) plt.close() From 203e17b8d2fed68e4c84110bde681026e3e23f94 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:13:20 -0400 Subject: [PATCH 129/131] plots-300/ --- evals/video_classification_frozen/kp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/video_classification_frozen/kp_utils.py b/evals/video_classification_frozen/kp_utils.py index e4d3a066..21dcd118 100644 --- a/evals/video_classification_frozen/kp_utils.py +++ b/evals/video_classification_frozen/kp_utils.py @@ -26,5 +26,5 @@ def plot_guess_img(input_tensor, output_filename, reference_img='evals/video_cla sizes.append(input_tensor[idx].item() * scale) plt.scatter(scatter_x, scatter_y, s=sizes, c='green', alpha=0.4) - plt.savefig(os.path.join('plots/plots-300', output_filename), bbox_inches='tight', pad_inches=0) + plt.savefig(os.path.join('plots/plots-300/', output_filename), bbox_inches='tight', pad_inches=0) plt.close() From 875218ce0ea325758b29b1c4b2d91c9fc42e0d7e Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:19:12 -0400 Subject: [PATCH 130/131] take out code you don't need from run_one_epoch --- .../video_classification_frozen/pegs_eval.py | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 1ee487e9..31f94ea3 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -394,42 +394,6 @@ def run_one_epoch( # print("PRINT length labels", len(labels)) sum_softmax += F.softmax(outputs[0][i,:], dim=0) # no averaging (dividing by len(outputs)) outputs = sum_softmax - - # outputs = sum([F.softmax(o, dim=1) for o in outputs]) / len(outputs) - # kat - # try: - # print("outputs attend no grad:", len(outputs)) - # except: - # "not a list" - # try: - # print("outputs attend no grad:", outputs.shape) - # except: - # "not a tensor" - # else: - # outputs = sum([sum([F.softmax(ost, dim=1) for ost in os]) for os in outputs]) / len(outputs) / len(outputs[0]) - #kat - # # Initialize variables for correct predictions - # correct_count = 0 - # # Iterate over each row (i) in outputs[0] - # for i in range(len(labels)): - # # Get the ith row of outputs[0] and compute the maximum index - # row_outputs = outputs[0][i, :] - # max_index = torch.argmax(row_outputs) - # # Compare the maximum index with the corresponding label - # if max_index == labels[i]: - # correct_count += 1 - # # Calculate top-1 accuracy - # top1_acc = (100. * correct_count) / batch_size - - # kat - # acc_list = [] - # for i in range(len(labels)): - # value_acc = outputs[0][i,:].indices.eq(labels) - # acc_list.append(value_acc) - - # top1_acc = 100. * outputs.max(dim=1).indices.eq(labels).sum() / batch_size - # top1_acc = float(AllReduce.apply(top1_acc)) - # top1_meter.update(top1_acc) if training: if use_bfloat16: @@ -448,13 +412,8 @@ def run_one_epoch( logger.info('[%5d] (loss: %.3f) [mem: %.2e]' % (itr, loss, torch.cuda.max_memory_allocated() / 1024.**2)) - # if itr % 20 == 0: - # logger.info('[%5d] %.3f%% (loss: %.3f) [mem: %.2e]' - # % (itr, top1_meter.avg, loss, - # torch.cuda.max_memory_allocated() / 1024.**2)) return loss - # return top1_meter.avg From 6dffc08c3715f5bda18f43473c11541677120552 Mon Sep 17 00:00:00 2001 From: Kat Inchoco <88949861+kpinchoco@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:33:50 -0400 Subject: [PATCH 131/131] add code to track train/test loss --- .../video_classification_frozen/pegs_eval.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/evals/video_classification_frozen/pegs_eval.py b/evals/video_classification_frozen/pegs_eval.py index 31f94ea3..f48749e2 100644 --- a/evals/video_classification_frozen/pegs_eval.py +++ b/evals/video_classification_frozen/pegs_eval.py @@ -272,7 +272,8 @@ def save_checkpoint(epoch): scheduler=scheduler, wd_scheduler=wd_scheduler, data_loader=train_loader, - use_bfloat16=use_bfloat16) + use_bfloat16=use_bfloat16, + training_losses) # Pass the training_losses array val_acc = run_one_epoch( device=device, @@ -287,14 +288,22 @@ def save_checkpoint(epoch): scheduler=scheduler, wd_scheduler=wd_scheduler, data_loader=val_loader, - use_bfloat16=use_bfloat16) + use_bfloat16=use_bfloat16, + testing_losses) # Pass the testing_losses array logger.info('[%5d] train: %.3f test: %.3f' % (epoch + 1, train_acc, val_acc)) # logger.info('[%5d] train: %.3f%% test: %.3f%%' % (epoch + 1, train_acc, val_acc)) if rank == 0: csv_logger.log(epoch + 1, train_acc, val_acc) save_checkpoint(epoch + 1) + + # Save the numpy arrays after all epochs + np.save('training_losses.npy', training_losses) + np.save('testing_losses.npy', testing_losses) +# Initialize numpy arrays outside the function to store losses across all epochs +training_losses = np.array([]) +testing_losses = np.array([]) def run_one_epoch( device, @@ -310,6 +319,7 @@ def run_one_epoch( num_spatial_views, num_temporal_views, attend_across_segments, + loss_array, # add this to keep track of loss ): classifier.train(mode=training) @@ -408,12 +418,15 @@ def run_one_epoch( optimizer.step() optimizer.zero_grad() + # Append loss to the appropriate numpy array + loss_array = np.append(loss_array, loss.item()) + if itr % 20 == 0: logger.info('[%5d] (loss: %.3f) [mem: %.2e]' % (itr, loss, torch.cuda.max_memory_allocated() / 1024.**2)) - return loss + return loss_array