From d9c61d9ce3de7629ec53357800b3af16902ce347 Mon Sep 17 00:00:00 2001
From: Mozzie <mozzie@Mozzies-MacBook-Pro.local>
Date: Thu, 5 Dec 2019 12:45:47 +0000
Subject: [PATCH] commit

---
 .DS_Store                                     | Bin 0 -> 8196 bytes
 .idea/Task_likelihood.iml                     |  11 +
 .../inspectionProfiles/profiles_settings.xml  |   6 +
 .idea/misc.xml                                |   4 +
 .idea/modules.xml                             |   8 +
 .idea/workspace.xml                           |  88 +++++++
 __pycache__/configuration.cpython-36.pyc      | Bin 0 -> 219 bytes
 config/.DS_Store                              | Bin 0 -> 6148 bytes
 config/__init__.py                            |   0
 config/__pycache__/__init__.cpython-36 2.pyc  | Bin 0 -> 148 bytes
 config/__pycache__/__init__.cpython-36.pyc    | Bin 0 -> 135 bytes
 config/__pycache__/config.cpython-36.pyc      | Bin 0 -> 5969 bytes
 config/config.py                              | 239 ++++++++++++++++++
 config/configuration/default.ini              |  30 +++
 config/configuration/test.ini                 |  35 +++
 configuration.py                              |   3 +
 learn_consistent.py                           | 107 ++++++++
 results/.DS_Store                             | Bin 0 -> 6148 bytes
 results/mnist/result.png                      | Bin 0 -> 42525 bytes
 utils/.DS_Store                               | Bin 0 -> 6148 bytes
 utils/__init__.py                             |   0
 utils/__pycache__/__init__.cpython-36 2.pyc   | Bin 0 -> 147 bytes
 utils/__pycache__/__init__.cpython-36.pyc     | Bin 0 -> 134 bytes
 utils/__pycache__/__init__.cpython-37.pyc     | Bin 0 -> 138 bytes
 utils/__pycache__/data_utils.cpython-36.pyc   | Bin 0 -> 2258 bytes
 utils/__pycache__/dataloader.cpython-36.pyc   | Bin 0 -> 6016 bytes
 utils/__pycache__/dataloader.cpython-37.pyc   | Bin 0 -> 5267 bytes
 utils/__pycache__/ewc_utils.cpython-36.pyc    | Bin 0 -> 2170 bytes
 utils/__pycache__/fig2grid.cpython-36.pyc     | Bin 0 -> 2404 bytes
 utils/__pycache__/layers.cpython-36.pyc       | Bin 0 -> 2386 bytes
 utils/__pycache__/load_data.cpython-36.pyc    | Bin 0 -> 3906 bytes
 utils/__pycache__/load_data.cpython-37.pyc    | Bin 0 -> 3063 bytes
 utils/__pycache__/model_utils.cpython-36.pyc  | Bin 0 -> 890 bytes
 .../__pycache__/predict_utils.cpython-36.pyc  | Bin 0 -> 2195 bytes
 utils/__pycache__/train_utils.cpython-36.pyc  | Bin 0 -> 574 bytes
 utils/__pycache__/utils.cpython-36 2.pyc      | Bin 0 -> 365 bytes
 utils/__pycache__/utils.cpython-36.pyc        | Bin 0 -> 352 bytes
 utils/data_utils.py                           | 133 ++++++++++
 utils/dataloader.py                           | 193 ++++++++++++++
 utils/layers.py                               |  59 +++++
 utils/load_data.py                            | 164 ++++++++++++
 utils/model_utils.py                          |  17 ++
 utils/predict_utils.py                        |  69 +++++
 utils/train_utils.py                          |   9 +
 utils/utils.py                                |   8 +
 45 files changed, 1183 insertions(+)
 create mode 100644 .DS_Store
 create mode 100644 .idea/Task_likelihood.iml
 create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
 create mode 100644 .idea/misc.xml
 create mode 100644 .idea/modules.xml
 create mode 100644 .idea/workspace.xml
 create mode 100644 __pycache__/configuration.cpython-36.pyc
 create mode 100644 config/.DS_Store
 create mode 100644 config/__init__.py
 create mode 100644 config/__pycache__/__init__.cpython-36 2.pyc
 create mode 100644 config/__pycache__/__init__.cpython-36.pyc
 create mode 100644 config/__pycache__/config.cpython-36.pyc
 create mode 100644 config/config.py
 create mode 100644 config/configuration/default.ini
 create mode 100644 config/configuration/test.ini
 create mode 100644 configuration.py
 create mode 100644 learn_consistent.py
 create mode 100644 results/.DS_Store
 create mode 100644 results/mnist/result.png
 create mode 100644 utils/.DS_Store
 create mode 100644 utils/__init__.py
 create mode 100644 utils/__pycache__/__init__.cpython-36 2.pyc
 create mode 100644 utils/__pycache__/__init__.cpython-36.pyc
 create mode 100644 utils/__pycache__/__init__.cpython-37.pyc
 create mode 100644 utils/__pycache__/data_utils.cpython-36.pyc
 create mode 100644 utils/__pycache__/dataloader.cpython-36.pyc
 create mode 100644 utils/__pycache__/dataloader.cpython-37.pyc
 create mode 100644 utils/__pycache__/ewc_utils.cpython-36.pyc
 create mode 100644 utils/__pycache__/fig2grid.cpython-36.pyc
 create mode 100644 utils/__pycache__/layers.cpython-36.pyc
 create mode 100644 utils/__pycache__/load_data.cpython-36.pyc
 create mode 100644 utils/__pycache__/load_data.cpython-37.pyc
 create mode 100644 utils/__pycache__/model_utils.cpython-36.pyc
 create mode 100644 utils/__pycache__/predict_utils.cpython-36.pyc
 create mode 100644 utils/__pycache__/train_utils.cpython-36.pyc
 create mode 100644 utils/__pycache__/utils.cpython-36 2.pyc
 create mode 100644 utils/__pycache__/utils.cpython-36.pyc
 create mode 100644 utils/data_utils.py
 create mode 100644 utils/dataloader.py
 create mode 100644 utils/layers.py
 create mode 100644 utils/load_data.py
 create mode 100644 utils/model_utils.py
 create mode 100644 utils/predict_utils.py
 create mode 100644 utils/train_utils.py
 create mode 100644 utils/utils.py

diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..234705ab46fef7234934e29ad3a9f93206bf8bd2
GIT binary patch
literal 8196
zcmeHMO=}ZD7=EWs(oIS+MWH$FMeq<LA#D>VLX7dyTVX{HRnpCe$--tgWH*KyBf0n^
z^eloW|9}^df_Hz2XVGUqjGIjqp&)_Gz|1q5dEXi4d1iO^oe&YLjoL+`91$7F9J9M9
zRwUlf^HSPUE&D(Qf1(!I$UW*%W64@KXa+O`ngPv#W<WEr4h-PT=E?ZOxi5QlsTt4=
zY$OBx{a_+<tSX#I6t4~xA_M>?&@2+_hy#R=sj#YWCQ-OzOc^~e<;qlu!K6F-O>PdX
zDx67_?!=@!F*P$&5egHt!_O4v#Htc?sTt4=EHl7k_gzHm4I0qpLj2x1b^TV;^_#HZ
z57i0stsf$xMwEiJPaZubhq^J__kXi(j)Q?3_j7aLIzd<{d}UkPiDYWWFfvAFFZ0Ce
z`C}`z!%<MPhv)p)nH~0;s{X+D-Fe+^K6E<cM)t-%-wSQW>kNgn)9%3J@gv7;`{SBF
z^4ftI$C4d}kv7teY;H0+Dp&Gmsd6~Yo0D?6kT(xY$J1%rIJjB7b9&Lgd_H+Gefe4}
znV5R}&^7scUcNzXfskj`&~tsSi+1jljgmzp8sefP1aX|e+noAE0@*kCM9IERE-qDU
z_<4{@5+A@nz$hKGg{wvplD&&awgdkTd`1{8q#!ouL2S;L^_t06Dj!3t;_;Pbi!Iab
z7Oj@wAAk&^@B1H7#w_}Ny{`5zKXlGhUq0PkW!3%%t3mJgY%F<(VdAsJHqsvC8$dn>
z0yd}*>3MC%7NWNp>qA8RBxL7X&Rr7z6)dBhEn>N5qE|{s{8=qtS@g&fV+3;vbkYoL
z00Y}{jX56w-^UrH?*TSIbiG8)K#T#Fs9W_K8h?G=#`;C5Zldu*b#S{GGElgn5aBpb
lgyX>ZABL!#Fy)3-g)@n0LHhp}0sLECpZ|h<U2H4^KLM*<WJ~}6

literal 0
HcmV?d00001

diff --git a/.idea/Task_likelihood.iml b/.idea/Task_likelihood.iml
new file mode 100644
index 0000000..5c88ce7
--- /dev/null
+++ b/.idea/Task_likelihood.iml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.6 (tensorflow)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="TestRunnerService">
+    <option name="PROJECT_TEST_RUNNER" value="Unittests" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..281715b
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (tensorflow)" project-jdk-type="Python SDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..02cd9d3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/Task_likelihood.iml" filepath="$PROJECT_DIR$/.idea/Task_likelihood.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..c557f00
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="99550bc5-aa3b-44b3-94d7-b84afc45844f" name="Default Changelist" comment="" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ProjectId" id="1UWaMsw6zBMWl6bWHnCTXed0kq5" />
+  <component name="PropertiesComponent">
+    <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="RunManager" selected="Python.learn_consistent">
+    <configuration name="learn_consistent" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <module name="Task_likelihood" />
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/learn_consistent.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="true" />
+      <option name="EMULATE_TERMINAL" value="false" />
+      <option name="MODULE_MODE" value="false" />
+      <option name="REDIRECT_INPUT" value="false" />
+      <option name="INPUT_FILE" value="" />
+      <method v="2" />
+    </configuration>
+    <configuration name="split_mnit" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <module name="Task_likelihood" />
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/split_mnit.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="true" />
+      <option name="EMULATE_TERMINAL" value="false" />
+      <option name="MODULE_MODE" value="false" />
+      <option name="REDIRECT_INPUT" value="false" />
+      <option name="INPUT_FILE" value="" />
+      <method v="2" />
+    </configuration>
+    <list>
+      <item itemvalue="Python.learn_consistent" />
+      <item itemvalue="Python.split_mnit" />
+    </list>
+    <recent_temporary>
+      <list>
+        <item itemvalue="Python.learn_consistent" />
+        <item itemvalue="Python.split_mnit" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="99550bc5-aa3b-44b3-94d7-b84afc45844f" name="Default Changelist" comment="" />
+      <created>1575474759490</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1575474759490</updated>
+    </task>
+    <servers />
+  </component>
+</project>
\ No newline at end of file
diff --git a/__pycache__/configuration.cpython-36.pyc b/__pycache__/configuration.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19216a8cfb866d94afa95a5ae329a4cf9ee47f4d
GIT binary patch
literal 219
zcmXr!<>e~PVv4n4U|@I*#Bjg_WH|tFu>_DvVMt-jVaR2SVq|1UWlUjeW{hG=VGd@{
zWO)gcWzb~2#pax!mzJ4c#Zi)4T%wnmm+7a;e2X_3ET{*eia<u*VgYehG8C}_Ibh<K
zlYVG%YEiL%Zhlo&W~#nRYH@Z+et~{+eoCsoduB;SX_9_OVsUnSPG)v$PG&}aehN?y
iWLarZVo7Fxo?b!aEe@O9{FKt1R69nXvBe;Zc$fe<x;ifa

literal 0
HcmV?d00001

diff --git a/config/.DS_Store b/config/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..dfe7ddb0f400bab31a43a8171599dc31c8e62b48
GIT binary patch
literal 6148
zcmeHK&2AGh5FV$Y^`@%G0jWLug2W+0sai;-3TYL}p*N&OZ~&C<HlbN*Sx3o+D5ODq
z;UVA+cod$1$ANEbry>b|Cxoac8h^9i`8@LH&3a8lqCM{J6V-`G!Wk<8njaY7XJ505
z>)8YfGe$}Ub@01OgSBkm@h>XCYqxFIETx>jU%%;Trq7d1C&=K(;~0MDt1(0i)_|sT
zPBFYsJsxL;^=X9_AXB5#E7ZC$&&f(1vAe?9Sz?T7h-wAc7-hMZc>m|jWHK7KxqVIs
zSvo43%`c*|QN6LbC1p+4c4{x9zMe!yT#QHUc=(*J9>+yLaq$zav#U5xo~FG?r+(|9
z&WkwBdqYD`yFH}5c$Vf}J!$K4-W{27B6~y1Kn9)q-fVWSb<|J?M~Cx<nzdTZhB`dB
zKc5G3_xApS)3evpx3kOnyAPNiOyI9(?54v7d_?dIvED?(Jk$9FvKAvOm>#_XUV&?;
zfO`$d?Q1u4KVh$cSKxOF@cTi*8AFGqMf2)FV~zm8D!Pp!=8r|@D2JiL(jxA_grx#4
zRk$ODuyph*mlrxLEm}GWclZ#lvT!F9VX9+%WztE67Jcg#@Cqy|uwgIjy#GJ?`T2jD
z<gdH}UV;Bg0Z~1PPTH7~+gsNr$9t`UpTXHUue5kYL14CG<nmU$2RDX(#Q`vMSXx96
Q%zp?N8GPdv_^S$h1B~L2Gynhq

literal 0
HcmV?d00001

diff --git a/config/__init__.py b/config/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/config/__pycache__/__init__.cpython-36 2.pyc b/config/__pycache__/__init__.cpython-36 2.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..80b40a74486b624b66b76f86b2fa786eb7bb621c
GIT binary patch
literal 148
zcmXr!<>iul!Vt><1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFGu~*;?$yI{oMSj
zs?1b<m(=3ylKcYw<ouLW{er}T)FORnA3yzql(cvVFF8LiEi+v|K0Y%qvm`!Vub}c4
ThfQvNN@-529mwcnAZ7pnlSw2)

literal 0
HcmV?d00001

diff --git a/config/__pycache__/__init__.cpython-36.pyc b/config/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..28b47b6d3af461c0305ac294cb553cdfc58de179
GIT binary patch
literal 135
zcmXr!<>iul!Vt><1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFBARH;?$yI{hZ8<
z{Jiv>%shRU)Z*-t`~rPvA3y!%{FGE6k(ZX4t{)$tnU`4-AFo$Xd5gm)H$SB`C)EyQ
JS}_na0065wA2k2~

literal 0
HcmV?d00001

diff --git a/config/__pycache__/config.cpython-36.pyc b/config/__pycache__/config.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2d7d4051f78e15cfb1f9dbe8d4b3efa5d00616b5
GIT binary patch
literal 5969
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
Ro!HxV8PU*Q2KE3S{2#I4)Pev2

literal 0
HcmV?d00001

diff --git a/config/config.py b/config/config.py
new file mode 100644
index 0000000..42f5529
--- /dev/null
+++ b/config/config.py
@@ -0,0 +1,239 @@
+import numpy as np
+import configparser
+"""
+Configuration Parser:
+
+	|- Task Setting: Describe the typel of task
+		|- task_type:
+			|- Baseline: load all the data at once
+			|- Sequential: load several tasks sequentially
+				|- _split: split the dataset
+				|- _permute: permute the dataset
+			|- OneShot (#TODO): load data for one shot training
+
+		######################## Sequential Split Only ##########################
+		|- num_tasks: how many tasks to be trained
+		|- task_labels: list. FOR SPLIT EXPERIMENTS ONLY.
+		#########################################################################
+
+		|- dataset_name:
+			|- mnist
+			|- cifar10
+			|- cifar100
+			|- ucr(#TODO)
+			|- text(#TODO)
+			|- object detection(#TODO)
+
+	|- Model Setting:
+		|- model_type: Model Type
+			|- NN : Conventional Neural Networks
+			|- BNN: Bayesian Neural Networks
+			|- CBLN: Continual Learning Bayesian Neural Networks
+			|- GANs(#TODO): Generative Adversarial Networks
+		|- model_archi: Model Architecture
+			|- MLP: Multilayer Perceptron
+			|- CNN: Convolutioanl Neural Networks
+			|- RNN (#TODO): Recurrent Neural Networks
+			|- RL (#TODO): Reinforcement Neural Networks
+		|- hidden_dim: mlp dim per layer
+		|- num_layers: number of mlp layers
+
+		######################## Convolutional Only ##########################
+		|- is_conv: use convolutional layers or not. False (Default). 
+		|- conv_hidden_dim: convolutional dim per layer
+		|- conv_num_layers: number of convolutional layers
+		|- num_filter
+		|- stride
+		######################################################################
+
+	|- Training Setting:
+		|- batch_size
+		|- num_epoch / num_iter
+		|- learning_rate
+		|- optimizer: which optimizer to use
+		|- enable_one_hot: True (Default)
+		|- multi_head: False (Default)
+		|- lam: balance the novel and learned knowledge
+		|- enable_iterator: use iterator or sample from data. False (Default)
+
+	|- Test Setting: to produce the uncertainty information
+		|- num_runs
+		|- num_experiment
+
+
+"""
+
+
+
+
+
+class Config(object):
+	def __init__(self,config_file=None):
+		base_path = './config/configuration/'
+		default_path = base_path + 'default.ini'
+		self.cfg = configparser.ConfigParser()
+		self.cfg.read(default_path)
+		if config_file is not None:
+			path = base_path + config_file
+			self.cfg.read(path)	
+
+	def read_list(self,input_str,dtype=np.int32):
+			
+		task_labels = []
+		count = -1
+		for i in input_str:
+			if i in [',',' ']:
+				pass
+			elif i is '|':
+				count += 1
+				task_labels.append([])
+			else:
+				task_labels[count].append(int(i))
+		return task_labels
+
+	def read_omniglot_labels(self):
+		return [range(10),range(10,20),range(20,30)]
+
+
+	######################## Task Setting ##########################
+	@property
+	def task_type(self):
+		return self.cfg.get('Task Setting', 'task_type')
+
+	@property
+	def num_tasks(self):
+		try:
+			return self.cfg.getint('Task Setting', 'num_tasks')
+		except configparser.NoOptionError:
+			return len(self.task_labels)
+
+	@property
+	def task_labels(self):
+		#return self.read_omniglot_labels()
+		return self.read_list(self.cfg.get('Task Setting', 'task_labels'))
+	
+	@property
+	def dataset_name(self):
+		return self.cfg.get('Task Setting', 'dataset_name')
+	
+	
+	######################## Model Setting ##########################
+	@property
+	def model_type(self):
+		return self.cfg.get('Model Setting', 'model_type')
+
+	@property
+	def model_archi(self):
+		return self.cfg.get('Model Setting', 'model_archi')
+
+	@property
+	def hidden_dim(self):
+		return self.cfg.getint('Model Setting', 'hidden_dim')
+
+	@property
+	def num_layers(self):
+		return self.cfg.getint('Model Setting', 'num_layers')
+
+	@property
+	def is_conv(self):
+		return self.cfg.getboolean('Model Setting', 'is_conv')
+
+	@property
+	def conv_hidden_dim(self):
+		return self.cfg.getint('Model Setting', 'conv_hidden_dim')
+
+	@property
+	def conv_num_layers(self):
+		return self.cfg.getint('Model Setting', 'conv_num_layers')
+
+	@property
+	def num_filter(self):
+		return self.cfg.getint('Model Setting', 'num_filter')
+
+	@property
+	def stride(self):
+		return self.cfg.getint('Model Setting', 'stride')
+
+
+	######################## Training Setting ##########################
+
+	@property
+	def batch_size(self):
+		return self.cfg.getint('Training Setting', 'batch_size')
+
+	@property
+	def num_epoch(self):
+		return self.cfg.getint('Training Setting', 'num_epoch')
+
+	@property
+	def display_frequency(self):
+		return self.cfg.getint('Training Setting', 'display_frequency')
+
+	@property
+	def num_iter(self):
+		try:
+			return int(self.num_epoch * self.num_samples / self.batch_size)
+		except configparser.NoOptionError:
+			return self.cfg.getint('Training Setting', 'num_iter')
+
+	@property
+	def learning_rate(self):
+		return self.cfg.getfloat('Training Setting', 'learning_rate')
+
+	@property
+	def optimizer(self):
+		return self.cfg.get('Training Setting', 'optimizer')
+
+	@property
+	def enable_one_hot(self):
+		return self.cfg.getboolean('Training Setting', 'enable_one_hot')
+
+	@property
+	def multi_head(self):
+		return self.cfg.getboolean('Training Setting', 'multi_head')
+
+	@property
+	def enable_iterator(self):
+		return self.cfg.getboolean('Training Setting', 'enable_iterator')
+
+	@property
+	def lam(self):
+		return self.cfg.getfloat('Training Setting', 'lam')
+	
+	
+	@property
+	def num_samples(self):
+		return self._num_samples
+
+	@num_samples.setter
+	def num_samples(self,value):
+		self._num_samples = value
+
+	@property
+	def num_classes(self):
+		return self._num_classes
+
+	@num_classes.setter
+	def num_classes(self,value):
+		self._num_classes = value
+
+	######################## Test Setting ##########################
+	@property
+	def num_runs(self):
+		return self.cfg.getint('Test Setting', 'num_runs')
+
+	@property
+	def num_experiment(self):
+		return self.cfg.getint('Test Setting', 'num_experiment')
+	
+
+	@property
+	def test_batch_size(self):
+		return self.cfg.getint('Test Setting', 'test_batch_size')
+
+
+	
+	
+	
+	
+	
diff --git a/config/configuration/default.ini b/config/configuration/default.ini
new file mode 100644
index 0000000..49cf187
--- /dev/null
+++ b/config/configuration/default.ini
@@ -0,0 +1,30 @@
+[Task Setting]
+# Baseline, Sequential_split, Sequential_permute, OneShot(#TODO)
+task_type = Sequential_split  
+
+task_labels = 0,1,2,3,4 | 5,6,7,8,9
+dataset_name = mnist 
+
+[Model Setting]
+model_type = CBLN
+model_archi = MLP
+
+hidden_dim = 200
+num_layers = 3
+
+is_conv = False
+
+[Training Setting]
+batch_size = 128
+display_frequency = 200
+learning_rate = 0.01
+optimizer = Adam
+enable_one_hot = True
+multi_head = False
+enable_iterator = False
+lam = 1.
+
+[Test Setting]
+num_runs = 200
+num_experiment = 200
+
diff --git a/config/configuration/test.ini b/config/configuration/test.ini
new file mode 100644
index 0000000..f6b6cc7
--- /dev/null
+++ b/config/configuration/test.ini
@@ -0,0 +1,35 @@
+[Task Setting]
+# Baseline, Sequential_split, Sequential_permute, OneShot(#TODO)
+task_type = Sequential_split  
+# num_tasks = 5
+# task_labels = |0|1|2|3|4|5|6|7|8|9
+# task_labels = |0,1|2,3|4,5|6,7|8,9
+# task_labels = |0,1,2,3,4|5,6,7,8,9
+# task_labels = |0,1|2,3|4,5|6,7|8,9
+# task_labels = |0,1,2,3,4,5,6,7,8,9
+# task_labels = |0,1,2|3,4,5|6,7|8,9
+task_labels = |0,1|2,3|4,5|6,7|8,9
+dataset_name = mnist
+
+[Model Setting]
+model_type = NN
+model_archi = MLP
+
+hidden_dim = 200
+num_layers = 4
+
+is_conv = False
+
+[Training Setting]
+batch_size = 128
+num_iter = 1000
+optimizer = Adam
+lam = 0.
+multi_head = False
+enable_one_hot = True
+
+[Test Setting]
+num_runs = 200
+num_experiment = 20
+test_batch_size = 10
+
diff --git a/configuration.py b/configuration.py
new file mode 100644
index 0000000..dcccb95
--- /dev/null
+++ b/configuration.py
@@ -0,0 +1,3 @@
+from config.config import Config
+
+conf = Config('test.ini')
diff --git a/learn_consistent.py b/learn_consistent.py
new file mode 100644
index 0000000..bd108f1
--- /dev/null
+++ b/learn_consistent.py
@@ -0,0 +1,107 @@
+from keras.models import Model
+from keras.layers import Dense, Input, Conv2D, Flatten, MaxPooling2D
+from configuration import conf
+from utils.dataloader import Sequential_loader
+import numpy as np
+from utils.model_utils import mask_layer_by_task
+from utils.layers import Probability_CLF_Mul_by_task
+from utils.train_utils import train_with_task
+from utils.predict_utils import get_task_likelihood, get_test_acc
+
+PATH = './results/%s/' % conf.dataset_name
+
+epochs = 50
+latent_dim = 250
+output_dim = 10
+verbose = 0
+
+data_loader = Sequential_loader()
+
+inputs = Input(shape=(784,))
+task_input = Input(shape=(5,))
+archi = Dense(1000, activation='relu')(inputs)
+archi = mask_layer_by_task(task_input, archi)
+archi = Dense(1000, activation='relu')(archi)
+archi = mask_layer_by_task(task_input, archi)
+
+task_output = Probability_CLF_Mul_by_task(conf.num_tasks, num_centers=output_dim // conf.num_tasks)(
+    [task_input, archi])
+task_output = mask_layer_by_task(task_input, task_output, 'task_out')
+clf = Dense(output_dim, activation='softmax')(archi)
+clf = mask_layer_by_task(task_input, clf, 'clf_out')
+model = Model(inputs=[inputs, task_input], outputs=[clf, task_output])
+model.compile(loss=['categorical_crossentropy', 'mse'], optimizer='adam', metrics=['accuracy', 'mse'],
+              loss_weights=[1, 4])
+
+tlh = [] # Task Likelihood
+tlh_std = [] # Standard Deviation of Task Likelihood
+test_acc = []
+for task_idx in range(conf.num_tasks):
+    # Learn a new task
+    train_with_task(model, task_idx=task_idx, data_loader=data_loader)
+    # Get the likelihood of the current task
+    mean, std = get_task_likelihood(model, learned_task=task_idx, test_task=task_idx, data_loader=data_loader)
+    tlh.append(mean)
+    tlh_std.append(std)
+    # Get the likelihood of the next task
+    if task_idx < conf.num_tasks - 1:
+        mean, std = get_task_likelihood(model, learned_task=task_idx, test_task=task_idx+1, data_loader=data_loader)
+        tlh.append(mean)
+        tlh_std.append(std)
+    # Run 200 times to get the test accuracy (for drawing the figure)
+    for _ in range(conf.num_runs):
+        test_acc.append(get_test_acc(model,data_loader,test_on_whole_set=False))
+    # Print the average test accuracy across all the tasks
+    print('Learned %dth Task, Average test accuracy on all the task : %.3f'%(task_idx,get_test_acc(model, data_loader, test_on_whole_set=True)))
+
+
+def paa(sample, w=None):
+    w = sample.shape[0] // 20 if w is None else w
+    l = len(sample)
+    stepfloat = l / w
+    step = int(np.ceil(stepfloat))
+    start = 0
+    j = 1
+    paa = []
+    while start <= (l - step):
+        section = sample[start:start + step]
+        paa.append(np.mean(section))
+        start = int(j * stepfloat)
+        j += 1
+    return paa
+
+
+tlh_s = []
+for i in tlh:
+    tlh_s += i.tolist()
+tlh_s = np.array(tlh_s)
+
+tlh_std_s = []
+for i in tlh_std:
+    tlh_std_s += i.tolist()
+tlh_std_s = np.array(tlh_std_s)
+
+test_acc_s = np.array(test_acc).reshape(-1)
+
+import matplotlib.pyplot as plt
+import seaborn as sns
+
+sns.set()
+
+tlh = np.array(paa(tlh_s))
+tlh_std = np.array(paa(tlh_std_s))
+test_acc = np.array(paa(test_acc_s, tlh.shape[0]))
+
+fig = sns.lineplot(np.arange(len(tlh)), tlh, label='Task Likelihood')
+fig.fill_between(np.arange(len(tlh)), tlh - tlh_std, tlh + tlh_std, alpha=0.3)
+fig = sns.lineplot(np.arange(len(tlh)), test_acc, label='Test Accuracy')
+a = [10, 30, 50, 70]
+for i in a:
+    fig.fill_between(np.arange(i, i + 10 + 1), 0, 0.1, alpha=0.1, color='red')
+    fig.fill_between(np.arange(i - 10, i + 1), 0, 0.1, alpha=0.1, color='green')
+fig.fill_between(np.arange(90 - 10, 90), 0, 0.1, alpha=0.1, color='green')
+# a = fig.get_xticklabels()
+fig.set_xticklabels(['', 'Task 1', 'Task 2', 'Task 3', 'Task 4', 'Task 5'])
+plt.legend(loc='center right')
+plt.savefig(PATH + 'result')
+plt.show()
diff --git a/results/.DS_Store b/results/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..fe5ffd9446fac329c82a003fb85532a2fdb2e3a6
GIT binary patch
literal 6148
zcmeHK%}OId5blm~?L-!H5cD{gy@_PVk{o1VjPc-27+DYQlFT^43{0j&W@6A7nV0b3
z-u6*EF6`aM(dzDsBt~7xVG*f<>aV)Gs(-#7x~CaqygmqQ#!8Ga0je-pfZ_#F?Mmk)
zhn^KcuKP$2B6;dZ(w~bZ$NOYJ?cFl#vY3S|VblAkK8YPr`$3DI{#2wtOnSJ}fBaq)
zCTY2R&vQ%p<xeX@6h-lK@u%C7LpSx(K~nenC#rVnr5zvbBPpXN+w;GN?P0UDz9-|<
z3*&ZQCx<~BLVg^FaUh3vIf#Qq_v4xdAqt|<ENzZPm0ESn`f69lTh^#nD}!CBj>iSD
z@x}gj(CS`Xj;_Ynw|Wtb!^f&+4RHd$z?fQMbY{D!vfG<9&$f1Dqk#m7-`m^X&ELD-
z=Mlj_B6^*-MmTr-aU|n2=yfvVsi}}j3=jjvz~T(xp(0in?}9Rk0b<~TGN8@}3sj+l
zm>JYZ2Ne1V0GJ227O>Tiqsp-m9mLEaw19Av3TRR}J~6mS2fu}J4q|4|q%)3>4~`>q
ze4%hXI`nVpaK;^jR1yQkz$^nxrdm?>|NiUm|Jfv}5d*})hhl)|8*ZZxOTxQ#ZgJ|a
uwLn{-N>p5C@F@iheHBBjx{5bJwSeDJ2B3qO83Ydq{Rn6ps2~RZD+7-kb$N#X

literal 0
HcmV?d00001

diff --git a/results/mnist/result.png b/results/mnist/result.png
new file mode 100644
index 0000000000000000000000000000000000000000..b718b04455e8592c094188b5b263ebe8fdebb9f6
GIT binary patch
literal 42525
zcmeEu^;cV8^kskoMGCaVrBF(7cc+vVic_Gty9M`PEk%l3aV=JgyAvo@+?^1d;;tcK
zUO(S8YyO1!VTP5gykzBNz5DLD=j^lhzI;<tk$Zwmi3<XOp2&ZArw#(42Z2CntB<jO
zPXs2GH-VQ&Zg1r^9|M1Wk1fK1_c+cUblpH8Leqaww4YMNw!nuX?(cQnHJq&6y-Zy#
zL10sNX9p*D2U{~bPfJ%fTPH_4K2B~<K6W}AcXww|F0TLc1x_bdYpyK3(tHqz4kZ6h
zTGKo80Ok|NaO*LDeato165A0g;^}!MSv7Bn?}+xuM4hfAjyaTBx`-u`o@L22LvSFl
zz=WA$&{Q$P<ZHKkc(TV+0tLnrZjNWkZ{mK-Q$Hewm>w@=!9*Z;6-T1AHD@=sv1PxG
zvO6Fx)-6SFCNncHE4!B3{Xc%U0nqF0Nj>|oL~kFz?D=N8e2DSy=qr&|@}r>t4w$0;
z{{hkeOE<xzk<et^w)~s9KZEfS_jJ5J*oFHnomvWbs-Cs{doAO^4^iK9r0p|&jkXGo
zFjp>|6u+pn*Tvd$P1Y-aPu>@Xy6i;_*t_2Uv3C_8*#GxhGcm44Iwih<mdlQY2gKLg
zOzvkO-2Yn#7@ge2p?ODFrs0sU|AluCk9B&)jBMD9tlXD3F3e@E{-A%+KcCG@e9i_Y
zW#wQWqT5PuO8z|Sh4|A$mx!MWEE5-emcsDQRFTS7WK`~7!js9kTc_W?(tYCsVE_>W
zr^irqtJMXEm%4c*Yw5i^)oZC-JV`UQHBEi?C?YuVwFxl#b-}cv&wG95_KLNX<q+r`
z#HdC9|NRhQbH{k@0<Iv^pV~fITVk@}J<C2(e+?=7l`8rh;50KT1(plW_zYW0%{_2(
zsbo<ew{l2HLWJQEZ<SJrC8bX2XImEPA-b3bRJsDoJ>7brncL86W%2W#VXnpxVvI2d
z*u>a$X#WOLjXA~t6GBtNLe;LEJi<+U>DjsLidRYFcuQW`$&ZgOV@esJ-euXADGf^?
z(Zv12yxnIOEL&T<e=5)(w4e~lXYTWc{!O*i|IB71w{ov5M@id=HBC`yZ3gdW1!<;;
zG(!hRs(b00N7S-B?*@*MTj33~JR%7%4^!X8%d&*?53>uF%z6=`e6@g)s4GQV@DL~9
z5JMRM=lWu7DcLK0hdCPmK6-kn@~+I(m!b9L?}*PCipqPCKeOdz{psKJsG!ezBr~m;
zbLb-kgvj>GW|t5MJ-ynxy{EnDyA#yO)rf?8qJIPS`ko->`7(yYl6hN8kDa~o@o)0K
zq=seQxgJteq3Xk&0=ngQ*eIiN&(7%E@MPLNAh`Ev|N7+$X#N8K5Z<1)A(#`q)+DcK
zwt1h)aIHj@3cnwLZ(0XzTYLHq4-Vo&&)A^9L-5F&oY&9;kB^ZOdgZe;qHkZ$GJm(A
zNY4sS-FyfUwoO{sQLa}DHLI933n*CtM(&%|kk*S;9a?CYu{9%j3YJxsCa<lUwy2(L
zIjsCt?$sm;&)o`3E&6OrsiSoU*RfAG3Zm`1kya{wuI|JH_1&TK@H4`7!Crn&(K!}~
zI=}C8y2m2pG?+hif!;(y!;cYusPmj+t<uv{=w0dkVkMIDVKe7GQOvzyoq=2Vee3g$
zMR_%^{j4TiO7E<=-Wk&RmRL)QBwWtIGMPd7qvhj1n%nk-XiZ#x+`>22x3}=UQ-#;D
zgm0C_qMSLNFKJF1Z3NY!SJE7iFQ*m#*pl-O2;WF;(o!G6b(g~MI%?KdcxpRx@HTPl
zSL5M+g#f$ul04Ct+(1W%jB~1#ZT`ZVUKs^z!Q<|56>_GovM=s~c@qxLL(_Ha-OD~I
ztcfx<m&x#$C(19R?i)2SPkt4Z?T>TC{{jA$(z{CW7vvlekZp{dG2RLxGg@74b`z7l
zDoin2Z{Eq?h%~;Z-x<rnUZq8K2mTp*xF0(og5D2B#m2(F$&g-iPx0G$y|vQzvwK3j
z#LK*8;7XBEXO5Q6Jvm(It@-Ok`B9MzbO{Ds*V}X>C~Q+4<gIQclPUMOo?D|SRkxSf
z3g%{v63F8IT^)rgx{xkNqK^^~O4<8rs>G5*pHeNqfaQXp+uD^)KRd9$=Ji%w>c=i-
zo!C=p^0h_A{4M^i%+|^s$${L14(!tFW%w>=in~P$LQQK}RY@#FmSMBCrlU68B%CZg
z{Uljws*{j@TU%UfPcne1hxdsC+klp(hTv_KGN-xI66+Q>aN`#U(hTj??cF_}^wov>
zng>EqM|H_$<7a{maXiW)rs+3Xf0M@=886Jzjo$R~I@3h@^)ZH<iAtZ%GplUJBt^2w
zMzScGBQo+=My3~!^RCn4sD5o&=3;ct83$&WRsSLDIKf2iN+FAfhld>y^E)|#*%K2J
z0VmieU4#Kdg~VKKC+JdF=2D(a1h+c7{%VAj1_y;wv+^e7^5fO+iY7Z~msZ$wg7U=<
zuDTgBEvmI74x&%(I?rXqr7Y@a`)ZWf72{pl)hj~GsS0TDhWH!Wys2apj?V5M5Ah2c
zIL~RY>TdsPM7N73Fk)he;{QneT$ZN-%p;gol<Cz7hPW6|g#IQpw<4v|w3np(DIiur
z9cj>4l<FoeUHp8*1AP&OuQERrSN8l74_N9)_A$5KXq*ejdee1kJ)Xfa)U*ueH$(Vr
zbzgO2RI+8cA@g_jch!A_^ov=W66%9AE9VZL#c#_3oouqixvFRD#6CVq2=Zhuc*Lce
zG6><cJ1jfWdK9+2e;TQ*wGZaiO(|5!c-^YpysAFhOdh%ypt9(Fm`m$`xo;G#m)~6j
zR_APrN}iM-YvahyuQ$0`U3i<n1a%5%o_Sc#wiwtS&zo2j?Ytz*;Mb$+3*{xA#r)eo
z_k-r0cfcEB55A~$)Gg~)x`hGW9FH{ZeakC?u{YR3IjD=`+lykU_Tv80u`xaok><5A
z>i#@URvs}ih<?ARZWuJMw2{f7vE5YvaADl{u)-b*mveDtB9nDVn2j|vd(tq|ju0ei
zu)ToxX)(=MjHx8-+IhU4jFBI#Zon5j63}mFRFLk*Yi^#--Nm$N_k4MT^CLBPSHu1e
z8R)ieJ{xJKJdJZIHtvAQ{QlYW0%LQOvgAgb@{)W#?W!03uMvX!(AYT`LSwX5p3wzn
z<!s5EZuDo;E>dp_PJ98nkxsxl6@B?!CQZVL5vuQ78Dg0>t)CU}P<Q#NM%46OA?ZhZ
z&+)$;wHf;DFDOS8VEy~=@X0hRGz49QBA<G3IY<+4)ORyPE<X8DUz9W9N}cH7C11Xa
z=^b!gZ5n0z(~&#5S1=j_ljoOy)VN(3`^?f`;agoLnLPZEyoBQk8%*~v46Qf=n22c`
z$E9Oi@`ziK*if=KW&Hwbyg8L*8xD=9{ZwOw3ex1=BOzF99)vRzr_6;XVlU5!Ue1KZ
zs<YzU^NYpsM6Rc9eTq${<<(Qr;A~2T4TFi^*CEL(XYy#?0oQ6fN57TI>`A~rn~Wea
zCFV1>tp+O9*VCAs0gMUCS2j=eS-6M0k&F93$GaUlOz%FiLqiuT%slt%`m%edeCi&W
zjAnhhYy7Cu?Tq{9F3_z=DeGF$e93LoM+h#p!aSLNJb$N;eW0*5j}>DcKelM0<UA!W
zSUpD@50=bXx50M@HPL48tO<`6NqHHP!KJ)OQcRf#w+;@e7aM@WVymwM>sFC`F;Mf7
zoJlu>S%vdMUrSx<1Q=tywe%`@B`o2nSMhr4G<`F8;ejX}%XW@oORpen({aRuT}fu*
z=<9R_&9523@}u`-4fsGlb(MTCxo?scWET4NW&7IojOP>lM2D-tDrXYPQbja(n))vn
z>XeE4>X6(6;<h1&^PuTABB^O&H%^&eV$oUl3h!w>nlB$Vil~=qI#k8Rhb!-t@U6)?
ztzu?mk>!slllN)Vu$m3_#-RZtc(!-)Y((y7&ANEJ#Do0R%FhwA8xbb;6c<vhgZwT^
z&x;Y8jTj?-^&^|k$$4fiw8Dq)iF-9OXaJOzei)=u#gluyg2C8tOD<gTd4o}Io<N}9
zv!|qbxoA!>21x9b{EIJ5@n@_)z#;*lWlLTFW5`dJ*R?R98sfF7$JpN9e-zJ{VF*F-
zrHvfdAOlpi($S>xLo#KC@J{Z3(mG?*iAg4ttm<GjM=3H|dg4(MhsI~Z-#q>L^zf*8
z{9Hy<`YZgKCz72yeAXiHq_v>Z4=<Wtg(O_#^}1#}vrxo!r}cQrdc%Xk?GtrvsEqX)
z%a8l3rNqn(uEfB#^Pe{7J#h!W*~;#3A8^1<;>MRo&$on_{SO1B#dLqsKG2S<I2uct
z4aKGz+CJ}Zf$)`7Ip7Vgh?Irr6P#*4U}oLUl}I2(ew@>)8nJ1_D=uVau^;RU_jF~Y
zg1EmcOzb+S*dsbr852cL=AzA&%RO(t_cVZcYnROm_rQAedzLTjR8UgQHDy^RpC*k_
z4G}oLx=cg-RSp<)yr=g>&|063b9GF|MMma7h2WzM=H*1i?jl<?=7N%$wt&7VZsH*}
z4$5fc<&h|UWb3^@jZOuBnhVEYPP8Mre6*SLel?z6Z;@cz0|SQ1C3T{G3*&q^&Nl(1
zzq?#l4gOpFmFAYVjrp>TvXvma8S|zjtEN<R<%d4b7=a1WF+*ymg@NQ0iz|X3haTa-
z<MP^CUn;gW?eR3eCpqv9RiAJ841TR^J4RSCgG41%m@@NHq-YI65Akbe(-pNP@MU<C
zRKY%cKkBWTXSe&_CbS=wn_Qq@It-ebF?ZXrz~K6jq=*!#(%oPqNbN5J+g!!f!%D|3
zZY}MN)3>bqqCopc9E?Uc%9(xaC5;bXZ;JyztDGJb^%thBFgygq-|mM08F*SW_|Eb3
zI7fm}NBAK}K4(Dmo&NyqLV2b9?qm)_|8zwHa#YG3wflezUh&0qYto#zI>3IQ^xA@L
zT6?d-)k<c5W+53srYy=V=CJrrVQ*jhueWk#rh=T!%)W31-VRZr%BFU!T3URUFzMC^
zm<EG?Hj4Tk7G`Mbqe&C3r^-SVI2Y{WA3@sjD%5fFAB<<5%Bv)6=M<}{_EE~J)b?Li
zjD9lroy+W%2l<xDbmRSOM6a>UC>|x`)11#V#K})R?vNZicj6%GO@FwAJ_z3qPh@{M
zD*A~qcujoh>0Oq>@q6iUR2%bV5j=Ndk6SY7WsavH`}K9hqZ{dWwKU^rZ}ni7qjceF
z3LiO|q6jS;U_%~aN$SJeiD@PMw*vFZLwL4`C&}82HVJ#fO_1QmnHOCv3Y~{1KjP9t
zutM|xG?OZHnH7#4sJqSO^8QG<#3`9=G?xChv7|rQ+C04}RypG8Cel36z!7}vn*J>h
ze`5=uLuwP~Xn-zGJkSYp6N=0ET!vy)l|;nr(L&Mky<!p^`3gizdykWzf82dmI`9l!
ztgyQ`SEU~r1-%(-zC}Hx&l@Se`B^p6GxR`R9PgmWD--*T>_OEk=U#Vl3;QlsvAk{Q
zFI$e>Zg}6k#<0}YRPOATGy{}RAN<}BR~y>3H{CDv$kU~4!YKInCBvJUL56zYw7j{%
z*pPnIU1+6SYE*7-4<QP(<j%uvs!-%i`1Y2J!gmLcs7|-}I1F)|l2}#vS6G+_Z58M{
zZZ3@<JSvRZ2N!AwVAIzf*Ak#?pY60(ADfJ}lPmhblacF~3kW%EE8c=@YDHzdvZHbM
zwgjEl+al`J6{}p}c%|&LT-#AypUh&IUBG)&>Gmf9QfK$wX<q#o;fgwyyU5$D)Ohvu
z3H4vlf`tp2Ur%CvyH$%`JNR<FRvat${Bxrg>bfFPm)L5`tVM~U8MuG%qE5W-!4}$n
zRD&pqr!Kr-W2ft@E}H46)m5sbadoR6SokLXglk^o#EU3^=?BoxAhb1RD->aor7z$<
z;F!{Lk08{DJyGAXj)SXtb@MJ<r^w7zc!^8!<FD5H(gd@zW`!EeAL{2N(|#*$HNVGD
z^ZA>TVP3WAdhNsW8Bn~=y<Jr`u}c>aeIqCntCLNtXIc^ZZK-KslkFiQLlud>sF3#~
zXh1tKQWGf}|K0S;U#fq6iz{B&Cu~3)_4-`(KBX>{wzu5S{A?yL`e_({7_B90VnkZs
z{J=Jp^MS_`5^}%nHeDpuuy(9C2mSo?_NLi3dF(+rvGQK=43Fz+QP|JrhkVGLZoV*M
z6n{lKBB5iUgzxrDsvkVcD7B;k4a$*v&&1bvvc<*YzNN}dPdg}8Uwq6#&@Vv+lKuFu
zQ2k}jSfWCq_g+b{_ja1~O`-AKYgCui4R)O#2MPs$K-~AJ-uG17qn+o;_2ax6sSm;W
z{!4BtHsN(W-JZ5qUZV2eX^S0exrdjJH#n`SaqL*DdbUSDa|aBt8mXIn1h?*!F)uS3
z0M=o(JwssS5G5*+{AxBm?dY3uM#IN9z(PNWd)k!3jG481;`^D#3oNy{Z5EtN8>cE(
zCg|73ag_}&+{HA=sho1aj&fi6aB*eBQm9sStn`uGo>aRX%tyMPg6YIAr~|&+oFXX9
zlwsLXKR^oYJ5a>EtKJ@Th!(2QY7*79ZbcOEnTuqLOAR-FdmHG(8)a58I@ipvvDIgm
zcny;p4w37-x;%%mL|cWG)_RD-kS<}Sj?KN3-$^P)W>PEbbPVSNUvH&GkxoS=sYekf
zl3+rgPZ7Kol^(Y1-WfD_cEf@h3m57Ee&$aRn6+Ne?K>&(z+-z+0d}=x?=P94-q_+#
zw!Lt2M6l7r=6a65^0x;yD?~~myV&cs!hj>}qDFXRBdw=>{5S2y*9(1rp0npX;OR?p
z{)ys6OvA1A3Lk<s4_Ol{QKYr1DE5uY2dc@^<7XL;&*(^0_^vnMX7`tH#@2hR=fF3<
zyX6$RAKH`0$7+j?-ERb9L~(F#gbwVb(VATx2CD8Z&Xp(!kPmOV$QDbxY%hT{N0E<L
z#%0(g?=_;@FCj^l0U>k}O8#fTVyLp(A!XEG$lS?&oN7m41e3~6wWt6)G~%f*)r(U1
z;c<v@&uQ}GEb&@ZBv`b$fX?l*;{hKm8f9>YUbqimJ?teJl)8k+D?6=JauMWAUjMNw
zhn{<(2>AH;?ysC41VKWM%d31jxA+f#X_2o2&X@w91#N9v1{}@>L^}nXXEap|SxX^w
zQAcoOYtvEJ@oGMEk@|w4kZ-HOoLSL2kC<`mVIfEP<zn^^M-y_7lvMopjp*}#jguP9
z(j!7hV#zo;olo!V0=ZIcnX~<ElB{W8Y}j*+oXpmfpw5_%cenyBIv^E2@EZKVEp|4x
zkpPk%v-*+CquxE0)8O#Nit;MGYoEXF-v-tWBjb|o!B(Uh;;s!}&1sC{2c<J)*)S{2
zFB{n}8eUnbYn{0roJOV>buBAI-fl52I7G<i!yYo(%j&#Q>-0jTRFK8%zl)6KNXuUS
zg`|-sAuXT%#l29=_wOeM>9=$WV4G&XZnlTDIf_f-z73g=xNAMWcnD#!^l$Dw{5FSu
z`3hOWBO|-HvUkfsiD%T<+^%KAg$T1aPuKeUShft5Wa3>p^kBH_hnu{DuL|9Hk-tAg
zXyJdiC}pb`WSbE@ROy*BYU?UZVG}=JeM}n&pY946_lQzS+$DSPqIUY`iQ*T^K{<_Y
zk4i`Bw~kH^J>b7O`*whDHBK++V3l)+xmbvpdqFN2)qX3sNoI8P@Uhi78Ax;Bx_V^2
z;(Ih})Ine$F6FS)ok-g*-li){S;~X4f_BH3oQ&;0Y*c>$+qW}_vDx3fl!-wTRCP{~
zVN1@RQOC9}T=9zbThYsXC$~O5v*Di~`SmQKVF-G`5p=F>6h+j!@IumiVtdXJ&1U!f
zL1el1js1dDx0>_$0Cb?6_BPKDx^hTKIXL*D6ChW^wrC$V0^8QEi&e7L*Lx$WP!8VS
zsqmX<cvE7Shdw@L4EWj4rkoM6$A!enB_=s@frWHiI>fF7wsXI$l|u1YB=6@RaT)8;
zKQ`wS=aqfAZ$i$x&`D4>i+n!uN{yvgz5cuAGf_EXw6?0r^_go{gSL*h^G`ejPL6ns
z<=p&ECU}bE5?Lk71^5(|jr<_hIr6#&mp8+;#RP{s1b35mSr*TnW)1|)vnU6S7Rgju
zPDEdRpSdd905CpkRX+vsImeQ<NVX=Ea)d`+Y2pN3i;CvglbnA9a%e2=I|E}IXaBtF
zU5KSYq}*t-&xJ#p>k5px^HT<m5yUBNu2R#+8x0<4pZDO^TsML-^?s$T<!$Tp>Z)}f
z9`}<kwbE)%9yco)=b+3SPF^DwK0O6KErmo+j^DtVvafAgv?|%FHaO>rVtA~&z!;Nw
ze|_*SJAPg7(yn@yS0K}}da-B{yi}8|t~OYlN-3{L2A;vSvJ;l!*{`bF;}J;Tm>DA3
zW)0Km6ms1qbZ&e7MKi7W8d+`_ECqr(r!QP1sS~Ac$Wo>8%9XaW?=z@?&$}(wsvoGq
zEyPyPu$&AtphPyBpJ3-IX8^U8`+kLt#Td!DGF{6Y2tGF6T8?%2`>Mh9Xw1AZWnc{2
z)3Yy6|DG*zeBgQW`^QU7<vybr4yS@gHj&Jq-ZhKRm!B@a9P#`>ZLhU~AGqotG}9|8
z@3SZyDgNP?+IoI-srbdTMysUPy7Mw0+G@M3{mAaAcu3uMcD~So=`VCq2?U3xO4PeF
zLf_=}?-CBfOc^NB)Ft2Z*eALwCFlvJ>e{IN5%pUyiS`<~Et`Til?#d@v1+b)E1#c1
zk*(T~f2YcgCi&cT#dAbjIL^)7iUwZYQRA`ME3(P>qyR`qQAn$~V}A9{EO<AboiI}Y
zJ?1hN)BAi6m)6fc%5U47v%Ci;D8Sr1?QGRgH_nYus+|tY4znlYE*CKNcM0`mGAl@3
z4_lEMxlyB>nn!U;MF<RiiUoLuTZPEx@1*rsVE~2xqP22(;oI-fYMn+_D;mkGO$J(D
zhfGDjPb=-Z`AHt$CM|z-L~QpbPtgCZFHvpi4o2s3o1h%IEf9tGm$W{qR#Wh*FQ#c&
z=3DsYTkTSWEOTaMOGJ0mACk-Ld5mo@ohaF-Oqw#S%$TFQt|0089}+#4j;O|_u4GU*
z&GrD<`L259RA41K0=*`(5{>&|UiCTn<3eke=Wf9E%5@{NA(C}wDyNgm*E_?>tm@{(
zI8PM$^vm!~cBx0{6fIE3N`=cYc_S+m9pMMZNc$&JSnd!`ttIv{Z+0Kr4UConqyba0
zcv4Ii@{>bg{eyt^I=j&k@o0~aXtVA1B7w1A;h>qKDRXe`bDxTlxo<6%GK&Jufi-_V
z5XGONQyPtrZK}j>d!J~=pKHA5Wr@@jiT*yO`1B7AJ=!V{Nq@T1VBfXqd?<QjqXAYs
z)>wPrs6M8*9+L*n7w*2}9`Ath!>qz@>jh8UkKfsn|60OdWJs*}<8h7BE!xwvc%4BI
zhQ|q(vdEiUJdrT$w`j`*TD)fl0P*&PdBtP0GdH8M?k=qeSh(Iug%AYenK*KlxmdOq
zvA5fhrM+UfO~p0FfTVoV8$9(syDczvU=3e^#V%I$<aaNo5wzv^uzF(JQ9^+&^NUue
z@M2o(HG8g6XaDN1b275q>8Ytke<iusF#?L;NkhL3<PA4W(f%rDaPumSoYVGkY6#6E
zmb(8u1yF?<FWlIs)Q~}&1Bfs}zk_7klRs%^$-S!9OlR^SVdEW{Sei;?Uzn|D^FZ&u
zeC~<NagJ!xHB?=VvuPl~^jchVP^3UZo@o9IU3Sn`HiBi{W*<4ae|e=K<=*mcu^zw<
z06kwBbfL97_&!RQ?!)&}yo{y#gFZH?aP0u+Yi!o{Oi(C$M}s;5c4cq(w3*uxuh|1J
zKhy-C!`^136>f))EwcHM-*98`_-uXT)gz83eaiUB>x<NNo*V^7;V#UK^fOeP@@#9z
z>14$rdZ<<a)Hh_i;uY`}Ta`rUGVBoiUKGdQJeCg!g#G53LpkBatYjHhm1O}?1k6nf
zd_S9qa!-DBS#~0#`6^GB>YC6uR*|*bb(#JS-g3<y!w+<B_jG3U4T3XfKU0VGIjj;}
zCqq++v6{Sc;j^$Gnl;l;2562p)snBR><!XN-7G6q26==I%IlPZ{ra}=HREfa-x{**
z)Xn<s)QcE-i|t-r&oA)O`nx7XwVuAx2hzx1nugzMJP%MZ;sNc;?KviZRhI(~Lgf0J
zfE*FcMgmkL&!3-S!#E-Y@L-nBz-+dBdo}<M`#8L=5V@NCJ28~(Bs#?j{iI8-|BCn?
z#$w%{7&RVI(WCpny#RiNAv<A6WbpN~a)H3R;LY2>1BbLznL&4}DZ%{0i%_?Z)b`XG
zE>`SeJ8~B4*s1Rd)|M?k3so=-bv8Z+S*0W#7`ttLE0^PgS(X-~sC)MVBc_zDEPWSP
zI-EtusOC5?X{VO3#k5qC_YIc{76@z`5~B>K@R%)V0`4bHImQfG`q%rVT$AUxv~_eY
zy$?F_Xlh}yji<Futw-&A@$)8!qnx*uz>I(sT*?AutA%Fe`-!U0zfG&jmxibiO`W0F
zP=rmWrwdOK*TC>|$pF?@9o8;<O<zb{I%2Wm_HzG>OwyN@%_Ap;i{o^A2KP{<t^{OS
zfquOF(~KMl+|Rr8*UF@Vm>#CY=UY3K=U34ME(c+>R6D<4nTuIzo>7DW2zUQr<>Etf
z$r`>;ihkS8)q2quVuLY)Kk_@NDX}^0`=0_X*W0gS=BHWT+mEE=Kx1g%MSY+2TV3m}
zZ1}|R{tYr99cFA=VCy5+=r~Xa1^@+s87sK>z5lxJj>jH5LiQI~&)HrySf0c)F%oRq
z>lJm`h(y=-dL|e#a&0+CocnT(s#anK9g9H`8;!(r7AY&B79bN5i;382(Ef0LwSc&8
zjf_2!6&skAbS?VVaWHQ!V^}(zFIb2w65A)Ki@Q+iy1VSigS_9;xDz$brbpTH@+6sd
zOe*McxvP$c9HDB8$R;m>9mg6W!k_~y=_wd`oa@S#hN|lM1QR1b+{pI{>~Xfr@tm`9
z07XF;?0%Q__5=FYc(aHJ^_ry1V6PN_r0-EXNwZcx|GTiXU-C0){r9Vl`?W@{^TjPo
z$&(ZEwCPjS->`VA>h(j^n^o*%b{C(97*pneo8P;yDD;I46nG32%qg%!OSnl=L#6-8
z(s9GID=M7k=O=0E&`MZ4DaiA8_;Fh@KWE3uAM%CiZTwmw+Z0tP2Nxc7w8Dtb2mpm^
z!)Se}8G2A3*qrq??qUy;Y8v@xbdobm?52x4k9k(Scx6oP@_ZRzv28iq3P`=rRh19t
zrA>r@5@yFg^tRW$&=Zju=deV#MSXle*)E$6u6FuZz_La2Lq}t<T;S@^5@cRpqA8&g
zec;rvNjG8hYlH#Rc3H5s$mr;D{%rGhm!8(g?~4LV6&K6u7yG9r{uZkI$})SV4IL~g
zRD5mbi=_aW<~&VaTxYTdOXmm8&j2|D6zCLAj<aee#_PNM7xn<HE_J)|2_$(oFWkLE
zyhg6@k+tcaOG5RM?eIc*4MoQ38hcF1EIL6Jv2Gzv;*_~a#Te6+`m6@SOzG4sk(KKp
zI3cKhHmpYKsL6Y6ogM%@FE>t5*s_Aic2nk1MWBxJrn069b*R}M3QL!0-?${PJ>F4$
z{rSc&-)*(<_F%FU#4q<kss@J=n?#n!$;fc+HWF`IA1$!Q80g$@;|WzxPf8}iQ0&O&
z0_`$R+w?}B1R}b`hBWd)hB*=zP_sE;O2B?5mmY6s*Bv&)`vf5FipZ+;j>mD#k7mFx
zq<<nlh1+@^bC@Kl<CFb+`2C%50n%y7qLuB8dG%hkCfGa;OX>nu@&wH7Xqg@XjJVu$
zeC(a$EdVWf5(+19n@;`+Kdg;aoD8-Oi6h4UO1Ly4FH@Y>v7aV(Q)CC&xDWNGhME;*
zTDb~Gs;gb2v(5-c&mNI+^b3;H4z4=#0aWd!9#NB8@kEw_8F@tBmmxrJU(yu!ZuttP
zs9SugICE9KnC~rSH$uSWd0i54@1K|<c&T611rWnMYDHozDttUieVP%?3T{(IDmqKr
zZCW=j{Ac^g+dFI=M@z>#!ZeA7zBIx{Lr^_?Bmc_Z*Ib+zV;?Ez))&I$ZvSdbx!*6*
zX8aYk3jC$Yd8jtr%Km~b@fR`iIcH+GE+B#V#a58hXa@&k5_yeidD-=r$xPw>6coEL
zeP=~z{srqJku3kByj1HFPJzLag)hU<#h;ZFGyFnwme*h|ad_U;H=Fv#>|nkBWIvlH
zJB;U1#2P?2w)xq9Bb4$KhSVPwtuUmkiVM_RCRz^hl2Z+Ge^g=8aN*z75DbY@?#9z8
zxz(h~;=quWd7W0OKDu!Fo47x{&fe9Ree5zs6aX+yneq`jA0kS4V|vr7sR1(2#iJu&
z>`~CaRw+VYDqnY06^x(Dt^t@OOq=2s$7h*h`17}jLrYTi?bf~Mi5Vn7G>K-T?dD5z
zqe`1P74>QQ3xS}&vrZ<rpUkFU`Xt9RysgXY`&?rn`KKebgwba`%`Xl5d#aU1QHQZq
z!`5J4mJH#D&%(Ra3kL_bFWh*uUN5};$XS%iT+B0lIMzUlU_#3k*6c0o9w}tJ)WU{7
zk9RAF90ivr{U)Sua~%KPfuWo`*CB)t_%ybK6|T%<2(6oV;PZ85Y06BBDK^T30@dun
zc(GBZa`4tZLQanJi{N}n`i74Irs*<t)nO)ZqB?QMsw`>6x%NlBtX!N2$JqwKj9(al
zwgK0QsjBYFV{R>#V-~gvJapCQEgSEb=7rOtJW)j@O@Y7W2|=+x)V3UTbd;}bB|SZD
zx)XkwX8>x`fGAcLM^SZ8yj8)f8Eda=x$?`6IK`y`gXg_jI9PSF%R;)Vg^ekx`YVA~
zzvd8?0v9LQh%*>YBy8?qAQ<1>G|M>En=N6<+!BkbNNVUYQS`a;yoXd*+Zq>{GAsC`
zC=DK|Sj)2pDa*tw>&hdtA^XpGxMSvuFnLZQ7V6&;RnjbLK(c(3zBJITc_gg9%4l|D
zdN5nDv}2e94`m(nQx7s>;_m0zA(9If8<%!YfhxMy7D@ZAEuh)8KL)`(-2ypMhYe5o
z0$J6UeMpC;{xF*!2J6@Uu#}m>&drn1yNlIhI|ry4!PT*j$u4CBO{5zzhYjE467N+_
zb$7tqBwm-+>XkT~UTF8s;lk?fD(Q?f@znwiMl<td(mBDkDhWA9p)>fEE@Ov`P?TOb
z5>^IZR<MU7o*)npvN_@x=B+gCx(Cm@(_Zb?rYMS8OkIWMazvN`#h15{7_^Yw)$<`4
zfd738ETMP<2Zw%x^x&a{V;JBA64q>gOEgAkTc0mM!h-)JnRfCjG4clJZKi4d9wrZo
zD#cpxd|z}wqv0xM*-o5LQ|NN$QD%W^N$<`xCfnvFtq-`#mxiVlj^vMF$+zqK=nsRb
zzgdz;oaW)n+)igFKi$wV2LU;1RB4-K(-08bEi|q=g1;05Zf^%o@h4a!)JI>=I{Uj+
z<v@ab*><mOe_BAzW5E=}*YjEo5f?O1?gS?@DaXvyB2<WK)!_kLhvf&`;wtt}%a!!H
zW2x78j^M71^j^$?HyYo3A)<|YO@}%IkT&g*98Zp-eph>hR4bHV@$*}1NgPmb-X3NU
zhZMs>Oj+yP*LX(!jQ}j?x};$-iHNIL5^0)~u3fOA#vggai88uCBlLDuxkhat{izJg
zBug!%Z6L(7#1~OcbyQ@8RpqV-N|o15az#`!M!m|iz+gJVCs~%Mkku@pPUM3Xjn8ch
zj>*vQN5T%^YF#jHM=n?vqx-V$lM2g=46Wm08l}M7#(TPIkG3l}Edbp(o9^g#VaF@$
z6Z7iB$zM|#rufY==6DE8#G3=T#QDXu{>Vo`>uMx(*g>XWY2Wo%i=e=}U!P{Fe1*f7
zlE#DqPBtlK^(&sdti3z4jAT7BK%rb9Eh&vy9N$`y<Q+qxQ+}?op@9=7GRKr?riG-j
z@P6^!k-1lm$76M&!lmqE)du@|@VMT_yj39Uhf11Zx_#K2GGo*yRv(F&6QjRsX`x;2
zjbtkw=$)vu<I@rprcHf!0LI-J8eb5g4HX=sJi}j1eUQ`_Yp)CaQtcXAo9N@pqOaFN
z?e+{5Au}@uYQXsYfr%vGTIbPU?5EM5<Hnc+)(+$8r>@%{DA}#~1h<xtKE;15pkQs<
zRG%$ceQO`R&k#aaVb0i(kCZS7{@Kv`%vlutak0?n1eWVj!|!V)9%jmHS8g)o(-&-E
zTi^KL#DS6Q%8pC1GcWP5#Dkyu0%i=dY0#FRamxKzC;LKbuzRUdK>}wGPZt{j$`=L?
znfM8J0{~{H2u~??=Z`fF^%6s31B-=M066h8NbrhuO26my)qg9*mae^lL77W<vT&lc
zi|_|Zn73agg3b54bN&|o>`Or@e&yZ|JoP(K3e@22HT?E1&f36_e=WgSJ`_zW#^@?5
zZVInwI<I&fBunc1Y7*qJ+mofVcd#I|t6CJD2D5$j*gG|5lo1-{^4)h^b{Q&75ZN{%
zM5AF_?4N~>j|f<mAJq^vEor3Wlp3g(N|+S=7C$n#KWoTy3rlA5pRFh}d}_xqca|(M
zqbq}Bknb~KkT07Lf%a2$c`Ig&pUJbX87S!2F#y@U&i)W0BA(K~VoAu9zomnvB?VHd
z5e%jVU0s2$c!ScCU|C9T;+2vOwkGL)p_Z%CGdQn)!SD}0G!~my-n@E|8{2Bi(4VQe
zWMg7#c^!4*l8w~g6%2u^qJ^ugu{LF94f7>=As|-?thWUpm^M<0CmSp-k9hvY!1pl*
z#BiO8ULj!MvW|3o2>#XhP&pUKd8kKqwPagPK|2^XG(VtjKWYld1<fVsJ4KPit`I0+
zqf+pi*`3<8+SPVlg(V2v4M%tvE%njb03C#xOkEgT=c+}+S7Kbni%+HY`*!CMhQZN_
zu!RO`nj@y)VErGOT-Q5Cb$9*m2l+%jR|x}5hwBUZ;&m9iBtZ@{WNvIlc>or0_7qng
z6l`qwnbe~cfJYWQtpn1ci}Mq%+%0T?N)BM6uUEd@%iVRS|INITil%8VvkUniqG2wg
zR0vo;f5Eqmcmxt&<8PqCi?TLr1bdg)4vQ7iN%R405_Zr~y<qjMzRHB~sPBRlV9;tN
ztseNy8hFgG#Gep-5dzp0>Ryxxh-EC!<A15&f-@i*J8sO!*B|xs0szz5wx|UHBA3$%
zAPM6B)PW(_2uK0wg803E)IxXHl%Nuk!n!fXhc)Cny~~S|ox-!%!;)_bb745&=wV|Z
zEA^`)iW8vVh-yJ`+?-USW(St%zpV{dJQrpkGHI%E>xBhe;z~R4>0Z?+y(hQ*6+QYg
zAVn;H4x=hgnRm3;&yKDrT{tG~;?aSX4Jo!ePCz+`;a0?e$(E4UM)$|c%J3ycXBPU)
zQVp41^73JGU`Dr&+tHim*xc=y`J5}$gvI|&ePag+KA?0Ree(}eV9`5tmcimaOxL#>
zYiJGcsV+)#17^VFNUbbxOqkfKq)F^?zseOFCD0&|FI%nxxi-$jnL07=-t_uV%&#3p
z{dWv~WhlFL!{#&@J<gzS@4+GX-Tu+=dY;7#a4F5zwV-3KT_uR9<+UK}7G~ML1&6T)
zk#K7&0aFxT2FLMgTj^TQ9@n4T`-G0jin9`<zVYPVueC(-INMsojhQ0&^9x5dmV6z6
z8<ZrPpdh-$e@C__&G~5e62xvnjjL-t#oV+pSdE{ghX;bV>0^JJZGmDt7bNxZK2c~U
zzVq&fFO36sQUKh<GC=sajPzkw6Ix=ot=yklUdc7mB9Vc&St)^$J}J8s%bgc?#By@z
zZ(ROH?E9j<eI`7Up7q%XOU1X*<D`|(0Ajvc!?OS8vmUiQV;C<03SzQ`Ym|%Gfd<2D
z<#mo^`p5+^xkcDeq5?Pu_x`Hr_M5t_aXqhVG)kl`doVdjD+8d}`uK^rG8G2}5?L3e
zy`MVf3Fw6W<|d9^NjcbsY}i>Y<rJo%;m2&DpatmO-eKr*4vXv4Is|U84oeqT`KRH+
z?(GsmBS+7;-_()-9ZigBWP`*+r$V`MSt4yNYy`ADiT&`H0#_w^3#XerAM#Y4wPaZA
zSFIcLWnBqY3z><(AzrEl{=z9V-S$bcr6)wJ=p(}tL%Pv8;UKp3F>;d4%B2-S8EcQo
zf~AIjE+O72ju4*3ztrlC?zMvIK_rHbInijlK~-~)d|Po>-;QowcxMYg#yQFx#a~}#
zz+fhTm5=1+HR4m_Z}L{D%X7D)c1~xbKa1I%<O!tW8Z31Rk`yUO#)(R{$o|q}`d*uC
z$-DdngzdtxtVj3;dx|{MA=H+!+{9rhciHflK6w?p375I}qW=T6#d?p68KrzEyaE4(
zXcqfnhf96Umigfo4*{sL1f+!<s=zWDwZm)y`+N)7e1zt63|!b@E!aeK5dwe}(;NhM
z2{lzKN4S5frz?TMF>DBzab~LV4~{e=q^WTltFd#ZMnD9i7R@{&D-&lXK;qJa&7(7>
zedRNu{o<jdaoJcb?g=LXr8sILmLz8N+0aFd&`gF15jo#3NjibN#bGThk=!kaz2ioI
zgzqC4E~EVyi=^B`u`@0z<Q&_17pPPLOHV%}e}q6l=V?f?&&%LYb>w!t{rAq`TKu*S
zY?H<M#MkF&6GJGpC{k>G(7_6OR8oTA`{0Xvr(QK#DG)UP`gRO|=$wyU>PJY|Nj5-0
z2$IgUdR&twUUJ$2UWxSgPaOR?W8wgCGJe_D<rC197cJlVe8Mga;}bs6XX@2X9V4(;
zy?&s6IC1g`LmGYSW(zcCL+z%eaY2wSZ%K1=W~@DALH&_7d+ZYvta0FyF|R)GgzTvZ
zQLH|qt7?cUPg*~9Bt3~PWutmw{)i*0Nq@d!jCGYR3h?{?<G8pC4E|QqQ76~q&<*TG
zT2d;-Sfx=9<`$0S%!d+x25!n9VdO5k5z|2|ZKSz!{jSC+ZNO|9*(2%#r)*PZHT~oE
zNP)6x<deXarH36ItQbrD<zB8BNC;iu8!hz8W3-=1lvN<2Ovmm$AQjEx0+wd=(Nig!
zYe!;N+l-_{rSI~0x&-rKCK%D?<@HZ}Z<M|{K?R2l3f~t3{r9H}yf>NR<YG`QJ$pcJ
z*cd4#NiGd|kXUj9=XL$px@2@}G#8@JH{eGsY{02BmJJioh{IG^W(e<Qk1-zE_`D48
zzF{i#B$_xO(6adPIjxuRkgm_5QB{`ZJq+)}@s`4Op)<++iN!}ehN0pHO9x6Ep~t=)
zCb$&E8J{ULr&4DrmlR}wH^(fDC395}$YNd1;?RXEWIv$!>^rcOj2b}*0i*M^GJ}TX
ztTo!T9*DPgeiiPIH0-#6l^SH1Uk5|$?16di<t3RTqx5?i36ViiBs-OW1o2<{qk1Z0
z9yp50-=x2tmET5#KNG)|eh2WKJIgW|uBPc&-$`Osh&&MShe$YUAz)}qE(HVp0^rSl
z6+*0Mk1tcL?(}@cm8{(qH=HMRfpCex>Tu-M+F&bxyad6l&}TtS^<EKX-$W**DY}SP
zvWm9A$&sZi$zZvd41H@573}q@^ejYqcI+bH;D9K_dcV!XBP3Q_^0V#Fdh|FjdMALT
z{>{brX3;pmzHDEUuY4OKp|~ZejwL|VK4F4GN3T~ht?d}PcdJKUZS9p4R2o+}Ke)$N
z9|=Zhm05xk$12rvWlBDCjy{!h3R1~3izBXSe;a4gozw5)mEQN#h;K0~&JI?*a-asY
z?zXjLKv@6g?z0aYX6J8eP%D1kCm-9ORkaJh;0>~!qx?%42TsEfc~+6~aljg!q)t`S
z5ZuWd9Wc%>X!0a)jx6X+0-AW4<!~!g8di;DT)R`vn?(WJ+n3s{XogVGW-{(7^Q_<b
z_l)}`F6am_CWWrVYr=CONdz~ozu6a!{N{gN@jq#<fjMg_*{v#5OWrZf;`$q29cKh%
z?e(2d#NKOwTzBbzGkV^Q5-HI}b080{7t&g$3HI0~#*nsWwh(IkvU|F?mUo%OryL9z
zfX`*VaQ_oT=X!pqk2{3%&tm#~EYQ`nb+c?3^((C3a=8+8E;hsysG?f+fO7QYMt{|Z
zK5|I!>*VOxFPg}~faTzbgV0RM1cqQ{!A68{x<PK-MJHf;B!AqCDK&9dMx2Y4gR4i&
ztQhkS*!Kvhj(){scC?dD_xOkPFxqW^kG*c}a@a~d&H;qJ-{&$N7s~?cI?sF4o!VU!
zACASeZM^6wE9A=r;JzNoTz&|Jz?#YOhF_otCG#Pk#J6St_>gBv7iZKqX#DscKVb=F
z6U{r#{eXw-XstK(yT`lsRH0^t4b@O%Re)`BcusVA2QD<UH>suFzm|BS{_+D;)Sco<
zNK~*ukS@VgZchCHW)MKGuRgx&dr<^f?8$A}H7+6kjF1tm2VOJEzM`=+bL&KQ*wz9i
zkd-=565dp4qlvdJZ+bz`2!vA7=aai)18>-+uGVTHi?V>CD0P=t3w#J@SWfq=jL?T@
zFQ00v50V}MsX53AxqtdqYUui&U)BR+=-An#qhr_pQnvF+xjhJ+7VK-zdQ{N$uo+=)
z3x0934XR3!f9&K&m}^V<FPpum{5MnJ=Z9<djbc;?#NkZn>s7QTAX6}WDvKIt&JJ5&
za2{6bE2O`_Xa!C1Ibl|ZDXcmSGG-_wV;{c*q4pp{_x;C4TZdGo?@m$ZqlKt~Z<-JO
zft42N!yL&<VUYtDQ99j?#u=|FxG<axw@?0^fD&5CUmyTVhUE1wwy>1p^4v8$@aBA&
zh0e!to0WrF42MDL7G=vmwF>BLx69TqEPk#|p2?t2^iyuH>}#p6RIg<_%X82i(inrA
zgmjm6)gRHv^k_}JnYHH^0|ZZC2h%sg`Cq_p4J~_A(Uidyo{sHJ6sgA2D3gG4aEM*T
z6)D9a?1EP<&5^5J8YnB)5{@)DJECE&McPgtO@Q4gi|P|_A!igBWBzy2lSe33sd^6y
z5So(xi4mw=V6<h&yDq6nMBCbQ#@tmHVgdK+m;^Yvk=)N-*1rl26XnJTPH+5W#H`AJ
ztzX;fiE~^`6jdw9Xdf1%m+{hyE`cjWoD#zOmjHbcF(@vQptMBWW>8q3Xo9?VkEac|
z(uCHJ1xUEJ^Z+DXWn1I0x5$XKlzT(q`7)ouhtp<NsXs!-X<IYb$vyy;eg2&^2f0eY
z%L36LeDeYQ9J1!|R8A3qiwqIXn+&rTjVp~mfbCN+0FyV5`Ee`#JpYqqyB8~@#!@i?
zL#5ydT{5?f8@h0_Uza0Y8%97HqVRHF>a=+xd;MdM3P;-sll_xKksM($<z=}&Ticmq
z!h%la3hvFKBH#Vru+am=tv(!ssFO06lv_fNiR4FUUby*)4GWNb?&3+m0QNFAu9Y{5
z{JD<4Xd|9~BAvL-)|VoqQl>1XJQH*eQMmc3REo-^T6$Dp0P~R2!vnTIzCmmraUUrY
z-V(3({W8%pE#9igUuLoc{$I~e0XfL~DsN&*65H<#sUhz2K(ys&w-jMF#D4=U1f^K3
z+re|8rt104e;MuH%Gpm2N~97g#0oSnYT^SZc)1^S-Orp=nZna5>;5!_fHCU94`A|I
zb$cgB%90&6u%8bA(O(-6%J&YD=LB)c;DTm>@th)_pX}z~N3+f^-?x)+!$$^Jj@}<G
z`egxedWkwNmaP#NHY`YWyCH-(|1L~pC9ABw5?Va|<Zp-;&SRpS3#psc@l^L%!~?C_
zuzfc6gM2Qu%SbXmBa`xsNdmiCR`l7Yuo+~P@<G?T2Cv}IRDje;-Wc}IKGz6A<zyg`
zt1tBJ`gNPz(TTDs)^{XNnX~95)vzE#$7R!@WqT?wL_e7o#H~vOT(bhH2mUbSh1luL
zyKfnE=x$;{cXO%xZ{UrOmXF>6HiN6thK0Q<z?cJUvQRbLk9MqIaqV4dU?oUkA3C$6
zl3~H6pqk^EaB)42_NZ~%&h>u`aSN)g2<bApLi_4i`nX;z+SjsTw9zPQt66A=We0Xt
zNgSKWa%jI@J)6F>l8K%0x*}FeM4q!<>*+0^v)&$2o%<mRDS#b`NQV`pG5{`NIp8n*
zdNu|cfsm3;L!WY(V+h-;Jql;HA+VzE9B;c{@PtiN2|d7RmNbeEd$O${>27Cs-}O)e
zG7Vt*0pH$T`+`=eT>AQK=^FLy(G7p|<4+#JhQtX;)bHz6r8>2Zn!3b<e!bxhY?m4x
zRl}G8P?H4EX1@CPXVHFR_1;+qRAp2{yv&#Z&>UG$q|;29lhk|ko`2=ZVrG0ye?L09
z0L^Zobv5sZ+1Ig{A}!2R<OEOIc$~By2KQ&#lp`oQl?GSF#XZN%#&RY6T6!Qt_L_EJ
zQPbi3h!l&EATqeorks>}DBnf~)vTkXRms4}7HMdnAZ8$l*4sOZ&CLTyFsP~Xx!VEN
zW#~@S#@!2mBjd*A$FxtEZG0w7pCg}agrqZT-aallJvOo}zuk)z0v6W7sW@TIig>qR
zj>{Fv>NUB7M`;!I1x8iO?11Z)r>8x-f3ZmNfVGr&Xvvyo$K@XTwQ4y@F1dm!>jDO|
z=YO@X$TUuQ0cK0r)qqCF5Ijl7$^mRX?dJ`zFM9sYyZon=GDC#f@1sg&=6szBdRGH&
zjo!7qM=kA|VDHP;Q((^(!diWRefkhrIYz9O%0wpN)6FhzKsa|qiJ(~7v_G&rE(H+z
zDtrN*lk>cqiRquU$1u2lCA_r%m}>FNLkPb&)<AgV*zcCcDmlIFV)WUVIDbpA`3g6d
z<C~NqQ!pVNgJMvAA+Zo?2Jkasl%S3~qmYatj)S8YHQmd#cI3fQSQT>n7Vu?HA$O!m
zXFmhz>!$ztG{!6O07n}cfi|AbG#3|Zc@T5V*V(uscZ^PngL?Z0^zCH*`DAI>K9M`U
zsHvaL#yXwt)7lw}Sma+MdxNFP()OEUG=Aa?n^>2V|Lp}3>;S|q=a(~1ET<R2ul~jG
zN>j^kAn+}#_fFHSRlrLDmVnvgvKK4#i?!F|Jq3{zsq1Nmf4-yRHp%|9)8z_8uHzw^
z@Lw{~exBU4`v+jB0wKr?2s4Fhd%R5F(tpJfb2VR8>A=3kpR2+50l%W&mQEi=t#|kd
z^u?SQbhUgZsn)l;LjFxm(GxfPRpPN#peO62-HA@X(2x=NWG|ZFP{sXc7u<CBl3Gb*
zyOUF@;^Ta)K_|!5D&JW4dZMaw9<f1N!{Ebtv{y-E!%@x+vN7QR{>pl&6^r_x8@G8t
z+@<U`|Jca9e(m_?MjrxVJXi6$XX;O$O;2j~e1Ne%0&=D2a+`5U{VlZPg7jfes$-xq
zZLcBLz5xSugP6nloeFsQRkLX&+k%f<$hJY(4gyas+ELG{Aou8<`V<)V&Hw#FgZ1#g
z0RRNSU(NkHBB&xpx-BsdhBmtRF|`*K<=osL0a_feqQVi2h02G9KuH*2*G%vafZVp^
z_-q4K&|Zb^oquVatg_qz@$Whbe2cmpqEH_Wj2@tXUMvOicO0UtTG=}ZgLfzm5dy|k
zE+8Ws`=9oO;?M)VRY%7l6shXu=2r5}l2!8jpyZXUPDK>Nl;DKYtu==!rs|$yUQ$J|
zbBSWJ{OS5=0!WP-r+n9m9j=JwtX6lFho3v^+aG=02)MI1+;Rfq*4{>FiEUm(PdS~8
zjSnCExe(XmY0nCmk2b347UXWVr7l4luXMj~Z^uFdv$&)J{fDY;+R@{T@|UHJ&}T(;
zT@PpidG=2Rii<%1tgmo?^8gv5`6C7mI$(o`>*!V*wj9X&&@}{(*b@VauwK9)GN@NH
zmxNa|;A*Q&+O7=P`~2iNJwamLQ5HTO5a=8MFNP|AjN4c~6A7Dob<Rw|2sDZidI+dD
zUY82n3xYU`Nql0ydh{9hPXUp|@%Q17vTjx6xX(Y#TroUzJNYoS;?qCyX$JY=Kguy>
zZQoF!9gZd+^wsL^n>Ph`^gqn<u8V>?gHew@>-_lm<}vfnRT-ZGbM&u_5p^H%;vPMY
zi(?;f9JE4ALjnVrvld_u1IcL%&9ys7-zU0OM-pyF%U8|tyE|(K`v`6irKhxkD~~%f
z19TolpPyx9ay#)>R#sTv{u0%yD7D_0)gpjfQ<J==c^{TBN&04|>Dljg-A<Ls&##2l
z!Fbjx9Q`$5RJ+-$A?>-Bj}C<LBfNjFpFWgX>T4tgjjc8{CqBkjV$=-LY4DR+O8+5#
za!-kG`0U&3c=T<*yo7~TEsIaNBnnhb#O)p!^38!8E6<#z;pWA{Er?3xh=cq`x%6!F
zo^p+$$!}fJyc$3)Z7}sk+}Do=&>X^TZK(Y_-x&pXy>beu3z^fNIUS`eR^6NCdA}R;
z2t!(-D}e78xftu8smefEf43w=j&b)-GcJvOVm`3aN4Y1RR~x_FNNcJ77guiq71j5K
zjm{9#jdVBC0@5KN-AYK8h;(;JNq0y$N`rKFNQ+WKhk$f9e4F3@e)q0*U2DYU%pA^n
z_q*SCo@ej9qxVIqFKa5J_p4v!?BH(czbcz=rFN!M^_s#V{WJ4@l%0*?*vo>>gjx58
zp3}CUXowZm2`(IGGaQIV=?*X?-TaWHEIfCg<;jq<G>|TIh-V{~KMx;cf_@vseYI+|
z+T^c6AZ|Agw{2ie$|Fa}^42d-g3~Q#GBK#F_2>h}WMe|6ki|`BnV-;0*SE2Dl+9=y
zt?zmUcrmP(D2z`plv+<7ifZea7bxJr?c(z33V1pR90=Ip*JE(BwQ%ig&hU0s8>Y>U
zX6{~YlR0%tX_l8VlBk^Y4Vep#VvgYl|9VydKWVCHEdwWeNfLhjrJ|IbD*PcA7}g5E
zq2=E*m?ImdT+<Jqq85eDf{6k$b*e{OJOyUd)Yc<S47?YTJJ!>=E2rCJP0I-H^HD^v
zTLXAWNwhnf1Z-?xpa>iXHxIX{o-sh67xU)$^){#3m#?T1!H0vK^9G}lsZ+VCdD1oZ
z<MdEQ7mQ6WCZuKtf6z<_<sV%{(C9vy2(=z#RdvhN{;Qn>FPU=~)Y*YB7C(&vTe8+H
zn*8}ji{TuvB=^70!^t@xb>bG47x`>yM*Br?oR!pnEuFrl6o*p~&D$?X7+Px4<SdyD
z9r*oi4<GF-7QQAaf9O(kz=keiY`gtDZS!Mu!61e_<VDS!2@5Jj?fUg+6pAh1y=gbc
zToH0^mHg8b<lkHg3mT?Q{Q3C~8P3eY-2DdT%P}LnDlFVMhuA^;-Il7R?cOY$U5?5l
zdTMEMF&8I%VbwPwlE!Ybu=mi0<C#8{?aCN|xEe&KQ+-XII=#lZk-W!#>&+LqT1ZiI
zfU`h_b&CdR<6R8Y`68kQ^5P~`s8SSFi>gre^0SSllOHn?tbU3>yrY3ruTx!C3-!B1
zl{0!Rrm5)aZ;111z!VbsqPSqaLIfXeIl`;%=W<l)$UKCJC2AW;6{6~_!)rz9wkAuh
z9wQk72~)~KQ7*gF=goJ2N7JuYvHS+xZx4o_UVVgyBSlK-j{NI!!T997urxGrNdKDV
zJnvg3b|ZU>Ib>?Yv|+?X8=<*2Tj9up;g+hikfkLo{`<%MgXIEZxUY{m8n*1w6@wxN
zEhlbk)4Fz>54VR~H@lTv0Z0_$$X#D8vgBB&ow9!^aI_^xk@B5vi9LQ5d%PaEp05o%
z9TVah_(36nOpT00hGs;K+*zM$dOyV*_T8$Y;`PkehuXklKGgL$Ta9Fkvr3Z9jmU0>
zM9osWXW|=02-x<1UQ*Jw4$Da$ncA%V`fiJTV55V<yX(`hqCSEV1Z;Wr^~n}l9!0Q|
zsHiAb!}bjBap44F?hl-%{pe$YyR1uok3Ro)y$;1nh=e7?8~s`R<GyL^j%_)}cjA9W
zoT#_a`Y?q$`RCo%8$rG31EJ^weA!F#S3=SWa8ujtki}RC+<q?3flvm1Pmon*PN`O9
zQDI^5{RNEU-hiL%Lw_VO_?@k=6N(t5j^*+E7*TmAC+^YFQQ?bOQ^gGaxV*ePJ!PL>
zs$f~dKz0OZY7OK@k(@e+v{~XDO&_muKTC~?Pmpn^(+4TODD1O4WF7}rf9xTs*G8@{
zej@gOrH=I`xWN#Aj`}f>#FP4Yi<Z9r;^uvLIO;3gg;^Vqn1LP)zJ*Sg8U2C1xgR(Z
zoS%L(JzO+&U|hqMS#$*_J4$|Jj~tiJwT%CD@!o&b=J=up=YXC>K?maEtdwJgySPcH
zOP!(kb}?2Pe(%}KjP2&m3Er7(#%{;=C4G2JV$o)`C@Slo!cp0|(xkF!)bUv~xLGvu
zOEkFcFIn@qZUPOac7mp0b(Lbbef6w+vUu7<nJSvdK^=|bRcNr9FYRskI80qXc2jQ1
z#_CzC5|Bq{SFI34E2DE2SYiFvfOhsStZ4Mz37Hx#D0Z6L-wLNWZPbL+*VRFd()6u{
zJ%lMpNJyI5>|n1by^o+?2ThC?84k~e%;KdZ2pk@+x15%JE^*MGA@O1{Bhu50Xl;)p
ztlD3Ad45PJQBx-W@wXl!z<=P6gVT4|TTUZfWOwA?R(GYDED6habzIawS%yVghz~`k
z>TKYEy{}(G7Gs!Hym%Yo_pKtuc(oSX!{(I9-I?4vn_VXz-H$xu!eQIJO^c#v!L9hu
zufyzaGx{5{`jnlcT9n~*UG;`)WNWP%=W3&*rZnS6VO{k%B5vceJ8v_c>C-B`Y@}fI
zb2ZLfHg;lY66*ECgk18aUPOp{W}nkqDyZguiJ!YYQ2zaPtS^=lfAg1UNR}n*!$4|I
z%3EA?%+>*y3KS#}{O9NTJPYOj8R_C+^IVY8l$Ai?5d%Bw&GB_J<%&Ww>*|u%;nP+i
zvJq{45rj@hT}Y=Bl32(0hkkylr&X-!{r%Ig%VC6R3@D*KJg@5G6fYiWzN*MFAJq*^
z(Zv(!Hq@=0H(tc%=Q5-E=c3Hdo7C1zSz3i*o|c6u^CTCP^S)tS!ctIdH~Lyz_a-d7
zv2+|yDM2cqD=pniS#OxAUTLy<iy7=bv(AQaERI-x#J|?=SgVcqz7{Gn?@urnO<_fI
zcHz^jn`W6|ubQ$dANVYN*(dXFv2A}e#^%k;_~+<kY3H6#ukJP(5n|flb`FtY)i&w%
zj|&RUeLwc?w12l>Q3V7l?>c<j{z(}2N8k_5rw3QI-1SGK@^3HiJ%lZBEG=`d{=g>Y
z>*ILtc--HZ^2$8x_$ttCCr?81-m4DMe62Ucvsz`>t1GGR#i!ilyZi4Sky!gWN<~FQ
z^v+bVo9;st-;&X<0y%wFA8Bc6#WbF<I;$B>OZG6S3*{oSUqAm{%}Grm6jiM9^3qh(
zVX$${Op63Yvr`#p^wf|Y+qDeZ%#*?~Qg<m4h?5SuC-w^PEqG?}FEX0B`gyUu?nClp
ztlhzYkd$8LHaV)~<yLEZa!gafip~-W6TL6s3MoaP$H?b+9czsyh)1gtJZv3U)@V9h
z#6Eim`kE=~E9WFqG{?#&QdHj5K^+LhOs^5-vD-QGDCg*gY)C)qo>;}hrl+n3&#z*d
z;fPt`scx1-!^+)BAf^qHVI7aG)qfuQXHWUfa;#25Z0J9Ft#fVpp>w$Ix~5UwB0iW_
zD#wH-<!nT?99cgiD4bR~#BhfxP&TgI#Y)7=YWsvZHJ<CKnNiH3b^=@Bp+EE3ubcS=
zS5;jdm&Bsw_>;NVS+~8pIjvA31s6D_dq!hzef_If*0Y^l17rzPO)>Zx>FFBig18F5
z7D$R)2ip!pWmD*|w@lKV9jMpvZ56+9@)V;5N6@0qS98_viQo@uqrE%4M>Omyo|ULE
zpLgJi-VqYTgiz1E+GJuKRhTPQQE$E=Hlz7D%`Bt#FeDbc`-tH$>f+amlodYF60)}4
zTu?wK?&G8IrZ+@Wkl?XeYpQueYZjxfR@9gFA)lSG`a;RXP88FBOQG24z?ErwdR*4_
zCU!Qw_~_uVoPE7l><-IyiXez1^06^{;$}m_qLsd*-*4m{vR&-<X~eO$K`=eWs{@B;
zlShrz<6>Idv<rEKL_`%L?-i#u5;c^KSG$9SFBhE34BFD3l4D893rwLs&iEm^bUr%<
zT!)bh!`t~8NaIGlf_9syi>JpFkHBgWUWk(hYTDSM_(B%S!sIh$Nm)07qkR<SMJ<g=
zRa@u!%r?QuHwtW~%Z(_&GIYEgq?i0{eruI@Fh+{*WXl1lYU`?Dq~AVa5Uej-;1;13
zDf^GoojID$+px#kQXJ`bv!l9}9vkoTD(|zoQ+$+r7xq=R4n<;~QMLa=+>>?k^nuA^
zd+nlFeEljz-IISr>4He39kN&zR$qt~)_NqfmVHO4`_KAj?YmSs<E9zx<?9lWy!42C
z7RQLv$~;1SXB@^XcbXYJCyeEr>4piOD51kvyeXc!Mh9A_tugZ*b;iGid3m3`4%-M}
z_16!V9pm4Nv%-yu7TlJ7f_hesm*Ts7>(NR{WeY^mX085Jj6dv0G8FF0dwxvoW%n1-
z|0$n^0W~;ZS|o}q?`<pmz2^h9DQv;~lo3*W`YqiT_Z1widJH|r8Ao=gMWv}z)^GYi
z^Q)L9R2@M~ll?INAJP5XyW3|k=Vv)+h8e_Z-t4tSr&VQ^`}Ic#3ib>ALk+4#wt{)$
zQg)z9n2d@<$j-3~EY|1#n#>x%-wLMTYn(<z2RMF;p|1dVc{GgoN0SdDQF>2owlQlI
zRk<Ip=_#oML?y<@b{w(#tA~H~_(eb?R2W$!m#YowdSgfE|CP0e)^s$rybkhv&jl(s
zK0)D_UUEroiGXZ#!(pR=W!jx6@{()xHTAtTxbOHumdpI4x2AgzQYquX*r{F=(i?NS
zVQr7Be<=(R7q?CB@c@d`nkVlqqpu9Z>*$QGUlF=eG+DopxNV($SM8`wh;0sidq$~+
zCNBLzE93%i=~xY^wGpy`o_RQH)gS(gvTmmS5rF3>u<&CLy?$TYh?jcMjG9R0bPLk!
zy(vlH$NYZSEx*p24^Gr{*3WMhWkqQF%s_00am-b(4<r3c<qf0z-C~(v=A`_<+T&li
zFSS$=rBw+8%_DoFL$AmQ#DnwvzU52D@mj;e*jNzIjD(HjtQ#iWM-w5ekuo;0di|tK
zwjgm9DzviXU|0LBA`*y6*Ca7H;XJGpqXBLKMM7TqM>HH&{n~efa=*;DCG46;REXr1
zo)%33=Zz_gV^~YHeeiCq1iloyk#5Vm$_!n|LG9rSd?;LF-tcSGueNUQh=iy};U=sb
zAa4RqUkbAG)AV2v*!%o@_#)2isw<g2-H|oHa~Uk%_&Sy41kH_n6?KL>m<r#X)&Dq1
z`nOVFh|uK39=<nbgPj7k{zr1Y0xw&Nyv1K?OmM=aa#UG=UD1q~P6@;%-3EGMCY(pU
zk{<{7=sbFAlV<Nwl=9c=_Uq65(dEi`>VIBH_|Hrn6OHx#F4ydA-dFB7ey0O@z1o{2
zFuSeZ$bdInE&hD0Pysb=vVb5i(xle*S&b=_hv(8PjbsW-3jZB-MCq-~Jv<|8_xhwh
zeQ^->mu>+zd;xL#0H&I7>q9c^Gh(TAWv=ZS`-jWl3vr|Sa8=E$kZzoM+p5oJp>JtE
zCpz;8kC_Icp=n(P+XPyg9gNw$vXd}M;FKg*fb2vb;G$9aPlzD2I|QD(i3vs**sqz;
zr!mMi7TBcyCR6augEZqYI|h0hsG2>Ofi!mzIqUl{qUFfy45MyIuq>KE@q;Iz1%Zl;
zs|AZ4I<gQPIA_AXh|jcl&uAWU^b>c}N=;0o;35<>%_!+1&vm3_^*A8;`#zD-lAm|T
ztG^ds(3vHN<5<8`BfJl|ZgysK$~0Fe?$nWkSaR^HBTF~Bg;bbN^JaHXm}|y=Tu83X
zBl7)?lRx<4yXcSCgejlp`W}Pf8GI`PI_HWcnvp(9Y)Ji<XZ|(NZNyxw%?PWXtQ&DL
zm9v0YP(!8U1Ae12LW?=jl|KB2+ver{so<?hMqX6QbZX4$8Q?siwt@K^9*h{X)z@@3
z|L<2F;U<)^FQoP`t#te*9XH_EF}#>CymT7AhkdlRhlZ*P+8PlCv0Oxq?XSd3MlILG
zr?QbkznFhVh%^vK;TP($_{W1wdUhkhAG{tRK@lEE;Z1=t|KosE*CbFB$urNsd7a5I
z7}r0%%mfzAQb>hhBqt9E&$tu^pq;grs~r`z<F&aCq>}pB<NWpVowHK?<3q6N{zT!(
z7qq31u*h0m?X=LwN>+I8-EfUSuJxY3^z}CD=jaav%!Nj8!(!C>M1@1%ytFi?&orGr
zbdfS%oSu#x`NJIbR@(qY`hu9cxW<HkvXE}W1ez)j`OeC$hn6#i$?gR+BO!TL=qtQW
zTp;~=JjZnD49@wrJR5gklF-^?3GtWg){ZreMkbw)-<-|hu)Mv3{eRJL{4s|*Gs_;t
z%30If{On$$Mj07%t_@(R!jp`9mk4=lMoe0sfXGRrf~(Lt;6WI{_}z{JPNXCP(VpKT
z38Q8PQ(6ACM_5c=PMG<ecCylh#R@Ny+v$}4+t7-RkHnwW|HMHT#4albelwwX5gR_w
zWBPdD?7_S+iAaZ6;Aw`{zo}1l!r3f5Q7kuhILU;0-oWXy%&#w=h^WfNnTVzx_fDPn
zucBnnZ~E#WX$4&}?v3adx4I-W5CrdM&`Mep#NZUfy~ck(PKCAc&s5d+6k0kU!Xdqf
zQ<f17&xEszo*OiweWfO>noIlyo$-SEk_eYA!$`&hK$NRC<u20>Ek<MB$zSs=Nd}*S
zpZhg&qbu=?1RzaxG2!zNbHDgfpCDCj_N$0zFE>{}Ue|18>$OD?Q`y>f_(D!Jk@U3O
z;_LzuQmW%)5w3X7A{@US-cQ^eS9{`DHa9-c{%rd8MiU5;hQnn+BPgJVmI1i@(?!(A
zFiSKep5H$ZRgsGmCljlsBiYebczMbSlwMk{^YZj3A|0KtCG$AXJz&3e@9?wRhIfV{
zc|S894otmgP2T5rkq3k1h5we)sLx0hPBreGH4H^r*##b&g3`G!g3{Ry{NAWx25w~G
zOEbfF*7H@~T3bHJ;Tn`H^j7%2hP3e4EIepbv#FBKUAvR}AH!Z*Q->jzc<S|=e#8%L
zmEERD`7jrB$M9~`S22HA@6I5wI_Y)E@ZI7xix~o3WwGCF-{GI{6wf=iCaZ3~j%F&p
zPYe;hYSmYuwM?U0;XCrW-6}{RMx|DbWPKVwmtTwGdfI4Jwk-*TDL*04er1ZIe*c?n
z6UYv;f--Rb&@cLqbMm!q30+Aa_b9y<v-6%lD1lS$BbUE&>)ZrF&RiA*_f+fi-u178
z^M6;0<ytr?xO8C!qy21bz}wU&Bwd<1eA>Ei7TrQ@U_SjNB+b31|L{YFgYKUB#)ujP
z>~ZnP_ZZMj2AP_l6Ym_?^9^Wse77wAtd1P;W;K&Ad@m2cZNszsn(4{}ouVd@Ct>d0
zdF|CAP%|X79Q@B_0s7XwUz<#NSMb|;ohM5_g61sGU(QFeVEJA%^Cexd1=RTyR1ju?
z;kfSl_aR9_mF#Tqtc(6@E%CcO`nXzb3E-2GMlt-yNZ*s~mA#A11yF37876t<IE~ad
zfVD7qcJ6EgtD_kb2<WLTI)Xq%jES~^?VOrM$P}A1VvVW`_D$}`nP$8*gFHpyJ_o4V
zKGMPlF4{_R$SZ4rzM(if_6>d>fg7_Xi^Ik~N%ukJh1H|Dy9gJ($t(ABV=u<ggFal<
zy1~cgDb$RJAJw`+cFK{e27V*oMEW){mKP|we4o1D{922)r&jzpTfd&h!EwCG>#V3@
z@^36Kik&{$+!*$1i26exQCd#PZ-+`Zg18U{W>k-lHW8OiSV7J;Kky{k=qiZRo|2{@
zi9TYEu3o20CaSm_`yH$PZz^A^k9l6WUn)?<&tMWM-4panzP%DVX>??qZl6|V)xLEd
zM5DEf;JL?|bT7zZ8Fi=(m=5~tp4^ZQXl`G%3HsV$!|Gv%{)-|Zj!gU=E|<$fUu&5#
z)2yu~!p`Ej?C_0j6s0fJz)Wx<L(9317gr}27i{tC!jTVluTFYD(0-CC2+dY@m<Tk7
zSugyW-@^DPgRb9Wx+h#TTEi*<4P=ASANP*geGAqO5|S<<UoeV2CWzd2g_ww(L8c3G
zm{ynv*I&WV-F`)k|3*d}$wU@U8vjnj|AbgZ$Brop(L-pfflDUwwXyKo+2u1Cxej~p
zeMdmYx2?~_ry-x9xFB^`#DF>0YfaH*+u7#UWv?x6{o&+kno2LW30yW^;c{6E%e>TM
zdwVH_KHB`%@v*<HP`kPEcB@EvVj09vnhxM~@v(A}8j0E*=g2PlEZ+)vq-_UdgsSp#
z;%ar1(90JKQ^hnp$3LYv9yY~Xbr4Qt?>jpv(XrL@3QFe)SwJL9F!fjUt=Wb@=t=vl
zNgJRmnb7ZFTroscjT`Bib7l@L5=Pg}>|J8WB`9wNJ$%XTj)IbbT^(z08&VKrbCy*#
zX;MJ0yQEv$y<cGIolgY>Km~GmS%N$qjs*6Jz<$w*G^G7}k^oZAEA4S}KK_e1RhN`j
zyFOuvWMQ?N1&wE^zs7p+LeoaXhu~;CvJw?%Np6@^a^~pk4dheqTw<_DWGN~RYTC9B
zz7+e0r$rim;6EWWa)QpRwMS<qT+9oDXqi<wYmmi%VNGP>bPKqm9;X!yvi~;<+s;#C
z#r&N&MNGS&(ji-L&8`}F933q<+xCyqFAmZmaQJ12pDeVKqhw}?42kpj7rd}ErefWn
zy<Z__Li0!!Ecz0b-;?;<%Zp5M3Uvn28a8IfM<nP8af^98b?1RI&~HN4S1gfjs6=AP
z!Ox?zGJR1K^OXHTjXpM5Y%;+j>RRT9S1LjF%7P5?#CRlGH5B5ByE;F@Eh4PScGugW
zE4?h4ow3?|*`Y<5sPMu(0Nn$FK{NO(kD#L5EUa&>`20s-GO1h=*$$SzuNO<$WHa%0
z6O#R`U0$hZb%hKn6NX1iFiL@m4BC0Csu`BcJ5@7sYAL~0TEp<y18Z`C4ni{eo9O6D
ztUDrV_zkjh-SFwk*_3ud1WIQ<N;X8O3qryT`sas(3L|C&Xf_v}mBx#M35!pP-%!=w
zQOH{0ld7u^CSyvb2-VqpDn^x@h&M-NQGAz~B}o1)=NaA{Z6PZGg&$Ub{&_LlypAyZ
zVn;tZP9i$uof+X%R2tZEj1?g~Dkddux<9`3c$~7iH?a6)ao&rk994dt^cr$;FF~)-
zk8iB=ifw;?$dwgJYu}uPUxU0u_$u+aM@!!>aY(O_|5b-*N4M*PhW<ZOJ(n-4ol;;l
z;6Ca^S6z7Au#aJ*61`2nVn!9Pb<ek9fuPvwG%)-z&|qBQMZMr7wM=a`Qk0HG`D6TI
z_$~;J!62q6UK~GA0!3UJvucX{n<AR{aQ*dV_;^@<LhF?>1}r^aC_BpL$C~L@k${uD
z$9y46&<e|s0X2gS#0>YcJaH|S6l_`;Vg?vJ3EzBO&8l20_t6mp&3L(VFlkI&+&im-
zZF@{VS{l#bg-|nNcvQ1S)X;E<#zf;dL~k}$mJQcPh^tKm{(2TH2{Jo3kGv#Be>Cb#
z8$BGnlJ2$;Qzm?$+-MT%X$MySIUIk=^5wCM55>NEG?u3e>7=gzeDw@x6n!-CB~ui$
zRex=AOQt+=NN-ZE=e$zX7JCg!u&Zmn@rRKX8r!9KMnkis@xOMI0Uu|`;a8oVEBoGF
z)usc57flfN65`ALu0eKDz~(Q6+G*cez`92qC*qApKJ3^{S61L;FpKD|%v2K!JUSz1
zKNfL;L@AccL@(YP*4o~T>A%R3oM-hpZIrFG0Z;2lXn%;(Fje)JX+wDI@<uOexC1zi
z;D2WX1Qxxt@HEG=!fMyl%>^TE+#%Pw_2oG;BGk?`0t3rUD@1RFo3~p;8|tE@N^lV?
zcoQ!d@vDl^ZbV>72u-|FrnqLLGWuPx#3ajqv)U#wG5UPO%C)z&w)VWEPFtmHZbBRw
zBqo>3E#?#EY#WJx%F?2&hSj(}JxN-=ck?9k{Yxi#otWXXU~FXzyx>55)%P2KBG5>=
z5-y?bQk7${k(bPJj+a5r9;ezn`~*EGA^FgY;~(Y<{U+D-&4e-+iodSOginj*!lJPO
zA!RmiCUX9XI-4%LJM*P}bhq>qbk^y;0EMLK-^7=oB<jV}tgKjhp3Q$ybNu|Zyu=dJ
zuQD9E7j8a>k0^X~54QVru_`VmBJ+)T!!&D*n5Yh(+I1LPnJ#{iU?4BE20{=jl1S(!
z6IAy$R~4NCOeBHVRxz3I#d#u~EG$-Xn7{O|)Rf?1^W}cr#mVr|oI=ir)gRT5bZodw
z#Y$B;0Nf5@Y?&U+;HJ<gGvHSoVwo&8Vq$O`!hMLNzz5`E$L9Qkcmr>POna>37*}0d
zy1ZHB`1Y4@qJbsqVlQOh<*M#Qw(nvv;S+Z{K+y(V(t?@{%Rcn{B@kWy)$O;mI2gd)
zLRh)))rz^hT=soaf9*<M!r&rZZ3w8mdpnlq1~2{+)xqA+y<L`PJ<yiwh9;oA%k8pJ
z{0aBXw#t%>B}dMQPHh5(q^Y;Q>yQ^2QPJf16}SSrlC#2g6=^1sHZc=5{)Gm~#R?Zs
z9VI?$pRyW(xU_PtdQrI~JvE2n*L~+DcdyZ8_T=V=s-mI*n<zC!{g<Uk3QJj2Z`9P*
zXh~FRyj{q%|M22P=x(POIeYj^UXXBqR7lFv{mzT1yrAPC-j`vH3#$Qn0~sLmp(7MO
zJjwx@QDXGAy0T3wavlja*kp?dEr*72klbXeD3aM^><l%zvSR(3kMC)?Seh5`qR+>h
zc1F|QFPZA|Gb4tM6OTvO&0rr1NIRAOyaVQzWKVq&lz^B)wiBG=)`>&@k8g;se&1}g
z;X1+HxqKj1v~<W4$|(6f2(BpnR)Y!u{tXC9%GfntdkgK{FTMjtTi*sx!9ZtVC{(e}
z%9SiW*=FiDZhr2Rm6c>rc@z%1{!6R(hYsHK)L4e;d;+JiToBm=dh0WMf48BufKDlh
zCGiSe7yc>ODaSe!Dyt(uDFZIW8bbP~iNKX*-hIyo+3|c-jpV&aTl0^L49z8J*1xFG
z7bsG3+!^hIZMvFM>?=p#^pxasRq>I*{B!(l%>n&EYoM|9?Vj=I(yt=-g8~{aSc~Xg
zA@`c!NIlULQ6v!oWNqZXpZ@7%*KF;pGKB;><H|Ogq*~;uGA)EW#S<zoduTDyyS?=<
zK8#08#W3Vs4A4!>|JPGX_|jG)q`dtrCY@z8kgrTk1iDS|5HkN62d-ec#XapU`3H3u
z{!nfbvNZe`Q}5ykwUwgJu~Z<dDCmb~_^83Vs^&)c0$ug5XBPY#Eq~p^a+uJ69s5x~
ze=JsIdKTTB&g>Xs06EaugwxzWd-0$GrWxYXH0!Fjsr_69c>xMmtg`+K5`XZ(_~EZt
z9)xPTdGS9(64k%4+lRO2<Uh-CgtFj=2dw}14*#Nfh!;Vi4Dvg8)i^QWH4?c*sQ=l@
zMritn_lupEstDh&S@3d9+^gBpS}f6W5S~6l_VkgUMGH1@KB}N_=-Uk>*I~`71S*%H
z4ztGMd{rjBFHg2o#U>D^ev6(%!y((^C%K9IE=?BPFPzJ!>IQmwimQFaYkszU{P5Kx
zTBuZ$-*eQym8bTPyTHB)jc9?*=sBXK42F0Tv<y6XXenZjxz2*~l+s8#U(8o-3&(lO
z;%eK)W`mTNf%Ut;d>zJ5baWbTgod&}@VipYP5XXY(uNlQLi}x?+8-JK-6#wf2M<oY
z_6h2~Ti)RKcz@}1e?D{C36Dh;v@*gyPDc=N-gr0ed%;cNee~KFY~KGwVX5iqjXcrJ
z8X6kW7NRe4;DRCmfuFeDT&hAW9Wa3d|LuPksc1{@GvPXD-eqTRJ(Bo4o;`lHGo@4e
z5vQ)MPWW_$dokIt!&d}L^ok0NfORD&5YyymBJ+a#dQ@uB5Wu7P&~-UaCJI`1x8;~Q
zQFBu3x)*2b%S|A_D6tOvi`M7={?yjiRxSJ97A~WO_Kc)*1#S+f0MZC-x=%xf>9i7n
z<f;RB$!rVoT;oF-GJ=5BZ}G>FB#`363my)u7jMN-<?;uy;b^-@B%rIta*6>`Qd-*5
zYN)2x)gMLL!q(xs{~r8fpvHW-aXnh-TY0%TpqceNHj@;;zBHG08Vb?nq~}4Evj<@K
z1bv#q`nEU4mNRpKPrTKh6nbecL1`gHY17hmLm|c5<O4<y>7Y2*OV!WFiAJHrUv!M)
z>(XVx5<FW<756)L3-T~dANVvwM_r7#=fgK**}gQb0cRQJRe)HMCU{3BwLB1?spuc8
zFW*M@p6s#`T*SSNIMbqN+xxzzj4n(H_no+pyBq_3oNSQU%V=|*9+6B|nh6&S=DO7^
z*`@XO(Anv~!qD`hxlNy#0ZH(uVKY5F{d(`mc;orBZqr&g3vy`Bf-B6%`xdtRVdqz2
zVp0;uCkk~`d3m_N_YGn}J@737n?hYiL39WB{;N4oKiF!0;#tbv6VD_3WNRE0-V7`*
z!I0`G)m=__Wq<h5FxQ*IXN$E%O6#~xop#a2Q}w^!{C)SaT{R|KM$}Mp|B+4H^Zsq7
zH^v(WddO%t-volYd})p6KJklso2do8@r!+o*%J2;2CBM33*3Vk63F2Z5#K5*T<d0-
zVSt(Tgk^i1R%_qb`G4dIAD_8@W<&H$NlA(IeJzvCu`Y14)2;EXI2nr7NbWJB-@>fJ
zMb*_Vs=F7#MRMK7lu=PObP2)7wG4$+6j4(PWW)#G(TS8$aZ$D!Ux4vbz;($MTvL&)
z{lyi{TXs*cXxKp_4Le5G9KNV69RKt^R0@5ELpg@=PP$j~Az|?5opqxfv@4%o`s17I
zbp}$tsk6cJ+4885n|PdV_v%HjNUcd*%9%wBpB%yxZ88l@`!U4|ncNHUm*IkW($!X}
zrNN2r7a7@lYl|MkhtP>?u{SKlO0cb6Xw{wh@0kWO+brVV>O1MV=DIASD&&{}G<KgO
z7W^RlimqgHLU%5&^p8B<)8()#RynGPQ+Q4OJ<{VPGQbTc?lu56^>}@tc)7B))b!?T
zXEC|5q(oxooc+L{a%Q;EVSTpBxF_~+ysViDI$eUM=D;|8+TX+gIfg~I^EmaKI<!QI
zdB!F>gTquxvp%!C0sVwHE*E`ub=;ix_QGM&NrpY?-FU-<*&~Wkl}G4d?iRJ#c#2SI
zVb=73U%;Yz3@dTe<=}AaQkEUbSDL2skov-o{`vZVei_?Nzu(UXbJl}p%M4$`YSO8R
zWlEQx3;hau_b8wgv*3R?I4o=JhAWO7^%J%Z<RP!@DtdO$@z4n{E}ilBx0^>`rVI&0
zA)!(<%94^IMLSxWod)*hcbPzq(q$AoW8lShZ(wRl%c50bcCk0Nn4B%*^(sv2Ga$D3
z?hWX0jqh*H6;nB>8J#G0W?xlAJx&$$PAm#sdQ+#=?biPMeuddV#FN=O&lh%gs%+hI
z8#VsPs=#KbvMT)*ZTIu5=w_PTH7s!!^1vq^uj}Pr$ouz{9XO@Nc*iQqQx|84<i~uz
z4DGbOL5HcOv72~Rv`V!P>x6WC70*suo`J|shl|o`@My0h%_VW{d9STm)45I_8e+xf
zUu5~j-d5SKO2{iH0R0Sl$HRH$_mYyesvb<*uZlG`uvZef*anp;b3ZJcI-y8M>y(eF
zyA>_bYilO9%{vS{O6wq6ksgc^bA4nlhtHQ=op0Jgb2V*2<do@_rsRfS&Ly0v-}``T
zWk5~Cdlu&9l7&;vN6|Cij)TMGQf4pIX!0WrU28?`!Vi$xEM*}|wW6LPu4RbUq&_F2
z?pUH|xjV><y?$pgmR^oHL-R3Jru)P|Xg>;3W=Md%z&7NvE{GNxmd~^N$G?X%gDUPH
z!QT8uil&QqMo$vheJn#@!DA~EMEMX5QvQutN$n~lC}V~_9E5M#n;VUged9A4I~8tN
z6&ON?%SAVh_wNNqbYH%#+J7s=AFx?Ng|CEqhC{*e@@+`ISFort!4gNd^u~1`ov3$M
zZzzY0?whOb=qt3OEo%d2vnu@MYAvCIm2ze4?CM=%;Zx=P_-htLv36RH{Qa-#a<=yW
zlK;A4h;Q9#R`B)N=SH_>(po2F@zR05#Rm40^2?&GbwWB0TpA6EXt|}mKA8~!!kJCO
zkwbkD>r@=&P9GnzTg*ux)+=6@W~9Y&-Fjv9is>ld-CI<bo26U^Gx}R(+vOxhj}Cf2
ziy*h5KKXe+m?uA?BXjYdqF=c`to_0*Xtj%bYgZu4{IR->U$@>mub=?8htsY7GYw;8
zB9XYiyKw(>IVm$s>A^7(D;vf)y4ck$f0K<BZHR`-hXY)H3Q3JZ))4>9FUAeO;d@M*
zUNVe#r3y1{EyE0h82t}(rrg>yKCFnWzywm`;8sFNeftws9`eV{4Lo-`Bp<Sb4jPlT
zvUL05v4qp&Hd8qKq7*npvO_5iB&4P32PpmM2FTsufYfI?=Px)yr<mKgTdJb<gt0C9
zK9CZ<BEH|qV=YWZr_mnD(S9{QMyPrAU!jwS66XBX(g2y$8SF`eR}=B47O|@9h{iG2
zELYX+a|B0wq|;av)&1iD`Q<zI=4}}=$3f#B{?bftt7!wE*wRQ$G!t!QP6vEq#8cfw
zQ@E|t)X*v+Ke@Co&D`1bO8_d>_m^owf|H1j2;J4IvW)feI1j#yGqP-y>;L-}Ld6fr
zCv_89b0`^VPaGs~P|O;}KtS0}#4|OhEOyf0|Av60{i~M2H5RPirtsUh)a%oZ5kx}0
z&jahw6+6FMv>34m<aE9nH3NgLNg2xF%XYW-F{d6Y0gsy(u*auEjuhI@3O(Sn#-nZL
z$AG}%B%e}WTvs<}`Tjr?q^s+VgqZ6dO5bt7y30{vgE-{F|9BU{%(lNoU0Ph-U_ICU
zN6T<*x3c5&%<g8Xp-9^4SPSx8)?lqkAMEZprs22?sgz48(Bl+yt@V_h0pGC|3i3M$
z2+CPL00?TZ{jk<6m*G0EGm<GJcHah0zF~D+bV1_f<=v}?9gL*aX*D!4Kl`strwO*t
zM3hbFt~*CNeJYUaZGNoS+0_&kd6kaoak*IIX!%%FMj8e_m3dVl#@IHlY9%Hno*c9s
zRvC4<00~`KrQbcBf%h@uLE9xoMT;%ebRgQaFWjy1xIdfg!-zJf$k`FQsmRsJ{er_l
zIjH0$E?|fLkz?Grmh0gx?9?Pt4pT}EIGBWLT3W-PFdJG8r5utbypOG~*L=7d=*#dr
z*jezoyx-T?yZIZ&NU_?D#<2-v!D`2&Pp0Ahzh^~?Uw`7rkd1mBmapVRjICN33dK?0
zZ_C%)z<z?!Qebb{qp@w-S1w4rJ1f>Y9%8h*0^-Y&+3Iz$V|j7ozmnmrO%6hbPN<W|
z?LOc2j!Na)+0^*oVMEc#h9%Fy<wsxRH-71H|2Z&CVNMFdK&$kp5`+=eY7##9YlCK~
zI2Y72flol_W-%^e!EGL%uxOw!lGgEf?<@LnMGN`#>6K9$!=FF-AX*odl%)OqDPK}j
z(h_;PosU)He#~~aM%ZCKmf^!KIPj6@XN<2i*W|~b<;REm+VlO@&_`u+^XDmgjyj%m
z*^hUGWIkuPcc<CoPFJfk2hMweSfYt|D#FD6rZFN}kGCDSS1W<<$Q*hnfl@<cuV(n{
z><W)jd97INUZ6PB71gfwSg^2gv-R$zL#OemsCGr<{_Mv!xR1uItQP(i|0dz975FFr
z5S%o-yF&54JC*^{u7~(O>J7<LD-+J5-<c-9(~)bu*@#?A^N1~B|Htj(g)HIG@qk}o
ziop$`ib!1$2C3-!ddy6f!}^xxYxiCpnd6NF75kH+0dDi3Jby>#QowvtG&g_e8QI+Y
zo`CI!7cBGF7ZF@{@&;3go+5_ZVyxZr80ly=wDkIHDn?+hs-ohryYSe2UG|05-tl^i
z>lA9RgjBv71lZT~@0du{@K(#-OY-dT@ibm5CKecGCxzF@znYPeuU-x_`fiXTFy_rs
z)wc)SNf0uc{~ko+*@s38E>1wUcBQd9`rGKtD(OOErIUno-m48FQy--U|4HhqVP)^Q
z!=0|U532OuM8*`o;v5s$lCW((o<Dm@PhWU<UU_+X(88kKe)rD6Yu_Bq2?`)-6>h(5
zn}T3VoWPcsdTkmOM?NFYI1ID7nY}Gj&TK{l2UAf41rCLZ@G;W>*=gO`oyGW43eX<4
z!UQveO$=q{?opcZt&<nmU1#fqD|XM4^(=ITF2*&6-R@gYEyBBU_eenK3%XtSP9dqq
z3kmgKta)BWCriG{L42?S5FPXLe@U$mH!M$64csqW`$<yeOV2YR;D-g3q$;A<SQK7+
z#vjHq`iLzudMF>=`D7?O(8om@SVhLZspZdl9SYoC4a^)Zd9k<yed0^Oad^zs;U%x}
z)q;ffQMLxwyn0tWNCKmZ@&3HZx3V&my;+Aya-nD=&R!+H`w$hed$Yl1A&--{OCDS0
z?1$wBZQ-(X-MwK6sls#B@fF&~t|{i=EgJ^q41~^F%a*5Dvd7tfE13n89ng0(3Er)?
z(MwVV0&Dyi@b1V3Yma8%S{1ywgY&SNSXgAHc(VL_iL?C-dP?3MI*sybRrz>{9J`a*
z*XY?bnd1y6iwqShkv>gjkKJ;<IiE|B<|sa!d3Ntz-DMD;?Q)AgNLDVBhDo`f|4C_S
zBO$$2t`S&|{K3r5zN*#HjN^}|%pV4FKt<by-xZh|Pt)USZoJ~dpOPdH?mUn?B768c
zu5CoGjGlMgE=mCRNaS0-<Crmg)F@KP?#l8y82$ZyYStqAUK`}U%GMLyY@hmQ5bHBj
z3?KM_;K~hpHQmrY{B--^4v*(7cERxp^ujma93L^Cn@hgiAR=9qrV&r5Sv0ZCU+4_%
z`DDNL_!jO<9`^ULvbBGukCac*9JI)g!b0<rOfM=R=6YG#e)AFn5;F}DH-kcI-+D<;
zh6(@gN+8zef)mHK!-$58NCKgucNQXA#rofLyTi%gW|v(85FGPt50{;%)<m~<kKLQ@
zPD-0L;!m#z#3<Ic^JAVqX>q)kE^xUpHQ^G-;p>3q`*;guVrQr5<@lBK6&xF&)p0}a
zcQa)|;df^Y7eIwX;f`&Q?els*%Ip5TW1}8syV_4$nGZzSLkYzoWk~!5JE!~aOm%dE
zyy5kfXptyev*i+sjusEIer7*7!(zAi;?>&xL%;k(6y_|z|7{afm0NGwSp17axTt@F
zOWNI8r|OmtCS~B`e-+Ni<tm1L2wfi9p8b@)!B|3Q@0;fdb<6RDvJh685KR<#v0A1%
z8;+Q?8<&!Rwq7F6?VC_KP4Vn2*_|v!BW8L}V|uo~WTnjX5E+b9MSv_x#65v&(baM4
z%|!$`8t|%_41s<1Hf7IbASFcN!4kQHl)p2T;+%K_tmeBsl$6XNSkRVo99%VVDoFr;
zsxskUe|{=X)*Ag6r!dEOc;3O=KRK~f6@D&pk1#2?f@*>Nkd3yQY-1lHYhmX^K@9{G
zszC40gpVq1@We`Q4GKF!(?i}k3{LI)D4{y*Goh_uZ)5xayf1yae9+V7X$z>bUvvcp
zKFgOuJoajtmQGR6v3h~%&QySqBM(ty!VkZDdXBM4Y!6fDZx=a-!HDI2jrSY7YiZL3
zQd$;+vD;M;P0as2@+9#eROL7)DT*e4ptjDLp^B3Q%V{Pia0|Z+JgZIdpQNiV)awkC
zejcFN_?6W5iWo$Z7||4uox(@VYcFdU00tOSg)YUz!*6Um>RtDXGaP^NrHcAI1CFsM
z`C!{ODE)LVaUN@M1aRS!6a|oBSCfY~&#ym5(8<!VIxFSLy_P`fd~G~1Uq!1tECvb@
z+l{pdj`a*D!JBgmw*{@H?L10{LF!QRGp{9gQvoyry@4Jqj=7y0g%r`Tt7AMM&ZGz8
zf3ur2V&cpQlZ_lQJzygQS(~fpIWxaeZZXPS11xl2^}SB8pRj(^`vW0E-MJF8LpHt%
z@py&W*NO5h5Fi`HhHY(pZ*S5+Cd<;f-|Q5EY&%0F<_i}idZYTL-H_|$6WQ!!o!+`#
zNqUy<K3XA1QE$TymblF11MiZQ0%Q0FHQC%@T*U7$=`w$^B<3})*i~19$HiQ63+rh^
z$9-^uvS4%|)>5{e_d5T>&5RIGPj3zzuK!XPM_LKOi(cC)PPw=dd790jj(aK#1g^kB
zGVpy%Tib&gMVh!36~Ff*GabG>p=2lY%3}8|tcDMtZcZ^sr=2#F#5Rt4wwyNNLXRFF
zmjC>ov4dY}-u3P7Bg~#LZ+)ui!GRc7JJnlbnWG@^lY;&V9~AQZyu75dwU&6GwZZ@?
z>G|LB<rEMF!^Q3`9a46;o&wcz-<IR7@hLy32A-;VP;L?$xF^G7Erd2V&$BOk-RvxH
zPV4$DFYD(JA@ukWYDUVQ8DBt2n+y2Oipu?%tw}!{WX4w^>Er!`<41UlA>J1~TOUOp
zgSpJ2z<9RS$9H<Q9%H{#sAYe-h-JSP#&|qzXfO_{8uU)k7Id~<F7-Uuy2H9$yyOI{
zN!Y<TqLdy7P3E9hA)L{_M1uf8(T>b{g1XIjJf1#=+jY;qNC_4U?2ig=wK(e^Nq*zU
z$x8RL$<W4?&kBvV2S`r=`sz5wZ_pyUyzu+?u+wp|KyB8sL%)txP^V*gKU_caJxO3e
zs%?8J_t6OMLP%}32e&6p8}CjcK3ZFEG<38DdmZ|G0eurDIKV2~eKYA1qN?#D0F6U9
z{p3V#!S^=1>EXuk1gyh3NngJE+~l-{hZ*W|v%@&G?g#$%KI(cA&A*lk9aZ4se1d<s
zfJt7B5QtZ5F>Z5vDjvx)09}^BnjBaT0<!$J@FWZL8)U21&gbq~**q`Uxv1Qcq}{Y~
z>?7`b1qE)u$J={7uYEX7ej|2>X@6v4QBep$Ow$2I8IYESky<3@a{duio=;_HO-+1B
z$tUz4DtuI^svhWUrrH>ofec&ZDP1jJk6l7jg*{L;iWE1i2Pppb;;B5#X=?gPuRyU?
zGhDF&k_zGqfC%lfEzs=RuMOYp!Wu8;NvD>t0q76}qJNq;>-3?G=-QY3S(lj|h!hP@
zwD1WilQtzm27_C9sv|@$?}CA0zdY3zV3?)k<e0Ve&o!JE<H$khg}3B$NsivLQq>c^
z0%pX?;^70tpE3ImiTlIeSb<!^tq5aZCzy;}tmwsP+Q@(;#}T(X88emrPd&Hk_z5xi
zPa`ov$tMGhu1x*7M~kz4C4?!q=B*x)n1w2=zycL*);C}>eW8tB8)D2}0WF!u&qT|S
zuRl0WxBLXyQg3>uR5+;PWS!;21vX+U?FYykPC)hW5_F<v`nSvgG9u<~pEX}hMAmCQ
zb6`+RO(pPyXcQ}({`+kSKmWJdbfEb0!n4i$ewXpM8*RMC^Zdmt>#Im!E781mU(z8n
zTz_7x>8jldL)i#1|F(;?Q3J3G%F0v91s)jlr&OzYn7!p>gj)ry4apYG5nz564Z^;0
z7c-({zh0RHKObQ!CH#%BV6O5IrAVCO{24pe^ZVC*kQaiqL7i@Ue`2>g3YpipKlCf8
z>Lj1Wx`SkFve0<EC_2Lv6(6q-LeH(o<>GS?JYH0`UAzQ{3YJBt3&ry7lI8tPR-r;R
zWaYO;M}jZMX71ChN#(VwtnK_~L&~dUv6a4j-kc&!*UUCKCqFkmJ$;}V?Qql;dh(}|
zVia^*V{;adRBe$JyFL#Gz=h0b^gB9h%)$0Up9*qw10=CTye;tFq2oN!F$1<7O*B$}
z=gX1^Jh(8T=F7`{P=)N{#S&dOT4sm%U4P(dSFrkrgCnasJzX7|lfv*Ab1g~g>e6TZ
z9ytn^{XoND4iGy%*SRF&>kTo0Cz1Kxg@M&}5!_?^p`>=L$xk2#Xwc`CrFTFaI~`)A
zbo%$*!ttm}-xR^F-2(^U6T;``=aH0R6iQPdi<lE$?pPLQc7rao3pkoi^BE=R;8!k@
zewiA&&Pm^0k6-5PdNvfqr=^|yjO}lx7_RkTiLHQWn!ILG9AXUS5Uj!O@PzapbZN#q
zn)C8Ecc<egp<;K@AXos5wnt5de0cfcg3zRz|8$E|k&|fe)a$vV3=jv0K!x(_AWD+?
zWrGSX-?M9I?6OrFi{j)TRM$At`40?9ow2$JDV~aa9a=K>wN%sg{{4o>0Q2Fjf}#)b
z3dzD_Ykdu>1_y~@VNx^;j>9y`Y+mt7>93v~_XMm8thqh#f~=fgL!ateOB<X03v%$K
zfblIbqIZ~}qTfFe+)Sjzjv3IY+2Fc+0QKY}hHb|^R_ocX4gd&?L=Y}_-<<CP<2QjO
zQw;$Q`h*MABrl(p{$DM?hfx`@mLh)n?r#d{Kb>E^crj-h^VR!o5=r>{H|{IjyNsvC
z*ud|;PPCz;=GV^259>MgS2pv5pg`_>r*+S?4~N8m+-s+9*bxN|jjIC1MC<u9DF~))
zAmTh&TCEv}`Xuec8cv^@%8j@e*R+IBEG~$h8tC&L|HzvWImtMYZ_t6P(#6By{g;WC
zX)VmLC|6DGALGitz_nzYK$%VSAMxbKq4Ww4ROx!Kwqux?nRzo>$ku#!n(gh|w~qb9
zTSxnLepvqNF=BCl|9&`VJ#_^@Gc7(USg{rAc+jLAw_`cwYMkwJv6W_3u>vaWH4xO2
zD1=C&PWFDNJay+6AD_cOEA?aqP#WX3pJpC9EqM@vZM^_c6UD>F$7M5L!K&wuw?3dE
zK11Jezt0AS?2vyeL*v-9jm*ANn7wfY7wquxCtv5s2Mo|+=$cd$A(3&WOsR-PfR?Rl
z#s**xBK(J~5lxQ|kLJf~Vyb|ndNNOVxV&bCH<my62@b$Y*J-^XP!`%33X(7eXpH@s
zU}^q_A`?DXm<sQ4*yc6|Zc}oZIXsibI_WR}|1i$?FGVXV6adKsXogr>{H(ecX;oM5
zlJM2;j<V~iA^p9R)NmB!FjqarYN>da^t6w*QN<~zUM?j+;Sz&JF0R@GG`4T)5~K`o
z#Y_%a`>wiQyKmi7SuN*Z$oZP+IMiFufrw8ZVvPC!p!U0`8(^B4RknR_y4kV7@+kZN
z;hX4Qyy2^FbRf@rB#QJpS99bBEsEB!tzkgB8p)3JB#emr_}PBK3<v@IwJ2+^G|(eA
zrpF<%=6E3<45-00%hxj<4@04p|Fv--OGW`A3@7j@qP|Xm)1RSw<&Ks!Fu}xj;u^8_
zgEc*NxuAJLMZ+rNUk#)gU;b_r8CG9CkC>ymB*LPetI8zkG%n(He7(gBXg}V>lo*nO
zoyaE^8y&3~Kayh8Lb6=Rimv_ixhEAF4~l0b1)d;4j^krP*Zh&H-o4%;Gik6Lu(d*<
zjx96|^%4a4Hx5$gA;kf6r0kn|cs(xbCqcCpXAzD6xX{rScFd0Uqjk%rI|0iMvRL80
zqr%S{#)uLePvfLJ&=7=6yhai4tNKrP)3vSkx-}~x45)o1J4;y{QbOq(%HYLcTvmd%
zV}lJ~A0bIV*37>`XX&n3K5kx!y`9#1_=lP0<eNIXhrHl}3cY`%Q3g84bI)8N_TSYF
zPM|O`nU(9?otw3`ilhk^m&aD8g6dCkI)^bJs^e|{!U;&0|2L>0_|iWK(Y_#WmqbFG
zm7tI39g#oHWv_`co3@h1%VNIY9QlK2PpY5T(3&d3*=m_8yn(IOt-JDGLtm4D_th{j
zh}9-24b|h+^BWse%XN35oJuh-kh74qHCMGHt8CJ>S;5j>5m7_VMNj2Pa*#Yc0-cOs
z>_uqgCM^7OhTsIK2Wg$3kPW@n(!vYtwY06EJowHuAEzFj`YKh_FxI}&xv@BI1}Ifk
znO=qzE_8&u24Mpv6Au|bL6ITEOOTdA2@k9qwfy*z&7CEuXy@n24Ay_T1Y%l1t%J|w
ztIHR>-3L&)eu{gW!Tfx@$0DY3oKT_^5DpPb0@p+h?k4}=^*?7S8vU7plptn2SzQQN
z9X~u0{EvSU!c+`$G8S-p&}dE~{qKzlHHc^Hi)-Lk_#Pn118<;puJzYIp?YdY5C3;X
z35zGqfhyApDR^?gbywSz<|AhOuhDA-!iiuBF0;M<QS2E1BHD=3|9na!cNV3Bz#p_D
zQ%ZbXc1ywl@)-iDtsnILH+2U9HtecsIrs_amKtG&;JhO_-ADO;nt~FJ%BLnXx)gDx
zykY6*{pIrb`HbN>AOifcKR+$r2DROmC%}@yEUFVoE0j>X(%!+O`d@Eq+gS(4Nf7ab
zx;d-{6Tb9&@CKO3Se|qQpvgCZK48a1WVi-Y(8F^88FS><4bH2Q(}fJbeO3jYt`Q2j
zNl^Ms{rc7Id%K_F%Rz?84c3V#a~Lk|dPWd(Fi^xeUCdc*frI(r`jmUWRQe<gb{x>0
ztY!9UimEsczqhtBd)1~z+zBkV%C1LR_Tzu_eao{9t+#IhAlXkbqf>2y2=EiaCy4>j
z91y2RR9G0uSf%ZqRMH5|4k6f7ihNnDX@gmGugf6F#|Ge<RUrszOH74~TY5Y`H`!eZ
zkSbOU#Cq7jD<uX@?nHOKKY2LyZV0#Ltpb8VY!=m?HjmB}&JvY`^YW!;L73TMG2JJz
zu1~WF7no?W0Y`)lexaw8M})Km(=ILLbgowLnhHKQ<_)$;Rs&GCXdB(JX5^8dC|_7J
zu-bCR67Hn-Q|=`9@%p0w-*wj?QZ7X(urM$%7L)C4Y&L6#+1J6#bgegx7|;JdW}cY1
zl(E~`aJpYpd>E;+`hLGK@VypR%KEYkWx)>Z%{56L>5P%|d)es<YMqu3AMp|dJ-;Ea
zy$z>$fk+)@dzUJ8Uz8h_E<F;ClBk)8G3-`)N++gvOaG{PD;3vW2RE^M4yVj&^zZ+Y
z?2wL!o87Pc4m6C}-i~j!Kp={WDkmn#%P6k3pOrB+B^@eAIzE1m8JBjk5gb00IwjbR
zQe^|yF>0ad47;A?IRd&dPi29$+*_h~^Q#+!yESQPZnD%O<E%~8V*7Bk^!&iwG}njP
zP}2eV&q-91RbQogKI92`vqqFourTB&MI+jTYVd#U{IqxwxvUoh=;c4t$QPIcv9Yp-
zv(@&`VCC@-YX|EX5YukOf4jQR+8&Hlx8!{DE)*VeFXXhkjhDYPgfweHiu5{MTwEe4
zmvP)c6d3@*loqx}plvZuV|ZHG4tc8D!4?8(pkGM_)T-@-lN?=*+e`W<ew=cLj^q`5
zPE=MvJ51|FPjiNzo*oK*8Gtu{Zq!zE*69Bfcb(yIuHE_-L`XskVGEJO=q*k3*rFte
z-a;}+5R8^!l#xM-*z80ZEm0<dMD$MdG_i;1Mxq5lFnVvpoHhIVzH`oXuIv2xetp;F
z$9UiODes!+S<k)Jy4M<JtHRq?y^8agd|Vz0{;=XZ>?m^7X?(OpOYgE@vE#iHY!`b~
zxVJ8+h-`-S$!v!9iG*|Ja|L&08i?>5Sn6{rc+G74kH9rOZ*{7i3jC8QDh*)MCjg<X
z{JsMpV#Q26&pB%D-jeNMIJp}Xuzo_o%zr+BT75@Pn45q+xO?{O+v{KdY`&F_3KdN|
zKH?zNH)@{ybNp)Uw0keEoAc10Kbg6hazrU-k7?BO+?IGPzS@~y%q(v1c390lZEO!p
z7<G#D)oPlmcJyg5oA#YN(z1WOb<N}P#1}&`Hp2J)drF9;uWOYAe6Hbja~y|QZRpIr
zDnAme9$(0C=1ABixO94;4nka9-0S3IzLrE;Sotd*-;3<V<s-x;B;ul@U&Y39u1<f$
z1%&@fx(deezSYT*wkn~Gw!vBx0%y}ceS`@~O&3~WUeJyacBXDDCSG()1ncW$f4P~l
zaoSZ>T4$&6Gd>05=6L=edxE?Ji4#qN$R6Z?y+6@+a{E$h$mqN5TvuAi{E)TBleLK+
zvn=<;g9I+)t#O)feV%dMGa?g*3ajwe5#^PPvfNzhFGEbX*Cub3#;*oVsnp3)8IblD
zhmc#j_=KQ<t(&X}vZ#qXE*cmNs0e0do@BR0ke?5beRh?y0gR~)2Tvl%CwN-2z<+NP
zvJW|PfZ@;=OfO@U?)!h-K(&Q6<>U}P3)v#U{`-Q@5Gn!^PzG#Q>|fh&pxF`R9&{dU
zHHWlL3N;ts&)<s#Z=6OxUTtA$zs>PG68r#~7%v|?GXQUR<}kw{t=s!~kYE!1YV)x(
zO#gbKnfLv*9(d%dI`a5l%^O@+k^YhM!3c8xFmfw7z75eQMa9Mb^pZu8&jK*P-U{Xe
zB|-nZjrT=Lb~zAR;XNmxj`mQe*@wScU$WSP1gpX*>@WAg!2HnW)=?)UcnU6sPxx<N
zeDKR|7(t%ER7HOfF{Ch^cp(X>L+yzm3(PP}=U&D_-S}L??-Llf!a~1d2{B)g$s?E%
zX9Cod1ZMF^NvVY3N=6>U_6&?&Jb&a2!y&|08a{UxGasPOpZ@fLwlGpoUhL;g`2VXG
z^7w2`ADW;{iug-smg1{`ARABM+bA7iNbWU>ci6mn5J7fNAs>0%$v)b~q9qk=aR@Rj
z1AUIf21#qPttx(*(1AH|!z($l2m8$1;q#dgBnSp#s_;pusnQ{_ky`KUg^65*M#Hfl
zv8WInpO}PL@89nN?X>PT$zA=qB!eJF7!E!8Ua>oW<!^b>_61L_)Lc&=NU^zk8#+M3
zkbR8uO66CHf)aU2xhp3E6Bv=;dHPdzmAjD!AcJ7~6ArmFMr1e%u6HZ9#oQ?J-Op3a
zF-=2|D7Z9Mlj!Mxuv$nd*Dx}W-ofuD4<Q{{Wv;Z&WhYCYzXiN+@1B#2WxrN~PL&5S
zAgRm@XC73pk}-ac57LfXY@&5S|8TR(d_r5#7%0%?*jBK*gILm7kl**`hcU-;yAZm^
zhiOA$S+_Qo6~>Qq?yR^ql;d+_W26-_+A3Gm4ifm|xhT&)7~7UPx2g5x<_Qu@9;5al
zf~p%u9W4THN1kmGj+?kPhwAK*^oj#c^zmLQDAIQ)TM$syAS@*K4%2%i9KYy08@O|-
z^3xY_)4LxS+MMsxdTY1)Lj(y&&0Ke?vt?*E#q4%Xd?E$cm4>|1Jbm3_Op3HyBlJ8a
zE|T)3V+h7vt;e$$IvORCl{Cyz*daS!%=pZAlw;!^Qq0UuIu`|7dRgqZA*H<&)3ccS
zj<1qC+fdr>Zm*5?D`!|{KXDHhUOwodddfdPHuiMEtqMxQkDSu;yKSfNgisiWAR<wc
zaM>9hv@nVwlQa8*)na4CEAugz{LG>gF`D|7HDpP&_fA0g?(#uxV~X=PaAslrmW?XO
z4%tDQK0@4R(Q1#n0sf?2u8oV$gR3E9ire+(-jTPD4_Ua5Zi5I@&R;b*4o~J!8Yi3b
z6)H;z-tZ}~vv(9oH!MhZSf3G*sPX;P;gyEj+CC?X-v}T3Qg_&J$f)#NNB9B0ofLHs
ztL-<uLueGq#P7Yf&TnVc0<5>6B`+P!rgcfaChpp>O&p-A*?hsjq&3e7Ajl9X!--9_
z#%V7;i?}%K>~786FSBeYH9^91&dFU9v&)Zh5FzzeYOV&o)AdXX=cCofDpOV0i1nFT
zbTK*hH?rXMC4|&p&7`k~RLrE0kxfObHW?erbE7Rx>S%UVYtbqAl^@@}7x~ZUjs%K?
za5go;mD1$mw(-DPG{IhAQ#JP7(h*JgaqX^b?u@9s(vmlP7oueGrPrQG*hHa(4l3)B
zM9`>aHqxILF>TWvO`DXL1b%bMbDHV9p~Cqc-X5BBd~(5V)>t%cJK)g-$6@x+?%Duu
zGc&T-F|U5=eJ3T{k!veLev{fRmX>Jy{yRf^quUwUvFMg0IRkL|q+u`^?~kk^PC$O6
ze4Bso(g0O3Qo+)mf)n0Yl+##E?SZfXF;@@{p+c9*w+Ih=C};0xR+CMll!8&O!lT%8
zl!@#hhc}>aikF{=uddJt4zt^P*OV<f46H3iDG8`%!r<~-^9OBBlm6|xg~SO`-j+_0
z%&xRQab|}8<qAnut}1H4c4%$Q^Ax|>G+1P*-yrP2YEz-usMBJ)6vi!f|Jp0bX2OI&
z#&7g+!^OP#xE?*{iGeqURu%EfgMDZWwf{&%PrZb8IJN&pIA?Nyws~7vHte}@H%mdw
za>Cx->eG+(P2NHo+Q>$%S@nXVSYK+X*S!3&!=icvNBi(Akq;U+4?~HiTFA8pL>`O;
z72x0|DtNuYt<U9wG@O9~V^!sybvn97j?dK0Y$~^;l`a~v928|QUZg-d8*)Cny40R@
zL`a0TkR(!<CCF&IK8H44Bw@(XNfHgbLQ0YfXDwgUlE+m8Yi;CRekq(K72Ai*_!Lb4
zK2RmDz?HNX_)|+h?XTgYZI(u-M-&_4sR~T>%q7NH#r*5mCbfyXyCRz3>P{(~)i%zs
zts#V__`m<QIPjeJhqTemGR<A#&cp#@`*xmQe|3kD%S*}@KZv}btH_1aQ(|J8Qwf(&
zOLVWvDXRYdD3r)_6wi7B*U1Y?kkQt}Bu48g&#NSlI?JQN*P>A5?(RwOD)kKd4&{NZ
zP^L(O%3R$l>jUXr66U3kYm1A|r2q@hs?hd9cz8H_PDBKIu$dVaL&elmXv$YG*$E#>
zI!fE-y_S`;yNUcQJ5|@Py6y>S0ru-E^e@@CRE<FY82xaOZGCgDZF*JNpf!PJ*rhrY
zwcK!puok#&<vfUzKo!(kEv@BYOTG4rxec_;8ms=_xqIxftZ+}EP$(B}fBqxh?!}82
zyz+Nb%?qq+Z4gOu@lJ3_-hcn14jy1HsF0fZ(I`HfOTug|a0!jSBt(rE5H1gHiDFmC
zean4}QobyqxD^x6k;-DPP-?2uW2t82jlWK@2`Ff|x3Fuf;&t_=cl)-^l{%1gX2m5`
zbfX`A72bo`7C$~1?BEdKp*7iGvC3O$U5m>q^`<?0<mKfRm(;H)uL32uboBMj)zs9I
zFsz~dG@HXMv~$k89`DwTbaoeI`ggEDr3Pqzmg&-FT@w;<%6?A?TO1x`5sOjwtL9@F
z`(xKs+l+EuALV9nhE#bc#PyV^O9us2i!2EI6QD5-0j|8;MpPk`4q4TYjg1LhNMG+Z
zF_;2Fvjf0zclwpcPvEsH?ylYbAm{3y^Yv@@ysB77GPSF=zE6)^th$i@<$N`^iHMT_
zr?y~C6mmtbX=_K9`bya@&kJQ06&Yn^vC#IeD;v~rws>3six!PvB`3<?yPZV2i#Cvz
zU3J4nFc!^5ojY%0W>Rt`;uG%K$yAXK>IM(P>HteROPxPY-so)yX|*H-N{EZcCM10G
ztVv6|yt%o_a{t-|UNTIz)O*U9i<^6TsaeJ&!Aj9nEpPOl<oAO-IKZK(=aae%?ME-@
ze&0xX`LbYT#XIk2W%2lRJ-uf=`RJUHPoV+}XB!$CaI0hsEYR93Zfr0j$khw1N{l>V
z8s3Wy+%7<MZE9*V*4K}?(~|i55`N2R=6jJR-xWaOO@IAmsG}1OVf`VO-eL!FX=(FY
zw_f?oeD7Gg*)oA3$n%r891$UBsJO(d8dw8$>fW#(75=N-EiN`z^hns-(o$2wD-qpb
zji9u36Qtu%uzT>l3ZC{kHveia_mDl@&y}eK_ssTx3+CCg)T8(5NC*jy0C0@h^6WW@
zAi=lx0hB|YoC3g#@Bn)IPuyVLMkDOfzrJu{)4~<<hhCS4jmxv$C?9etP2o1q&3a|B
zqCr97L3?(GZCy5?I#|YkJe8(%WjKe|@T}Y$H!@eBrHPbCyu3%xj(o&vuDB*W3UR^X
zcB5yRRGGDsN#_`9Ys_C{YQGBW8~rYB+)r4DM*2AYk3l<+{wQ$z-Jh8G_Gp}2h(oAU
zeY1jVL|5wdTx)k71AlE&U_zHLu|LD9>qKwXZ^g5J42_p+JO15KYbSIh(}?BtN*wbi
z4!!o)VR|22qF#R4dXG)uK25F|RDV2yK+S*Sb~|E>nj`XxNkI31wNz?+wu!!+87IH|
z9>nj&4c5coHVOlR98gC91k;Td1bI(4EB*sFu3cvN{Tp@_LXQ->if(_Uj_q|waGvhT
zV^OKk&eoCp;g`<F#%5}0n0mvb)(k>A_i}k)x<Rb`h=BjtVbJ1URZ!}172M3t#gb@9
z*8l{dIJ_Antk(%t!BX1~dw`_)2sdB5?!7%*(O3z#2@(X_z!ih(j4`;BWwX1K0O1jn
zSlELQ%FV8+x!If`Gc-@-P^B8?nCEqVeQ{pasr@7u7nd_6glv5h*iBtp@)Xd5eug7q
z`@>vK(C8F6aymRE&!0D8WMS{7kaO0RXh2g;DlRD@*9Xz!?LtCAiY0ZSoSxcE%w7c9
z_poq?nJ*vC9&O{HI{Xd(d2&tyaKP7<>T7E5*Lw*@{{ap?pZCign(_m?3Vm@R3Is_D
z_iEJuz7S>0S5dD1#puR)Oy6hB)MJrvIx|Jy@pbJnwv-F7e0PhLdq<)^!k^E_RtskH
zk9*&%1gu@{JN~myOhLhtOeV7^)A}baz8w1g-S0d0@#Xj`-+9mPk*d$1A2-p%5@LJi
z4ESxtNIH}b^q?S#E!4F>$2sQtaU-lrb}SLq8>SLZUzJC$rM!_@`RrIun2~OxB<9~0
zy)~+1D>P$qK}blm^G8{5OMOBHP_7_iePV&iILO!e{X6KDPX?Cx(^+rc?94+_T~x#j
zE+ac<dR(4WnZ-%heEvtDn@|%+@}m;C^;KSrjMWPpJet+D5<+A$$%GBDm@;nFhaME2
zS`fjoqt2f<D<3HdXFZN2$xN7=nu^NE6pZ_6YKAN=FM}ivUS8U2w%P5ZTn9{0x4Y%C
zIyYFYSN8cf|MDHS(2s1S_-RZ2CF;GS#azqPPu32xiScP0y=~Q|60fGD%YcSfG_jcs
zt5+8LC9H3&hhjY*w7k3=M<nJ$)wOcIoUE*lzA_it`x^^8tumsbhL)C=Iru$E0s+*;
zM&J7%V1Y117oHD}zN!HXt)e?^#Jt>G$?>r<r=DC(N>^qi)UT3gyk}}@nf3JPf!7%s
zPLu7g6n8g9u~1!d5-3(CcziARS@TQUE>*YCEn_4M1xovM?Qx|@0afd+H+o%<S&!QH
zm+R>0aE57^T3KaB3tqv1x+kETi!T7|8~^o-0@Xpu;OZ?fO4pi#PM3Y@s`=iX|7$CZ
z+`T$j?Q3Lah7Qd;`}q|p!T&kxBy#>-lzZ@81qUq|4}%H&@9B;O?UQbxyKYw4)jclf
zCyW-_1w^&S{5MLSIm%{PEZIDN?!M+f6jDO)zdORA|8Gu@ccf2t=n<7Ip-AIqtJkIN
znUah3tpk-_Wv;#Fq-^S_Q3BQXMzvDBS`~0mQ?EPI;N`_{N4(YMNWf2d3z14nvrN6|
z{Eu2Ja2uzfzG|gwzq^-;+OaXB<jr@6;Jh|>cFuy}X(q(=uT3O-=_k2pGpWt#o^M;e
zaPOyvW&CUA{l`ix<5Ty08qibY@W8#yi{LtT4AYUO>6Xv3cm;7yzu{h~37XEX`Q?=e
zzN{>hOp1u=W>}=zY>E4zA{t9J!#FuDRL8z!#Tdj(TBbps2;IIBmz3;Q-Cg7u#7*ag
zYo%AM^||2l^3s{hM1ZVWdctp*VGzGQ$gAvE2yk8n0>*lSRoJe{j&yvU)QN|E2_E8N
zVjbJ_^#y5Zr|WgY{ye#E|LMs=x;Dj9vNFs0AWpbcaI%z@q43$cbLV2Cql<=$W@cPp
ziuXA}vLOx@Id-O~5ftXYyys8hw<<tqa>UM6PGG=)N64tDQFa@6X9Qfzc||;O0Aql0
zalt~!VhU2UqEP6&ADFFb{EEzTuiw&uyEcjVt*K0UpR(SQhA^9?)HVC<wb^XgV{j<o
z3z%o&=VtC1qtSUbw5@NvvY6Pt2YEAqcBNf06j;rB{P>Mle|qaXUwICmP`(bd=tRgu
zlxbUL-?$GchwV|P)K?%@&c7lH(N%QIi}P3H2E9$HBQwwc;cEcwec5|IKQs0`sQoz@
z<C0&g1ytT>R904&woE;>_@c*;To@^9hb7@Xbz_s<-ku5^1fy>@LA6UuOMUojVbVWT
z=*e}Q?4j6hqbu0YcZV78AfsbIv+QY2QIdt7=-}Ys44%<MMQnD2%G!0bcZa4`-Tg|~
zxhs%@33|)Gr6-q;ZUIMT(ybI+KGa%uo*SsdZH$D<V!Gcxs`~}uNfB+UqT8CG5mH7C
z)gqrlIXqS;C=`qejk-(+XQ9u|c5EzOip~H9g@MR{C)z@FySL2>{qvzJzH)*X5Sx^g
z14XY5VX&#mQ^Lu9>-Ipj0I=9z>fE&g<%K0wRM3zB@+7}*3!`~D+V8+`vriEo5pNqJ
z9J|byv^CUBAskT5wtqhsi2vFIPcN@Br;fDvh8mmuiy^0@|9}f|F)``j2wt7-w@^?}
z$RkelI=&=B#HnC&d14w^M^Crq6_2V07~i;&Lzi`jlPM$vd2O>xKG-D3?Cxy4kO)Fs
z00+E*z9JzZp({6VSACn~j9Nprj7R-Wxix;(tahnMf?w_}6ZbqZ*QVYYiV)Lx1DD0k
zS5P&S0%YBewb_1IuU}syj*BWDU^t^s-+Q&2zmjm9;|XQhY4bd2WfQphdhY?AliG@)
z7RtcZea5e34#c@+edR@sl)$Yi3UEG}y<+3zDG^F@hNvUG^LkI!CoBw_nwzmLvfn0i
z3hIotwOMPad+TwXC5{HGGrcAN|NAPvGEd-FjPw#OWOWUt?5H=C$SC>Fb$4f(V4?fM
zo*AXj+qIss5VPv)>KyPtgBcj@E#qMon%%sa3rCdifNjUA>x?`s`O}o_ocvCxzx?{H
zd@hh*)FWZ><b<@S;8xlNXd736>EFexf-40ZF%PJ2Hb7}~YF2n<copIll%e|iH~J~K
z_A<VWz`)fpxc?0@F$y44LCU)3y84p?Q-x=Rc~x;s5JWdiy6A?%&RkL5iiXm^*ONA7
z7U!A)a=k`Z`((X)cO5iC7vv7EfC{vvqayleAk+A4Jb%<0xgPG;zde}Tsl4sfsrMu$
zJk&?l_B}EW$+^%aI9`@O%ES02l896z?9|%Bf?9sSAX-#zTLyLZ6DISHJPKZ!nH2wD
zFNhQVKav%^YR=ky@q^DV1Glo|?hgO%0Tn$}-@aJ~!us(uw!s!wR=Dq@I`(Q)q@KJR
zwV=V~A%}Sdtf4*!*D!HWmEYvtljZ!E#>^Y%>S=)mZ{Pmqg<fA^d7k>PJplw90J&Gr
ztJ4sFS#4FN-S=pYm$HU5+3II<hnZf9z_=4BzC<|)W0*Hu`;9PrEDV3J24>BzNRHi+
zBX{}i9UYs?-K1`mUjy-&nVH3%04!=|ZVu{7n_y~VQveJ-i>aw8MJOs-ir@Chvnrzm
z`wIS=n3#r`UKhNdH>g<8(1BYE=_2)8<bpBz2s%D66wTmQ^0^8>OJfZ7uaeJu*7uRb
zoA(;H=z8M`JAXF3Xx{ar%Rnpfki}9=E#t`}cKS?<bGkTORcBY%4Sro+T{>)l6Y1MM
zM!l1PH5QQ6oJn{2w5O`^p1u8;o?OvFRJmbc?f<&Ud#ZE9PHS5b`Jx6O6!yzCx*rYd
zdmH=slxszv$kUas)R?bXj>xE;RsaRQ3Sl$g`qAH-92rC%edIo}^rsE=azXuWm3!s*
zF_qPB6RHFD5745(<*67TZFIfdEhUe-_V)l%QgX@&`xLoO0(BtOw!8wGU=kcobn_KZ
z&W~aX!HrEWjlh*LKrCkRd_8n@4o97+lF|*R_gM*vXie+_GKx>e{UuRg37=t=djNRk
gKV?h)`-bc$4W(RVKGTouf@ve#n)({~mu(;Z7qh0%v;Y7A

literal 0
HcmV?d00001

diff --git a/utils/.DS_Store b/utils/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..0c339ac5b9b16ed65b9dc4e97de18864161fb11b
GIT binary patch
literal 6148
zcmeHKJx{|h5PdEkS`|<?7&9^<F|$Nf8JPJ2rC$<}0;!-Kx@F<7Ao2V70r2k5L}}WB
z#DEaGi_Xun@A>SPD2@Sy!D@B^^Z|6}f~_u#9VY$aTh@v#(iwD&3`>l7onx^T?G1lX
z0eN;keP$URP=9{w>%5pw@?ydWc|9)aXYXpPeX<r<V~R2T4s#i&!Fp}5jxb~Nl0L$U
zm?6iLzAue@;bbo}M?wCK`5t#NpBv0BbBsApiQk{=rM9+1GAzfany<Xm%{jg`G9BZd
zJegVk-TENP)N^*e)<gBL$CK{n3b+EUzz-GRo-Nkt8G7joxB{*~rGR`N61rd-u{6|A
z2Mav{5Zi24V_kk0g_A@~BbJ8jp#`H7jT+(+BN(0SNsLP)mWD=0h=-35GlzIW37Vbb
zCmN2B8hYspxB{CB9N2AN_W!H>=l@NT-?;*=z`s%;w1+pt0hbi_)~&_KUYpQw>0%OB
m8delmbSq}8Y{jQ^HMS>GA*K;aL$=WTM?hup!WH;c1wH^*aDf8=

literal 0
HcmV?d00001

diff --git a/utils/__init__.py b/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/utils/__pycache__/__init__.cpython-36 2.pyc b/utils/__pycache__/__init__.cpython-36 2.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e142c6f89a118a8a1d993df85078915222ff2db2
GIT binary patch
literal 147
zcmXr!<>iul!Vt><1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnF9-e5;?$yI{oMSj
zs?1b<m(=3ylKcYw<ouLW{er}T)FORnA3yzql(cvVue2mHr&vEeJ~J<~BtBlRpz;=n
SO>TZlX-=vg$mC)mW&i+hm?QlF

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/__init__.cpython-36.pyc b/utils/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bd32f26b03d4f9dd41ab1b726dfab36b7b7a3a55
GIT binary patch
literal 134
zcmXr!<>iul!Vt><1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFJt}C;?$yI{hZ8<
z{Jiv>%shRU)Z*-t`~rPvA3y!%{FGGv(vr-aV*U8|%)HE!_;|g7%3B;Zx%nxjIjMFa
J!-|2J0RW7n9`67E

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/__init__.cpython-37.pyc b/utils/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e9323e5691cb4f9e3688624e4c01ac79384dfff1
GIT binary patch
literal 138
zcmZ?b<>g`k0=Xv)u^{>}h=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg7{^uA6lGRRIHzq
znUSBDo|BoU?~+=aU6Nm*@9g8JpPZkPs$W`?nNzGEAD@|*SrQ+wS5SG2!zMRBr8Fni
L4rEv{5HkP(mKh%Y

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/data_utils.cpython-36.pyc b/utils/__pycache__/data_utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..41c0217c97d17f2eca21168ea7c2219499ef95af
GIT binary patch
literal 2258
zcmZ`)-EJF26rP#=U;iX6QAsP1+=2ij8uOzTse}r(<qkzi6{JK2YvWlv>#TRzv*R|g
z#@vKnp-O!KUV!)D0T7pS(HpMv3f#aqV<%J<?0Uv$=gc{Ce!uyo)ry69vHx>S$e-k;
z#{vBXM*TG=PB_iUp801vov=Mdmut?RYkA(D&l}v~?oV_t;7#svA5_R&Jm4Xyh_`vf
zV^A@t4@r0J3|h%fmuf$oh&15?W)|?QW4wlOAEOqOkP%rh3@0NC7sFF@;XkLxZ%Z<!
zik#91<T>5nSOhBI^oWU%r#B?yOa-rlM~U*eGh)h9!8U<}Gj<hG!6{pW$1kjg&}i8I
zeG#e1%8Myifr^Gqxys)*r^hR~P(_ey9B*5>hLzh|G*{e)YJ%I6o@$-aMO(#VU$w0T
z4k+JH(_ePU$rZ(9Aj5H_;!}D`KZSR@q`2)886U;ZsklbTVvUmdretc(NWmKydlB(n
z@*P2poyFRZYmZ359vSaEXn=n1Z4%?<Rl>b(GUdBudSjR1oQ85>k7G|{pcwSBaZ@?t
zrfgxgZTNT{#EL0r$dDa>ek+cuL>_iNzuWoR{FlRy6iHTecqY<;EX7Hu6djq?^52y>
znnzm?9`+xCoz5@kWx}&!)JgK{FgZx&ozBjDGZg}IH#>twrXy(SXOm=<)_2a3XjFw}
zWvzoet0m6SUL~?ZYS&nz-Eo-}!c>X&ld4J!u3fWHv!c>oEtA2Kj=xRvS^A|pL;H`H
zYhHbrRH=6Iw9x*n$fmQjyDkEwhZdSX()2`!FsIM6fz(l+6r&~S4`xF2!8~_Bx6Y})
zwaCv?DN~`>UU5b@mW<`DaG2rfWRmLG`np{8EUjt!D-qXW%U}0;-_)t7dy{fL&(hw5
zv_6t$)f<#N?Nx9<^zMJP)2sLp^5$zMv%K!{L?(SpZdE7xk_mago*nedNs*26Qu<I`
z-@`;am#$uCgNBsRCf>HQzM@@AxA7IzHf8JzyA1jbj7_Y>^cod!LCe6T$vg%f%&=Yh
zJ_rRoI10sOP8XE31uH^DzGn+lZ$zQKFr)fxbvZlp>s!|J-npH<Wf}Ajkj0TGX9fS?
zE$L(AIFVUdbeA@Don<y-TcFGEMy4_?X`{QGZoo|4vN1Y8_coSlARi&{)TKTP9q|sn
zF8nlgVuEP>`~cps{A|KcgALT6)A1h`5iAz%|F&>|KF*Pk_8?<6c7QhykinJi*i$Y#
z(BqEul{XGfDR%t;Dm2LX%y7I5P9TbDM@Hiqd|(Z5&jZqur;Ph%9<r+z3&Cxk5?}yD
zN4Gd)%z*(G5ki9u7dH6T2IyPb0bS8Eg9jeE-W#`h^OUYMv1td$VNOQg7SvK^CsPzs
zji)$Sv2zMINrC*Z$gZxaA?yQ=w07q0Ri<S&Is9nr*1XxzlTp7&pKJ~4$J#$k@+Zj&
zu7O}s=CetG?&tlXC<}RJTHWA3naBM>p47FGFc-!lt_$FZDZgy}T|&<O#?xIBt`YFe
zWU?kgOqx|(hvt6iLs*zhi}%dB%SBm<h9SK~h~xx#VX&jtzAP=Qcy*O$QU@Zn0MZSX
zRpy$O(_Ril%f*{UJ~9oyEIZ0|Foc7KXS({Ox{GYx$?R}qOKA&STXPIu$xIivZRepU
zZEtRv?zF2L=tXoO6L%nSQJ2Pf6CkT>6U2YjB`3%M+nHZl<sivMnY68A4O=yixCL=x
zI^k8D+t%jfTxftTwTbGv;o>vU=t7gEF2!YTe+`=meQA=&3J{cM2f!vnEy3F>W|Qh<
z8G64;3ZB&BCKOnFvCU^awYpz2$cEE)aJW4w`7BTGnq%uWrVzmjX~^Oa<5t}H2a*{z
A3;+NC

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/dataloader.cpython-36.pyc b/utils/__pycache__/dataloader.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3bf2dd290e23b85938261bc5933b7084594e979a
GIT binary patch
literal 6016
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

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/dataloader.cpython-37.pyc b/utils/__pycache__/dataloader.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..399ddb389e0b9d5e6794566aa73c12d64c1f3f67
GIT binary patch
literal 5267
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
UY!ojAw<u_ht;kOJ*^4*-3%QX-o&W#<

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/ewc_utils.cpython-36.pyc b/utils/__pycache__/ewc_utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d38c0e79bdcf5bd89f8bbed7bcc3155e408fbd00
GIT binary patch
literal 2170
zcmbVNOK%)S5bmD$j-N3G*+K+EAh0~VV32Z&z$lS8VC?~fER7URCeyv+8PChzvx#lZ
zo;GJVlYhWZ;2-cC`pO|PS8klB>e=<$Rt`X~x~96Ty1E`;^?tFk;y?cV<)goBLjE9E
zh6VgSOnCr=5k_+oQ2jMBGq8X&a=UN>hZ5#9i`ma<;C@S(!`$bDx!jqWfd^}k^<dr8
z>mH*&kp9vISR}(fRZHLVWSmDLJ?G-$Hf+WwieUJ&`2fE1Pap}In5TOUX=qC_V@jv=
zA$hbjv05`T8!NLLCv#EKTH6GrQ%cFn<{<%@*P2rbr(ZOrg_CgZr-=>wz07ZEw!|o&
zm^i0T7uK1v1$&_Rc;bTPWtb~qeYMlo9vH2=O(q^l)?mG!(AG=n)R^>IvvqB<jW^$F
zdq6i@+B(~i!Kncnw6k%KnB+b=d3s1r4h{*NG2Vg*TNCnQ4h4mXFR%jr*OV=yGU3Y1
zd8yoIJWY-oshp^;dC8Pf*2;$LRZ`LKR4*-?P##4!S9T;sbfz3Q%&J1U_ywu5J8>@&
z5leXqrp&xblv9nHdfX^)G%n*Ntx9F5C2lzKWE=^umiTE6CPJ1LvhORqs2I-!CoK}m
zo4_x}MJS`9&UxUD!YGc%g`%mVS<nNOFfAEBRkTnx-V5#vF2{NED-l@rzrPv$D7lb>
zqB=iM`QRa!$4ylaVz^^aLo{OW;9xkY*(mH*<0j4JfIo{v&F$7_YAvn`@Ry5ll*%J6
z9Iz|5fDmfYO}ayUx=J_b7QGGhOX^Xv1F{$u<^!>}4^!R+!Zq3hgY}rfOu)9OF-`#a
z8sUM>JgAkgTy#V5<mHQBaQyaljCI3-UjwGb@EgDY4oC<X1WKXeBs3TS8+6z=mD9Pc
zR%($}BD}2gK~y|pQQuOQ<oQV40W;z~B<~}^>~-XA;FK3arqd=2@ivJmAk=~1`TESs
z-MK=Hj^V(dU6|U*U0@iU80caKtp@ExpuK2jq3fBAO|hxxJ%U=`yfIARkRE-fb7~1z
z%9P`x^A>&4F857=nN{>utwO@O#*YweuZSa#@;nUR1pQeY7QK5dj!q%QPQig+j77(>
z3Jjyr?j(bTOYzY$hT6Hlq3ls!MNPM&+M}D-`w4HtxGG0!vICZ+&J{i1m?v=|hDS`i
z3o3mFb6-XU4@2dLA#}$$M}9dBp?~sDB0d0B@iCH5ku0jGIV_=g2gvI%b<`g9ZO_(w
zG3;Fq40Ipne?zL1?`fcFGy6a9Up}^I4rA20TL<PUQ0EXe7O<NYa<OqG5*-A_i6E7_
z6%c@H-QBOo9|Be1{UI>d@dwy5HTEpT9-{A+$g>y76KF)-1fA&P?ng)#S=YW|Iq=9O
z%yzDN`+rd;KEbQ7M*$&-`kU7x0C3L1b!(QO>)6^u1CGGH6ayrmA^8_D`W*D`z?{R#
z0vO>Qc!Sl(7aX4K`b_j-6|5X{5y{;rQGASlD(;LC*vY|0C%o)fc&G)UML(b#o7(b~
b058$3y!%}ze1+{P@lPEfO_xo7ZGH70D%8?u

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/fig2grid.cpython-36.pyc b/utils/__pycache__/fig2grid.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..39989a9f587959739d34b1f7865874419b0a24b9
GIT binary patch
literal 2404
zcmZ`)-HsbI6t+D-nPg{w+5+2Bs8$t1L`V%<1gcO~AzE!E1glC5suZajrtxetLo%7Q
zC(Aa<-jMc^2jLd+23+z6zU8VHyZ|@w9XrWJ+cJ^QIrgy~`+Vm+{&aJ*_2(bIJ^j1E
z*k5ez^I(68ray;}O!6Tscvo1<EBvl+t)LrP-RMS-m=w}`!K61A-KOM6tnI(TT6WkY
zx%^i9-p5GBx?D2s%B6V0x}Nl;5ADl9hR}g*$Ot-=P1%BO$SoPm%@@2I$qnqkZMKiH
z^x0UI2YG-0k;-MyU;Gbg`l|<M`Ui-an6ZS-I3%BWkfMexc<mQK5zd9)U+XvKLfwNm
znlsMI>ua7SJm107A`kQiX~}RHe%OwUcbxZ)(0$X;lV{a%T$@&|^HSGo*~^TlOKqa`
zEZ2RU)ie*%URKkwP4qa;m9?75XndME|JUQZbp9<nT2SA)lH<Hghxs&X`^MMV@Yrl<
z7Ygz#y1I!MXGnCF^?qgQDhB_#+xcE+N_U3&U|jZxdD(fG=^yKH)p_vEVW*PENtITa
z>P+f<s5`jMK5clXdTyd5$;-S>k|y@iI}nVA_P57de1}JTdi@d{ca}?foTlRo(2!~l
zm!DxEhHMc_UWmez{02J*N`>nQ^aNo9<bYriO79m!uW|OUj%Iw$AF`)+&%LvK^n~qw
zc<y6f)9nDH{bTHbUSny`1!pIZpRkj!o-pYHxnTO<-nR()-V%hpvD&lP(AD=8o&6Pw
zHdj}m4%;o$NK~c~enp99{PZl-CeQ<f&P23|LT+{+!8(F<pvI#kmk`ud6a||iG}Qzu
zE&G{q$kR^kKyA|uUK&0!JU6_s;5l&(F0}zchQmQbd<#DxD3G4scnybTQmufXbBAb_
zAiu*vh-}d3tne%VtndqAd!i2N5CH@PH`yFPKPT!~a@5VDH3Mk7Y#~7jDJ(=W=4`rM
zA!Bgddx;7mgO`FJAsALO2(noE@P=>jZmq3vEZ0g8&_&Z72c4yggX?WvW{H%;?q7WB
zHioTeZ#&RH#Kbbn#Qm&Js<F=Nd|aAvkmdbBZJO|pQq@n+j0fHsQC5IzJSnAmhxWQb
z;$0F1r@BeveTa*N&)fb2$bk`qeZ$pd7&kHh7Mdn*GC|;71(9}mEN=5#e0uARK(6XQ
zk9bZWX=)bD$1rC6f>tx05OsKgx=oa^apy!SYYX^8%x}y@5z#zC7;`vC1WH|$x0VT2
zMv3IgONinyQJLDs-<dG2s;opIOQlRK8{%Y9ek>JYy%u8i0WI04p|v?}&jm}QXGZk(
z<xo**KStAA5DXblIUl3`T>Za%r(>-0o%p+o&?o5BxG8RnlCy{iqEiHt#_$~27|}>$
zRp7;;i5=;a>@+Luc4WM2Seu|X9HXQXp%#JZrR8a=&Bmx2CcSZ4X1&^`jPa#Pe?o2&
zyD#65uJsw3CRQ?=2yfu=vg{xB1Wm(7nwo|FIt*OE5}BaH<v`dA2>rEVy7;4pp{(}?
zs9)Pe11f5Zfwpjfc-d)v`Lx7<FVM6-2A}S}mZ&aN^ei^%=_u1tmL#T?;3bojA=z<~
zoJ`W8^QgD5n=NaKNMV_zC?<|<#E;8opueWKM8^=3h+5G`v<Vp~@}Njx8KpHn!o&O-
z9x(eHhfb@zm|?E1`Ikl8(i*kdJ*JBGH$gcWRnOH&u<h1s2eId(LTsXY?qc^T({u#U
K!n24p_5K5HdPfWZ

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/layers.cpython-36.pyc b/utils/__pycache__/layers.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e604adb6d884387df3294be2c16727cc5e03cb1d
GIT binary patch
literal 2386
zcmaJ?UvCpf5Z~SV>$77*KrLyYr7Bc1LNRJ3iYnAnfuK@pgj8B2t7vt;T|4KT@67I9
zajdiYkVy0;{RI62?Q=iPzV-p})(4*Y)R}dhga~n`otvB8otd5A%<ShYE77m7Uq1ai
zB;+4*;&Fk$14APbM9_@%D12GQ#!k<rD04Dz?Du@jyIC*}dm$wci138JPlPYSJ*U?Y
z^as)jUV#>})uATn$H|V&1+Z)5Snu#G-j#~?cX<haAoU)iAi?#^2Ytaue+xufKYC2i
zo+Hk@AOmXcHF~b)0}<|rJx{EPhKTlQ&lgS6+9$n0tcW&z!xzLQy$1Mn)@(ddML+JR
zSz7M$yASX4@2hO-$?TFS5?!h^A6_05>hh_juh6Hhm*^EC|9+i#3y%2kbzn4M=uIFs
ztqCVJ14?TbD61WyPU)6jP4?KxACTJnonjEdDZ14OOjK0mq$;^c$EKNAW1h&olu8><
zr^9h<qBtqjU*a+?au8J$sTA5bA?InHmYjEd<7$}=6rf5}0|`2$B3$L~Jdf2-L#P{^
zCt0jD=YNv_zUls`!A5sn%x0<V-jjN#EGFHg5VHFqEw`(F_p!w*-H}<kT@<2Qm1(BC
z7C^l@*;Ol`9!+Q@g!+f??8>R&os9G5(&vQXCV22D=r@K@{{|!_7{aM2A(SJwNAHoR
zKh4<?q$3FIZ8E)YXB<0oYYyQZxq?E-odJ6f01#{)@^&3F#SyOX4%|5afqU1<$gABw
z2>!F{Psp>iC#3Ytz`_z9@56Zuj=wc)E}*z7_*L<Wf^#OQ@)Qze{J7&9H;=~>AlZ&5
z(lil^G|tkQRHjj?IL+gJCOZui9O0?rd?=4m0%V2Y&t*E?E{z{gCQvA<1y&aLdi^TR
zM8{KYGz|JNNfySOR7?#`41Lm}Y87{!MY4wE5)k~;C`VXUX$0dU4e13o`}kepSc3^7
zfe(6u$#fTnUWL;`jOaRnh}#&?-I73ZyBOsI=Vvze=Khe(gXv!<ko#jEf~+yUcLKAU
z^Qdl&5EHNTM*)lwOJ&rk!*x<e>rf`OkCp@j^Z;jz*nLE61Us#i%^UF7T>hQpL6h@7
zu5B%6QF5MKARA=ftOKyzv>HD<)EFFUgiIK%2(r^quaT>RJvtA{_UMc~XRybX-<k>k
zz`;JZr7$VfIUtXr!kS8!mC8AGI{0<tX^Mpx+H8Q<(pgm)T=fBx<6^xCzvkR9uCz|$
zoS!InRt`+7Ulf@HIcha)`dJk#DWF>n22#m9k!l_Hd%A>HYa*Dd63KNnKH|sm)HVb|
zzccML=hhuQ*^agBv=-Ur+w9Wn3aW~*H$!iMd@~gCj2qY5_OoJ`mRfy;i|7M&*?u1_
za_=Ysjhn<-hG){B0wIuhAzfoG<e<w|f!}0p+M?HJo3&X)Bh~`h>~zO{qiLYRqlSTv
z1Dl3TOSDju5rx4pJq0^pO}MHSkT2*4*~3f8-Lg1A!F&RnhA{BC({U9lF^-&0)HUF2
z+w3qK7j**#_Gm}vQ&&Ou1q^Ll7@c+BRZ?$3^^KFD4to-;-9>?6^8(MwfPvS}!fTsn
z;5sJF(zg$RKjoV_pA=(&P4dG##kPwtVd2u*8}D-VZJRre!dq@j1!x*BtOze2?0lS?
zi1TqFstoxS=a8D&;Y`3e+^C$}Tf+7vbrb!?;Hg_c%*x?)l*lZDbw@#7b~M|}5NI^4
zu^EMsK<%K_j5b2Ywn*?LDrK$<HOPwR3mm;2sbZ}#uIf6F-dTHZZGxXN<CeEYXj*pR
h=Hfn6c)?qp$BryGbi;(V7svbx%UvS~A*3+8&i|p>N4Wq1

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/load_data.cpython-36.pyc b/utils/__pycache__/load_data.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4861423c1a27201f4fc6b3ddc91befe2d3a0c442
GIT binary patch
literal 3906
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
X{kq*~f2Tay9dfChPD2Gey`ujCCaRMk

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/load_data.cpython-37.pyc b/utils/__pycache__/load_data.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f9f720243a90cd78b49dda268ae427d42e86bab7
GIT binary patch
literal 3063
zcmZuzUvJ#T5$7)d-syZ%Z6S$Mw`GE~^)-%Ur$!!xz;GNF1qwqCF<PsKBn0o4C()wF
z)9zj%2|S>P+{eE6p${h@FMaE0DEcY(sX(9HkI<L&H%s1~oS4K8XLpCQ!<paA@X@tv
zT?f}Y@9{7DJ;(VEO_rAj<{^gK1rd&5g)?OK$&cNk$C@>N=>OIcT(~bB;by^wI}Al2
zJmJ4!!$`2F&LDh=_no~l(dEU#Jj77<K{Bg%$ORMpg)?-8D?B`*Lj-vGA`}sxf#`@X
zo}t)))}HA+sZx=MRHtJGEp*Y7#%CCc>=zD1+1}qljHj|<B3-On^1u5#zgL-5J4Jq2
zl?O#$?mW)ak*=mYpFP>z8CN3Pnd!WM!1A2!>6wX=BrkKFBq5za-{G+H>nl^Xm)k3w
z$P60RrV$wJJZEzT%ICahf*l3wZS8);YA!hV_bu-%yqZJCzvOclQtnYCAJpzs2fPP<
zPY1Po0rz6=WB!#6+c{(g!QQ|%-egu3##hrK*Cw21@_44Rfjjh%%UtPUIL;@jymxmP
zwai^fpClt99gsm}ym3`dOox1&=(B0ovSoUlnf|8=?$dcy{zl45n%>GyD#LlXO7Qa6
zrfbi)VKTke2s;~ilH4LUhyZ(z@#vg&fTV91NiBg?y$#~90C$h|+&+(($D-!u=lyjA
z=!G$bnJ)Se(qp}U3PwAc)$D@2>Mr=D^9BEc&%L=18q7oOYH#7!{w2F$wUY!jSHG*h
zMM%&@B)mFU@d4H&;a(yhKX&ZSdWOB)uY)=i{@=WLR7W-@FTcZ;Z^ASaPGF_}^+zwi
zgGmF=g!_q>X<nM}tYreMWJ;R=3wRDXCOpV=s<kxHWB3V9R;EMW+W6KjveNK!YJypr
zpUg7TEl0_?ND(AuLYb+<6!8mEMR6Q-8sC%K<r^Tw4e~v7Ce`S<e2bRJ-SQ@pcZggk
zLSAhM`Be5neuAM$!eL#u#WoQXgopQ8pL0fc#LwS+H8|E_oHe%DgEt9s0fr6Izrmb!
zZIbY3PPxU9(ah1P4j1ej_D84W`%do6T}Zfd@AMxUiE_anJ70c_5c=~#`-=d{5FlJ(
z?$mDWe?m#ZZ#s2|f%#3;E3A3)PdZw3D7l(F-PIcx?2?z=^;#?MS{>diIy|f6U#$*k
zCH=4HXxCaDu;b+ZGgx53aDMYiI?9STS8-YCcq*%}bCHR7dwctJ{vY%tCBd-Qq*Fof
zD%1T#TFkO0|N2>(j*2X)$}BmowCQB!>^PID&g9SVrt$Lfo-hm*tehscu$jKDk}(7h
zDw&Vd!nk><<+~6bL=8SD=w<`JI7-?RqZTK?)bgOn?&spv1g(&Z$@j6c2~~G7)GZJP
zxacC0`#?*;t^+X<-(q)xpZolLYmJt5?O0)jys*LwN3m~^asWh}KGM9!!pCz@yU#uC
zKMw>$R6@c30(8_K3aKX_Vviz^G-rs%qT6sMTh9nt0W@yR!_#kdk4h?#^;aM(ns<Pv
zppKSEKqqwm%<ImCkcD-iiV%Tv4DN?}gu+n%Q(s&3Arp{I`VEV=pqaNi0xS35R*n#L
zRgMtcoD~91BcLe&nxegz)b-Hgd_n0gY1W{~Ca_Iq%F)55MUm+M8VQ9>8DFO5K?{)}
zZ6=ieXdF~A<OjqDSQpi?3Dx0jGAXEzOs82X<j?7#Ul17(`4tfhpzaz#l6w5I_NUY^
zlwrBNN3tIh*(S0>LLN1U?<40&*m;DZVi0No9&odT!rxorC*rr*Eq0sTd8O7|?KXSp
zW@z2ixst?mljOJ(Gh|C*dP#CJON(Yl613zEB2?TYp;nRsSB$bn(AGbyU&JT^WyB*l
zx`F$;r1dd1H@c{}QDe2m?JF>~i=H3JH>ndX@CQJ>X6^#O-syvy18yJBee9s?1D5DY
zHG&KnP+ww}vz`BvPf*~fH`O7*_#_4xJb;0xHxT}()b-;wS>w@J+@$7qH^%j;JW#uq
zquKthm0Qivc3a`q%9R3uJ^Vbx)nxs&rRYwKau81{8E5JEaCz`b!@3vk#=zbvlcb_;
zPx0-ULgmv{On(gcryv&UK13NCSQVdVdM3*&Ha}^NxV?WTJ{!b(HZ3w0%WR59mz6p%
z4}NF|ARvDV|J!mXW8!{EWQ|<Hx}?8dfQ9YL+cdpHgdp8ul}cCx-Pbfk^VYgxQ7;{x
zwPo`e-cp1mryHR$dMJK9K(@~$0UJN4XzxD!GCi}#4f{tZ+-iGSYn!8~a5m{1ph;(A
cZE<Ebybhfv`lP}51F8m!U`Qzw@y*Zw4|>+ni2wiq

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/model_utils.cpython-36.pyc b/utils/__pycache__/model_utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9089c9c9b4b2623217da9d7546d1426a45df0879
GIT binary patch
literal 890
zcma)4J8u&~5Z<|$&#wptgc2$WnrnOo6;c#YAk!c>fyM%z&fax$_THVfyQe&KNJx%^
zQ{;#6kI=RhD1U(lX4XL<(Xi4yb{;$5%<S{wu($pC{lg27v2X0J<D>o(Nso|m#zC?v
zp!B3y`cogs=F6ZAry=Sc9`fiKrV)n|mc)0M!zKyX=uKYEc#c{yudBs)9*_r5h!i1F
z8NEej*b-XCWA5F0H+1v1Sd>ExOP|9bGr=-^!cKke-}|FwXBltUmTlmMwH{}ySiLvh
z&ujra;Nf+=!Q2ge461{BYeZIz?A&@gPwT5sZLnnv?}W9%3ATjbyOTRWJOnwvC^X7$
z*+^5YrO<Qo&>@KvV-JyZjI2c<k0>1`UnmzY=z%iVE7d{wk8%1=3#HStzPc(z`by}P
zsn_Ye<|2Jvn6qY<zQy277Aql(v%2PKV+u(LT*%DnqxGeYkEEOEai1z9v8!iPC6oE3
zP}%G<Gk6;v$$FkkeT>R3{J)Sps0k=)2t^l#GpQbFRB?#ps#14VUW&V)c#@v=%)<7?
z#X7He#*0$h0MQE@>a%<;6m8jdtEP15v<+86<=RFLw6>kG%#9J1qLC({?NJX|QLP(e
z2To+@)wNOs44C$nFpa7*>f8EtV}9dyfC;PJ|92+z+w?v%27B-n9zYC_y#oj!_S7L-
z6K^t3I#}CPTFClb?V;HY9M;heszYdp^p}g%M&+icE7zTSVmB<>_n)!h#&Cs=6vy;u
LG@*!L00aLQ6du|y

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/predict_utils.cpython-36.pyc b/utils/__pycache__/predict_utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8e9f42220f6e324d31f1f89cbdf450958905b75e
GIT binary patch
literal 2195
zcmZ9NOK%)S5XZacJ+rfGI|&X>0)&SI6CR5K+#(c-C~)#6Mo6PrtI2lTp5568J+rX3
zdO5J+Xer{vSKvGFNm|^vkRw-w1pn&U#1=E^+Un}6uHK$sSAWv&COd!qdH7qx*dOfD
z<3hiWR(}d1nBW!5IewkWnYg*jndk^l_)mH6i9m!;S?-He#3F$u5d0C#y3Y~G_A_q0
z;cR;JaOhAUPY2CM`vR^09im|)zH&4hIfCyo?d-CZtC@B?Nc@wt$5x((Mt$4!wLfx2
zpq;g|3L0<Z>p(cd72dhK3egWP^&`#IFR+C=(hj`*a~HAUny(_VT5oU7n@B@qz8IDm
zzVX_5#9oYAt4|)QL`R5^C|-xqVrVqWCdO)^PS(y5;swJtB>RfvKRzdMkU7RHmSt_C
zv6ORBPU?&+kB0xnqXK9bB1;r)nb~S&-3*=-&G2MUmuJ%W^+_?8CRDOjoax-Sbt8;7
zk;T*mO3r1`7`Kw>6!W>9imYQ?xVL!+NNkcP)oeJn6XqScY*aBQr$R3CwC#LXR0~<>
zT|^=0pzRvBsZLA?F+jdNB8771NgHJKxYgnCD^suFAN>7Q|La<+x<8qnot3ixK-S}C
zHt!E-LiWEbo0G+p{y|ZX2UR(iRe3U-iT<J~tGYi|Qk27HV0$0UPtA6_>I+8#slE-t
zc))x1P5CxnkMH75orJfqx(=Tq?KM4HXtdjw!GE9}gEBN9EkFykI|7M<6Iti(V`mku
z;^of`*Ianl*_uCKhd-{8#u>Rf9^oMDvBn<-#}0VF!O$HX70{}aBj+9i*~DMRj;4r-
zbSk_(h65CwJF9LJ>+YH(M|aiJ-YB6SXP`XMJ*$Ny%G5y=^0ZN8|Mu=T4EEHL=~>N3
ze&1%mnrL=Sy^h}Wpm#B^N7>i>2xp5p&BFZy;}K=xGyeW$R>?sv8xxA6DWE7S2A1Lt
zty#|mbupP&U{Mv*W2sO+nDNh~n$;>IZ%b}GT}%d;VqBYW^C^uxDVFwIDEbEAQys%%
z{6eYXl)5xuwq^VY=%`Fu$wEz~u+x~>9tE1wbZBvdYE}rT@+~r5!Y9A_KLhwxd5>`2
ztfQPwjYqoSOT$m|#O4u$QY=kkgUjiB(U|1IUtPt5a|=Iavt+kom;T7rW7*h6URuT;
z2I_Yp7;tRgYy1kZ+y<yucxutSMTj~nS0BRfU`TsSPZy1L(h_<P)dN(z&-n6A!x}yU
zXAjsjes}}5(NT9b2Z!DzTK!cp-EFP#_CPVJBM5_?=thf{KU~aoI7f{Gzd9I&mStqH
zv?i#t$%f^4!*Zm3owTH*2F6W-$PS1Pz$UJOb2>HAIaUaUBaHhXv}4J&qn6yqAlC<r
zREa~Y*_sNirz0DIb<kYUw=hdcv$w?B(V)#VMwS<AzR6Z8PHn7Ho8gMhu&v!ST}JW#
zfqE6YnK_C+in?KS6v3BO)tW5i7WWsVbG1XRJL(pN5!LE-5;sYNBnW-=8VL*j8>A81
zE#$XJdy~Xl5Gd1&iF%v5DMZ#)M2C8phITC5v+3aC07lkS42LFakrYdnQNSG%+a%tj
z(AE#=s`ttE0oh!H{h!g)GD^1z20w<^OE|9q&s}HNLb|;H^ftF>^838!sL$Y?@rM~d
z$U@`eT+dJ2L*J##y*ys1qQRMJcZf=@#o2~kS_Rz(${v^K9?tiolAqJPSkul$Jav<6
H(e?iTHi;P+

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/train_utils.cpython-36.pyc b/utils/__pycache__/train_utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e68cb6674023f972b9010a932f219a634f8d616b
GIT binary patch
literal 574
zcmYjOJ&)8d5cNl#-P>aYLgEk|Z5mS0o)8iUx@$O^6)4Ka-i@<P9N7+cyUJGFmG?tv
z`8m^4p!*9{jC0Ldn&%n$dFDO)?Q*&J4S&C{DItHzqs1_PkKtb<NFu2rD~dZatmP|C
ziR3c5A*)2vFC-K9$RZaRg`~3GrsA>0m14{=K4AD2!pIsjQb{GdW8c`3ACo{EHYN?1
z{1pjFBev`(JqnqO0;iE%Hqs3{CnIUnk&k#f;>ngtf!rBtNbdw{A*f+?ahWlghtlr~
zEwAC^s<uWIUImBd$o&Kh%rXwC>TOkfSggxX)rHpw1+yQ@t*uwt98zDly-~or9>hU8
z>p}Rs?3Ihp0w>+j7IBUTzR|(WW78BwYo#(SdWTb4hO#iWl*$3U2D*pEgR-t4!Y|@p
zAnV_!{Hs^a=dC>)w8}p!zYDg{E9{eh)}bEO`DL_Y^iCOFTPyP+XyfzXO5GJx{-)o<
z(}(&BuS~iGHuq5#q0i|VeMa3&%rgN3mG^shiWMy5PwDO8%AjpGIh$ycv`26j$@6nG
QHyHIUzM@YM=JW~w4{jxxB>(^b

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/utils.cpython-36 2.pyc b/utils/__pycache__/utils.cpython-36 2.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..213faff09203b0c1e1cdd621d6a3b1dc3316bc42
GIT binary patch
literal 365
zcmYjNy-ve05I(zsMnUb=2e4QmOO4bO5K@4t3PXi}N(e=<tA_kII=e$6Hh2e~fmh1P
z#49jy2@>M0@4K_V&u8lvlSy#B2p-=7;FItdoT>|goe?QetbjEru10ULW{RyK^u9=e
zIAwjJ=<@*~BG_Z1X6oRXy}&DDa0k`Q1IP0K4;fh*JV3?osV{Zn?TLs`Cr*n*s0?-L
z3^pR$2)EU!MP{obCrm|hK{nOQMI4SgZfv(#=5(PO->j|>4Th}q>cnk70Qcz!-)HjH
zYP7O6ZJTL%scr5|EmNbktdm-!jFz#i)#mAUw{uxx<-qg0!4dW7VSOUtoK0yBry<9F
aLPI?~^^e9RbpB~+)UMFy{a9@8_4yBQ4^Qy`

literal 0
HcmV?d00001

diff --git a/utils/__pycache__/utils.cpython-36.pyc b/utils/__pycache__/utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..843ccbd9168104d14a45a45054381541af7d8158
GIT binary patch
literal 352
zcmYjNu};G<5IsAARzdC553pDuOI@ieLP!B76ov``l^CMf5R=r7Y<CD^gMa8Z@Jm^l
z_ys1;K|<W=y*v56J6X4!Op?oG@~{JdPsCqP?9LEwh9p3c2G$^`h~8mM1X)2Ef1v_-
zNkYL0^#G9}+%Zx&_3%ty;f)Zu1wD(w(>k$-1g!+_LDM_ji<{`nf@M|~Ub2D-Wo7A&
z?U;IGzLHil<@AwfMx)%IO>}dXr%_Lh>-RP_4)mkz)rGajrlgPC!dD+)_wfhc3x4CI
zb-YoP(NB%i{9L-)o0ex+IWLWneCt)?etF(@Ho~z0H%0<V$rN*VO{on>8Tw)SKN_LX
Sk54v6Y#VtRF5!ZAOn(4chDzfA

literal 0
HcmV?d00001

diff --git a/utils/data_utils.py b/utils/data_utils.py
new file mode 100644
index 0000000..7a20e6a
--- /dev/null
+++ b/utils/data_utils.py
@@ -0,0 +1,133 @@
+import os
+from matplotlib.pyplot import imread
+import numpy as np
+import pandas as pd
+
+def load_sub_omniglot(path,n=0):
+	
+	'''
+	path => Path of train directory or test directory
+	'''
+	X=[]
+	y = []
+	cat_dict = {}
+	lang_dict = {}
+	curr_y = n
+
+	# we load every alphabet seperately so we can isolate them later
+	for alphabet in os.listdir(path):
+	    if alphabet == '.DS_Store':
+	    	continue
+	    print("loading alphabet: " + alphabet)
+	    lang_dict[alphabet] = [curr_y,None]
+	    alphabet_path = os.path.join(path,alphabet)
+	    
+	    # every letter/category has it's own column in the array, so  load seperately
+	    for letter in os.listdir(alphabet_path):
+	        if letter == '.DS_Store':
+	        	continue
+	        cat_dict[curr_y] = (alphabet, letter)
+	        category_images=[]
+	        letter_path = os.path.join(alphabet_path, letter)
+	        
+	        # read all the images in the current category
+	        for filename in os.listdir(letter_path):
+	            image_path = os.path.join(letter_path, filename)
+	            image = imread(image_path)
+	            category_images.append(image)
+	            y.append(curr_y)
+	        try:
+	            #X.append(np.stack(category_images))
+	            X += list(np.stack(category_images))
+	        # edge case  - last one
+	        except ValueError as e:
+	            print(e)
+	            print("error - category_images:", category_images)
+	        curr_y += 1
+	        lang_dict[alphabet][1] = curr_y - 1
+	y = np.vstack(y)
+	X = np.stack(X)
+	print(X.shape,y.shape,len(np.unique(y)))
+	return X,y
+
+
+def load_omniglot(path=None):
+	if path is None:
+		train_path = './data/omniglot/images_background'
+		test_path = './data/omniglot/images_evaluation'
+	else:
+		train_path,test_path = path
+
+
+	return load_sub_omniglot(train_path),load_sub_omniglot(test_path)
+
+
+
+
+def load_tihm(path=None):
+	if path is None:
+		path = './data/timh1.5'
+	
+	data = []
+	label = []
+
+	for filename in os.listdir(path):
+		if '_lag_new.csv' in filename:
+			file_path = os.path.join(path, filename)
+			d = pd.read_csv(file_path)
+			if 'halway' in list(d.columns):
+				d = d.drop(columns='halway')
+			if 'd_front' not in list(d.columns):
+				continue
+			d = np.array(d.values)
+			d = d[:,2:]
+			data += d.tolist()
+			f_label = filename.split('_lag_new.csv')[0]
+			f_label += '_class.csv'
+			file_path = os.path.join(path, f_label)
+			d = np.array(pd.read_csv(file_path,header=None))
+			
+			label += d.reshape(-1).tolist()
+
+	data = np.array(data)
+	label = np.array(label)
+
+	return (data[:10000],label[:10000]),(data[10000:],label[10000:])
+
+
+
+def load_agitation(path=None):
+	if path is None:
+		path = './data/aigitation'
+
+	data = []
+	label = []
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/utils/dataloader.py b/utils/dataloader.py
new file mode 100644
index 0000000..ea1a7bb
--- /dev/null
+++ b/utils/dataloader.py
@@ -0,0 +1,193 @@
+import numpy as np
+from utils.load_data import Load_data
+import tensorflow as tf
+from configuration import conf
+
+
+class Baseline_loader(object):
+	def __init__(self):
+		try:
+			load_func = getattr(load_data,'load_'+ conf.dataset_name)
+			self.data = load_func(conf.is_conv)
+		except:
+			assert ValueError('Dataset is not available ... ')
+		conf.num_samples = self.data['X_train'].shape[0]
+		conf.shape_of_sample = self.data['X_train'].shape[1:]
+
+	@property
+	def num_classes(self):
+		return len(np.unique(self.data['y_train']))
+
+	@property
+	def num_samples(self):
+		return self.data['X_train'].shape[1]
+
+	@property
+	def shape_of_sample(self):
+		return self.data['X_train'].shape[1:]
+
+	@property
+	def is_flatten(self):
+		return len(self.data['X_train']) == 2
+		
+
+	def sample(self, dataset='train', batch_size=None):
+		if batch_size is None:
+			batch_size = conf.batch_size
+		assert dataset in ['train', 'val', 'test']
+
+		N = self.data['X_' + dataset].shape[0]
+		idx_N = np.random.choice(N, batch_size, replace=False)
+
+		images, labels = self.data['X_' + dataset][idx_N], self.data['y_' + dataset][idx_N]
+
+		return images, labels
+
+	def build_iterator(self, batch_size=None):
+		if batch_size is None:
+			batch_size = conf.batch_size
+		self.init = {}
+		with tf.name_scope('data'):
+			train_data = tf.data.Dataset.from_tensor_slices(self.data['X_train']).batch(batch_size)
+			test_data = tf.data.Dataset.from_tensor_slices(self.data['X_test']).batch(batch_size)
+			iterator = tf.data.Iterator.from_structure(data.output_types,data.output_shapes)
+			img,label = iterator.get_next()
+			self.init['train'] = iterator.make_initializer(train_data)
+			self.init['test'] = iterator.make_initializer(test_data)
+
+	def get_whole_dataset(self):
+		return self.data
+
+			
+
+class Sequential_loader(object):
+	def __init__(self):
+		self.data = Load_data().load()
+		self._task_idx = 0
+		num_samples = 0
+		for i in range(len(self.data)):
+			num_samples += self.data[i]['X_train'].shape[0]
+		conf.num_samples = num_samples
+
+	@property
+	def num_classes(self):
+		num_classes = 0
+		for i in range(len(self.data)):
+			num_classes += len(np.unique(self.data[i]['y_train']))
+		return num_classes
+
+	@property
+	def num_samples(self):
+		return conf.num_samples
+
+	@property
+	def shape_of_sample(self):
+		return self.data[0]['X_train'].shape[1:]
+
+	@property
+	def is_flatten(self):
+		return len(self.data[0]['X_train']) == 2
+		
+
+	def sample(self, task_idx=None, dataset='train', batch_size=None,whole_set=False):
+		if batch_size is None:
+			batch_size = conf.batch_size
+		if task_idx is None:
+			task_idx = self._task_idx
+		assert dataset in ['train', 'val', 'test']
+
+		if whole_set:
+			return self.data[task_idx]['X_' + dataset], self.data[task_idx]['y_' + dataset]
+
+		N = self.data[task_idx]['X_' + dataset].shape[0]
+		idx_N = np.random.choice(N, batch_size, replace=False)
+
+		images, labels = self.data[task_idx]['X_' + dataset][idx_N], self.data[task_idx]['y_' + dataset][idx_N]
+		if labels.ndim == 1:
+			labels = labels[:,np.newaxis]
+		return images, labels
+
+
+
+	def _build_iterator(self, batch_size=None):
+		if batch_size is None:
+			batch_size = conf.batch_size
+		self.data_init = {}
+		with tf.name_scope('data'):
+			train_data = tf.data.Dataset.from_tensor_slices((self.data[0]['X_train'],self.data[0]['y_train'])).batch(batch_size)
+			test_data = tf.data.Dataset.from_tensor_slices((self.data[0]['X_test'],self.data[0]['y_test'])).batch(batch_size)
+			iterator = tf.data.Iterator.from_structure(data.output_types,data.output_shapes)
+			self.img_holder,self.label_holder = iterator.get_next()
+			self.data_init[0] = {}
+			self.data_init[0]['train'] = iterator.make_initializer(train_data)
+			self.data_init[0]['test'] = iterator.make_initializer(test_data)
+			for i in range(1,len(self.data)):
+				train_data = tf.data.Dataset.from_tensor_slices((self.data[0]['X_train'],self.data[0]['y_train'])).batch(batch_size)
+				test_data = tf.data.Dataset.from_tensor_slices((self.data[0]['X_test'],self.data[0]['y_test'])).batch(batch_size)
+				self.data_init[i] = {}
+				self.data_init[i]['train'] = iterator.make_initializer(train_data)
+				self.data_init[i]['test'] = iterator.make_initializer(test_data)
+
+	@property
+	def task_idx(self):
+		return self._task_idx
+	
+
+	@task_idx.setter
+	def task_idx(self,idx):
+		self._task_idx = idx
+		print('------------ Training Task Index : %d ------------'%self._task_idx)
+	
+
+	def initial_data(self,task_idx=None):
+		if not hasattr(self,'data_init'):
+			self._build_iterator()
+		if task_idx is None:
+			task_idx = self._task_idx
+
+		return self.data_init[task_idx]
+
+	def get_holder(self):
+		if conf.enable_iterator:
+			return self.img_holder, self.label_holder
+		else:
+			img_holder = tf.placeholder(dtype=tf.float32,shape=[None,self.shape_of_sample[0]])
+			label_holder = tf.placeholder(dtype=tf.float32,shape=[None,conf.num_classes] if conf.enable_one_hot else [None,1])
+
+			return img_holder, label_holder
+	
+
+	def get_whole_dataset(self):
+		return self.data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	
+
+	
diff --git a/utils/layers.py b/utils/layers.py
new file mode 100644
index 0000000..0327b34
--- /dev/null
+++ b/utils/layers.py
@@ -0,0 +1,59 @@
+import tensorflow as tf
+from keras import backend as K
+from utils.model_utils import mask_layer_by_task
+from keras.layers import Layer
+
+# Multiple Centers
+class Probability_CLF_Mul_by_task(Layer):
+    """docstring for Probability_CLF"""
+
+    def __init__(self, output_dim, num_centers=4, activation=None, sigma=1.0, **kwargs):
+        self.output_dim = output_dim
+        self.num_centers = num_centers
+        self.sigma = sigma
+        self.activation = activation
+        super(Probability_CLF_Mul_by_task, self).__init__(**kwargs)
+
+    def build(self, input_shape):
+        self.centers = {}
+        for idx in range(self.output_dim):
+            self.centers[idx] = []
+            for c in range(self.num_centers):
+                W = self.add_weight(name='center%d_%d' % (idx, c), shape=(input_shape[1][1],), initializer='uniform',
+                                    trainable=True)
+                self.centers[idx].append(W)
+
+        super(Probability_CLF_Mul_by_task, self).build(input_shape[1][1])
+
+    def call(self, inputs, training=None):
+        task_input = inputs[0]
+        x = inputs[1]
+        _, mask = mask_layer_by_task(task_input, x, return_mask=True)
+
+        logits = []
+        for idx in range(self.output_dim):
+            G = []
+
+            for c in range(self.num_centers):
+                G.append(self.gaussian_activation(
+                    tf.boolean_mask(tf.squared_difference(x, self.centers[idx][c]), mask[0], axis=1)))
+
+            G = tf.stack(G, axis=1)
+            P = tf.reduce_sum(G, axis=1) / (
+                    tf.reduce_sum(G, axis=1) + self.num_centers - tf.reduce_max(G, axis=1) * self.num_centers)
+            logits.append(P)
+
+        logits = tf.stack(logits, axis=1)
+
+        if self.activation is not None:
+            logits = self.activation(logits)
+
+        return K.in_train_phase(mask_layer_by_task(task_input, logits),
+                                mask_layer_by_task(task_input, logits),
+                                training=training)
+
+    def gaussian_activation(self, x):
+        return tf.exp(-tf.reduce_sum(x, axis=1) / (2. * self.sigma * self.sigma))
+
+    def compute_output_shape(self, input_shape):
+        return input_shape[1][0], self.output_dim
diff --git a/utils/load_data.py b/utils/load_data.py
new file mode 100644
index 0000000..ae9ed23
--- /dev/null
+++ b/utils/load_data.py
@@ -0,0 +1,164 @@
+import numpy as np
+import keras.datasets as Datasets
+from configuration import conf
+from keras.utils import np_utils
+
+class Load_data(object):
+
+	def __init__(self):
+		pass
+
+	def load(self):
+		task_type = conf.task_type
+		dataset_name = conf.dataset_name
+		assert task_type in ['Baseline','Sequential_split','Sequential_permute'], 'Task type is not valid'
+		assert dataset_name in ['mnist','cifar10','cifar100','omniglot','timh','fashion_mnist'], 'Dataset is not available'
+
+
+		data = self.load_dataset(dataset_name,conf.is_conv)
+
+		if task_type == 'Baseline':
+			return data
+		elif task_type == 'Sequential_split':
+			return self.split_data(data)
+		elif task_type == 'Sequential_permute':
+			return self.permute_data(data)
+
+
+
+	def load_dataset(self,data_name,is_conv):
+		if data_name in ['omniglot']:
+			from utils.data_utils import load_omniglot
+			(X_train, y_train), (X_test, y_test) = load_omniglot()
+		elif data_name in ['timh']:
+			from utils.data_utils import load_tihm
+			(X_train, y_train), (X_test, y_test) = load_tihm()
+			#self.get_description([X_train,y_train,X_test,y_test])
+		else:
+			dataset_obj = getattr(Datasets,data_name)
+			(X_train, y_train), (X_test, y_test) = dataset_obj.load_data()
+		self.nb_classes = len(np.unique(y_train))
+		conf.num_classes = self.nb_classes
+		if data_name in ['cifar10','cifar100']:
+			is_conv = True
+		if not is_conv:
+			#assert data_name not in ['cifar10','cifar100'], data_name + ' must be trained with is_conv = True'
+			X_train = X_train.reshape(X_train.shape[0],-1)
+			X_test = X_test.reshape(X_test.shape[0],-1)
+		else:
+			if data_name in ['mnist']:
+				X_train = X_train.reshape(X_train.shape[0],28,28,1)
+				X_test = X_test.reshape(X_test.shape[0],28,28,1)
+
+			elif data_name in ['cifar10','cifar100']:
+				X_train = X_train.reshape(X_train.shape[0],32,32,3)
+				X_test = X_test.reshape(X_test.shape[0],32,32,3)
+
+			elif data_name in ['omniglot']:
+				X_train = X_train.reshape(X_train.shape[0],105,105,1)
+				X_test = X_test.reshape(X_test.shape[0],105,105,1)
+
+
+		if np.max(X_train) == 255.:
+			print('Normalizing the training data ... ')
+			X_train = X_train.astype('float32') / 255
+			X_test = X_test.astype('float32') / 255
+
+		data = {
+			'X_train': X_train,
+			'y_train': y_train,
+			'X_test': X_test,
+			'y_test': y_test,
+		}
+		return data
+
+
+
+	def split_data(self,data):
+		try:
+			task_labels = conf.task_labels
+		except:
+			raise ValueError('Label is not provided ...')
+		datasets = {}
+		one_hot = conf.enable_one_hot
+		for task_idx,labels in enumerate(task_labels):
+			datasets[task_idx] = {}
+			train_idx = np.in1d(data['y_train'],labels)
+			datasets[task_idx]['X_train'] = data['X_train'][train_idx]
+
+			test_idx = np.in1d(data['y_test'],labels)
+			datasets[task_idx]['X_test'] = data['X_test'][test_idx]
+			if conf.multi_head:
+				if one_hot:
+					datasets[task_idx]['y_train'] = np_utils.to_categorical(data['y_train'][train_idx] - np.min(labels), len(labels))
+					datasets[task_idx]['y_test'] = np_utils.to_categorical(data['y_test'][test_idx] - np.min(labels), len(labels))
+				else:
+					datasets[task_idx]['y_train'] = data['y_train'][train_idx] - np.min(labels)
+					datasets[task_idx]['y_test'] = data['y_test'][test_idx] - np.min(labels)
+			else:	
+				datasets[task_idx]['y_train'] = np_utils.to_categorical(data['y_train'][train_idx], int(self.nb_classes)) if one_hot else data['y_train'][train_idx]
+				datasets[task_idx]['y_test'] = np_utils.to_categorical(data['y_test'][test_idx], int(self.nb_classes)) if one_hot else data['y_test'][test_idx]
+
+			#idx = np.in1d(data['y_test'],labels)
+			#datasets[task_idx]['X_test'] = data['X_test'][idx]
+			#datasets[task_idx]['y_test'] = np_utils.to_categorical(data['y_test'][idx], int(self.nb_classes)) if one_hot else data['y_test'][idx]
+
+		return datasets
+		
+	def permute_data(self,data):
+		num_tasks = conf.num_tasks
+		permutations = []
+		for i in range(num_tasks):
+			idx = np.arange(data['X_train'].shape[1],dtype=int)
+			if i > 0:
+				np.random.shuffle(idx)
+			permutations.append(idx)
+		datasets = {}
+		one_hot = conf.enable_one_hot
+		for task_idx, perm in enumerate(permutations):
+			datasets[task_idx] = {}
+
+			datasets[task_idx]['X_train'] = data['X_train'][:,perm]
+			datasets[task_idx]['X_test'] = data['X_test'][:,perm]
+			datasets[task_idx]['y_train'] = np_utils.to_categorical(data['y_train'], int(self.nb_classes)) if one_hot else data['y_train']
+			datasets[task_idx]['y_test'] = np_utils.to_categorical(data['y_test'], int(self.nb_classes)) if one_hot else data['y_test']
+		
+		return datasets
+
+
+	def get_description(self,data):
+		X_train,y_train,X_test,y_test = data
+		
+		print('X_train : ', X_train.shape)
+		print('X_test : ', X_test.shape)
+
+		print('y_train : ', np.unique(y_train))
+		for l in np.unique(y_train):
+			print('y_train == ',l, y_train[y_train==l].shape)
+			print('y_test == ',l, y_test[y_test==l].shape)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/utils/model_utils.py b/utils/model_utils.py
new file mode 100644
index 0000000..fa82ab4
--- /dev/null
+++ b/utils/model_utils.py
@@ -0,0 +1,17 @@
+import tensorflow as tf
+from keras.layers import Lambda
+from configuration import conf
+
+
+def mask_layer_by_task(task_input, input_tensor, name=None, return_mask=False):
+    mask = tf.expand_dims(task_input, axis=-1)
+    mask = tf.tile(mask, multiples=[1, 1, input_tensor.shape[1] // conf.num_tasks])
+    mask = tf.keras.layers.Flatten()(mask)
+    if name is None:
+        out = Lambda(lambda x: x * mask)(input_tensor)
+    else:
+        out = Lambda(lambda x: x * mask, name=name)(input_tensor)
+    if return_mask:
+        return out, mask
+    else:
+        return out
diff --git a/utils/predict_utils.py b/utils/predict_utils.py
new file mode 100644
index 0000000..0c254a9
--- /dev/null
+++ b/utils/predict_utils.py
@@ -0,0 +1,69 @@
+import numpy as np
+from configuration import conf
+
+
+def block_likelihood(res, keep_dim=False):
+    block_size = conf.test_batch_size
+    extra_index = res.shape[0] % block_size
+    extra_values = res[-extra_index:]
+    resize_values = res[:-extra_index]
+    tlh = resize_values.reshape(-1, block_size)
+    tlh_std = np.std(tlh, axis=1, keepdims=True)
+    tlh_mean = np.mean(tlh, axis=1, keepdims=True)
+    if keep_dim:
+        tlh_mean = np.repeat(tlh_mean, block_size, axis=1).reshape(-1, )
+        extra_mean = np.repeat(np.mean(extra_values), len(extra_values))
+        return np.append(tlh_mean, extra_mean)
+    else:
+        extra_mean = np.mean(extra_values)
+        extra_std = np.std(extra_values)
+        tlh_mean = tlh_mean.reshape(-1, )
+        tlh_std = tlh_std.reshape(-1, )
+        return np.append(tlh_mean, extra_mean), np.append(tlh_std, extra_std)
+
+
+def get_task_likelihood(model, learned_task, test_task, data_loader):
+    task_likelihood = []
+    task_likelihood_var = []
+    tlh_prediction = []
+    pred = []
+    x, y = data_loader.sample(test_task, whole_set=True, dataset='test')
+    for learnd_idx in range(learned_task + 1):
+        task_input = np.zeros([y.shape[0], conf.num_tasks])
+        task_input[:, learnd_idx] = 1
+        prediction = model.predict([x, task_input])
+        tlh = np.max(prediction[1], axis=1)
+        tlh, tlh_var = block_likelihood(tlh)
+        task_likelihood.append(tlh)
+        task_likelihood_var.append(tlh_var)
+        pred.append(np.argmax(prediction[0], axis=1))
+
+    task_likelihood = np.array(task_likelihood)
+    task_likelihood_var = np.array(task_likelihood_var)
+
+    return np.max(task_likelihood, axis=0), \
+           task_likelihood_var[np.argmax(task_likelihood, axis=0), np.arange(task_likelihood_var.shape[1])]
+
+
+def get_test_acc(model, data_loader, test_on_whole_set=True):
+    test_acc = []
+    for task_idx in range(conf.num_tasks):
+        if test_on_whole_set:
+            x, y = data_loader.sample(task_idx, whole_set=True, dataset='test')
+        else:
+            x, y = data_loader.sample(task_idx, batch_size=conf.test_batch_size, dataset='test')
+        res = []
+        pred = []
+        for test_idx in range(conf.num_tasks):
+            task_input = np.zeros([y.shape[0], conf.num_tasks])
+            task_input[:, test_idx] = 1
+            prediction = model.predict([x, task_input])
+            res.append(block_likelihood(np.max(prediction[1], axis=1), keep_dim=True))
+            pred.append(np.argmax(prediction[0], axis=1))
+
+        res = np.array(res)
+        pred = np.array(pred)
+        acc = np.sum(pred[np.argmax(res, axis=0), np.arange(pred.shape[1])] == np.argmax(y, axis=1)) / y.shape[0]
+        test_acc.append(acc)
+
+    return np.mean(test_acc)
diff --git a/utils/train_utils.py b/utils/train_utils.py
new file mode 100644
index 0000000..f59c91b
--- /dev/null
+++ b/utils/train_utils.py
@@ -0,0 +1,9 @@
+import numpy as np
+from configuration import conf
+
+
+def train_with_task(model, task_idx, data_loader):
+    x, y = data_loader.sample(task_idx=task_idx, whole_set=True)
+    task_input = np.zeros([y.shape[0], conf.num_tasks])
+    task_input[:, task_idx] = 1
+    model.fit([x, task_input], [y, task_input], epochs=10, batch_size=conf.batch_size, verbose=0)
diff --git a/utils/utils.py b/utils/utils.py
new file mode 100644
index 0000000..e83e59a
--- /dev/null
+++ b/utils/utils.py
@@ -0,0 +1,8 @@
+import os
+
+def mkdir(path):
+    """ Create a directory if there isn't one already. """
+    try:
+        os.mkdir(path)
+    except OSError:
+        pass
\ No newline at end of file
-- 
GitLab