From aeb4990c81ab3ea16b8e20a7264c3b73a9e73d1c Mon Sep 17 00:00:00 2001
From: ltcptgeneral <35508619+ltcptgeneral@users.noreply.github.com>
Date: Thu, 30 Apr 2020 16:03:37 -0500
Subject: [PATCH] analysis pkg v 1.0.0.12 analysis.py v 1.2.0.004

---
 .../analysis-amd64/analysis.egg-info/PKG-INFO |   2 +-
 .../analysis.egg-info/SOURCES.txt             |   8 +-
 .../analysis-amd64/analysis/analysis.py       | 113 +--
 .../build/lib/analysis/analysis.py            | 263 ++++-
 .../build/lib/analysis/metrics/__init__.py    |   0
 .../build/lib/analysis/metrics/elo.py         |   7 +
 .../build/lib/analysis/metrics/glicko2.py     |  99 ++
 .../build/lib/analysis/metrics/trueskill.py   | 907 ++++++++++++++++++
 .../dist/analysis-1.0.0.12-py3-none-any.whl   | Bin 0 -> 32026 bytes
 .../dist/analysis-1.0.0.12.tar.gz             | Bin 0 -> 21001 bytes
 analysis-master/analysis-amd64/setup.py       |   2 +-
 11 files changed, 1322 insertions(+), 79 deletions(-)
 create mode 100644 analysis-master/analysis-amd64/build/lib/analysis/metrics/__init__.py
 create mode 100644 analysis-master/analysis-amd64/build/lib/analysis/metrics/elo.py
 create mode 100644 analysis-master/analysis-amd64/build/lib/analysis/metrics/glicko2.py
 create mode 100644 analysis-master/analysis-amd64/build/lib/analysis/metrics/trueskill.py
 create mode 100644 analysis-master/analysis-amd64/dist/analysis-1.0.0.12-py3-none-any.whl
 create mode 100644 analysis-master/analysis-amd64/dist/analysis-1.0.0.12.tar.gz

diff --git a/analysis-master/analysis-amd64/analysis.egg-info/PKG-INFO b/analysis-master/analysis-amd64/analysis.egg-info/PKG-INFO
index 410189e2..83058193 100644
--- a/analysis-master/analysis-amd64/analysis.egg-info/PKG-INFO
+++ b/analysis-master/analysis-amd64/analysis.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: analysis
-Version: 1.0.0.11
+Version: 1.0.0.12
 Summary: analysis package developed by Titan Scouting for The Red Alliance
 Home-page: https://github.com/titanscout2022/tr2022-strategy
 Author: The Titan Scouting Team
diff --git a/analysis-master/analysis-amd64/analysis.egg-info/SOURCES.txt b/analysis-master/analysis-amd64/analysis.egg-info/SOURCES.txt
index 25a54640..2d8be231 100644
--- a/analysis-master/analysis-amd64/analysis.egg-info/SOURCES.txt
+++ b/analysis-master/analysis-amd64/analysis.egg-info/SOURCES.txt
@@ -1,13 +1,15 @@
 setup.py
 analysis/__init__.py
 analysis/analysis.py
-analysis/glicko2.py
 analysis/regression.py
 analysis/titanlearn.py
-analysis/trueskill.py
 analysis/visualization.py
 analysis.egg-info/PKG-INFO
 analysis.egg-info/SOURCES.txt
 analysis.egg-info/dependency_links.txt
 analysis.egg-info/requires.txt
-analysis.egg-info/top_level.txt
\ No newline at end of file
+analysis.egg-info/top_level.txt
+analysis/metrics/__init__.py
+analysis/metrics/elo.py
+analysis/metrics/glicko2.py
+analysis/metrics/trueskill.py
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/analysis/analysis.py b/analysis-master/analysis-amd64/analysis/analysis.py
index eb898a1a..c13aef90 100644
--- a/analysis-master/analysis-amd64/analysis/analysis.py
+++ b/analysis-master/analysis-amd64/analysis/analysis.py
@@ -7,10 +7,17 @@
 #    current benchmark of optimization: 1.33 times faster
 # setup:
 
-__version__ = "1.2.0.003"
+__version__ = "1.2.0.004"
 
 # changelog should be viewed using print(analysis.__changelog__)
 __changelog__ = """changelog:
+    1.2.0.004:
+        - fixed __all__ to reflected the correct functions and classes
+        - fixed CorrelationTests and StatisticalTests class functions to require self invocation
+        - added missing math import
+        - fixed KNN class functions to require self invocation
+        - fixed Metrics class functions to require self invocation
+        - various spelling fixes in CorrelationTests and StatisticalTests
     1.2.0.003:
         - bug fixes with CorrelationTests and StatisticalTests
         - moved glicko2 and trueskill to the metrics subpackage
@@ -275,22 +282,19 @@ __all__ = [
     'z_normalize',
     'histo_analysis',
     'regression',
-    'elo',
-    'glicko2',
-    'trueskill',
+    'Metrics',
     'RegressionMetrics',
     'ClassificationMetrics',
     'kmeans',
     'pca',
     'decisiontree',
-    'knn_classifier',
-    'knn_regressor',
+    'KNN',
     'NaiveBayes',
     'SVM',
     'random_forest_classifier',
     'random_forest_regressor',
     'CorrelationTests',
-    'RegressionTests',
+    'StatisticalTests',
     # all statistics functions left out due to integration in other functions
 ]
 
@@ -301,6 +305,7 @@ __all__ = [
 import csv
 from analysis.metrics import elo as Elo
 from analysis.metrics import glicko2 as Glicko2
+import math
 import numba
 from numba import jit
 import numpy as np
@@ -467,11 +472,11 @@ def regression(inputs, outputs, args): # inputs, outputs expects N-D array
 
 class Metrics:
 
-    def elo(starting_score, opposing_score, observed, N, K):
+    def elo(self, starting_score, opposing_score, observed, N, K):
 
         return Elo.calculate(starting_score, opposing_score, observed, N, K)
 
-    def glicko2(starting_score, starting_rd, starting_vol, opposing_score, opposing_rd, observations):
+    def glicko2(self, starting_score, starting_rd, starting_vol, opposing_score, opposing_rd, observations):
 
         player = Glicko2.Glicko2(rating = starting_score, rd = starting_rd, vol = starting_vol)
 
@@ -479,7 +484,7 @@ class Metrics:
 
         return (player.rating, player.rd, player.vol)
 
-    def trueskill(teams_data, observations): # teams_data is array of array of tuples ie. [[(mu, sigma), (mu, sigma), (mu, sigma)], [(mu, sigma), (mu, sigma), (mu, sigma)]]
+    def trueskill(self, teams_data, observations): # teams_data is array of array of tuples ie. [[(mu, sigma), (mu, sigma), (mu, sigma)], [(mu, sigma), (mu, sigma), (mu, sigma)]]
 
         team_ratings = []
 
@@ -584,7 +589,7 @@ def decisiontree(data, labels, test_size = 0.3, criterion = "gini", splitter = "
 
 class KNN:
 
-    def knn_classifier(data, labels, test_size = 0.3, algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform'): #expects *2d data and 1d labels post-scaling
+    def knn_classifier(self, data, labels, test_size = 0.3, algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform'): #expects *2d data and 1d labels post-scaling
 
         data_train, data_test, labels_train, labels_test = sklearn.model_selection.train_test_split(data, labels, test_size=test_size, random_state=1)
         model = sklearn.neighbors.KNeighborsClassifier()
@@ -593,7 +598,7 @@ class KNN:
 
         return model, ClassificationMetrics(predictions, labels_test)
 
-    def knn_regressor(data, outputs, test_size, n_neighbors = 5, weights = "uniform", algorithm = "auto", leaf_size = 30, p = 2, metric = "minkowski", metric_params = None, n_jobs = None):
+    def knn_regressor(self, data, outputs, test_size, n_neighbors = 5, weights = "uniform", algorithm = "auto", leaf_size = 30, p = 2, metric = "minkowski", metric_params = None, n_jobs = None):
 
         data_train, data_test, outputs_train, outputs_test = sklearn.model_selection.train_test_split(data, outputs, test_size=test_size, random_state=1)
         model = sklearn.neighbors.KNeighborsRegressor(n_neighbors = n_neighbors, weights = weights, algorithm = algorithm, leaf_size = leaf_size, p = p, metric = metric, metric_params = metric_params, n_jobs = n_jobs)
@@ -716,203 +721,203 @@ def random_forest_regressor(data, outputs, test_size, n_estimators="warn", crite
 
 class CorrelationTests:
 
-    def anova_oneway(*args): #expects arrays of samples
+    def anova_oneway(self, *args): #expects arrays of samples
 
         results = scipy.stats.f_oneway(*args)
         return {"F-value": results[0], "p-value": results[1]}
 
-    def pearson(x, y):
+    def pearson(self, x, y):
 
         results = scipy.stats.pearsonr(x, y)
         return {"r-value": results[0], "p-value": results[1]}
 
-    def spearman(a, b = None, axis = 0, nan_policy = 'propagate'):
+    def spearman(self, a, b = None, axis = 0, nan_policy = 'propagate'):
 
         results = scipy.stats.spearmanr(a, b = b, axis = axis, nan_policy = nan_policy)
         return {"r-value": results[0], "p-value": results[1]}
 
-    def point_biserial(x,y):
+    def point_biserial(self, x,y):
 
         results = scipy.stats.pointbiserialr(x, y)
         return {"r-value": results[0], "p-value": results[1]}
 
-    def kendall(x, y, initial_lexsort = None, nan_policy = 'propagate', method = 'auto'):
+    def kendall(self, x, y, initial_lexsort = None, nan_policy = 'propagate', method = 'auto'):
 
         results = scipy.stats.kendalltau(x, y, initial_lexsort = initial_lexsort, nan_policy = nan_policy, method = method)
         return {"tau": results[0], "p-value": results[1]}
 
-    def kendall_weighted(x, y, rank = True, weigher = None, additive = True):
+    def kendall_weighted(self, x, y, rank = True, weigher = None, additive = True):
 
         results = scipy.stats.weightedtau(x, y, rank = rank, weigher = weigher, additive = additive)
         return {"tau": results[0], "p-value": results[1]}
 
-    def mgc(x, y, compute_distance = None, reps = 1000, workers = 1, is_twosamp = False, random_state = None):
+    def mgc(self, x, y, compute_distance = None, reps = 1000, workers = 1, is_twosamp = False, random_state = None):
 
         results = scipy.stats.multiscale_graphcorr(x, y, compute_distance = compute_distance, reps = reps, workers = workers, is_twosamp = is_twosamp, random_state = random_state)
         return {"k-value": results[0], "p-value": results[1], "data": results[2]} # unsure if MGC test returns a k value
 
 class StatisticalTests:
 
-    def ttest_onesample(a, popmean, axis = 0, nan_policy = 'propagate'):
+    def ttest_onesample(self, a, popmean, axis = 0, nan_policy = 'propagate'):
 
         results = scipy.stats.ttest_1samp(a, popmean, axis = axis, nan_policy = nan_policy)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def ttest_independent(a, b, equal = True, nan_policy = 'propagate'):
+    def ttest_independent(self, a, b, equal = True, nan_policy = 'propagate'):
 
-        results = scipt.stats.ttest_ind(a, b, equal_var = equal, nan_policy = nan_policy)
+        results = scipy.stats.ttest_ind(a, b, equal_var = equal, nan_policy = nan_policy)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def ttest_statistic(o1, o2, equal = True):
+    def ttest_statistic(self, o1, o2, equal = True):
 
         results = scipy.stats.ttest_ind_from_stats(o1["mean"], o1["std"], o1["nobs"], o2["mean"], o2["std"], o2["nobs"], equal_var = equal)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def ttest_related(a, b, axis = 0, nan_policy='propagate'):
+    def ttest_related(self, a, b, axis = 0, nan_policy='propagate'):
 
         results = scipy.stats.ttest_rel(a, b, axis = axis, nan_policy = nan_policy)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def ks_fitness(rvs, cdf, args = (), N = 20, alternative = 'two-sided', mode = 'approx'):
+    def ks_fitness(self, rvs, cdf, args = (), N = 20, alternative = 'two-sided', mode = 'approx'):
 
         results = scipy.stats.kstest(rvs, cdf, args = args, N = N, alternative = alternative, mode = mode)
         return {"ks-value": results[0], "p-value": results[1]}
 
-    def chisquare(f_obs, f_exp = None, ddof = None, axis = 0):
+    def chisquare(self, f_obs, f_exp = None, ddof = None, axis = 0):
 
         results = scipy.stats.chisquare(f_obs, f_exp = f_exp, ddof = ddof, axis = axis)
         return {"chisquared-value": results[0], "p-value": results[1]}
 
-    def powerdivergence(f_obs, f_exp = None, ddof = None, axis = 0, lambda_ = None):
+    def powerdivergence(self, f_obs, f_exp = None, ddof = None, axis = 0, lambda_ = None):
 
         results = scipy.stats.power_divergence(f_obs, f_exp = f_exp, ddof = ddof, axis = axis, lambda_ = lambda_)
         return {"powerdivergence-value": results[0], "p-value": results[1]}
 
-    def ks_twosample(x, y, alternative = 'two_sided', mode = 'auto'):
+    def ks_twosample(self, x, y, alternative = 'two_sided', mode = 'auto'):
         
         results = scipy.stats.ks_2samp(x, y, alternative = alternative, mode = mode)
         return {"ks-value": results[0], "p-value": results[1]}
 
-    def es_twosample(x, y, t = (0.4, 0.8)):
+    def es_twosample(self, x, y, t = (0.4, 0.8)):
 
         results = scipy.stats.epps_singleton_2samp(x, y, t = t)
         return {"es-value": results[0], "p-value": results[1]}
 
-    def mw_rank(x, y, use_continuity = True, alternative = None):
+    def mw_rank(self, x, y, use_continuity = True, alternative = None):
 
         results = scipy.stats.mannwhitneyu(x, y, use_continuity = use_continuity, alternative = alternative)
         return {"u-value": results[0], "p-value": results[1]}
 
-    def mw_tiecorrection(rank_values):
+    def mw_tiecorrection(self, rank_values):
 
         results = scipy.stats.tiecorrect(rank_values)
         return {"correction-factor": results}
 
-    def rankdata(a, method = 'average'):
+    def rankdata(self, a, method = 'average'):
 
         results = scipy.stats.rankdata(a, method = method)
         return results
 
-    def wilcoxon_ranksum(a, b): # this seems to be superceded by Mann Whitney Wilcoxon U Test
+    def wilcoxon_ranksum(self, a, b): # this seems to be superceded by Mann Whitney Wilcoxon U Test
 
         results = scipy.stats.ranksums(a, b)
         return {"u-value": results[0], "p-value": results[1]}
 
-    def wilcoxon_signedrank(x, y = None, method = 'wilcox', correction = False, alternative = 'two-sided'):
+    def wilcoxon_signedrank(self, x, y = None, zero_method = 'wilcox', correction = False, alternative = 'two-sided'):
 
-        results = scipy.stats.wilcoxon(x, y = y, method = method, correction = correction, alternative = alternative)
+        results = scipy.stats.wilcoxon(x, y = y, zero_method = zero_method, correction = correction, alternative = alternative)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def kw_htest(*args, nan_policy = 'propagate'):
+    def kw_htest(self, *args, nan_policy = 'propagate'):
 
         results = scipy.stats.kruskal(*args, nan_policy = nan_policy)
         return {"h-value": results[0], "p-value": results[1]}
 
-    def friedman_chisquare(*args):
+    def friedman_chisquare(self, *args):
 
         results = scipy.stats.friedmanchisquare(*args)
         return {"chisquared-value": results[0], "p-value": results[1]}
 
-    def bm_wtest(x, y, alternative = 'two-sided', distribution = 't', nan_policy = 'propagate'):
+    def bm_wtest(self, x, y, alternative = 'two-sided', distribution = 't', nan_policy = 'propagate'):
 
         results = scipy.stats.brunnermunzel(x, y, alternative = alternative, distribution = distribution, nan_policy = nan_policy)
         return {"w-value": results[0], "p-value": results[1]}
 
-    def combine_pvalues(pvalues, method = 'fisher', weights = None):
+    def combine_pvalues(self, pvalues, method = 'fisher', weights = None):
 
         results = scipy.stats.combine_pvalues(pvalues, method = method, weights = weights)
         return {"combined-statistic": results[0], "p-value": results[1]}
 
-    def jb_fitness(x):
+    def jb_fitness(self, x):
 
         results = scipy.stats.jarque_bera(x)
         return {"jb-value": results[0], "p-value": results[1]}
 
-    def ab_equality(x, y):
+    def ab_equality(self, x, y):
 
         results = scipy.stats.ansari(x, y)
         return {"ab-value": results[0], "p-value": results[1]}
 
-    def bartlett_variance(*args):
+    def bartlett_variance(self, *args):
 
         results = scipy.stats.bartlett(*args)
         return {"t-value": results[0], "p-value": results[1]}
 
-    def levene_variance(*args, center = 'median', proportiontocut = 0.05):
+    def levene_variance(self, *args, center = 'median', proportiontocut = 0.05):
 
         results = scipy.stats.levene(*args, center = center, proportiontocut = proportiontocut)
         return {"w-value": results[0], "p-value": results[1]}
 
-    def sw_normality(x):
+    def sw_normality(self, x):
 
         results = scipy.stats.shapiro(x)
         return {"w-value": results[0], "p-value": results[1]}
 
-    def shapiro(x):
+    def shapiro(self, x):
 
         return "destroyed by facts and logic"
 
-    def ad_onesample(x, dist = 'norm'):
+    def ad_onesample(self, x, dist = 'norm'):
 
         results = scipy.stats.anderson(x, dist = dist)
         return {"d-value": results[0], "critical-values": results[1], "significance-value": results[2]}
     
-    def ad_ksample(samples, midrank = True):
+    def ad_ksample(self, samples, midrank = True):
 
         results = scipy.stats.anderson_ksamp(samples, midrank = midrank)
         return {"d-value": results[0], "critical-values": results[1], "significance-value": results[2]}
 
-    def binomial(x, n = None, p = 0.5, alternative = 'two-sided'):
+    def binomial(self, x, n = None, p = 0.5, alternative = 'two-sided'):
 
         results = scipy.stats.binom_test(x, n = n, p = p, alternative = alternative)
         return {"p-value": results}
 
-    def fk_variance(*args, center = 'median', proportiontocut = 0.05):
+    def fk_variance(self, *args, center = 'median', proportiontocut = 0.05):
 
         results = scipy.stats.fligner(*args, center = center, proportiontocut = proportiontocut)
         return {"h-value": results[0], "p-value": results[1]} # unknown if the statistic is an h value
 
-    def mood_mediantest(*args, ties = 'below', correction = True, lambda_ = 1, nan_policy = 'propagate'):
+    def mood_mediantest(self, *args, ties = 'below', correction = True, lambda_ = 1, nan_policy = 'propagate'):
 
         results = scipy.stats.median_test(*args, ties = ties, correction = correction, lambda_ = lambda_, nan_policy = nan_policy)
         return {"chisquared-value": results[0], "p-value": results[1], "m-value": results[2], "table": results[3]}
 
-    def mood_equalscale(x, y, axis = 0):
+    def mood_equalscale(self, x, y, axis = 0):
 
         results = scipy.stats.mood(x, y, axis = axis)
         return {"z-score": results[0], "p-value": results[1]}
 
-    def skewtest(a, axis = 0, nan_policy = 'propogate'):
+    def skewtest(self, a, axis = 0, nan_policy = 'propogate'):
 
         results = scipy.stats.skewtest(a, axis = axis, nan_policy = nan_policy)
         return {"z-score": results[0], "p-value": results[1]}
 
-    def kurtosistest(a, axis = 0, nan_policy = 'propogate'):
+    def kurtosistest(self, a, axis = 0, nan_policy = 'propogate'):
 
         results = scipy.stats.kurtosistest(a, axis = axis, nan_policy = nan_policy)
         return {"z-score": results[0], "p-value": results[1]}
 
-    def normaltest(a, axis = 0, nan_policy = 'propogate'):
+    def normaltest(self, a, axis = 0, nan_policy = 'propogate'):
 
         results = scipy.stats.normaltest(a, axis = axis, nan_policy = nan_policy)
         return {"z-score": results[0], "p-value": results[1]}
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/build/lib/analysis/analysis.py b/analysis-master/analysis-amd64/build/lib/analysis/analysis.py
index 944dd0c7..c13aef90 100644
--- a/analysis-master/analysis-amd64/build/lib/analysis/analysis.py
+++ b/analysis-master/analysis-amd64/build/lib/analysis/analysis.py
@@ -1,16 +1,37 @@
 # Titan Robotics Team 2022: Data Analysis Module
 # Written by Arthur Lu & Jacob Levine
 # Notes:
-#    this should be imported as a python module using 'import analysis'
+#    this should be imported as a python module using 'from analysis import analysis'
 #    this should be included in the local directory or environment variable
 #    this module has been optimized for multhreaded computing
 #    current benchmark of optimization: 1.33 times faster
 # setup:
 
-__version__ = "1.1.13.009"
+__version__ = "1.2.0.004"
 
 # changelog should be viewed using print(analysis.__changelog__)
 __changelog__ = """changelog:
+    1.2.0.004:
+        - fixed __all__ to reflected the correct functions and classes
+        - fixed CorrelationTests and StatisticalTests class functions to require self invocation
+        - added missing math import
+        - fixed KNN class functions to require self invocation
+        - fixed Metrics class functions to require self invocation
+        - various spelling fixes in CorrelationTests and StatisticalTests
+    1.2.0.003:
+        - bug fixes with CorrelationTests and StatisticalTests
+        - moved glicko2 and trueskill to the metrics subpackage
+        - moved elo to a new metrics subpackage
+    1.2.0.002:
+        - fixed docs
+    1.2.0.001:
+        - fixed docs
+    1.2.0.000:
+        - cleaned up wild card imports with scipy and sklearn
+        - added CorrelationTests class
+        - added StatisticalTests class
+        - added several correlation tests to CorrelationTests
+        - added several statistical tests to StatisticalTests
     1.1.13.009:
         - moved elo, glicko2, trueskill functions under class Metrics
     1.1.13.008:
@@ -261,20 +282,19 @@ __all__ = [
     'z_normalize',
     'histo_analysis',
     'regression',
-    'elo',
-    'glicko2',
-    'trueskill',
+    'Metrics',
     'RegressionMetrics',
     'ClassificationMetrics',
     'kmeans',
     'pca',
     'decisiontree',
-    'knn_classifier',
-    'knn_regressor',
+    'KNN',
     'NaiveBayes',
     'SVM',
     'random_forest_classifier',
     'random_forest_regressor',
+    'CorrelationTests',
+    'StatisticalTests',
     # all statistics functions left out due to integration in other functions
 ]
 
@@ -283,15 +303,17 @@ __all__ = [
 # imports (now in alphabetical order! v 1.0.3.006):
 
 import csv
-from analysis import glicko2 as Glicko2
+from analysis.metrics import elo as Elo
+from analysis.metrics import glicko2 as Glicko2
+import math
 import numba
 from numba import jit
 import numpy as np
 import scipy
-from scipy import *
+from scipy import optimize, stats
 import sklearn
-from sklearn import *
-from analysis import trueskill as Trueskill
+from sklearn import preprocessing, pipeline, linear_model, metrics, cluster, decomposition, tree, neighbors, naive_bayes, svm, model_selection, ensemble
+from analysis.metrics import trueskill as Trueskill
 
 class error(ValueError):
     pass
@@ -450,13 +472,11 @@ def regression(inputs, outputs, args): # inputs, outputs expects N-D array
 
 class Metrics:
 
-    def elo(starting_score, opposing_score, observed, N, K):
+    def elo(self, starting_score, opposing_score, observed, N, K):
 
-        expected = 1/(1+10**((np.array(opposing_score) - starting_score)/N))
+        return Elo.calculate(starting_score, opposing_score, observed, N, K)
 
-        return starting_score + K*(np.sum(observed) - np.sum(expected))
-
-    def glicko2(starting_score, starting_rd, starting_vol, opposing_score, opposing_rd, observations):
+    def glicko2(self, starting_score, starting_rd, starting_vol, opposing_score, opposing_rd, observations):
 
         player = Glicko2.Glicko2(rating = starting_score, rd = starting_rd, vol = starting_vol)
 
@@ -464,7 +484,7 @@ class Metrics:
 
         return (player.rating, player.rd, player.vol)
 
-    def trueskill(teams_data, observations): # teams_data is array of array of tuples ie. [[(mu, sigma), (mu, sigma), (mu, sigma)], [(mu, sigma), (mu, sigma), (mu, sigma)]]
+    def trueskill(self, teams_data, observations): # teams_data is array of array of tuples ie. [[(mu, sigma), (mu, sigma), (mu, sigma)], [(mu, sigma), (mu, sigma), (mu, sigma)]]
 
         team_ratings = []
 
@@ -569,7 +589,7 @@ def decisiontree(data, labels, test_size = 0.3, criterion = "gini", splitter = "
 
 class KNN:
 
-    def knn_classifier(data, labels, test_size = 0.3, algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform'): #expects *2d data and 1d labels post-scaling
+    def knn_classifier(self, data, labels, test_size = 0.3, algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform'): #expects *2d data and 1d labels post-scaling
 
         data_train, data_test, labels_train, labels_test = sklearn.model_selection.train_test_split(data, labels, test_size=test_size, random_state=1)
         model = sklearn.neighbors.KNeighborsClassifier()
@@ -578,7 +598,7 @@ class KNN:
 
         return model, ClassificationMetrics(predictions, labels_test)
 
-    def knn_regressor(data, outputs, test_size, n_neighbors = 5, weights = "uniform", algorithm = "auto", leaf_size = 30, p = 2, metric = "minkowski", metric_params = None, n_jobs = None):
+    def knn_regressor(self, data, outputs, test_size, n_neighbors = 5, weights = "uniform", algorithm = "auto", leaf_size = 30, p = 2, metric = "minkowski", metric_params = None, n_jobs = None):
 
         data_train, data_test, outputs_train, outputs_test = sklearn.model_selection.train_test_split(data, outputs, test_size=test_size, random_state=1)
         model = sklearn.neighbors.KNeighborsRegressor(n_neighbors = n_neighbors, weights = weights, algorithm = algorithm, leaf_size = leaf_size, p = p, metric = metric, metric_params = metric_params, n_jobs = n_jobs)
@@ -697,4 +717,207 @@ def random_forest_regressor(data, outputs, test_size, n_estimators="warn", crite
     kernel.fit(data_train, outputs_train)
     predictions = kernel.predict(data_test)
 
-    return kernel, RegressionMetrics(predictions, outputs_test)
\ No newline at end of file
+    return kernel, RegressionMetrics(predictions, outputs_test)
+
+class CorrelationTests:
+
+    def anova_oneway(self, *args): #expects arrays of samples
+
+        results = scipy.stats.f_oneway(*args)
+        return {"F-value": results[0], "p-value": results[1]}
+
+    def pearson(self, x, y):
+
+        results = scipy.stats.pearsonr(x, y)
+        return {"r-value": results[0], "p-value": results[1]}
+
+    def spearman(self, a, b = None, axis = 0, nan_policy = 'propagate'):
+
+        results = scipy.stats.spearmanr(a, b = b, axis = axis, nan_policy = nan_policy)
+        return {"r-value": results[0], "p-value": results[1]}
+
+    def point_biserial(self, x,y):
+
+        results = scipy.stats.pointbiserialr(x, y)
+        return {"r-value": results[0], "p-value": results[1]}
+
+    def kendall(self, x, y, initial_lexsort = None, nan_policy = 'propagate', method = 'auto'):
+
+        results = scipy.stats.kendalltau(x, y, initial_lexsort = initial_lexsort, nan_policy = nan_policy, method = method)
+        return {"tau": results[0], "p-value": results[1]}
+
+    def kendall_weighted(self, x, y, rank = True, weigher = None, additive = True):
+
+        results = scipy.stats.weightedtau(x, y, rank = rank, weigher = weigher, additive = additive)
+        return {"tau": results[0], "p-value": results[1]}
+
+    def mgc(self, x, y, compute_distance = None, reps = 1000, workers = 1, is_twosamp = False, random_state = None):
+
+        results = scipy.stats.multiscale_graphcorr(x, y, compute_distance = compute_distance, reps = reps, workers = workers, is_twosamp = is_twosamp, random_state = random_state)
+        return {"k-value": results[0], "p-value": results[1], "data": results[2]} # unsure if MGC test returns a k value
+
+class StatisticalTests:
+
+    def ttest_onesample(self, a, popmean, axis = 0, nan_policy = 'propagate'):
+
+        results = scipy.stats.ttest_1samp(a, popmean, axis = axis, nan_policy = nan_policy)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def ttest_independent(self, a, b, equal = True, nan_policy = 'propagate'):
+
+        results = scipy.stats.ttest_ind(a, b, equal_var = equal, nan_policy = nan_policy)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def ttest_statistic(self, o1, o2, equal = True):
+
+        results = scipy.stats.ttest_ind_from_stats(o1["mean"], o1["std"], o1["nobs"], o2["mean"], o2["std"], o2["nobs"], equal_var = equal)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def ttest_related(self, a, b, axis = 0, nan_policy='propagate'):
+
+        results = scipy.stats.ttest_rel(a, b, axis = axis, nan_policy = nan_policy)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def ks_fitness(self, rvs, cdf, args = (), N = 20, alternative = 'two-sided', mode = 'approx'):
+
+        results = scipy.stats.kstest(rvs, cdf, args = args, N = N, alternative = alternative, mode = mode)
+        return {"ks-value": results[0], "p-value": results[1]}
+
+    def chisquare(self, f_obs, f_exp = None, ddof = None, axis = 0):
+
+        results = scipy.stats.chisquare(f_obs, f_exp = f_exp, ddof = ddof, axis = axis)
+        return {"chisquared-value": results[0], "p-value": results[1]}
+
+    def powerdivergence(self, f_obs, f_exp = None, ddof = None, axis = 0, lambda_ = None):
+
+        results = scipy.stats.power_divergence(f_obs, f_exp = f_exp, ddof = ddof, axis = axis, lambda_ = lambda_)
+        return {"powerdivergence-value": results[0], "p-value": results[1]}
+
+    def ks_twosample(self, x, y, alternative = 'two_sided', mode = 'auto'):
+        
+        results = scipy.stats.ks_2samp(x, y, alternative = alternative, mode = mode)
+        return {"ks-value": results[0], "p-value": results[1]}
+
+    def es_twosample(self, x, y, t = (0.4, 0.8)):
+
+        results = scipy.stats.epps_singleton_2samp(x, y, t = t)
+        return {"es-value": results[0], "p-value": results[1]}
+
+    def mw_rank(self, x, y, use_continuity = True, alternative = None):
+
+        results = scipy.stats.mannwhitneyu(x, y, use_continuity = use_continuity, alternative = alternative)
+        return {"u-value": results[0], "p-value": results[1]}
+
+    def mw_tiecorrection(self, rank_values):
+
+        results = scipy.stats.tiecorrect(rank_values)
+        return {"correction-factor": results}
+
+    def rankdata(self, a, method = 'average'):
+
+        results = scipy.stats.rankdata(a, method = method)
+        return results
+
+    def wilcoxon_ranksum(self, a, b): # this seems to be superceded by Mann Whitney Wilcoxon U Test
+
+        results = scipy.stats.ranksums(a, b)
+        return {"u-value": results[0], "p-value": results[1]}
+
+    def wilcoxon_signedrank(self, x, y = None, zero_method = 'wilcox', correction = False, alternative = 'two-sided'):
+
+        results = scipy.stats.wilcoxon(x, y = y, zero_method = zero_method, correction = correction, alternative = alternative)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def kw_htest(self, *args, nan_policy = 'propagate'):
+
+        results = scipy.stats.kruskal(*args, nan_policy = nan_policy)
+        return {"h-value": results[0], "p-value": results[1]}
+
+    def friedman_chisquare(self, *args):
+
+        results = scipy.stats.friedmanchisquare(*args)
+        return {"chisquared-value": results[0], "p-value": results[1]}
+
+    def bm_wtest(self, x, y, alternative = 'two-sided', distribution = 't', nan_policy = 'propagate'):
+
+        results = scipy.stats.brunnermunzel(x, y, alternative = alternative, distribution = distribution, nan_policy = nan_policy)
+        return {"w-value": results[0], "p-value": results[1]}
+
+    def combine_pvalues(self, pvalues, method = 'fisher', weights = None):
+
+        results = scipy.stats.combine_pvalues(pvalues, method = method, weights = weights)
+        return {"combined-statistic": results[0], "p-value": results[1]}
+
+    def jb_fitness(self, x):
+
+        results = scipy.stats.jarque_bera(x)
+        return {"jb-value": results[0], "p-value": results[1]}
+
+    def ab_equality(self, x, y):
+
+        results = scipy.stats.ansari(x, y)
+        return {"ab-value": results[0], "p-value": results[1]}
+
+    def bartlett_variance(self, *args):
+
+        results = scipy.stats.bartlett(*args)
+        return {"t-value": results[0], "p-value": results[1]}
+
+    def levene_variance(self, *args, center = 'median', proportiontocut = 0.05):
+
+        results = scipy.stats.levene(*args, center = center, proportiontocut = proportiontocut)
+        return {"w-value": results[0], "p-value": results[1]}
+
+    def sw_normality(self, x):
+
+        results = scipy.stats.shapiro(x)
+        return {"w-value": results[0], "p-value": results[1]}
+
+    def shapiro(self, x):
+
+        return "destroyed by facts and logic"
+
+    def ad_onesample(self, x, dist = 'norm'):
+
+        results = scipy.stats.anderson(x, dist = dist)
+        return {"d-value": results[0], "critical-values": results[1], "significance-value": results[2]}
+    
+    def ad_ksample(self, samples, midrank = True):
+
+        results = scipy.stats.anderson_ksamp(samples, midrank = midrank)
+        return {"d-value": results[0], "critical-values": results[1], "significance-value": results[2]}
+
+    def binomial(self, x, n = None, p = 0.5, alternative = 'two-sided'):
+
+        results = scipy.stats.binom_test(x, n = n, p = p, alternative = alternative)
+        return {"p-value": results}
+
+    def fk_variance(self, *args, center = 'median', proportiontocut = 0.05):
+
+        results = scipy.stats.fligner(*args, center = center, proportiontocut = proportiontocut)
+        return {"h-value": results[0], "p-value": results[1]} # unknown if the statistic is an h value
+
+    def mood_mediantest(self, *args, ties = 'below', correction = True, lambda_ = 1, nan_policy = 'propagate'):
+
+        results = scipy.stats.median_test(*args, ties = ties, correction = correction, lambda_ = lambda_, nan_policy = nan_policy)
+        return {"chisquared-value": results[0], "p-value": results[1], "m-value": results[2], "table": results[3]}
+
+    def mood_equalscale(self, x, y, axis = 0):
+
+        results = scipy.stats.mood(x, y, axis = axis)
+        return {"z-score": results[0], "p-value": results[1]}
+
+    def skewtest(self, a, axis = 0, nan_policy = 'propogate'):
+
+        results = scipy.stats.skewtest(a, axis = axis, nan_policy = nan_policy)
+        return {"z-score": results[0], "p-value": results[1]}
+
+    def kurtosistest(self, a, axis = 0, nan_policy = 'propogate'):
+
+        results = scipy.stats.kurtosistest(a, axis = axis, nan_policy = nan_policy)
+        return {"z-score": results[0], "p-value": results[1]}
+
+    def normaltest(self, a, axis = 0, nan_policy = 'propogate'):
+
+        results = scipy.stats.normaltest(a, axis = axis, nan_policy = nan_policy)
+        return {"z-score": results[0], "p-value": results[1]}
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/build/lib/analysis/metrics/__init__.py b/analysis-master/analysis-amd64/build/lib/analysis/metrics/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/analysis-master/analysis-amd64/build/lib/analysis/metrics/elo.py b/analysis-master/analysis-amd64/build/lib/analysis/metrics/elo.py
new file mode 100644
index 00000000..3c8ef2e0
--- /dev/null
+++ b/analysis-master/analysis-amd64/build/lib/analysis/metrics/elo.py
@@ -0,0 +1,7 @@
+import numpy as np
+
+def calculate(starting_score, opposing_score, observed, N, K):
+
+        expected = 1/(1+10**((np.array(opposing_score) - starting_score)/N))
+
+        return starting_score + K*(np.sum(observed) - np.sum(expected))
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/build/lib/analysis/metrics/glicko2.py b/analysis-master/analysis-amd64/build/lib/analysis/metrics/glicko2.py
new file mode 100644
index 00000000..66c0df94
--- /dev/null
+++ b/analysis-master/analysis-amd64/build/lib/analysis/metrics/glicko2.py
@@ -0,0 +1,99 @@
+import math
+
+class Glicko2:
+    _tau = 0.5
+
+    def getRating(self):
+        return (self.__rating * 173.7178) + 1500 
+
+    def setRating(self, rating):
+        self.__rating = (rating - 1500) / 173.7178
+
+    rating = property(getRating, setRating)
+
+    def getRd(self):
+        return self.__rd * 173.7178
+
+    def setRd(self, rd):
+        self.__rd = rd / 173.7178
+
+    rd = property(getRd, setRd)
+        
+    def __init__(self, rating = 1500, rd = 350, vol = 0.06):
+
+        self.setRating(rating)
+        self.setRd(rd)
+        self.vol = vol
+            
+    def _preRatingRD(self):
+
+        self.__rd = math.sqrt(math.pow(self.__rd, 2) + math.pow(self.vol, 2))
+        
+    def update_player(self, rating_list, RD_list, outcome_list):
+
+        rating_list = [(x - 1500) / 173.7178 for x in rating_list]
+        RD_list = [x / 173.7178 for x in RD_list]
+
+        v = self._v(rating_list, RD_list)
+        self.vol = self._newVol(rating_list, RD_list, outcome_list, v)
+        self._preRatingRD()
+        
+        self.__rd = 1 / math.sqrt((1 / math.pow(self.__rd, 2)) + (1 / v))
+        
+        tempSum = 0
+        for i in range(len(rating_list)):
+            tempSum += self._g(RD_list[i]) * \
+                        (outcome_list[i] - self._E(rating_list[i], RD_list[i]))
+        self.__rating += math.pow(self.__rd, 2) * tempSum
+        
+        
+    def _newVol(self, rating_list, RD_list, outcome_list, v):
+
+        i = 0
+        delta = self._delta(rating_list, RD_list, outcome_list, v)
+        a = math.log(math.pow(self.vol, 2))
+        tau = self._tau
+        x0 = a
+        x1 = 0
+        
+        while x0 != x1:
+            # New iteration, so x(i) becomes x(i-1)
+            x0 = x1
+            d = math.pow(self.__rating, 2) + v + math.exp(x0)
+            h1 = -(x0 - a) / math.pow(tau, 2) - 0.5 * math.exp(x0) \
+            / d + 0.5 * math.exp(x0) * math.pow(delta / d, 2)
+            h2 = -1 / math.pow(tau, 2) - 0.5 * math.exp(x0) * \
+            (math.pow(self.__rating, 2) + v) \
+            / math.pow(d, 2) + 0.5 * math.pow(delta, 2) * math.exp(x0) \
+            * (math.pow(self.__rating, 2) + v - math.exp(x0)) / math.pow(d, 3)
+            x1 = x0 - (h1 / h2)
+
+        return math.exp(x1 / 2)
+        
+    def _delta(self, rating_list, RD_list, outcome_list, v):
+
+        tempSum = 0
+        for i in range(len(rating_list)):
+            tempSum += self._g(RD_list[i]) * (outcome_list[i] - self._E(rating_list[i], RD_list[i]))
+        return v * tempSum
+        
+    def _v(self, rating_list, RD_list):
+
+        tempSum = 0
+        for i in range(len(rating_list)):
+            tempE = self._E(rating_list[i], RD_list[i])
+            tempSum += math.pow(self._g(RD_list[i]), 2) * tempE * (1 - tempE)
+        return 1 / tempSum
+        
+    def _E(self, p2rating, p2RD):
+
+        return 1 / (1 + math.exp(-1 * self._g(p2RD) * \
+                                    (self.__rating - p2rating)))
+        
+    def _g(self, RD):
+
+        return 1 / math.sqrt(1 + 3 * math.pow(RD, 2) / math.pow(math.pi, 2))
+        
+    def did_not_compete(self):
+
+        self._preRatingRD()
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/build/lib/analysis/metrics/trueskill.py b/analysis-master/analysis-amd64/build/lib/analysis/metrics/trueskill.py
new file mode 100644
index 00000000..116357df
--- /dev/null
+++ b/analysis-master/analysis-amd64/build/lib/analysis/metrics/trueskill.py
@@ -0,0 +1,907 @@
+from __future__ import absolute_import
+
+from itertools import chain
+import math
+
+from six import iteritems
+from six.moves import map, range, zip
+from six import iterkeys
+
+import copy
+try:
+    from numbers import Number
+except ImportError:
+    Number = (int, long, float, complex)
+
+inf = float('inf')
+
+class Gaussian(object):
+    #: Precision, the inverse of the variance.
+    pi = 0
+    #: Precision adjusted mean, the precision multiplied by the mean.
+    tau = 0
+
+    def __init__(self, mu=None, sigma=None, pi=0, tau=0):
+        if mu is not None:
+            if sigma is None:
+                raise TypeError('sigma argument is needed')
+            elif sigma == 0:
+                raise ValueError('sigma**2 should be greater than 0')
+            pi = sigma ** -2
+            tau = pi * mu
+        self.pi = pi
+        self.tau = tau
+
+    @property
+    def mu(self):
+        return self.pi and self.tau / self.pi
+
+    @property
+    def sigma(self):
+        return math.sqrt(1 / self.pi) if self.pi else inf
+
+    def __mul__(self, other):
+        pi, tau = self.pi + other.pi, self.tau + other.tau
+        return Gaussian(pi=pi, tau=tau)
+
+    def __truediv__(self, other):
+        pi, tau = self.pi - other.pi, self.tau - other.tau
+        return Gaussian(pi=pi, tau=tau)
+
+    __div__ = __truediv__  # for Python 2
+
+    def __eq__(self, other):
+        return self.pi == other.pi and self.tau == other.tau
+
+    def __lt__(self, other):
+        return self.mu < other.mu
+
+    def __le__(self, other):
+        return self.mu <= other.mu
+
+    def __gt__(self, other):
+        return self.mu > other.mu
+
+    def __ge__(self, other):
+        return self.mu >= other.mu
+
+    def __repr__(self):
+        return 'N(mu={:.3f}, sigma={:.3f})'.format(self.mu, self.sigma)
+
+    def _repr_latex_(self):
+        latex = r'\mathcal{{ N }}( {:.3f}, {:.3f}^2 )'.format(self.mu, self.sigma)
+        return '$%s$' % latex
+
+class Matrix(list):
+    def __init__(self, src, height=None, width=None):
+        if callable(src):
+            f, src = src, {}
+            size = [height, width]
+            if not height:
+                def set_height(height):
+                    size[0] = height
+                size[0] = set_height
+            if not width:
+                def set_width(width):
+                    size[1] = width
+                size[1] = set_width
+            try:
+                for (r, c), val in f(*size):
+                    src[r, c] = val
+            except TypeError:
+                raise TypeError('A callable src must return an interable '
+                                'which generates a tuple containing '
+                                'coordinate and value')
+            height, width = tuple(size)
+            if height is None or width is None:
+                raise TypeError('A callable src must call set_height and '
+                                'set_width if the size is non-deterministic')
+        if isinstance(src, list):
+            is_number = lambda x: isinstance(x, Number)
+            unique_col_sizes = set(map(len, src))
+            everything_are_number = filter(is_number, sum(src, []))
+            if len(unique_col_sizes) != 1 or not everything_are_number:
+                raise ValueError('src must be a rectangular array of numbers')
+            two_dimensional_array = src
+        elif isinstance(src, dict):
+            if not height or not width:
+                w = h = 0
+                for r, c in iterkeys(src):
+                    if not height:
+                        h = max(h, r + 1)
+                    if not width:
+                        w = max(w, c + 1)
+                if not height:
+                    height = h
+                if not width:
+                    width = w
+            two_dimensional_array = []
+            for r in range(height):
+                row = []
+                two_dimensional_array.append(row)
+                for c in range(width):
+                    row.append(src.get((r, c), 0))
+        else:
+            raise TypeError('src must be a list or dict or callable')
+        super(Matrix, self).__init__(two_dimensional_array)
+
+    @property
+    def height(self):
+        return len(self)
+
+    @property
+    def width(self):
+        return len(self[0])
+
+    def transpose(self):
+        height, width = self.height, self.width
+        src = {}
+        for c in range(width):
+            for r in range(height):
+                src[c, r] = self[r][c]
+        return type(self)(src, height=width, width=height)
+
+    def minor(self, row_n, col_n):
+        height, width = self.height, self.width
+        if not (0 <= row_n < height):
+            raise ValueError('row_n should be between 0 and %d' % height)
+        elif not (0 <= col_n < width):
+            raise ValueError('col_n should be between 0 and %d' % width)
+        two_dimensional_array = []
+        for r in range(height):
+            if r == row_n:
+                continue
+            row = []
+            two_dimensional_array.append(row)
+            for c in range(width):
+                if c == col_n:
+                    continue
+                row.append(self[r][c])
+        return type(self)(two_dimensional_array)
+
+    def determinant(self):
+        height, width = self.height, self.width
+        if height != width:
+            raise ValueError('Only square matrix can calculate a determinant')
+        tmp, rv = copy.deepcopy(self), 1.
+        for c in range(width - 1, 0, -1):
+            pivot, r = max((abs(tmp[r][c]), r) for r in range(c + 1))
+            pivot = tmp[r][c]
+            if not pivot:
+                return 0.
+            tmp[r], tmp[c] = tmp[c], tmp[r]
+            if r != c:
+                rv = -rv
+            rv *= pivot
+            fact = -1. / pivot
+            for r in range(c):
+                f = fact * tmp[r][c]
+                for x in range(c):
+                    tmp[r][x] += f * tmp[c][x]
+        return rv * tmp[0][0]
+
+    def adjugate(self):
+        height, width = self.height, self.width
+        if height != width:
+            raise ValueError('Only square matrix can be adjugated')
+        if height == 2:
+            a, b = self[0][0], self[0][1]
+            c, d = self[1][0], self[1][1]
+            return type(self)([[d, -b], [-c, a]])
+        src = {}
+        for r in range(height):
+            for c in range(width):
+                sign = -1 if (r + c) % 2 else 1
+                src[r, c] = self.minor(r, c).determinant() * sign
+        return type(self)(src, height, width)
+
+    def inverse(self):
+        if self.height == self.width == 1:
+            return type(self)([[1. / self[0][0]]])
+        return (1. / self.determinant()) * self.adjugate()
+
+    def __add__(self, other):
+        height, width = self.height, self.width
+        if (height, width) != (other.height, other.width):
+            raise ValueError('Must be same size')
+        src = {}
+        for r in range(height):
+            for c in range(width):
+                src[r, c] = self[r][c] + other[r][c]
+        return type(self)(src, height, width)
+
+    def __mul__(self, other):
+        if self.width != other.height:
+            raise ValueError('Bad size')
+        height, width = self.height, other.width
+        src = {}
+        for r in range(height):
+            for c in range(width):
+                src[r, c] = sum(self[r][x] * other[x][c]
+                                for x in range(self.width))
+        return type(self)(src, height, width)
+
+    def __rmul__(self, other):
+        if not isinstance(other, Number):
+            raise TypeError('The operand should be a number')
+        height, width = self.height, self.width
+        src = {}
+        for r in range(height):
+            for c in range(width):
+                src[r, c] = other * self[r][c]
+        return type(self)(src, height, width)
+
+    def __repr__(self):
+        return '{}({})'.format(type(self).__name__, super(Matrix, self).__repr__())
+
+    def _repr_latex_(self):
+        rows = [' && '.join(['%.3f' % cell for cell in row]) for row in self]
+        latex = r'\begin{matrix} %s \end{matrix}' % r'\\'.join(rows)
+        return '$%s$' % latex
+
+def _gen_erfcinv(erfc, math=math):
+    def erfcinv(y):
+        """The inverse function of erfc."""
+        if y >= 2:
+            return -100.
+        elif y <= 0:
+            return 100.
+        zero_point = y < 1
+        if not zero_point:
+            y = 2 - y
+        t = math.sqrt(-2 * math.log(y / 2.))
+        x = -0.70711 * \
+            ((2.30753 + t * 0.27061) / (1. + t * (0.99229 + t * 0.04481)) - t)
+        for i in range(2):
+            err = erfc(x) - y
+            x += err / (1.12837916709551257 * math.exp(-(x ** 2)) - x * err)
+        return x if zero_point else -x
+    return erfcinv
+
+def _gen_ppf(erfc, math=math):
+    erfcinv = _gen_erfcinv(erfc, math)
+    def ppf(x, mu=0, sigma=1):
+        return mu - sigma * math.sqrt(2) * erfcinv(2 * x)
+    return ppf
+
+def erfc(x):
+    z = abs(x)
+    t = 1. / (1. + z / 2.)
+    r = t * math.exp(-z * z - 1.26551223 + t * (1.00002368 + t * (
+        0.37409196 + t * (0.09678418 + t * (-0.18628806 + t * (
+            0.27886807 + t * (-1.13520398 + t * (1.48851587 + t * (
+                -0.82215223 + t * 0.17087277
+            )))
+        )))
+    )))
+    return 2. - r if x < 0 else r
+
+def cdf(x, mu=0, sigma=1):
+    return 0.5 * erfc(-(x - mu) / (sigma * math.sqrt(2)))
+
+
+def pdf(x, mu=0, sigma=1):
+    return (1 / math.sqrt(2 * math.pi) * abs(sigma) *
+            math.exp(-(((x - mu) / abs(sigma)) ** 2 / 2)))
+
+ppf = _gen_ppf(erfc)
+
+def choose_backend(backend):
+    if backend is None:  # fallback
+        return cdf, pdf, ppf
+    elif backend == 'mpmath':
+        try:
+            import mpmath
+        except ImportError:
+            raise ImportError('Install "mpmath" to use this backend')
+        return mpmath.ncdf, mpmath.npdf, _gen_ppf(mpmath.erfc, math=mpmath)
+    elif backend == 'scipy':
+        try:
+            from scipy.stats import norm
+        except ImportError:
+            raise ImportError('Install "scipy" to use this backend')
+        return norm.cdf, norm.pdf, norm.ppf
+    raise ValueError('%r backend is not defined' % backend)
+
+def available_backends():
+    backends = [None]
+    for backend in ['mpmath', 'scipy']:
+        try:
+            __import__(backend)
+        except ImportError:
+            continue
+        backends.append(backend)
+    return backends
+
+class Node(object):
+
+    pass
+
+class Variable(Node, Gaussian):
+
+    def __init__(self):
+        self.messages = {}
+        super(Variable, self).__init__()
+
+    def set(self, val):
+        delta = self.delta(val)
+        self.pi, self.tau = val.pi, val.tau
+        return delta
+
+    def delta(self, other):
+        pi_delta = abs(self.pi - other.pi)
+        if pi_delta == inf:
+            return 0.
+        return max(abs(self.tau - other.tau), math.sqrt(pi_delta))
+
+    def update_message(self, factor, pi=0, tau=0, message=None):
+        message = message or Gaussian(pi=pi, tau=tau)
+        old_message, self[factor] = self[factor], message
+        return self.set(self / old_message * message)
+
+    def update_value(self, factor, pi=0, tau=0, value=None):
+        value = value or Gaussian(pi=pi, tau=tau)
+        old_message = self[factor]
+        self[factor] = value * old_message / self
+        return self.set(value)
+
+    def __getitem__(self, factor):
+        return self.messages[factor]
+
+    def __setitem__(self, factor, message):
+        self.messages[factor] = message
+
+    def __repr__(self):
+        args = (type(self).__name__, super(Variable, self).__repr__(),
+                len(self.messages), '' if len(self.messages) == 1 else 's')
+        return '<%s %s with %d connection%s>' % args
+
+
+class Factor(Node):
+
+    def __init__(self, variables):
+        self.vars = variables
+        for var in variables:
+            var[self] = Gaussian()
+
+    def down(self):
+        return 0
+
+    def up(self):
+        return 0
+
+    @property
+    def var(self):
+        assert len(self.vars) == 1
+        return self.vars[0]
+
+    def __repr__(self):
+        args = (type(self).__name__, len(self.vars),
+                '' if len(self.vars) == 1 else 's')
+        return '<%s with %d connection%s>' % args
+
+
+class PriorFactor(Factor):
+
+    def __init__(self, var, val, dynamic=0):
+        super(PriorFactor, self).__init__([var])
+        self.val = val
+        self.dynamic = dynamic
+
+    def down(self):
+        sigma = math.sqrt(self.val.sigma ** 2 + self.dynamic ** 2)
+        value = Gaussian(self.val.mu, sigma)
+        return self.var.update_value(self, value=value)
+
+
+class LikelihoodFactor(Factor):
+
+    def __init__(self, mean_var, value_var, variance):
+        super(LikelihoodFactor, self).__init__([mean_var, value_var])
+        self.mean = mean_var
+        self.value = value_var
+        self.variance = variance
+
+    def calc_a(self, var):
+        return 1. / (1. + self.variance * var.pi)
+
+    def down(self):
+        # update value.
+        msg = self.mean / self.mean[self]
+        a = self.calc_a(msg)
+        return self.value.update_message(self, a * msg.pi, a * msg.tau)
+
+    def up(self):
+        # update mean.
+        msg = self.value / self.value[self]
+        a = self.calc_a(msg)
+        return self.mean.update_message(self, a * msg.pi, a * msg.tau)
+
+
+class SumFactor(Factor):
+
+    def __init__(self, sum_var, term_vars, coeffs):
+        super(SumFactor, self).__init__([sum_var] + term_vars)
+        self.sum = sum_var
+        self.terms = term_vars
+        self.coeffs = coeffs
+
+    def down(self):
+        vals = self.terms
+        msgs = [var[self] for var in vals]
+        return self.update(self.sum, vals, msgs, self.coeffs)
+
+    def up(self, index=0):
+        coeff = self.coeffs[index]
+        coeffs = []
+        for x, c in enumerate(self.coeffs):
+            try:
+                if x == index:
+                    coeffs.append(1. / coeff)
+                else:
+                    coeffs.append(-c / coeff)
+            except ZeroDivisionError:
+                coeffs.append(0.)
+        vals = self.terms[:]
+        vals[index] = self.sum
+        msgs = [var[self] for var in vals]
+        return self.update(self.terms[index], vals, msgs, coeffs)
+
+    def update(self, var, vals, msgs, coeffs):
+        pi_inv = 0
+        mu = 0
+        for val, msg, coeff in zip(vals, msgs, coeffs):
+            div = val / msg
+            mu += coeff * div.mu
+            if pi_inv == inf:
+                continue
+            try:
+                # numpy.float64 handles floating-point error by different way.
+                # For example, it can just warn RuntimeWarning on n/0 problem
+                # instead of throwing ZeroDivisionError.  So div.pi, the
+                # denominator has to be a built-in float.
+                pi_inv += coeff ** 2 / float(div.pi)
+            except ZeroDivisionError:
+                pi_inv = inf
+        pi = 1. / pi_inv
+        tau = pi * mu
+        return var.update_message(self, pi, tau)
+
+
+class TruncateFactor(Factor):
+
+    def __init__(self, var, v_func, w_func, draw_margin):
+        super(TruncateFactor, self).__init__([var])
+        self.v_func = v_func
+        self.w_func = w_func
+        self.draw_margin = draw_margin
+
+    def up(self):
+        val = self.var
+        msg = self.var[self]
+        div = val / msg
+        sqrt_pi = math.sqrt(div.pi)
+        args = (div.tau / sqrt_pi, self.draw_margin * sqrt_pi)
+        v = self.v_func(*args)
+        w = self.w_func(*args)
+        denom = (1. - w)
+        pi, tau = div.pi / denom, (div.tau + sqrt_pi * v) / denom
+        return val.update_value(self, pi, tau)
+
+#: Default initial mean of ratings.
+MU = 25.
+#: Default initial standard deviation of ratings.
+SIGMA = MU / 3
+#: Default distance that guarantees about 76% chance of winning.
+BETA = SIGMA / 2
+#: Default dynamic factor.
+TAU = SIGMA / 100
+#: Default draw probability of the game.
+DRAW_PROBABILITY = .10
+#: A basis to check reliability of the result.
+DELTA = 0.0001
+
+
+def calc_draw_probability(draw_margin, size, env=None):
+    if env is None:
+        env = global_env()
+    return 2 * env.cdf(draw_margin / (math.sqrt(size) * env.beta)) - 1
+
+
+def calc_draw_margin(draw_probability, size, env=None):
+    if env is None:
+        env = global_env()
+    return env.ppf((draw_probability + 1) / 2.) * math.sqrt(size) * env.beta
+
+
+def _team_sizes(rating_groups):
+    team_sizes = [0]
+    for group in rating_groups:
+        team_sizes.append(len(group) + team_sizes[-1])
+    del team_sizes[0]
+    return team_sizes
+
+
+def _floating_point_error(env):
+    if env.backend == 'mpmath':
+        msg = 'Set "mpmath.mp.dps" to higher'
+    else:
+        msg = 'Cannot calculate correctly, set backend to "mpmath"'
+    return FloatingPointError(msg)
+
+
+class Rating(Gaussian):
+    def __init__(self, mu=None, sigma=None):
+        if isinstance(mu, tuple):
+            mu, sigma = mu
+        elif isinstance(mu, Gaussian):
+            mu, sigma = mu.mu, mu.sigma
+        if mu is None:
+            mu = global_env().mu
+        if sigma is None:
+            sigma = global_env().sigma
+        super(Rating, self).__init__(mu, sigma)
+
+    def __int__(self):
+        return int(self.mu)
+
+    def __long__(self):
+        return long(self.mu)
+
+    def __float__(self):
+        return float(self.mu)
+
+    def __iter__(self):
+        return iter((self.mu, self.sigma))
+
+    def __repr__(self):
+        c = type(self)
+        args = ('.'.join([c.__module__, c.__name__]), self.mu, self.sigma)
+        return '%s(mu=%.3f, sigma=%.3f)' % args
+
+
+class TrueSkill(object):
+    def __init__(self, mu=MU, sigma=SIGMA, beta=BETA, tau=TAU,
+                 draw_probability=DRAW_PROBABILITY, backend=None):
+        self.mu = mu
+        self.sigma = sigma
+        self.beta = beta
+        self.tau = tau
+        self.draw_probability = draw_probability
+        self.backend = backend
+        if isinstance(backend, tuple):
+            self.cdf, self.pdf, self.ppf = backend
+        else:
+            self.cdf, self.pdf, self.ppf = choose_backend(backend)
+
+    def create_rating(self, mu=None, sigma=None):
+        if mu is None:
+            mu = self.mu
+        if sigma is None:
+            sigma = self.sigma
+        return Rating(mu, sigma)
+
+    def v_win(self, diff, draw_margin):
+        x = diff - draw_margin
+        denom = self.cdf(x)
+        return (self.pdf(x) / denom) if denom else -x
+
+    def v_draw(self, diff, draw_margin):
+        abs_diff = abs(diff)
+        a, b = draw_margin - abs_diff, -draw_margin - abs_diff
+        denom = self.cdf(a) - self.cdf(b)
+        numer = self.pdf(b) - self.pdf(a)
+        return ((numer / denom) if denom else a) * (-1 if diff < 0 else +1)
+
+    def w_win(self, diff, draw_margin):
+        x = diff - draw_margin
+        v = self.v_win(diff, draw_margin)
+        w = v * (v + x)
+        if 0 < w < 1:
+            return w
+        raise _floating_point_error(self)
+
+    def w_draw(self, diff, draw_margin):
+        abs_diff = abs(diff)
+        a, b = draw_margin - abs_diff, -draw_margin - abs_diff
+        denom = self.cdf(a) - self.cdf(b)
+        if not denom:
+            raise _floating_point_error(self)
+        v = self.v_draw(abs_diff, draw_margin)
+        return (v ** 2) + (a * self.pdf(a) - b * self.pdf(b)) / denom
+
+    def validate_rating_groups(self, rating_groups):
+        # check group sizes
+        if len(rating_groups) < 2:
+            raise ValueError('Need multiple rating groups')
+        elif not all(rating_groups):
+            raise ValueError('Each group must contain multiple ratings')
+        # check group types
+        group_types = set(map(type, rating_groups))
+        if len(group_types) != 1:
+            raise TypeError('All groups should be same type')
+        elif group_types.pop() is Rating:
+            raise TypeError('Rating cannot be a rating group')
+        # normalize rating_groups
+        if isinstance(rating_groups[0], dict):
+            dict_rating_groups = rating_groups
+            rating_groups = []
+            keys = []
+            for dict_rating_group in dict_rating_groups:
+                rating_group, key_group = [], []
+                for key, rating in iteritems(dict_rating_group):
+                    rating_group.append(rating)
+                    key_group.append(key)
+                rating_groups.append(tuple(rating_group))
+                keys.append(tuple(key_group))
+        else:
+            rating_groups = list(rating_groups)
+            keys = None
+        return rating_groups, keys
+
+    def validate_weights(self, weights, rating_groups, keys=None):
+        if weights is None:
+            weights = [(1,) * len(g) for g in rating_groups]
+        elif isinstance(weights, dict):
+            weights_dict, weights = weights, []
+            for x, group in enumerate(rating_groups):
+                w = []
+                weights.append(w)
+                for y, rating in enumerate(group):
+                    if keys is not None:
+                        y = keys[x][y]
+                    w.append(weights_dict.get((x, y), 1))
+        return weights
+
+    def factor_graph_builders(self, rating_groups, ranks, weights):
+        flatten_ratings = sum(map(tuple, rating_groups), ())
+        flatten_weights = sum(map(tuple, weights), ())
+        size = len(flatten_ratings)
+        group_size = len(rating_groups)
+        # create variables
+        rating_vars = [Variable() for x in range(size)]
+        perf_vars = [Variable() for x in range(size)]
+        team_perf_vars = [Variable() for x in range(group_size)]
+        team_diff_vars = [Variable() for x in range(group_size - 1)]
+        team_sizes = _team_sizes(rating_groups)
+        # layer builders
+        def build_rating_layer():
+            for rating_var, rating in zip(rating_vars, flatten_ratings):
+                yield PriorFactor(rating_var, rating, self.tau)
+        def build_perf_layer():
+            for rating_var, perf_var in zip(rating_vars, perf_vars):
+                yield LikelihoodFactor(rating_var, perf_var, self.beta ** 2)
+        def build_team_perf_layer():
+            for team, team_perf_var in enumerate(team_perf_vars):
+                if team > 0:
+                    start = team_sizes[team - 1]
+                else:
+                    start = 0
+                end = team_sizes[team]
+                child_perf_vars = perf_vars[start:end]
+                coeffs = flatten_weights[start:end]
+                yield SumFactor(team_perf_var, child_perf_vars, coeffs)
+        def build_team_diff_layer():
+            for team, team_diff_var in enumerate(team_diff_vars):
+                yield SumFactor(team_diff_var,
+                                team_perf_vars[team:team + 2], [+1, -1])
+        def build_trunc_layer():
+            for x, team_diff_var in enumerate(team_diff_vars):
+                if callable(self.draw_probability):
+                    # dynamic draw probability
+                    team_perf1, team_perf2 = team_perf_vars[x:x + 2]
+                    args = (Rating(team_perf1), Rating(team_perf2), self)
+                    draw_probability = self.draw_probability(*args)
+                else:
+                    # static draw probability
+                    draw_probability = self.draw_probability
+                size = sum(map(len, rating_groups[x:x + 2]))
+                draw_margin = calc_draw_margin(draw_probability, size, self)
+                if ranks[x] == ranks[x + 1]:  # is a tie?
+                    v_func, w_func = self.v_draw, self.w_draw
+                else:
+                    v_func, w_func = self.v_win, self.w_win
+                yield TruncateFactor(team_diff_var,
+                                     v_func, w_func, draw_margin)
+        # build layers
+        return (build_rating_layer, build_perf_layer, build_team_perf_layer,
+                build_team_diff_layer, build_trunc_layer)
+
+    def run_schedule(self, build_rating_layer, build_perf_layer,
+                     build_team_perf_layer, build_team_diff_layer,
+                     build_trunc_layer, min_delta=DELTA):
+        if min_delta <= 0:
+            raise ValueError('min_delta must be greater than 0')
+        layers = []
+        def build(builders):
+            layers_built = [list(build()) for build in builders]
+            layers.extend(layers_built)
+            return layers_built
+        # gray arrows
+        layers_built = build([build_rating_layer,
+                              build_perf_layer,
+                              build_team_perf_layer])
+        rating_layer, perf_layer, team_perf_layer = layers_built
+        for f in chain(*layers_built):
+            f.down()
+        # arrow #1, #2, #3
+        team_diff_layer, trunc_layer = build([build_team_diff_layer,
+                                              build_trunc_layer])
+        team_diff_len = len(team_diff_layer)
+        for x in range(10):
+            if team_diff_len == 1:
+                # only two teams
+                team_diff_layer[0].down()
+                delta = trunc_layer[0].up()
+            else:
+                # multiple teams
+                delta = 0
+                for x in range(team_diff_len - 1):
+                    team_diff_layer[x].down()
+                    delta = max(delta, trunc_layer[x].up())
+                    team_diff_layer[x].up(1)  # up to right variable
+                for x in range(team_diff_len - 1, 0, -1):
+                    team_diff_layer[x].down()
+                    delta = max(delta, trunc_layer[x].up())
+                    team_diff_layer[x].up(0)  # up to left variable
+            # repeat until to small update
+            if delta <= min_delta:
+                break
+        # up both ends
+        team_diff_layer[0].up(0)
+        team_diff_layer[team_diff_len - 1].up(1)
+        # up the remainder of the black arrows
+        for f in team_perf_layer:
+            for x in range(len(f.vars) - 1):
+                f.up(x)
+        for f in perf_layer:
+            f.up()
+        return layers
+
+    def rate(self, rating_groups, ranks=None, weights=None, min_delta=DELTA):
+        rating_groups, keys = self.validate_rating_groups(rating_groups)
+        weights = self.validate_weights(weights, rating_groups, keys)
+        group_size = len(rating_groups)
+        if ranks is None:
+            ranks = range(group_size)
+        elif len(ranks) != group_size:
+            raise ValueError('Wrong ranks')
+        # sort rating groups by rank
+        by_rank = lambda x: x[1][1]
+        sorting = sorted(enumerate(zip(rating_groups, ranks, weights)),
+                         key=by_rank)
+        sorted_rating_groups, sorted_ranks, sorted_weights = [], [], []
+        for x, (g, r, w) in sorting:
+            sorted_rating_groups.append(g)
+            sorted_ranks.append(r)
+            # make weights to be greater than 0
+            sorted_weights.append(max(min_delta, w_) for w_ in w)
+        # build factor graph
+        args = (sorted_rating_groups, sorted_ranks, sorted_weights)
+        builders = self.factor_graph_builders(*args)
+        args = builders + (min_delta,)
+        layers = self.run_schedule(*args)
+        # make result
+        rating_layer, team_sizes = layers[0], _team_sizes(sorted_rating_groups)
+        transformed_groups = []
+        for start, end in zip([0] + team_sizes[:-1], team_sizes):
+            group = []
+            for f in rating_layer[start:end]:
+                group.append(Rating(float(f.var.mu), float(f.var.sigma)))
+            transformed_groups.append(tuple(group))
+        by_hint = lambda x: x[0]
+        unsorting = sorted(zip((x for x, __ in sorting), transformed_groups),
+                           key=by_hint)
+        if keys is None:
+            return [g for x, g in unsorting]
+        # restore the structure with input dictionary keys
+        return [dict(zip(keys[x], g)) for x, g in unsorting]
+
+    def quality(self, rating_groups, weights=None):
+        rating_groups, keys = self.validate_rating_groups(rating_groups)
+        weights = self.validate_weights(weights, rating_groups, keys)
+        flatten_ratings = sum(map(tuple, rating_groups), ())
+        flatten_weights = sum(map(tuple, weights), ())
+        length = len(flatten_ratings)
+        # a vector of all of the skill means
+        mean_matrix = Matrix([[r.mu] for r in flatten_ratings])
+        # a matrix whose diagonal values are the variances (sigma ** 2) of each
+        # of the players.
+        def variance_matrix(height, width):
+            variances = (r.sigma ** 2 for r in flatten_ratings)
+            for x, variance in enumerate(variances):
+                yield (x, x), variance
+        variance_matrix = Matrix(variance_matrix, length, length)
+        # the player-team assignment and comparison matrix
+        def rotated_a_matrix(set_height, set_width):
+            t = 0
+            for r, (cur, _next) in enumerate(zip(rating_groups[:-1],
+                                                rating_groups[1:])):
+                for x in range(t, t + len(cur)):
+                    yield (r, x), flatten_weights[x]
+                    t += 1
+                x += 1
+                for x in range(x, x + len(_next)):
+                    yield (r, x), -flatten_weights[x]
+            set_height(r + 1)
+            set_width(x + 1)
+        rotated_a_matrix = Matrix(rotated_a_matrix)
+        a_matrix = rotated_a_matrix.transpose()
+        # match quality further derivation
+        _ata = (self.beta ** 2) * rotated_a_matrix * a_matrix
+        _atsa = rotated_a_matrix * variance_matrix * a_matrix
+        start = mean_matrix.transpose() * a_matrix
+        middle = _ata + _atsa
+        end = rotated_a_matrix * mean_matrix
+        # make result
+        e_arg = (-0.5 * start * middle.inverse() * end).determinant()
+        s_arg = _ata.determinant() / middle.determinant()
+        return math.exp(e_arg) * math.sqrt(s_arg)
+
+    def expose(self, rating):
+        k = self.mu / self.sigma
+        return rating.mu - k * rating.sigma
+
+    def make_as_global(self):
+        return setup(env=self)
+
+    def __repr__(self):
+        c = type(self)
+        if callable(self.draw_probability):
+            f = self.draw_probability
+            draw_probability = '.'.join([f.__module__, f.__name__])
+        else:
+            draw_probability = '%.1f%%' % (self.draw_probability * 100)
+        if self.backend is None:
+            backend = ''
+        elif isinstance(self.backend, tuple):
+            backend = ', backend=...'
+        else:
+            backend = ', backend=%r' % self.backend
+        args = ('.'.join([c.__module__, c.__name__]), self.mu, self.sigma,
+                self.beta, self.tau, draw_probability, backend)
+        return ('%s(mu=%.3f, sigma=%.3f, beta=%.3f, tau=%.3f, '
+                'draw_probability=%s%s)' % args)
+
+
+def rate_1vs1(rating1, rating2, drawn=False, min_delta=DELTA, env=None):
+    if env is None:
+        env = global_env()
+    ranks = [0, 0 if drawn else 1]
+    teams = env.rate([(rating1,), (rating2,)], ranks, min_delta=min_delta)
+    return teams[0][0], teams[1][0]
+
+
+def quality_1vs1(rating1, rating2, env=None):
+    if env is None:
+        env = global_env()
+    return env.quality([(rating1,), (rating2,)])
+
+
+def global_env():
+    try:
+        global_env.__trueskill__
+    except AttributeError:
+        # setup the default environment
+        setup()
+    return global_env.__trueskill__
+
+
+def setup(mu=MU, sigma=SIGMA, beta=BETA, tau=TAU,
+          draw_probability=DRAW_PROBABILITY, backend=None, env=None):
+    if env is None:
+        env = TrueSkill(mu, sigma, beta, tau, draw_probability, backend)
+    global_env.__trueskill__ = env
+    return env
+
+
+def rate(rating_groups, ranks=None, weights=None, min_delta=DELTA):
+    return global_env().rate(rating_groups, ranks, weights, min_delta)
+
+
+def quality(rating_groups, weights=None):
+    return global_env().quality(rating_groups, weights)
+
+
+def expose(rating):
+    return global_env().expose(rating)
\ No newline at end of file
diff --git a/analysis-master/analysis-amd64/dist/analysis-1.0.0.12-py3-none-any.whl b/analysis-master/analysis-amd64/dist/analysis-1.0.0.12-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..60e0b51c7e0824323d9fea32c844cadcaeb7528a
GIT binary patch
literal 32026
zcmZ6xQ;;S~w5?mV`Il{W*>-i=wr$(CZQHhO+cvv!)_%D6>^SowBO@c`Tjm@iV|?<`
zpkQb~KtNDHnav^c|80Ok{%85G{^!)d*1+1s$-;?2PtU^E!dXv`-rfTgNdEutkt)xX
z*UAin3nc&o+Kc&rdj7xW|9WnCt>TVG6ZYWW`R_;j;Z3a2C9htL=(&b<`Td<-jn?@n
z`VD28$5V&#B8xYUr_B*R?$lJi$+HqoU7H#btU;ozUDec7)Yh6NJ_tXl>@={x<!h?g
z<V2rQ&HkBl>e1H~)~QbwGDxZ7iqIFDsjQ-ZeZTRA|7;%HOih{lg!h_n>a2<Q-4^~v
z|AdvSaD6iOO-Nt9c3XC|57NA^-2w%#tLP+%TH&Ak>$KF&75ythTZwp6OI^e}gXBWY
z(6(?=TJeg!)HDTr`r`;@oq?ePq5p(}|4?48s4Akdd*57>DXh$j%wYFeO8wStU4*lG
zY)u!j*pG(7EnqzpFkWf<<nx2AZ>#^@OS7pngf*L>`mfUpSdEqECKIBd)+6KgwYnp=
zG6sKkvzxlEaOC>o2nxGBob7LO_dr2ln-09U=Wh>b$3cvLt|UrLVbq8<XV%>5Qyjzn
z0i;5w(Mc-i%4)$o`B|HP)Un3Su?db9{!HR<v_v9wpxdoOU=-{U&=U!~sgz6HFTQBj
z7s9CoiYgjoeNADg9gIE|3vt>~r67cOR_)&eS@lJfbtOikcEF%V<PPlNxSV!#<69gZ
z3sk&->bMy8t$(qG-;F+1fWZia>N^AmW?lz#J)D|p9_-;*ZVNXVr!Y&e*Uwi#()h!i
z`__J_2LKMOrxJ9d#zTRy7D_pPJ9h-%uLa+$s^ylYc?<Wv50Zz|S8oT%V~bd>u8Qo%
zHY+yjs+%&NL;InpP{;Wyvt-SBDhx=VvYtCi%9oo<K&c*XTuZftmkZPECDW^CF|Y~6
zO#=SfpEs$IT#2awK)Tq?hm>=O&BYEJfPEj2;j_*_J2K=OI3xx+ldRdUAPwqo^gS^e
z2Fsm;$45?m-#6BuGglWV&AI~1=c2j=<DzETtx#AC)(8341hj3J0+#@Q(gj_li}M7@
zAN9jl*Ge|lBo0!vo2M|6uEA(u`<_sLW0dMeLGucwEr=2I^4_v1GC!ftt^-aaAw-@Y
z&P}l(SU<w|0XO$c?>6q&VRFIHw=3>r$ENpyeWl&8kO^9~mLjGl_|Z?$0=3}lZTg(g
zGC*D=NPNoA(wA;uPE~<zvsp_nZ|!$yN0*0(sX2d#^7>Z{zSdqFDXekh6mPQC*BAKY
zpS<75K@z{-*s0=<9(LYpS&PRw6|hYyf`$+G6_Ta>c#G6?DiflKr5)5N)ogJS;DrLD
z=K7B{svjxfn3zzL{W#s5aBX|Xy|?sc=H5XLLaH^5>oYUC8f*dQiGz|It8PI3teOmw
z{HRBeWH40rfZR?*dN-<w_z@*pe&bXz47iBx8se)M=0+Db%5YN@vWjStyiQ9GC=C=?
zIg2W4eqnOWBcTm4_#Db$rDfj>*$CXcs8eh<P>x#v7H(S=Q=4L*Ouq%iyj9OET3NC4
zi1S*5#k_z@2OtVwJeA^=(k21dQ3SS7NY=KWnpS+?2-Z~?1kTnL^NuIi)r)h#q}Tg7
zg)ZR#0lPUenxXi3#Qdk6BsIuq!BN?7-@yM_+5*mw-Z<|WH|3-YZQ-r-j6HjR{;am1
z!SpGFAD!kBPs@pk{anwicqO?__qg|41MWKRLB+F&kGpEE%<Sc}cnoJDF-l#^XX19S
zR|zq^Z=@y5LVy3TI%9kZ%*K%*C~j`hX*lZY<&oVSrb->%Lu||A4%_r&`)S)N9s@Wr
zp4-nHClseORL1|`F=T$jrk_#(WwYD@=r}tkrFZeRPqDS^%5!N3WT^*00vh-lu@59n
zgua-0WBx5EX+bu#Cvn(c4D@jPV0AVI{NcmDZ>^ikL-1hlO|Fj+jL7z0Jh)p?o%clN
z=lzKp`!zeD_9GF`-L4mDlq1x;hKg&NIzDl-B<#f@)te1u?~u3*_;v~kyzq!l^sdan
zj|=2qC+*QhJr<bDQo?0uel_qN$SN@?cd(4jPzQccK0j6@XGjGW<sGQGZ!@?oZB#xZ
z3WoV?f9+}abYu`BJ?Yi`9&Q9gPCK{1L!}0&D*85)158Ie=Hc+|Q33PC7!kRV6EBuI
z_(q>>#$JV8OB4M|i@ko%E3VF5^Eo480M4L}7ySBJmH=~z7ORs@!yn?N)<|aGq_S>t
zVF}qlj0rd8qX|E7u)8B<|4|ADPQYVc$=&f^>LKi9=UB3~In;@C_eH0F6aO?T%P_{<
zmamKIp`@A|zgYC0D~eh{#r?af?M3A0HJ0jw5a~pE0#A&DccFOi+ejrUwMC<VrI%_A
zDwvn%Ly{Zev}RB4=Pi<<ICqShS;xDvsl_`ipo<Z$7qsZ15k6|M?o6GZDf1{cZ5~%W
zLKS)ewBF-;E}zjQaRN$=&n#4Q?r^60T@#jEITOL);{;L#4{)VuXZ6h{ItsYXdb^;2
z#8jYlf8Xm7l`r}emn&;+?m6%MXqT2}NfgFb8{(Eg8n&kZqf!sVTh9Rp8dgXt`*<zd
zuLQY35{C+)HCAiFdK8P6vmOJ2u;=)gb(vIZTVD;?qMrSHh}Xg}7yfFHUswtTnyisi
zCN(%1jQo4rF}(#4)KaFCYZJ)O3kHS8PKfvhVrvk#CzX|Q%5oacxoFon(HcwnJGCn{
zfFKg_L*{_H0IV9ScfP?ru!BuaA^fyC<|MD7RdX}ox~`)evURX@gpad=GS4_KzZY!^
zyf9rY1bdUqhcbo0VPQTrgNt3^3^Wfipp0;m4&c0wS>mKqBN)CISQ}5b|4|+sb%sup
zP(IN6q9b-{I=H=SOBqwCY9u6`(=9t5gfAKK{sAUMG_eUjTeFye0oxX7j{)<u>w@B8
z8{B)r*gJFydy?o}QpD*N*hsCgr~iC+3S)!?WwBY>O30Kl;29V>uf)+h{>Vk;z+O0Y
z6IROH4{G?FtYqnD>Io0NIl8#$^&2DxPr|bO0GY$xbODy<jMh|Ow|fsi#FWUU-k6dK
zdxHm1S%+6fz=oj^4Z(jpVL}Xy=j6QU^$p@c9d#ebzh0e#sVIqH`@(2NIpNj+?#BxS
zAO9B=6l)@6!4s6qZ-}*eKiQ@d0m~>-Og4!TByn*GC9jWF5sd?CEqiEuhxw!J15T`Q
zH^H|)03`Rt>NK*p=P0RSY{biqQ2$LEHof|pD6@j(I#UuS=0UOMwB?^!t<eRGjDqBQ
z%KWtiJOqgayg`-Ted7khHC??;HcK8(l)AVAw#CB<{GF6=9Nv{M15vzOZ7b>vy_*aC
zEAk`a%9X&E0XaCCAj@l~GufgCwDK5ZiIj@16dq8+6OFFII339n(6ed%=!(5_>o_mA
zzKTxhOQ_n0&V>k)WTz~=%ImSD%p}cJ&ip(;Lb;r4NqbnGqRli-JS#rb+)pT6A;vp~
z-K$^j+EcQ7TtbV48ZWQAw*@r7saztGFOCUqe*q^tFT8<c<!Q|Knr6}*iIKY>sHK!D
zJMCxEZ;bR%#?@yTk2f&-cy*LeKUUQcwoG<`A)Pxdsivi=;;R-Unexga51P;vs)z-p
zAKXEW%?;53IYFjvkn&FC$&km92M_Dd)o_3u#k9cMe>^Iq9qKw;PfQ71%Z&s%-IB?S
z@v|8G$(F1D_99kN9kIMbEy=H~P2dBkMGR-)xUA9WcRk92N^s^Yp~R}CnrKv138(Bj
z8XXPeFB!Iu_Ng8!0d!iwR1DdAlWDW-nN5;ooU=Rr;!kn~BEAaw`f$sM3$T4|DPkBk
z{);2D!4NrNTgwVA%)P5af&?>@oxF)=QX8aSq_74$=fhKh2IWTsWyQ!7HC%@$Jj6#2
zIwL_4^RCcz1ky-z2+CoZs10;hTY-C|0x>NJ93Y7lZSjmnq!pPJ#-zfuK2<2n7LrxC
zRfVmlv?FCU?%ql{D=VC?K?IA66w`lxa(#PCe{3oO0>@G|7;@7Cct(h12}vUHkBT%g
z7f^Cw_C9Yc8jF0}>uPV059?^|4`hubi-z^my^RB`?9a4*F1gM<8bVC}+(lJfp5vEB
z{k&J^NAaI{4Vdy=mG6nn2=Pr&dlHH35+6eA`&0<%aJf(|K@3ne&UCQ*W>`FZn=Dzg
zr&=gd2u=6Q6usv0yiCG>moZV;*j^=PSh0)RV)uFdY-?|2hFW|+oS9)*F@a2kUP?(?
zTFR2(Ve5D_roYLatZR6l**pg!j&nA1&nc{e?=>IK8{?%F^r@ZHj0<t8K9unMswEar
z9N~sl7B!Q+d$^AZ7IVj*VKDQ&0_DFVG27N1GupTq;u18o{}voFHtM5dmo_q!e(y?7
zXUHa2;JZ&pMVwz1axE<2Iw5^($7h(xDI|6lREGtYMD9NVo77oTWX#Z6Es34AFAI2-
zO7qU+?<n8N^9m5W!JL$II}fo`K4lhx{!yVYM49$LSIS|^z7(27i{eBlCw96ZF6s~D
zJ^gTP3kAZUSCCI)m7*qeZpu^qtd?NBso1vEh3PGGsu1V2lrsP#@ol6K-}RF#{iV_l
z_ZtoWvFgsIWK~mI{P=!j>Wye_4R>j-<W4ZsT<K<!i;vVQ_I2^#9H24)@Hr(@?2<EK
z>kceVpEHTMQH0Jib8&19TW%X4wx3tpq++BnMi{D~HprI<1PQ}rqvVIUxE#w7;`}k;
z9{|+GqoYdZ7X34v<Vvt7vF?`E#FX*mGb-d==Gg@@+Kjl(j&G_b&Lc`Cp*V#;b-TdQ
zea=;+M#5jTyUUOTA2RaU2+K(eCj5HMtLOd*-r1nQUqZ?7m398%RDd>TzDeGfgHAoJ
z!ljCqAwwRQ<}wF0FxNS8pNv))EF;r;XCSv&Kuw*5^^Cw)`xsB8TtemES9aBo%FV`$
zCU+4$g7+a`ATVaw7%NJFcyDY_Zv4{%4H>SuR65uQxCJ<Z#1dMBj=;=@Rd2wM@PiVS
z{Z5_~pvX0m>A)IY|I7!;7PGuWUn6K2pbySRRh_eX5rzN8L$}j2+?Ix=C35W5kGW^P
zXOZj;gI{|;9glpSkbd5oTX^mBKdqkxg_v>=md@D$I?Ho4?ak8rnHU5-4o`z*J^xui
zSr(aom^yiezK$G{Nl3%0Z{agyPkZ2O<)WrxjA+Q|t>*$+aD84sNW+I?2I_(5^VLb!
zqSq?zrfOMLA~wm8P#NrVKIf)``}~~Kv=n-#_I2Q<454Z9TqyhFk{Mii?sN4v!y+OW
z>*``}fEzO|fZ2|sj~hKJG`n6{Wd(`XX-C3;&_CcIfoW&Kd2(bMEQBopQU6p8m<O%M
z&@ASf&zNmS&n?yh!*&WTgn5)M?3FGUEJE(fa|}6ZW{ms+$+78=uo8SGZ)zo;V#!zp
zk>NqAT>oJGmL~^OH4unsEe>^AaSe7!E{s_FgOVjne!q9!8x2MP$~G?PI+!`6{qQ-|
z(BV6E?NY`uYq^eMRDHU@K%s6^=B`Bx>FirZ%RhVC$r0Uv<$ANj089FQn?|PS{WfLv
zo-t#JQQV{G8(fs6J6@U=i@o+adsDKh>p2Xhsp)W03Zfoi3NjOk9b`I%7ZS=DXDnqu
zb#(Hd{?;;h92bRpx{F|316RXu=6XAVBu0{$db!S^`e0U>3%xlSMQ`L?jE*ip7#kyO
z;FUnNuPNW0IoTkWCRi+_>J#cZf5`wCk*1eH;HbX*LLV%G43hxRI9O3r<f2M!GNAK|
zk#;ER*q~P<hnJToNQLM(2_MRBjH*3<2$}dCc_H=dyX=RDci@N#RPNOOdYwr@QheuF
z<~*1<qQw`k(x{*BtDeMK^FV43lbF8G;(>p{ul5;N1IH@IAa^+RVc>?(0i9Sp?~ooh
z`{*b$D<wzWLC=p!5j4UYncikicXU)l_TzrycTGZ{L?99TcIrd!_B&RwO#S^HjiH6E
zh2Ri?YkNcv_}C$D&w(pTpD+|4zB|NpE7rfD?T+K(m>UR_d2JMz(8n`m%^3ErJQJf`
zDT%^k+Rg<_p&e^e0~3YwX&u0CMXZRe7$S2Lgk%y;e$se86z#s#Pk6k^4XBUXA#6Ew
z@xG{l5+F?w`Q+pL5#C*p=1?zY0leXo2m0Un>R)d!g+K{Fhk`h;F4K!S{$;Xw1tlt8
z^&cd3={UE#=7V_sB<TrVk_0jkZB(T<RhPh^)pc)Yb{&&jDA$Wx5y&p?1QZt^MU-(R
z79Y1sqLhIPfH>uyFnz!*f^O!v5tozXzg0^r2b_<uQ@w1%`ZmfnVTymY1GYR$lEV^8
zd76>%dL3sA{D2$ZGHL8+1rlBblq(%pX;nJK1fNeI?gcMn4ID>})6W)^$(X!695s#C
zdCNwepZ<PrHa`d>+k?@lFSuI`rrgR&{oTx_Vg$N^UmNQlP8d()kgY=?d@FVG{F3QM
z9;2N-A5KPIf>hdx&XwHR)L4n$m)HoS&`(FR14R0Gqs7iZg!T6?G3&ci9U%eE?I8eJ
z+6V*srw3Go)QETxg#@vsw8-JKKO>8O(;_O%!dJ|cxcnPB+kHiN`99A<@|3m=`9|9A
z5^+6i@#hW@ycf`Okagp&$L*Z&NvHm3!2@q!2D;dQBiXt))q?5GlwJBmnY_Nk=%~})
zu7(}Q&JRuK2B;{=sW*%it#|bV8dIf~$>gZZB{2TG#ZoY}7!;V;mUv`zrhSM`D~|RY
zhmau<Grde47eS5EH4K-Ejs}?twWQ@7r^)j)ce7(9$k)&{*G2MlKez{FUitJqbPOg|
zq|m#v)&LZJmW#FNO-hf@u82F(Dj+82mRFd{QQ)SubD5}a*PDh>6x;LBfKFl-CfUAE
zWT`yE)5KdHl1raYbJa$rQgu)h`qr1$ctW<<+V=4Ax+)E`&<pAQad`b+VmQRFysZ($
z^21F&5k)lfI+9!hvg<o2Z-17Scl}7h_=JW_o0A9I-LiM|foVN8Ke|sA7eat*{P=^k
zP3Q|y0|{%ZH}D^FzSgx(hxH%pEbNKjq6`8!o2BFX<S$(k&@+2b!%b;M{gpXWgL%kV
zujquJWs&_1=nWE|eSD$rV!q6lphlYd^Qd}SS(fu$G3u)c?ZNs_>d!4jdxPD|D1F>?
z%NV)Oh0}!g+i9}}c^ET2d*DCqSjRTb2f-oLl$(`s{*w+wgt~vkXa8A|wAY=dvs`gk
zozz((q?4lTc-E>91_uT`A+=dH#~%E-m*Ohv`i!*|x?rlbPP&8-auY!wCq?p8^ZrZd
z^4b*?Hu~0PLzj&d&fAQsrAF+4SaX7iWb|i{KqbIGco;hge|SvOJ>IpnShzRw*AWJo
z@jV}7djN@qpl3ddB{K6^I1e=Q3tyN*EG|%?Tr^TXijtxI0gjf9d^C~}P9)Ljt~8y;
z`rP=Ds2qMw3A5Nvo0#~qctU<&`WB?*d^~}jOz<=&m|@<)Y|fOW3+v&^dpFx!;z`Sp
zqsO1)RyY3p64}Z2vFA3*<Du<viv8O|u7EmT`!kDGn=o#O!Tcs?OZe9EhCrx4(!{SS
zqIU`hM7}@fKOY((A6rW1ujy;oTC2!%xqetUfhQyJ#&<t%<*)a!5gpaBIaaDycv^Jx
z7GiP<?}Z=?C@d?Et(KoM(u2%Xct{Y$IV^BrT*pVi0G}HNU|tTdH}2$E)?hFdHMEZ&
z6Qi88>H)I!Un_~pv`i&o&V_1!44)4MBA#bYuAYs5tE^Ex<n4v~KW_}&a_~jF+7lA9
z`AH!BeIx}5vXgQA{LEDqk1sjqRo`yOnfI8TdF6gwDp+tlOFbi87pXUIa80z{piE@0
z@b0UP<QvLX<bBxeDIUpaee`9k@{UTMsY+SyO&dHp4-(HAzarP_J6hid0sgw9+S}J=
z{6AkTzL5&g%cqGf$ickZUCQ!}<7E&g)Dl>nbbL8nR>l>g{v^dX9hVM+GGY)(IV9Hs
zd}e=aX{Ad@MRE-J#EDrb@}x?L5x=YPX;vqj1&H;0hLSf*3>#TALMx=eIlHwhiVJ0R
z8MI?-Q`6U6Im=j5XZ5QF$Ps_c|4cTnn7AxyLon_BV$}MD+xzU<d&063YBvV)Y@zdf
zUP$aNGzom8Gf6v9$tCE>hAwTQT9=iEiYj{S8Rs;G85-_QbuVv0U}_7kHWr!!4F3(K
z?PZH4f!zh1vtG@Z$OVI%f2G^KspRH}oy4e<9n+>2c^4cRcDM#S|0MN>I8z?C@STT+
zX@5=(RU~l^&n1l40{^>GwjVXSkJaC)A2e1i>9{qTTzT+uvABOm0N_<2V?hzc9l)s#
zWV!lxI|=;e5c?9tG7DrP@JDyAaGYuw&O+Bd@eajRRMXoELNH`gPfD%H|Gm}Q$mFGM
z`x*?2@1;4d*b$o!t-)xNsoXbSVys}hz}gT1>ryZ?l_A5xp~_GVY@*19e)8ElP^$w<
zYCiZ|zCPzgnvh_$s<HxuG^44pUa2`XM6)U4neisDvQ_~NYId%%bU6SDyX}{D-G)vA
zCl&EoGN|!>RMkL(m7LVv=9@E9K?FV}3T!bj_T5_W_3UY|)GkmlTOjU}pg6t}iu|BR
z2ze80Y%pF^hX)*F>V#LGKtR_3iHlC-ou0(TF3y{4Kk+T0?b--OKwFQ6`Tm2vA#bqp
zINmTg?hw*~`L*|HSzaegUFPQse#Y~CylVG@b$KC}DJ~tIsj}DW)54Nm?W-p`X(#N5
zr>0PFxteuR9=6i*N#J>3sa0KVs}7QNmx`C{^<Lm>rNq7A?3}%ut_pI(?NvxqzDlV#
zn!hG#h6Aq%g7Y5w>-I21^2xL}k`gLl*1&Kn_;h%(rxR?ot~J=+==L5uwqoJETu$Db
zR2K|4Z-E~kD=_Y*gg0#5O7&B*mUH$V5zG`2|3?lHjfYKTrj^ht?JU36%-j&%+eWXr
zcS;noy~iU<dC}_%sRepoxD?Knoj2}<Llx2IAFTb%R5W@B38K=s56!%Y+k0d)F9u^H
zobvjv%KPGfQ_TrM$MP`M<zc<LCv~C3@iYyS2x344(Ii&!=G3@n7*mfSeA+?aS}=o@
ztm|2a)AL`pY-7#<5^uywcqXvlHr8?qdql6dR`Ok2g}C+ac{x$@0V_&lx{)HvZ(}S^
z0d%f1LgsU;Pzq*-QldB_cWhIr<+yu#1cer(GWQpl5l^Ig-vnU<KYik5WmshoXUYbS
z{paVG4AhKyU3TlqRG&D3h)zVF$8Z~Lp3lGJZHgx>1Pq<4zDnastR6dfkJgG5s=!3)
zCL<MVos~x#96Rx$Ne>JTX<UC_JGw1C`4mZ>M@7HGR+s2W<(})px2vor*r#Cx<F9C#
z=b|e&iJFh><ieJ~m@vPlnUYss7P9vcq8EiI%ZEddv`3J=$snr*)6YgQ{`lH7*|d_I
z#%3LeYma~0gum0}W*yW-8@jyaCBUB71KwsRK6Ljs+F#|Z#5ElQ`{Y~WazP^RntLps
z2z^r@%D&0%%LKd~U}Ucn$5<&j=Sz3yIad1pJ07nZgbxq;VqXbPe0Ope+Zj|36y?+-
zpdN|0jvqp)hS2SkfJAE)`?eUB$wo`&dy=_=O`*Gi5<O6WACCi6g1Np4qAQM_M-ni5
z7Tp-T*RAxu^0!0NF@9<4>ECS0yD>;NDHn7@nYhL<J4BO;7?&j30ecG4pq%_~<(RFD
z?|9mY;gC{yip06GaZx?a+&R8nv8N5QBq!C3wHAr{l&iotl?&w1{!OIauLAcwJ5*-_
z-em3p)Gt$4UDw8SnwiGAm8KnG)zo)c=?TP57ySM=oY-o;@aNlu<Tg$<0=PDC(&Nyt
z`k(!jv3ztULPIxWiKFxk{E4|qt!18WBskB!RedgC+#jlq8;{q8egm^$eVE{=F&o|D
z6};Y&h&oF*uQC5Aw}*>552xNWKm70?b7Lt#6l0(8+<{JUzZ6)4Z<T?_ANJ3P-fvHY
zN5(S3tsgeE9eJ`xn~A2}YaF^5KS`Db@3f-w=_<^HQJJFB@9KWV1JtSu#P5!ruHEO?
z(_HS;0sJ|eMv}gviISd-Hs2lR!%TDssAY#bn>PXMdxlw){G`O*szbj&_fWIgf#8gp
zklscVMm=)2c(HL<@<&pJ$~(tbvXbK_ULU4cO}3ql$1}Y&dO>+Ui|wzaZgzJq?QMuI
z{8isv3?7Qobk%#NX>PUnJI97$d8n?t<eY1{FJ}OuwJewWQmJ)nr1t9sXpB3Vmns(q
zqz>+|ShebpmZJ%5I4N(;!RwXJfU5pg=#WJH$-9gR(-M6dzDzL_#1ZqEOpNS`Rd3ms
zUN2oxz}_X|N(Fe|0ig`haOowP1)BOtOQ1AYNZ6ioKf7&Jv#_5%Ulu=S7zC%%HY6Q`
zkiQq5ol{Yy*7t-e4T;$btZVgb7By`>qL>&k-at^ko^gIi)+M12&hy?ef%S0TV3Mx;
zVjg^>r<)@4Ay?`n{DM=f&}apQG31e4_$~5LV2R2!?_^nF-oD6hSS(nuP&b()6ve}N
z=WDs*3lpuisch#r->_u315je8XWB8><)9xK41cjc?og)db`tyZr#VEW$taAch3?<(
zG#Yj!+r5nrU(84orF@#5Zk-uNg5OxCr!^B7EkjHEU)QKVrOz4lOq(0q-KR6Xl}s-^
zHwAK0eyyM#O{bzRTW<eMSge((qS&7rND&kPUl%6?h*&QlkQ3QnAL@t?G6fz4>pb(@
zhkDu0*aUBeHpXn6;L4PbI~!icK*+M!@HkU<J-#AmB)4{OwH;RuO-C;2mtRtCp;P#|
z6~2@*YdTA+#F)QOojmKmV4KA_4{`a^0bjA_pML*0x2MC5l)tF7U8MyD0t$cw0z&=Y
zS-+XJg^`sV(|@sjkLrZ&79&y*<T!u*dB`J%v{+`Lza5+B)d0AsB#0n9R#rJ}1&R%g
z-yW7C3g(3DX5on-Va3687CS7}tEjG2qulZB=jG=ml}u%%x9rGL9M7k-kEs4I6K6bG
z#+<DJh#SC<T#KGP0&OEzmB$AGTLYIYEsTl8(hp;-B$1c|WtYy>?O<ojKU&hAI}cS$
z=cGIf$!Ajas!|JObGlSYL%@~`v}RYfner(x?J>kPpJG&h-)m&nW0_b#mAMzOdSouN
zo*4)<54e0fY=T7u13)*bh#U2HoWpe-1b%#2ghp$7@H)MW+VKf7e00c&l0l2u^B0RQ
zqpvPyaP8XbJTlR0CQD`Pgb^#<t?AN?sv;Bpqe2>okZ@4h!Ove~o51))zFy?9T_Oon
zmuq>rqWn16T6Kn$f4t0lZe<eOYyz~~OB3-J(_>az5jA0BF-}a}2x4w6Xbd|*eCr;0
zxaCTm3(S)P=2K);Ztv0gKK+WuIJj;MS~X6UUzh0J$WW}ygux!b`SNc)4jp0QZDef-
zziG*uSWxIG(}q*V!}K58I=aafppD1c;^?Kv9WGyjK-<GhJ_`dWjL{0uYK!#iJY6J*
z_i@veMK|{VSe}J3OugQ+G~z(334`Q<wAQ}Dm?uRtjnMLC>m#8VJo8lRQxoe_S|}^1
z<3nN2fWKk2AZmG9mOH^Q*{=<Ziede30@IgR$nlwYE}#3fxRjW1k8`lj{trCpTYRHV
z*sbZB+qFJxTi_+fSnJh&Xa39fQit%D(t233BuE!fzfFljq#GI7?&`tWA$&goaUv#~
z4^KE=qy|46N-)^2b+;<Sx6cIt=(o~m6-v!Out|DM<00rV#o?)+gUr1NAux&#i-g!A
zBI=^F$L{RyiV;hW2(?quA@|b`{4FW_b~&<y;>^AK8yR&3j{g(0bye%9?R-M3r>n|2
ztWo10LmDcOrTH8&@YOCd-APm$zS&GyI5X)b3Q*CXyd;-zETXT!+&;0I#NQ3_+$4eu
z%@cO`m)h$;yL|%XWU%&RS|ZUDDJM6)@rH>?JL`xg?1`cM*d)h)Hu3=be;?QXfHY4|
zh&cKXKtSAtKtLG(`*As%m^qp_Ia%1*{tp(Tv1Pl>hU9~|?*~{HAR%k)yn3Ao4+N9c
z%y&s7cG!X(LTX1*o6;m!NqpS=_(YJ@p{!|AACp}`lLgW$KIJ=;Uwj9W%^=6+3lEv6
zRkD|o1Q%~ADl&3^`FE8T23u&3KwwT(q4?Jx+)i{i+4*h(_=_rIHF@X|TUV;bk~Ev;
z9`8$tslgxBbD|yHi-JXE>=Z_zE<JEk(;r=-KEGTJn~pm0R#HP3)Dk_>{CTn+Lx6*-
z4qeH?2k(FwvIRvZqlg^f(I_Bo9xkAYQld{K8lp?NOxi^VzT+IFrje8+tYD?uAa_2d
z-cy``u}BZ<nX;fcq$q)u9auS!xS7PovWm7M6LWFRE43s|Eu*lAhO(YF#{A^>deqzD
z0kjc$ADCKrFVt)797B&i;tt$03>U;FxPi$jyQIr0BYZTWg`@ZH9P}x0_pCuH%P*|n
z97es7rt(XsDFIP1=EZNlbPpQuLx|xCcSc1hQ&Cz`A*Kb$8n7Abue+koRf|PMQZDK-
zBO0=X^GTqg0G*nIg8WL8lAVemiHt!*5>trRC=sJOPY4pMl<AdGAWa8-)OrQ;$3W`J
ze=v2Eb{Hl3iCNP8mSUKL`5>^EOmtqn-qaJ^JO%~MOiPuHJ_okF-r~K4qNJF#?+14j
zLRem27Wp4k!2D)2+I2wZ+xY8FKQL7j%Az5WeeSEz=0H=Ql-EO`O5`w$UGAND&9=ab
zS$eq++M%cdvg&9?d2Ufyy^CV%>QKg#cQ+}UuOgqV4e#o4pk{+7ol4(S7B#D62~>pT
zy4Ybcr&!8@@71ts+nrBeA9R$UC|XulUqRc<4!hb5eW{KhL_nTi9yZSlP91j0S<=>)
zm$R+qP^G3s%zV<uWObAxZM_dYchf;FoYIVj6VDc8tMg&QKZ{nQQborI7xpl9B#^?;
zLZO{@P?0EYTw(ggQlV+!*HZcflam&w`rv~6fWi|dA=B!un0nDxEwUl_qAS@+$(tZq
z6MbgapY59(DjHQyvb$i;#hKYaWIu~RNhRR|mYYC9G;Nd$p*Z7H*=;PRkofSY{G^z8
zA3t`uxB;|0U=K%X98$w9k*tm3O!#4D)?W}D-AOawaD}@AZwXYYE^;O}4b{)dxjM9N
z2^*0fa{Mb+GA@oRoC9^DgrIwCU*B7BqK5=xk0?ZM6jd3l=tD-^+}F`CeA~beTN~@S
z`qtd+v6>)4Z}X>~mW|8i6a?2BkM^32Td*#ZD=fLPov|>pNC$H}ITlahYkt^7`V#I#
z<MJUq_?MA?mHjqNvE&2dM*v&Uo7&jk4;>)elz+wIw{`<@`q^ViT2Cc09M)+%P`gEQ
zUSaQT>QDWVkgD4hG};gMO~<~J2YodB@`nK^d-P=YB;UT2e?H5*x4c~FR+Vo<zs8~M
zkoq&~`NO!yCVY*%uw(hVgDNI=C{0}YLfD@rTU(>GD#Ho(T@e$(Om}-B%Qql~r~PL?
zZ_NmNRPr>f!k&<N!y>|;dOG$h3KgN`48n2?ip9rv<ELB_@#GTcj#&v@XQB^GiGGZ+
zZ^l2&mzNA*6HNhUp30}L)(dl;gzfq~6uM>13Uq+G`a@OM(-IIXB!%8o+pp9^1Np@0
zOyKa5I5P<7txN&Uiu{&MJV4VE<0`Safhm2?bt9UHm+CZ7EbtXyuZx*k)@!jZ0E$P_
zKc=9yRUm6m+e&$(gv=)7o&`>RC_#TatQHhPflsj&cN?<oPOpzYl>ZYVqk{_HeKWTG
zn=NI0@QJP@6L6bssJNEQeU@ae!IEuKum;YYCuAjQw(+f+X^a{02TL{&PtRa<ag;Hm
zDc#Z)bpYeVwm*sjYk@RSC^GcSRG@nKUh?bpC<}EPY7i>jR=krsW6qR0xmd(8ly6#(
zGjTmPiM(|=J)im`f{?ItaPz<}%*hGQh$R4afSZ1y@~>DZH;aCJ1r{6m=_F`N*G-`t
z$gQU^*Z^)c2yP$vdc0k51dE>qROoY=dc)I8>yq-8nTS+JM#yQv$)`v!gZNj3l)*`m
zy;5;1i`*uN3(t9#eGpIKwlOlGXS`}mrjTt5VK3bIZ!OFqPRuAQSe=XSkWE_XVlx68
zk>@JNw1*W9Hz(=OoM^A`g|-NuUC+RGaOdiH8nZjB9>M#npaDA?PyMx)$p-)b)ugeG
zY<V0e#3*)fAfP`8|Bog)TR0ooTALU+{*NY=sA*Xpv!VGS9`ob!%r|UQxFwF&D|Ob(
zQ*Q7$gZ`@rD{5eEz}8?&<dKx}^PWpM-f|Dc;6hSuoc);nPI3j08~g+Aci!V#*nB^(
z0ot~;wZ;AJiKyqYBI)bX5_l)ZF@}D<chKbEVz%EKl(+Audda)}R3xu^Ey!(qXCA_@
z1`FG|np3SmC&*I67OU1z%V@r*Q-jX33*xL=Zl(^2Y=4||JYD_*PN_0kD@0jvA0D(!
zmLv~7BwaScZ4Ro97qU=!FgcKbHSkIlk57v|nqr${KCBn+D$rA!RLho)>{*f3>U6$=
zC3=?|60`sh6_yv`avgGnX?j1$Wh;-bBt4<6MX7O>E}xoD>!uT>(b-EKNy4sbu7Xw{
zbj-GQ%KqW%l{9})De`Sb|MEooT(n<zt|_5z73@f*^tV^b;HeP65=l(*Jdt~!Wc==b
zN>w~yxV>~|#@M|e-n_`TCUsN1K6aUd>d97JQ_{*dbDF+|MP5Z&64?c>JpE^jp?Fj~
z3!YIWz$Jw_I&v~gm1(Tt5V9b62yTOHT^|b}hg#CyS-%U4`aD^=U2u06{S;s6gG`(P
z&Tr)P%%7fWq^jcYh?X_iKzW@V&*at?&TwI_!v@SC7y+4zyyXr=g`n4^aC8!lE#L$8
z6DW@Wzt={8uA1^-%T5oX`iiF7&YXJnz#dEQi6x)xXxZ1$m#Rw-FV=gu>NZUVrKI!;
zF7GGVw;_3|5R0lOhT!08^USp;f}8fGJ{CRiM))91jxX9^&25nKUWCmnaK5y<uI}sJ
z0>=yWnp;+<33vpXFTAqWVlTo`SsG|vt^j=T8Udu9!ySJ8X5OsrmVYTO5Vo8O!fZ{0
z=V<Y9$}t%%vAdU=Z0K}Yq<Hs8yMjla8e0#ZSGGCmxPaQ!T!1S`JCqAJ7ndF;GoVm{
zE-lP@k)YM8Lz2Ke`AdOM!n9~UJSbFmAvA1*(2cl5W<k^0^_eS`)-#rc(nfagk>Oz9
z5lVp>==Y40e)A(OKk_i+C}bcj{BMBDmkri>MdtBkG_wzigz5F7bAC0ilZlRcHv`+U
z)<_i_1ILZJe<wGteY4xWIajWSCxt+eu^n1A{M`@nyR9XK(A{Al^HA3W*A?DdQIaZ0
z51Aw?i=B%`QPxlS+4j%nkclLmS-fF+?N`l6*7B_MCQZ+(30_fS{3pGT_QWd(x(0y@
zTts3tRt8|^NOBjG5F@1;v*h-^b9aEPv{p&PI;8BqNe?z+jsDNPl3hC2!kCmDsBoGN
zw$NC+{>cZ%{U+1T4wBD9TJL=~Ew-&!IlgRgR3s3mX;yi9Srd=#nB!YtJf?GuvY&OH
zW0{d)V~4(kHiJ7eW_A?9$>f6^ru(<bg<`qW0@H)6{n4`V_?i48%jL5QDW*^#KBG`t
zPC3KCBQK2}Pm6IHkC>x%+HCDTXGl{G{7wj|;X@3`%N22!k(>AWz|5EZD!KbLFR>WM
zi|GO<r<GQ1rL(7fAu2<ZQrO@W4c4tg%`IU7qJ8VILVDnRn>$j=Y%%eW=%d4W;kvUU
z-z>RVaqx82z#cxu!#A(t=M65qY`;g_<Sf9G%*#Em8`(<Y1bipG9koV7kWV%;jSj%m
zSXB0(u?v)75xo=8I<hLC^I)3ac~_U<ou6N44$X2@p9@V&MnJ`tlBhlrC$y%LLGRik
zf7XVAd?vzd)fXox{eB~!`5FRBY`jS<Fq$u7jDm##Y-i6N3R#8&m5e%YrDQ%!7AMwc
z=z4w2Jp0jy`TZ{@{(tQM@}}P3C43+tcz+-u^#5)DogH0FoUAOYt^b>}E4)@oTmM1v
zIw!yW?oCAPgF>Vx7HXB%cgIaRjwv_o)?^jjo`@l2f+)yP^FZy#QYXK@-|6fSq-qN~
zj<i~^hMxaZonD@vp;4Whkdlq-ty^5uiG+G~m7Va5U8U5mHmUb-a{M39N#H`KHmYqZ
zDl91Wtx`{qOLD_)E}OMz)=76{XsSWKYcceZYb!pb^VLf-Xv-EI(}nvwy$?q2S-dRa
zI&3;N_<Y~RH3YgopOQcXm5R1&ZW=ZBKLUFE-=te}jWRgi(sq5dSCtqk0K#_Y!T<R8
z{PIZ?G}=h&5QZkp9;(Lg_)S_&AQA8bpkBE1n`((H@^__9n@k?Mq08I5jcPoYWwW|K
zf-CD(b`KRX!LG@`?rzA<#(d5BwSUc_noYE(?=lE<(VZ?q&OdK9OQuiyIVB)VV(7JP
zqFHv4xRH1G<!}XHlWaRovOipN7>uhP8UJO?Y#I&W`JXe0D$v??k0)H{b6H=eXa*-)
z3D<DGkKq209;nIa_85dQObW8<NW)6ed0aCEzjpX+Snxs|`!E(g+qF%NWXBq8bEo5a
zO@^wJ*X;8}y32ktQ8gj|4h>OQsw}mD{2KK&%%~(#?y2a461JdXfY==!khNv66-~+e
zwSjP)kstq*W@c@BOtJ3kaRUAJR#d@H=R@-1U(v+`Pn>ZDO{h~3TX3$O=T5Fc$}1v%
z)*qt9Wa(Y8;aV9BV{<R)s<Kd4!fIIx%qGt(6PmU}cqNGk@}f+jLPR!*AT#Kph~suH
zlY$(ep4;yK7RZQd*)@6i{sN@veUi0*K$A(K6@X*_&;7~p7%F&Q@AI|#s<PINO?v;R
zT*YvTwHB@7x~UnDBN{MoEY=Mke-!rByC@r%6t<uD)pKP>F?}dyDUPD}m@ciAU}<wN
zg9wD=J?`{I<}mssOUCv>g8&dnrQ(#CNQXj<tpG(-aLPoVHat)GMg>IQfeJS1sJFWy
zg1|jrSkMjX-|ss~`)bLw*S$RUJ_4|_?a)^Ky)v7eyCGt`<eLZc&(d7c0qUu=D%J82
z9X>m?=WBBh!cK|1NZMd7Veu6v@@&2EyKg&Ji=@7(eCx@ZaB^F2QxJHlAa^v*iu!69
z0O2t|J(g+E(gI!cguM<Wd_jUIG_fY)yzmLpw^w}TpH@+Q-r;DnKlp?<v*`rOv<C3_
z6O15r1wc2rw1coBtJ0FZS%%=&FqRyn$vs3Sp>ltg>r#~G-|GfQ5*(pR(Xz{`O9un;
z@Sm91YaTbK)lJEkEe4?f2D!rKVsL1iz}_0`(#r`kS5<oEruhf5obYD)t`%zqhK~Yp
zU?QCGi1gJjdcgXfYG0t-M#sp!jmGg8Jf+@}g9&ZU*B6e7->SN^&HC?I?<*~yGBzyy
z!N=;YHJ@pPGmA?N<@IG0rPkUc*4&<0*87;OZb=SsxV<-1KkBw<GgL$apIK-pi8$^J
z5>kqBLu>CKbQ#h`0js1TqM?><37GQ{@(Ca*ZC2zSo>#;HzQ8~8HokzbTXMjW`T^Q&
zt8-=@r8sQ%FdCQ_gtoeER5Qe0vn;{938plx+Tf-RI0CSH-Fa-8=-_=Z0V`og-EI5y
zlZKo2-xJENm9h-i^4I6Wfv^10{*Smyq1qhp%k3>&L^$924wp_uwR&w(KU*H2@Y*>0
zCeU!3u;kB%9HI1m4923iA0nw@+w~l_dZn>k<f??ZW?x?Yx=YKmirp>cY+E)BPQ-%D
zFoyNZzipoLw7?J%a3X}dgWf5t#>TVE&tG_GJK$NY3i2)a$%T|hdKKT(l8e>`J}8Yz
zg9x*Xs=X0yXG5S-I0xv@?QZ47<>x>Utw-WW{$u(d-gNaH8_F`P73Z3O$NgjJ&%<;N
z*Sx=T7s(Ag8k6&nL5>x6;B-r$u3TL=&dni2C%wU?W)e2iYw|3HkHCKsB!In=2~{N{
z3=)Z{eu-kkIk98y9R$@43J&iK)SQ^Rbr1JUZs@1<UF1Svy<-uYF2hrut7I-gnlDbg
z+aw|Qw@Hf@(`6UPDPsO0=^h!zf8JpEITt=UW^v}+U*?Km<|w%!&=bXr94f`hJ|<B~
zsBB72*txM9L){yY1sc-qlr&#g#v&rC894a59kJ5tM0_}D@PN(KY28aPf`DcsDVs!G
zI=0e{2e3-Aw3u~`j-UJ33qQ=d=bGSn@9T;TaPU=&1y1S1Y4X9)kKIbxJpQW`Wu9f@
z_<NU$q>1_!8dyLRZ(YPK$Se?)+fse$Vh%NFhU&p6-awKbOk3F39C{EYf#z-s1~)Pt
zM!@N&vBwSSOrX8ZC=(l8#(X_>!hw+MIfWPcUYrLq5`I<~M}e~R14TX)aq+|E4q^^I
zi`9ER4Rwu<9%p;Nuk`gNup8{pKea@kX96${Co^D@?~W|}Lw&iTec4UcOOxW<F@&Ur
zfz*5>Q0Hy%8_VPiX9T5Fgv-ASzzUvL)P#M&{FUu;E4ebgw2}}B=tQ0yO+<iXXh_pB
z-zbK)Ph1IN5*d75Ys+4uaY#e{1+4J@2%kjKRz|Ks(xWlY^XBLMwgwt<{M4o5C1I~C
zh0lV(25vFlp*E?-oPGzcytgn6eq)Sawm5sPVBGj*@UI(@v_r20MfQtK%+H`-;Q*)O
zFqPEkRsKo8=ZNWq9#AUI>94(s`dYVvwUe#1i|(P?pdpLsN&c__z#-CKh!S6-^zJt;
z=(i(v_?h+tLCA}9sFkr$D4TZVK0+jPBCb|b@1{u*?T`iE(8o+AWCc!-b6LH=-*wTr
zFB<0=ag0>4*Gk>Lbl!H?lIGL(uJnSEq>{@`jTqr!Wp^6>V=)fh7liLa1c8EIZ`2G!
z7yCTEt^Fy}v@|fL06xOG%AJ~fcmtJ$r`+fPI3w6&dactFuh!2#@H3fv*!Gu4ZeqxE
zJ&`Dh5vnZw<s1`La*dw!0A82}I}w~L_V>6BNMb?!>095|4Kuswo%fN}?3VTv-9O%N
zC#l!``=&`(5m1lxV<by%B`znR^i(@^mcVvFeN&gz8v<tw7r~aLE|^KOK^#yH4;;X6
zKLhGC@iYu?ZVVLdN-=s-mRNlLJK4jfnf*kaxFc#sRSy6{zlMdd15#hMPR}2>YoN}?
zB6mkt&p-Ge*eruzOt>Qqda~pU=+oy<b9DwGK*kwWHfSl@bFC5F|G_kvMC1SL`J20j
zgZVm$0G6IS9lowFj$enC&yOEZ562%V*Cwrd!D$EhZMPI6AUuXGwSR9CIw0;Q8alU`
zv;C11ji9$po6b?$fMc@;eHU;o3q)AFq<R1obmI-;;MERUn#Lr6AucS%HUK}ugReO<
z!aCVPU=hd*HzC5BI|_bD$Tk)JoEt462qt|8?Pzb1-JLxvmYgo(9)%)f{wow;k{Lto
z3C>Q6!q@fX)56rl6sD%37=xa+jvt@uJYmq$6=u@a)j||Kh!|5xXRogVZ>OS)09-C_
zUUY6x_o}kDug|yl*VpG{92o!n;)^kpZ*4?aX`R@bT2d7aj;FaS+KVVJl&YMezC_Gm
zb65wrA!jAoo7vNkf$G%mnIWU3BLi?cdAi-QMjrF!jKgyBuEBEJI^)Js;IY43Mi6Y*
z*{CuMe4=v*kqjdmh9C-5HkucwU}z*{Ri$O)F?~+Yh<ofijU@PJ1iNKi%p>JuVgFkW
z7BFs1{T(ta=S<h20LWGJfM*ad0I*ciRYILK%a&b7uJ=YBLB%xQ@Mm&ppzRzvK;tVq
z!3U#Rr5-%r6`U8v8NL%cyx=I&leABM4vk<$OKHy<PIU3Yoq38KG3?)rqze=#=t|9G
zV$jOrCrLv<ecmLvH9I-R{E`^|#K8^M*I5e{vpJFA>?2cAepNC9mG6a5=8|u4azA-;
zBZXf6UQi;%7bc4ej2|?8LVTG7)B7u77-|9|^iNvpiSekbQDLGK7E((B44V{T4)UWg
z>s++8Na(IW1jGjoIe}p;<e(V!g=CPMqQqa+5rfcbi$yXU;4B0VuM!kLv#~KpX@{$H
zOuRP>12)FFNVXJMpidOyVBvt2CD90kXPDnlrY@*BJPfhno(kiL;=pD-io9tAO^bV+
z>D;F-ztX2Nl*iYC!Mo#9coN}|DG2K^->!@xqwMeoB%gtMBNeTPZ2t&BE@=Kk-p|-W
z=u-hdl<aC%bf=BV@M?!D>PW)g%200JGi?eYV10SGX!Dx)i8YPMXO3kRkaOqc-Ntll
zf<4JHtyWTOAG2#rRTTt{7iRxUj;kS)Rl~_<%@ilt9xMk#ddtVZ+A)}E*crPSHqO%U
zhtO8*&ANq(9L?r8m5?3QF`d3y+sP`<1Kj{PW2tZ*p#ibiVThQqQ@9_fD*1Q2w6>~!
z?^v$3Y4dNlUGD%kun04`DD)HdVGzY6$Yi78jqUlO(jgg23kgOr{~pG`HFFE)iXx8v
z@8s1rf5C~Wo;H=6$zI06@myZ<0iLZB0RcDvEC_#=w}!B3k3MI^jwZ4PgF&PJZV$RR
zEsMdJ$f2>vd&6v%Ce#SKr7S)Q?4q~=qo2R-F*A2ru31n(lMzFi|G_G&cRJWP>1#vD
zF<bs$9z1lk1SPxm|6rkNrUQz4&Bpm9l&&iE6mM#@<i*Q5)087ruVk((yBc(|yS}Nt
zz&%*2$d3z9|1lyIPMEE~e2)uJxAN^W&SOJC^~`)w!cs|sT}5T^32oUGNm8KrGYE&Z
z4vCf@kAKaLbnJ|}`(duTaFL^#4Qw)`hU_%hrCSz)cf2d}%4A99J?sOG%QtDD*2C8_
z3PS9gNatkvx+p+-DrFYzvcnw4&m7z>y+7^|<Z0qc^<ZA-wq7n!cC6QE{n~*;<>1K=
zjH5)C(9J^HX~sa{ZJ#McYH>l~?ljzs(P#=vRa0^t$s<rO?+?oR2Y^@-cY?RDnKjET
zjLbD=3ok+sq2c4iDZ7N2G15cMiIXJqXhr?Ka&K&0WcH=V%WsqWZSm4alQx?$KhiZi
zbd*k=%oF$5ef)?yLNd(*fNfq)R|)w#3`u1K>UboBbA$Q$Q>Qc#F&aw0>#A#eC+{vK
zH1(u9VjR#A5#hd{S88;q+i3&z8To6S?W?xK>Bx1V70_D(+-TNmBxB)mB08^XzH=n$
zp(6SNj{BzA4-Ae)lzrz;!Hj%o79-AW{`k%U7?4=l;_42<)apbE?QSN6&ZO5KVK1<3
zuWj%Rx#&I)pY&5wo$ReYp8s>=45G_;Ct!$lvri+$RS)lb^giJ}@4dkN)_I2xf74Ux
zPU7}6B+7w;K9(@dwaom2%y_uuQv^Sp(flc3Z=W~A5ZeAUInSOkURj2<aG~Hr4$Pr9
zM5Tt($dztlNeF8gAb?P+pPL3bFl=sgZ=H&IMU1i3&*kz#`(6bcq*D_xo`~^#mr{8Y
zDS3a^z`Z+lAdfxfS))0P+%H%Uk*7|l5_u`vO=0=-tqRK8W75O89^Q4!x=mnf-*sPa
zvUJ6u;+YCXCk5kYFXqthd`Q6?&Nr;?#kvz-7fb(Eje%C^q!qc*7dhq56I$x^kWe|k
z1cM)TQ>sOE`gFvbl#;6^BUAkMr!h~yGya&>lSKuA1|02%X9!fvnKCU1U;~S1u2WRT
z?Uy2u`HK_6?iCK8jWwwasBIAMVA%L8CV;X}sD)tZB_UYq%liIeZVUO~dky?qFvwkX
z%0J+fJNc=v{d#Ki`}|>Dh9s2>GQ)`UnAJdWpKOOu-D;MdVjFUjbz5nLuhq>yYVZIn
zXT<3dsR0M{eSN|c8xPApKvhI2Rd;g`g3jCN{*D0Q$BD6Vz%g6&KhrZjz6#=V>J4&X
zQ~SLvUG<Ui|2&^D==puzxb5|R$o-%8&N?WnfA8a@fOJYLDYbMrEJ%Yiij>mf5(_LK
zC5@yYprn+N(!He8-3UuJNH?O--h1bF;W|9`H}m}W%<P^yv$KDk*L=@>&YAC-J+JTk
z(@YXg(Y7_u>EJwUUal+Xg{{ivjG>Y$Fo?N$ej%3W5oqZ50xBgx%NzDV258-BET<$!
zSR;F?mxRYb*l>_i)2)~ez;4!K++zZ}Ejm&aHFWf$l~X)Jqrf&4KW0MO<;BTf^vR8e
zFPyHEIGfaApsN`hu?an}_mCR@jt=(9u+eDFC^}cv>6HDzv1MDYS^Sz)LEpyQ-kpGY
zx1Z{`*8xvgR}@5ULRUfupf%q=a^@i26=&~7nM&)8(`0&tpY7G0e1KJpK?iq4onJx9
zqg}V=*9zYmI`4ZD4+!D@P%1iDVJrByAl7kCD)5^D;H0f&WjT;f867|>eBq}nh(EcU
zHrKp4EtE+m^_&Yb60RTlUGbM3(#P60`o7NnEsB({91N`30RV90kSo3}$sLCfvw4`d
z4dxorN{5U;%^48H;dvH}IpCq>4C%`=t^KI56BPq6JWg$&5;2{1OF`iyuyC2KhB5{7
za*cJ_f1;cv9yY;O@nU-$b2?%Ed%%P=dY>kPG+N7ZAT~Y0J$N=6uhxwwT!w?V&9ZsS
zRbY;cBsMi~og<B6uW~N3I!y?IdH=8{+jQx0@SX#@3D@PhgE2|}3fr&RgDVq8S>6aj
z_!2+RV9CKM9=V!Eudw6TZlv9P29Y0Pe2>AC?+xls{c9e7Wd+t{gu2$~KA)j@4&6-(
zO~#vgNu{N!ym)yO%(A0NOP$qR<S~mprV)QS)bb;Ym0D&fj`4Yr_{MBPAYinsZoh<+
z2zY8ulZ{c$FeO`h`L53!r7<moCb0opkRoy3S;Ep#agR#*Sx_`!DxbFwM_IPZruQ>(
z6hG{s^_^~evJ$PJ+g<Msqc{TZ2A-(s+}3#p%G`TydHHfJIZgA@yISCp(Q2_Q*6=K)
zL0nShL0sK!_}@mN64WhVmR`=RiAmtQv14=l$d#QJkvXNavJpnlPKL2H&H_*8!S8{1
zU!(T+=vSjJM(`ry`cgEP+^YgNh3e0Lt24`e=NQ{t1<-8QSs8?)e$e|pskmRaR>VV|
z!TnA_OYrTi*kK=R&|sdjoEvaZtLNHEk%;lqJ4(W*|LfC8Baa0GDry;DSTRo7aF_MY
z^3$uBg`5|!S`3(<t_c=8=(r{cqVvI2vYNuaXg6R5cCPmDp4}y=)-8~zuU@Yphvp<=
zL2-`8NX}p@b0ux`S)6n1PTQt!TbTqux%&kM32Ehq7h?UTW_6MsLlc4>+DjA2@1mx6
zS~q65lH(^!Bmps;k2uS{W~_b#9*DB6)xSrXo6-tn{pIs>2AyhD!Ye{Z3u4Um)d59M
zyGHa!)vnl%O}xTn;OFQca<c{ZN+kT^TIqIsGN$jgsV75)ILNs-fAT}OY99b&nLjQB
zVT^8mL0b{C=O`1`jcszn9a|j|yT2XVrb3(I@q<SB=)EZ0P`(0i7;+4Yit1KWd)O%7
zxGAZj(R>PdSw@omfLg(N$)@U%BEjO}k<*r{;fs8hx>tO1B+Le66p{JLl27IoM3J(D
z?%>;M+V=3d;!rL(pTel0ch$c<$%sIGXq|D%<;O2oBQ4`7K6NtaQl^%AC?wJ`5r<?*
zy9cRXdzOqOm=l_n*<1`RS9aXBNE<WGQc8?ybQoPv@-`x|nYPSH+Km)0P#AxqLZxw%
zAtz%^^w4h0%-yz!EY)+dou5Q81PL`1Hw5{+5Y@m}<*r0~=FL$1iacc`S~qpl=kY`2
zWomj{k{Oif=jw$8Vv{X?FDJ6NO&?bW$Ul<2T*_u9eshFOhNTswDg|x<<!C-=9!%u{
z^Q${er`Xn{+C>1D@1}xwB$g?J$t=G=xmT?oKzs2yM^iXbPsG&NcFg)@WJ+o1fG#?M
zB{WVYH*6gKhp|YjTvhfIWgl5<T8}aT%UP>e0f&$D=>)hfD9TD3H-<0zxmb)g9ihk0
z)}nOe$ZL#C`<!;|UaVtrrX#q2{UuFR+39GsMOi#kRH*B@<?`_JY-L5Xe$!zcNgM8!
z>{FcFVT>!@^~W4`XR^Ni9c1??1NHgGHC|(h#%Q!d;<}5P-qZlRGrTT+OF-k_QW|4S
z(-$PQ>qB;`GVUAmnAxiqg^_6VrCt?C?0<`vzY`^|s>*<lz22A{I_MN#z8&W6NijGT
znUId^a)4uH;l&G5XUZ`&GyrXo4qAkrbgLYUto2QcU_RW{IpHP+^~y+Lf*v#%WS>#E
z(||V6jMd$pSEriJ-<w+5O@1WuP)%<Xw`II2*|Dxqirwj*eE)MV+nrZ~R_suM@d(|k
zAJST$Xew$zk2!iwkQqf2_483b@Uy<}Bcs$8=sWYS!@YVGJHwb#XN>utXUm@|Ln_*Y
z`CAB$nL89dykv=Oj-2h$+I6~6XH*L4*}}Ty@>+{^NqDRr7c#u>LdvF}g?{J5J}V%i
zwmXJKiwq|zi|AVsJ}~8n;rB;Edm`mJJB*YBxk#M*2Q?M#?8Gz1tOrRYc~&#geZkt_
zT4@XoB@4H_I7;~}I`aazs6gql_3?yCO~Qo61`RGn4yst~<MB+E=vJn~{mgs6`R3Sw
zZ?i2%EtbN{d?GaKkmHo@92AmZOMH@9(?Wl7#YbEFj3BDWzm#god{zen)UPkVY}}9)
zmQz)zrn%D-EzV;DCTyvux>wUdkh0MU!sjUqN>c&hCQL#*bj_kyoGz<(chi-S(`K@*
zRLn~R-Ksy8eFFH=;-5F8<h~mP2P8aemTF9tn7F#y0=t=mt2)WNy(LhYYLIbhO+7*W
z&3%*uNiLfv3ghqc9tStK`H693fz&FIbY^sau+1Nic!Q(SU{?gGngnf|72l>@wn&Kk
z?B1)p>t~l&(>N59q-D{0vtt8rNfd}WW<42ciRX#{FUGWd8T!$x3gcGX*Bc-vGitx~
zkiJNKt41~Udw5}&0^4_pKmG=eC`r*Z3{J&IPmy9Icqp-*7RsLp18142ufI=5GWZ@n
z?5F_!*fgeFyKK1){dkA#RY}zWH~M{Kfl(OnH5baE?HSa|iJo4TQRpbX4+u>VSbQX5
zraw2Nc8r`hhe;Id<~1emw3lBUX#9$A@v35r_&jPcum=;QIETA&hkYj^d4Iu1E4UCA
zNfSp<iOLTafX6T-vp!jFL#ayKl;1=<)+8-Z3V1_$BH@m8V!rm|vm-=2W3Ptu9rjTN
z-?+8xMXmGmbB6t$x@Y`FY*JVec;`RCtquU&XYsGAQ$EbBL7sjzeWZSwYN<2Xfv3H{
zBtH*frD}$p3Occ{d?rI*BqB_~JHuww%ik{O*)LLxDabo+w9ud9iU6<+N{NQAX`YQs
zW?@1dGwJR(8!br?uVTjvtt*16*G^8JTiFq=?uCC5<QwbkTpz63wk9;!t4WOGSBjVt
zi4f<f9%WQcd_Ys>mSFfqa;10Np-zVitQeSiJWe7SBNTHQ;hT<1okj60iuOM9Ku=#)
zPNZzZyE-2Nuk@Gfn9@+PdW*pn1J#SC<GCjj4$3@SUn&Iv+f5ZRS8Mil{!fgCuil1K
z!%WA>XRNZtT6BSP+7NqO%k1GWqQe+A+7q&S)N`HpEk39_`M@>}SyRVfrmo6e!SYc8
zBnL*AjIH|>N|GOtzGl{N5!%e<Ru*l&#2%UImSb6mh1LYnY{yum4fRJ>!Ms@Hl1+JS
z4`2E<7UR~3+kMfPogM-OL8U%N8@67WnWu!hD{XPlv4(!F>1iU{5=iD`olh5pX!BmN
z&>0(sH=$!qe#j>QnwOUqKW*p`Rbt{g-n|+u_5a$VJzyMj21{_P3i6HPovsEZYtzhy
z1G-+I5=OBlMVY|xpl{HvO0n3;x5?G1G6oIX$V)#c^unCKpKg;^K&XdZnvNUSpg^kb
zkc>zQcS_g9j!r(GH@&BELKmM}PSo?*NuF}Uh(-j4n>lp~eFMKbz4|_-{5`<5v}hyq
zsbk@RmuO9{SzP@1!N>AT%4c93=;L^UvE)%8`5c>BpNxrX?UfCSa=FT^=+-MqF2_>&
zY$-FM2zerhWY2Y;@4}l5mRM(RI}=nIqhmK32pl>Nx?Ln80`A2+LUj)ZALR5`ZfP(T
zr{%ALToz$(<YHZp-Wb1!J1gCDS+SPG@n_Yd-;9i%7Brr&<?|Q`U69H9H({H?Xb(7*
zk^=|kkAB;-CK-!YxsG%(`y5ThDeOY>3n=hF9Ug-FNBaput_>Du)F7UT)ztYM{5218
z<COHJQZlLY=IwoJbN5Nnx`k7X<CdtF=IpNXFdkIRfgwE9Sjh#Vj{SL44QOS*-FEJj
zrTfS87KKppaWxz6)N>-&_6K+C61lt8>e7IUi=6~gi?MV*2S1JHGF)ue8$>{(bh#fT
zr$XJtDCUG-nALPR*QqBhAFL*mOwNP_dPfB0()aVz$hU-MW>2P_F=3glvGn6{Lu%eW
zi^$6)zOq!>+|!eH;!oX#XND-Vtl)$95=(!o5v_)m=y}_pCq1-Zk<I&J*sk~<vRwOQ
zD;yh_;4u34u<`>Xa@l7?dv)mLF4YcVQpFza-(z3()e7g~em<z9R~X@D%9i_4d?W<O
zTYGxn5oafMZH`t#{DL4|l;Rsdp-9J?gUQ4bYZ!9%!!#j+^CV$#$khV(j=a4&XR>x%
ztY>vTsB*{d#L+d2W`S~2-5);-9`1H69KEDXdE8_0g*puxE*rrubBdd9!QE_JT+Qrl
zJk7xW@?c%H)ZWZ+<3RCyeF-Sm8M$#cs1qG*zF15HpL_?h$|zM3-|N8p)%o&bi~ZY%
zeL@Z%+LWiyuF?VWj;=K7oc)UcTZtKBJjdexHLA1XS8_$aOdpRo-<y_KyM!V82$P~v
zSX-Vg%igD%k%yqBmsaA=3}yGCT-u_ZQ-wi-j6L?Ck#zyV(zsc!{-V<Om`l{2dgNs2
zp~mmAsfp2Yi^7(CCshkxbl7)0hD%SA34psbsS1-@L?7_6TJ=c>vktM^YXKT)2P?|I
zrpZ!I?fK|W5Q_}FcE#PL^U~Kl(A8z`0#0Yu##ALn1}P0OP$|wTd{XTk%1DDASQwdr
zMqTN)lc9T7Q^$TQ-$rzuU_GALMGWz|&~+t|enT9$;m|j2r4!?q4UkmT)Z<GU>`%5l
z2S_u|nKjO~J<6(U0!4jre#$CuE{14VWmfTpOwV~@883zFKH8FBvJ#arHlo$oSWcWD
zZ^0*j<Pe~TtIrbK@J<uMAAD58s_C=*#=^Pv;46{(#e4mSgXX`G$Mv`sSYMqJTWPO~
zv=DpuzG=EHsvW$j@H+lGB9QuKQ5`J6&NeUp*Qh}2`zepx4?da0Qv#7T;QPJXj<v7{
z!NmxpD4Dwf+$3_RBHuU;$HwabM`*A0S!{j+UNbK|jP<;vXDLdB;j|@F<jym-tgv!$
z6LPYQ9TJa62u3rPMs+Dt&TP>Z-7B64?(I)V(f9Ov2Nlbz=;xG#&G|bl(hBiczU*Gr
zB6(WxC`fNPq(HC`xI{8WGnB}jQdZN1r(E$ZJi=r6GLE!T{t`VC|N89p;Aekx(FE0P
zXMk8dfml3&SUmB6Up(;yev{p_r)X}w$q*J5!lFW0R0xX-VNoG0DuhLau&59g6~dxI
zSX2m$3Sm(pEGmRWg|Mg)78SyxLReG?iwa>;AuK9{MTM}a5Ed1}qC!|y2#X3~Q6Vg<
z|5p~38N9#dl9@A?4cww~hBxM9yzw?1z{AN6-*|XA&23!30GpSVATBj|9T_<p9T^AB
zX?Soaj`xKA9)|rxyb=s#D!mG6p+c9}%&;_@WY^Gj!LXgpru0!)zz0$k#)Z8-YU9SZ
z`Ow#6_~BvDk->4hv5!o+>w_F&ah_pCTe^~4dOxh}csRdMV+yA@(vxraN8t0zHZ}XB
z(`;i%Vb^2rcn7w{&I>AVMVNt6^SEZUNS*V8vlJEUY?u?4W+novBT0gE(7x+V3ljBc
zGljA612&&0WJO;n9rtcaTc<CPJ~7W)D4JZ$%lIY_+mq&8xm#Q>R>Q17h`YTyyN5Ku
z1DPCUujFH?#V%MVz8rV(b=w>^Rem)PUoa^zC0|iBIhT>V%1e;C&!oT54LS^N!kt>r
zo4k4(Xm4hJx;GX{!eXL63b^_pqLu&4*81$oN!$0aetdAJ%z<9M$}XdJK^u`XhHUik
zGA!lM?`deRi4zg-%PNUR)Zi6rRn#WzGy^su`R_ROpAft!@um&rJMS)pICFm8h<*7-
zsUBJ3=b8PZMDU&NZ%U=FC@-&yJ)o%8H-xJKVC(N4DA(d1<(pq|*633KD06gim1!v|
zcX4orabd7(4RR0i2@dfMFR$F~9^e`}<`~Ci0Vwx%sg`N6u(GMGtlU*nt=3}s%s<}O
zGoUi2)?2W=vbcis$N0|B@kp@Y<HCaPtba2;Fv!uw-onkoo)ZiKtMsb$=5h3Mto}*V
z*K%CbgkPAsXh=x(e?!!g2Wn`^6%E%WWIiUiGvAPoZr`vigW<=I5?;po*0DGoGL^{w
zKtoExe?)ayGhLbOLj6h?T_s6MY!s?M$VM2IDSyRSCx*sx+Oo$!R;+CXsE>&dhYG(f
z{P-1L%&qKoWmTmUj=;r^q@?$2&j7BCvEJ-RoWps8h*ilN6*n&Y7XGK;&GDdTG8TZ^
zwwn6G2bj{bgVa!xrb<SI#6lFlh!1#F<|1rU6Ll5>YN1C(IU`uEAvk-CL8aC+Rl&KI
zBr>SB=MI%l!|g^P`OfV@7)VZ$YI8sGLVU>mVn;FV_!|4O8|20BOhGGv^jmeJbVzRP
zW`Sn!J4#Yr7X51AErFzdv~x6Mgaavlt13PT(taEK(HVXJQ+q{1*6&E=ftnLScZ%-A
z_k!)-%}S*nvy@oP_lEG**Q9f`TxfEF^^%&!OHY=i61Fzk*|~aiw=_@vL_R$DB?VfE
znQ@y?F;sYbKoz3P%I;;F|HNZDgjEhbGe_*X84MGRtAFR|*Bbf6xu5Zg<ZEL%adk#I
zZssM!<jhZX@96Y0h#k8v>?~Tedo&y1IgD!nnFviAo9~?_a~<;fo(eBJ%Xp6waTI@U
zV`Kx3UFscYzgt$~f_?#kx7-yboFCEY$<hj1=@JVT-$OS-j^Ow#+U6z*O(mqB_o;}s
z(}gw6$N7G+@2~!%%Xf#B%?;D5ue`Uk(7Y|o&Utqg<}WEwr4jlwnzMM5CHhj>WS;Q%
z;l~0DUI}aQ=><1x&N7XnNa;8|5x_;XTaO=Kt#e`E7}mbRtmeDaa{AC}xO0k(Lh{dU
z#kcn`hF_Kc{8ah><Lj@c#5X${-z41D(fD7-BOz7!^WP-=g@PN4Hwm|8D_;|~;hmEI
zI*{vH7Q6|#EkE`epu}(k@E>WiHyO9({arI)@SFeNgZPj1znhHPf~>9?id;7tH)5@B
zB5t#QuMz6%HxPe1!8b9td8gMH2Dp>@@3XnZLcK}4%|g8<ncPPDmy>!Ea+?Tx4WZM#
zWjME2`Zn3^8WgN^3+Sf$c5_U(Jt<tH;$5y$|LwWqPvV~w+BH$i^}iGUIlcXf`*Z%e
x#?Ac=?muRuKe2yKLVsZ^ka^tx`zZf4B|TO_hetIdA>qR}S@=ZO3i-#c{{a=he?b5M

literal 0
HcmV?d00001

diff --git a/analysis-master/analysis-amd64/dist/analysis-1.0.0.12.tar.gz b/analysis-master/analysis-amd64/dist/analysis-1.0.0.12.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..1ba274315415d3096304b963298c369f7d3b44c2
GIT binary patch
literal 21001
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

literal 0
HcmV?d00001

diff --git a/analysis-master/analysis-amd64/setup.py b/analysis-master/analysis-amd64/setup.py
index 89a9bdf6..f290c88d 100644
--- a/analysis-master/analysis-amd64/setup.py
+++ b/analysis-master/analysis-amd64/setup.py
@@ -8,7 +8,7 @@ with open("requirements.txt", 'r') as file:
 
 setuptools.setup(
     name="analysis",
-    version="1.0.0.011",
+    version="1.0.0.012",
     author="The Titan Scouting Team",
     author_email="titanscout2022@gmail.com",
     description="analysis package developed by Titan Scouting for The Red Alliance",