diff --git a/AngularApp/prototype/src/app/api.service.ts b/AngularApp/prototype/src/app/api.service.ts
index 40e84b6b529c5ed59765c1ac5acee58856ba4104..9b23e33d4dd0a60e37a46dac73ab03b314525498 100644
--- a/AngularApp/prototype/src/app/api.service.ts
+++ b/AngularApp/prototype/src/app/api.service.ts
@@ -1,43 +1,62 @@
 import { Injectable } from '@angular/core';
 
 export interface RawData {
-  index: string[];
-  values: number[];
+  index: string[][];
+  values: number[][];
 }
 
 export interface LshData {
-  candidates: number[];
-  distances: number[];
-  hash_functions: number[];// number[][][][];
+  candidates: number[][][];
+  distances: number[][][];
+  average_candidates: number[];
+  average_distances: number[];
+  tables: {[bucket: string]: number[]}[];
+  average_table: {[bucket: string]: number[]};
+  samples: number[];
+  hash_functions: number[][];
   parameters?: number[];
 }
 
 export interface TableInfoData {
   prototypes: {
-    average: number[];
-    min: number[];
-    max: number[];
+    average: number[][];
+    min: number[][];
+    max: number[][];
   }[];
   distances: number[][];
 }
 
+export interface Parameters {
+  windowsize: number;
+  hashsize: number;
+  tablesize: number;
+  stepsize: number;
+}
+
 @Injectable({
   providedIn: 'root'
 })
+/**
+ * This service acts as the interface between the client and server side.
+ */
 export class ApiService {
 
   constructor() { }
 
-  // Read input data
-  async readFile(): Promise<RawData> {
+  /**
+   * Read input data. The format is a list of channels, where each channel is an object of type RawData
+   */
+  async readFile(): Promise<RawData[]> {
     const response = await fetch('http://127.0.0.1:5000/read-data');
     return await response.json();
   }
 
-  // Split data into windows and normalize
-  async createWindows(parameters): Promise<any> {
+  /**
+   * Split the data into windows (server side)
+   */
+  async createWindows(parameters: Parameters): Promise<any> {
     const postData = {parameters};
-    const response = await fetch('http://127.0.0.1:5000/create-windows', {
+    await fetch('http://127.0.0.1:5000/create-windows', {
       method: 'POST',
       headers: {
         'Accept': 'application/json',
@@ -47,8 +66,25 @@ export class ApiService {
     });
   }
 
-  // Calculate parameters for LSH + find candidates using LSH
-  async lshInitial(query): Promise<LshData> {
+  /**
+   * Get weights which will be applied to the LSH hash functions
+   */
+  async getWeights(query: number[][], labels: {[index: number]: boolean}, weights: number[], hash_functions: number[][]): Promise<number[]> {
+    const response = await fetch('http://127.0.0.1:5000/weights', {
+      method: 'POST',
+      headers: {
+        'Accept': 'application/json',
+        'Content-Type': 'application/json'
+      },
+      body: new Blob( [ JSON.stringify({query, labels, weights, hash_functions}) ], { type: 'text/plain' } )
+    });
+    return await response.json();
+  }
+
+  /**
+   * Do the first iteration of LSH and return important information
+   */
+  async lshInitial(query: number[][]): Promise<LshData> {
     const response = await fetch('http://127.0.0.1:5000/initialize', {
       method: 'POST',
       headers: {
@@ -60,7 +96,9 @@ export class ApiService {
     return await response.json();
   }
 
-  // Find candidates using LSH with weights
+  /**
+   * Do another iteration of LSH, with weights, and return important information
+   */
   async lshUpdate(query, weights, parameters): Promise<LshData> {
     const response = await fetch('http://127.0.0.1:5000/update', {
       method: 'POST',
@@ -73,21 +111,25 @@ export class ApiService {
     return await response.json();
   }
 
-  // Get query window based on windows labeled correct
-  async getQueryWindow(window): Promise<number[]> {
+  /**
+   * Get query window based on windows labeled correct
+   */
+  async getQueryWindow(indices: number | {[index: number]: boolean}): Promise<number[][]> {
     const response = await fetch('http://127.0.0.1:5000/query', {
       method: 'POST',
       headers: {
         'Accept': 'application/json',
         'Content-Type': 'application/json'
       },
-      body: JSON.stringify({window})
+      body: JSON.stringify({indices})
     });
     return await response.json();
   }
 
-  // Get data of a window by indices
-  async getWindowByIndices(indices: number[]): Promise<number[][]> {
+  /**
+   * Get data of a window by indices
+   */
+  async getWindowByIndices(indices: number[]): Promise<number[][][]> {
     const response = await fetch('http://127.0.0.1:5000/window', {
       method: 'POST',
       headers: {
@@ -99,14 +141,17 @@ export class ApiService {
     return await response.json();
   }
 
-  async getTableInfo(windows): Promise<TableInfoData> {
+  /**
+   * Get additional information for a given table
+   */
+  async getTableInfo(table: number[][]): Promise<TableInfoData> {
     const response = await fetch('http://127.0.0.1:5000/table-info', {
       method: 'POST',
       headers: {
         'Accept': 'application/json',
         'Content-Type': 'application/json'
       },
-      body: JSON.stringify({windows})
+      body: JSON.stringify({table})
     });
     return await response.json();
   }
diff --git a/AngularApp/prototype/src/app/app.module.ts b/AngularApp/prototype/src/app/app.module.ts
index 134f905489e7836b15f76faad55f9d40f3ab5b7f..294abb79034a4272a7eed68303cbc142d6b9a88a 100644
--- a/AngularApp/prototype/src/app/app.module.ts
+++ b/AngularApp/prototype/src/app/app.module.ts
@@ -19,6 +19,7 @@ import { ProgressViewComponent } from './progress-view/progress-view.component';
 import { MainComponent } from './main/main.component';
 import { MatProgressBarModule} from '@angular/material/progress-bar';
 import {MatSliderModule} from '@angular/material/slider';
+import { TrainingWindowComponent } from './training-window/training-window.component';
 
 PlotlyModule.plotlyjs = PlotlyJS;
 
@@ -33,6 +34,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
     QueryWindowComponent,
     ProgressViewComponent,
     MainComponent,
+    TrainingWindowComponent,
   ],
   imports: [
     BrowserModule,
diff --git a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.css b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.css
index a896b1b65a85421361a116a326469b0f7876442a..59f8b2d6552484daf1950cd72845d436898c1877 100644
--- a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.css
+++ b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.css
@@ -2,11 +2,12 @@
   margin-right: 20px;
   display: flex;
   justify-content: center;
+  border-right: 1px solid;
+  border-bottom: 1px solid;
 }
 
 .subplot-container {
   display: flex;
-  flex-wrap: wrap;
   overflow-x: scroll;
   width: 95%;
 }
diff --git a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.html b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.html
index 2bca5baec00c8f58b8c54943c2ac36ffeb2107e7..40023ddd31108be63dae3cf560b8585d42a0415b 100644
--- a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.html
+++ b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.html
@@ -1,5 +1,5 @@
 <div class="container">
-  <div *ngIf="show" class="subplot-container">
+  <div class="subplot-container">
     <div class="subplot" *ngFor="let subplot of subplots">
       <plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
       <div class="button-holder">
@@ -9,10 +9,6 @@
       </div>
     </div>
   </div>
-  <div class="button-holder">
-<!--    <button *ngIf="show" (click)="updateQuery()" class="train-button">Query</button>-->
-    <button *ngIf="show" (click)="train()" class="train-button">Train</button>
-  </div>
 </div>
 
 
diff --git a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.ts b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.ts
index cda0355db26432c5a07eedf1dc1ab62fb3eb6131..6f030292af52664f2b0abc31425da03577a99da2 100644
--- a/AngularApp/prototype/src/app/labeling-window/labeling-window.component.ts
+++ b/AngularApp/prototype/src/app/labeling-window/labeling-window.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {StateService} from '../state.service';
 
 @Component({
@@ -10,86 +10,97 @@ export class LabelingWindowComponent implements OnInit {
   public topk: number[];
   public subplots = [];
   public labels: boolean[] = [];
-  private k = 12;
+  private k = 5;
+  @Output() labelsOutput = new EventEmitter<boolean[]>();
 
   constructor(private state: StateService) { }
 
   ngOnInit(): void {
-    this.state.onNewTable.subscribe(() => this.showSamples());
-  }
-
-  async train() {
-    this.state.labels = Object.assign({}, this.state.labels, this.labels);
-    await this.state.getQueryWindow(this.state.labels);
-    await this.state.update();
-  }
-
-  async updateQuery() {
-    this.state.labels = Object.assign({}, this.state.labels, this.labels);
-    await this.state.getQueryWindow(this.state.labels);
+    this.state.onNewLshData.subscribe(() => this.showSamples());
   }
 
   public labelCorrect(index: number) {
     this.labels[index] = true;
+    this.labelsOutput.emit(this.labels);
   }
 
   public labelUndefined(index: number) {
     if (this.labels[index] !== undefined) {
       delete this.labels[index];
+      this.labelsOutput.emit(this.labels);
     }
   }
 
   public labelIncorrect(index: number) {
     this.labels[index] = false;
+    this.labelsOutput.emit(this.labels);
   }
 
   async showSamples() {
-    this.topk = this.state.lshData.candidates
-      .filter((candidate) => this.state.labels[candidate] !== true)
-      .slice(0, this.k);
+    this.labels = [];
+    this.topk = this.state.lshData.samples;
+
     this.subplots = [];
-    const values = await this.state.getWindow(this.topk);
-    this.topk.forEach((index, i) => {
-      this.subplots.push(
-        {
-          index,
-          data: [{
-            x: [...Array(values[i].length).keys()],
-            y: values[i],
-            type: 'line'
-          }],
-          layout: {
-            title: `Index: ${index.toString()}`,
-            hovermode: 'closest',
-            autosize: true,
-            margin: {
-              l: 30,
-              r: 30,
-              t: 30,
-              b: 0,
-              pad: 4
-            },
-            height: 150,
-            width: 300,
-            titlefont: {
-              size: 9
-            },
-            xaxis: {
-              showgrid: false,
-              zeroline: false,
-              showticklabels: false,
-            },
-            yaxis: {
-              zeroline: false,
-              showticklabels: false,
-            }
+    const values: number[][][] = await this.state.getWindow(this.topk);
+    for (const idx in this.topk) {
+      const window = values[idx];
+      const data = [];
+      window.forEach((channel: number[], index: number) => {
+        data.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          type: 'line',
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
+        });
+      });
+      const subplots = [];
+      window.forEach((channel: number[], index: number) => {
+        subplots.push([`xy${index + 2}`]);
+      });
+      const plot = {
+        index: this.topk[idx],
+        data: data,
+        layout: {
+          grid: {
+            rows: this.state.queryWindow.length,
+            columns: 1,
+            subplots: subplots,
+          },
+          showlegend: false,
+          title: `Index: ${this.topk[idx].toString()}`,
+          hovermode: 'closest',
+          autosize: true,
+          margin: {
+            l: 30,
+            r: 30,
+            t: 30,
+            b: 0,
+            pad: 4
+          },
+          height: 100 * values[0].length,
+          width: 300,
+          titlefont: {
+            size: 9
+          },
+          xaxis: {
+            showgrid: false,
+            zeroline: false,
+            showticklabels: false,
+          },
+          yaxis: {
+            zeroline: false,
+            showticklabels: false,
           }
         }
-      );
-    });
-  }
-
-  public get show() {
-    return !!this.state.lshData;
+      };
+      window.forEach((channel: number[], index: number) => {
+        plot.layout[`yaxis${index + 2}`] = {
+          zeroline: false,
+          showticklabels: false,
+        };
+      });
+      this.subplots.push(plot);
+    }
   }
 }
diff --git a/AngularApp/prototype/src/app/labels/labels.component.ts b/AngularApp/prototype/src/app/labels/labels.component.ts
index d1767fadc41539895451585a83832d720aee89da..7788885e43b9f0dc9d0f6c49b5da72df0f7fc73d 100644
--- a/AngularApp/prototype/src/app/labels/labels.component.ts
+++ b/AngularApp/prototype/src/app/labels/labels.component.ts
@@ -20,7 +20,7 @@ export class LabelsComponent implements OnInit {
   async createSubplots() {
     this.goodLabels = [];
     this.badLabels = [];
-    const labelWindows: number[][] = await this.state.getWindow(Object.keys(this.state.labels).map(Number));
+    const labelWindows: number[][][] = await this.state.getWindow(Object.keys(this.state.labels).map(Number));
     Object.keys(this.state.labels).forEach((key, i) => {
       const index = Number(key);
       const plot =
diff --git a/AngularApp/prototype/src/app/main/main.component.html b/AngularApp/prototype/src/app/main/main.component.html
index 1c08fca09cc7b3679c34d0a793a428297a9caf8b..b70cc68786f2a38811755bd08dd93239a897819b 100644
--- a/AngularApp/prototype/src/app/main/main.component.html
+++ b/AngularApp/prototype/src/app/main/main.component.html
@@ -3,8 +3,7 @@
     <app-overview-window style="z-index: 10"></app-overview-window>
     <mat-tab-group animationDuration="0ms" (selectedTabChange)="changeTab($event)">
       <mat-tab label="Training">
-        <app-labeling-window></app-labeling-window>
-        <app-table-overview></app-table-overview>
+        <app-training-window></app-training-window>
       </mat-tab>
       <mat-tab label="Labeled data">
         <app-labels></app-labels>
diff --git a/AngularApp/prototype/src/app/overview-window/overview-window.component.html b/AngularApp/prototype/src/app/overview-window/overview-window.component.html
index 0804bef3c84a77c090c5056d7adcc6be524a9366..0b0f92c8304b7680fc17ed6a7bb2889285fb11ef 100644
--- a/AngularApp/prototype/src/app/overview-window/overview-window.component.html
+++ b/AngularApp/prototype/src/app/overview-window/overview-window.component.html
@@ -1 +1 @@
-<zingchart-angular [id]="id" [config]="config" (mousewheel)="zoom($event)" (click)="clicked($event)" [height]="150"></zingchart-angular>
+<zingchart-angular #chart [id]="id" [config]="config" (mousewheel)="zoom($event)" (click)="clicked($event)" [height]="300"></zingchart-angular>
diff --git a/AngularApp/prototype/src/app/overview-window/overview-window.component.ts b/AngularApp/prototype/src/app/overview-window/overview-window.component.ts
index 9e4fa626bd6e5a4bfe6612a567619fdedee80376..c086316e5976a89ff8c2f5a3fd3dc3f68964ff95 100644
--- a/AngularApp/prototype/src/app/overview-window/overview-window.component.ts
+++ b/AngularApp/prototype/src/app/overview-window/overview-window.component.ts
@@ -1,4 +1,4 @@
-import {Component, OnInit} from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
 import { StateService } from '../state.service';
 import zingchart from 'zingchart/es6';
 
@@ -8,12 +8,15 @@ import zingchart from 'zingchart/es6';
   styleUrls: ['./overview-window.component.css']
 })
 export class OverviewWindowComponent implements OnInit {
+  @ViewChild('chart') chart;
   public config;
+  public graphset = [];
   public id = 'overview';
   public markers = [];
   public series = [];
   public goodLabels = [];
   public badLabels = [];
+  public candidateLabels = [];
 
   public data;
   public layout;
@@ -23,98 +26,181 @@ export class OverviewWindowComponent implements OnInit {
 
   async ngOnInit(): Promise<void> {
     this.state.onNewData.subscribe(() => this.initializePlot());
-    this.state.onNewTable.subscribe(() => this.updatePlot());
+    // this.state.onNewTable.subscribe(() => this.updatePlot());
   }
 
   async initializePlot() {
     this.state.queryWindow = undefined;
     // this.debugClicked();
-    this.data = [];
-    for (let i = 0; i < this.state.rawData.values.length; i++) {
-      this.data.push([this.state.rawData.index[i], this.state.rawData.values[i]]);
-    }
-    this.series = [
-      {
-        type: 'line',
-        values: this.data,
-        text: 'Raw Values',
-        zIndex: 5,
-        marker: {
-          alpha: 0.0,
-          zIndex: 10
-        }
-      },
-      {
-        type: 'scatter',
-        values: [],
-        text: 'Good labels',
-        marker: {
-          backgroundColor: '#4caf50'
-        },
-        zIndex: 20,
-      },
-      {
-        type: 'scatter',
-        values: [],
-        text: 'Bad labels',
-        marker: {
-          backgroundColor: '#f44336'
-        },
-        zIndex: 20,
-      }];
-    this.config = {
-      type: 'mixed',
-      preview: {
-        height: '30px',
-        position: '0% 100%',
-        'auto-fit': true
-      },
-      plotarea: {
-        'margin-top': '10px',
-        'margin-bottom': '50%'
-      },
+    this.graphset.push({
+      id: 'preview',
+      type: "scatter",
+      x: 0,
+      y: 0,
       scaleX: {
         zooming: true,
+        minValue: 0,
+        maxValue: this.state.rawData[0].values.length,
         zoomTo: [0, this.state.windowSize],
         'auto-fit': true,
-        markers: this.markers
+        visible: false,
+        guide: {
+          visible: false
+        }
+      },
+      height: '30px',
+      scaleY: {
+        maxValue: 1,
+        minValue: -1,
+        visible: false,
+        guide: {
+          visible: false
+        }
       },
-      'scale-y': {
-        'auto-fit': true
+      preview: {
+        x: 50,
+        y: 10,
+        height: '30px',
       },
-      series: this.series
+      series: [
+        {
+          type: 'scatter',
+          values: [],
+          text: 'Good labels',
+          marker: {
+            backgroundColor: '#4caf50'
+          },
+          zIndex: 3,
+        },
+        {
+          type: 'scatter',
+          values: [],
+          text: 'Bad labels',
+          marker: {
+            backgroundColor: '#f44336'
+          },
+          zIndex: 2,
+        },
+        {
+          type: 'scatter',
+          values: [],
+          text: 'Candidates',
+          marker: {
+            backgroundColor: '#b1a343'
+          },
+          zIndex: 1,
+        }
+      ]
+    });
+    // Initialize channels
+    this.state.rawData.forEach((channel, index) => {
+      const data = [];
+      for (let i = 0; i < channel.values.length; i++) {
+        data.push([i, channel.values[i]]);
+      }
+      this.graphset.push({
+        id: index,
+        x: 0,
+        y: `${75 * index + 50}px`,
+        type: 'line',
+        height: '50px',
+        scaleX: {
+          zooming: true,
+          zoomTo: [0, this.state.windowSize],
+          markers: []
+        },
+        'scale-y': {
+          zooming: false,
+          'auto-fit': true
+        },
+        plotarea: {
+          height: '50px',
+          'margin-top': '0px',
+          'margin-bot': '0px'
+        },
+        series: [{
+          type: 'line',
+          values: data,
+          text: 'Raw Values',
+          zIndex: 5,
+          marker: {
+            alpha: 0.0,
+            zIndex: 10
+          }
+        }]
+      });
+    });
+    zingchart.bind('zingchart-ng-1', 'zoom', (e) => {
+      if (e.graphid !== `zingchart-ng-1-graph-preview`) {
+        return;
+      }
+      for (let i = 1; i < this.graphset.length; i ++) {
+        this.chart.zoomto({
+          graphid: i,
+          xmin: e.xmin,
+          xmax: e.xmax
+        });
+      }
+    });
+    this.config = {
+      layout: `${this.graphset.length}x1`,
+      graphset: this.graphset
     };
+    console.log(this.config);
+    console.log("showing plot");
+    await this.debugClicked();
   }
 
   async updatePlot() {
+    console.log('updating plot');
+    if (!this.state.queryWindow) {
+      return;
+    }
     this.goodLabels = [];
     this.badLabels = [];
     this.markers = [];
     for (const index in this.state.labels) {
       if (this.state.labels[index]) {
-        this.goodLabels.push([Number(index) * (12000 / 6), 0]);
+        this.goodLabels.push([Number(index), 0]);
         this.markers.push({
           type: 'area',
           // BUG: For some reason the range values are multiplied by 10
-          range: [Number(index) * (12000 / 6) / 10, (Number(index) * (12000 / 6) + this.state.windowSize) / 10],
-          backgroundColor: '#4caf50',
+          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
+          backgroundColor: "#4caf50",
         });
       } else {
-        this.badLabels.push([Number(index) * (12000 / 6), 0]);
+        this.badLabels.push([Number(index), -1]);
         this.markers.push({
           type: 'area',
           // BUG: For some reason the range values are multiplied by 10
-          range: [Number(index) * (12000 / 6) / 10, (Number(index) * (12000 / 6) + this.state.windowSize) / 10],
-          backgroundColor: '#f44336',
+          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
+          backgroundColor: "#f44336",
         });
       }
     }
-    this.series[1].values = this.goodLabels;
-    this.series[2].values = this.badLabels;
-    this.config.scaleX.markers = this.markers;
-    zingchart.exec('zingchart-ng-1', 'setdata', {
+    for (const index of this.state.lshData.average_candidates.slice(0, 100)) {
+      this.candidateLabels.push([Number(index), 0]);
+      this.markers.push({
+        type: 'area',
+        // BUG: For some reason the range values are multiplied by 10
+        range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
+        backgroundColor: '#b1a343',
+      });
+    }
+    console.log(this.markers);
+    for (const channel of this.config.graphset) {
+      if (channel.type === 'line') {
+        channel.scaleX.markers = this.markers;
+      } else {
+        channel.series[0].values = this.goodLabels;
+        channel.series[1].values = this.badLabels;
+        channel.series[2].values = this.candidateLabels;
+      }
+    }
+    this.chart.setdata({
       data: this.config
     });
+
   }
 
   async updateCandidates(sliderIndex) {
@@ -170,9 +256,12 @@ export class OverviewWindowComponent implements OnInit {
   }
 
   async debugClicked() {
-    const index = 80503;
+    const index = 6713;
     await this.state.getQueryWindow(index);
     await this.state.lshInitial();
+    const temp = {};
+    temp[index] = true;
+    this.state.labels = temp;
   }
 
   zoom(p) {
diff --git a/AngularApp/prototype/src/app/progress-view/progress-view.component.css b/AngularApp/prototype/src/app/progress-view/progress-view.component.css
index a633d3984a1a71cf5248bb857c510425c7897d12..8a385fa99584c21721eb6106a1fac3bb2a9c1bbf 100644
--- a/AngularApp/prototype/src/app/progress-view/progress-view.component.css
+++ b/AngularApp/prototype/src/app/progress-view/progress-view.component.css
@@ -27,5 +27,14 @@
   justify-content: center;
 }
 
+.slider {
+  display: flex;
+  justify-content: center;
+}
+
+mat-slider {
+  width: 400px;
+}
+
 line { stroke: #5e4646; }
 circle { stroke: #fff; stroke-width: 1.5px; }
diff --git a/AngularApp/prototype/src/app/progress-view/progress-view.component.html b/AngularApp/prototype/src/app/progress-view/progress-view.component.html
index 77667304f4252234cb19ae7719ca80b4a65bdae6..02c36963f40c80674539abea0b1f6868eb971228 100644
--- a/AngularApp/prototype/src/app/progress-view/progress-view.component.html
+++ b/AngularApp/prototype/src/app/progress-view/progress-view.component.html
@@ -1,11 +1,18 @@
-<svg id="visual" width='500' height='300'></svg>
+<!--<svg id="visual" width='500' height='300'></svg>-->
+<div *ngIf="data" class="histogram">
+  <div class="container">
+    <plotly-plot (hover)="onHover($event)" [data]="hist.data" [layout]="hist.layout"></plotly-plot>
+  </div>
+  <div class="slider">
+    <mat-slider [min]="0" [max]="maxLength" step="1" [value]="sliderValue" (input)="setSliderValue($event)" thumbLabel tickInterval="5"></mat-slider>
+  </div>
+</div>
 <div *ngIf="data" class="container">
   <div class="window">
     <div class="plots">
       <plotly-plot *ngFor="let data of this.data; index as i;" [class.hide]="i != sliderValue" [data]="data" [layout]="layout"></plotly-plot>
     </div>
   </div>
-  <mat-slider vertical min="0" [max]="maxLength" step="1" [(value)]="sliderValue" thumbLabel tickInterval="5"></mat-slider>
 </div>
 
 <script src='https://d3js.org/d3.v4.min.js'></script>
diff --git a/AngularApp/prototype/src/app/progress-view/progress-view.component.ts b/AngularApp/prototype/src/app/progress-view/progress-view.component.ts
index 5424b6ddec761d422bba933a639f831b5564259c..c379c9e575757414d791a7589be984ab6e096a2a 100644
--- a/AngularApp/prototype/src/app/progress-view/progress-view.component.ts
+++ b/AngularApp/prototype/src/app/progress-view/progress-view.component.ts
@@ -1,6 +1,7 @@
-import { Component, OnInit } from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
 import {StateService} from '../state.service';
 import * as d3 from 'd3';
+import {TableInfoData} from '../api.service';
 
 @Component({
   selector: 'app-progress-view',
@@ -8,9 +9,11 @@ import * as d3 from 'd3';
   styleUrls: ['./progress-view.component.css']
 })
 export class ProgressViewComponent implements OnInit {
+  @ViewChild('chart') chart;
   public plot;
   public data;
   public layout;
+  public hist;
   public amountOfCandidates;
   public hover = 0;
 
@@ -19,24 +22,67 @@ export class ProgressViewComponent implements OnInit {
   constructor(private state: StateService) { }
 
   ngOnInit(): void {
-    this.state.onNewTableInfo.subscribe(() => { this.showgraph(); });
+    this.state.onNewLshData.subscribe(() => {
+      this.showgraph();
+      this.showHistogram();
+    });
   }
 
-  hoverPlot(averages) {
-    this.data = averages.map((prototype) => {
-      return [
-        {
-          x: [...Array(prototype.average.length).keys()],
-          y: prototype.average,
-          type: 'line',
+  showHistogram() {
+    const table = this.state.lshData.average_table;
+    this.hist = {
+      data: [{
+        x: Object.keys(table),
+        y: Object.values(table).map((values: number[]) => values.length), // / (this.service.rawValues.length - this.service.windowSize)),
+        type: 'bar',
+        opacity: 0.5,
+        marker: {
+          color: Object.keys(table).map((key) => {
+            return this.getColor(Number(key) / Number(Object.keys(table)[Object.keys(table).length - 1]));
+          }),
           line: {
-            color: 'red',
-            width: 3
+            color: 'black',
+            width: 0,
           }
+        }
+      }],
+      layout: {
+        hovermode: 'closest',
+        autosize: true,
+        margin: {
+          l: 10,
+          r: 10,
+          t: 10,
+          b: 10,
+          pad: 4
         },
-        {
-          x: [...Array(prototype.average.length).keys()],
-          y: prototype.max,
+        xaxis: {
+          showticklabels: false
+        },
+        yaxis: {
+          showticklabels: false
+        },
+        height: 200,
+        width: 400,
+      }
+    };
+  }
+
+  onHover(data) {
+    console.log(data);
+    this.setSliderValue({value: data.points[0].x});
+  }
+
+  hoverPlot(averages) {
+    const subplots = [];
+    this.data = averages.map((prototype) => {
+      const channelData = [];
+      prototype.max.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
           type: 'scatter',
           fill: null,
           mode: 'lines',
@@ -44,10 +90,14 @@ export class ProgressViewComponent implements OnInit {
             color: 'rgb(55, 128, 191)',
             width: 3
           }
-        },
-        {
-          x: [...Array(prototype.average.length).keys()],
-          y: prototype.min,
+        });
+      });
+      prototype.min.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
           type: 'scatter',
           fill: 'tonexty',
           mode: 'lines',
@@ -55,10 +105,32 @@ export class ProgressViewComponent implements OnInit {
             color: 'rgb(55, 128, 191)',
             width: 3
           }
-        },
-      ];
+        });
+      });
+      prototype.average.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
+          type: 'line',
+          line: {
+            color: 'red',
+            width: 3
+          }
+        });
+      });
+      return channelData;
     });
+    for (let index = 0; index < this.state.queryWindow.length; index++) {
+      subplots.push([`xy${index + 2}`]);
+    }
     this.layout = {
+      grid: {
+        rows: this.state.queryWindow.length,
+        columns: 1,
+        subplots: subplots,
+      },
       showlegend: false,
       hovermode: 'closest',
       autosize: true,
@@ -77,15 +149,26 @@ export class ProgressViewComponent implements OnInit {
         zeroline: false,
         showticklabels: false,
       },
-      height: 300,
-      width: 300,
+      height: 350,
+      width: 400,
     };
+    this.state.queryWindow.forEach((channel: number[], index: number) => {
+      this.layout[`yaxis${index + 2}`] = {
+        zeroline: false,
+        showticklabels: false,
+      };
+    });
   }
 
-  public set sliderValue(v: number) {
-    this._sliderValue = v;
+  public setSliderValue(v) {
+    this._sliderValue = v.value;
     d3.selectAll('circle').transition().style('stroke', undefined);
-    d3.select('#node-' + v).transition().style('stroke', 'black').style('stroke-width', 20);
+    d3.select('#node-' + v.value).transition().style('stroke', 'black').style('stroke-width', 20);
+    const data = this.hist;
+    data.data[0].marker.line.width = Object.keys(this.state.lshData.average_table).map((key) => {
+      return Number(key) === v.value ? 4 : 0;
+    });
+    this.hist = data;
   }
 
   public get sliderValue(): number {
@@ -93,106 +176,19 @@ export class ProgressViewComponent implements OnInit {
   }
 
   public get maxLength(): number {
-    return Object.keys(this.table).length;
+    return Object.keys(this.table).length - 1;
 }
 
   public get table() {
-    return this.state.table;
+    return this.state.lshData.average_table;
   }
 
   async showgraph() {
-    const nodes = [];
-    const links = [];
-    const keys = Object.keys(this.table);
-    this.hoverPlot(this.state.tableInfo.prototypes);
-    const distances = this.state.tableInfo.distances;
-
-    for (const key in this.table) {
-      const size = this.table[key].length;
-      nodes.push({id: key, group: Number(key), size: size});
-    }
-    for (const key in this.table) {
-      for (const key2 in this.table) {
-        if (key === key2) {
-          continue;
-        }
-        links.push({source: key, target: key2, value: 0.001 * (100 - 5 * distances[keys.indexOf(key)][keys.indexOf(key2)])});
-      }
-    }
-    const graph = {nodes, links};
-
-    const svg = d3.select('#visual');
-    const width = +svg.attr('width');
-    const height = +svg.attr('height');
-
-    svg.selectAll('*').remove();
-
-    const simulation = d3.forceSimulation()
-      .force('link', d3.forceLink().id((d: any) => d.id))
-      .force('charge', d3.forceManyBody().strength(100)) // Gravity force
-      .force('collide', d3.forceCollide().radius(25).iterations(3)) // Repulsion force
-      .force('center', d3.forceCenter(width / 2, height / 2)); // Position force
-
-    const link = svg.append('g')
-      .selectAll('line')
-      .data(graph.links)
-      .enter().append('line')
-      .attr('stroke', 'grey')
-      .attr('stroke-width', (d: any) => d.value);
-
-    const node = svg.append('g')
-      .selectAll('circle')
-      .data(graph.nodes)
-      .enter().append('circle')
-      .attr('r', (d: any) => 5 * Math.log(d.size) / Math.log(10))
-      .attr('fill', (d: any) => this.getColor(d.group / graph.nodes.length))
-      .attr('id', (d: any) => 'node-' + d.group)
-      .on('mouseover', (d: any) => {this.sliderValue = d.group; })
-      .call(d3.drag()
-        .on('start', dragstarted)
-        .on('drag', dragged)
-        .on('end', dragended));
-
-    simulation
-      .nodes(graph.nodes as any)
-      .on('tick', ticked);
-
-    simulation.force<any>('link')
-      .links(graph.links);
-
-    function ticked() {
-      link
-        .attr('x1', (d: any) => d.source.x)
-        .attr('y1', (d: any) => d.source.y)
-        .attr('x2', (d: any) => d.target.x)
-        .attr('y2', (d: any) => d.target.y);
-
-      node
-        .attr('cx', (d: any) => d.x)
-        .attr('cy', (d: any) => d.y);
-    }
-
-    function dragstarted(d) {
-      if (!d3.event.active) {
-        simulation.alphaTarget(0.1).restart();
-      }
-      d.fx = d.x;
-      d.fy = d.y;
-    }
-
-    function dragged(d) {
-      d.fx = d3.event.x;
-      d.fy = d3.event.y;
-    }
-
-    function dragended(d) {
-      if (!d3.event.active) {
-        simulation.alphaTarget(0);
-      }
-      d.fx = null;
-      d.fy = null;
-    }
+    const tableInfo: TableInfoData = await this.state.getTableInfo(Object.values(this.state.lshData.average_table));
+    this.hoverPlot(tableInfo.prototypes);
+    const distances = tableInfo.distances;
   }
+
   getColor(value) {
     const hue=((1-value)*120).toString(10);
     return ["hsl(",hue,",100%,50%)"].join("");
diff --git a/AngularApp/prototype/src/app/query-window/query-window.component.ts b/AngularApp/prototype/src/app/query-window/query-window.component.ts
index c0f581cbe94cb5eeec6ae76ab8a893456c8497fc..7a24026ccabba901cf10bfd20d3f4ab28a0ded55 100644
--- a/AngularApp/prototype/src/app/query-window/query-window.component.ts
+++ b/AngularApp/prototype/src/app/query-window/query-window.component.ts
@@ -21,53 +21,59 @@ export class QueryWindowComponent implements OnInit {
   }
 
   initializePlot(): void {
-    const data = [{
-        x: [...Array(this.state.queryWindow.length).keys()],
-        y: this.state.queryWindow,
-        type: 'line'
-      }];
-    // if (this.service.distances.length !== 0) {
-    //   const max = this.service.queryWindow.map((num, idx) => {
-    //     return num + this.service.distances[idx];
-    //   });
-    //   const min = this.service.queryWindow.map((num, idx) => {
-    //     return num - this.service.distances[idx];
-    //   });
-    //   data.push({
-    //     x: [...Array(this.service.queryWindow.length).keys()],
-    //     y: this.service.distances,
-    //     type: 'bar'
-    //   });
-    // }
-    this.plot =
-      {
-        data,
-        layout: {
-          hovermode: 'closest',
-          autosize: true,
-          margin: {
-            l: 50,
-            r: 30,
-            t: 30,
-            b: 5,
-            pad: 4
-          },
-          height: 150,
-          width: 350,
-          titlefont: {
-            size: 9
-          },
-          xaxis: {
-            showgrid: false,
-            zeroline: false,
-            showticklabels: false,
-          },
-          yaxis: {
-            zeroline: false,
-            showticklabels: false,
-          }
+    const subplots = [];
+    const data = [];
+    this.state.queryWindow.forEach((channel: number[], index: number) => {
+      data.push({
+        x: [...Array(channel.length).keys()],
+        y: channel,
+        type: 'line',
+        xaxis: 'x',
+        yaxis: `y${index + 2}`,
+      });
+      subplots.push([`xy${index + 2}`]);
+    });
+    const plot = {
+      data: data,
+      layout: {
+        grid: {
+          rows: this.state.queryWindow.length,
+          columns: 1,
+          subplots: subplots,
+        },
+        showlegend: false,
+        hovermode: 'closest',
+        autosize: true,
+        margin: {
+          l: 30,
+          r: 30,
+          t: 30,
+          b: 0,
+          pad: 4
+        },
+        height: 100 * this.state.queryWindow.length,
+        width: 300,
+        titlefont: {
+          size: 9
+        },
+        xaxis: {
+          showgrid: false,
+          zeroline: false,
+          showticklabels: false,
+        },
+        yaxis: {
+          zeroline: false,
+          showticklabels: false,
         }
+      }
+    };
+    this.state.queryWindow.forEach((channel: number[], index: number) => {
+      plot.layout[`yaxis${index + 2}`] = {
+        zeroline: false,
+        showticklabels: false,
       };
+    });
+    this.plot = plot;
   }
 
   get isQuerySet(): boolean {
diff --git a/AngularApp/prototype/src/app/state.service.ts b/AngularApp/prototype/src/app/state.service.ts
index ad38eed9b6b415c963f322556498b947f6a065f5..4745c9eb1c88d392cd5ed8a1cdcdc731b1f181b2 100644
--- a/AngularApp/prototype/src/app/state.service.ts
+++ b/AngularApp/prototype/src/app/state.service.ts
@@ -1,34 +1,43 @@
 import {EventEmitter, Injectable} from '@angular/core';
-import {ApiService, LshData, RawData, TableInfoData} from './api.service';
+import {ApiService, LshData, Parameters, RawData, TableInfoData} from './api.service';
 
 @Injectable({
   providedIn: 'root'
 })
+/**
+ * This service acts as the state of the entire application. Components can subscribe to EventEmitters within this state to update their
+ * contents.
+ */
 export class StateService {
-  public loadingProgress: number = 0;
-
-  private _rawData: RawData;
+  /**
+   * These are all LSH specific variables. The variables can be accessed using the getters and setters
+   */
+  private _rawData: RawData[];
   private _lshData: LshData;
-  private _tableInfo: TableInfoData;
-  private _queryWindow: number[];
-  private _table: {[bucket: string]: number[]};
-
-  private _currentTab: number;
+  private _queryWindow: number[][];
+  private _weights: number[];
   private _labels = {};
-  private _sliderValue;
-  private _parameters: number[];
-
+  private _lshParameters: number[];
   public windowSize = 120;
   public nrOfTables = 5;
   public hashSize = 5;
   public stepSize = 200;
+
+  /**
+   * These are all GUI variables
+   */
+  public loadingProgress = 0;
   public querySelectionMode = true;
+  private _currentTab: number;
+  private _sliderValue;
 
+  /**
+   * These are all EventEmitters. Subscribe to these if you want to be informed about an update in state.
+   */
   public onNewData: EventEmitter<void> = new EventEmitter<void>();
   public onNewWindows: EventEmitter<void> = new EventEmitter<void>();
   public onNewQuery: EventEmitter<void> = new EventEmitter<void>();
-  public onNewTable: EventEmitter<void> = new EventEmitter<void>();
-  public onNewTableInfo: EventEmitter<void> = new EventEmitter<void>();
+  public onNewLshData: EventEmitter<void> = new EventEmitter<void>();
 
   public onNewLabels: EventEmitter<void> = new EventEmitter<void>();
   public onNewTab: EventEmitter<void> = new EventEmitter<void>();
@@ -38,6 +47,9 @@ export class StateService {
      this.initialize();
   }
 
+  /**
+   * This function initializes the application. It retrieves the raw data and creates windows.
+   */
   async initialize(): Promise<void> {
     this.loadingProgress = 0;
     await this.getRawData();
@@ -46,96 +58,93 @@ export class StateService {
     this.loadingProgress = 100;
   }
 
+  /**
+   * This function resets the application. It re-creates the windows
+   */
   async reset(): Promise<void> {
     this.loadingProgress = 50;
     await this.createWindows();
     this.loadingProgress = 100;
   }
 
+  /**
+   * This function retrieves the raw data
+   */
   async getRawData(): Promise<void> {
     this.rawData = await this.api.readFile();
   }
 
+  /**
+   * This function creates the windows on the server side
+   */
   async createWindows(): Promise<void> {
     await this.api.createWindows(this.parameters);
     this.onNewWindows.emit();
   }
 
+  /**
+   * This function performs the first iteration of LSH
+   */
   async lshInitial(): Promise<void> {
+    this._weights = Array(this._queryWindow.length).fill(1);
     this.lshData = await this.api.lshInitial(this._queryWindow);
-    this.createTable();
+    this._lshParameters = this.lshData.parameters;
   }
 
-  async update(): Promise<void> {
-    this.lshData = await this.api.lshUpdate(this._queryWindow, [], this.lshData.parameters);
-    this.createTable();
+  /**
+   * This function performs every other iteration of LSH
+   */
+  async update(labels, hashFunctions): Promise<void> {
+    this._weights = await this.api.getWeights(this._queryWindow, labels, this._weights, hashFunctions);
+    this.lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters);
   }
 
-  async getTableInfo(): Promise<TableInfoData> {
-    this.tableInfo = await this.api.getTableInfo(Object.values(this._table));
-    return this.tableInfo;
+  /**
+   * This function retrieves additional information given a table
+   */
+  async getTableInfo(table: number[][]): Promise<TableInfoData> {
+    return await this.api.getTableInfo(table);
   }
 
-  async getQueryWindow(windowIndex: number | {[index: number]: boolean}): Promise<number[]> {
+  /**
+   * This function retrieves the query
+   */
+  async getQueryWindow(windowIndex: number | {[index: number]: boolean}): Promise<number[][]> {
     this.queryWindow = await this.api.getQueryWindow(windowIndex);
+    console.log(this.queryWindow);
     return this._queryWindow;
   }
 
-  async getWindow(indices: number[]): Promise<number[][]> {
+  /**
+   * This function retrieves the window given the window index
+   */
+  async getWindow(indices: number[]): Promise<number[][][]> {
     return await this.api.getWindowByIndices(indices);
   }
 
-  public createTable() {
-    const indices: number[] = this.lshData.distances.map((x) => x > 500 ? 100 : Math.floor(x / 10));
-    const table = {};
-    this.lshData.candidates.forEach((candidate, index) => {
-      if (table[indices[index]] === undefined)
-      {
-        table[indices[index]] = [];
-      }
-      table[indices[index]].push(candidate);
-    });
-    this.table = table;
-    this.getTableInfo();
-  }
-
-  public set rawData(v: RawData) {
+  /**
+   * These are all setters and getters
+   */
+  public set rawData(v: RawData[]) {
     this._rawData = v;
+    console.log(this._rawData);
     this.onNewData.emit();
   }
 
-  public get rawData(): RawData {
+  public get rawData(): RawData []{
     return this._rawData;
   }
 
   public set lshData(v: LshData) {
     console.log(v);
     this._lshData = v;
+    this.onNewLshData.emit();
   }
 
   public get lshData(): LshData {
     return this._lshData;
   }
 
-  public set tableInfo(v: TableInfoData) {
-    this._tableInfo = v;
-    this.onNewTableInfo.emit();
-  }
-
-  public get tableInfo(): TableInfoData {
-    return this._tableInfo;
-  }
-
-  public set table(v: {[bucket: string]: number[]}) {
-    console.log(v);
-    this._table = v;
-    this.onNewTable.emit();
-  }
-
-  public get table(): {[bucket: string]: number[]} {
-    return this._table;
-  }
-
   public set labels(v) {
     this._labels = v;
     this.onNewLabels.emit();
@@ -163,16 +172,20 @@ export class StateService {
     return this._sliderValue;
   }
 
-  public set queryWindow(v: number[]) {
+  public set queryWindow(v: number[][]) {
     this._queryWindow = v;
     this.onNewQuery.emit();
   }
 
-  public get queryWindow(): number[] {
+  public get queryWindow(): number[][] {
     return this._queryWindow;
   }
 
-  public get parameters(): {[parameter: string]: number} {
+  public get lshParameters(): number[] {
+    return this._lshParameters;
+  }
+
+  public get parameters(): Parameters {
     return {
       windowsize: this.windowSize,
       hashsize: this.hashSize,
diff --git a/AngularApp/prototype/src/app/table-overview/table-overview.component.css b/AngularApp/prototype/src/app/table-overview/table-overview.component.css
index 6432bc23d1326a6f6f1d8f1da6140bdac49e1c9f..2177b09b7a77f4c19154b86ff9d01f6367c7b653 100644
--- a/AngularApp/prototype/src/app/table-overview/table-overview.component.css
+++ b/AngularApp/prototype/src/app/table-overview/table-overview.component.css
@@ -23,3 +23,15 @@
 .button-holder {
   z-index: 5;
 }
+
+.label-button {
+  width: 40px;
+}
+
+
+.correct-selected {
+  background-color: #4caf50
+}
+.neutral-selected { background-color: #ffa300
+}
+.incorrect-selected { background-color: #f44336 }
diff --git a/AngularApp/prototype/src/app/table-overview/table-overview.component.html b/AngularApp/prototype/src/app/table-overview/table-overview.component.html
index 5b1e6ac5556e3d96096b52e2e8cd3e4534deb057..9fb866f389c4c904cdab739f489fc1d28dcd4a4f 100644
--- a/AngularApp/prototype/src/app/table-overview/table-overview.component.html
+++ b/AngularApp/prototype/src/app/table-overview/table-overview.component.html
@@ -1,15 +1,16 @@
 <div class="window">
   <div class="plots">
     <div class="subplot" *ngFor="let subplot of subplots">
+      <div class="button-holder">
+        <button class="correct-button label-button" [class.correct-selected]="labels[subplot.index]" (click)="labelCorrect(subplot.index)">&#10004;</button>
+        <button class="neutral-button label-button" [class.neutral-selected]="labels[subplot.index] == undefined" (click)="labelUndefined(subplot.index)">&#8226;</button>
+      </div>
       <plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
     </div>
   </div>
   <div class="plots">
     <div class="subplot" *ngFor="let subplot of averages">
-      <plotly-plot class="plotly-plot" [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
-<!--      <div class="button-holder">-->
-<!--        <button class="query-button" (click)="setQuery(subplot.data)">&#x21c4;</button>-->
-<!--      </div>-->
+      <plotly-plot class="plotly-plot" [data]="subplot" [layout]="layout"></plotly-plot>
     </div>
   </div>
 </div>
diff --git a/AngularApp/prototype/src/app/table-overview/table-overview.component.ts b/AngularApp/prototype/src/app/table-overview/table-overview.component.ts
index 24df3bcf865ce20f8dfa2bbaa078360d7aaa05c6..0aef1ba5026c9e5e1dcc771b4162214f9d365f5c 100644
--- a/AngularApp/prototype/src/app/table-overview/table-overview.component.ts
+++ b/AngularApp/prototype/src/app/table-overview/table-overview.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {StateService} from '../state.service';
 
 @Component({
@@ -7,103 +7,172 @@ import {StateService} from '../state.service';
   styleUrls: ['./table-overview.component.css']
 })
 export class TableOverviewComponent implements OnInit {
+  @Output() labelsOutput = new EventEmitter<boolean[]>();
   public subplots;
   public averages;
+  public layout;
+  public labels: boolean[];
   constructor(private state: StateService) { }
 
   ngOnInit(): void {
-    // this.state.onNewTable.subscribe(() => this.createHistograms());
-    // this.state.onNewTableInfo.subscribe(() => this.createPrototypes());
+    this.state.onNewLshData.subscribe(() => {
+      this.createHistograms();
+      this.createPrototypes();
+    });
   }
 
-  createPrototypes(): void {
-    this.averages = this.state.tableInfo.prototypes.map(prototype => {
-      return {
-        data: [
-          {
-            x: [...Array(prototype.average.length).keys()],
-            y: prototype.average,
-            type: 'line',
-          },
-          {
-            x: [...Array(prototype.average.length).keys()],
-            y: prototype.max,
-            type: 'scatter',
-            fill: null,
-            mode: 'lines',
-            line: {
-              color: 'rgb(55, 128, 191)',
-              width: 3
-            }
-          },
-          {
-            x: [...Array(prototype.average.length).keys()],
-            y: prototype.min,
-            type: 'scatter',
-            fill: 'tonexty',
-            mode: 'lines',
-            line: {
-              color: 'rgb(55, 128, 191)',
-              width: 3
-            }
+  public labelCorrect(index: number) {
+    this.labels[index] = true;
+    this.labelsOutput.emit(this.labels);
+  }
+
+  public labelUndefined(index: number) {
+    if (this.labels[index] !== undefined) {
+      delete this.labels[index];
+      this.labelsOutput.emit(this.labels);
+    }
+  }
+
+  async createPrototypes(): Promise<void> {
+    const representatives: number[][] = [];
+    this.state.lshData.candidates.forEach((grouphash) => {
+      grouphash.forEach((candidates) => {
+        representatives.push(candidates.slice(0, 20));
+      });
+    });
+    const prototypes = await this.state.getTableInfo(representatives);
+    const subplots = [];
+    this.averages = prototypes.prototypes.map((prototype) => {
+      const channelData = [];
+      prototype.max.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
+          type: 'scatter',
+          fill: null,
+          mode: 'lines',
+          line: {
+            color: 'rgb(55, 128, 191)',
+            width: 3
           }
-        ],
-        layout: {
-          showlegend: false,
-          hovermode: 'closest',
-          autosize: true,
-          margin: {
-            l: 10,
-            r: 10,
-            t: 10,
-            b: 10,
-            pad: 4
-          },
-          xaxis: {
-            showticklabels: false
-          },
-          yaxis: {
-            showticklabels: false
-          },
-          height: 100,
-          width: screen.width * 0.1,
-        }
+        });
+      });
+      prototype.min.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
+          type: 'scatter',
+          fill: 'tonexty',
+          mode: 'lines',
+          line: {
+            color: 'rgb(55, 128, 191)',
+            width: 3
+          }
+        });
+      });
+      prototype.average.forEach((channel, index) => {
+        channelData.push({
+          x: [...Array(channel.length).keys()],
+          y: channel,
+          xaxis: 'x',
+          yaxis: `y${index + 2}`,
+          type: 'line',
+          line: {
+            color: 'red',
+            width: 3
+          }
+        });
+      });
+      return channelData;
+    });
+    for (let index = 0; index < this.state.queryWindow.length; index++) {
+      subplots.push([`xy${index + 2}`]);
+    }
+    this.layout = {
+      grid: {
+        rows: this.state.queryWindow.length,
+        columns: 1,
+        subplots: subplots,
+      },
+      showlegend: false,
+      hovermode: 'closest',
+      autosize: true,
+      margin: {
+        l: 10,
+        r: 10,
+        t: 30,
+        pad: 4
+      },
+      xaxis: {
+        showgrid: false,
+        zeroline: false,
+        showticklabels: false,
+      },
+      yaxis: {
+        zeroline: false,
+        showticklabels: false,
+      },
+      height: 300,
+      width: screen.width * 0.1,
+    };
+    this.state.queryWindow.forEach((channel: number[], index: number) => {
+      this.layout[`yaxis${index + 2}`] = {
+        zeroline: false,
+        showticklabels: false,
       };
     });
   }
 
   async createHistograms() {
+    this.labels = [];
+    console.log('creating table histograms');
     this.subplots = [];
     this.averages = [];
-    const table = this.state.table;
-    this.subplots.push(
-      {
-        data: [{
-          x: Object.keys(table),
-          y: Object.values(table).map((values: number[]) => values.length), // / (this.service.rawValues.length - this.service.windowSize)),
-          type: 'bar'
-        }],
-        layout: {
-          hovermode: 'closest',
-          autosize: true,
-          margin: {
-            l: 10,
-            r: 10,
-            t: 10,
-            b: 10,
-            pad: 4
-          },
-          xaxis: {
-            showticklabels: false
-          },
-          yaxis: {
-            showticklabels: false
-          },
-          height: 100,
-          width: screen.width * 0.1,
+    const tables = this.state.lshData.tables;
+    console.log('start of table histograms');
+    tables.forEach((table, index) => {
+      console.log(index);
+      this.subplots.push(
+        {
+          index,
+          data: [{
+            x: Object.keys(table),
+            y: Object.values(table).map((values: number[]) => values.length), // / (this.service.rawValues.length - this.service.windowSize)),
+            type: 'bar',
+            opacity: 0.5,
+            marker: {
+              color: Object.keys(table).map((key) => {
+                return this.getColor(Number(key) / Number(Object.keys(table)[Object.keys(table).length - 1]));
+              })
+            }
+          }],
+          layout: {
+            hovermode: 'closest',
+            autosize: true,
+            margin: {
+              l: 10,
+              r: 10,
+              t: 10,
+              b: 10,
+              pad: 4
+            },
+            xaxis: {
+              showticklabels: false
+            },
+            yaxis: {
+              showticklabels: false
+            },
+            height: 100,
+            width: screen.width * 0.1,
+          }
         }
-      }
-    );
+      );
+    });
+    console.log('tables histogram created');
   }
 
   // async setQuery(data) {
@@ -112,10 +181,15 @@ export class TableOverviewComponent implements OnInit {
   // }
 
   public get tables() {
-    return this.state.table;
+    return this.state.lshData.tables;
   }
 
   public get visible() {
     return !this.state.querySelectionMode;
   }
+
+  getColor(value) {
+    const hue=((1-value)*120).toString(10);
+    return ["hsl(",hue,",100%,50%)"].join("");
+  }
 }
diff --git a/AngularApp/prototype/src/app/training-window/training-window.component.css b/AngularApp/prototype/src/app/training-window/training-window.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/AngularApp/prototype/src/app/training-window/training-window.component.html b/AngularApp/prototype/src/app/training-window/training-window.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..a7e346f2039d2ad5f9c29b3ba98e185ba070f5c2
--- /dev/null
+++ b/AngularApp/prototype/src/app/training-window/training-window.component.html
@@ -0,0 +1,5 @@
+<app-table-overview (labelsOutput)="hashFunctionLabels = $event"></app-table-overview>
+<app-labeling-window (labelsOutput)="labels = $event"></app-labeling-window>
+<div class="button-holder">
+  <button *ngIf="show" (click)="train()" class="train-button">Train</button>
+</div>
diff --git a/AngularApp/prototype/src/app/training-window/training-window.component.ts b/AngularApp/prototype/src/app/training-window/training-window.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9a2b567673a5920ff597c495da38e5e8b80c084c
--- /dev/null
+++ b/AngularApp/prototype/src/app/training-window/training-window.component.ts
@@ -0,0 +1,35 @@
+import { Component, OnInit } from '@angular/core';
+import {StateService} from '../state.service';
+
+@Component({
+  selector: 'app-training-window',
+  templateUrl: './training-window.component.html',
+  styleUrls: ['./training-window.component.css']
+})
+export class TrainingWindowComponent implements OnInit {
+  public labels: boolean[] = [];
+  public hashFunctionLabels: boolean[] = [];
+
+  constructor(private state: StateService) { }
+
+  ngOnInit(): void {
+  }
+
+  async train() {
+    this.state.labels = Object.assign({}, this.state.labels, this.labels);
+    await this.state.getQueryWindow(this.state.labels);
+    console.log(this.hashFunctionLabels);
+    const hashFunctions: number[][] = [];
+    this.hashFunctionLabels.forEach((label, index) => {
+      if (label) {
+        hashFunctions.push(this.state.lshData.hash_functions[index]);
+      }
+    });
+    console.log(hashFunctions);
+    await this.state.update(Object.assign({}, this.labels), hashFunctions);
+  }
+
+  public get show() {
+    return !!this.state.lshData;
+  }
+}
diff --git a/Flaskserver/.idea/workspace.xml b/Flaskserver/.idea/workspace.xml
index abed6cc1b54a8e45db0f8f415442cfa7753a65a5..6f2b237bee78e81f82c18822f7e116ec49b7f664 100644
--- a/Flaskserver/.idea/workspace.xml
+++ b/Flaskserver/.idea/workspace.xml
@@ -19,24 +19,19 @@
     <select />
   </component>
   <component name="ChangeListManager">
-    <list default="true" id="556080ba-825c-4b55-a92a-867a4df4fb32" name="Default Changelist" comment="">
-      <change beforePath="$PROJECT_DIR$/../AngularApp/prototype/src/app/labeling-window/labeling-window.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/../AngularApp/prototype/src/app/labeling-window/labeling-window.component.html" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../AngularApp/prototype/src/app/overview-window/overview-window.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../AngularApp/prototype/src/app/overview-window/overview-window.component.ts" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../AngularApp/prototype/src/app/table-overview/table-overview.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../AngularApp/prototype/src/app/table-overview/table-overview.component.ts" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/1.csv" beforeDir="false" />
-      <change beforePath="$PROJECT_DIR$/DailyDelhiClimateTrain.csv" beforeDir="false" />
-      <change beforePath="$PROJECT_DIR$/_lsh.cpython-38-x86_64-linux-gnu.so" beforeDir="false" afterPath="$PROJECT_DIR$/_lsh.cpython-38-x86_64-linux-gnu.so" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so" beforeDir="false" afterPath="$PROJECT_DIR$/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/setup.py" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../environment.yml" beforeDir="false" afterPath="$PROJECT_DIR$/../environment.yml" afterDir="false" />
-    </list>
+    <list default="true" id="556080ba-825c-4b55-a92a-867a4df4fb32" name="Default Changelist" comment="" />
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
     <option name="LAST_RESOLUTION" value="IGNORE" />
   </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="Python Script" />
+      </list>
+    </option>
+  </component>
   <component name="Git.Settings">
     <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
   </component>
@@ -55,6 +50,10 @@
     <property name="nodejs_npm_path_reset_for_default_project" value="true" />
   </component>
   <component name="RecentsManager">
+    <key name="MoveFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$/data" />
+      <recent name="$PROJECT_DIR$/libs" />
+    </key>
     <key name="CopyFile.RECENT_KEYS">
       <recent name="$PROJECT_DIR$" />
     </key>
@@ -137,13 +136,25 @@
       <screen x="72" y="27" width="1848" height="1053" />
     </state>
     <state x="686" y="355" width="777" height="403" key="#com.intellij.fileTypes.FileTypeChooser/72.27.1848.1053@72.27.1848.1053" timestamp="1603212805629" />
+    <state x="729" y="302" width="524" height="509" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1605609733644">
+      <screen x="72" y="27" width="1848" height="1053" />
+    </state>
+    <state x="729" y="302" width="524" height="509" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/72.27.1848.1053@72.27.1848.1053" timestamp="1605609733644" />
     <state x="479" y="254" width="1200" height="800" key="DiffContextDialog" timestamp="1603129938934">
       <screen x="72" y="27" width="1848" height="1053" />
     </state>
     <state x="479" y="254" width="1200" height="800" key="DiffContextDialog/72.27.1848.1053@72.27.1848.1053" timestamp="1603129938934" />
-    <state x="779" y="311" width="424" height="491" key="FileChooserDialogImpl" timestamp="1603390700256">
+    <state x="779" y="311" width="424" height="491" key="FileChooserDialogImpl" timestamp="1606260652750">
+      <screen x="72" y="27" width="1848" height="1053" />
+    </state>
+    <state x="779" y="311" width="424" height="491" key="FileChooserDialogImpl/72.27.1848.1053@72.27.1848.1053" timestamp="1606260652750" />
+    <state x="687" y="162" width="618" height="783" key="find.popup" timestamp="1606586473850">
+      <screen x="72" y="27" width="1848" height="1053" />
+    </state>
+    <state x="687" y="162" width="618" height="783" key="find.popup/72.27.1848.1053@72.27.1848.1053" timestamp="1606586473850" />
+    <state x="659" y="259" width="672" height="678" key="search.everywhere.popup" timestamp="1604929652702">
       <screen x="72" y="27" width="1848" height="1053" />
     </state>
-    <state x="779" y="311" width="424" height="491" key="FileChooserDialogImpl/72.27.1848.1053@72.27.1848.1053" timestamp="1603390700256" />
+    <state x="659" y="259" width="672" height="678" key="search.everywhere.popup/72.27.1848.1053@72.27.1848.1053" timestamp="1604929652702" />
   </component>
 </project>
\ No newline at end of file
diff --git a/Flaskserver/__pycache__/DBA.cpython-38.pyc b/Flaskserver/__pycache__/DBA.cpython-38.pyc
deleted file mode 100644
index ee756e972d4a8aac20fcbf3c7ac617a69c472ca0..0000000000000000000000000000000000000000
Binary files a/Flaskserver/__pycache__/DBA.cpython-38.pyc and /dev/null differ
diff --git a/Flaskserver/__pycache__/DBA.cpython-39.pyc b/Flaskserver/__pycache__/DBA.cpython-39.pyc
deleted file mode 100644
index 368c5be97531cb8f6473dc6bef50b905d96221c0..0000000000000000000000000000000000000000
Binary files a/Flaskserver/__pycache__/DBA.cpython-39.pyc and /dev/null differ
diff --git a/Flaskserver/__pycache__/bigwig.cpython-38.pyc b/Flaskserver/__pycache__/bigwig.cpython-38.pyc
deleted file mode 100644
index 00c1792d524e86a06d07155df2a61697b8296f77..0000000000000000000000000000000000000000
Binary files a/Flaskserver/__pycache__/bigwig.cpython-38.pyc and /dev/null differ
diff --git a/Flaskserver/__pycache__/main.cpython-38.pyc b/Flaskserver/__pycache__/main.cpython-38.pyc
index 03caa6125bfac047073c2e152501016012ec2759..d7e1394f0ec8adca440344b7cccf0ad1393d6745 100644
Binary files a/Flaskserver/__pycache__/main.cpython-38.pyc and b/Flaskserver/__pycache__/main.cpython-38.pyc differ
diff --git a/Flaskserver/__pycache__/preprocessing.cpython-38.pyc b/Flaskserver/__pycache__/preprocessing.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a7235ecbfce8b71c221b4345ca9ee868b8370c8b
Binary files /dev/null and b/Flaskserver/__pycache__/preprocessing.cpython-38.pyc differ
diff --git a/Flaskserver/__pycache__/pseudo.cpython-38.pyc b/Flaskserver/__pycache__/pseudo.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..59cff614cd0a683799a6b40d1e3c54bddacc3b8a
Binary files /dev/null and b/Flaskserver/__pycache__/pseudo.cpython-38.pyc differ
diff --git a/Flaskserver/__pycache__/utils.cpython-38.pyc b/Flaskserver/__pycache__/utils.cpython-38.pyc
deleted file mode 100644
index 53aa8e25f8cca63b270439f74b880d04a1d5e23d..0000000000000000000000000000000000000000
Binary files a/Flaskserver/__pycache__/utils.cpython-38.pyc and /dev/null differ
diff --git a/Flaskserver/_lsh.cpython-38-x86_64-linux-gnu.so b/Flaskserver/_lsh.cpython-38-x86_64-linux-gnu.so
index 89d94127179ed338adc6156c0c816aa142b143f9..7c4f653f514557fd1480603746e2815bd9b585ac 100755
Binary files a/Flaskserver/_lsh.cpython-38-x86_64-linux-gnu.so and b/Flaskserver/_lsh.cpython-38-x86_64-linux-gnu.so differ
diff --git a/Flaskserver/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so b/Flaskserver/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so
index 89d94127179ed338adc6156c0c816aa142b143f9..7c4f653f514557fd1480603746e2815bd9b585ac 100755
Binary files a/Flaskserver/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so and b/Flaskserver/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so differ
diff --git a/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o b/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o
index 2f1de0adb2dd1c1b4a90549a90750652cd1131a8..0781171e271ea7cbf6bcac8631bfcbe239ce775f 100644
Binary files a/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o and b/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o differ
diff --git a/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o b/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o
index da6a9f6c883e641b1cadf3540ac6aec57a8a39c9..99a7abdc54bc44a0fd083ffbc3e1c1f7a652eb0c 100644
Binary files a/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o and b/Flaskserver/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o differ
diff --git a/Flaskserver/data.pkl b/Flaskserver/data.pkl
deleted file mode 100644
index 58dd3be81cbe8f2e4c1554bc192d07c07500a70a..0000000000000000000000000000000000000000
Binary files a/Flaskserver/data.pkl and /dev/null differ
diff --git a/Flaskserver/data/21.csv b/Flaskserver/data/21.csv
new file mode 100644
index 0000000000000000000000000000000000000000..b32f810ea3a22e35971393cb192467019a0d1fed
Binary files /dev/null and b/Flaskserver/data/21.csv differ
diff --git a/Flaskserver/NW_Ground_Stations_2016.csv b/Flaskserver/data/NW_Ground_Stations_2016.csv
similarity index 100%
rename from Flaskserver/NW_Ground_Stations_2016.csv
rename to Flaskserver/data/NW_Ground_Stations_2016.csv
diff --git a/Flaskserver/chip_w-3000_r-25.h5 b/Flaskserver/data/chip_w-3000_r-25.h5
similarity index 100%
rename from Flaskserver/chip_w-3000_r-25.h5
rename to Flaskserver/data/chip_w-3000_r-25.h5
diff --git a/Flaskserver/data/data.pkl b/Flaskserver/data/data.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..3bc7abd304c501fd40b36e1f8c4dee5c622f6c32
Binary files /dev/null and b/Flaskserver/data/data.pkl differ
diff --git a/Flaskserver/data/parameters.npy b/Flaskserver/data/parameters.npy
new file mode 100644
index 0000000000000000000000000000000000000000..b75db92afd755a1a5afecb6116f7dd8fe4254124
Binary files /dev/null and b/Flaskserver/data/parameters.npy differ
diff --git a/Flaskserver/processed-data b/Flaskserver/data/processed-data
similarity index 100%
rename from Flaskserver/processed-data
rename to Flaskserver/data/processed-data
diff --git a/Flaskserver/data/processed-data.npy b/Flaskserver/data/processed-data.npy
new file mode 100644
index 0000000000000000000000000000000000000000..9c7f6cabbd615eefbc8dc2a2c297eec9a98bffeb
Binary files /dev/null and b/Flaskserver/data/processed-data.npy differ
diff --git a/Flaskserver/query b/Flaskserver/data/query
similarity index 100%
rename from Flaskserver/query
rename to Flaskserver/data/query
diff --git a/Flaskserver/test.bigWig b/Flaskserver/data/test.bigWig
similarity index 100%
rename from Flaskserver/test.bigWig
rename to Flaskserver/data/test.bigWig
diff --git a/Flaskserver/DBA.py b/Flaskserver/libs/DBA.py
similarity index 100%
rename from Flaskserver/DBA.py
rename to Flaskserver/libs/DBA.py
diff --git a/Flaskserver/DBA_multivariate.py b/Flaskserver/libs/DBA_multivariate.py
similarity index 100%
rename from Flaskserver/DBA_multivariate.py
rename to Flaskserver/libs/DBA_multivariate.py
diff --git a/Flaskserver/libs/__pycache__/DBA_multivariate.cpython-38.pyc b/Flaskserver/libs/__pycache__/DBA_multivariate.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c05779e917b5cab3b52eb89a19ee2a3f8aa6e2ff
Binary files /dev/null and b/Flaskserver/libs/__pycache__/DBA_multivariate.cpython-38.pyc differ
diff --git a/Flaskserver/__pycache__/bigwig.cpython-39.pyc b/Flaskserver/libs/__pycache__/bigwig.cpython-38.pyc
similarity index 71%
rename from Flaskserver/__pycache__/bigwig.cpython-39.pyc
rename to Flaskserver/libs/__pycache__/bigwig.cpython-38.pyc
index d7b5cc2d9c3f2b82802447276d67013e31df8328..53394d44f75209bebbfc7b6452b784f4de06c190 100644
Binary files a/Flaskserver/__pycache__/bigwig.cpython-39.pyc and b/Flaskserver/libs/__pycache__/bigwig.cpython-38.pyc differ
diff --git a/Flaskserver/bigwig.py b/Flaskserver/libs/bigwig.py
similarity index 100%
rename from Flaskserver/bigwig.py
rename to Flaskserver/libs/bigwig.py
diff --git a/Flaskserver/setup.py b/Flaskserver/libs/setup.py
similarity index 100%
rename from Flaskserver/setup.py
rename to Flaskserver/libs/setup.py
diff --git a/Flaskserver/utils.py b/Flaskserver/libs/utils.py
similarity index 100%
rename from Flaskserver/utils.py
rename to Flaskserver/libs/utils.py
diff --git a/Flaskserver/main.py b/Flaskserver/main.py
index 611733be4b3261b1064a20cc7aa6fba53a3845b5..fbfcdbad80d524ffdbb862f77a8c30b5b50ef5b9 100644
--- a/Flaskserver/main.py
+++ b/Flaskserver/main.py
@@ -3,14 +3,11 @@ import numpy as np
 from flask_cors import CORS
 from time import time
 import orjson
-import bigwig
-import bbi
-import _ucrdtw
-import _lsh
-import dtw
-import math
-from random import sample
-from DBA import performDBA
+import os.path
+import pseudo
+import preprocessing
+
+data_path = 'data/processed-data.npy'
 
 reload = False
 
@@ -21,251 +18,222 @@ CORS(app)
 def index():
     return "hi"
 
+
+"""
+Returns raw data
+
+Output: [{
+    index: 1d array [x]
+    values: 1d array [x]
+}]
+"""
 @app.route('/read-data', methods=['GET'])
 def read_data():
     t0 = time()
-    size = bbi.chromsizes('test.bigWig')['chr1']
-    bins = 100000
-    data = bigwig.get('test.bigWig', 'chr1', 0, size, bins)
-    print(data.shape)
-    response = {
-        "index": list(range(0, size, int(size/(bins)))),
-        "values": data.tolist()
-    }
+    response = preprocessing.read_mts_data()
     response = orjson.dumps(response)
     print('Data read: ' + str(time()-t0))
     return response
 
+
+"""
+Creates windows
+
+Input: {
+    parameters: {
+        windowssize: int
+    }
+}
+
+Output: '1'
+"""
 @app.route('/create-windows', methods=['POST'])
 def create_windows():
     t0 = time()
-    if reload:
+    if (not os.path.isfile(data_path)):
         raw_data = request.json
         window_size = int(raw_data['parameters']["windowsize"])
-        chromsize = bbi.chromsizes('test.bigWig')['chr1']
-        step_size = int(12000 / 6)
-        start_bps = np.arange(0, chromsize - 12000 + step_size, step_size)
-        end_bps = np.arange(12000, chromsize + step_size, step_size)
-        data = bigwig.chunk(
-            'test.bigWig',
-            12000,
-            int(12000 / window_size),
-            int(12000 / 6),
-            ['chr1'],
-            verbose=True,
-        )
-        # data = bbi.stackup(
-        #     'test.bigWig',
-        #     ['chr1'] * start_bps.size,
-        #     start_bps,
-        #     end_bps,
-        #     bins=window_size,
-        #     missing=0.0,
-        #     oob=0.0,
-        # )
-        # data = (data - np.min(data))/np.ptp(data)
-        np.save('processed-data', data)
-        np.savetxt('processed-data', data, delimiter=' ', fmt='%f')
-        np.savetxt('query', data[80503], delimiter=' ', fmt='%f')
+        preprocessing.create_eeg_windows(window_size, 5)
     print('Windows created: ' + str(time()-t0))
     return '1'
 
+
+"""
+Does first iteration of LSH and returns a bunch of useful information
+
+Input: {
+    query: 2d array [d][t]
+}
+
+Output: {
+    hash_functions: 3d array [k][l][d]
+    candidates: 3d array [k][l][i]
+    distances: 3d array [k][l][i]
+    average_candidates: 1d array [i]
+    average_distances: 1d array [i]
+    tables: [{
+        bucket: 1d array
+    }]
+    average_table: {
+        bucket: 1d array
+    }
+    samples: 1d array
+    parameters: 1d array
+}
+"""
 @app.route('/initialize', methods=['POST'])
 def initialize():
     t0 = time()
     raw_data = orjson.loads(request.data)
-    data = np.load('processed-data.npy')
-    data = np.reshape(data, (len(data), len(data[0]), 1))
-    # data = np.repeat(data, repeats=1, axis=2)
+    data = np.load(data_path)
+    data = np.swapaxes(data, 1, 2)
     query = raw_data["query"]
-    query = np.reshape(query, (len(query), 1))
-    # query = np.repeat(query, repeats=1, axis=1)
+    query = np.swapaxes(query, 0, 1)
+    # parameters = np.load('parameters.npy')
 
-    r, a, sd = preprocess(data)
-    candidates, distances, hf = _lsh.lsh(data, query, r, a, sd)
+    lsh_data = pseudo.lsh(data, query)
 
-    response = {
-        "hash_functions": hf.tolist(),
-        "candidates": candidates.tolist(),
-        "distances": distances.tolist(),
-        "parameters": [float(r), float(a), float(sd)]
-    }
-    response = orjson.dumps(response)
+    response = orjson.dumps(lsh_data)
     print('LSH done: ' + str(time()-t0))
     return response
 
-@app.route('/weights', methods=['POST'])
-def weights():
-    raw_data = orjson.loads(request.data)
-    parameters = raw_data["labels"]
-
-    # Caculate weights
-
-    response = weights
-    return response
-
 
+"""
+Does LSH and returns a bunch of useful information
+
+Input: {
+    query: 2d array [d][t]
+}
+
+Output: {
+    hash_functions: 3d array [k][l][d]
+    candidates: 3d array [k][l][i]
+    distances: 3d array [k][l][i]
+    average_candidates: 1d array [i]
+    average_distances: 1d array [i]
+    tables: [{
+        bucket: 1d array
+    }]
+    average_table: {
+        bucket: 1d array
+    }
+    samples: 1d array
+}
+"""
 @app.route('/update', methods=['POST'])
 def update():
     t0 = time()
     raw_data = orjson.loads(request.data)
-    data = np.load('processed-data.npy')
-    data = np.reshape(data, (len(data), len(data[0]), 1))
-    # data = np.repeat(data, repeats=1, axis=2)
-    weights = raw_data["weights"]
+    data = np.load(data_path)
+    data = np.swapaxes(data, 1, 2)
     query = raw_data["query"]
-    query = np.reshape(query, (len(query), 1))
-    # query = np.repeat(query, repeats=1, axis=1)
+    query = np.swapaxes(query, 0, 1)
+    weights = raw_data["weights"]
     parameters = raw_data["parameters"]
 
-    candidates, distances, hf = _lsh.lsh(data, query, parameters[0], parameters[1], parameters[2])
-    response = {
-        "hash_functions": hf.tolist(),
-        "distances": distances.tolist(),
-        "candidates": candidates.tolist()
-    }
-    response = orjson.dumps(response)
+    lsh_data = pseudo.lsh(data, query, parameters=parameters, weights=weights)
+
+    response = orjson.dumps(lsh_data)
     print('LSH done: ' + str(time()-t0))
     return response
 
+
+"""
+Calculates new weights for LSH algorithm
+
+Input: {
+    labels: 1d array [?]
+    hash_functions: 2d array [?][d]
+    query: 2d array [d][t]
+    weights: 1d array [d]
+}
+
+Output: 1d array [d]
+"""
+@app.route('/weights', methods=['POST'])
+def weights():
+    raw_data = orjson.loads(request.data)
+    labels = raw_data["labels"]
+    hash_functions = raw_data["hash_functions"]
+    query = raw_data["query"]
+    old_weights = raw_data["weights"]
+    data = np.load(data_path)
+
+    new_weights = pseudo.weights(data, query, old_weights, labels, hash_functions)
+
+    response = orjson.dumps(new_weights)
+    return response
+
+
+"""
+Calculates query based on given indices
+
+Input: {
+    indices: 1d array [?]
+}
+
+Output: 2d array [d][t]
+"""
 @app.route('/query', methods=['POST'])
 def query():
     t0 = time()
     raw_data = orjson.loads(request.data)
-    windowIndices = raw_data['window']
-    if isinstance(windowIndices, int):
-        output = np.load('processed-data.npy')[windowIndices]
-        response = orjson.dumps(output.tolist())
-        print("Query done: " + str(time() - t0))
-        return response
-    else:
-        indices = [int(index) for index, value in windowIndices.items() if value is True]
-        data = np.load('processed-data.npy')[indices]
-        output = performDBA(data)
-        response = orjson.dumps(output.tolist())
-        print("Query done: " + str(time()-t0))
-        return response
+    window_indices = raw_data['indices']
+    data = np.load(data_path)
+
+    response = pseudo.query(data, window_indices)
+
+    response = orjson.dumps(response)
+    print("Query done: " + str(time() - t0))
+    return response
 
+
+"""
+Returns values of windows on given indices
+
+Input: {
+    indices: 1d array [x]
+}
+
+Output: 3d array [x][d][t]
+"""
 @app.route('/window', methods=['POST'])
 def window():
     t0 = time()
     raw_data = orjson.loads(request.data)
     indices = raw_data['indices']
-    output = np.load('processed-data.npy')[indices]
+
+    output = np.load(data_path)[indices]
+
     response = orjson.dumps(output.tolist())
-    print("Query done: " + str(time() - t0))
+    print("Window(s) done: " + str(time() - t0))
     return response
 
+
+"""
+Returns additional information on given table
+
+Input: {
+    table: 2d array [x][?]
+}
+
+Output: {
+    prototypes: {
+        average: 1d array [t]
+        max: 1d array [t]
+        min: 1d array [t]
+    }
+    distances: 2d array [x][x]
+}
+"""
 @app.route('/table-info', methods=['POST'])
 def table_info():
     t0 = time()
     raw_data = orjson.loads(request.data)
-    all_windows = raw_data['windows']
-    data = np.load('processed-data.npy')
-    prototypes = []
-    for windows in all_windows:
-        actual_windows = data[windows]
-        average_values = np.average(actual_windows, 0)
-        std_values = np.std(actual_windows, 0)
-        max_values = average_values + std_values
-        min_values = average_values - std_values
-        prototypes.append({
-            'average': average_values.tolist(),
-            'max': max_values.tolist(),
-            'min': min_values.tolist()
-        })
-    distances = [[_ucrdtw.ucrdtw(np.array(v["average"]), np.array(w["average"]), 0.05 * 120, False)[1] for j, w in enumerate(prototypes)] for i, v in enumerate(prototypes)]
-    response = orjson.dumps({'prototypes': prototypes, 'distances': distances})
-    print("Averages calculated: " + str(time() - t0))
-    return response
+    table = raw_data['table']
+    data = np.load(data_path)
 
-def preprocess(data):
-    # return 0.10882589134534404, 3.1202154563478928, 0.9705780396843037
-    # data = np.load('processed-data.npy')
-    data = np.array(data, dtype='double')
-    # data = np.reshape(data, (int(len(data) / 1), 1, len(data[0])))
-    # data = np.repeat(data, repeats=1, axis=1)
-    subset = []
-    t0 = time()
+    response = pseudo.table_info(data, table)
 
-    r = 3
-    for i, window in enumerate(data):
-        if i % 10000 == 0:
-            print(str(i) + ':' + str(len(subset)))
-        state = 1
-        for s in subset:
-            if np.linalg.norm(window - data[s]) < r:
-                state = 0
-                break
-        if state == 1:
-            subset.append(i)
-
-    # subset = sample(list(range(len(data))), 50)
-
-    dtw_distances = []
-    eq_distances = []
-    for i, index_1 in enumerate(subset):
-        print(i)
-        for j, index_2 in enumerate(subset):
-            if index_1 == index_2:
-                continue
-            e = np.linalg.norm(data[index_1] - data[index_2])
-            eq_distances.append(e)
-            d = _ucrdtw.ucrdtw(data[index_1], data[index_2], 0.05, False)[1]
-            # d = dtw.dtw(data[index_1], data[index_2], dist_method="Euclidean", window_type="sakoechiba", window_args={"window_size": 120}).distance
-            dtw_distances.append(d)
-
-    ratios = np.array(dtw_distances)/np.array(eq_distances)
-    mean_dtw = np.mean(dtw_distances)
-    sd_dtw = np.std(dtw_distances)
-    mean_eq = np.mean(eq_distances)
-    sd_eq = np.std(eq_distances)
-    a = np.mean(ratios)
-    sd = np.std(ratios)
-    theta = mean_dtw + -2.58 * sd_dtw
-    # theta = mean_eq + -2.58 * sd_eq
-    r = theta / ((a-sd)*math.sqrt(120))
-    # r = theta / (math.sqrt(120))
-    print('Mean: ' + str(mean_dtw))
-    print('Stdev: ' + str(sd_dtw))
-    print('Ratio mean: ' + str(a))
-    print('Ratio stdev: ' + str(sd))
-    print('Theta: ' + str(theta))
-    print('r: ' + str(r))
-    print('Preprocessing time: ' + str(time() - t0))
-    return r, a, sd
-
-def debug_test_lsh():
-    data = np.load('processed-data.npy')
-    r, a, sd = preprocess(data)
-    create_windows()
-    query_n = 80503
-    query = data[query_n] # performDBA(data[[80503, 11514]])
-    query = np.reshape(query, (len(data[0]), 1))
-    data= np.array(data, dtype='double')
-    data = np.reshape(data, (len(data), len(data[0]), 1))
-    data = np.repeat(data, repeats=1, axis=2)
-
-    candidates, distances, hf = _lsh.lsh(data, query, r, a, sd)
-    print(repr(candidates[0:20]))
-    print(distances[0:10])
-
-    data = np.load('processed-data.npy')
-    query = data[query_n]
-    print(data[0])
-    distances = [_ucrdtw.ucrdtw(window, query, 0.05, False)[1] for window in data]
-    sorted_distances = sorted(distances)
-    print(sorted_distances[0:10])
-    topk_dtw = sorted(range(len(distances)), key=lambda k: distances[k])
-    print(topk_dtw[0:10])
-
-    # # distances_ed = [distance.euclidean(query, window) for window in data]
-    # # topk_ed = sorted(range(len(distances_ed)), key=lambda k: distances_ed[k])
-    #
-    accuracy = 0
-    for index in topk_dtw[0:20]:
-        if index in candidates[0:20]:
-            accuracy += 1
-    print(accuracy)
-
-# debug_test_lsh()
\ No newline at end of file
+    print("Averages calculated: " + str(time() - t0))
+    return response
\ No newline at end of file
diff --git a/Flaskserver/preprocessing.py b/Flaskserver/preprocessing.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe38926877a790c2944f2962afd2aad93f7ee8c0
--- /dev/null
+++ b/Flaskserver/preprocessing.py
@@ -0,0 +1,118 @@
+import numpy as np
+import pandas as pd
+from libs import bigwig
+import bbi
+import dask.dataframe as dd
+import os.path
+from sklearn import preprocessing
+
+def read_data():
+    size = bbi.chromsizes('test.bigWig')['chr1']
+    bins = 100000
+    data = bigwig.get('data/test.bigWig', 'chr1', 0, size, bins)
+    print(data.shape)
+    response = [
+        {
+            "index": list(range(0, size, int(size/(bins)))),
+            "values": data.tolist()
+        },
+        {
+            "index": list(range(0, size, int(size / (bins)))),
+            "values": data.tolist()
+        },
+        {
+            "index": list(range(0, size, int(size / (bins)))),
+            "values": data.tolist()
+        }
+    ]
+    return response
+
+def read_mts_data():
+    filename = 'data/data.pkl'
+    if (not os.path.isfile(filename)):
+        print("start")
+        df = dd.read_csv("NW_Ground_Stations_2016.csv", usecols=['number_sta', 'date', 't', 'hu', 'td'])
+        print("read file")
+        df = df.loc[df['number_sta'].isin([14066001, 14137001, 14216001, 14372001, 22092001, 22113006, 22135001])].fillna(0)
+        print("split rows")
+        df = df.compute()
+        df.to_pickle(filename)
+        print("to_pandas")
+    df = pd.read_pickle(filename)
+    df.dropna(subset=['t'], inplace=True)
+    response = [
+        {
+            "index": df.loc[df['number_sta'] == 14066001].loc[:, 'date'].values.astype(str).tolist(),
+            "values": df.loc[df['number_sta'] == 14066001].loc[:, 't'].values.tolist()
+        },
+        {
+            "index": df.loc[df['number_sta'] == 14066001].loc[:, 'date'].values.astype(str).tolist(),
+            "values": df.loc[df['number_sta'] == 14066001].loc[:, 'hu'].values.tolist()
+        },
+        {
+            "index": df.loc[df['number_sta'] == 14066001].loc[:, 'date'].values.astype(str).tolist(),
+            "values": df.loc[df['number_sta'] == 14066001].loc[:, 'td'].values.tolist()
+        }
+    ]
+    return response
+
+def create_peax_windows_12kb(window_size):
+    data = bigwig.chunk(
+        'test.bigWig',
+        12000,
+        int(12000 / window_size),
+        int(12000 / 6),
+        ['chr1'],
+        verbose=True,
+    )
+    data = np.reshape(data, (len(data), 1, len(data[0])))
+    np.save(data_path, data)
+    return '1'
+
+def create_peax_windows_12kb_mts(window_size):
+    data = bigwig.chunk(
+        'test.bigWig',
+        12000,
+        int(12000 / window_size),
+        int(12000 / 6),
+        ['chr1'],
+        verbose=True,
+    )
+    data = np.reshape(data, (len(data), 1, len(data[0])))
+    data2 = np.copy(data)
+    np.random.shuffle(data2)
+    data3 = np.copy(data)
+    np.random.shuffle(data3)
+
+    data = np.concatenate((data, data2), axis=1)
+    data = np.concatenate((data, data3), axis=1)
+    np.save(data_path, data)
+    return '1'
+
+def create_eeg_windows(window_size, nr_of_channels):
+    datafile = '21.csv'
+    data = pd.read_csv(datafile, header=None)
+    npdata = np.array(data)
+    window_data = [npdata[i:i + window_size, 0:nr_of_channels] for i in range(0, npdata.shape[0] - window_size, int(window_size / 8))]
+    del npdata
+    np_window_data = np.repeat(window_data, repeats=3, axis=0)
+    del window_data
+    data = np.reshape(np_window_data, (len(np_window_data), nr_of_channels, len(np_window_data[0])))
+    np.save(data_path, data)
+    return '1'
+
+def create_weather_windows(window_size):
+    filename = 'data/data.pkl'
+    df = pd.read_pickle(filename)
+    channels = list()
+    channels.append(df.loc[df['number_sta'] == 14066001].loc[:, 't'].fillna(0).values.tolist())
+    channels.append(df.loc[df['number_sta'] == 14066001].loc[:, 'hu'].fillna(0).values.tolist())
+    channels.append(df.loc[df['number_sta'] == 14066001].loc[:, 'td'].fillna(0).values.tolist())
+    data = [([values[i:i+window_size] for values in channels]) for i in range(0, len(channels[0]) - window_size, 1)]
+    windows = []
+    for i in range(len(data)):
+        if i % 5000 == 0:
+            print(i)
+        windows.append(preprocessing.minmax_scale(data[i], (-1, 1), axis=1))
+    np.save('processed-data', windows)
+    return '1'
\ No newline at end of file
diff --git a/Flaskserver/processed-data.npy b/Flaskserver/processed-data.npy
deleted file mode 100644
index 93c1b23840760c6e45279029707556349164bdc3..0000000000000000000000000000000000000000
Binary files a/Flaskserver/processed-data.npy and /dev/null differ
diff --git a/Flaskserver/pseudo.py b/Flaskserver/pseudo.py
new file mode 100644
index 0000000000000000000000000000000000000000..9adf51dbafa0847f4b849ca9bbbedc3c205436cf
--- /dev/null
+++ b/Flaskserver/pseudo.py
@@ -0,0 +1,243 @@
+import numpy as np
+from time import time
+import _ucrdtw
+import _lsh
+import math
+from libs.DBA_multivariate import performDBA
+from tslearn.metrics import dtw
+from collections import defaultdict
+
+def lsh(data, query, parameters = None, weights = None):
+    if parameters is None:
+        parameters = preprocess(data)
+    r = parameters[0]
+    a = parameters[1]
+    sd = parameters[2]
+
+    if weights is None:
+        candidates, distances, hf = _lsh.lsh(data, query, r, a, sd)
+    else:
+        candidates, distances, hf = _lsh.lsh(data, query, r, a, sd, weights)
+
+    dict = defaultdict(int)
+    for l in range(len(candidates)):
+        for k in range(len(candidates[0])):
+            for i in range(len(candidates[0][0])):
+                dict[candidates[l][k][i]] += distances[l][k][i]
+    sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}
+    average_candidates = np.array(list(sorted_dict.keys())).tolist()
+    average_distances = np.array(list(sorted_dict.values())).tolist()
+
+    tables = []
+    samples_set = set()
+    candidates = candidates.tolist()
+    for l in range(len(candidates)):
+        for k in range(len(candidates[0])):
+            samples_set.update(candidates[l][k][0:5])
+            dict = defaultdict(list)
+            length = len(distances[l][k])
+            median = distances[l][k][math.ceil(length/2)]
+            stepsize = median / 10
+            indices = list(map(lambda x: 19 if x > median * 2 else math.floor(x / stepsize), distances[l][k]))
+            for i in range(len(candidates[0][0])):
+                dict[str(indices[i])].append(candidates[l][k][i])
+            tables.append(dict)
+
+    length = len(average_distances)
+    median = average_distances[math.ceil(length/2)]
+    stepsize = median / 10
+    indices = list(map(lambda x: 19 if x > median * 2 else math.floor(x / stepsize), average_distances))
+    average_table = defaultdict(list)
+    for i in range(len(average_candidates)):
+        average_table[str(indices[i])].append(average_candidates[i])
+
+    samples = np.array(list(filter(lambda x: x in samples_set, average_candidates))).tolist()
+
+
+    response = {
+        "hash_functions": hf.reshape((len(candidates) * len(candidates[0]), len(query[0]))).tolist(),
+        "candidates": candidates,
+        "distances": distances.tolist(),
+        "average_candidates": average_candidates,
+        "average_distances": average_distances,
+        "tables": tables,
+        "average_table": average_table,
+        "samples": list(samples),
+        "parameters": [float(r), float(a), float(sd)]
+    }
+    return response
+
+def preprocess(data, r=10.0):
+    subset = []
+    t0 = time()
+
+    i = 0
+    while i < len(data):
+        if i % 999 == 0:
+            print(r)
+            print(str(i) + ':' + str(len(subset)))
+
+        state = 1
+        for s in subset:
+            if np.linalg.norm(data[i] - data[s]) < r:
+                state = 0
+                break
+        if state == 1:
+            subset.append(i)
+
+        i = i + 1
+        if i == 10000 and len(subset) < 10:
+            r = r / 2
+            subset = []
+            i = 0
+        if len(subset) > 200:
+            r = r + r / 2
+            subset = []
+            i = 0
+
+    # subset = sample(list(range(len(data))), 200)
+    print("r = " + str(r))
+    dtw_distances = []
+    eq_distances = []
+    for i, index_1 in enumerate(subset):
+        print(i)
+        for j, index_2 in enumerate(subset):
+            if index_1 == index_2:
+                continue
+            e = np.linalg.norm(data[index_1] - data[index_2])
+            if (math.isnan(e) or e == 0):
+                eq_distances.append(0.0001)
+                dtw_distances.append(0.0001)
+                continue
+            eq_distances.append(e)
+            d = dtw(data[index_1], data[index_2], global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05*120))
+            dtw_distances.append(d)
+
+    ratios = np.array(dtw_distances)/np.array(eq_distances)
+    mean_dtw = np.mean(dtw_distances)
+    sd_dtw = np.std(dtw_distances)
+    mean_eq = np.mean(eq_distances)
+    sd_eq = np.std(eq_distances)
+    a = np.mean(ratios)
+    sd = np.std(ratios)
+    theta = mean_dtw + -2.58 * sd_dtw
+    # theta = mean_eq + -2.58 * sd_eq
+    r = theta / ((a-sd)*math.sqrt(120))
+    if r < 0:
+        r = mean_dtw / 100
+    # r = theta / (math.sqrt(120))
+    print('Mean: ' + str(mean_dtw))
+    print('Stdev: ' + str(sd_dtw))
+    print('Ratio mean: ' + str(a))
+    print('Ratio stdev: ' + str(sd))
+    print('Theta: ' + str(theta))
+    print('r: ' + str(r))
+    print('Preprocessing time: ' + str(time() - t0))
+    return r, a, sd
+
+def weights(data, query, old_weights, labels, hash_functions):
+    alpha = 0.2
+    all_good_windows = data[[[int(index) for index, value in labels.items() if value is True]]]
+
+    good_distances = np.zeros(len(query))
+    for window in all_good_windows:
+        for i in range(len(all_good_windows[0])):
+            good_distances[i] += _ucrdtw.ucrdtw(query[i], window[i], 0.05, False)[1]
+    if len(all_good_windows) != 0:
+        good_distances = np.square(good_distances)
+        if np.sum(good_distances) != 0:
+            good_distances /= np.sum(good_distances)
+        good_distances = np.ones(len(query)) - good_distances
+        good_distances /= np.sum(good_distances)
+        good_distances *= len(all_good_windows[0])
+        good_distances = np.sqrt(good_distances)
+
+    if len(hash_functions) != 0:
+        summed_hash_functions = np.sum(hash_functions, axis=0)
+        summed_hash_functions = np.square(summed_hash_functions)
+        normalized_hash_functions = summed_hash_functions / np.sum(summed_hash_functions)
+        normalized_hash_functions *= len(hash_functions[0])
+
+    if len(hash_functions) + len(all_good_windows) == 0:
+        print("no update")
+        new_weights = old_weights
+    elif len(hash_functions) == 0:
+        print("only windows")
+        new_weights = alpha * np.array(old_weights) + (1 - alpha) * good_distances
+    elif len(all_good_windows) == 0:
+        print("only tables")
+        new_weights = alpha * np.array(old_weights) + (1 - alpha) * normalized_hash_functions
+    else:
+        print("tables & windows")
+        new_weights = alpha * np.array(old_weights) + 0.5 * (1-alpha) * good_distances + 0.5 * (1-alpha) * normalized_hash_functions
+
+    print(new_weights)
+    return new_weights.tolist()
+
+def table_info(data, table):
+    prototypes = []
+    for cluster in table:
+        windows = data[cluster]
+        average_values = np.average(windows, 0)
+        std_values = np.std(windows, 0)
+        max_values = average_values + std_values
+        min_values = average_values - std_values
+        prototypes.append({
+            'average': average_values.tolist(),
+            'max': max_values.tolist(),
+            'min': min_values.tolist()
+        })
+    # distances = [[dtw(np.array(v["average"]), np.array(w["average"]), global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05 * 120)) for j, w in enumerate(prototypes)] for i, v in enumerate(prototypes)]
+    return {'prototypes': prototypes, 'distances': []}
+
+def query(data, window_indices):
+    if isinstance(window_indices, int):
+        output = data[window_indices]
+    else:
+        indices = [int(index) for index, value in window_indices.items() if value is True]
+        indices_windows = data[indices]
+        output = performDBA(indices_windows)
+    return output.tolist()
+
+def debug_test_lsh():
+    data = np.load('processed-data.npy')
+    # data = np.repeat(data, repeats=7, axis=1)
+    print(data.shape)
+    data = np.reshape(data, (len(data), len(data[0][0]), len(data[0])))
+
+    r, a, sd = preprocess(data, 11.25)
+    query_n = 1234
+    t0 = time()
+    query = data[query_n]
+    data = data.astype('double')
+    dict = defaultdict(int)
+    candidates, distances, hf = _lsh.lsh(data, query, r, a, sd)
+    print("Calculated approximate in: " + str(time()-t0))
+    for l in range(len(candidates)):
+        for k in range(len(candidates[0])):
+            for i in range(len(candidates[0][0])):
+                dict[candidates[l][k][i]] += distances[l][k][i]
+    sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}
+    candidates = list(sorted_dict.keys())
+
+    print(candidates[0:20])
+
+    t0 = time()
+    # distances = [dtw_ndim.distance_fast(window, query) for window in data]
+    distances = [dtw(window, query, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05*120)) for window in data]
+    topk_dtw = sorted(range(len(distances)), key=lambda k: distances[k])
+    print("Calculated exact dtw in: " + str(time()-t0))
+    print(topk_dtw[0:20])
+
+    t0 = time()
+    l2distances = [np.linalg.norm(window - query) for window in data]
+    print("Calculated exact l2 in: " + str(time()-t0))
+
+    # # distances_ed = [distance.euclidean(query, window) for window in data]
+    # # topk_ed = sorted(range(len(distances_ed)), key=lambda k: distances_ed[k])
+    #
+    accuracy = 0
+    for index in topk_dtw[0:20]:
+        if index in candidates:
+            accuracy += 1
+    print(accuracy)
diff --git a/Flaskserver/topk.npy b/Flaskserver/topk.npy
deleted file mode 100644
index 50b87ddaedfd74d2e81f8a82c2de7b40a8a1711f..0000000000000000000000000000000000000000
Binary files a/Flaskserver/topk.npy and /dev/null differ
diff --git a/experiments/.ipynb_checkpoints/Compare Algorithms-checkpoint.ipynb b/experiments/.ipynb_checkpoints/Compare Algorithms-checkpoint.ipynb
deleted file mode 100644
index a019fc69fcea9af3c3086c0e484cc0fb1f617383..0000000000000000000000000000000000000000
--- a/experiments/.ipynb_checkpoints/Compare Algorithms-checkpoint.ipynb	
+++ /dev/null
@@ -1,608 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import numpy as np\n",
-    "import json\n",
-    "import h5py\n",
-    "import os\n",
-    "import sys\n",
-    "from time import time\n",
-    "import warnings\n",
-    "\n",
-    "# Ignore warnings as they just pollute the output\n",
-    "warnings.filterwarnings('ignore')\n",
-    "\n",
-    "# Enable importing modules from the parent directory\n",
-    "module_path = os.path.abspath(os.path.join('..'))\n",
-    "if module_path not in sys.path:\n",
-    "    sys.path.append(module_path)\n",
-    "module_path = os.path.abspath(os.path.join('../experiments'))\n",
-    "if module_path not in sys.path:\n",
-    "    sys.path.append(module_path)\n",
-    "\n",
-    "# DNase-seq 2011, hg19\n",
-    "bw = 'data/ENCFF158GBQ.bigWig'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "./data/ENCFF158GBQ.bigWig already exist. To overwrite pass `overwrite=True`\n",
-      "./models/dnase_w-12000_r-100.h5 already exist. To overwrite pass `overwrite=True`\n"
-     ]
-    }
-   ],
-   "source": [
-    "from download import download_encode_file, download_file\n",
-    "from pathlib import Path\n",
-    "\n",
-    "Path('data').mkdir(parents=True, exist_ok=True)\n",
-    "Path('models').mkdir(parents=True, exist_ok=True)\n",
-    "\n",
-    "download_encode_file('ENCFF158GBQ.bigWig')\n",
-    "\n",
-    "download_file(\n",
-    "    \"https://zenodo.org/record/2609763/files/dnase_w-12000_r-100.h5?download=1\",\n",
-    "    \"dnase_w-12000_r-100.h5\",\n",
-    "    dir=\"models\"\n",
-    ")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from scipy.spatial.distance import cdist\n",
-    "\n",
-    "def knn(data, target_idx, k, metric='euclidean', sax = None, ignore: int = 0, sort_only: bool = False):\n",
-    "    \"\"\"K nearest neighbors\n",
-    "    \n",
-    "    Find the `k` nearest neighbors of a \n",
-    "    \"\"\"\n",
-    "    \n",
-    "    target = data[target_idx]\n",
-    "    \n",
-    "    if sort_only:\n",
-    "        dist = data\n",
-    "    else:\n",
-    "        if sax is None:\n",
-    "            dist = cdist(data, target.reshape((1, target.size)), metric='euclidean').flatten()\n",
-    "\n",
-    "        else:\n",
-    "            N = data.shape[0]\n",
-    "            dist = np.zeros(N)\n",
-    "            for i in range(N):\n",
-    "                dist[i] = sax.distance_sax(target, data[i])\n",
-    "\n",
-    "    # Ensure that the target is always first\n",
-    "    dist[target_idx] = -1\n",
-    "    for i in range(1, ignore + 1):\n",
-    "        dist[min(target_idx + i, data.shape[0] - 1)] = -1\n",
-    "        dist[max(target_idx - i, 0)] = -1\n",
-    "    \n",
-    "    return np.argsort(dist)[1 + (2 * ignore):k + 1 + (2 * ignore)]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from scipy.signal import correlate\n",
-    "\n",
-    "def norm(data, zero_norm: bool = False):\n",
-    "    mean = np.mean(data) if zero_norm else 0\n",
-    "    \n",
-    "    return (data - mean) / np.std(data)\n",
-    "\n",
-    "def norm2d(data, zero_norm: bool = False):\n",
-    "    mean = np.mean(data, axis=1).reshape(-1, 1) if zero_norm else np.zeros((data.shape[0], 1))\n",
-    "    std = np.std(data, axis=1).reshape(-1, 1)\n",
-    "    \n",
-    "    return (data - mean) / std\n",
-    "\n",
-    "def xcorrelation(data, template_idx, n, normalize=False, zero_normalize=False, ignore: int = 0):\n",
-    "    unknown = data\n",
-    "    template = data[template_idx]\n",
-    "    \n",
-    "    if norm:\n",
-    "        unknown = norm2d(unknown, zero_norm=zero_normalize)\n",
-    "        template = norm(template, zero_norm=zero_normalize)\n",
-    "        \n",
-    "    xcorr = np.apply_along_axis(lambda m: correlate(m, template, mode='full'), axis=1, arr=unknown)\n",
-    "    xcorr[np.where(np.isnan(xcorr))] = 0\n",
-    "\n",
-    "    max_xcorr = np.nanmax(xcorr, axis=1)\n",
-    "    \n",
-    "    # Ensure that the target is always last\n",
-    "    max_xcorr[template_idx] = -1\n",
-    "    for i in range(1, ignore + 1):\n",
-    "        max_xcorr[min(template_idx + i, data.shape[0] - 1)] = -1\n",
-    "        max_xcorr[max(template_idx - i, 0)] = -1\n",
-    "    \n",
-    "    return np.argsort(max_xcorr)[::-1][:n]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Extracted 124621 windows from chr1 with a max value of 1.0.\n",
-      "Done! Took 27.24 seconds (0.5 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "import bigwig\n",
-    "\n",
-    "t0 = time()\n",
-    "data_12kb = bigwig.chunk(bw, 12000, 100, 12000 / 6, ['chr1'], verbose=True)\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "image/png": "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8Jvnn3/eLcnr7/nnn3e73W73li1b3Ndff73b6XS6Bw4c6D5w4IDXvEuWLHG3b9/eHRcX5x4xYoT70KFDnnEHDhxwDxw40O10Ot3du3d3b9myxY9rBYQnPsYCAIABunABADBAgAIAYIAABQDAAAEKAICBJn2RQm5urpxOp1VtAWChHYeOe/7du2Pbesdd6vLpEH7qOzYuF6rHisvlUmZmZp3jmhSgTqdTGRkZPmkUAP8asmy559+nl2bVO+5Sl0+H8FPfsXG5UD1W8vLy6h3HV/kBQS52xqXB+GADUwLwJd4DBQDAABUoEGQurTgBBA4VKAAABghQAAAM0IULhCi6egFrUYECAGCAClR8DAAA0HRhGaB0bQEArhZduAAAGAjLChQId/TCAFePChQAAAMEKAAABujCBQB40L3feFSgAAAYoAK9zOV3X3wuFMGE6gHwHypQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAG+CIFAPXii0WA+hGgP+LSCwgXDwDAPxGgQBDgK/oA+yFAAQBXLRx763iICAAAA2FTgdIFBgD+ES4Pn4VNgALBhps++AvHmhkCFECjheP7XEB9CNAm4OIBKwVbFdBQezk/EA4IUMCPwuW9IdhfsN2w2REBClisoQsVF7HQxI1SeHC43W53YyfOy8tTRkaGz17cn12iVl+owvEEaez+C8eub4KxfnY8BnxxjPpin/ti29j92PP1/rf6ZqWh3AupCjSQB059r335zmxsGy+dzy7vNTW2kmpsmF6uoXUO1Ho2tk12v2jZSaBuqBq7j+x4HYE92aYCvZzJicXBZ6ax29ou29c0uOpbT7usF7yFQzUWjqzer1SgTcAJYi07bl/TNtlxXVA/094KhCY77ucmVaC5ublyOp1WtgcAANtwuVzKzMysc1yTAhQAAFzEl8kDAGCAAAUAwAABCgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKCAhd544w316dNHLVq00AMPPOAZfv78eY0bN06pqalyOBzKycnxmq+srExTpkxRu3bt1K5dO82bN88z7tChQ4qOjvb6czgceu211yRJOTk5ioiI8BqfnZ3th7UFwkuzQDcACGXt27fXs88+q82bN+vs2bNe4/r376/HHntM48ePv2K+2bNnq6qqSkVFRSotLdXPf/5zXXfddZo6dao6duyoiooKz7QHDhxQ165dNXbsWK/XPXLkiHUrBoAABaw0ZswYSdI333zjFWg/+clP9Nhjj0mSIiMjr5jvgw8+0MaNG9WyZUulpqZq2rRpWr58uaZOnXrFtCtWrNDtt9+u1NRUa1YCQJ3owgVsyu12e/179+7ddU63YsUKTZkyxWtYaWmpkpKS1KlTJ82ePVuVlZWWthUIRwQoYEPDhg3Tyy+/rDNnzmjfvn1avny5qqqqrphu27Zt+uGHHzRu3DjPsLS0NOXn56ukpESffPKJ8vLyNGfOHH82HwgLBChgQ4sXL1ZUVJS6deumUaNGaeLEiUpJSbliuuzsbI0dO1bR0dGeYcnJyerRo4ciIiLUqVMnLVy4UGvWrPFn84GwQIACNpSQkKBVq1bp+++/V0FBgS5cuKBbb73Va5qzZ8/q3XffvaL79nIOh8OrOxiAb/AQEWChmpoa1dTUqLa2VrW1tXK5XGrWrJmaNWumc+fOeYLt/PnzcrlcatGihRwOhwoLCxUXF6e4uDh99NFHevPNN7V161avZa9bt05xcXEaPHiw1/CcnBx17txZHTp00JEjR/TUU09p1KhRfltnIFxQgQIWevHFFxUVFaWXX35ZK1euVFRUlF588UVJ0vXXX6+oqCgVFxcrKytLUVFROnjwoCQpLy9PN910k2JiYvT0009r1apVSk9P91p2dna2Jk+eLIfD4TV8+/btuu2229SqVSv169dPN954oxYvXuyfFQbCiMNN3w4AAE1GBQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGGjS50Bzc3PldDqtagsAALbicrmUmZlZ57gmBajT6VRGRoZPGgUAgN3l5eXVO44uXAAADBCgAAAY4LtwAQC2Eztjudf/Ty99MEAtqR8VKAAABghQAAAMEKAAABggQAEAMECAAgBggKdwAQC2cPmTt3ZHBQoAgAECFAAAAwQoAAAGeA8UAXXpex52/KYRAKgPFSgAAAYIUAAADBCgAAAYIEABADBAgAIAYICncOFXwfZNIwBQHypQAAAMEKAAABggQAEAMECAAgBggIeIbIqvuAMAeyNAAYtxMwSEJgJUXOAAwO7seJ0OqQC9/DOGdtnIaBw7niAAUJ+QClBfIIRhpYaOL449ILgQoEEg2C+sfPtQ/dg2QPAiQG2EiykABI+wDFCCCgDsIZivxyEdoMG8YxoSDg/bBHu3NYDQF9IBCgAIbYG82Q76ALW6ygyHas/XQrXy9zeOPYQiX1wf7HKNCfoADXfh0tVJmNhbuByHwKUIUARdOAVDe319h+yLdW6oTXbdjrA3u1SCgRLQAA2GC+Glgq29JoLtIuvP9oZyleXrYzsczhWr2WUbhntINsQ2FWhTLoR236GNPfADuR5WVkiwVmPPFX8+H2BXVraxKaF2te1oyvxXG7bBsF/twuF2u92NnTg3N1dOp9PK9gAAYBsul0uZmZl1jmtSgAIAgIsiAt0AAACCEQEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMDA/wf6bnHeYyXbdQAAAABJRU5ErkJggg==\n",
-      "text/plain": [
-       "<Figure size 576x810 with 9 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "from utils import plot_windows_from_data\n",
-    "\n",
-    "k_12kb = 20 # Number of KNNs to be saved later on\n",
-    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
-    "targets_12kb_ex = 12933\n",
-    "\n",
-    "plot_windows_from_data(data_12kb, window_ids=targets_12kb)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Done! Took 85.77 seconds (1.4 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "\"\"\"Compute the CAE latent space\"\"\"\n",
-    "\n",
-    "from utils import get_models, predict\n",
-    "\n",
-    "encoder_12kb, decoder_12kb, autoencoder_12kb = get_models('models/dnase_w-12000_r-100.h5', loss_fn='bce')\n",
-    "\n",
-    "t0 = time()\n",
-    "predicted_12kb, _, latent_12kb = predict(\n",
-    "    encoder_12kb,\n",
-    "    decoder_12kb,\n",
-    "    data_12kb.reshape(data_12kb.shape[0], data_12kb.shape[1], 1)\n",
-    ")\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
-    "\n",
-    "with h5py.File('data/cae_12kb.h5', 'w') as f:\n",
-    "    f.create_dataset('latent_space', data=latent_12kb, dtype=np.float32)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Preprocessing done! Took 115.74 seconds (1.9 minutes).\n",
-      "Done! Took 13.87 seconds (0.2 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "\"\"\"Compute SAX\"\"\"\n",
-    "\n",
-    "from tslearn.piecewise import SymbolicAggregateApproximation\n",
-    "\n",
-    "t0 = time()\n",
-    "sax_12kb = SymbolicAggregateApproximation(n_segments=120, alphabet_size_avg=10)\n",
-    "sax_data_12kb = sax_12kb.fit_transform(data_12kb)\n",
-    "print('Preprocessing done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
-    "t0 = time()\n",
-    "N = data.shape[0]\n",
-    "dist = np.zeros(N)\n",
-    "target = sax_data_12kb[80503]\n",
-    "for i in range(N):\n",
-    "    dist[i] = sax_12kb.distance_sax(target, sax_data_12kb[i])\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Search for window #80503.... done! Took 16.87 seconds (0.3 minutes).\n",
-      "Search for window #43895.... done! Took 16.10 seconds (0.3 minutes).\n",
-      "Search for window #33430.... done! Took 15.50 seconds (0.3 minutes).\n",
-      "Search for window #42575.... done! Took 15.87 seconds (0.3 minutes).\n",
-      "Search for window #6112.... done! Took 16.19 seconds (0.3 minutes).\n",
-      "Search for window #91938.... done! Took 16.08 seconds (0.3 minutes).\n",
-      "Search for window #82896.... done! Took 15.96 seconds (0.3 minutes).\n",
-      "Search for window #1060.... done! Took 17.08 seconds (0.3 minutes).\n",
-      "Search for window #11975.... done! Took 16.38 seconds (0.3 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "from time import time\n",
-    "    \n",
-    "with h5py.File('data/cae_12kb.h5', 'r') as f:\n",
-    "    cae_12kb = f['latent_space'][:]\n",
-    "\n",
-    "    \n",
-    "with h5py.File('data/12kb-similarity-search.h5', 'w') as f:\n",
-    "    f.create_dataset('knn_ae', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
-    "    f.create_dataset('knn_eq', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
-    "    f.create_dataset('knn_sax', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
-    "    f.create_dataset('top_xcorr', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
-    "    \n",
-    "    for i, target in enumerate(targets_12kb):\n",
-    "        t0 = time()\n",
-    "        print('Search for window #{}'.format(target), end='', flush=True)\n",
-    "        f['knn_ae'][i] = knn(cae_12kb, target, k_12kb, ignore=2)\n",
-    "        print('.', end='', flush=True)\n",
-    "        f['knn_eq'][i] = knn(data_12kb, target, k_12kb, ignore=2)\n",
-    "        print('.', end='', flush=True)\n",
-    "        f['knn_sax'][i] = knn(sax_data_12kb, target, k_12kb, sax=sax_12kb, ignore=2)\n",
-    "        print('.', end='', flush=True)\n",
-    "        f['top_xcorr'][i] = xcorrelation(data_12kb, target, k_12kb, normalize=True, zero_normalize=True, ignore=2)\n",
-    "        print('. done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {
-    "scrolled": false
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAC9cAAAW7CAYAAACHUqN3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdvdLbyJUwYFClxKl2JvvKVuBUVVvluRBdqq5gr0CqcpVSJxPbNemG/AItRxRFAmigf053P09izysSbALog/453bxcr9cFAAAAAAAAAAAAAABm9qZ1AQAAAAAAAAAAAAAAoDXJ9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABM723Ki//rv/7r+te//rVUWbr2z3/+c1mWZfnv//7vxiVhNLPeW//85z//c71ef21djpLE1Dhu9exmtvrG+MRUgHzEVNjnsY29LNrZ/ExMBchHTAXIa/S4KqYCNY0eU5dFXKWs+7HW2xirHIcyno1rL0us8yumAuSzFlOTkuv/+te/Lv/zP/+Tp1SDeffu3bIsi/NDdrd769aA++OPP1oWp5p379793roMpYmpcdzq2Y3rwmjEVIB8xFTY57GNvSza2fxMTAXIR0wFyGv0uCqmAjWNHlOXRVylrPux1tt9JsehjGfj2ssS6/yKqQD5rMXUNzULAgAAAAAAAAAAAHz37t27l8ndAEBdkusBAAAAAAAAAAAAAJje29YFAMq7rWz9448/GpcEAAAAAAAAgBzMAwP0z271ABCP5HoAAAAAAACgGMmfAAAAABxxvxCt1tjSmyqfAhN59+6dVaUAAAAAAAAAAAAA0BnJ9QAAAAAANGfTCgAAAAAAoLW3rQsAAAAAAAA3twT7Wj/vCgAAABCNDQgAoB071wMAAAAAAAAAAHTML8IBAOQhuR4moiMFAAAAAAAAAAAAAM9Jrs9M8jIAAAAAAAAAAAAAQH/eti4AjOq2yOKPP/5oXBIAAAAAAAAAAEZkE1AAYEQt2ziS60/SQAUAAAAAAAAAAKAkeWoAUIfkegAAAAAAYEh+YRTakvwDAAAAQG/etC4AAAAAAAAAAAAAAAC0Zud6CMhOLgAAAAAAAAAAAGXJ04If64FfgATJ9QAAAAAAwOBMEAIAAAAAsMeb1gUAjnn37p2VkwAAAAAAwLTMlQAAAACQm53rAQAAAAAAACZwW4zgVzygXxYVAVs87/smzgNAe5LrAQAy8jPzAAAAAAAAAAAAfZJcD8C0rPgGAIC8tLEBAACgT3a6BgAA+OZN6wIAAHG9e/dOgtQJzh8AAAAAAFCa+QgAAIB87FwPAAAQnF2jgBGIZQAAAFCHPjgAAHtYoAnP2bkeAAAAAAAAAGBQdrYHAADYz871UNj9IIWdAaAPdvMAICrPKAAAAABgLwn1AAAA6STXQ+ckWAHEJ1YDAAAAAACt2RgOAABgm+R6yMSqf2YneRgAAAAAAPogwRa4Mc8NAADwI8n1AADAFCwEAwAAgDFIBAUAAACglDetC0Bf3r17Z8ASmNqscXDW7w0AAAAAADATc0IA/RG7oT/qLcRm5/oDBDUARudZBwBACu1HAAD2uG83+mU5AICy/KIvAD3zHKMlyfUAAJVo+EMbEj4BAOIq1VbT/0I/AOYi7gN8k9IGytleEocBgNFo30BMteqm5HpoyEMYAACAnh2ZiNcXBgAAAABmZ1E4EJV5HJBcD93RuIYYNCR5JD4DACPT/gV6JX4BAAAAcIbxpfHc53dsXVfXH+YkuR4GJtET2nlW/1o3tDX4YTwpnf6c7wVgXtqUQE1HYo7xMPbwPAMA2LanzaT9DQDQp57acWtlNb5HKZLrdzgziaPy8kxPDydYM8u9PPr3HDXB1rMYGMHozyAAgBT6eQD90J+NxzUBctAmh1g836GuUXMraEv7CmKSXJ9g5kbpzN+9Bg9JRuJ+fu3Vucl9zvYeT2xvRz2hBPfVfs4VAAD3tA+3OUcAAPMynwQAzKR020fbCvoguR4SPT7gck4onXl4muCC/Eo1aEvU15Syrr1WIz6dc0YNj3HDfVePNhbAc55FQEvP2mhbcWlPu07bD+A87USAfLRPAcZTK2nXs2Mf/ReAmCLEZ8n1UFGNSh8hsMDMRq+DawkMs3XQc1zrWc8dx/W06AcAABhP677Dsz5R1H5MT2WF6EYfcwXYSzwEjrqPH/olAD+K0sZqPe72TMQyQS2S62GHKA/RCDw04Uc560Tv9StK+cVsehOl7pBfyWtrIBxiUBcB2jrb/9N/HJPrCgD0ruf2jPFugG9a/yq1Bd8AcI7k+jutGzY90Sn+rsf7ZM+97toyshL1Nucxcydp1f6+0Z4RPZxP5uReKqv389t7+WF0s9TR2j9RrG8K+Y2yCKjVBPSZcxatb1zD43Xa+u5r92fK+at9rme8tkDf9jxHxTYg1ZE2ulgDwJYaz4pZxvd57sz1N9YK5aXcn6nj0akk1y91AsYowZWx7EmOhaOiDJBFvpePTGpE/j6PotwD97YaVhHLzDxqtRd7iiOl1UrYEVsAxiGm07PSA82pWrVLSw/O1/peteLR1vfJPb74+J4z16u0V9dAn4sRHIkxUTY00V77TjyCcYxWn8Xqbc4R9OtMv5YyxFQ4L3I9svEGpQyXXJ9zV6Ecnh1LBWMEe+qJe5xladeIGc2o36u1yJP0rz5XbO1PrtXvxNbyWtlZFWIY4ZndKhZ43kFbe+r+q3r6uBC8x9iXYi1eHUlAPbNws7QzSfUlPq8HOfp+o9ch6uqhr1h7V8rUz+l146wRYirMaqT661cz6tnqrxFTy3ZGD3VvazFzxLL3EMNrj2HvvV5ruXWPouQD3h/Pxlzk5v7oI6ZyXC/jLcWT63M+mFOOtRVkIlTAV9+n9wDZe/nvRbhPAI6KEsN6fy7U/oUb6ol8b+ZMyoj8PXPKPYA1S91/tYNK6/ullw41HBEpgb3H+iVOMYMcCdwpiSyP/53SJorQnoni1bk4srP7mZ2iI00yj+bINX712h5/oRDuRUpK2Tpm7fc+O05P7cUey0x/RlicnpP2AGvEZV7JETu24vHaeGKJWH5mU7RnYxk5y7Q25yaOf1N6/CPl82AmrRfNRGqrpJRFn6SuI8+ICLreuf7IJFFkRwbnU4JByZ2Q1lYRRgymW3q6byLr6ZrzoyMd6b3HLNWxdp/Fd+S6nWn8nuE5wKO9O3VGVmunoK3dRHIdv2elvkPK4GTUXTXtaMWjrUXpj39POWbE99SWI0mwtK0y5hrrKNFPiXTtI5eNNHvjYs7POPpe99lxrkEctdvurl9+EdpkJduue5J7jmxctffvpZSueyV2lkyZKC410V+iPRApFqWOz0Uq+8hKjifmOkbp+alXtubW3KPfRTw3RxJBjzy3935uxGcj+ey9DqXbZGdysPa8N0rO0p6ybbWpI42fnpEj6b32otbez33v5Y+s9jMt6jO0VrlyL/JqfR5HnQd8VDqX49Xn9aqL5PreT/JRRxJLcgzepZzvI43rlDI/WntPjiT+We81+nGmA/h4jDOfe8aeCZ8j8UH97dORa+9ak1vtQZ9aSidPbx2/9KTy2dflem8Pz6pS32ur853rWX8ksTbihNwsSrdPzyRa55gAyfmeswnekZ9BNUUYKD5zX+793NpjHGcSRqgrcizI0denjpmvSY+TYOSzFadKPX9zjM/OltwTSc4EgpRNbY68J4e1/nXJz845bnB/PMrZm1S85xiPciUi50ggpI61+ptyr+29H3PHtpSx85L3356cisfXnpmDppwe2kh7tOp/lWqjz845I6pWfaetzy/1OaXf06MS49K1758jcs0x5ug3jXKvVU+uP5NYzWslBmNLyx3ktzqAZz4XomnVAcx5TMnTPJMyEA6U10MnsbaeylrLkdhdq02x9RoTQflEmaDovY72Xv6Wzp67kud+z6KjvcfIXaacxxJT2SLG1bd1ztXb79yf4zvSXt2TVNbDvEqJY/QuyjnoMRnCWNHcUmJpzjiZY1F+7vfkOK77fJ8z80Z7z/GReyzXPR6tLeG+bKt1Dk8ts3zPnrkmaZyvmFr3XXK3g1NjZss2xpFfYik5z3CmrZf7+I9a9ZvOHH/PxnejuFyv1/0vvlz+vSzL7+WKA/Cnv12v119bF6IkMRWoSEwFyEdMBchHTAXIR0wFyGvouCqmApUNHVOXRVwFqhJTAfJ5GVOTkusBAAAAAAAAAAAAAGBEb1oXAAAAAAAAAAAAAAAAWpNcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADC9tykv/uWXX67v378vVBRgzf/+68vqv//l7/+oVJI6vnz58p/r9fpr63KUJKYCtYipAPmIqZDusT87Wv+V48RUgHzEVIC8Ro+rYirP6L9TyugxdVnEVeq5xWoxuqw9z8RW10JMBchnLaYmJde/f/9++fz5c55SAUm+frys/vuHT2PVzcvl8nvrMpQmpgK1iKkA+YipkO6xPzta/5XjxFSAfMRUgLxGj6tiKs/ov1PK6DF1WcRV6rnFajG6rD3PxFbXQkwFyGctpr6pWRAAAAAAAAAAAAAAAIgoaed6IN39asYPn64NSwIAAAAAAAAAAAAAvGLnegAAAAAAAAAAAAAApmfnegAAAAAAAAAAABjI14+XP///h0/XhiUBgL5IrgcAAAAAAAAAAAB44X6xAgBje9O6AEAeXz9eNOIAAAAAAAAAAAAA4CA71wMAAAAAAAAAAEAwNtoEgPrsXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAlXz9ePGzfQAAAAAAAAAAAEFJrgcAAAAAAAAAAAAAYHqS6wEAAAAAgGn5pTkAYDTaNwAAAMe9bV2AVu47kh8+XRuWBAAAAAAAAAAgjltOhXwKAGZhYRoAN9Mm1wMAAAAAMCaJQAAx2fwKAADOM+4BAGW9aV0AAAAAAAAAAAAAAABozc71UIifCgIAAAAAiMsYLgAAALDF+AHAfCTXA8D/8dNpAAAAAAAAzETCIAAAwI8k1wMAnGBRBgDAz0zMA62IPwAAAAAAwBmS6wGY3uwT7/ffX4I4AAAAAABAX2wEBAAwH21AKOdN6wIAAAAAADCHrx8v0y9yBwAAAAAAzis152Dn+sUKHgCgLm0PAAAAAAAAAEqwsQEAoyv9rLNzPQAAAAAAVdnBnojcl1CXOgcAAABARHauh4rsVAxEYuIKAAAAAACgX+Z6AKAtuWAA5d33e2rFW8n10JAGFpSzVr/UPQAASPM4Wa8tDQAAAPGZEwPgxjMBAPaTXA8AUJidY4BUBjgBAAAAAAAAAOqTXA8NpCRZpiZkPnu9pCx4TsIzAAAAAAAAAAAAcCO5HiZkJ1SA8yzOAAAAiM84GM/o0wMAAAAA8IrkegAAgCAk+QAAAAAARxlfBEqwcD0u1wZYFrEASpBcD8AUUgYTH1+r8QkAAAAAAECvJFwBOYglAMAsJNff0QhkVO5tgPLsBgMAAAAAzxk7AwAAAOCsWmNM0yXXG7yD7yTdAwAAkJNxFwAAAIjrvt9ujhhgPMZnARhJy+fadMn1MDONaGaU47430AgAAPlY6A2UYNwLYBzaiwB1aEMDjENMh7mo81Ce5HrIzMMLiMqkVB9cJwAAYCYWtFNLyritvjkAAAAAwLyGS6436A0wNwtc6JH7FgAAID4LAQC2macr43H8MOX8uiZAC2IPAADQs+GS64F0JgZhLmuJ3AY7gRmIdQD5WSwIzEabsh+eUdBG7TgpLgPEZB4axqTtlZfz2Z6xAwAeFU+uf2wAlGgQeMARwZn7UEMZIAbxGABgH+0mINWesTOxBaBfOeZIXv3dc+G1lKRV5xMAgJlpD8/F9QbOsnM9POEBC/2x0Oo15yYu1wbqilbn9kyAa5cC0UWLrcAYam3QIgmxP3Y+BUby+GwS1wCASCySzyPlHDmfkN+remWMCWKLMP8ouf4JjRUeHZl8A8rRyKWlCA04oL3cfYa9sUW7FACYSelxWuPA/dAXh7mtxWvx4TvPNZiH2AdENUt75Ei+wiznJqK156Zn6niOXNPW9dPCa4ipWnJ9zofRkYCW4+coZwxcUb57jnKUum9KNLQ03mA/9YUcWsX7PZ/X+hlMTO6PbaUWYj3GAtcCAKC81m0uYw99ct0ghhLzg8sy5i/ApYxlRBzPBMZlww9gBBHbia/aa9pxkN+eGNAqP/HI8c98fsR4CBHZuT7B6IGlh8bZWhm3BlKf/ffaT7600Prz18ow6n0PueSIT5Hq2ejPvC2Rfh1h9mvBj1J2Vujxnsk5YLH1t1yf9+wzXrUxb38/s2PCnn/r8drDSHp6dkcr65FkoihlB14rOd5V6tgRxuhK6LHduKcdXPJ7HEkkM4nJDCLEyRwJBSmv7SmG5jw3Rz438rkByovwjADOyT2HEU2tNktP52Q2rg0Ae3SVXJ/ycKs1aTPCAFHpSageztHonQPmFLUORi3XXj2Uv1SyaK5j9iZKvO/h3uvdmXN8JHniyCTv3r/ntufn13MnxNc8Ru6dl1pfr1efl+s7lYhDuWPcq+N5rhFBT8/0lu2g2uepp+sCuZVOsCtxzEh1davdUStxsdXnPdP6+pR+fh05JymvgchGu4e3fp0u1/ctddyoIj6vgfJyjM+uxUkxpSyxm2Wp94tDJcbpW+Zxpbb1IrQFay8wqP2rU2LanPbWrSPjN0c2UDiyiDuljEds9YEhggjPyZtmyfUqZ196uF4S5MtKOVdHkgbJI6URmHJdXh33zDH2dHAjTzocWfC19T32DBamnJMoC81a7fx0prPCHLbq4pGk95TYtufzatXjEsertWigdtJlD848Z/a8p8RCkVfHTtHTNSK/CJOuqfdg6TKf6SOP2oeL3L8A0pRuy9Y61pm+cKsYVnuBb+7X5tRDwgRwzJFx9twLbGq0zXMloYl38NxWWy/XWF0rJRfTUk/OsWSOexUvam0W07qfl3teIGeCbam2XhQl2pxHrknu3IO9n9vS6GPxo8kRA2rfj2frVY48MdKtXYszi9VqtSm2Pr+3/K3mO9en3BC15bhgRxIljx439Ril5FzlFLHSsM11Ky/HIHyOB1eugZWtsoxyT+VcBBR14njPe/c0yM/Yk+w8yj1FfSUTPHJNaB79/NzHXHtt6+TRlONGaF+XlCOu7zlW6nk8MuCT+m9QWs5E7tITBin1OaccSUt7Yk/Ke3J89xyJSUfGiNYGVmuXiTxS7u+U+HCmPvFazv577v5zjgSGnGPlvU2ilCTGlpdy30VfnLksecdeU8Z2e66bpcve+/FLfs6RuH/kmSSG1pcy//3q33tV+pkxW9sgx3xnbq2vQY64uPbeM4l/rc/NTHIueli7btHaGWtjWT3OjfckR389V2zY23/p9dr0Wm6Oi3DNj8Thrdcc+cWhlHORcoyIieK5PmPrb1v/vreMKXMDZ655hOuXonly/U2EQHJEzsT4HIMMZ2/0GkyiwHElJ1JzKVFGYkuZoFv7e+prjnCPkaLl/TL6vdrT9+uprJG1XuxBH2ol+NWe4C+1iCXyYFMJORYN1LJnUjt1EHTPBOieydIcA6lnj822I32mlH5Zybrh+XxOjoniXNcgx/Nr7y8Vnv28EfQ2sdSjI7E1JQEp4oYOoySf0L8jbcvcxxdT89iTdHv03+/VmkOu/atB4nCe/mPOY9T6vD2fn9J2PvM5xFG779bbuKL7lx7vgdS8CehZrX7envGWI8fPsQAgZzuxdo5U7ut3Zu41cowMk1z/zN5B+AhSKnTqMXMp0Vk9U9FMogAAAFskbfZtz2RhqaSfkpOtpZKnSg9G0lathci5B5lzvJd6Sg/C9zBOS7pWC9zdN0QXsW1Wun9UYq4LIFXtmHqTEvvWkkdy5gmIx/sdGYNKOd6ZRXhHPq/Ue2BZ3Du8diaPy331M+eEWfWQdJ7zc44sJB49Pozy/S7X6/6b+HK5/HtZlt/LFQfgT3+7Xq+/ti5ESWIqUJGYCpCPmAqQj5gKkI+YCpDX0HFVTAUqGzqmLou4ClQlpgLk8zKmJiXXAwAAAAAAAAAAAADAiN60LgAAAAAAAAAAAAAAALQmuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgem9TXvzLL79c379/X6go/fjff3356W9/+fs/GpQEvrvdl6Pci1++fPnP9Xr9tXU5ShJTgVrEVIB8xFR47nGsZJS+KWWJqQD5iKkAeY0eV8XUvt33wfW/6cHoMXVZ4sTVZ/lMyyJWRDdavk80o41di6kA+azF1KTk+vfv3y+fP3/OU6oOff14+fZ//t/P//bh07znhRhu9+co9+Llcvm9dRlKmz2mAvWIqQD5iKnw3J9jJv9nlL4pZYmpAPmIqQB5jR5XxdS+3ffB9b/pwegxdVnixNXHMbobsSK20fJ9ohlt7FpMBchnLaa+qVkQAAAAAAAAAAAAAACISHI9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD03rYuAAAAAAAAAAAAr339eGldBAAAgCnYuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAACO/rx8vy9eOl2PHfFjsyADRwe2h++HRtXBIAAAAAAAAAgJ+VTAgEAM6RXA8rnjVkJewCAADAuvv+tH40AAAAAAAA0AvJ9QAAAAAcYnclAACO8iukAAAAAEQkuR4AYMVjwpjJPgAAgPgkbLKH+wQAAAAAgEdvWhcAAAAAAAAAAAAAAABak1wPAAAAAAAAAAAAAMD03rYuAJDX7aeMl8XPGQMAjOLWxtO+AwAAYDT6vADliLEAAADp7FwPwJC+frz8sNgEAAAAAAAARmI+DKAP4jUA9EVyPQAAAAAAAAAAAAAA05NcDwAA0Ak7mwAAAAAAAAAAlPO2dQEAYAS3RMcPn66NSwIAAABACuM6AAAAMBabVQFwhuR6AAAAAAAAAACAAd0nGVtUDAD0rNbiKcn10DkrLQEAAAAAAAAAAADgvDetCwAAUNvXjxeLkwAAAABgMMb9AAAAADjLzvUADMGECQAAAGB8AACA0WjjAszhFu8/fLo2LgkAILkeAAAAAAAAOE1CEEAMEvJhbNpc/RKf81AHAPr17FkYMZ5LrgcAAAAAgA33g/4RB/vZTzIDAAAQjWRhAIA4JNcDwOAMxAAAADCrHH1iidgA+YipAG2YK4L+aUcBANQjuT4TnVGA8YjtALRmsBwAgAiMkQAAANSh/wUA0N6b1gUAgJF8/XgJmwgZuWwAAAAAAAAAAMA6+T9QXuid663GBAAAAACANkzSAQAAwHH61QDQp9DJ9TAaC0YAAAAAAAAAAADOuV+8IBcLgJwk1+9gFSFnuH9gbJHreOSyAQDQJ4vGAQDYQ7sRAAAA8uohD8h4AKOQXA+JPAAAxtdDhwQAAKCEWjt+GWMD4NGZZ4PxPABgNNo3AIzIuDC9kFyf2Z7KL0AAxLZnoMJgBgAAAAAAAAAAwDp5VpRSKh+7i+R6yegAvKLxRYrH+0Ubg165dwFoLaUd7rkF/SpRf/Xj8xJjAQAAYCz6+gDQXhfJ9VBbD5N8PZQRRnFf3/Z2YI+8BwAAAOhD64nuVmODrb93aaN/P+idMVeA1/a2Y9ZiaenFtWI3AGetjYfo00Ms6iS9k1wPDTw+PDxMIE3LxSUWtoxtz/UVs6GN2eqe5w0wotliOcAWcRGgHDEWoAzxFfIzHwAAEI/kejio5Mp9gxFE8aoj7x6Nbe8AzLPXubYQmwHWPmnjAQBwT7se4LzR+9qjfz+gnJS25qtYIwZBP/QvAeam3QblSK5foRHKEUcGLICxRWvMij3AyKLF3FL8nDLQs1liNcDIeozlxkOAEfQYf4H9WrVXtj5XOwqgDW2/Msyx0SPtMahPcv3SrjGiETSGEg8vu0nT2t5BNPdlHBrSwOx6iIOenwBAZD20pyKq3cZ7dZ20NYHozjxnRn1G7YnddpUGojoSh8Su/khABVKJG9BGj+0s8YLoJNcX0mPAIvYA7ZGyuQ8pTUOnvsd6HTlu9cR5pFfi8GsRzo3YAvSudBzTZ4V+lKyvEdptr/TYnjtzPs+MPx75vB6sbYLiOQbkIp7A3CK3OS2M4p7n1Thcy+NSzp04CHMQUyGPiHUpZHJ9jd13nn1GrUmirc/tYSf9UmV8PE+vzsnokza5RQw+jOdVnGt93/XYwd0T40qVdcR44VwxgijxKYLR697ZhKZlGffcAABx9Nj+6L0dmaOdeFNqwX6P98Ure8bzH/+75+8LOWzN7eU8Zq7j15Jjw5SU94hLENPomyeJU5AmQgxQF7/b6s+2vl5rC7+jaH2O7kUqC+1Ey79MyQMarb14pJ14Ey3WzSxHnertng6ZXJ9qz+4xZ4931JngcKZxlPu9Ke/JuSPSnnOy9V5B9rszD3DIpYeOXyk9/kTm1qKnZ/8WRW+Nsld0HubWw30cLU4dea96BfSo1QYBJYjH8KPIdSLyL1rsLVvEcbBWcbf259QaU2jdj9pzH0eu50A7fkEE6FGJtpfYBkSXO0/tTBkix8mciZilv+dWPtWzz+/hGlBvA+FW+aZR9Fhm9jmS0zzK/dBlcn3K4DTfpUxmHD3m/d+2Hkq5rtHWcdwLPyvV+Iu6c/mIZlwNVlLrSew98bh1GfeUI0rHFvYabcAj9TmcMvC31mbYW66SCVIlvNoZoNT9UnvAZZT7/pXR6jektBOP/BqdOhNfqcQC134uJdtWvY7X1liopH59t+ce2HpNT+fzWeyOWA8goih1JWXCeM/YSa1Fao//fWZMpqe4C1HVjgU9ydmPeNbeEsNe2zr37tO5GCvMQ715LeWeOpKncMbe5/SRMQ11KJZXse7+byU+r7baG2WWzv9s9Uzq6Vl4Jsbm+trJKTkAACAASURBVH4lch0inPsuk+tvZmyY9LTKae2hRAwp16TE4gzSpQyOj3jNci0GivAAvtfzNVmTs8GztpirtT3Pu62FAPf/HuV7zSSlA5FjIVnOxPXccgwYvaoLtTvyKVKSVnMucGv5/VMXxEa4ViZ8xlVq4WiE+3ZZjn2/HO3ePQsRe5rgrzUxceZzai82vYlyr5Pfs3tq6/q3vj9yJRNvxbKIYxwWgp8zwnlK6VcQ0556POtzN1LfMNWe6xc52aeEMwsCerwHaOtMf/1I3ax1j/YcFyPKEUPXxj16uk5nxpHOJEb39ByjnDP995sIv3KcY96jpzrRY6x71NP5fialj9DzderF1v0Uoc3Q+z2/LGN8h2dK5Abs+Zwc7bbc12TUa5yi6+R6+qCi9W2EgeIZHFklG0mOZNUcn0ceZyZger42Z+phz997RLU7HbUWPN7UTvjb89rau9qXOOe91uO9i/FSvt+ZxUZ7nLnHogz0j+hIe+7IAFXOBM097zkiRz3Koce4lHsSbOu1uc7R1r28J3kpRxLyzZFjjTAJN7IzCbstY0HOzy4dU3Mm7fcYf3uy9qzo8dyLv+Wt3RdH2m0lxzFTEi96vN8jat1mr6XUmOSZ+nDks1MTso+8l+NyJsLnboulXv+U9sae5ww8SplPOjK2duRz4Jm1mJoyHnFk4cfe164lyb76/LX39qxV/zLnnM0MzFPFNuo4TY7v1bq+9r4wqmQf6IyezlmLsl6u1/2V5rfffrt+/vy5YHG+iXzRgHRHHs6Xy+XL9Xr9rUBxwjgSU2eLjyNMkkJuYupzYip7zDxYx3Ni6nOlYqo6SIpo94u+yXdbO4mnEFOfm/n+glnl+ElyMfW52jF1TxtmhHZFpF/hI65IbXpt1Z/lmvdvdX0j3V/wqETSVKRnr5j6XGpcFb/SREtG7Mme+FE74dZz/Dsx9bke+v8j6Hl8Yu3XXmt+9pqezmdkKc+M3DE1Kbn+crn8e1mW35NLAJDub9fr9dfWhShJTAUqElMB8hFTAfIRUwHyEVMB8ho6roqpQGVDx9RlEVeBqsRUgHxextSk5HoAAAAAAAAAAAAAABjRm9YFAAAAAAAAAAAAAACA1iTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAAAAAEzvbcqLf/nll+v79+8LFQXi+d9/fVmWZVn+8vd/NC7J97LcRChTSV++fPnP9Xr9tXU5ShJT44lU5yEnMRUgHzEV9rnvw2pf84qYCmwxVrOfmAqQ1+hxVUwFaho9pi6LuEoZj3lCy6J/nOLZ+VuW/s+hmAqQz1pMTUquf//+/fL58+c8pYLAvn68fPs//+/b/3z41P6+/7NM/ydCmUq6XC6/ty5DaWJqPLd6Nnr9Yj5iKkA+Yirsc9+H1b7mFTEV2GKsZj8xFSCv0eOqmArUNHpMXRZxlTIe84SWRf84xbPztyz9n0MxFSCftZj6pmZBAKAHXz9eXna0AAAAAAAAAAAAgDEl7VwPACOSSA8AAHloWwMAAAAAAAA9k1xfyY8/h35tWBIAAAAAAAAAAAAAAB69aV0AAAAAAAAAAAAAAABoTXI9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAgX39eFm+fry0LgYADE9yPQAAAADFmPABAAAAAAAAeiG5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAYjF+TA5iDeA8AeUmuBwAAAAAAAAAAAABgepLrAQAAAAAAAAD4k12QAQCAWb1tXQAAaMWAIAAAAAAAAADQIzkPAFCGnesBAAAAAAAAAAAAAJienesBAAAAAAAAAACgA3asB4Cy7FzfwNePF40cAAAAAAAAAAAAAIBA7FwPAAAAwCk2EQAAINWtDfnh07VxSQDGo58OAABwnOR6AKZjQBEAAAAAAIDZ3M+RWdwEMB4LWAEgD8n1AAAAAABAWJIDAADOSdl4yiZVAADA7CTXww5W8AMAAAAAAJwjYRMAANZpMwMwsl5ycd+0LgAAAAAAAHP5+vFishgAAAAAAAjHzvUAAB24JZ1EXrUJAACQqpddagAAAAAAgDlIrgcAAAAAAGjMYhMAoCab+gAAADwnuf6OziMAAAAAALR1n2QOAAAAAAA1Sa6HTlkMAuwlXgDsY5dIAAAAiMO4JgAAAKPT94WY3rQuAPDd148XuzIBAAAAAAAAAAAAQAN2rn/CaqB0dvkE6IfnHAAAAAAQlU2IAAAAAMbS23iP5HpO6e2GBwAAAAAAAAAAYrJZHADQmuT6ADQK5+XaAzU9Loh6FoPEJYB8xFQAAAAAAACI4z5vwhwea8z1wtwk18MdO/EDAJCbgReAb8RDAAAAAACAn5lDYUaR73vJ9VBR5GAAjMeCIYB9nsVL7TYAAAAAYAbGQoHc7AwOAPROcj008JjAtZYAKzkWKG0tqfTGoAcAAAClSeoBmJP43zfXD2IxtwxEo63QH4sj4EfiGMxJcj0UdmQAw6AHAMB4DLwAAPTN5DIAAFGZXwZGZF6lDs8QaEPdg9gk1wMAAFMyYAFwnBgKQAmeLwAA8VhkCkBPSowtWOgBMB/J9Uu7AfvHz/Ug5ojH++bZ/eyeAuiXxAIAAGAkZ/o4xk8B5iT+t+cawBzMRwCMY0/7bU/c1w4EWhKDaElyfWE6oH1wnYBn1mKDhhsAAADslzL+ZtIEAOIztwYxqIsA5RifAHozatwa9XsRm+R6kghUADH5SU6AMrR/AQDiOdJG064DgHSvfoUbAID8tLWAXOQQEUmvzzfJ9RyydsOPPlEV9fv1GoSA/MQDiClqG4J9XsVW1xMgnWcirFNH9nvWRns8b/rIfXCdYHx76vnWayQHxKYNAwCMqnQ7p3af+MjnjdrW2/pexiuI4vFebVUnR40FtBfx3iqeXB/xSy+Lh9+IWt9r7imIrac6mjJJ1NP3Yh/XlNL2JCCN5tVgQ4lj7zl+63YrwI14BORWqj8zWz9plvg823Vd41wAJZx5nohL8E2OdtljfRq9jVfbLG1nmIH2R3nO8Wt7nycW/EId4hVravWx7FwfkA5gH1wnIol0P24lMOYcgFw7Xq3V4xb0cIbrOKfW8eOZkrE7EnVuLBHrErGMfo+MkCgz6vMGyCfyTmo5P2e0Z1aU5wwA6cRwoFczbioDsIf2XZrRxmg4pnS92Xt89fdn6ig1Sa5foTJ+18NE1qv/fpSyq+iRzx+NZIfY1u7/Vj/98+q/H/+eq3w9/EzXmZ9nilD+ZfFMzC3KdSWWPTF8rS7WeGZHmKB4VX8ey9HDT2hyjHMN+5xpc669Rx2E/pXo30WMDXvKtDf+rR2r5GKnI+M8kcaGWulpPDPKOYOSSv+qSeQ6vmWE79CC89an3nd5rX3f9TD3NRuxB/bpNT6p4/vlGAfp4Tz3ei9T1pk2bco9tWcs8shxz1AnmJHkeprZ02h6NRFyJmAL9t8dabimXLceGsSck6s+5RwkbF3HjzRyc8S22nINhIsXjOxMbMsRH3qKKTn0+H17n1SspcdrSyw9tDdK7H689+97y6MuQixHkofV429anoeUZPqt1+ToK+SYCI90X0Uqy5aeygpH1Z7gPzLP8ejMMWbpb6R83s2ovy5LWz3UwSObUGkj8Gjtnmi1mDZifaMPrZOye8o56MGeDQZnPY97nvViaXsRNpXrmXuZUkrlsx4huT6waCvga8qRDMBrOc6jRkYbUepAqXuo5G5vpZQ6F1GtXbdHrzrSKdc+5dzsee+Rnf623msgnHspdeTo8c4e88jnAYwo0uBM6uc/+1uJ3ew8F45pfZ8wjjOTvinJ9j31wUvLeU5yx4Aju1KVTITv6R6IFJd7Om/kE+kePGstYSbioptlOb/I9Mzn7D0nue+RveNJkRKfRqonsxnp2o30XUaWcp167vO0/vybKOUY0cyb79Tue0dOqh+hjuUYrzj6mq2ylFa7nU95Je6hCPV8z2KYXMfOdbzZnMmNSjnuq7wqceq5asn1US7EmZ18biL8nG5KwuJWpTjS0Dmj9ueRlmyRc4fcKPV+ViOcf/Ghb62fL2uvORLr9naOmdPo13/07xdB6nN7rf3W47M/ejIG20rff1uL+XIdu2Tyy56xhZJtlR7knlSsHRd7vgY9P0N4rlQiYc/3+cy2kixzP5NKmjkBhXJS5oD2xsyURZFn4vCRXwY+Ys84X8Q40fIYOY/z7Jg9xcDS/ZpX97pnRjm1+6pn74vUmH22zKnvjxI/cyudFNnqvB3Jz9hzvDNlOfK5xFKy3VZ64XfrX2B+FmtGjauz2Hou9xjrUvqHlCdGfLdWv87MXT873rPXit3n7BnbTT3Wq+M9O+YM8SvkzvU5LkTJi7l287WasF0r09bkSWkaBH3xsCIC9+G8aj+bmNuZ+yBagskMZjnXtRc4lkxY3iPH5OWe79v6e5KmduLFmePtef2RHeVniXlrco4ltFr8ceZzWw1SGsOZm9iTV0/nc5Zn0tok0ZG4O9K5mVWrjRTOLHjZ+/fU449ghDq5tvC3xO5yI5yzZ0b9XhHsaTOU3k1877Frfd7a5+Z4T4+xO2KC/JnFaUdet3Xdarcxety5n2057tUzvyh+5j0lRCkH5fX4bKSOVwvgSs3rt3rel7TWls51vBLHzjHOd+S9OdpeOXMDcn1ezrqTsx60qFPVk+tzrGIsPcBIGa5Be64By5K3EQEwK/Hwu63O1Z42uwGwMs6sVk95b8TJGXW0nT0DLq0GGlvdF+7HPHIsHCqRsN+LnM9ez3EgmhIJIL3FedLkuP5bCc+5lLgX9yRYqQPt7Z0sd63oWetE4BybPLRKDm8p9Rm4tnColdrXrfX3Xks+W3st7fTc1hzdkfFuY2dluH955Uzi8ZnP66Guj15vUvrNR9qyqeXIsaCzpZTxs5ILp1vWrcv1uv/DL5fLv5dl+b1ccQD+9Lfr9fpr60KUJKYCFYmpAPmIqQD5iKkA+YipAHkNHVfFVKCyoWPqsoirQFViKkA+L2NqUnI9AAAAAAAAAAAAAACM6E3rAgAAAAAAAAAAAAAAQGuS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgepLrAQAAAAAAAAAAAACYnuR6AAAAAAAAAAAAAACm9zblxb/88sv1/fv3hYoC8/nff3354b//8vd/bL527TUlpJQxpy9fvvzner3+WuXDGhFT63i8h5elfj1iDK3icA5iKkA+Yio896zdfdNj+4k6xFS29NwPg9rEVIC8Ro+rYup4Ws3pwh6jx9RlKRNX1WvgGTEVmNF9uyhnm2gtpiYl179//375/PlznlIBy9ePlx/++8On1/Xr9tq115SQUsacLpfL71U+qCExtY7He3hZ6tcjxtAqDucgpgLkI6bCc8/a3Tc9tp+oQ0xlS8/9MKhNTAXIa/S4KqaOp9WcLuwxekxdljJxVb2GMu7r1odP14YlOUZMBWb0Y+zOFx/WYuqbbJ8CAAAAAAAAAAAAAACdklwPAAAAAAAAAAAAAMD03rYuAACU8PgzeQAAAAAAAAAAAABr7FwPAAAAAAAAAAAAAMD07FwPAAAAAEAYfo0OAAAAAABoRXI9AAAAAAAAAAAAMCSbOQCQ4k3rAgAAAAAAAAAAAADxfP14kZwOwFQk12emMQEAAAAAAAAAAAAA0B/J9QAAAAAAAAAAAAAATE9yPQTilw8AAAAAAAAAAIBo5DUBMIu3rQsAABCZwQEAAAAASHMbU/vw6dq4JAAAAACQxs71AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAABhff14Wb5+vLQuBgAAAAAAE5BcDwAAAAAAAAAAAABAWLU2YpFcDwAAAAAAAAAAAADA9N62LsAo/CQtAMzh9sz/8OnauCQAAAAwNuPuAAAAAADUJrkegnucQJLUCQAAAAAAAEBr5q4BAIARvWldAAAAAAAAeOXrx4sdzNnkPgEAACAafVUA6JOd6wEAAAA4xMQQAAAAzMd4AAAAMDI71wNJrKoFeiFeAQAAAAAAAAAAkMLO9QAAAAAAAAAAnbHJEAAAMKqW/R3J9QBQwP3D/cOna8OSzMdAMgAAAAAAMLPbXIk5KgAAgHSS6yEgiaEAAAAAAOkkkgEAAAAAcMab1gUAAAAAAAAAIKavHy82hoIBqdsAAADP2bkeCrsfkLjtlmSQAvqQa6czO6YBAAAAANC7Z3NeQGzmqGAcnsO0UCO/yb0NQESS6wvRSaV3FgDQG3EXgNl5FgLRiVMAAGNYS355nFvQBgQAAACgN5LrCzNoyD0J6xCD2AwAAAAAAAAA5CAHIY8ez2OPZQZgm+R6AIZiEQsAAAAAAAD8zDwaxKee9sX1KqNWwnrOz5FkDzAWyfUA8EAHGAAAAOrTHwcAAGBW+sRjcT3jcC0AOKLr5HorvuCcZw1I9QnolU4xMCvxD4hOnAIAAIC29M0B2uopx80zAwA6T64HAIBI7gebehgcAwAAAACgL5IeAZidzUQhXU+LfCCCYZPrBQNa6X0wo/fyAwDMTl8IiE6cAiAn45lQT636pr0IEItNZaAsfRq2iMP1PNbHtfOt7hJZrrihf87Mhk2uBwBYFoMN5KXzCADfmDgAoAV9fACA/Ix7A1DSq+dM7jFmzzMwdwM5DZdcHzVAGPQHOE4nCGjtSBtT7AIAgG1Rx3OpS/8JeEZsqM85h5hq1U0xAPrxqi99q7/qcztb4xwz548duS9rPwO3Pn/POJb6BzCG4ZLrgTo0Bmnh2X1nEh4gjWc4wDfiYXuuAcxNf358kSfNgfxyxHXPhnace+hDhLoaoQzAa+poHbXOc+TPOdN/j/y9ahwLasvZXzdmx0yGSK73AKtPwPzZrPfhzKtqKS9KvUq5z6OUmedyPr88C7kXse73cI/2UMbWnCMoT58GoB/aRrGV6HMDYxPX4xOPoa1WdVDdByCqlJ3jYST6z1DfEMn1QBoNSXrnHgZ6UrujuzdGSiaNzQ4CUI625DFiCszpMWae+Xl5cWQej/dNq2vvnoM6oravxYDynGPgnpgAaaK2oVjnugFRpcSnPe028S6uV2P25Ndlcr3KG4dOMswtd2Km+M4ej8+e2j9TB72KFGNrl2XEOh/pegLjehZrxB/g3lo769W/iSPHRJ00aXk9UxcWRzlnMLsjbcxn/763To+yuYBYBgAcoQ3Bmp7GaHoqK/Si1HhjiV+3zJ2TFuW56Dn9WsovlZQ6f10m16dwAwLkp+NyTNSJ8F6VvA9zr+olth6Sfs7cZ6W+x9Z5S1kA8+o9uetVz/W157IDbBHjIIYcP6sdeVFOT7Gmp7Ke0WrR7bKMf24hotJ1fpbYWUuJ63VmkQSM7FkbJUobGoBvas+15X5PSXs2XphVtGs1Ouf7vDPz+nteu/b3kptszh6LZlCq/g+fXF9aq91yW/+U7p6/5yxb6e+bEqA9hF/TUOGoERoydk/nGdc4tsd629Oiityf/+q7p3Q8z5zPPcdITbyvNWl/s+dn8/ZcryMJa3uPKRbBtpL1RV0E9krZDX6rHVerv+2XifJIaVOXOAdn2t8px4903XJshFBrsTBzat0+jTxuO+ukecQYE7FM0IPR49URFuFAOaMsNi61GVXrc1Lie7X+TjC7MwtP1sZ2o/S/juRWnHltyvk8Mt4RJQd3778/e23pvNqblF+x3TrWs/dE6ieFTK4vOTGQY3A8kj0Taqk/jflsVVCOsqX++9p79oh4vWYRuc6MotYE6tprUssU8b44svIx4veYQaTG0ysp9WPP93GPjedIB20ruSbCrm+t6uer81mqI5/zWJFi2tZ5PNNWX+tX7Nmh4NXxJS31r+dr13qhe63PjRSnbmovuq9t72B6yrFGPVczSVnYmPrvM9iaiFmW7XZFSt8tpd9XYvHDmX7m2kRdyvF7suf+WJa0sfI9i4Uf/00sbatG4nrp4z+LJ6kTmb0nWp3pj0f5vqPF2Ee5v1/U68iYSizES/m8Hu1JfOpxE0IYWY75qyM5SynJ7jlyl86+poacc02txpTFZ1rbGqMrnXCdY0yt13nnVL2fmyOLm/aOSeZWYhw61y+WRL6HL9fr/iDw22+/XT9//lywON/sTbw4IvfqxTP2NiDPJru33tXzsRxnHlo5Pj/X8aOsmtlTjtZlPVLvLpfLl+v1+luB4oRxJKbmTLhIPfbIjkxql6xXuZ5VWxO3a+/JOYiS8p5WWsfJNTmSSMXU56Jc54iJ64yvxm62uRbt5vi8nIO5Yuq6IwMqKYsqzsjR/9vTX8+ZmLl17LXjr5UjRzJpCWd2cHkmxzXZI+cA6h45xnlqt/tfEVOf0waE+eRo64ipzz1rD6Q+y3IlCG3J1U8701ao0VeMqNUCmNznObW8teY/j7S/z4zVPzuGMdWflZr3b5W8lGuDiNTXpvTXo/S9e1Oi/1r6vnl8T+uF/Lnnj8XU51Lj6owxYNa2ZmvmIWMTU5/raUxVG29MOWJn7bly8sfUajvXb0001rqBIq8Mr70yJeL367Ex3bqsrT+fWI4MFruHzq2cq72zVY5VmGvH2PuePY3Anu6t1gOca3o6jxyzZ6Ifcqtxj0Xpb9z/W8Q4P4rH83/m+j97795reDZ5IqVMr/6eY1eGHO2rI22+1kr1Z0q091M+N/dYR47j5mzDi7EA+ZRqy5D3eVlKqbZCyvGjthNb2TNOG2m+MVq7rFa9i/a9Z1WiH5uS0LLnvSX72mJsOanzVinjIbnHr7Ze+6yMNTZKPPI8c79Sgvuqjd5zsiA69YlX3Bv9S9q5/nK5/HtZlt/LFQfgT3+7Xq+/ti5ESWIqUJGYCpCPmAqQj5gKkI+YCpDX0HFVTAUqGzqmLou4ClQlpgLk8zKmJiXXAwAAAAAAAAAAAADAiN60LgAAAAAAAAAAAAAAALQmuR4AAAAAAAAAAAAAgOlJrgcAAAAA+P/s3bu2G7kVKNqihpKbqxMn3sFNHbU/xH+koT/yh2hHTk/SiRM7PyFP0IPWFkWygCo8FoA5o+4tPsCqwio8FlAAAAAAAAAsT3I9AAAAAAAAAAAAAADLk1wPAAAAAAAAAAAAAMDyJNcDAAAAAAAAAAAAALA8yfUAAAAAAAAAAAAAACzvc86Lv3z5cn17e6tUlHX83//zvm3btv1////vnUtCb7dr4eZ2TXz8+6O/ffz7rN7f3/97vV5/612OmsRUoBUxFaAcMRUeW63PShliKrmMq8JzYipAWbPHVTF1HdrQRDB7TN02cZVj7sdUb8RsXhFTAcp5FVOzkuvf3t6279+/lynVwv71j8u2bdv2t386lqu7XQs3t2vi498f/e3j32d1uVz+6F2G2sRUoBUxFaAcMRUeW63PShliKrmMq8JzYipAWbPHVTF1HT/6638mcP7tn9d+hWFZs8fUbRNXOeZ+TPXGuAeviKkA5byKqZ9aFgQAAAAAAAAAAAAAACLK2rkeAAAAAPb8/EQ2u+IBAAAAAAAAY7BzPQAAAAAAAAAAAAAAy5NcDwAAAAAAAAAAAADA8iTXAwAAAAAAAAAAAACwvM+9CwAAAAAAAAAAQBn/+seldxEAAACGZed6AAAAAAAAAAAAAACWZ+d6AAAAAAAAAIDJfdzR/m//vHYsCQAAQFx2rgcAAAAAAAAAAAAAYHmS62Eh//rH5afdCIDxqdcAAAAAAAAAAABQhuR6AAAAAAAAAAAAAACW97l3AYAf7D4N+W715m//vHYuCQAAAAAAAAC0Ya4cAKAOO9cDAAAAAAAAAAAAALA8yfWwoH/942KXfAAAAAAAAAAAAAD44HPvAsCKJLYDAAAAAJx3G2v92z+vnUsCAAAAAMAMJNdDcBLxgUfEBgAAAAAAAAAAACjrU+8CAAAAAAAAAAAAwOr+9Y+LzfYAoDM71zei0QMAAAAAAMBMbvNff/vntXNJAAAAAKAMO9cDAAAAAAAAAAAAALA8O9d3ZDcPAAAAAIDXPBUUAAAAAABoxc71AAAAE/vXPy4S0gAAAACAnxg3hHk8q8/qOaRRVwC4Z+d6AKAIT2QBAAAAgDUZGwQAgH0SuAFgDJLrAZiCyRtG4noFAAA4Tp+KV1wfAADA6iRwAwAjijS2K7keBhUpkEBrBgOYhVgOAKxAmwcAAAAAyjFfDgBQ16feBQAAAAAAAAAAAAAAgN7sXA+T+bhC2a6AQAt2RgAAAAAAAJiT+WcAAGA1kusBAAAAOMRCSwCicE8CAAAAgPHdxvks7KQnyfUAAEBIdkQCAACekUwPANCeRCeAdsRcAOhHcj0ATEACKgAAAMAPkhAAAACIwgJxAHgu4n1Scj0AUzORymhcswAAAAAwFmN6AEAEERPT9mhHAXAz4n2MeUmuB4CBaEiOLef8GUgCAAAoz5PfAAAAgFZqze+bS4b5qNcQi+R6AKbyrLFp8rwfHQCAPizIAgB4TX8VgNKMQwO9aNsCrGkv/mufQnxH5nS1/aA+yfUAABl0UoBRGUAFAACgN33TY2wqAwAAAKwiQm6W5HpoyO6h0I76to4IDaqzXK8AwApmaLcBAEAExhOBZ0rGB7EGqEmMIQLXIbMw/wLlSa6HQiLepCKWCZiDx1IBrYkh6QwEAgAwK21dGM+requvDxCDeAzzG+FpNyOUMYJn7ev7vz86huI9zGf2sTJxi54k10NlrW5is98sAUZ2JkbrLAAAALA6Y58AAD9EaBuZu4D2ItT9XsScfCnXi+P6K8eE0bmGoRzJ9YEIbnOJ1LHZW7nqmgNSRYpt91rHNDEUAOAY7SgAgHlFHj8cUc7x1M4GgDloT/0Q5Vgc2RW+ZNmjHIdc2qfw2pG6PWo82DPr72JskusDGCk4C1qluQAAIABJREFURG749CrbSOcPGNdIsaZVPE49JrUfIZgymAL87Fn9VX/2PTp2jhsAcMYI430A9CUejynyPR4AWFfOjupnPn+vDZQyh7y3keWj947Qdq5ZxhF+P9T0LH9klrqhn0lpkeuG5PpNpU8R+SKOXDagjNpx2n3guYgxNmKZgF8dia3q9zmOHwAwi5KLqfX5AVideyGQ68wuqmINjGNvp/VX9bnX5mMlYs2jGHfmc83NjMc5o6VSu9P32my45veqi7/Spo5l6OT6iBdTiUof8Xc9Y7f4X7UuW8lrbtvGuO7IM1JMuXd/fZeuX9FiSbTynNX7EValB0aOfG/J7xm5LvPYq3N6ZFeNm/tB0NmumVl/F3CO2ACQr9cYVs7k/JnPrz2mQBsjnrcIE6BQSq86qH3/XImdXh1f4Jne8zqwulb1acSclmefWXqMQUz71UxPo3Z+qan29ZX7+aXyVkouPpptF3+OG+UaGCq5vsTkSsprnj2y51XiUw05CVd7k0fPPufV9+a85szjkmo1dnPOI4wup/OYUgfOrFIfQcrj27btXOOw5zGKUIZXai/oqfWYwFEad7RRo57lLAh5dT0+a6fVfvoHdeWcc4A9JfrNI20uMFt/hvWU7kO1nqwfYYwuYplWNfu5GKleQEur1I3evyfi+EHvY8IxNu3qJ2I9vqdew3hS5s73EiJ7L8rknCOxOyVP7cznj2DW38W8SibKv5p3EZv/pN9UVo8NTYZIri+ZYN26HLW/N/IOTKllqX3h1zomkY51SSXqjgZkPTnXXW4C+aukzmd/n/0cj56QOsJ56n1vTdnRsPRjBYnnTCLhmcGmZ/+f894cvWKCehBbzevCgMFachYDRe7vlUzCjtYWO9Le/yj6jiKjxxwLAHik5CKWs6+t2S+qHcuPvLfGhiZnpd5XcuJhyiRYicm21PKkfMYRvRZzvfq3qPfTGUVrk/HakWStvT5I6XNfMonIRh/AvdXvW6v/fohM22Qts5zvGr9jlmPDz2Zf8N1ifDblM0bMdehltDmvmmMxPRdvVU+uP1Ipcn9szqD12c8bWeogXqnvifoZOatrV7YX9HJuiiME+Vm0jnmlYvyM10rEhk7OxA+soGRyQ61EpJTPP/pZo8fjyEmIZ8rWe9HRTekEutaLn1MTySJdN7Mo0U8404569d4zC6Jq9KNLJWgeSQQ9Imrb8UwfKHIMGKGM1JMzWBy1bqaIXPacvsLeOcnZtSknUTPlPTmL3/Y+4/77jpBEui/ieBJrGrFOnllQdmbDhSPf9+z/I2yIUHIRV+53E1+rMZ+ISiRc1Y5T0aQcm1Z9+iPnadZjTkzui4zsyP2t5+L3Gp8p/sZ0ZH5nlXg8wzVbeo6txGccGad9Vo5ZjD6fEXLn+tEO4mgc3x8ci3SOFaWUXhAVReTfVTKBeDa1V8/CtsW9hs4OAkX7XTllPjPZdWTBYe53tLD33ZEmBlsvHqSd2gt29xIHcwZyStT1EgNHOW3OkepBziBoyfN1JDGo9KBzyfM0Q/IF6VrXcdfXvpyE9dzPOPueGrFmxITKM3H/1XtGuueuLMLChdaJJEfanyPG99T+7dnXtBChHCUXceWMoZS8v4x4Hc+sVNJLL6l97Qj1N6pWbdyUBZxHYlyOZxsf3H9m6ST/I2NCJdvDABBB6pwQP8zWhk2d33/12pxx8CNtsCjJ5mfamkc2iKn9O2vV85DJ9QAQiYEjgD+N2sF+1nk782SeI98/2z2kxPUw67FhDL0TU1+9puRCnlFFjw+v+ghHJvhTvidXrcUD0c8NbYhXPDLS+d+L1aUSrIgpdSKz1lPI9l5b6ukOFipTQomxklKL8lMn9EdP5h5V735CrY0iohixzK1FuO+1XoxR47qovRCKH9RrImp1XeaMQd70TkRlHqXaDK7JPiK0+Uo40k+uMU51pP8c8XjWcrle0w/65XL5z7Ztf9QrDsD//PV6vf7WuxA1ialAQ2IqQDliKkA5YipAOWIqQFlTx1UxFWhs6pi6beIq0JSYClDO05ialVwPAAAAAAAAAAAAAAAz+tS7AAAAAAAAAAAAAAAA0JvkegAAAAAAAAAAAAAAlie5HgAAAAAAAAAAAACA5UmuBwAAAAAAAAAAAABgeZLrAQAAAAAAAAAAAABYnuR6AAAAAAAAAAAAAACWJ7keAAAAAAAAAAAAAIDlfc558ZcvX65vb2+VijK293+/b9u2bb//5ffOJWE2q15b7+/v/71er7/1LkdNYmocq9Yz1iGmApQjpkKaWxv7I+1t7ompAOWIqQBlzR5XxVSgpdlj6raJq9T1caz1NsZ6P/5q7LWMR+Pa2xbr+IqpAOW8iqlZyfVvb2/b9+/fy5RqMpdvl23btu37V8eHsm7X1vv2ZwPu+vXaszjNXC6XP3qXoTYxNY5V6xnrEFMByhFTIc2tjf2RMRPuiakA5YipAGXNHlfFVKCl2WPqtomr1PVxrPU2xno//mrstYxH49rbFuv4iqkA5byKqZ9aFgQAAAAAAAAAAAAAACKSXA8AAAAAAAAAAACdXL5dnu6cDgC0JbkeAAAAAAAAAAAAAIDlfe5dAKC+28rW69dr55IAAAAAAAAAUIJ5YIDx2a0eAOKRXA8AAAAAAABUI/kTAAAAgCM+LkRrNbb0qcm3wEIu3y5WlQIAAABAJuNqAAAAAABAb3auBwAAAAAAAAAAgCBsQAAA/di5HgAAAACAMOxgDwAAAAAA9CK5HhZiYhIAAAAAAAAAYD5yQgAAypBcDwAAAAAAAAAAAADA8j73LsBsbitAr1+vnUtCb64FAAAAAAAAAABqsls9AEBZkusBAAAAAAAAAAAAAAih5wJCyfUnWf0JAAAAAAAxecIoAAAAs5CnBgBtSK4HAAAAAAAAipP8AwAAAMBoPvUuAAAAAAAAAAAAAAAA9GbnegjITi4AAAAAAAAAAAB1ydOCn+vB9eu1Y0kgBsn1AAAAAADA1EwQAgAAAACQ4lPvAgDHXL5drJwEAAAAAACWZa4EAAAAgNLsXA8AAAAAAACwgNtiBE/xgHFZVATscb8fmzgPAP1JrgdgWTql1OAx8wDAyrSxAQAAAAAAgJF96l0AACAuj1UGAAAAAACIrcR8jjkhAACAP0muBwCoxEA0AAAAAAAAAADAOD73LgAAAACv3RbqXL9eO5cE4DixDAAAANrQBwcAIIUNI+ExyfVQ2ccbkMELAAAAAAAAAFqSbA8AAJBOcj0A3DHASGmuKaAU8QQAAAAASHW/E6mN4QAAAPZJrodCej0iRYIVUbgWAQAAAAAAYCy95rkBAACiklwPAAAswUIwAAAAgD/ZvRoAAADgMcn1AAAAAAAAwDDssgwAAABALZ96F4CxXL5dDFgCS1s1Dq76uwEAAAAAAFZiTghgPGI3jEe93ecY0ZOd6w9QYQGYnXtdHbfj6jHLAMBstB+Bo8QPgLV8jPvGyADK69W+Nv8BMambAMeJobA2yfUAAMDUJGwBxGJAGmhBrEE/ANYi7gPk014C6EscBoB8rcaAJNdDR0cqusY1AAAAUeijAgAAAAAwM4t55+Opaq+55kFyPQAcoiHJPYlljMaAAQA5tH+BUdz3zcQvAAA4JqUtbW4EAJid8UVYk+T6BGd2FxdUeaTVIIPBDOjnUf3rfU9wb4L5SJAHoDVtSqAlMYdaXFtQn/kJAID6tLmgLXOz1NBrnGqke8irsqqL1CK5niQjBdMRmcxhVKvEhtq/s3cMmLUD2Pu4ApSwyr0WACBFrX6e/iMAKzDGAJSg7QwAAKxAcn0Gg04A+wyqPdfq2Ox9j/tZWUeOp3pCDa6rdDnHynEFeEybEoimRFzS9nvOsQEAWJcxAIByxNRYnA8eabUBJxCb5HrIdH+DKzmhdObmaYILyqvVoK1RX0uVVaI4xHRfz0rHJ/UYAICRHGm/avPS2qxPCoQ9NcZUJR4Aq9KGBSCXewcAM4gwFiS5HhpqUekjBBZY2ex18FVnfLWOul0R6WH2GDObmnVcog4AgPZxD737sY/O+Qjt4d7HDQCYg/YvcJQ5hf5ax/BR+8/QQ5Q2VsTxo4hlglYk10OCKDfRUs4kx7ppws9K1ola9Wu13aIilw0+qvk0HADamH1SqtWjTx89mWXG4wnEo/84J+cVIJ+5H4hlhPbMszKKJwB/Eg/jGuE+C0C6WvdcyfUfvJrU5WcagT/McJ3M8BvgmUfxKnqyec4q8oj1N9o9onSSVsRjDvwqUl09EhcjlR/4lTpaX7Q25U3UcsEzsyxa6bW725ljNku8yDn2z16bMqZx/5qcxcitj/Us5xZGoN1dhuMIRGHDGWAF97FOWyyPPje1namTxlpjEjfmUmI8uhTJ9VubgOFxO0T06trfqxduTOyJNkAWsXF4pEwRf8czEeNE6vGLVOabiMeTslp1xkeKI7Xl1Ct1ENgjThzn3gRtlOynl0w+b+3M4HxOu7G22ved1LHBEp+V8tqUz4iyCOPMeI92BFFEjn97ajxptNTntRblnADpzrSFokmJx9pAzx0Zu75xPIFnVo0Xte437mOsxPX+g2OxjumS66NN7IzY0YUcr65xNxF6mDXuzp6IP4IREj+IqdTq99z3uA+3dbaunjlvNfpArh84buQ4PHLZYSatxzdzkl72/j57/DjbN79/YuqZtl8NPfufI/d9Ry47cxuhbVfzPhJh06te50BcIrrV2pCrE5POOfNUVHUrtrOL+ErMPUW7rlLabxHvIeLcn87kDj16b+7T8fbKkPLvLYnVvBJ5g7hW31c7T0Id7CtSPH6lenJ9jR2R7j8r5SZbYveY0vZ+z6iruCOXLVWE6wNgFiPeF3rtdkdbNa7NUjuaWeyZrkR/49G10OvpViPEn5pxPULyA9QWKcFmpPoVbeJs9F1MGUPtenv/+bO3GyPIPeZ2qYylRB25bweod0STek3Ofu2W/n0lngQwW6IEfDTDdZfTR9Qe+FXEa2CEdrZrZz212yhn3lv7qWrPPv/V/E7Oe5695mbWmN36PEb7LJhJ77mniG2lFL03wFvFqLF76J3rj+zAFFnqDlCP/u1IQ67EYzxTynbk+0forLLPTSSmlPpVY4HSq+sht86PENP5VU5iSIkJJzjr7DU14jV5ZreSe6/uHTUXHoyUnF5azi4eqcex1IBx6mB2zmfdvPp92qHtnenLpSx0eXZNnolbtdoZvSbLj+zMkfr3HvbKWGpnrxJ9kMhjGaXrJv1Eqp+PWHhS1tm2pnNwXuu2u/NXXu/J5UdKtF1f3dv3FvJEe2pGy+8r3Yb8+FklF+D0en/KZ5WqSyXHoJ4RR9uo2Q860r+tPU6U0zeMuPlfdBH6n2fGIVLnV0s8NSzHozZmat3VPm0jwrWfqsQ1WqM9+ujf98ZnjyyMml2LNtrqHK96Wo/PR43drcpVug/c4jjm5ODmvLeGlHms2jG7Vf8psubJ9W7E6XotHmg94Z/z2leDlDk7/5coE/RwJEGnRpLIGa2/j9hSz7Vrgppmvb5KDLbXerRi1AU0tb+j17VWauKlxOfWeM+ZgRDqezUwdmQiJuc9Jb6vhCPfWyJBZ9b7271a9bzkIoXS4xOpn1d6oHjvmhJruZeaEEo7Er1+5Ziso9Q5rbFguITS8y29RCpLqjP93DMLHkccY2jxec8+W1u1rFpjQiXnj3L6NLXHJnuNR4ysdDJ4r/5syrmvGZ9y6kHKfcZYaz/ixTnyE87Rb2ZUvfpQrcZEc+ZPWxyDSP2vkRdanJkjPZPbkfKeFfO9L9drxo++XP6zbdsf9YoD8D9/vV6vv/UuRE1iKtCQmApQjpgKUI6YClCOmApQ1tRxVUwFGps6pm6buAo0JaYClPM0pmYl1wMAAAAAAAAAAAAAwIw+9S4AAAAAAAAAAAAAAAD0JrkeAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmS6wEAAAAAAAAAAAAAWN7nnBd/+fLl+vb2Vqko63j/9/u2bdv2+19+71wSertdCze3a+Lj3x/97ePfZ/X+/v7f6/X6W+9y1CSmjkkMZ0RiKkA5Yiqct1r/lufEVIByxFRaejSHAbOZPa6Kqeu574tvmxhOO7PH1G0rG1cf1ddtU2f5k7HVOHqdCzEVWEntPL1XMTUruf7t7W37/v17mVIt7PLtsm3btn3/6liu7nYt3NyuiY9/f/S3j3+f1eVy+aN3GWoTU8ckhjMiMRWgHDEVzlutf8tzYipAOWIqLT2aw4DZzB5XxdT13PfFt00Mp53ZY+q2lY2rj+rrtqmz/MnYahy9zoWYCqykdp7eq5ialVwPAAAAAAAAAAAA1PdswQUAUM+n3gUAAAAAAAAAAAAAAIDeJNcDwAGXbxcrxAEAAAAAAAAAAGAin3sXAAAAAAAAAAAAgMc+bvx2/XrtWBIAgPnZuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmS6wEAAAAAAAAAAAAAWJ7kegAAAAAAwrl8u2yXb5fexQAAAAAAABbyuXcBgHZuk5HXr9fOJQEAAAAAAKCXjwvYzBsBAAAA/CC5HgAAAAAAAAAAAACAriI80VZyPQQSISgAAAAAAKzEEz8BAAAAALj51LsAAAAAAAAAAAAAAADQm+R6WNDl28Uu+QAAAAAAAAAAAADwwefeBYAVSWwHAAAAAAAAAAAAgFgk10NwEvEBAAAAWInxMAAAAAAAoBfJ9QAAAABUJ1kWAAAAAAAAiE5yfSMmkAHmdIvv16/XziUBAAAAAAAAAAAAzvjUuwAAAAAAAAAAAAAAANCbnes7stsxAMzn49Nq3OMBAAAAAICI5CvAuNRfAIC6JNcDAAB0YDEOAAAAI/nYjwVgDGI3AABAvk+9CwAAAADAui7fLib7AQAGpS0HAAAAwGzsXA8AAAAAAAAAAAAAQCgfN3a4fr02+U7J9TCoW8BoFSxgZXZeAgAAAABgVuacAAAAAH741LsAAAAAAAAAAAAAAADQm53rYTI9HoEBAAAAAAAAAAAwq485WUAsnshGaZLrAQAAACjKwm8AAKIx0Q4AAMAefUdg2yTXAwBUo9MFAAAAAABEdr8LrzkNGI85SQCAsiTXAwAAAADQ3bNHa0sSoBaPcwcAAAAA4J7kegAAAAAAAAAAgIFYMAwAUIfkegAAAAAAYHmekgBrWL2uS8IDAIDyVu9nAMxGcj0AAAAAoZiIAAAAAAAAani06Nh8BIyl9lyi5HoAaEyi0Jzs+AQA8Jh2EgAArRh7BQBGZQwNIBb9yzE5b5QiuR4AAAAAAAAAAAAAgLBaLUiUXA+FpKx6ar3S2EosABibe/lzIx8bu88AMxPjAACIQLsUWE3J8dKRx14B4Az3wLXpR47JeaMWyfVQmQAOa4i4wCYaHVGoa5U6ViOWRjh2EcoAAAAAK9InBwAAAOAjyfVQSa9d6nP+zYAxlLdivcr9zR9j0krHCZ55VIdWX4wDwJrc/wAAOOpIW1L7E5iR2AZrW3Guegb3sdv5i8f9dR698vnUa6inVj2TXB/ASI2kyAG/V9k0oIBHSsWGyHH3XomyjvR7oSV1w2JBAIARpCymvm+/GVsDAAAAOMY8WR2OKzNyXTOCSPMFkus3gSNFpIsWoDb3hbLO7BrV6xw8KvNeYgjkur92VlyUAwDAHI48UbG2ZxuaeJoa23buutTngliMzQEAMJIjGxNQn34FpUW+psQYSDN0cn3kih45QJZkt/hfRS7bMyYV4bFej4N69W9R6mirJOCSu+Gf/ZwzUn/nq9fAttnlszTHDwCgnr221pmF2I8caSOXaA/O0IeLNuZQS+lrI+e4rXKMYXTqqmMA/CxnIyIAyjOP1V+tc6DdTUtiCXvkLD02VHL9mRvLmUSkV99bI/g821UptUxnXvvo+1Nek7Oycu91Z9+z91mzBQA3QEb1KG48i9Wv6u3IdftI2Vu959lnRND7nJf8/kfHtffvYwyR6uQZ0a73nE5jyXYqAM9Fu1cAcdVI5m8tYsw7MlYTTatzbzE0z4xYb+71qke9ytGLyWxgBDPc12AF6uoYSrZvnfNfPTu+H49Rzbw/4wN8pL8H4xkiuf5VIvfee+6D0ZldgaM8wjj133o7cjxzk5hSvrf2KsLZlEzC1Rhop/Qx730OI8bbaN9b4j21Fo3V+D2l7oVn7vVH2iNn9K6HUFpOO7xWjCvhTMw5sohVDIBxtbqXR2kzzNpHvolynFnTmYmXI++dvT7X8qwdV3q3z7025pHF+M/+P/XfnpWtt9bJwCnfq72/thIbSD0T4VoqOcfWO55E3Km59QYqNTf5gpGMcH1Ha79r7wA8Fi1eR5V67z3TZu81XsC4auVk3dNuojUbgr7WLLm+5sBf6eTzWW9urRYPnEk+rLEq89XfrRJ8LvV6ebWiU7Ctp9X1vdegy/nsV+9J/ZwzC6RKvWdGo8bAGtd2bZEThld05NieSZhpfd21Tuq8OfO7a7UFW5Sp1PdxnB0fiKpWPN7re7eqB2IclHdmrDPlyW+UlTJG8+zfnvUnjizKzHlvrSex9RaxTHuMTbXTur9Qa75lNZF+f+oC+ldzJjnzc6lx/sh4Vo6RFkXAWRES7VIXUEaIjyU2TNn77I+ff+S998SnfWI5PRnjL6PEuEDE/lOp10BtJfpfs47dlTT776vN8UtTPbn+TDKKk1iH4/qDY7Fv7xg5hm31SlAs8dmtB/Brff5MVv3d8MyRyYCR61FK+3uW5KzI963Uz0q5LnsvMKs98ZJzLCxMiq3k4qbSjiwyvv+3s9+R8t5WUhaPtXLmGjgTSy0iZzQjtdEYa+H3kc9vvdB3ZJHuuZxLRolQr1PLVjspe1Zn5kxqHM/Zz1GrRWPE0vq854wDn3lK0Jn3RK7rJcrWuv0421M5Soyb5Sz4HeGYjKbFvH7KeOarcbGcBYZHy7j3t1dmq9e1PTv3r85F6+MW+d4H21Z3oeH9d3x0/30lngwfOS7WmhuK/JtHNsI1laPZzvU53CABAOhlxd3lSk7ajPS7R1Jikq/EAPWjz0+ZeCm5u9asg0MrSI01r3Z6fPbe0olBe4OSJeJjTrJAie/LmUBrnRB0xJGFDr0TJl6V9chjjp99bk6C5rPvT/k+C5mAHqLchxhHTnJI70XWvRZSnlk4mvK56u16aiTd5Xyfdml9Eep1hMVMpHmVxJQyVtJ7YVLJGHOmr11qTNQ1TIojdfHIgoyS1+OZsd+z33dmXC+KEcoIe/b6IbX67a3bKiXmq1rp3Y4r8TmRNggrocRcaco4UuTrMsfles2YLLxc/rNt2x/1igPwP3+9Xq+/9S5ETWIq0JCYClCOmApQjpgKUI6YClDW1HFVTAUamzqmbpu4CjQlpgKU8zSmZiXXAwAAAAAAAAAAAADAjD71LgAAAAAAAAAAAAAAAPQmuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmS6wEAAAAAAAAAAAAAWJ7kegAAAAAAAAAAAAAAlie5HgAAAAAAAAAAAACA5UmuBwAAAAAAAAAAAABgeZLrAQAAAAAAAAAAAABY3uecF3/58uX69vZWqSgwp/d/v+++5ve//N6gJGN5f3//7/V6/a13OWoSU4FWxFSAcsRU+Nl9n1f/lhxiKkA5YirRvZor0YYkotnjqpgKtDR7TN22seLqXg6Ltlk/t3NzOwfa0DwipgIreXQvLHkPfBVTs5Lr397etu/fv5cpFSzi8u2y+5rvX9Wre5fL5Y/eZahNTAVaEVMByhFT4Wf3fV79W3KIqQDliKlE92quRBuSiGaPq2Iq0NLsMXXbxoqrezks2mb93M7N7RxoQ/OImAqs5NG9sOQ98FVM/VTsWwAAAAAAAAAAAAAGdfl2SdpMFYB5Sa6HBWj0AQAAAAAAAAAAAMBrkusBAAAAAAAAACZlMzYAAIB0n3sXAACi+zjYeP167VgSAAAAAAAAAAAAoBY71wMAAAAAAAAAAAAAsDzJ9QAAAAAAAAAAAAAALE9yPQAAAAAAAAAAAAAAy5NcDwFcvl22y7dL72IAAAAAAAAAAAAAwLI+9y4AAAAAAADk+rhZxfXrtWNJAAAAAACAWdi5HgAAAAAAAAAAAACA5UmuBwAAAAAAAAAAAABgeZ97FwBo5/aobI/JBgAAAAAAAFjLbb5428wZAwAAPCO5HgAAAAAAAAAAAACArj4uCu7lU+8CAAAAAAAAAAAAAABAb5LrAQAAAAAAAAAAAABYnuR6AAAAAAAAAAAAAEh0+XbZLt8uvYsBVPC5dwFWdAuo16/XziUBAAAAABiLCSsAAAAAAKAWyfUAkMECKQAAkNgKAAAAAFCDsVcA6E9yPQAAAAAAMAUbIwAA5NF+AuhLMj0AxPOpdwEAAAAAAAAAcl2+XSQjAQAAVRzpb+ijAMzBzvWNuGkCAEB5dlUCAAAAAAAAzpLfB8CNnesBAAAAAAAAAAAAAFieneuhEqsZgVXdxz+7SQMAAAAAALRnzhoAACCfnesBAAAAAAAAJnD5dpFMCwAA0NBI/bCRygo92bkeCnPzAZjbLc7bkR8AAAAAXjNnAgAAAEAprfK2JNcDAAAEZ2EPAAAA/CBpH6C8+9hqLBJgLs/a0OI9rMn8M7z2qXcBAICxeWQUAAAAAAAAwPjM/c7BeezPOQAYm53rYXBWkQG0oeMLAAAAAAAAwCjMcQPAMZLrAeAJHU0AAAAAgLpsIgQAwIrO5CM8a0PLcYA21DWoI6du1R5PklwPE3MjB4jBBCHUN2s9054DRjNrPAYAAIBVfRyj1N8HgMeezem5jwKMSXI9DCpKopVGIKwpSgyKQAIZAAAAAJRn3A2gL3NBsDa5IHWIrTG1Oi/6OADjkFwPhZRoaGlEAQAptBkAAAB+JkGrVWEfAAAgAElEQVQB5qE+A7RxJN4am4YxaV8BAOSRXF+ZBioA9ww8zsGgMwCwIuMcAAAAAACxGLc9xnED4BnJ9XBSlIaWhE2gtyjxsBdxGAAAAOLQTwdWcz8+Kw7C2lafswEAADhDcn1HBrV45uNgh+sDYFwGrynNNfXDqsdCHwIAAAB+pb8MAAA8oq8AEF/E/A/J9TCZnoFGg5TSUq4p1x2wMgvyAAAAgFVEnGgFAICeareRo+RjlCzHkWP26vv1U/goSp3JMWKZoQXJ9ZMR7ACoSccQoC7teQCAY7SjAGIpOY6Y81kj3Q9KlNV4LQCM7/5+PkI7BkbQauHBmfeq77Sk/0gvo8a8ZZPr7fLJWa1uOPfBxY0OHhvxRjximY8Y/XeKu0TgOkw3eswBiMq9CIhALAKIr0SCSclyRBwfkIQDzEA8ArZNLMgx+piGc/2n0c8j5zj/RLZyPnSte9QQyfW9H+0S+XtSvn+1ylJbr3Pb+5qCmZRY/a/zWEbr4xjlvEUpB/HNujMbv8pt62nvAwAAwBwejQns9fXNGQHP9J7LNlYJc9qLLWLA2CKfv/tr70xZtaE5yrUDaxoiub62yI2EEmb/ffdq/F43yV85JvMoVWdKPq6uRAepV9L2I6vE31St48ej73v2VJDWC/lWu0cD6VaNJTP9FlidRUAwjhHuv8ah4hLvIZ4R4np0tY7hmb5+yScCuDZgTr2T6gG2bZ226Ox94VJzVL3yPNybYAyzx1J+NVo7oXpy/bMbVokVZLUO8pmbO3GMVhlbspJzLSXO97P3HrkeHn1mahlTXleqTLnvLf3a1M+KsHigxGfsJbu3alSLcWuL1HZo/XjwSL+9lEdxo+bvPLLLXK0yjHgexV+iGLkelRC5Lq5+bqCFV/31myO76O4lBZaafD1j73dGaOutJnLcj1w21tX6qc2vYvfqXo1HnP08gEeixQltJYCfRYvTZz37PaX7CkeeljDbseYcCzV+GOF3jNSGjFbWEc7vvVHK3G3n+pIBrNSF2vukRUl4HnVVUI3z1/uagD0lFwOlJD7n2NtZ59Vu4qmf3fO1JaV875GJmGfJATkd216Joc/+/+Pfnh0Ti+NIdWTwZ3Y1nuKQsiAqZRFXjacS1X5aRa9raW/BUs+ypWq9OALgplWsEdPoocai6ZS+aupk6JH3pryn1ljr3mtaLxZ/pUZfP2Vc58hijMiejVmUaK9awBHLKvfpV3UwZZFRyr9FkNK/TBkzP7IBTdRjU2peYfY6ApFFjS97bAwDP+S0ISL1L1PltDUfvafFZmul5pRHjcmP1Bg7qm2m408Ze+M3vcoRPW6fNUKfsfR9psRYYK38phbX/avjOUts7pZcn6JWwnjue1pNqLb+3hQ1yzJCUOWHWYLe6HISQVOSlFtw7dTthJ5Jts9JfI3oTIJGNCkDTJHaB6tI6QyMPAmQkzBUekFs6/p7JIbuDe5GOY+vHFnYFvGJKKn3ryPnE7YtbTHfkc/rfd3l1O/a7aa9eptTtpQY0HvTgiPf2/t6STFSWVfw7JptvUPuSP2uR3pN+J7p5+3F91Lt/JrtxDPXWK0YVDoxnnhaJyK9mv/ofV2XWEA06nV/Zsw8NSF/JCm/IeX6TG2XaEeSqsTYa6l56L3ru5aUxNpRpIxJnvlcseWH2m0Mx7yflPHLkc9PTpzIXSz56jUpfYQR4y6sKrW+Rki2b5WHGdWZPN6bM33Vj/+2N2ZyZHOZEXNIUsaxXh2LKL+jtO7J9SUTds5+zt7np+zwW0OpJJEzA6klHQlcOZ+x99qzwXUVJSZhZwuYI3DtcsRs143fQw0lk5N6T8aWmEQ/8t6cDuer10RJ/i45ATSqnP5Fjev9TBIE5aVMNpc8D60mmfc+L2Vxa0oSVer3tEqWrWXvHlFqIVaLGJ2SkJpz3vZi6qsxqSPvuRl5AQmPRajr0USYMNv7t5oJsLN5NBeQes9oNb6fc82tdv56SEnU2Uu2KRU/cif6P+o9r8MPqx37M+3ulMUMOfOBuXWx9vzxyo4kMKa8tuSC7JTX3pcj5TNSXrN6stRNqzGanOvkTPJszhhoa0fG5PeMvKBjNdHmoFLUmHMr9X0RjxdQxqv4MWJ/oeaY1ralb0RXIg/07HvOqJETcGQsstbvTu0Dpbx3xbHqy/WacfFeLv/Ztu2PesUB+J+/Xq/X33oXoiYxFWhITAUoR0wFKEdMBShHTAUoa+q4KqYCjU0dU7dNXAWaElMBynkaU7OS6wEAAAAAAAAAAAAAYEafehcAAAAAAAAAAAAAAAB6k1wPAAAAAAAAAAAAAMDyJNcDAAAAAAAAAAAAALA8yfUAAAAAAAAAAAAAACxPcj0AAAAAAAAAAAAAAMuTXA8AAAAAAAAAAAAAwPIk1wMAAAAAAAAAAAAAsDzJ9QAAAAAAAAAAAAAALO9zzou/fPlyfXt7q1SUdbz/+/2n///9L793Kgkju7+OHhn52np/f//v9Xr9rXc5ahJT4xKnmY2YClCOmMrq9vqi2s7kEFPJdYtBYg38SkwFKGv2uCqmAi3NHlO3LU5cfTZ2px8dm/GOumbL/xBTgdE9aq/0is2vYmpWcv3b29v2/fv3MqVa2OXb5af///7VMSXf/XX0yMjX1uVy+aN3GWoTU+MSp5mNmApQjpjK6vb6otrO5BBTyXWLQWIN/EpMBShr9rgqpgItzR5Tty1OXH02dqcfHZvxjrpmy/8QU4HRPWqv9IrNr2Lqp5YFAQAAAAAAAAAAAACAiCTXAwAAAAAAAAAAAACwvM+9CwAAUTx7TB4AAAAAAAAAAAAwPzvXAwAAAAAAAAAAAACwPMn1AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADLk1wPAAAAAAAAAAAAAMDyPvcuAAAAAAAAAAAAdV2+Xf7339ev144lAeBjTAYAYrFzPQAAAAAAAAAAAAAAy5NcDwAAAAAAAAAAAADA8iTXAwAAAAAAAMVcvl22y7dL72IAAAAAQLbPvQsAAAAAAAAAAAAAAMRyWzx//XrtXBJGNtomDHauBwAAAAAAAAAAAAAe8pQ6ViK5HgAAAAAAAAAAAACA5UmuBwAAAAAAhmTHLAAAAKLTdwWAsUiuBwAAAAAAAAAAAABgeZLrAQAAAAAAAAAAAABoKuITXj73LgAAAAAAAAAAAHVES1QB2voYA65frx1LAu249wFwhp3rAQAAAAAAAAAAAABYnp3rAQAAAAAIy05jAABQ3q2dbRdrAACAn9m5HgAAAAAAAAAAAACA5dm5HgAAYBB2kwJG8XGXaTELKE2biFdcHwAAAIxIfxYA4pBcDwAAAAAAAAAA0ElOYrUk7HF93JSE49QBAGqTXA8AAABAESaHAAAAAAAAgJFJrm/E5DI9WKkJAABACcY1AAAAAKAf43MAAO1IrofB6DABAPzKokIAAACAOh7NTRmDgXkYW4VY1EkAonOvYgWS66EjNxoAAAAAgPNsSgIx3NdF8yAA4xLDAQDWNvJ4m7bsmCKdN8n1AAAAAFQTaSAMgHmMPLkHo/tY/7TxAOah/w5Qnr4rAIxJcj0AsMuAKjAK8QoAANg2fQMAAACYnYW/ANQiuR6AX5h85BnXBgDAOkrvqqQtCQAAAAAAAEQnuT4Ak8u4BgAAAACgPjuaAQAAMILSG18AAJBOcj0Ay9sbmDDxDgAAAPOx4QUAAPxKQi9AX8YrgFGIV8xMcj0M4swghhsZAAAAAAAAAAAwI7lRwLZZKEo5kusLcYMmhyAOvGKn/DFpCwA1aT8CLYk5AETlHgV9taqDxtkAytF+AmAm7msA8cw6jiO5HoLTMIS1zdoAAQAgHslSAABEot3YnmMOAO3JCQEgGvcmSjpyPb0an2g1diG5vjKBBoCRuY8BxOQpJ0BJ2nwAROdeBWtQ1wEA8mg/QT5zbPCYewo5Wl8vr76vVrK95PrC7OgARHMmLtWMaTosPxw5zr3vN84flPeoM6B+AQCwMhM6AOMQs8f27Pw5r1BfrfkW9RdgfL1zAgAgx/19q0SfpGe/RnL9STqllOR6oiYdrx96LTi4r+NHkukBAKCUyG1M/RdoZ/b6NvvvA+jtTJtSjAaYl81kgNVFHnutySZ9sCZ1nx5q32sl1w/GQCMQyZHGkcmW544cm9mPyQjuz5tOAzfqZxurDk4C3KTebyLGy4hlgpX0emzrq3iVW6ZXCTuv+mqMY8TzJpEM6skZd1MX6zP2Besw7wHl9ezrnNkQbnW92j/iMFBT6XvSs8/rFb/0XTlKcv0DexU8JaCUSJAcceKA15xTSqlx4z97fZYsU05ZziQTlUz0PxLDa8WE3p36Vb6XNZW43lyzAH2Iv8CoTKDW5x5BK641ODZOa26lffxwzKG+2nNEtezFI/EDGNHegoMj+Qu1RF0cESn+RyoL1GKMichmicPLJdef2ami1Ukv8T0m3SjlzGoyN/L6It6Mnp33V2XNvVZKftZZdsKL85vFHFoqsSgy55p1fXOG3fqIpnd7rdZn1/w9K98HWv32lY8xcZUeIzzy2hKLSp/9vVZ988S8fK3OSU7fp9f3l/ieM+9Z7dpjLa2TjGYV8V51ZgOcSL8DItSvCGXoYdXfDYxLuyZNyU3LatvLc3n0G9y/6GHkvu+rHIu9HLNX/64OtjXyNZhr6OT6lMZKz52DWzpzwzaAvy/lGhnhuLV6OsIMdSqqkhPrJRJCe752772rXYeRfu+RsuTscNL7CS8lr9MR7h0rK9WOPLP7Wq+4H/kJFKnH5EhnPGInPFJ8h9JS6n7Jvm5JEdshsw/kH5ncKPk9EMWRBe01vq/kZ0dUol9bYjHtq3Ic6UfvvbZUX+HIworI10MJqcc6Yp+EvlrE4ZT2eES1NzroIfLxBs6brY7P9ntgZc/mkaK2mVqonUNR0gjna6+MPe8pR/rrqf8W+Zww3hhM7nhb5EVAj8p2JAcg972vPi/KsSGWoZPrX5m9M5cTGGskZdVSo8FxJJGx5KBsxGtxpGuCeuwUxCsjd/5zJutrx+wzSdXia30jxqkzyS61r++ca/bIwNQZZ+ri/WuO/M7a73n2GWe+p3Q5WifkiaExlaiLz157Jgb12kW3ltn7ajnJiK3bfvefO+s5oL5Sizxpq0Qbt/ZrSyxWr91vr+lI+3S0iVbS5LYHzyxayfmeV5+RU49zf09KO2o20dprvRYK1BorKtHuPjPGCzOIFqdKKdkuXc2s1wSxlOiT9uznpZZBfaKVUpsYUFbrXKlIfbaRlcx1PPL5H8/jkbLkXgdnxzFT35sTp1a8HqdLrl/tJNb4va1X25VKZjqygmm1XbdqWO33wkhGGhhIXRG+92+PXjf67lsjnD9i6bWILnJ9OiI1OSplkjelDZ0TB/e+74wj5Wi14DdHzgAIZdRYcJPzmhJJgttWJ1Gw9rGp8d7R1bxezpTjyEKOnCc7nHlvjiiTp7SVet5Xjj0jaD15WPr1JZ1ZgCUpbCyRzk+JfsqZ+RSLt36Vc6xa9BXOfPajzx/BXkyN0NejjMjnI+W661XmWReT7I29vho3rf1EuzNKxPW9e0XtZK5Ix5P+St+He49dHX3dKFod373vTXmt/jQ17I1flkisfvW6EvHqTN04Ml6gDqY7e6x6zfc5x+dcrtf0iv33v//9+v3797wvqNDhc9JjO7PSphc3jboONSAul/fr9fr3CsUJo0RMBdZxagJPTH1ITAW0Ux8TUyHPkTGFGcchxNTHxFQYS6T4nD3OLqY+VPtcRrpm7kUu24xSFt/3MsJiuNrXq7bqr0rH1Nb9ohH6YeJwf2eukxvn71di6mO5cdW1dYzYWkfOZnXOQVli6mMR+/9nnd35vCT1mFmVjqlZyfWXy+U/27b9kV0CgHx/vV6vv/UuRE1iKtCQmApQjpgKUI6YClCOmApQ1tRxVUwFGps6pm6buAo0JaYClPM0pmYl1wMAAAAAAAAAAAAAwIw+9S4AAAAAAAAAAAAAAAD0JrkeAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmfc1785cuX69vbW6WiACW8//v9f//9+19+71iSc97f3/97vV5/612OmsTUsd3q2sj1jHWIqQDliKnw2Me+6D1t5v/H3r0cOY5cCwAFO8oBRfSEliof1L60IW2AYgwoQ8qXKiNmqZAiZALfYh4lNpsEkcDN/zkbabpIIEkkLvJzM8kjYipAHDEVINbocVVM7dso88HMY/SYuiziKoyihzwQMRUgzlpMTUquf319XT4+PmJKBWRx+v303///8Y9+79fT6fRH7TLkJqb27XKv9XyfMQ8xFSCOmAr3XfdFb2kz84iYChBHTAWINXpcFVP7Nsp8MPMYPaYui7gKo+ghD0RMBYizFlO/lCwIAAAAAAAAAAAAAAC0KGnnegCY3dqOnAAAAAAAAAAAR11yE87/OFcuCQDEuc69a/kZJ7keAAAAAAAAAKBhNoACAAAo40vtAgD5nH4/GWQBAAAAAKZhTBTG4X4GAAAAoAbJ9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9F5qFwAAAAAAAAAAAACgtNPvp9pFAKAxdq4HAAAAAAAAAAAAAGB6dq4HAAAAAAAAAACAyuyiDgD12bk+wen3kwYMAAAAAAA0zng+jMP9DAAAAEBJdq4HAAAAAKA714mW53+cK5YEAAAAAAAYhZ3rAQAAAAAAAAAAAAAoouVfK5RcDwAAAAAAAAAwmJaTVQAAAFr1UrsAPfJzwwAAAAAAAABATZfcBXkLAAAAcexcDwAAAAAAAAAAAADA9CTXA8ABW35O009uAgAAAAAAAAAAQPsk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAADC90++n5fT7qXYxAKjopXYBAAAAAAAAAJZlkcQCAAAAQFWS6wEAADp2STo4/+NcuSQAAADAiIw9QF0WHQEAAJQluR4AAKAzJtSAVohHAAAA0B79dQAAsFic/STXQ6JWA64BEgCAda224wAAAAAAAAAAaMOX2gUAgFmcfj9ZCAMAwHS0gwEAyEVbE2Ab8RIAAGA7O9cDAASwIzYAMBMT8gAAAAAAAMCIJNfDTjmTKK+TFCRpAgAAAMD/WOADAAAAAADkIrkertxOzI2S2G43ZYB+ieEAQEsktAIAwLxsDgUAADCWe/M+I/b39GdJJbke+MmoCwygNElH83CtAYAZaPMAAAAAAADQA/NaHPWldgGAPp1+P3kIAQAAAAAAAAAAADAMO9dDQySrA/DI5RnhF0UAAAB+pc8EAAAAjOg6l8i4BwCUIbkeAJ6w8KVNt9fFQAKwlcQrAAAAAAAAAADukVwPG0isfcwKWaAVkmUBAAAAAAAAAIgmRw7mIrl+gy2J1XbP5Yi1OhaZLCrxFPKzGKc9OjgAAPto2wIA0AvzH8DstsbBtTmTHLHUHA0AANAjyfUHPZpoNohHTyRMAD1pPWYZKAYAuM9YCQA5tT5eAAAwAn17AEZiLAGgnJSY20K/Q3I9LMcaSy3cyCWl/JLDLN8JpMp9j7gHoX/uYwBm4HkHAAAAsSISVvTXAQDmNnp7cPTPN5Ka10pyPXTmdkCkpSB/WzYPImZSe0Vzb6v7Sqh9TQByENuAETz7FcBlGb+tCkA5s4yDwAie9Xm1F4HR1Rr7S4m/AOQj3pbhe55D5HjQzHXGuBqltXS/Sa5naj0NFGxJPoAWaWjFGOl7zD0JthYXe/oexXeWpa86CwAAAMBYjFHC3KLnW4x398fCtnx8t9CHtWeX59rcWt4cd6tR+3ujfq6ejBIfJdfTpIgbrPRN+uxn80qW5Rk7XEMbSg88bvl1iSMdgGdl04AFauk5/mi3ATO4F+vENOCentt15KNewJzc+8AoRo1no36umRmryWeEBE2YmfjIPaPWi9GeWRaMlrGlb9Bi/0Fy/ZL3pnczpdmS+Hnvdfdes/Uc0VKueYtB4ZGeykq8I42JI8fgsZSGx7PvfMvOIxcRSf33/nakjHtELuIC+ucZBQAwp2f9Ou3Dx7Shgb3ubUhknA2YwW37abTYZ5MQiLcWN9w/5HQkJ6tFkc/c0Z7fMyjV7niW49jzPbQsMXV/tMR8fvUoV7BXxZPraweMHldBrDWQa3+fpWz5nK19FynJqjCCEet1qc/UWvxas2W3+z3f26P39PCdrBm9AwVreviZxJafXS2XDe4xIAbQvoj+ybOEoBbifyttzVGMlAQmEQXa03NMAdhq9FiX4/NptzG7LXOvW39RvNd7qOfyp4ydzPKMaDlHsPSxan8nMys1jvmoruxZtBK90CVH/euhjBHnj9wANcqeRXi5Nlgt8ZlrnLfazvVHJm32vLblBklKmUsk6bXcWd2zOKJ20L3Wcj1kHilJzM/qbFQSdeovT0Q/O1qxJXH9yHEjlV54MKrRVv2PJqpNtLWD0tKgzJ6Fjc8GCnqo20cWtR4dEIlMVtrSv8h5PVIWVrSYkEd+PcWFI2b5nLlFLMKsdS3UAaJsaR8c+aW523/fMj6Qq68a2VZ+1M5IOdbo9/Ge7yK3URffA20aPc7n1tr311p54JHR5z1SpIxDP2Nn7zR7xrvpw5GkzhbH62snKj573fVrt46dHL2/nr1/S+7ZkWTKHuJGK2VZK4e2a317EpFzluFaqV32cx9/ax7B9Wvv/e1aqUURke3Uo/bk7m29BlFaibvRsifXRyZmtjjYH2lP0uiWf9+6UjUlmT9FK9eilXJAhC0d29Q6v2fxSpRnjaK1juielZyPjLALG2n2XOuolZsRryVW9He/NWkpJf4eec/W8q29JuJ5c++9Wz5X6d1Xtra3ozrUpRdC5UhyT0m6ixxUzjEIzHFRbcutbb2U+HgkAfX2PNFx8dGxUn4FJCKZdBTP4lLNQdhWJiv3lEMMzS8ikbz0+e+9N+fmIHuMHgdrfb61hILcz6DWrumWz/2sLSEZjNattWtai/v3RIyZ70m0evSaUu3RPQlWudsjkX351p4H/OzofbTl9Xvfc0SLMa5nEfdxrlyH0iL66RF5J/TjSE5WynujN/q8tqXvmHvuYGtS5VqsaU3093nkWBHzgY/O11KMb7UuzGaE61AqbyG3HHPlPbbv7qk1X/Xo7y0sImhRtZ3raUdkQlTUcYH7IhPRelA64b+V77GVcnCf6zOOyM7ckV0wUxx5T86Bz6Pv7fm+6rnsy/K8bdHDwETv14B1pReepL43V3s1JVnkyATaqFIHYZclfbFR6eTnLRNOKZNSEX3Lnp4V1DHSGMaRSd+o8/awWGrPc3JEKc/tWb+jkkrdv0cmI3MvFt+TiPzsPSkJjLXr+Z5kn6PH2/ratWu19TquvWdrOba+JvK9W8fa9rx3TzI3x9XqS6TU+63nS2mD1Y5x9Cnqfnn2fFY/iZSzPuU6dq6FO63LXebc7cbUfkX0IhDmNMJYd8oilhGUGjetnZ9RUw91KPd3Lbm+kNyJVrmP9ywA93AzAQDk0lNbqKeyXtvaHp1lwKCUo8mcUMpo9XC0z5ND9IBZ7USJR8lTUYlQJSZAex8opg09tulSkmW3vnYtaXVWucbMn9U1u32OrbVJ1xTRbYWI90S8t7baZd+zqLZ2mXMZ9XONqES8iKoPpeMh7Sh9HXMuNFMngVl4blNTy3VJDuevWv3MPS3arX3+o3LNU53O54SfwTmd/rUsyx+hJQC472/n8/m32oXISUwFChJTAeKIqQBxxFSAOGIqQKyh46qYChQ2dExdFnEVKEpMBYjzMKYmJdcDAAAAAAAAAAAAAMCIvtQuAAAAAAAAAAAAAAAA1Ca5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgepLrAQAAAAAAAAAAAACYnuR6AAAAAAAAAAAAAACmJ7keAAAAAAAAAAAAAIDpSa4HAAAAAAAAAAAAAGB6Lykv/vr16/n19TVTUWAsn//8z7Isy/L3v/6lckn69Pn5+e/z+fxb7XLkJKa2w/3K6MRUgDhiKmxzaWNf097mlpjKrdvYIW7AdmIqQKzR46qYCpQ0ekxdFnGVY+6NpS6LcZEWtDhWJaYCxFmLqUnJ9a+vr8vHx0dMqWBwp7f3ZVmW5ePH98ol6dPpdPqjdhlyE1PbcblfP///v8/uWwYjpgLEEVNhm0sb+5r+MbfEVG7dxg5xA7YTUwFijR5XxVSgpNFj6rKIqxxzbyx1WYyLtKDFsSoxFSDOWkxNSq7nuctDVWImAAAAAAAAMzNvBgAAAMAR14udSo0xfSlyFgAAAAAAAAAAAAAAaJjkegAAAAAAAAAAAAAApie5HgAAAAAAAMjm9Pb+0094AwAAAECrXmoXAEZjcBgAAAAAAAAAAAAA+iO5PoiEagAAAAAAAAAAAACAfn2pXQAAAAAAAAAAAAAAAKjNzvUAAAAAAAAAAADQsNPb+0//ff7xvVJJAGBsdq4HAAAAAAAAAAAAAGB6kusBAAAAAAAAAAAAAJie5HoAAAAAAAAAgM6c3t6X09t77WIAAAAMRXI9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAAAAAExPcj0AAAAA2Z3e3pfT23vtYgAAAAAAAAAdKjXf+JL9DADQKIk9AAAAAAAAAAAAwIWd6wEAAAAAAAAAAKARfgkUAOqRXA8AAAAAAAAA0CkJmAAAAHFeahcARnc9iHH+8b1iSQAAAAAAAAAAAACAR+xcDwAAAAAAAAAAAADA9CTXQ0F+jg8AAAAAAAAAAAAA2vRSuwAAAAAAAAAAAADAz9Y28bz87fzje6niAMAUJNcDAAAAEMKvtQEAAAAAPGcsFQDaJbk+ExD5K8oAACAASURBVCsDSRFRX9Q5AAAAAAAAAACAeNcLIuRnAYztS+0CAPuc3t6tYgUAAAAAAAAAgAbJ7QGAPkmuBwAAAACgOSagiaAeAQAAAACQ4qV2AWBGl8kcPxEEAAAAAAAAwFZRCwcfzVmbywYAAGYnuR6CtLL70XU5DHgAAAAAAAAAAAAA0JOaObmS63doJYkalkV9BAAAAAAAAOB/bueQbcoGAACw3ZfaBQAAAGDd6e3dokoAAAAAAIAOmecBSCd2UpOd6ztwHSCsKB/b5Vq7zlCXexGAVnlGASUZjwAAYC+T3wAAzOxRe1g7uQ+uEwCS66EijTEAAAB6YHEPAL0x9goAAAD/Y4z3OWMJAFxIrs+sh4ZJD2UEAAAAAAAAgNlEzuevJQ1KKAQAmJdfM4afSa6HzuwZ1LCAAgAAgJxMwAM5GdsCAIBtfe8jc8mP/l07HKB9YjYAI2lh3lFyPQBD04kEoDTPHmAGLQxqAQAAwMj0vQGgDM9caIvNh2mB5HqYiIcIADCzHttCBvMAACBGDz9t3UMZ4Sj1HAAAyrk3z9TjfBnAUcYjSCW5PsGRxJZ77312k5Zu4Gg8tSMqmEvGgvvcG3k9ep7kfs54jgEA5KctDUQTVwDmZTwPAIDRGOcARtBTf13cJRfJ9YPak8xPm3I8APY8AHt6aPKz0a/d1s83SmOqp+tZ6zvv6TsC6igVJ8QjgPtu24mXOGnXEOAZ7SsAAEaWc15llHkyAOLNNt7imQg/W7snHs3nlDZbnKIN0ybXtzBh66YHjrqNI9GdgNJxamujrFRnZ+08s8butTqx9brs+V5beG4/c++7aaWjAYynh7gIsJXJDGAvbSJapn4yi9obbFy4z4Be6RMDjKHHeH5b5tHz2Hq8RsDPRo9TpMXq3PVh2uT6a7PcdLmTcOnX2i8dHGlMz3Jv1fDouqS85/YaryUE7ylbRKw5Ut9yx7hnx99T71MS17d8N89ek/IrJ3vq3B576nKpcmy9prkWuaSWgzxyXg+JF/nY8WkMj5717hcYkzYQsKalNpg2SXtSxhZyXLc99bOlOk1+kWN2tZQae/Xru2Mx9gUA/Zq9rWWsEhjBSLH86LjESN8F+Uiub0DEIKTBd/ZI+VmXlL978OQTea+nJEunJHJvOV6qPavSaotYVBD12iOr+lr5PqM8qstHJt5zJ9OTX61f6Vi7zyLLVHrAL9dCvGefI9fnLHXvPzovv9rS5nh0vbRTYZsWY9CzeOz+BnqMBz2WuZZcY5GR/YijY2uMK8ccUEQ/uiURv4j56DV7EvTvybHBQsvX5KJUPerpO4FUtcYXI1kcA/27dx8/ikN7Nner9SxPiaVb4nCtzdZas6W+9PQ8yL1xYE/fBff1cC2PbEL26B44skFE7r5hrWPmGlPYc7zb40aMW7bynG75XrvWdHL9s6Cwp6EzygB3T2Ud3eiN5j18J/Nwrcc1wrU9soBo73FbOibPPUrQzTXpemQRUkTneO11ewYLnw2+5l5AumenvyPnPtL+TumEHxnE2HL8R+999j3e+4WbUh34yJitH8VRPU8gbNFDm6SHMkaIfO7sPQ59yLWw8Wh5rtUasM8x0R81tjx6LHv0vIxIDi6lhbpMrKj5pJyJkVHjBKn99LVfNK2dCBo9tpBrDGGviLGo6In+lGNsTcy79/dn9fTIL7bSj1LXskQiaMuxppRW7s2Uce8tz9PanyeCtm2bcifgrR3j2blTnsdb/r2VXwyredyeba0v98wSa1LmLGf5TmqImL+JzBeIGtvf85qSx2hx8X+P47Qp1z5yjj4qhteeP83Vdj+dz+fNL/727dv54+Mj7QTBk4HPPFudc6SB2srNVJKH+mMz1oe9dt3/p9Pn+Xz+lqE4zTgSU2upPZkCozjyywBi6n05Yura5HJtewZD9x436tgtqvVci06uTzl+5HlynDdX3d5ynq3E1G2iJ1G2JuntOd9aWffU2a3nSUliymWW+H4rJVEuYgA+5X5IuSY5x7yK1UExdZNc9SLHDrxblGqDHdmRLrJMKe2biEWSLUzYbv3+creLox3Z2OfRMSLvUTH1vhbrEvVFtqO2iBwDVKcfC59EHzyuRsfUlhOQbo+/Z0FIypi+ubTHIsZq1l6z9fyl5mYutowJ5RzLOFIHozZdGT2mLkt6XI2ODUfqdynRfV7ua/k7e5bTdy1y7KSUPW14MfW+Vvr/kbG1p0TvPVLu51LzwZGixjEj54a2xJYe6m6ututWazG1WHL9RU+BoofGZ26RK2FTGj4R9ebIe0YI6i3RGLyvlcZgipY7YjALMfW+HmMq5F7A4bn9nJh635FE0JbrmXuCFo1UL8XU+0q3U48kC/Zc//ZqLXFxS6J8qcmFPZPYEWXroR4eid2S64/R9ydK5H28JnISW13e7t53pq36q55iqnlartWOiymLW0etp2LqfbWT63twZMFy7XufvPbMl7Wcf3hkUd4WYup9PcWH0dsMezaw6uk7GP36PdPyM7lqcv3pdPrXsix/JJcAIN3fzufzb7ULkZOYChQkpgLEEVMB4oipAHHEVIBYQ8dVMRUobOiYuiziKlCUmAoQ52FMTUquBwAAAAAAAAAAAACAEX2pXQAAAAAAAAAAAAAAAKhNcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9F5SXvz169fz6+trpqIA/M/n5+e/z+fzb7XLkZOY2p7Pf/5nWZZl+ftf/1K5JBBLTAWII6bCNpe29TXtbG6JqQBxxFSAWKPHVTG1b/rc9Gb0mLos4ip5yF/gHjEVIM5aTE1Krn99fV0+Pj5iSgWw4nQ6/VG7DLmJqe05vb0vy7IsHz++Vy4JxBJTAeKIqbDNpW19TTubW2IqQBwxFSDW6HFVTO2bPje9GT2mLou4Sh7yF7hHTAWIsxZTv5QsCAAAAAAAAAAAAAAAtEhyPQAAAAAA1Z3e3u/uwgkAAAAAAFCK5HoAAAAAAAAAAAAAAKYnuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgei+1CwAAAADAGE5v77WLAAAAAAAAyS7j2+cf3yuXBIDaJNcDAAAAANAME5kAAAAAf7re0MRYCQAzqTlXILkeGne765+GMgAAAAAAAAAAAADEk1wPAAAAAAAAAAAAAEBTavyKi+R6AKZ3+wsRAAAAAAAAAAAAwHy+1C4AAAAAAAAAAAAAAADUJrkeAAAAAAAAAAAAAIDpvdQuAAAAAAAAAAAAAEBpp7f32kUAoDF2rgcAAAAAAAAAAAAAYHp2roeKLisfzz++3/13AAAAABiZcTAAAAAAAKAldq4HAAAAILvT27skWgCASWkLAgAAANALyfUAAAAAAAAAAAAAAExPcj0A3LCLEgAAAAAAAACQm/wEAGiP5HoAAAAAAAAAACR5AgAA05NcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAB06shu83aqBwAA+JnkegAAAAAAAACAwUicBwAASPdSuwDA8t8BjfOP75VLAgAAAAAAEENCJwAApNGGBoD6JNcDAAA0zmJMAAAAAGAriZkA7ROrAaBdX2oXANgn4if8/AwgAAAAAAAAAAAAAPxJcj10ToI8AAAAAAAAAJHMQwMAALN6qV0AoJzL4Mf5x/e7/37vbwAAtONRew4AAAAA4AiJ9AAAAH+SXA8Dk3wF+bi/ACjBhBYAMDN9bwAAyMfYI0C/jJkAQF6S6yGzlF3hDWBAm/y6AwDEMNgLAAAAAADwqy05Q/KKAKAMyfXQGQ1lOG5rYp/7DQAAAACAHljQDgAwH21AAMhDcj0MYq3BfJsgLGEY/rTnXnh2P+m0AgAAAAAA0BLJlwAAANtJrkdHesWe76Z24nrt80Or3Bv1ed4AAAAAAMRZG/c2HgvjMdcFAGVoSwO0q1SMllwPBRnwALa4FysuDQI75QMA0CL9XQAAaNPtpLNEIQAA+JNxbQAekVwPQTS4IF7KIH8rSedrifEp79n6mj3ny+3Idbuo/RkAanv2bGgx/q/RVoZx7bm/JfMAy6J9ADCr6/ivPViWZy/0K+X+da8DWxmjAwBa1UK/RnL9xCIqoMb2eCKvqfpBCS08TJ8pfS/Uuve2XouUxQQpn6HU5xbbqOFRvTMhTa/EUuhfD+1wAPLTJwEe0V6s58h338omNjCiVsZ4xWeAMc0273Lk80a1l2f5runLbLEAcpJcz38d2Wl4tMbD2ue7GOFz5mJQZk45Fmbs/fvW15T26Od3a5dj699qOJJkf8/WXxFIeRa28l3Rvy3tqYh6p+4CANAbfbXynn2P9/revnuAY2om2IrdUE7Er/+WdiReiDXQnlkW4umjxnq2SCz6e35U12rnWKS8Vt0DSNdSvC2WXD/6g2P0z3cR2UjJ/Z3tWf3vJ/WO8Z30JdfO4M861HvqyWh1q9Tn2XqN90yIl46Xub+zteOnLvboYdECP2txIHDPIqMc9WxtUVAL39NWJb6bFrRYpta0eL9Dy+7F/Z7GBYDycrcXtywWr6WVnUiPONI3XnttysT7qO01z7x5jHKtj9yLOSZB773uWbJNi7+IGSn6uffoeKPGZWjB2hjvqHqItz2UkXFFPHe39E33nPdZWyGyrKUc2bAt13l7kiv5cWu7NEXuXe5HuabEqh3jjpplfp36Wt5gssud61u60Z7tcH4kAbWWqMnzrY32UpNuqX+b3aPvppV6ynZHkt2fxQAdiT5EdkB7X4S0tUxROzaImW1LGQjc2m47ElNze9ZuTXnv9b/VHvSM2Elzz+KxI3IP2D5aFJGy+CelLudYiLVngFXMhTilJ/j3xCmgrpT2U8Si+2fnSDl/yvH2JMrvGYvMNbm7Z7H9ntfsPcbRPsnW7y1qUcajPl1Ee5j+jXK9o8bEjr730f0WPd/z6PhRbc+t/fM9Yxi1HBn7PBLLoWe179toLSe/PDvfnveULmNP3yvHpPTH9oyX10pEPnK+a0f6e8/aeNHf/Qhyfd4jOXV7zlG67fzs+LPVo9q2Xu/S8xAp41IR7YB7/72nT3r7t9y5Zqlxf+28e16booc56tQ6HZ3nFDE234LT+Xze/OJv376dPz4+0k4QMGHw7Iu710jakzCzR46LmquMtRO6Uhy5fj18vhGkTEbtmiA8nT7P5/O35Dd2ZE9MvXBPQN/2JKAcIabedyQ+tjaxeU9rZcyVMLRHjnbx2sAtMZ5dty2DYRGDHWJqXQajy2g5jrW6qKu145YQMvEvpt515Ls9Mmide4yh1tiksZPxk78jFhHkOP+e84qp63pop26xdcHy2vEjFg4dqaM9xY9c/fUj4y49fo9rjiRB5NgFMerYo8fVlmPqrRYXZqyNObU2LptLzjZYizkdtfpYR47R0hjG6DF1WdLjalR/obUYE51EtzXW5J6jiZjbLXWtIubjSs15lW4Xt9gOF1PvKz33v1XNWHOrpXrcs63zzxHPrGu5FxuVljqPnzsPJMVaTO1y5/pbazs6bP33e2pNOvS0ECCXZ9ev9oAJrkUtz1ZZr70W6Is427YeYmxrZdwywVRqUCvH8Vv7vke0dQeQPe/luMiJkFzlyL3TwpGkJc/77XInoW2NNYcTdRL6dlHnuHf8iAl/7da69oyB1ppIrPU8VkfnVbvOHX2vOpvPkU2aIvqvj9oBF1GT6TnmuHrsW+Uq82zf45ran2dLe0hMjTVzP/dZDL/+t1G/gxK23L8pz+3IMqWc71mbI+q8e+RI6CK/2s/cLUrdm1vicU49XIsjSn0+143e1KxD6m8eR+afc5wv13tzK/09llItub50As0etTu+h1b+Nvh9Rmpxh4JZjV7XeuE6QN9SEkI97xhBxEJYoD9Hks+fHevI+fccd8vr9kyURkhJoup5N709C40jFyenJJPUqgspx+/p2s/kXp3NuRBpxgX8o36uWz2MxR9R+/PUnkdg3Z5FuNFtvVRR5699b8AWe2Koul1PqYTglBiX+9fQPd/T5UpAetSWLd3WbaltvWeDgMixL1gTtcitlf5WxLOplBnHd2AULbUzSHck/q7NYaoH9ZzO5/P2F59O/1qW5Y98xQH4r7+dz+ffahciJzEVKEhMBYgjpgLEEVMB4oipALGGjqtiKlDY0DF1WcRVoCgxFSDOw5ialFwPAAAAAAAAAAAAAAAj+lK7AAAAAAAAAAAAAAAAUJvkegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgepLrAQAAAAAAAAAAAACYnuR6AAAAAAAAAAAAAACmJ7keAAAAAAAAAAAAAIDpvaS8+OvXr+fX19dMRQGiff7zPz/999//+pdKJUn3+fn57/P5/FvtcuQkprbncs/0dK/AFmIqQBwxFba57Y8ui3Y2vxJTuaVfDvuJqQCxRo+rYipQ0ugxdVnEVfK4N8b6iLGUeYipAHHWYmpScv3r6+vy8fERUyogu9Pb+0///fHje6WSpDudTn/ULkNuYmp7LvdMT/cKbCGmAsQRU2Gb2/7osmhn8ysxlVv65bCfmAoQa/S4KqYCJY0eU5dFXCWPe2OsjxhLmYeYChBnLaZ+KVkQAAAAAAAAAAAA4H9Ob+9JCfUAQD6S6wEAAAAAAAAAAAAAmJ7k+oOsGgQAAAAAiGPMFQAAAAAAqOWldgGAbS4Tiucf3yuXBMZjwh4AAAAAAAAAAACwcz0AAAAAAAAAAAAAANOTXA8AAAAAAABkc3p79wuiAAAAAHRBcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAAAQIdOb+/L6e29djEAYBiS64NopAAAAAAAAAAAAAAA9OuldgGAci4LQM4/vlcuCQAAACOy8QAAAAAAAADQMzvXQ2f8SgIAAAAAAAAAAAAAxJNcD/xE8j4AAAAAAABA+8ztAgAAxHupXQAAAAAAAAAAAAAAALh2vaD4/ON7kXNKrgcAAAAAAAAAmMglQaVUcgoA2/hFEgD4U81nouR6AJiEQVIAAAAAAAAAaIdkegBoj+R6aJxGNHCUOAIAQG7anAAAANAnmzMBAAD87EvtAgBtOr29S44AAAAAAAAAAAAAYBp2rgck0QMANM7uUQAA+WlzAQAAAAAAkusBAAAAyE7SKtAL8Qogn+vNfsRZAAAAAFokub4hJm0AAAAAAAAAgBRyDQAAgFFcb85Qy5faBQAAAAAAAAAAAAAAgNrsXA/AtFpY5QYAAAAAAAAAAAC0wc71AHDj9PYu8R4AAAAAAAAAAAAmY+f6BkjgJJL6BAAwDm07AAAAAKCky5jk+cf3yiUBGJs5IABol+R6AAAAAAAAIJyEIYB+iNkAAEDrSi0GllwPrLIzAfw8mOheAAAAgDKMSwEAwDES5gEAiGK8lplIrgcAAAAAoFkmbQAAII2kegCWxUaCwD7GY0Fy/S46ogAAAAAAxxlrBQCANNrQADwiIRYAYkiuh4kZeIF19+4RnVEAAADg4nacwLgBAEAM7SoARiRPBwD6ILkeGrSnMa0BDtu5XwAAIIa2NcB9ksEAAAAAAKBPkusbZOKFFu2pl+oyI1O/AQAAYF5bFxfde52xBAAAAACgJffGMW2wRGkt1TnJ9dApib0AAAAAkI/xNwCA+q6TK7TLnotMRklpD2s7A7SlpeREAOjRtMn1uTrhOo1ctFwXjjSibz+XAS0AgHJabmNCSe6Fvrl+QAm3419rMefILvSpx7h+rTgIcJyYCmwlXpThe4Z07hsAgPZMm1yf25bG77MJFw3o+fS0ctRPwQAA7KOdD+n0NQBYlvh21AjPlz2LCB69xiYawFb34udt3NgSYyPjur52OnGfVkW30Uq0+dxPQKq1fAtxZEwtjEGoY0AU8YQ9eqs3kuuX/i4abbttEOceTGmhAQ4z8wwBYK8j7UQTdvAnbbG+rV0/1xaIFvFLjtFSYl3p8m9N2u+hXeqZQg576lWPdbHlMs86N7L2uWtfp5brC/NpKUbkWEjUgy1lFS+AGfQUuwFoT8rmKjWPuff8LfcJpkmub2mgs1bDyaBWjBIBC4hX6j4rFWsjfiEFYHa5J7Za6HsA5KKtCdS0ZXHOCEqPZWx5zZGd8feITCLtZdKGevaMt92+J+JeaSEZ8dnn3PKeI+e7uP1ej4qc33l0rLVY8+z8Ke9dK9Ozz5X7VwVqj3HUPj9ltZQD8Oz46iYAraidVAm0ZaTxVNalXOvSz4oW6+FwyfVHBiUf/S1iAOmIe4NpR3Y1iui4Pxow3nPcLe+tNchx+/eo8wBxnk1ilOoI7pmQODLoS6w9jcKIhmTLO02xzZHJ5d6vcWoMO5p8vtWW+ypH+3itLHuSASJe23sdoy+jLU6nLNcZ1qXcI0f6l7nbQs/Of+QcvTvSbnx0rOvjrb3myPG3vmbPrvel6keu++vZeXr+JYARPasH0XXpyHtS3vsophyJNaXjbktl3FNPjtStVr7rPeMsEedNObaY2oeo67GnruaU6z4epZ3bipTx054XFzGOI/lAufKAth6/1FzQFjnvSe2Mbba29UrndLhmPDLCwpO1ep6zjSku1hPx7M3d/+i1f3M6n8+bX/zt27fzx8dH2gkOJKsdSdThuT3XInKy4ch1y9XRvT2+uhVj1zU5nT7P5/O3DMVpxp6YmiJ1EntLw6r2KrTRd6SLirVb3x8d2/dci9qJtc8mGVOP/+y8e44RMbggpq47EuvW3pvzXtxzvoh2eK6YGzmINtJzIUrpAfhHx7x33C3t8NSd/nITU+9rJbk+uq9YW8tlLxVva3/2lq/BCMTUdbn6WDmTibXFWJNrzDVHYn7E+db6azkSQcXU++49y8UqHikdT3q3Na4f2ZQi6hoYU/1V1BxVjmdcT/3NGeNEjjZd7g329ii1qUxK4v/WY225RqUTW0ePqcuSHldzzwndvmetrkbMWx5ZEBctx321xQhtych8q3t/Sznv1viUMp+UWoajss2biKl3lZ5nPpKLdcSeHMdaeZDP2hv37t9ac9a15MpZzflMip6DOCKkfqzE1OLJ9RcpAykSnfuUEiBznHcLdaoMg5b3RQxcpnRSc9T3lIT8iE4V9ZWe1Ehp5JZqDNaur2LqfZHtVOB/Rl/oIKbeV6rvv/UY0UpPoqQcK+fgYZRa93bkAGqtRUe9yzKoLaauavFZWnoRJmwxQgLDPZLrf6XvD31qYdMc/f9f5YqpKc/l2m3LI31wz5dYLSbXX0SM86S8J/X8e4+753w2gVpXIrl+FDkS8mf+PkspnfP17PncwnxCiefM3fOKqXftWZBRy9YyttCX6kkrualb6mLP17HFz3Uop2Elpr7sPupBKasYe65MM7u9bqWuo13lGNme+yjnvbfl2I9eI7b3Kfq6lV49fIQ6C8xI7OOoLTvTla5nKZOekWWLaDvX7OfWjgd7Fu4/GnOK7lflWDDa0phGy/VyVLXvtzWuOy1q+Z4BQJzmsT27Huc4P30qtcFf5Hly1bnac8GQKqVePRuHUEfLMSf/p9bLR/lNgCPVyrUcRe3c1LXrN/rm4sN+rpSd60+n07+WZfkjX3EA/utv5/P5t9qFyElMBQoSUwHiiKkAccRUgDhiKkCsoeOqmAoUNnRMXRZxFShKTAWI8zCmJiXXAwAAAAAAAAAAAADAiL7ULgAAAAAAAAAAAAAAANQmuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgei8pL/769ev59fU1U1GANZ///M+yLMvy97/+pXJJyvj8/Pz3+Xz+rXY5chJT2zPbfcY8xFSAOGIqbHNpW1/TzuaWmMot/XLYT0wFiDV6XBVTgZJGj6nLIq4C5YipAHHWYmpScv3r6+vy8fERUyoY3OntfVmWZTn/+B56vI+g47XudDr9UbsMuYmp7ZntPmMeYipAHDEVtrm0ra9pZ3NLTOWWfjnsJ6YCxBo9roqpQEmjx9RlEVdhNNE5X5HEVIA4azH1S8mCAAAAAAAAAAAAAABAiyTXAwAAAAAAANmc3t7v/roRAAAAALRGcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAEBhp7f35fT2XrsYAMAVyfUAAAAAAAAAAAAAAExPcj0AAAAAAAAAAAAAANN7qV0AAAAAAAAAAAAAAAC4dnp7/+//P//4XuScdq4HAAAAAAAAAACASk5v7z8lDwIA9UiuBwAAAAAAAAAAAABgepLrAQAAAAAAAAAAAACY3kvtAgBpLj8Bdf7xvXJJYBx+Wg0AAAAAAAAAAACQXA8AAAAAQBUWvAMAAAAAAC2RXA/BTAgCAAAAwH5+uREAAAAAAKjlS+0CAAAAAAAAAAAAAABAbZLrAQAAAAAAAAA6dXp79wvrAAAAQV5qFwAAAAAAAAAYj0RPAACgF/ovAFzYuR4AAACAQ+yQBwAAAAAAAIzAzvUAAAAA7CKhHgAAAAAAABiJnesBAAAAAAAAAAAAAJienesBAAAAAAAAAACgEL8KCgDtsnM9AAAAAAAAAAAAwP87vb1bBAEwKTvXAwAAABDCRAMAAACUox8OAAAQT3I9NM6ACAAAAAAAAAAAAADkJ7keAAAAAAAAAAAAMrhsrHn+8b1ySQCgHzU3pv5S7cwAAAAATOP09u7X2QAAMkGwOAAAIABJREFUAAAAAICm2bkeAAAAAAAAyO56saVdOwEA4Fd2uQeA+iTXA8DkTGgB9MOAKlCbOAQAAAAAAACMTHI9ZCZpFQAAgNFc93UBAAAAAAAAciu1EZjkepjAbdKDJH8AAAAAAACAsdwmmqQknvi1OoD8bFrSFs8+AB75UrsAANCa09u7Ti0AAAAAAABcMYcGAADMQHI9dM4ABgAAAAAjM/4FAAAAAACU8lK7ADAKE3wAAAAAsM2WsTTjbQAA8KvcbenLe88/vu8+xr1yRBwPYCb3YrlYCgB/iuy33CO5HgaRO1gA45GkAMxKuwkgXY624+0xxWUAgDnppwMAMKrocVVtZwAoQ3I9FKSRCwDAHhZEAQAYWwMAgBqMTQLQsy3jSZ51ANySXA+d0rADADhGchZAHfqzwFFH2nHXMUg7EACAlkWOX64da08/PaJsxmcBSOXZAUApkusBAAAAACiipQU2JmQB4omtAPs9aivnSLKPfm3kewFGIA62q9aiMgD6IrkeDmqtQdxaeYC+6BQCo7jXJhLbANLoXwKtW4tT2n4AdW1pS2pvAgAAe5gHBHomN6sPkuthRa5AdtvIKx0oBWj4k8kbAAB6ct1+zdGfq91XzPX5an8uoI49428p8eLZmIKYA5BOuw2YUamd5FvQe/mBebXYTm2xTK149kswUcf23QO0IdczUXI9bKBxBGPZ2mnSIQUiiCVlbPmeR5q80T6F7cThdCPFS4CLtdh2+7faG2OsqV02z1UAgBj63gD0qNS4wJFNE0oxRjKeWtdUXcqjh++1hzKW1lI/SXI9JGrpBoaeaIS2QxzLay3hVX2ci3utjGeJUL0b7fNACzyPf9VirIm4Ti1+LmhBRHJ25A7vPYn+LCnXInJ3tSPXHOhH6XavOAEwp8j+u7EaoJatcUi8irHne2y5v6FejMc1Pab25iC37sWP0m3X1BgWXebb40Zfk1Hn9CTXQ0NaDBJw1Jaf3MrRkIpMtowu67NGRYvJ2bfnXfs+azeMS9nSIXh0vXTGGJF6nc7u8/CnXINsz9qD0XGrpzjYU99ztIkWaNGROLzWV+whHtaS4+fJjyx4WOvPRpyvFbnGdx65Pkdrk4q0qYf7qocyAnPqKT6N2met9bn2LFitNce25rZP1UNdJp5+Q3tSYluP8T1iEb7FVWnc5+VFjH3uee+e4+8Z33uUi3LtWW7SlrHBUm2VyI1htrzm2fe3JUcq5VqkHiNKxC+35hq7bvn5Kbl+EDM2OJ7paQK+9nnVm37kbES0tIPRkfu31M+PPWpAHdll7t7f90y4H2mw3b5nz7EiYlpUMsBWEddxS2M65e9i8zyirn8rz/Xcz5kc7aYWFwxFdLbXYlvO+pIrYfmidh2nrlqDec/Kce9vkWVZaye6J/4U1c9oZXGk68u1lAXYW57/OaT0Z3sU1a8u0ZaN2lxgz3ty9suPTAzWqp9HJ908A/pypF+55T5OmQjfOjm/ZWLz0X2U+x7aMpntHkkXPb/gGrBGn4YjjsSaXPOQuZXur/U8BzGKo3Outecuao+dRTgy5trSmEfpPInc7+nZbJ+3NVvGg+69bu21e86b85j3jhuRw7PnGHvmsm9tuQYp8zo57MkDyj0+u6Wub1kUcKQMe4/VW5w8nc/nzS/+9u3b+ePjI+0EAQ/xWZMpjlT80gmpWyp+6aSHlPP0duPWcCSReFfn/HT6PJ/P35Lf2JEjMfVizwRcSn1PmbQ/8mBOLce9MvGrnNeklJRVixF1vgdi6n17YuoeKfVvT3LII3vqd47B8ei438MiyIsjA6l7EoNKfd6t1+BomZ/1BSLuhxTaqetK9/1bv7/vSekDP3pvVAzsaaLniMjPGd2/ePZM3DLA+ez8a4PMPY+Tianb1LyPZ+lnESMy8WlLf2P0+pn8fYqpybbWFXMMfck1F9VqwljUJPqzOaCIxMyo5M614z2i//+rXOOpqeP30eeJcLS/XmucbxaRc18pz/hS8erWnjHYiPOmlGmL0WPqsqTH1ajr08JmI89sHdeLus+OzHuM5MgY6JGk4z3vTckJGI2Yel9EPtUIZr43OGaEfLE9omNqseT6i9wJNM86DJGJGPeOG3G+2pU6JTmspQ7ZRe3vj19pDN6XuzE48uBd1ApS2ndkIuhitDoipt4XGVN1Urln9Nhy0VOCUkRfS0y9r1RyfY/1KjLxOndyfYvfb4SIeDzLs37tc7aSFCamrmuhXs7SBiJG6s6F0ckko9VPyfW/ikoEjUzGG63ezSpiU4PcbfYensmRnzP68+n//0rC0j493IvUN3o7QUy9r1Zy/cWRMcham/20sFhkBrOMhfZKTL1PWxXYo2py/el0+teyLH8klwAg3d/O5/NvtQuRk5gKFCSmAsQRUwHiiKkAccRUgFhDx1UxFShs6Ji6LOIqUJSYChDnYUxNSq4HAAAAAAAAAAAAAIARfaldAAAAAAAAAAAAAAAAqE1yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0XlJe/PXr1/Pr62umogAXn//8zy//9ve//qVCSer5/Pz89/l8/q12OXISU4FSxFSAOGIqQBwxFSCOmEqrbuc7ZpvroF+jx1UxtW/XsVVcpQejx9RlEVfJSw4R18RUgDhrMTUpuf719XX5+PiIKRXw0Ont/Zd/+/jxvUJJ6jmdTn/ULkNuYipQipgKEEdMBYgjpgLEEVNp1e18x2xzHfRr9LgqpvbtOrZ+/v//nsVXGjZ6TF0WcZW85BBxTUwFiLMWU7+ULAgAAAAAAAAAAAAAALQoaed6AAAAAAAAAAAAIJ97O9YDAGXYuR4AAAAAAAAAgP9j796R3EiuBYBWM7gCBceSoY5oWx73ouA6ZLZNc9bRMXtpWrJpjCFLCm0Bz5gHCQSBQmblP/McS+KgqxL1ufm7mQCgkadff5NQDwCdsHM9AAAAAFldTgKd/v63hiUBAAAAABiHBHsAaM/O9QAAAAAAAAAAAAAALE9yPQAAAAAAAAAAAAAAy5NcDwAAAAAAAAAAAADA8iTXA7C8p19/255+/a11MQAAAAAAAAAAAICGJNcDAAAAAAAAAAAAALA8yfUAAAAAAAAAAAAAACxPcj0AAAAAAAAAAAAAAMv72LoAMLunX3/77/8+/f1vDUsCAAAAAAAAAAAAANxj53oAAAAAAAAAAAAAAJYnuR4G8fTrbz/sgg8AAAAAMzIOBgAAAAAAtCK5HgAAAAAAAAAAAAZgYwIAKOtj6wIAAAAAAAAAAAAAAMClywVlp7//rco57VwPAAAAQDF2UQIAAAAAAABGYed66IhkAwAAAEamXwsAAAAAAACMzM71AHCA3TcBAAAAAAAAAABgLpLrITMJtwAAAAAAAAAAAAAwHsn1AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADL+9i6ADCLp19/a10EAAAAAAAAAABgAedcpdPf/9a4JAAwF8n1ACzLohgAAAAAAAAAoBV5CwDQH8n1UJEVo9A37ygAAAAAQDmXiUPGYQHyM9cFsCbxHwDyklwPAAAAAEBzdmoDAID7tJcBAIDV1VpQ9qHo0QGAoTz9+pvBWQAAAAAAAAAAAJZk53oAluDnhgEAAAAAAAAAAKB/LTeIlVwPhdj5GRiFeAUAAAAAAAAAAACS66GJcyKr3bOhvFuJ45LJARiN9iMAsCJtIIBxGYMFGI/2N8D4xHIAyOND6wLAyp5+/c0AMwAAAAAAAADZmIcGAAA4zs710AEDGzAuK78BqEm9A4xMDAMAAIAyzDcDcMlYLACkkVwPABFWGZzU2QYAAAAAAJjfKnNfAL0RfwGgX5LrYQGSZFmJ5x0AAPp2r81+OZmkPQ8AAAD56XsDAAA8JrkeFiLpmJWkrPJe5V0JuUarXAsAANIcaX/bmQkIpW8KMA5tPIA+xcRn7W+AdCEbjAAA/ZJcDwAAAAAAAAAwGUmcAGvziyUAcIzkegCGVmP3DAOPAAAAAAB52RkZAIDZ9JxboP0NAOEk1wMwhRKd1J47vilm/V4AAACMJ6aPej0JfGv3tevjmTAGAIDbzBcBrEmSPQC9C+mrlK7PJNdDotqDDhq53DL7czHCxHiP96BEmXr8ngAAlHevTV6qT6zdycpyPP+t3qFbMeFeGVLix62/lRgEAAAA9Mq4BTASczSMpNTzKrkeBhUSFDTO13Nrxzb6MXLjs3U88WwD94wcW/fM+r2Avh3ZPRroy/W7WbovNWLcOHJNYhYNjEzfG2i1yUnKefWfgRX00pYGIF7PMVxbGri0t6GJOEEpPW+4K7ke+IFKcSw9d8Qe2fvp9kfPX8/fO/c79Oh4MQttSuxgf+S4LSfr712L63/fe8bERwBgJPp4wNmjvnSpODFCH/7sXl9x729zJoDu/ffQ63ikPLFlGdXeIomYSZwSEz4zXm/GkStOt/qVX4CZaBMA0IL6B9Z0ZOOUkPHT2Bww6JXk+kIEhzGNeN9iEkKPHPfaSNdmZik7w6VMstaaaJ9hYuTIBHXI3xz97yWFJgfUduR6hpT1UdwNSYI48i6NWEexppQ2RI5kotxlau3I9xYvgG2La9f0TEzLw3UcU09JiiM/O7WuY0xfv2QfP+RvS9/Pe/3mmD7BWa2yhv57zDGPjA/49YB5HJlczv0rGaGbTBw5xq3PjKTEAqnR9bxT3D2z3xPWcaS9WIv3DMqp3fYfvc+fs62SEtvExbxG/6XAEdvQkKpVf7r0+zZSfO+xrKH3Z7S5y+rJ9SGJwLFJwpc3I2fyWsj5Yv927296euBnciTp8chxW2s9UUh/Hk0OxiR2x5zjUcJxb+/OSkpf+yOLfVIWGrSOQyUm4GkrZsI4ZQI6JD6GPt+5Bl9rDP7slTXH+5S7HR57vL1jpCzGuUfSDavqpR0wotHjhomKeHsJGq4f3JZjbGSEPmHtccSU8x6J/0fGJ1LkWMDPeHLOKeR+DkLfvZQ+9yxtiZSxybMRrkWOcdsciU+pxxAz+3FknG+EdyVEzPjeyL/SPIsRYzYclTI3n7JA+oiUBdglynFZltD2oRjep5R2yKPn0j2nNzHPZI78sJjzp4xDhNZfIYvGjszNH/mbWm3MHNf1yPmOPD+zxMyn0+kU/OHPnz+f3t/fj52o0QUrkVy/d/wc3zNHA3JvwcG988QMau0FiUfnSwkwRwbeUu7JbLuxXEuZYCq+a9TT07fT6fS56EkaOxJTZ3juIJcSdXAttX9BQky9Lecz09MCotBk/tjP3PocfTjy/D26xzHt4NK7LT6S0kcQU29L6fuXEtrPNEm6XqxOSWToQYn+eI76oBYx9bYe32Ptw3WNkPTYU38sp+ikVTH1piPzHq2TfG6J2X1+pnchpW8a8jc55NzsINf5ao151W6X1k7anj2u5o6pPc413lMrTs6UXN9TUlGMnONJPSUbj2j2mLpt8XH1yEYYRxY35XKkjPf+NiZ+pNQvI8XZ3rROFA0pQ662ZsrClNDzpXzPW8TU22Lv2eh1rhhXV0hubMpxj8zR5zjvnhGfsdwxtfjO9SNd5Jw7jZQSer5cK0RCd7MovSIlZLVTD427lcQE9dEbJECfRo7HtRvGlNfT/UpZxR3zGfpReneBR/89xzOVeyLAM9xerUUWeztKjNgPGWFiujcx8enIYGFKQnGpSc6cfe0jx6qd1ESf1LXrSNmhqJaeysKY9tqU21ZuAjXGo7mZVerhnuaKQs7b6xxirmPWqCOOzGXe+ttV3pEWSj7nPSRophihHRWqVJlj+pe1Y8ujzx5J6jwyjpryTIec98jzKabm96gdc+u+9BLTrv977H+7d+xS+UWUF9IGS2njpZRp1mRSjsnV1ixRH+/xjLZRqz1c6/72NJbRs6id65+env61bdvv5YoD8F9/OZ1Ov7QuREliKlCRmAqQj5gKkI+YCpCPmAqQ19RxVUwFKps6pm6buApUJaYC5HM3pkYl1wMAAAAAAAAAAAAAwIw+tC4AAAAAAAAAAAAAAAC0JrkeAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmS6wEAAAAAAAAAAAAAWN7HmA9/+vTp9Pz8XKgowNl//vHPn/7tT3/9c4OStPPt27d/n06nX1qXoyQxtR/X79xq7xvzE1MB8hFTAfIRU7mmfw7HiakAec0eV8VUoKbZY+q2iaukuZUjtG3GRXrQ41iVmAqQz15MjUquf35+3t7f3/OUCrjr7eX1p3/78v61QUnaeXp6+r11GUoTU/tx/c6t9r4xPzEVIB8xFSAfMZVr+udwnJgKkNfscVVMBWqaPaZum7hKmls5QttmXKQHPY5ViakA+ezF1A81CwIAAAAAAAAAAAAAAD2SXA8AAABAMW8vr3d3XwIAAAAAAADoieR6AAAAAAAAAAAAAACWJ7keAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAADo2NvL6/b28tq6GAAwPcn1AAAAAAAAAAAAMABJ9gBQ1sfWBQAAAABgLiZ2AAAAAAAAgBHZuR4AAAAAAAAAAAAAgOXZuR4Ku9yt78v3rw1LAgAAAAAAAAAAAADcY+d6AAAAAAAAAAAAAACWJ7keBvH28vrDLvgAAAAAAAAAAAAAQD6S6wEAAAAAAAAAAAAAWJ7kegAAAAAAAAAAAAAAlie5HgAAAAAAAABgMG8vr9vby2vrYgAAAEzlY+sCAP9j4AMAAAAAAAAAANZ2ziH68v1r45IAwHrsXA8AAAAAAAAAsBC73gMAANxm53rIzMpRAAAAAAAAAAAAAEhzuSi4Vl6unesBAAA6ZxcpAAAARqZfCwAAAMAo7FwPAAAAAIW12FUDAAAAHvHL7AAAAD+SXA+Z2HEFAAAA7jNZ/z+uBQAAAAAQYi8fyTgjAJTxoXUBAAAAOO7t5dVCTwAAAAAAAACADOxcDxVZMQoAAAAAAABATuahAcZj4yQA6JfkegAAAAAAACA7CUMAAKzM4qe5XPZv3FOANmrVrR+KHh0AAAAAAAAAAAAAAAZg53oAlmXXJAB6d6+uUocBACuwuxs5eI4AAAAAAIghuR4KkfAE4zLpCgAAx+gLAwBwlHFZgD6IxwAAwOok10MDBiQAAACYiaR6AAAAGJu+PQAAwB8k1wMAAABAIZITAAAAaE3fFAAAIJzkemjIIAa04d0DAIA8tK0BAACgP/rrAH05x+Uv3782LgkAEEJyPQAAwCBMigEAADCyy37tvcQiiUcAAIzu3nxOy3ke7ezHzMMB9KVlXJZcDwvQQAYAWM91R1NbEACAlZgQB4Cxmd+8TzsHAACgLMn1sBCDUAAA8zKpBgAAQC/0UQEAAAAYleR6AAAAgAFcJihZNA2sxIYRAHOTiA8AAGmMnQBAXpLrAQAACjKgCZQwe2y5TrBq9T1LX+fZ7yMAAAB1WbAEwCPGJH+m/gTgmuR6ALLSEeuPewLU1CrmiHUA+YipAMxohF+AGaGMAFBbrvpRXzdezDXrZZE8AD+SNA4Ax0iuh0S1G6IGfuiVTln/xA+gJPXAz1wTIJdW8aRUgt+I7dIRywyjiIlx3kWAPuROdH3038V9AABGYW4IAOooPW4kuR4GFRIcNNrZU7qC6WXiI+U96OU7AADAI9dt15Ad4460d/Uzw7lWAGuzCz2tlBzTvNW+MYYK5Ja7L1Wjb7ZX7+eMk6P3M+1uD9Cn1dr0o9enACvoIVZLrgd+sFqjeQWPBqpS7nlIRdbqmcpZybacDPVOAsSZJW720FkExnQvfqTGlRJx6chu1SFKJizMUs/EWPE7Mw7Jy/RIW54W9pLez+7FyVoJoSlufb/Zf1npyOLZo+fIdTxo4d77u1cft9p8qsdYU5I2ETCTWTe/vC7z7HXViPeIuc30zpXut0MLkusLmSn4rWTE+/ZogDX1uNdGujbcluMZOXKMEd+v2kIGe+9J2W3UPQGoQ10I3HMkGSDmMzWOQZpHffDaiU+eCXrX087JOTYt0D48pkT9mXIvUpL4xN0+xLyTOd/9lLG6HL/aWfo8paT8clPoMVPKFXKcHGU+otb9jHm2c7wHe/Nk6tp5lFpQflSp8/YYd4F5xSSO91qnptb/od+v9+tQ0srfnbGVHrvLMeazyvvV8/fsuWw8Vur+VU+uDxnwjk0SvjxWjoTBe8eYdSXi7EoNTvZ2r3srD3Pp5fnqIQ732qDKNZEW+r1Sknv26vzZkxFGKiuEar2zby911KWUyfqS38eOdIwsZ0ypvdCwxzg1u3vJNTGJcr0ISSB+NI51+W/MRx/jZyWvyQi7O/fsyDVqHZfF0nkcSSTP1XaInWAPSQwqNaeRO7m8htZx4uxIuy3kGI8+W2qsPOU9yBHnj7xbvTwLqwm9/yvWqTnf+dZScjlCjlv6VwTuybEoJ/eCnpJjYJdyzM+RJuT+pBw3ZRHykSTS2s/SkUXVIdcktP02Ugw/Yrbxj1qL4Ua6JjPLEaeOxJgS/enSi55icipz5OA++vdbZcn5nqXUhaXq7Z6VuBZ7bece69ZqyfX3AkrIZ2OPndte2Y88EI/kCOJ7Cw7unSem47cXuB6dL3fQLRE0R2wMpig1sUB+tZNCSsTXHBOpsw3C9tRACK0zQv7m+m/3Bihizt96wDYkeenoMSBUyuT9kfOM/ozmeOdKvLc9xv8SAxUQ6shgZekyPOoTl05kIc2jtmZKG7OHexQzMB2b2BVyXHVDGyljWSXvYa32aYrcY5Kh72DtBZU9CE0ky/VM1EpAYkw9tMl6HafNfb5e35/afYgWZchxvpx/UysJrddnbma5npNZxhyPGv3ZHb38l0JyVkov2u3luKu/l72JmYtM2Sk59Pwxn8mV01PimUyZy11ZzrZdjkWYI8ap3Llu3Baae5IjZynXZ3Mcq1QdHvo9emzX5DhW7nveetPSFK3aFD0onlzf85e/NsJgYc7AdSQApzSa7lViqUnCsYEj9Z6N9EzfkyPY6mDPZ4Znu6Z770DpRKtWWk9EpnQaQuqQsyNJD7Um6MTb+vbubaukjSOd/By7ReVIRNpLYKw9+JszLvW8knpPygT4kQW4OUjq7FvKQHfr9yclXkgOYTQlB6TF5XJKt4mOJOSPMI56z5F2Ta7zPfpMSnu/dP+lhL17MdIz1nrMBLgtd4Jhr++rsUk4buSxDI7NCZU4/95/Sylb6fib0t5WJ9RXer6jtNBnZ/QEPB6rPZ7Y8/MiptLSkfzPXp7ZWXOyzm6V/UjObY78jiN6eU5yeTqdTuEffnr617Ztv5crDsB//eV0Ov3SuhAlialARWIqQD5iKkA+YipAPmIqQF5Tx1UxFahs6pi6beIqUJWYCpDP3ZgalVwPAAAAAAAAAAAAAAAz+tC6AAAAAAAAAAAAAAAA0JrkegAAAAAAAAAAAAAAlie5HgAAAAAAAAAAAACA5UmuBwAAAAAAAAAAAABgeZLrAQAAAAAAAAAAAABYnuR6AAAAAAAAAAAAAACWJ7keAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5H2M+/OnTp9Pz83OhogC5/ecf//zh///pr39uVJJ43759+/fpdPqldTlKElP7cX5XRnpHIIaYCpCPmAqQj5gKkI+YCpDX7HFVTB3b9Rzwtpnjom+zx9RtE1dhNj3nkIipAPnsxdSo5Prn5+ft/f09T6mA4t5eXn/4/1/evzYqSbynp6ffW5ehNDG1H+d3ZaR3BGKIqQD5iKkA+YipAPmIqQB5zR5XxdSxXc8Bb5s5Lvo2e0zdNnEVZtNzDomYCpDPXkz9ULMgAAAAAAAAAAAAAADQI8n1AAAAAAAAAAAAAAAsT3J9oreX15s/uwa5edYAAAAAAAAAAAAAoBzJ9QAAAAAAAAAAAAAALE9yPQD8P78QAQAAAAAAAADUIk8BAPojuR4AAACALEwEAQAAAAAAACOTXA8AAAAAAAAAAAAAwPIk1wMAAAAAAAAAAAAAsDzJ9QAAAAAAAAAAANDI28vr9vby2roYAMAmuR4AAAAAAAAAAAAAACTXAwAAAADQnh3aAOYlxgMAAAAwCsn1AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADLk1yfiZ+zZASeUwAAAAAAAAAAAAC47WPrAgBAKxabAABAHtrWAAAAAAAAwAwk18NgzgkLX75/HfL4AAAAAAAAAAAAPbGJDABnkusBAAAAyOpyEsLibQAAAAAAAGAUkusBAAAAAAAAAAAAAOhKi029JNcDAAAAAAAAAAAAANCFy6T62iTXAwAAAFDMeeCr1k4SAAAAAAC9a5kwCADsk1wPndOYBgAAAAAAAAAAqMfGMQDr+tC6AECf3l5eJfYDAAAAAAAAAAAAsAw71wOS6AEAAAAAAAAAAABYnuT6jvgpGYA+iMcAAAAAAOls7gNQlzkuAACAdB9aFwAAAAAAAAAAAABm9PbyauEpAAzEzvUAAAAAFGf3PAAAADhOUiYAAEAddq4HAABgKXaIAQAAAAAAemQOAwDas3N9BzSIAAAAAIAVGRsFAAAAAAB6IrkeJmNCEgAAAAAAAIAY53nmL9+/Ni4JwLzk9ADAGD60LgAAAAAAAAAAAHm8vbxK4ASAB9SXANxj53pglx0KAAAAAAAAAPolMRAAACAfyfUH6JgCAAAAAAAAAKOT/wDQp1vx2caYAFCH5HpYmIESAAAAUuhXAiX4JUUAACjjsh+vvQ0wHmMmAFCH5Hro0JHkBAkNcNutzmWr90VHFwAAAABYmaROgDZi5sbMZwHkI5enPfUaAEdIru+QSp04FlT+AAAgAElEQVQeeS4Zxb1nVaeV0YnDAAAAAABADPNjAMyk1Jy5+hKAa5LrgWIkglLTSJ0d7wYApFOfzsc9BQAAAABgBiPlL6zmyL0xfwGwnmWT60v97KTKlFpaPWuecUaRo7PqeQegF9p+QG9MDgH0RbsNAIBY+vYAjOpWHWZMBGAee32VWmPhyybXlxZyA3VW59bzhFbOpONLPX5X6FnPcQKAPugz/Mw1gXQp7VCLWAEAAACAlRjPHMu9MWzzSwDEkFy/9dsI6rVcxIn5lYSUnx7qQU9lYWzXz9L1uzPaszZaeQEA6F+OMQPjDrC2R31vAACgD+aZALg2+9hur+NWNiLt1+zvBFCf5Ho46F6lPHqCPPSs1bsSs0imNB2COe09Y+oIoAc91YUpxNQxzPK85VTq18fufebWdS/x/mjbQl+8k2PSvgEAmIc2OUAbofFXnG636UvM+HZtnguAfHoa754uuT4l4fnRZ3I0DFqosZovJflhhMSJXPdPgwqO6anijO1Yt6DzP7aenncAoK2YdkFKG+L6b7VHYG613/He+p4jjEUCrOLRnN7533urSwBK66VfLv5CXd65/tQanx2RX1ZNs/J3L821HYdx2nWNcu+LJ9fXCFi1GiitdiQ/coy96126gVPinpdeIJByfDvVs7KQ3bZLv0+tlPj1ilLX6tHxR2m0zGikZx6o6158MCD0s5Cf4BRv+5LyHM/wDuR+Zmd4vmuPMeQ2QhkZW+0+216cikl2zDkuOtI4ZoreygNQS+hYa+7x6F7kKvvI1yCnkD4XaULapzU2f2sh5/eaoT8/CvGR0dyLDz08wzO9T7eu84g5DrXG23Nu7jK71b5vr3LG0pTxxVr9k5D3uVUb/d6Ycszf5DgvafbuW44Namvl28WotnN9zMsZ+tm9C7p6RVXr53ByN55Cj5fysqYeH0ZXu/FwpAE3kpxlz52UcGQH0pSd+WsPoj/6PimDHpd/W3sBFpSi8/hYyDubs63Z872oPahxlqu9IP6OJeeC5dRJgJy//BMzWOiZ/UPOBaSpZUgZCCxRn5QeB6EvOcf19vo2KWUq2d8MOf/Zre93ZCw5pRz34nzuBQdHxswfJanu/ffQ7zXbgv2cz+kM1wNi1J5zCl2UHpOQf+Q77P1tjV96PpIUlivWlf6l7Nhz6FeVl9IP6mnRQ85248p9tRHHOHsuc89lo4xcY6K15/xD/732s5y7jXKkXmstJVE+Rxus1MYLI1nt+44qZfy+1jxPjjLmGhcOlWtMO+ecYcoxj8TSI+MDIccIHbOIueelF1XF6Dl2Pp1Op+APf/78+fT+/h51giMNqZ4vGOEe7WhV6/x7PGt1HOm8PD09fTudTp8LFKcbKTE1ZFeelHev5EQ0Y2m182+OdkLpeqDVeyKm3nYkpp7lTBCOGTgqtSo+1JFj5N7ts0TySUp9l6OuvDxOyg4FR8pSKlG9hVoDPmLqbaX6/q2eu5j2cMrgFv1q1aYNUeJZChnATelb5iSm3tbTM1rCCO/kWU9lG1FIjLmndnJRiXmMkD5XzqRcMTVejnc8R1szRo/jTmdiZhm16qYcY509J8Lr//+sh3ZqyQXue5+pbZU2Zunx4VZjhI/abyFjXznnamPKuPfZ0IS8XMncs8fUbYuPq6Vi6pF5l9Jju0c2sUhZaPioHLPG4XtGSHrvYR6hFTH1th7aqjX0EpeOtMFa5YG2vlZ7Rijjtdzt75HyqM72YmpUcv3T09O/tm37/XBJAML95XQ6/dK6ECWJqUBFYipAPmIqQD5iKkA+YipAXlPHVTEVqGzqmLpt4ipQlZgKkM/dmBqVXA8AAAAAAAAAAAAAADP60LoAAAAAAAAAAAAAAADQmuR6AAAAAAAAAAAAAACWJ7keAAAAAAAAAAAAAIDlSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHkfYz786dOn0/Pzc6GiALf85x//3LZt2/701z83Lkld3759+/fpdPqldTlKElP7sep7xjrEVIB8xFQIc25jb5t2NveJqVzTP4fjxFR6JbYzqtnjqpgK1DR7TN02cZV6LsddL2lv53V9nXu6vmIqsJJb9V7OmLwXU6OS65+fn7f39/c8pQKCvL28btu2bV/evzYuSV1PT0+/ty5DaWJqP1Z9z1iHmAqQj5gKYc5t7G3TzuY+MZVr+udwnJhKr8R2RjV7XBVTgZpmj6nbJq5Sz+W46yXt7byur3NP11dMBVZyq97LGZP3YuqHbGcBAAAAAAAAAAAAAIBBSa4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrodBvL28bm8vr62LAQAAAAAAAAAAAABTklwPAP/PIhYAAAAAAAAAAABYl+R6AAAAAAAAAAAAAACW97F1AQAAAAAAWJNfkANYwznef/n+tXFJAAAAABhVrTGm6Xauf3t5NSEDAAAAAAAAAAAAAEAUO9cDsCyLsQAAAAAAAAAAAICz6XauBwAAAABgXH6dFAAAAAAAaMXO9TCx60nIL9+/NioJAAAAAAAAAAAAAPTNzvUAAAAAAAAAAAAAACxPcj0AAAAAAAAAAAAAAMv72LoAjOXt5fWH///l+9dGJeGI8/1z3wAAAAAAAAAAAADgR3auBwAAAKCYt5fXnxbrAwAAAAAAAPRIcj0AAAAAAAAAAAAAAMuTXA8LsmsgAAAAAAAAAAAAAPzoY+sCAAAAAAAAAAAAALRio1IAzuxcDwAAAAAAAAAwGL9YDgAAkJ/keuAHBmAAAAAAAAAAAGBe8oMA4D7J9QAAAAAAAAAAC5NkCUCslLpDvQNAzz62LgDws73G4/m/ffn+tVZxAAAAIIjJEAAAtk27EAAAAIBxTbtzvdVtAAAAAAAAAAAAAACEsnM9AAAAAAAAAAAA8FDODW8vj/Xl+9dsxwWAFJLroZBz42+v4RfymRJ/e+9YAAAAAAAAAKwr5zw0fXOv4Q8zvAsx36F1jlDr8wNACMn1AAAAAAAAAAAAAAA01cNCrCmS63u4kAAAAAAAAAAAJcmPAIC6Zvh1AwDifGhdAAAAAAAAAAAAoL63l1eLNoDpiG0ApJhi53roSe2G2fXqSA1DSGfVMQAAAAAAAKMwtwUAAKykdB9Icj3TW2Ugocek+lWuPQAAAAAAAAAAY+gxx+aekcoKALOQXA8L0wCHci7fLwtMAAAA6M0ImyKMUEYAAACAXhhLAWBkPeWzSq6fROnGUU8P7QxGuJ4a3OA9AAAAoD59UQAAgHpsmAUA8zPmCn3K8W6Wer8l15NExRNnhKR6AAAAWJ3xDgAAAFax6hz2qt8boLaYeJszyRKAvuzF+B5jt+R6ptXjCwcAAACrkrAOcUq9M63GzMQAAAAAgP6USmg3BkSPjFECoSTX05UjFdh1Ay1H5ZezIg2ZsOx5IYBGBTOKfedu/Rzkvdhz69jeIwBWot6DfbO+I7X7tSXGAoAy7sWHnsfDAAAAgPXcG7uNGdPtZfw3Jdn9Vn5Er2qXdaRrA9CrUeYGpk+u76XRUsr1g7ba9435zOzXBuifOAQA5RjQ7IP2DiEeTVJd/jfPFMxnlIFzAMqwoyUAtKdfBmFWe1dybx6a4/qFjCXnPN8RKRvJ6gsB9Gvo5PrVGjEr0YgAcstVZ+TsAJ6JdQDMQP+MSz316Xoqy4xKvfu9bCbg+XnMNSovVxKiDSmgH947AGBU2jEwv9Lv+Qhx5MiYZ4lx0tzHTPlePd+vWLk2a+plDJt95i+hndHj4tDJ9TFK3aheH4DZdm2sVdGpUIGjRowfvdZhAJBKHTemHu/bkZ/7jT32pZ6+e021dzsqdfwji2hT/iZld/8e3zfmU/J99QwDKcSQeDFtlhHHSXvkOYUw3pU6xHaoI8eYz0hSvl/ra5NrDHHWe5vDvcT1HMfKddwj1KnAikaNfV0m1z9qBOXeNTi2sdLyZpdYRThyo7O01tdmVD3fU+hR7ViTo+MpLgIAlx7thnwp5Odbj57/8tgld42ptVv72fWE2uW/hR5r79rcO0/pNl/O65g6KVVjZ6mcuyDd+re9+1bqWtO/I4tXSiwoSpVSzxw5fus+bw9975JJHaUXmN27n6nnffSchFwju9r1LWdyz5Hnba9NW3IR3Ui/+NlDIlLMHGbOmJkzHud41i/VHtcWM7nF8/E/OePUiv2/1Z+l1b9/K4+SiFuN1fVQ7+f63KXcY3SPPjvL+7RinZCLa8fMbCTFzJol14dUHCGDkTnO+2hSOcf5ajXOahwn9fwpExa5tb4mI7l3/3oYzIY9I73nuTrYNZICjgy+hiT5jBxHZhsgAQgVkuwmNhJjr/32aHxglv7ztb2xjNDFCjHjMLf+/0jvcWgb88hk2C05E9dyjoUduedAuCOxJjZ5KffCoSPJU4+SOnLEx0dlCD1mifbB3t/G1sWx5xmp7h1BzNxQ6WfmrPWvzpRuZ+Q4Xsw7GFKmlAWqOc7/SMzzsxc3Qp+XXO390ETeXPXCo3ldMZUZlY4x/GzEOZ8SC2JH+v78Iceiz9TjX5/jUfypHZ9axcOYMV7Gps7tQ4n70POcyezxJCXvtMdr0ipXqtZ5Z4mDxZPrR+7oxbxgjxqQt4JryaT+I2593yOrQXtf4V7q/K2/Vw9cA0LEPCdH4u+R88wg12TYkcSjI5M1oZ8J2aX1SOPvyPU6kjTVYyOdvGZaINKTnju6vciRNBBznp7vxZFkVdpqncRTIgmmpdZjJpQfpK/5t4wjNImt1Hl7dmRMN/TfY85baoFLzviQUhfm/n61r0Vvx6Ccnu9PSkJ5yvFnU/Ka5Bo3rSUkAT/Xsfc+02qudJVnfmZHFrjc+/cexoBC215HvmfM+Wsfv/Y92Is9ORfbl048OvJ8XB+jBHNe48oxt3v0+CH/HaC11FzHntqdl2q1XY78TasNmXu9V7mUbvfHlGE2zXauH0nugbnVGpmzfR9oKaXCLzFYV7rhE5M4P1Osyb1gqVZiTokGae57XXKgOOZ8szbaZ5Er1oZOKtx6Tko+I3vf795Afsq1SKlvYq5nzPlq7Pp55Jh7St2D2GOVON6jY+aM+7MPnhBHYhIwA4Pi4Wp9l1JJlr0t5GllxDIDc5g9/hwZ+3x0rJTPzH69VxByD2v9Ot2944aMK7ZapJJTqz7D3rh3icTe0nOHj5Lgb4lJ7g+Ni62T7ckntY6t9auHpMuxSBEIV7v91loPY56hn82dP3A20masKdcm9BhHylP7l/tG8XQ6nYI//Pnz59P7+3vUCVa6mMBtRwZGnp6evp1Op88FitONlJga0zCYqXKb6btQ3qzPi5h6W6126qzP1epy3NeQX38a4fkZoYw5iam36fszq9ViXG1i6m1iKnBUbFwVU28TUyHOrG1mbdWfianAUWLqbbFxVUwFtk1MvWemtmrKwrxc3ynHpp4jyHmtW/eNSy/8DTn3iM9F7pgalVz/9PT0r23bfo8uAUC8v5xOp19aF6IkMRWoSEwFyEdMBchHTAXIR0wFyGvquCqmApVNHVO3TVwFqhJTAfK5G1OjkusBAAAAAAAAAAAAAGBGH1oXAAAAAAAAAAAAAAAAWpNcDwAAAAAAAAAAAADA8iTXAwAAAAAAAAAAAACwPMn1AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADLk1wPAAAAAAAAAAAAAMDyJNcDAAAAAAAAAAAAALC8jzEf/vTp0+n5+blQUWAu//nHP7dt27Y//fXPXR6vd9++ffv36XT6pXU5ShJTgVrEVIB8xFTYd+67XlqlH0s8MRUgHzGV3q02x8H4Zo+rYurY9L0ZzewxddvEVcrQhuYWMRVYSem6cC+mRiXXPz8/b+/v73lKBZN7e3ndtm3bvrx/7fJ4vXt6evq9dRlKE1OBWsRUgHzEVNh37rteWqUfSzwxFSAfMZXerTbHwfhmj6ti6tj0vRnN7DF128RVytCG5hYxFVhJ6bpwL6Z+KHJGAAAAAAAAAAAAAAAYiOR6AAAAAIp5e3m9uaseAAAAAAAAQG8k1wMAAAAAAAAAAAAAsLyPrQsAAAAAAAAAzMcvGAEAAAAwGjvXAwAAAAAAAAAAAACwPMn1AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADLk1wPAAAAAAAAAAAAAMDyJNcDAAAAAAAAAAAAALC8j60LAAAAAAAAby+v27Zt25fvXxuXBIBSzrF+28R7AACgL8amADiTXA+D0ZADAAAAAAAAAID5WaAKAPV9aF0AAAAAAAAAAAAAAABoTXI9AAAAAAAAAAAAAADL+9i6ADCby59jAsZwfm/9hBoAAAAAAAAAAACsy871AAAAAAAAAAAAAAAsT3I9AAAAAAAAAAAAAADL+9i6AAAAAADM7+3lddu2bfvy/WvjkgAAAAAAwB/OY9cAcCa5HgAAAIAkJh8AAAAAAACA3C7nIWtt4vWhylkAYABvL6+SggAAAAAAAAAAAGBRkusBAAAAAAAAAAAAAFie5HoAAAAAqvGLUQAA89C2AwCANNrUANCfj60LAAAAAADAmkweAwBAX85t9C/fvzYuCQAAQBuS66FzJhjJzYAYwI/ERQBoQx0MAAAAAAAAXOohZ/ZD6wIAAAAAAMCZn0MHaEP8BViT+A8AAPAjO9cDALAkkwUAAAAAAMzg3q/D+dU4AACAeHauB1iUXSgAAIAe6JsAAAAAAAAAvbBzPQAAAAAAABDEwkgAAChHexuAUH6pqhzJ9VDYZaNXEAMAAAAAAGZjMhegLxIzAfonVgNAvyTXwwKuG+QGtwEAAAAAAAk9AAAAAPAjyfUALMvEEQAAAADAj+xCD8C2qQ8AAKBXct7Kk1wPAAAAAABkIQkL1iYGAIzjOiFHgg4AsDL9WeCS5HoYnIodAAAAAADoiQRNAAAoR64QAJQluR4yaT1QrOEMAADAyC771fq2AAAAAMBKQvKOWucmwQrk4AHbtm0fWhcAVvL28qqhCwAAAAAAAAAAJJGHBHG8M0AoO9cDwBWrUGFN3n0AAOiLNjpAXyQgALSVEoe1rQEAYFza8/VJrodBGcQGAAAAAHpxPV5pwgf6Zo4BAADgNmMa87vsE7vPwC2S62FiBschP50oAABGcqtfqC0L9MC4FQAAAAAtGZ+az5GcHs8BI/G81iO5HhIdCVglk3NDyiM5GMJokAAAQBv6rcAlMQHguJQYanwUIJ9a8fjRZ8V24ExfG1hJb/l9EEr7vR3J9bCjdCWpEqamkStb7woAkJO2BStImXgf4d2IeY+983BbyLvh/QEAgLIu++Ta3QActdoYTqtFxOrtcbR6J0acb6E/KYtBts1zl4vkeghwK/iMnKgMl1brZOXiugEA0JOc7dOe27r64lDeCO9Zz3GKcCZ8gFjiBjCDvbbs9X/rpW2eEn/FbuhPrsTibev7ve51c45eYnusR3VUrmt37/q0rhuPbGbT8/sxo3v3KMcz455SS64YN/szW+v7Sa6HSDUaaqM2ppnHvY7RLJXuKu/YSIMb0JPZYh4AbdWuV0Lauqu2h4E/jPxuXJe9dqKOxKBjek0Sg9Zq/XJuzx4lzjz6HMDI9mLbrHGvl7H3mAUOUErIBo8pO3LHtKdCzvsoaTXH7uGtd5e+/DcxIK8c1zV1F+ej51+xvuY+Y4Okal33tTZaPSu5Hi60bvjUPv9oAYuy9jqP1/8/526Ylx5Nsnpm/2evwVXj+uk0AADclrNf17r920Ob79H1bN2Pj9HD9WQMtRM9Qo4Zet69d7L0cx+aoMkxtZKAYzZ6KDlJnuN9gHtGar+04hpxi7p+XSP0pfbKOFtMy5kg2XojgtRk45xGvK7kk2Nud28x+tHyxDxLuZOnQ49z67w5rsVq71OpGPToXuRYhL+Xd9Laas/Rqnpt6/X8bqziyC9eEKd0nB0iuX71yiakAdnjqpbW9y2lo1Fb6/Nf6vFZYg6z7qAZ8848iks5V/anOrKrQcnzwgx6eb57KccsXM8wj+qPWgu/RmxrcFvrBL/ag5JiTR6lkn5TJhxzloN51aq/Svfbe6yHQ9soIRsS5NxRsCclFo3VOl+KkLo+xzhOz/d+ZrHXv3RSZ63noZf3i3J6n9+JeZeOzPHtjWX3di1mVru/XlvIe9a6jL3I1farvctxDjkTolOOkfsZ9Gy3E7IIv+R5W0hps9cuR44NCXqRY7FCD9/zyKKqklpuRkE5rcdJU+ZCQ+a8Qs8XU4aYTTVG0vpZCDl+zPPyKE8sZK40pq7o+Tl4Op1OwR/+/Pnz6f39PeoEuVcnXh4rx8BKqhLHzR1AQwNiq45pqXsSc54eGnczyPlzZU9PT99Op9PnLAXr1JGYenYkobuWGsnYPSSf35Oyo9qRRktPUiaZj3yvnhtYZznqXDE1TEo7NUTKopiS7aQjk5JHzrN3jBrJpLfOk7MdnjMpMuQ4tSYZQ8tz5Ji3jp9jgD93nyS08x9DTL0tZiAuRz2Ys1/bU/sqpu2XY1efI1qdt5aU9nfJtvsIbd8jxNTbcrRTU487k9pjJil94Nbtw1mekVZjKUfaxTnvuZi6L6Z9eiQO9zD2eG2Wd/qeWdtHKXqpX0KS3e+VrdRzq///s1Ix9az03HkvyfV7Vus/X8v1vVuNzceWZ+98OWLdkTHXlDnLvXOIqbfFxtVZY8NZ7nezlznzlM1XeuwznM3+PPZMTL2t9Jgq8UqPR4zYxx/pmeu5b5Kzjs8dU6sl15/1OPAXm3CRWq6eH9Ztq7/adU9PA28cpzF4W4nGYE/vb0k91iVHHFkF2vP3aeXItbk30dNjAtu9csQQU29rfS9L6+WZjZGzzEcWm/Ysx0D0kcmUXvoB21amjGLqbWIqjC1n+/hSiYRQMfW2UgszVo/Vtdo3pZN7co6JtG7z8T9iapjSiaCM6cgcUe1NBo70Z0MXFqckLfTwXvRQP98ze1yt1U5tNR5VatMfftbLXH1Pse1a6XHv2sTU2yTX39fz+1lCb3Hx0ir3YCRi6m2tx1S5r5dNO/baRPfqHXFxfk2T65+env61bdvv0SUAiPeX0+n0S+tClCSmAhWJqQD5iKkA+YipAPmIqQB5TR1XxVSgsqlj6raJq0BVYipAPndjalRyPQAAAAAAAAAAAAAAzOhD6wIAAAAAAAAAAAAAAEBrkusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOVJrgcAAAAAAAAAAAAAYHmS6wEAAAAAAAAAAAAAWJ7kegAAAAAAAAAAAAAAlvcx5sOfPn06PT8/FyoKcPaff/zzp3/701//nOU4R49V27dv3/59Op1+aV2OksTUfly/KyO8IxBDTAXIR0yFMLn6tcxNTOXaOXaIFxBPTAXIa/a4KqaO7d4c8LZpS9On2WPqtomrlLEX76+J/+sQUwHy2YupUcn1z8/P2/v7e55SAXe9vbz+9G9f3r9mOc7RY9X29PT0e+sylCam9uP6XRnhHYEYYipAPmIqhMnVr2VuYirXzrFDvIB4YipAXrPHVTF1bPfmgLdNW5o+zR5Tt01cpYy9eH9N/F+HmAqQz15M/VCzIAAAAAAAAAAAAMD/vL28RiXUAwDlSK4HAAAAAAAAAAAAAGB5kusBAAAAAAAAAAAAAFie5HoAAAAAAAAAAAAAAJYnuR4AAAAAAAAAAAAAgOV9bF0AAAAAAObw9vLauggAAAAAAAAAh9m5HgAAAAAAAAAAAACA5UmuhwbeXl7t5gcAAAAAAAAAAAAAHZFcDwAAAAAAAAAAAADA8iTXAwAAAAAAAAAAAACwvI+tCwAAAAAAwJreXv6PvbvHclu5FgYKail1ZN3YvZaHYA1A03iZ5uH4zaMzT6MH0D2EF9zYduQB8AvuR4uiSBAFnPrfO7pXTQJFonDq76D499pFAAAAAAAA+C/J9QAAAAAcIjkWAAAAAAAAGMGn2gUAAAAAAAAAAAAA0v3jr3+3AQoABLJzPQAAAAC7WLABAAAAAAAARmLnegAAAAAAAAAAAAAApie5HgAAAIDs/DQxAMB89AEBAAAA6I3kegAAAAAAAAAAAAAApve5dgEAAAAAAAAAAAAAAODa9a8i/s///W+Rc0quBwAAAAAAALK5LIKWWgAFAIBeXScQAsDMaraJkusBAAAAAAAAAACgMMn0ANAeyfVQUGsdYjvFAAAAAAAAAGDtGAAA4A+fahcA2OYff/17c8n5AAAAAAAAAAAAADAKO9dDEE/yw30t3xseWAEAAAAAAAAAAAAuJNdDsJYTiS8kFAMAAAAAAADAYz2s/QMAAPEk10NDtiS9G8ADAMxHHxAAAAAAAAAAGF0Lm0dLroeKJEkBAKXpfwAAAAAA9CdXgkkLiSsAAAAtkVwPgzH5AQAAAAAAAAAAAADpJNdDZpLdAQAAAAAAAAAAAKB9kusBAAAASBL5IPnlWP/zf/8bdkwAAACYkTE2QD9s1gkA6UqNeSTXAz912E20AAAAUILFIwAAAAAAAKA1kushE0kC8LMed8roscwAt8QyAAAAAAAAAOAIuQfMRHI9ANzwcAwwgmexzC/XAADQKos0AAAQ43aeWB8bYC7WA4E9zM/CsnyqXQBgn3/89e8SgAEAJqMPCDA2cR4AAAAA2Mv8IgDEsHM98BNPnjEqT2QDAAAAAJQhoQeAnt22Y9bQgSj6yQDQB8n1AHTt2WSWwSnAH8TDPrluAAAAAEBJEskBAOZjXRp+JrkeOpdrcsOkCUfV7nRFnt+u9wAA8IeIfnbtsQIAAABgfA4wMjEeiCCWUFpLdU5yPQwiV2CRZE9vttwLLTXEANFKx7hW+gqtlANgVPrQefl+mYl+G8DcbGQCUJfx5zrfDwAAsCyS64GNbhc+Le5Zb7UAACAASURBVIRyVPQiisku4Ki1OKK9AwCAWMbxAACwTa2+cw/rwbffTUpZe/h8jOvefa0uAgC0Q3I9HDTbQuBsn5ftSk5AqYcA9bUSi2/LYUEEAAAAABjBkTnYyPnbnn51ZE/Ccitz3WB9Y2wtxBp1DIginoyh9HXsrd5Irmc4KTfhkRu2hY5vC3qaTCHds3vk3n3w7N7Y856LFupYRNxo4XMARBPjaJn6CX2wY9cP4hYj2jOXdmQXSjhCHAYAlkWfIEKuteTaDx6oG8BWcosAOCLHHHnttuneGKF2me5pMrneQIQIpZLs+cH3OC6L2WWsdRQiHgJq8br1UEbGt6WTro2DPvllA+jfs3Z6z8+973kvlHTbXm3pr87yAHjLO+lsuW7PNi/o6Vr0JHqDla3H2ZNIZiMTeiSGAaNpIamjhTK0KuKh3dLnh14Zn4xr1nlSYxf42ay/dDSzlGs+a1txrXpy/VrD9ehvM1+4Z4s0tb6L6ACZ83MdbRhyDJgNwkm1p9MfOVCoVWdbvFe2xKtHiX2lylRLK+XI5dHnm6lfwjhKtxHuk+dGj6FAm/Yk9AL5REx0l76PWzjfs77mlnnMLeP4R9/x2neQ+guBNfvNj9qE3PO0z+ru2vn3/ALjnnvlWdnWfrXRWIje5N7EyK+EwvhmvFe39ulG/W6O9IdTjzeCUesBx+zpg10cqUt78reelSeqbHvkvL8kkW6zdfwcUW/XjrM2d+P6ca2lubm9tsTyluXcpb3l61lrc5C1Y0Tqoe7dUy25PnLRIeo9R5TqlK3929b3pywuPHrPlut1+97cuzc9+07sSsuI9twbe5LB+dWj7yjXd1f7gYYtsbv2w0etxO61wbh2pi21En9KT4busfUh16jzXFhU2c7E37rZ6wd9aOE+Hv1eafnzSSQjt9I70LSQVL/lb0eOW+s8qceIvn6P5pVyxaCUOd49Dzikni9FrfMSZ7Y2NmXBPXf9jpgf0K/qm2vRl5rj2Wfzlrn7KHvW2Z+9trd+wZZ1oxLHaMVa//RIfdkyRy9mji+iX7XmyEPjOUTV72fj2C25UXvieu41tZwikzr3rINGlSmyTZoloXckOb7vPQ8MRczZpYzXt8TynHVwLa81Z87olmMc+U5K5WvsyT3L3T94dowj+btR7ynldD6fN7/469ev5/f396QTtPLhczdUkYsZW4+99XzPytbKNWpJdBCY1ZH6fzqdPs7n89fA4jQnMqZKkGeLWZJWa7X5R+Ta/etCTL3vyLWM6EdFHuNaz/dvLjkfgE2Z1Hj096NSJiYevfeZHhZtSj2QJabut/UaXV+fnAmfM/cZtBWPbY3ZLSUfH1mw2rIAkPNeEVPva/ke7XmheE0P86RHyhiRBJZ67OjzzCg1/oqp90WPuY+IXJjds8C/5RitxcM95ckRL+/pMVGmxTI/u05r8y65P8focTU6pqb0E3PuonikzuyZS2slXjKnVh5u2WL0mLos6XFV/NjmSN+WWLXHCrXa4Nzz7GLqfRF91ZzzYUdF9EupZ+v1G3WdrsXPlWvtf5rk+ouUAfWWoLsnOWCr1r67GUlYO0bS0roRYip9mnnhO9eiZaRnExMG2PeJqWxx5CGj2pOGLSq9k+Cz8+dOnLgQU+8b/d7ItatRCca1+Umu+IOYep+YSktKtVWttom9kVz/qxaS6yMeGC3FvXjcng2t7oncBCv3dU1J8njUD24xiUVf9Vct9FNrJRUdGcOJrfTgyMMuR3aWXTN6TF0WyfW5tdi/YA6lNtBKIabe1+Pmw9YW+ranzzXSNW5h7utWdExNSq4/nU7/XJbl9+QSAKT7y/l8/q12IXISU4GCxFSAOGIqQBwxFSCOmAoQa+i4KqYChQ0dU5dFXAWKElMB4jyMqUnJ9QAAAAAAAAAAAAAAMKJPtQsAAAAAAAAAAAAAAAC1Sa4HAAAAAAAAAAAAAGB6kusBAAAAAAAAAAAAAJie5HoAAAAAAAAAAAAAAKYnuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmN7nlBd/+fLl/PLykqko3PrPvz+WZVmWP/35b5VLAuV9fHz863w+/1a7HDmJqWO4xOoLMZsWiakAccRUSKfPzCNiKkAcMRX6Yx2wbaPHVTEVKGn0mLos4ipQjpgKEGctpiYl17+8vCzv7+8xpeKpt9fT//+vH4vQ376f6xQGCjudTr/XLkNuYuoYfsTqP3z77prSHjEVII6YCun0mXlETAWII6ZCfy79ZP3jNo0eV8VUoKTRY+qyiKtAOWIqQJy1mPqpZEEAAAAAAAAAAAAAAKBFkusBAAAAAAAAAAAAAJie5HoAAAAAAEjw9npa3l5PtYsBAAAAAAAEk1w/AQs9AAAAAAAA0J5c63jWBwEAAAD2kVwPAAAAAAAAAAAAAMD0JNcHswsEAAAAAAAAAAAAAEB/JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAA16ez0tb6+n2sUAAACYhuT6iRh0A60SnwAAAAAAAAAAAIDaJNcDAAAAAAAAADTMZlUAAABlfK5dgFFdBrXfvp8rlwQAAAAAgKMkMgEAAAAAwPjsXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATO9z7QLwq7fXU+0iAAAAAAAAAAAAAABMxc71AAAAAAAAAAAAAABMT3I9AAR6ez35BRIAAFihzwwAAAAAAAC06nPtArDPZRH62/dz5ZIAAAAAAABHXT98Zu4fAAAAAKAOO9cDAAAAAAAAAAAAADA9O9cDwA7XO4kBAAAAAAAAAABAaX4RM56d6wEAAAAAAAAG9PZ6slkMAAAAQAI71wMAAAAAAAAMQCI9sCw/YoFdKwEAANLZuR4AAAAAAAAAYCJ+2QIAAOA+yfWZGZACACn0HQAAAAAAgAjWHAAAANJ9rl0AjvFzbgAAAEBrLNwDAAAAAAAAPZJcH8SiMQAAAADAXGx+AgBAT+Q1AAAAPCe5HoAqTN4BAAAAADCbR3Pj1//uoS0AAACAeiTXAwA0yO6HAAAAAAAAAMzO2jnAfTa3zedT7QIAAAAAAAAAAAAAALDf2+tJ0n0AO9cDAAAAAABUYrELALgnso+gvwEAALCd5HoAyODeJKWfKAMAAAAAACAXSfQAAADHSa6v6DKwTUm2NBgGRrYnLgLAUdofAAAAAAAAAACWRXI9AEB1Hp4DAEahXwMAAOVc979tGgAAUI+NnABgLJLrKyix0GwxG6BdBtYAAIxC3xYAAADKin6w5ja3wBgfgFaZj6YmDzfDXCTXN0DDDzCHPQ8+aSMAAAAAAOZiXhjYSrwAqOs2B0BchvHcy/Vxr8P4JNcnuBcoBUgAovn1EQAAWvdo0QgAAAA4pvYYW7IYAAAwO8n1DTkySDbABSgj54Tm2rHF+Ri+RwCAY2ov8APMyngWAIA1xusA5Yi5ADA+yfUbRHSKSnWsdOAA+tHKwvh123EpSytli3C0baz9XdQ+P4xM3xkAAAAYxbN5DvOMQKTbmCO2ACPTjwIeER9gXJLrJ/QoqG8J9hoEoITZYk2tXy7Zct6erkVKWW9fm7sN7Ol7hFTqNwAAoxtt/AxAHXvmgbUvQE17YpC4BfAH8TCGjbIAqEVy/UE9N+I9lx1gdrcx/N7u8xHHjXTv2FvLmvL5cifBR0yEmEwBAHqTo5+oTwSMKHcCktgJADCuVtfvt6zR5Cq7/i9QU6txmWO5BwCwheR6fpGyE9M9qZ2VqIRQYDyPdhe/ljNutDhYjijTkR2S7tma7L7lb5E78B9pz3JPAuc+D20w6Q8A+2lHgRk8GxMaMwL8LHJtast5Wt6pWRsBjMwvfcCYRrhP9cGAR0aIcbSttc1SZ8j5lVxPuEeNxZYk2WevuXcjjtQ4lfosa9/rSN/njFpquB416pHJ09d/exRztpRhtEFw5Hefcr7b2B19rR+dr5aUXe5LnY/6Rosna2b6rACzKR3jU86nTwTkEPHg96Nj7knMzHV8jslRT4BtSs0Z7onDa//eapzY8jlbLTuMqLd51iPlzfHLw7l+6Zk/2Bkayso97jSuhTS99dPgVgu5qD2TXH+HwBhrzy69e3YS3prUn1tKsNgyCRC5mJfydwt0bXpUv9au4TMpD61sSVivtetaxMLH6HJ/7tK7srdyHVspB+lSrt2Rh3IiH0AhLwsvwIh6b3f2zA8c+WWlXr8n6P1ev1X78+R4ULoUfdof9izqjLoQRB/uxb5n8TA6oVyd/1lL303tthG4z/jysVwPjkb0r4/0E2v9qkmtxCj68SyPYE/eSsprtmzwuOd8t/aste3ZmK6VDdRyP0Ca8t1ElqXUpoAp77l1JPcsJa9m9v5CTrW+4x6ubQ9lbFmO72/tmK20STPKnlyf2ghteW0uBgqxan2fzxbe1zrxFzmC39HXPHtPruB65DsSkPPLeY1Tjy+GAiPLEW/3JPe3nOih3W9fqaSAtd2MHj1s8uj1zCFyPiCqnqc81PrsfFELWLfnT33w68h7e3Pk80SMgR+9Zy0+ppZna5kYQ+mklKj3Piv3lrmsHP3flhIlIxxZJI+eX6y96cntedf+fWtbOFobyX0p98rWunMkmSNiveBoWWrHx1L3Xu7z9BxDWqkLa1KS/Fr+HLPYMl/06N+jfiW3dDJbzzEgt0fXIPo723q8lLZ+6/zm2nu2liW1rKnHuj6G+jqePX3MyNyWXHkykcfYM1d3xJHEyeh7/5ktcw0t969yJKJGnUe8za92bLk9Rktj8pS2IbWPkPLAUqkHG1P6QluPvXa+PSLmhHKd58jc/LP+fso6wp7zRzmdz9tP+vXr1/P7+3vSCWo3ChFPozGfqEmaGWzp+O/5Pk+n08f5fP66u2Ad6DGmAvWJqfeJqT/sGQBunYhLeUhxrT+wta8QdY0iFmkiEpAi+pjRuzeVfqg0p1IDajH1vpQE8j0iFwxy70i09eGR2vcMbTnSVu1JZn00yXwksVY/9T791FildpUjj4g2cM/CS25H4nDKcZ8RU9O1Uod6snYfP+vP5N597Vl5jp5XP/5XEX3YPXMoe8Za+qq/6r2fWiKxcO08LX0X9Ce6TSy9iYKYel9qXN3zEJDYw7WR6sfM8z1i6n0l+qql6l2uTVD2JJKXElmm0v3xXLF1hJjdUl1Lyd14Zi2mJiXXn06nfy7L8ntyCQDS/eV8Pv9WuxA5ialAQWIqQBwxFSCOmAoQR0wFiDV0XBVTgcKGjqnLIq4CRYmpAHEextSk5HoAAAAAAAAAAAAAABjRp9oFAAAAAAAAAAAAAACA2iTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAAAAAEzvc8qLv3z5cn55eclUFCL9598f//3vP/35bxVLwiiu69S1XPXr4+PjX+fz+bcsB2+EmAqUIqbCNvrQbCGmwnG340sxd15iKkAcMRUg1uhxVUwFSho9pi6LuAqUI6YCxFmLqUnJ9S8vL8v7+3tMqcjq7fX03//+9t0147jrOnUtV/06nU6/ZzlwQ8RUoBQxFbbRh2YLMRWOux1firnzElMB4oipALFGj6tiKlDS6DF1WcRVoBwxFSDOWkz9VLIgAAAAAAAAAAAAAADQIsn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADT+1y7AMR6ez3VLgIAAAAAAAAA0IhLHsG37+fKJQEAAGif5HoAACCMRRoAAAAAbl1vEGbeCAAAAGjZp9oFAAAAAAAAAAAAAACA2iTXAwAAAAAAAAAAAAAwPcn1E3h7Pf30U4sAAAAAAAAAAAAAAPxMcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATO9z7QIAAAAAAAAAMJ6311PtIgBXru/Jb9/PFUsCAADQLsn1AAAANy6LTBaYAAAgD4ldAAAAAAC06FPtAgAAAAAAAAAAAAAAQG2S6wEAAAAA+MXb6+mn3cUBAAAAAABGJ7keAAAIJxELAAAAgNzMQQEAAADRJNcDAAAAAAAAAAAAADC9z7ULAAAAUJPdzQAAAACAWV3mR799P1cuCQAAQBvsXA8AO/ipWQAAAAAAAAAAABiLnesBAAAAAIAibFYAAAAAAEDLJNcDqyx2AQAAAMztMj/07fu5ckkAAAAAAADy+lS7AAAAAAAAAAAAAFDa2+vJxpMAwE/sXA8AAAAAAAAAMBjJogAAAOkk1wMAAACQjYV8AAAAAAAAoBefahcAAAAAAAAAAAAAAABqs3M9ABxw2YXz2/dz5ZIAAAAAAADAPre/PGftCwAAmJXkeuCu28kTAAAAyMEDqwAAQCrrWAAAAEAukuuBQ64nLyVCAAAAAAAAAAAAANAryfUAAAAAhLALPQAA8IxxA/TFZmvAiPwKDgC0r+b8geR6AADgMJOQAAAAANQiYR8AoE36aQD0SHI9AAAAAAAAAAD/dW9DFQmSAADADCTXAwAAABBqzy+a+Jl5AAAAKMevkQJQkge0ANiqhbGK5HqYmI4rAAAAAAAA0VpYCIeZuQcB0smhAQAuJNfDhEymAAAAEMk4EwAAAAAAABiB5HrgJ0cSIjzFywwkDQEAQH7GlwAA0Cdz6AAAAP2wHgP3Sa6fiEDIIyY6AQAAAHjG/CIAUIu1LADgCH0JgJ+Ji7BOcv0gBDtaZMEVAGi5P6APDQAAwBG348oWx74AADCjltenAID2Sa6HiUggAwCOuO5LXCYj9S8AAOZjgRrgPvERgNpKzdfetnnaQKBV1rHq8d0D0DPJ9TABHVbIz6QhR9xLWIbRrCXm56j37qvx2SES2mC8CeNxX1ODeRV6I1ZCGXvuNW0Ks6rVNmkTgdaIS+3TXwOgB5LrJ6STMibXFdgrKgFVkmMM8byetTp8pH5vfW9vyeBHJidNbD6WY8entWP0GHMsrEMbau2EB+SjjwbrtEnATPbMhelLQB3uPQB6ZZwNQMsk13dgLdHKYJnbOtBCnWihDFDLWv3fklD77L2RA0yJsfWtfY8mE8qpnah77/zPjr8n1mwpwwj1bcv1TLnmkcntt9aO+aiPt5Ygv7ccz46fasuxcizSr/06QkrZGIfrPRbXE/KJGBu6N1mWMepDSl+2588JzKGHeJVzw5beNrKAUYy20Qcwp1niVY4Nno7mETw73ujXhPG0FE9SchBaKC9tqlWna9TP6ZLrj1zcex2AXDtIlrAnyaeWlr6rrWWIKrOOItee1YcjDUl0omZpz2JadAzfIzKZPfcO2xGD35Q4GFnmFFs+b4564uGENqQk6u55zZEHam5fG9V3vT5WSlJ/D3U2dxn3XIuIOpbjvUePu7Vub0l2v33tkYcHjr6HPEpPdETHtlIPOfWg9rj8thy3apfrWivfFeOoOS9VwpHPd62HzzqSXA9upsxL5ErAvFeOlPdu6dNaxOzXnoebn13LnmI2fYiMaal/j2Jcz1GjtKk9z9de7NlcZu9rgXwix3k53lMzLvYwX3lrT38xJSn3aHm2HC+6XsnNmkepvsWzHJ+1MkSXcUtZqKOH2LNlTPJow9g9bWRL9bN4cv2RJLYjHZJcCRkRA9pcr42Qo0FJCQopwf3ZNYhKSjvSYcxVJuYVsZB5NHn0olYy/5HJ/h4Huo9EL2rXXiRJGcA/+v/Sn1dyB7ci76PI/mJU3I90ZNKuxb5RzjK1+HkjlW5/xOk4R8bPpRyZF0h58DCyT1K7ju5Z1GhBZD//yBxGpJqJIa3VyxkcGd+tjZNyXruocWdEW5GzvdmTLJui1gYBtRYVj7526/0QUZ9S/pa7v0A5ufs9kQktoySRRmphru5Zv3RtvPFsp86I8c2e9+bWw3iDnz2ro7nHYY/ec+9ve8q2tU5Gx5cREqCi56EjrmPka1toZ27lWM+9d/zan5NytswNHpk3jTxGLnvmhx+9d8trb6VsSBRxb94rc2tt0p6crD3zZXvyFW6V3jhgds/GyylrzFGbLaQe44jouaZn8a92n2LPPMjaeyLmt2vnKK21GRFlS4m/ETkrW+SeYz2dz9sP+PXr1/P7+3vSCUo3qjmekOOHyM5YLSmdz5Tj1f5cLdtTb06n08f5fP6aoTjNKBVTa8fFiPPXSqQc7f6u/Xn2xN+I5KXouH973Nr30hZi6n2j3NsjyR3vI+7b2u1qS2q3KxH0U++r3U/do6d6eKRvEjUxtvf8o4lYGNnynpTzRLaFKfWl1j0spt4XnZR9+5oj5xndke+oh75RD2U8YrTPlxpnxdQ4tetQrrmsWufZo+U2a6R5gbWkqdEY//+qp/nU3HU1OuaMsJ7eo9xj74gEyYiE/C0PYuUmpt6XGlf31AexgS1qbQ7CPmLqfT31VfnDvT57xAMNta9rC/2tyHO3+j1HiY6pScn1p9Ppn8uy/J5cAoB0fzmfz7/VLkROYipQkJgKEEdMBYgjpgLEEVMBYg0dV8VUoLChY+qyiKtAUWIqQJyHMTUpuR4AAAAAAAAAAAAAAEb0qXYBAAAAAAAAAAAAAACgNsn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAAAAAExPcj0AAAAAAAAAAAAAANP7nPLiL1++nF9eXjIVBeCHj4+Pf53P599qlyMnMbU9//n3x0///6c//61SSSCWmArjuW6ztFdliamwzW3felnEK34lpgLEEVPhD5d+qL4nR40eV8VUoKTRY+qyiKtAOWIqQJy1mJqUXP/y8rK8v7/HlApgxel0+r12GXITU9vz9nr66f+/fXd9GIOYCuO5brO0V2WJqbDNbd96WcQrfiWmAsQRU+EPl36ovidHjR5XxVSgpNFj6rKIq0A5YipAnLWY+qlkQQAAAAAAAAAAAAAAoEWS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAABjG2+tpeXs9dXNcANhL2wQAAPEk1wMAAFOy6AAAAAAAAAAAwDXJ9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9CTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUA8MDb62l5ez3VLgYArNJeAQAAAAAAAADEkFwPAAAAAAAAAAAAAMD0JNcDAAAAkJ1f2gAAAAAAAABaJ7keAACYmmRPAAAAAAAAAACWZVk+1y4AAAAAAAAAAACwjQ1jAAAgH8n1AAAAnbBgAgAAAAAAAACQj+R6AAAAAAAAAAAAAACyud5Q8Nv3c8WSrPtUuwAAAAAAAPDM2+vJL/kQSp0C9hI/AGhNRNukfQMAgD/YuR4AAAAAgGZJ7gAAAAAAAEqRXA8AAAAAAADwgAe9AOjNpe369v1cuSRAJPc2AJQhuR4AAACAEJKOAAAAANpxb65GUi4AAKz7VLsAzOvt9WTRHQAAAAAAAACgELkaAACwzs71AAAAAAAAAAAwIYn2AADwM8n1AAAAAAAAQLceJQVe//u37+dSxQEAAACgY5LrAQAAAAAAAAAAAAAI19uvJUmuBwAAAAAAptHbQg4AAJR06S/71RcAAHJqud8puR4AAAAAAAAAADrnQVIYj/saAMqTXA8AAEzFJCQAAAAAALMzVw7ws5Z3UAagrE+1CwAAPXt7PZl4AgAAAAAAAAAAgAHYuR4AAACAX1w/RGqnHgAAZmG3SgD4g7khYFbGBAAUT67X+GCHZwAAAOiL+RwAAAAAgDaYrwXWeEAOjrNzPQDT2/PQjweFAAAAAAD6IQEJAACAkd3LZTIWhn2aTq53Y8/Bk1IAAADQFw+bAgAAAMxD/g4AADOpllyv4w1ALyQOAQAAAAAAACXJq4E5yU8AgPqyJ9fr7JPbbR171MlUB4Gc1to7bSEAR5lIBQD4wTgbgBK2jMW1SQCUZJ4YxqRPCQDtqbZzPdxzpMMYOZDUcQUA6Nt13/DZQ5hr7wHgZxFj70djbnEYgFrMB0O/9vRP3fMAtE4SPUBZ4i4zMBaGNMWS61MaIQ0WrbHAD0R41lHd05GNeCip1PmAP7iP+vDo15FyXTf1ApiR+R8AAAAAYFa386PmS9tj/Q5gXnaupwuPkpuOHGPL3+6dR8cJOCr3oDg1Tm15gKilgbw4TAtu74kt9fHZBNmeB13W3n/kAZotZerpXjwSw1qKf63J8QBCT/UKAIgXMQcIEbaMuWAUa7E2st73sNGHdmcMYjjQs0dtkTYKoC7rV3Ma9bqP+rloR6m+a+66XD253s3ajlzX4kgifMSxUs5z5BcWUpLqekg46mGiG1pUuoOQ+7x74vGenfmfxdReH3Y6kjxNfikP1z1L7ols49eOs+VefxQfIurfnnsxekGzh3t/qz3Xc8tro+rhtS0PWmwpx9bPs+V1I9QBaFULC7Z74hHQp1IPoF+II6xpoQ2EUlLGpDnGmSnv6WEuYMt8UsvlByhJHx0gzix9zZZy2rYec/Rr0ouIDel60GOZ4VrKvVqqvldPrt/C4CqPLQmTvuvtjuz0umVXrq270e65fmsBR0IDlLcnsTf63LXv8SOdptqLVikxtfb3zB8iE5xzPwh45LW5Jw723LfPYtv1sbYurPcwcdBiLN9af46WKdKRBPxW2jv6NWod6jmGjnot9nyuUesnbYuudxHxqIe5zx7v1y1lbnXsG9WnbeXzsF+Ja9lSrOlJ6f5o7rrQQ/86Qitxf5bvG5YlfkOT2kbpZ+3ZSMqvdkG80vNqqe+peb/3OLe658HbnGuIu5XkMwAAFlNJREFU4nX7cmyWF5G/0qIe+mA9lLFlOb6/iI32jp6nlC6S63NL3W2z1A7lLRjx6a1S5Tuys2zK8ba8J0c9lDxK6/Ys9rYsRwck1/lSEjSfxYfIna22nG/L8R5NdEYce41YOpec8alUYnfEa3PHq1x6Svzvua4xl62Lk6V+4evIe1tq00e6T6MT2HJOOK4dd8s8wZ73pva7W6qnpCkda7bUu61jqojz733/nnnhPYkze8uRy5Z7f8+cZA5b4mEr7Zqxflsi5paujfDgW+15gah+Wyv3fIrW6sI9R5JGUv9+fZ6IRBfaEFHPb4+R0sfs3bP6vOcBx9x9kxzX4shYeEufdrb2h/5EtotbYumWTSF7jLNH4uKzJPQ9xyg1d70n/kf0AVPmFHLN36bkYJWw1p71MDboTe3rvUcrfdoj+aGlHlY/0ufb07es9V1Ez0ndHjeyH5zrnttznlz18XQ+bz/g169fz+/v70kn2PolrjV2z96z1qHbk9jy7LV7EjVbagyPVOyIyTTqqbXgtKf+n06nj/P5/DVDcZoREVNb2iXsyIJ0ymtuX7d1cJj7ibmWtbrYXENEP6E2MfW+nP1UuCd33IhIOhvlAbMIkQuvYuq6iLq1Z35g6/Gu9XgfbPlujNvz7PqWaye5I+1JRKJEju8ohZh635Z5yz1zrluOT1ui28TWHF0EqyVH3yJi3k5Mva/0HHh0u9xa8l/0OLPFe7ymo335Iw8hRySQtUxf9Velxv6lN3DLFTdzPOTf4n0Vcb1yzUnmjEfmUtKIqfcdiasXEUnLpZSO74zJOpaY+kipHNXUY+TuMxxJBo+w5/OlvGdtHqT02DPHWkmpmBZRF2rXtVyiY2pScv3pdPrnsiy/J5cAIN1fzufzb7ULkZOYChQkpgLEEVMB4oipAHHEVIBYQ8dVMRUobOiYuiziKlCUmAoQ52FMTUquBwAAAAAAAAAAAACAEX2qXQAAAAAAAAAAAAAAAKhNcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcDwAAAAAAAAAAAADA9D6nvPjLly/nl5eXTEUB+OHj4+Nf5/P5t9rlyElMHdN//v3xy7/96c9/q1AS+EFMpaZLXBQLGYWYCuvEfVKIqQBxxFSAWKPHVTEVKGn0mLos4ipQjpgKEGctpiYl17+8vCzv7+8xpQJYcTqdfq9dhtzE1DG9vZ5++bdv311n6hJTqekSF8VCRiGmwrof/eEfD51++36uUxiaJ6YCxBFTAWKNHlfFVKCk0WPqsoirQDliKkCctZj6qWRBAAAAAAAAAAAAAACgRZLrAQAAAAAAAAAAAACYnuR6AAAAAAAAAAAAAACmJ7keAAAAAAAAAAAAAIDpSa4HAIDGvb2elrfXU+1iAAAAAAAAAADA0CTXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABMT3I9AAAAAAAAAAAAAADTk1wPAAAAAAAAAAAAAMD0JNcDAAAAAAAAAAAAADA9yfUAAAAAAAAAAAAAAExPcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQ+1y4AAAAwvrfX03//+9v3c8WSAAAAAAAAAADAfXauBwAAAAAAAAAAAABgepLrAQAAAAAAAAAAAACYnuR6AADoxNvraXl7PdUuBgAAAAAAAAAADElyPQAAAAAAAAAAAAAA0/tcuwAAAMB47LAPAAAAAAAAAEBv7FwPAAAAAAAAAAAACd5eTzacAoAB2bkeAAAAgEMsIAEAAAAAAAAjsHP9IDwJCQAAAAAAAAAAAACwn+R6AAAAAAAAAAAAAACm97l2AQAAAAAA4JnLL3d++36uXBIAAABgFpf5iAvzEuWZEwKgNDvXAwAAAAAAAAAAAAAwPcn1AAAAAAAAAAAAAABM73PtAgAAAAAAAAAAAEDr3l5PtYsAAGQmuR4AMrsMrr99P1cuCT1TjwAAAAAAgDXWEgDiSKIHgHl9ql0AAAAAAAAAAAAAgEfeXk8eegCgCMn1AAAAAAAAAAAAAABM73PtAnCMp/G4dV0n/NwfAPRNXw+AEfhJeuAo/WIAaI9+PgAAALTP+H0fO9cDAAAAkMTP7wIA0Dt9WmBkYhwAAMB+dq6HgXnqCKB/Jr8BgJbpqwAAAAAAs5OfA0DrtFVp7FzfmWdPmHsCnVzULQAAAAAAAIA5WB8GAABmZef6ThnEAvTHE4AAAAAAAHVZYwNmdh0DL+tV1q8AAI7Rn4LxSK4HAAAAYJWJYQBGpH0DSOPBBGjXs/tzy/2rbwQAcIz+FIxDcj2wykQpAAAAAABQ2u36hOQEgHRra72P/nb77/d2u996XrEbaNWe2AYAI9BX30ZyPQxCEjwA0AJ9EvYwgAcAAOAZCVAA7TM/DAAAjEByPbCLBCj4WcpkofsHuHYvJmz9CV9xhN7lXmxzr0C8I/etexIAAADGYIwPQAke2qJX+kq0QAw9RnI9kETQhXg61UAv7BA3vtptUq7z3x639ueEXhj/ATAL/UNoy5Z+qPsWuHYbN8SGfG6/a/EYGMGjNYQjx7oQH2Fs1lFgXJLrByXxCYCttBltMgibz55rvvYe9/MPORZ4Rls02rModuQ7EOMgzWgxB+AocRGAC21Cfa4Be7WWfFirLt+bJ7stQ89zaffWoMQNsD5bUmTiPOW4TsBMao9F9EXuk1zfgegOw7OOo5tln9pBbstrcpTNoA/2G2V3j17L3QLfXZtcl1+l9DdSjnfkO97Th015z6PP8+g9uR90SEl2Tznvs+t277zP2q8c1/eePdfPZCzc1+K8gPYYWBZtN/moWzCnZ2NFfc/HxE2e6fk+ejTXtSx5P8/afdXjPddjmaE3cjPSrMX3re+JLIdrFsv3Si/UVfhhy4PFLZkmuX7mQJUjsWTLwnuLi/PLkn/A0XJdi0goo22lB9RR52v5vqmhZpzaei1mjhF76uvM31dPtiyiPEu4Tkmw7qFe5C5j5P10ZOf/lN1Kck3Gbk3a35LsvvbalDIdeX3u45Q+NtSSe4G/1oMoe8amxgqQxr0D7gPKUM9+OLImZDwXa+u1GH23bOqI/KXD3LE1V/3WNjxWe9OpR+fbM9/S03Xesm7R0+eZ0YztsTo5pj25ZinHVF9oWUt1VYxtx5bcg0d9V+P3/LpOrjfpk0fuiYQjooP6s4SqLYmntepYy9eJNqQmSZeeuNpTltxPsB3dJbeEyInplF1Ran/u0lKSZSMeVGppIDWTlDbv2Wtr7XZxxFq9a62syyIp+4hSn6/0Ll+jX7feRTzMF3W+Vo5f6mHnZw+CtSiq7xXxntn5zvoXcT+1MD7poZ0vEW9zz4P07lHbeiRpK3I+pIV7iXL21J1a7e5aWZ/F31xrNDmOlXtskCLng7G5HmKIuDbR4yixtG9HNsa4dmQeM2Jzjohj99DXbcnWPl9UPEyNXS3HqT3rFuYF2rIntuTqd5Te2C/yta24d422xrh7r0k9b8Sx1o4bkb9wVES+SURO2Np7xVdqilh7iphTHm2sWHs+InL8vizH+ts5x1w1nM7n7YX6+vXr+f39PekEW7+wlMm7UmpfsFa+hxa10Cnb6mhgSen07ZX7/ttzvU6n08f5fP4aXpiGHImpKZOHe+rQkUnCiATNPccoca/U8Oy7aPEXKHIs6JTuVEctkomp5eTsp/Yud+J8xAOHo8bwPWo/wDkbMfW+PTH1IqXu5pqEOXLe1InzqL5YiXu/xXmXPbbs0FGrD1Y6Ge3R+Y/8EsDagk+ORGIx9b6Ua1nK1j7lvXtxz6YWe8t1z5F4nGOOY+9x9pxn6/nuXaOcbVN0nLo9bq77I8fYKrJtEFPvO/JwxUWp+7jW+agnuo/Zej2JXttLabeN/391ZOx/z7O+Xs36GdlHiFhza/1e7V1UO5pjffWIlATNXHkER4weU5clPa5GP0D0TO45hj2xVnzMI/p77XkNr4c1N/3U+0qtU10cmQPPsUZ+79g5c1322PMwUEru17NrkevhlZbjRW2l1itK52yvxdSk5PrT6fTPZVl+jyoYwIq/nM/n32oXIicxFShITAWII6YCxBFTAeKIqQCxho6rYipQ2NAxdVnEVaAoMRUgzsOYmpRcDwAAAAAAAAAAAAAAI/pUuwAAAAAAAAAAAAAAAFCb5HoAAAAAAAAAAAAAAKYnuR4AAAAAAAAAAAAAgOlJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmJ7kegAAAAAAAAAAAAAApie5HgAAAAAAAAAAAACA6UmuBwAAAAAAAAAAAABgep9TXvzly5fzy8tLpqK07z///liWZVn+9Oe/VS4Jo7jUqVvq2LJ8fHz863w+/1a7HDnNHlPX3N4b7gk4RkwFiCOmQhz9fsRUgDhiKjlZH2NGo8dVMbVN4i2jGj2mLou4CpQjpgLEWYupScn1Ly8vy/v7e0ypOvT2elqWZVm+fZ/3OyDWpU7dUseW5XQ6/V67DLnNHlPX3N4b7gk4RkwFiCOmQhz9fsRUgDhiKjlZH2NGo8dVMbVN4i2jGj2mLou4CpQjpgLEWYupn0oWBAAAAAAAAAAAAAAAWiS5HgAAAAAAAAAAAACA6X2uXYAe3P5MOQAAAAAAAMzksl727fu5ckkAAAAAIB871wMAAAAAAABVvL2ebHQFAAAAQDMk1wMAAAAAAAAANMBDRwAAAHVJrgcAAAAAAAAAAAAAYHqS6wEAAAAAAAAAAAAAmN7n2gXo0fVPsH37fq5YEgAAAAAAAAAAAAAAIti5HmBQb6+nnx4GAgAAAAAAAAAAAOAxyfUAAAAAAAAAAAAAAExPcj0AAAAAAAAAAAAAANOTXA8AAAAAAAAAAAAAwPQk1wMAAAAAAAAAAAAAMD3J9QAAAAAAAAAAAAAATE9yPQAAAAAAAAAAAAAA05NcD0Dz3l5Py9vrqXYxAAAAAAAAAAAAgIFJrgcAAAAAAAAAAAAAYHqfaxcAAAAAAAAAAGA2Kb/cfHntt+/nXMUBAABgkVwPQENSJhABAAAAAAAAAAAAIn2qXQAAAAAAAABgbm+vJxuwAAAAAFCdnesBAAAAKEbCFAD8v/bu5cptGwoAqOQesk4TU0BKSWkpJQVMisg6RcgLnzmWGZHC54H48N6dPSIJkeAjPo8QAAAAAACjklwPHUgkAAAAAAAArsxcCQAAAAAj+ta7AAAAAAAAAAAAAAAA0JuV6wGApT2vgPXHn4+OJQEAABjPV59JfwkAAAAAAEByPQAAAAAAAADAkJ4XEdr+e+8lWS/RAgAAlJNcD7CQ7eAaAAAAAACU2Btv9kuRAAAAAKzsW+8CAAAAAAAAAAAAAOf4+6+7BRwBYIeV6+FEqY1Sq74AtOFnUAEAxqUvDAAAAAAAAPRm5XoAAAAAAAAAgMlYdRgAACCelesBmMarwUErWgIAAEA+CTgAAAAAAHAtX3MDcu6OWbkeYHFWrAAAAHrSJwEAAAAAAABmYeV6AGBJErgAAAAAAAAAAADIIbkegvnZDAAAcm1fCNKWBAAAYCXmTgDOsR1nFH+BmYlhABDHIqV5JNdDEMEH+ihJRtQJBwCA8+k3AwCsx1grQDs5/Wh9bmBl2pxtOb8A8H+S66Gx2oEMjViIYVARAADOo/0NcF3GMwEAAKhhbBGYnfExmJ/k+koCIXs09iFdy/vFvdieZyEAAAAAwDUZHwYAAPhBjhKsQ3I9AJfVctD/ucH8tX+TDONwLQAAAABgTMbugCuQeAVc3bbNJy4CACORXH9Aw40UZ9cTg8pwrHfsTjn+Cvfxq++Z+r1ebTvzuQAA4Kfe7XEAAMamvQgAQKkV5tlHoE0OAO9JrodCGpvMRkfzve19HXWuWsaLmkT1lDpRU29anc/t/tVp4HYTEwAAYDTa6DCvkvFM9/z1mCcDAEpoQ4xLmx4AfpJcH0QDA5jdcyf2jFg2Uqd5ryyzxvYW5c7Z57vzWbv/3OMCbM0Q32coI0BL4iAAMLNXY629x+ygNfURAChhjnc8Z+eOAMCILptcf9QQ0HBjhjow8iDlyGVbRcRq4ttJnZT9H227V5YZ7qcINas5HdmbfEvZNrVMR5N9pfsslbOafkSZ3tX157+1Xomf6/G8jBEZD6PK8e6aXuXZCBBBGwzirfaCOePQzoXjsdbWxyndpnXcjxi7+/JcVs+tc4nxlHKvOgercB0Zlbr5Xutz5BqMxzVhJOojI1M/j3VPrn81GBOxaq0LPr4RrtUIZUg148DlTOd3FntJxTVJ9hHlqN3f6Hp+t8hE8pLj9XJ2OVJW1S/Zh/jHs1Hur5mUrIxR8ksbrz77LpkzJ6lfLABW1qvdJrYC9CEOQ72z76OV2mtXHFvpHXdrXuQ4+tWGlEVPXv2deV1xBdyz53feSRkLvcq1OfLuOqUshuU8EiXnufjuPk6pqzW/ZH52vS+JW5GxLmcBw9ZlGjmGp9bLs+rc0X1Q85yuWXRrxOtGmt5tO/aNHBf3RD7zidMtuT4liS314ZqS5Jnz2RopK3/0ruA537emMZ16/JJVPl+dz9x9vPu/WfSqTzOfsxW1uh6uM+wrWS275tdyNIzHUjPYk/L3koGc3G1GqlMl7fvUffb47GgTZ0d6D4DDs9595Wi9VgbdK0dNP/rd/q7gqt+btYzcJvlydtvEvf2rVpPMkdd1tcQ8dXAdvRfEiLo3ZnhWbK16H+1di5Rr1CphrHYfJeM9JUmrq9aJ2dTkAtDPVa5NqwTN7d9WP4/UqVlcqPYz28/m5AWltlFytq1Rk9D+rNc12G4zYtzIfSky5cWDiHm5qGvRot1LH6l1csT7jBh7fdCaZ0R0fUmNF1Hxq2Zst+TFve1xc/c5mvvjkV7Qj4+Px+fnZ9YBPED2RVaSXuc5IqEsZb8RbwiuXhdHeitzb5857vf7P4/H4yOsEAMSU4ESYuprLWLqURLi3mdnjdMtV5NLeauadFGd/5z6n7rflMHRFivSlbzsUlPnxdTXcq5lxMtlEQklURMve8etuc9KyhLRj54pZud836MVM1O2Ly3TSCLjfso2qcTU11Ke4Sn1+tW+UkSP99Ws3pWzzxZt9ppz8ep4qbHraNuSezJiIqTFc+CsseWUfaVs02JStqRMe8TUY9HJ55H3RnQbbPYxilIR92jOWEb0M+IMR+2HFnW7tZI+QY7V42pNTE0R3ebqpWYsadT7KGqMcG8frfqXZ7XBWqh51kc9k3pbPabebvlxddQYcVUtxi5qRLQ1S7blfNqpr8mn+qF1UnjNXFtJez9ijqamzxrdB46eX+RXZ7Vxj2JqVnL9/X7/73a7/RtVMIADvz8ej996F6IlMRU4kZgKEEdMBYgjpgLEEVMBYi0dV8VU4GRLx9TbTVwFTiWmAsTZjalZyfUAAAAAAAAAAAAAALCib70LAAAAAAAAAAAAAAAAvUmuBwAAAAAAAAAAAADg8iTXAwAAAAAAAAAAAABweZLrAQAAAAAAAAAAAAC4PMn1AAAAAAAAAAAAAABcnuR6AAAAAAAAAAAAAAAuT3I9AAAAAAAAAAAAAACXJ7keAAAAAAAAAAAAAIDLk1wPAAAAAAAAAAAAAMDlfQeWyMNWWXK37QAAAABJRU5ErkJggg==\n",
-      "text/plain": [
-       "<Figure size 3888x2160 with 234 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "import h5py\n",
-    "import json\n",
-    "import matplotlib.pyplot as plt \n",
-    "import numpy as np\n",
-    "\n",
-    "with h5py.File('data/12kb-similarity-search.h5', 'r') as f:    \n",
-    "    knn_ae_12kb = f['knn_ae'][:]\n",
-    "    knn_eq_12kb = f['knn_eq'][:]\n",
-    "    knn_sax_12kb = f['knn_sax'][:]\n",
-    "    top_xcorr_12kb = f['top_xcorr'][:]\n",
-    "\n",
-    "show = 5\n",
-    "\n",
-    "N = (show + 1) * 5\n",
-    "\n",
-    "T = len(targets_12kb)\n",
-    "sz = data_12kb[0].size\n",
-    "\n",
-    "plt.figure(figsize=(6 * T, N))\n",
-    "\n",
-    "ymax = 1.0\n",
-    "\n",
-    "show_predictions = False\n",
-    "\n",
-    "for i, target in enumerate(targets_12kb):\n",
-    "    ax = plt.subplot(N, T, (i + 1))\n",
-    "        \n",
-    "    ax.set_facecolor(\"#eeeeee\")\n",
-    "    \n",
-    "    plt.bar(np.arange(sz), data_12kb[target], color='#000000', width=1.0)\n",
-    "\n",
-    "    plt.ylim(0, ymax)\n",
-    "    plt.xticks([], [])\n",
-    "    plt.yticks([], [])\n",
-    "\n",
-    "    for j, hit in enumerate(knn_ae_12kb[i][:show]):\n",
-    "        plt.subplot(N, T, ((j + 1) * T) + (i + 1))\n",
-    "        plt.bar(np.arange(sz), data_12kb[hit], color='#d24f00', width=1.0) # orange = CAE\n",
-    "        plt.ylim(0, ymax)\n",
-    "        plt.xticks([], [])\n",
-    "        plt.yticks([], [])\n",
-    "        plt.subplots_adjust(top=0.9)\n",
-    "        \n",
-    "    for j, hit in enumerate(topk_dtw[i][:show]):\n",
-    "        plt.subplot(N, T, ((j + 6) * T) + (i + 1))\n",
-    "        plt.bar(np.arange(sz), data_12kb[hit], color='green', width=1.0) # orange = CAE\n",
-    "        plt.ylim(0, ymax)\n",
-    "        plt.xticks([], [])\n",
-    "        plt.yticks([], [])\n",
-    "        plt.subplots_adjust(top=0.9)\n",
-    "\n",
-    "    for j, hit in enumerate(knn_eq_12kb[i][:show]):\n",
-    "        plt.subplot(N, T, ((j + 11) * T) + (i + 1))\n",
-    "        plt.bar(np.arange(sz), data_12kb[hit], color='#008ca8', width=1.0) # blue = EQ\n",
-    "        plt.ylim(0, ymax)\n",
-    "        plt.xticks([], [])\n",
-    "        plt.yticks([], [])\n",
-    "\n",
-    "    for j, hit in enumerate(knn_sax_12kb[i][:show]):\n",
-    "        plt.subplot(N, T, ((j + 16) * T) + (i + 1))\n",
-    "        plt.bar(np.arange(sz), data_12kb[hit], color='#a6227a', width=1.0) # purple = SAX\n",
-    "        plt.ylim(0, ymax)\n",
-    "        plt.xticks([], [])\n",
-    "        plt.yticks([], [])\n",
-    "\n",
-    "    for j, hit in enumerate(top_xcorr_12kb[i][:show]):\n",
-    "        plt.subplot(N, T, ((j + 21) * T) + (i + 1))\n",
-    "        plt.bar(np.arange(sz), data_12kb[hit], color='#bf9f00', width=1.0) # yellow = Zero-nornalized X correlation\n",
-    "        plt.ylim(0, ymax)\n",
-    "        plt.xticks([], [])\n",
-    "        plt.yticks([], [])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Importing the dtw module. When using in academic works please cite:\n",
-      "  T. Giorgino. Computing and Visualizing Dynamic Time Warping Alignments in R: The dtw Package.\n",
-      "  J. Stat. Soft., doi:10.18637/jss.v031.i07.\n",
-      "\n",
-      "Preprocessing:\n",
-      "0:0\n",
-      "10000:28\n",
-      "20000:30\n",
-      "30000:34\n",
-      "40000:34\n",
-      "50000:34\n",
-      "60000:34\n",
-      "70000:39\n",
-      "80000:48\n",
-      "90000:49\n",
-      "100000:49\n",
-      "110000:52\n",
-      "120000:52\n",
-      "0\n",
-      "1\n",
-      "2\n",
-      "3\n",
-      "4\n",
-      "5\n",
-      "6\n",
-      "7\n",
-      "8\n",
-      "9\n",
-      "10\n",
-      "11\n",
-      "12\n",
-      "13\n",
-      "14\n",
-      "15\n",
-      "16\n",
-      "17\n",
-      "18\n",
-      "19\n",
-      "20\n",
-      "21\n",
-      "22\n",
-      "23\n",
-      "24\n",
-      "25\n",
-      "26\n",
-      "27\n",
-      "28\n",
-      "29\n",
-      "30\n",
-      "31\n",
-      "32\n",
-      "33\n",
-      "34\n",
-      "35\n",
-      "36\n",
-      "37\n",
-      "38\n",
-      "39\n",
-      "40\n",
-      "41\n",
-      "42\n",
-      "43\n",
-      "44\n",
-      "45\n",
-      "46\n",
-      "47\n",
-      "48\n",
-      "49\n",
-      "50\n",
-      "51\n",
-      "Preprocessing done. Took 28.18 seconds (0.5 minutes).\n",
-      "Target #0 done! Took 11.02 seconds (0.2 minutes).\n",
-      "Target #1 done! Took 11.10 seconds (0.2 minutes).\n",
-      "Target #2 done! Took 10.90 seconds (0.2 minutes).\n",
-      "Target #3 done! Took 10.49 seconds (0.2 minutes).\n",
-      "Target #4 done! Took 10.73 seconds (0.2 minutes).\n",
-      "Target #5 done! Took 10.41 seconds (0.2 minutes).\n",
-      "Target #6 done! Took 10.34 seconds (0.2 minutes).\n",
-      "Target #7 done! Took 10.41 seconds (0.2 minutes).\n",
-      "Target #8 done! Took 10.31 seconds (0.2 minutes).\n",
-      "[ 11975  80854 100423 113956   6129  77520   4669  78275   1762  20047]\n",
-      "Done! Took 123.90 seconds (2.1 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "from Flaskserver.main import preprocess\n",
-    "import _lsh\n",
-    "\n",
-    "topk_dtw = []\n",
-    "\n",
-    "dtw_12kb = np.zeros((data_12kb.shape[0], len(targets_12kb)))\n",
-    "data = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0]), 1))\n",
-    "print('Preprocessing:')\n",
-    "t0 = time()\n",
-    "r,a,sd = preprocess(data_12kb)\n",
-    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
-    "\n",
-    "for i, target in enumerate(targets_12kb):\n",
-    "    t1 = time()\n",
-    "    query = data_12kb[target]\n",
-    "    query = np.reshape(query, (len(data_12kb[0]), 1))\n",
-    "    candidates, distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
-    "    topk_dtw.append(candidates)\n",
-    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
-    "    \n",
-    "print(candidates[0:10])\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 34,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[5, 6, 7, 8]\n"
-     ]
-    }
-   ],
-   "source": [
-    "def permute(A, P, n): \n",
-    "      \n",
-    "    # For each element of P \n",
-    "    for i in range(n): \n",
-    "        next = i \n",
-    "  \n",
-    "        # Check if it is already \n",
-    "        # considered in cycle \n",
-    "        while (P[next] >= 0): \n",
-    "              \n",
-    "            # Swap the current element according \n",
-    "            # to the permutation in P \n",
-    "            t = A[i] \n",
-    "            A[i] = A[P[next]] \n",
-    "            A[P[next]] = t \n",
-    "              \n",
-    "            temp = P[next] \n",
-    "  \n",
-    "            # Subtract n from an entry in P \n",
-    "            # to make it negative which indicates \n",
-    "            # the corresponding move \n",
-    "            # has been performed \n",
-    "            P[next] -= n \n",
-    "\n",
-    "A = [5, 6, 7, 8] \n",
-    "P = [3, 2, 1, 0] \n",
-    "n = len(A) \n",
-    "permute(A,P,n)\n",
-    "print(A)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [
-    {
-     "ename": "NameError",
-     "evalue": "name 'k' is not defined",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-10-bce9b05cd905>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0mdist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcdist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata_12kb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_12kb\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m80503\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_12kb\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m80503\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmetric\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'euclidean'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margsort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mk\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Done! Took {:.2f} seconds ({:.1f} minutes).'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m60\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mNameError\u001b[0m: name 'k' is not defined"
-     ]
-    }
-   ],
-   "source": [
-    "t0 = time()\n",
-    "dist = cdist(data_12kb, data_12kb[80503].reshape((1, data_12kb[80503].size)), metric='euclidean').flatten()\n",
-    "np.argsort(dist)[1 + (2 * 0):5 + 1 + (2 * 0)]\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.8.5"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/experiments/.ipynb_checkpoints/EEG data test-checkpoint.ipynb b/experiments/.ipynb_checkpoints/EEG data test-checkpoint.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..e5df9079235124ac8d1667e115bbdd3be0401dc6
--- /dev/null
+++ b/experiments/.ipynb_checkpoints/EEG data test-checkpoint.ipynb	
@@ -0,0 +1,562 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The autoreload extension is already loaded. To reload it, use:\n",
+      "  %reload_ext autoreload\n"
+     ]
+    }
+   ],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(900096, 74)\n"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "\n",
+    "datafile = 'data/21.csv'\n",
+    "\n",
+    "data = pd.read_csv(datafile, header=None)\n",
+    "\n",
+    "#and convert it to numpy array:\n",
+    "npdata = np.array(data)\n",
+    "\n",
+    "print(npdata.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(59999, 120, 40)\n"
+     ]
+    }
+   ],
+   "source": [
+    "window_data = [npdata[i:i+120, 0:40] for i in range(0, npdata.shape[0]-120, int(120/8))]\n",
+    "del npdata\n",
+    "data = np.reshape(window_data, (len(window_data), len(window_data[0][0]), len(window_data[0])))\n",
+    "del window_data\n",
+    "data = np.reshape(data, (len(data), len(data[0][0]), len(data[0])))\n",
+    "# data = np.concatenate((data, data))\n",
+    "print(data.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "targets = [43895, 33430, 42575, 1060, 11975]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing:\n",
+      "1730\n",
+      "0:0\n",
+      "1730\n",
+      "999:59\n",
+      "1730\n",
+      "1998:70\n",
+      "1730\n",
+      "2997:78\n",
+      "1730\n",
+      "3996:81\n",
+      "1730\n",
+      "4995:81\n",
+      "1730\n",
+      "5994:81\n",
+      "1730\n",
+      "6993:84\n",
+      "1730\n",
+      "7992:84\n",
+      "1730\n",
+      "8991:84\n",
+      "1730\n",
+      "9990:84\n",
+      "1730\n",
+      "10989:84\n",
+      "1730\n",
+      "11988:84\n",
+      "1730\n",
+      "12987:84\n",
+      "1730\n",
+      "13986:91\n",
+      "1730\n",
+      "14985:91\n",
+      "1730\n",
+      "15984:91\n",
+      "1730\n",
+      "16983:91\n",
+      "1730\n",
+      "17982:91\n",
+      "1730\n",
+      "18981:91\n",
+      "1730\n",
+      "19980:95\n",
+      "1730\n",
+      "20979:95\n",
+      "1730\n",
+      "21978:95\n",
+      "1730\n",
+      "22977:95\n",
+      "1730\n",
+      "23976:95\n",
+      "1730\n",
+      "24975:95\n",
+      "1730\n",
+      "25974:95\n",
+      "1730\n",
+      "26973:99\n",
+      "1730\n",
+      "27972:99\n",
+      "1730\n",
+      "28971:99\n",
+      "1730\n",
+      "29970:99\n",
+      "1730\n",
+      "30969:102\n",
+      "1730\n",
+      "31968:102\n",
+      "1730\n",
+      "32967:103\n",
+      "1730\n",
+      "33966:105\n",
+      "1730\n",
+      "34965:105\n",
+      "1730\n",
+      "35964:105\n",
+      "1730\n",
+      "36963:105\n",
+      "1730\n",
+      "37962:109\n",
+      "1730\n",
+      "38961:110\n",
+      "1730\n",
+      "39960:114\n",
+      "1730\n",
+      "40959:114\n",
+      "1730\n",
+      "41958:115\n",
+      "1730\n",
+      "42957:116\n",
+      "1730\n",
+      "43956:116\n",
+      "1730\n",
+      "44955:116\n",
+      "1730\n",
+      "45954:122\n",
+      "1730\n",
+      "46953:126\n",
+      "1730\n",
+      "47952:126\n",
+      "1730\n",
+      "48951:126\n",
+      "1730\n",
+      "49950:128\n",
+      "1730\n",
+      "50949:128\n",
+      "1730\n",
+      "51948:128\n",
+      "1730\n",
+      "52947:128\n",
+      "1730\n",
+      "53946:130\n",
+      "1730\n",
+      "54945:134\n",
+      "1730\n",
+      "55944:134\n",
+      "1730\n",
+      "56943:134\n",
+      "1730\n",
+      "57942:143\n",
+      "1730\n",
+      "58941:143\n",
+      "1730\n",
+      "59940:145\n",
+      "r = 1730\n",
+      "0\n",
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n",
+      "8\n",
+      "9\n",
+      "10\n",
+      "11\n",
+      "12\n",
+      "13\n",
+      "14\n",
+      "15\n",
+      "16\n",
+      "17\n",
+      "18\n",
+      "19\n",
+      "20\n",
+      "21\n",
+      "22\n",
+      "23\n",
+      "24\n",
+      "25\n",
+      "26\n",
+      "27\n",
+      "28\n",
+      "29\n",
+      "30\n",
+      "31\n",
+      "32\n",
+      "33\n",
+      "34\n",
+      "35\n",
+      "36\n",
+      "37\n",
+      "38\n",
+      "39\n",
+      "40\n",
+      "41\n",
+      "42\n",
+      "43\n",
+      "44\n",
+      "45\n",
+      "46\n",
+      "47\n",
+      "48\n",
+      "49\n",
+      "50\n",
+      "51\n",
+      "52\n",
+      "53\n",
+      "54\n",
+      "55\n",
+      "56\n",
+      "57\n",
+      "58\n",
+      "59\n",
+      "60\n",
+      "61\n",
+      "62\n",
+      "63\n",
+      "64\n",
+      "65\n",
+      "66\n",
+      "67\n",
+      "68\n",
+      "69\n",
+      "70\n",
+      "71\n",
+      "72\n",
+      "73\n",
+      "74\n",
+      "75\n",
+      "76\n",
+      "77\n",
+      "78\n",
+      "79\n",
+      "80\n",
+      "81\n",
+      "82\n",
+      "83\n",
+      "84\n",
+      "85\n",
+      "86\n",
+      "87\n",
+      "88\n",
+      "89\n",
+      "90\n",
+      "91\n",
+      "92\n",
+      "93\n",
+      "94\n",
+      "95\n",
+      "96\n",
+      "97\n",
+      "98\n",
+      "99\n",
+      "100\n",
+      "101\n",
+      "102\n",
+      "103\n",
+      "104\n",
+      "105\n",
+      "106\n",
+      "107\n",
+      "108\n",
+      "109\n",
+      "110\n",
+      "111\n",
+      "112\n",
+      "113\n",
+      "114\n",
+      "115\n",
+      "116\n",
+      "117\n",
+      "118\n",
+      "119\n",
+      "120\n",
+      "121\n",
+      "122\n",
+      "123\n",
+      "124\n",
+      "125\n",
+      "126\n",
+      "127\n",
+      "128\n",
+      "129\n",
+      "130\n",
+      "131\n",
+      "132\n",
+      "133\n",
+      "134\n",
+      "135\n",
+      "136\n",
+      "137\n",
+      "138\n",
+      "139\n",
+      "140\n",
+      "141\n",
+      "142\n",
+      "143\n",
+      "144\n",
+      "Mean: 16672.21312363323\n",
+      "Stdev: 7180.272654591725\n",
+      "Ratio mean: 0.9379277278060563\n",
+      "Ratio stdev: 0.15076175892196642\n",
+      "Theta: -1852.8903252134187\n",
+      "r: 166.7221312363323\n",
+      "Preprocessing time: 14.979660749435425\n",
+      "Preprocessing done. Took 14.98 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import sys\n",
+    "from time import time\n",
+    "\n",
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "import importlib\n",
+    "from main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data, 1730)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "doing lsh\n",
+      "Target #0 done! Took 3.11 seconds (0.1 minutes).\n",
+      "doing lsh\n",
+      "Target #1 done! Took 2.91 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #2 done! Took 2.80 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #3 done! Took 2.82 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #4 done! Took 2.85 seconds (0.0 minutes).\n",
+      "Done! Took 14.50 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    print('doing lsh')\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Target #0 done! Took 5.99 seconds (0.1 minutes).\n",
+      "Target #1 done! Took 5.71 seconds (0.1 minutes).\n",
+      "Target #2 done! Took 5.76 seconds (0.1 minutes).\n",
+      "Target #3 done! Took 5.65 seconds (0.1 minutes).\n",
+      "Target #4 done! Took 5.84 seconds (0.1 minutes).\n",
+      "Done! Took 28.96 seconds (0.5 minutes).\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "from time import time\n",
+    "\n",
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    dtw_distances = [dtw(window, query, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05)) for window in data]\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i]\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())\n",
+    "print(candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "20\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084, 4807, 1325, 14433, 5422, 9312, 5421, 4603, 18938, 3578, 9928]\n",
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579, 18528, 8084, 4807, 3578, 4603, 59898, 9312, 15662, 4601, 11974]\n"
+     ]
+    }
+   ],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "18218\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(len(candidates))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/.ipynb_checkpoints/MTS test-checkpoint.ipynb b/experiments/.ipynb_checkpoints/MTS test-checkpoint.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..4d912f53bf450e8fe64f4941dafb6b6ae497d881
--- /dev/null
+++ b/experiments/.ipynb_checkpoints/MTS test-checkpoint.ipynb	
@@ -0,0 +1,358 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import json\n",
+    "import h5py\n",
+    "import os\n",
+    "import sys\n",
+    "from time import time\n",
+    "import warnings\n",
+    "\n",
+    "# Ignore warnings as they just pollute the output\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "# Enable importing modules from the parent directory\n",
+    "module_path = os.path.abspath(os.path.join('..'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "module_path = os.path.abspath(os.path.join('../experiments'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "\n",
+    "# DNase-seq 2011, hg19\n",
+    "bw = 'data/ENCFF158GBQ.bigWig'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "./data/ENCFF158GBQ.bigWig already exist. To overwrite pass `overwrite=True`\n",
+      "./models/dnase_w-12000_r-100.h5 already exist. To overwrite pass `overwrite=True`\n"
+     ]
+    }
+   ],
+   "source": [
+    "from download import download_encode_file, download_file\n",
+    "from pathlib import Path\n",
+    "\n",
+    "Path('data').mkdir(parents=True, exist_ok=True)\n",
+    "Path('models').mkdir(parents=True, exist_ok=True)\n",
+    "\n",
+    "download_encode_file('ENCFF158GBQ.bigWig')\n",
+    "\n",
+    "download_file(\n",
+    "    \"https://zenodo.org/record/2609763/files/dnase_w-12000_r-100.h5?download=1\",\n",
+    "    \"dnase_w-12000_r-100.h5\",\n",
+    "    dir=\"models\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(124621, 1, 120)\n",
+      "(124621, 1, 120)\n",
+      "(124621, 120, 3)\n",
+      "Done! Took 0.64 seconds (0.0 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import bigwig\n",
+    "import bbi\n",
+    "\n",
+    "t0 = time()\n",
+    "# data_12kb_original = bigwig.chunk(bw, 12000, 100, 12000 / 6, ['chr1'], verbose=True)\n",
+    "data_12kb = np.reshape(data_12kb_original, (len(data_12kb_original), 1, len(data_12kb_original[0])))\n",
+    "# data_12kb = np.repeat(data_12kb, repeats=3, axis=1)\n",
+    "data2 = np.copy(data_12kb)\n",
+    "np.random.shuffle(data2)\n",
+    "data3 = np.copy(data_12kb)\n",
+    "np.random.shuffle(data3)\n",
+    "print(data_12kb.shape)\n",
+    "print(data2.shape)\n",
+    "\n",
+    "data_12kb = np.concatenate((data_12kb, data2), axis=1)\n",
+    "data_12kb = np.concatenate((data_12kb, data3), axis=1)\n",
+    "data_12kb = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0][0]), len(data_12kb[0])))\n",
+    "print(data_12kb.shape)\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from utils import plot_windows_from_data\n",
+    "import matplotlib.pyplot as plt \n",
+    "\n",
+    "k_12kb = 20 # Number of KNNs to be saved later on\n",
+    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
+    "\n",
+    "# N = data_12kb.shape[2]\n",
+    "\n",
+    "# T = len(targets_12kb)\n",
+    "# sz = data_12kb.shape[1]\n",
+    "\n",
+    "# plt.figure(figsize=(12 * T, 4 * N))\n",
+    "\n",
+    "# ymax = 1.0\n",
+    "\n",
+    "# show_predictions = False\n",
+    "\n",
+    "# for i, target in enumerate(targets_12kb):\n",
+    "#     for j in range(N):\n",
+    "#         ax = plt.subplot(N, T, (j) * T + (i + 1))\n",
+    "\n",
+    "#         ax.set_facecolor(\"#eeeeee\")\n",
+    "\n",
+    "#         plt.bar(np.arange(sz), data_12kb[target][:,j], color='#008ca8', width=1.0)\n",
+    "\n",
+    "#         plt.ylim(0, ymax)\n",
+    "#         plt.xticks([], [])\n",
+    "#         plt.yticks([], [])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing:\n",
+      "0\n",
+      "50\n",
+      "100\n",
+      "150\n",
+      "Mean: 1.1977030729661218\n",
+      "Stdev: 0.7064648534040298\n",
+      "Ratio mean: 0.8819037050053659\n",
+      "Ratio stdev: 0.07885103686378629\n",
+      "Theta: -0.6249762488162751\n",
+      "r: 0.5\n",
+      "Preprocessing time: 5.447453737258911\n",
+      "Preprocessing done. Took 5.49 seconds (0.1 minutes).\n",
+      "Target #0 done! Took 11.72 seconds (0.2 minutes).\n",
+      "Done! Took 17.21 seconds (0.3 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "from Flaskserver.main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data_12kb, 20)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb[0:1]):\n",
+    "    t1 = time()\n",
+    "    query = data_12kb[target]\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data_12kb, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Done! Took 15.48 seconds (0.3 minutes).\n",
+      "[80503, 77574, 3128, 22594, 47036, 111653, 473, 17658, 12967, 21104]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "\n",
+    "t0 = time()\n",
+    "target = data_12kb[80503]\n",
+    "dtw_distances = [dtw(window, target, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05*120)) for window in data_12kb]\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i] ** 2\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "22\n",
+      "[80503, 77574, 3128, 22594, 47036, 111653, 473, 17658, 12967, 21104, 54908, 18303, 27633, 101051, 113445, 113957, 100419, 90491, 3100, 78022]\n",
+      "[80503, 77524, 18303, 12354, 1254, 113957, 117630, 45225, 21707, 77377, 111653, 12058, 103318, 3128, 77574, 13215, 47036, 12624, 80593, 101463]\n",
+      "14\n"
+     ]
+    }
+   ],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n",
+    "print(candidates.index(77574))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 864x5184 with 18 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "k_12kb = 20 # Number of KNNs to be saved later on\n",
+    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
+    "\n",
+    "show = 5\n",
+    "offset = data_12kb.shape[2]\n",
+    "\n",
+    "N = (show + 1) * offset \n",
+    "\n",
+    "T = 1 # len(targets_12kb)\n",
+    "sz = data_12kb.shape[1]\n",
+    "\n",
+    "plt.figure(figsize=(12 * T, 4 * N))\n",
+    "\n",
+    "ymax = 1.0\n",
+    "\n",
+    "show_predictions = False\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb[0:1]):\n",
+    "    for x in range(offset):\n",
+    "        ax = plt.subplot(N, T, (x) * T + (i + 1))\n",
+    "\n",
+    "        ax.set_facecolor(\"#eeeeee\")\n",
+    "\n",
+    "        plt.bar(np.arange(sz), data_12kb[target][:,x], color='#008ca8', width=1.0)\n",
+    "\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])\n",
+    "    \n",
+    "    for j, hit in enumerate(candidates[:show]):\n",
+    "        for y in range(offset):\n",
+    "            plt.subplot(N, T, (((j*offset)+ y + offset) * T) + (i + 1))\n",
+    "            plt.bar(np.arange(sz), data_12kb[hit][:,y], color='green', width=1.0) # orange = CAE\n",
+    "            plt.ylim(0, ymax)\n",
+    "            plt.xticks([], [])\n",
+    "            plt.yticks([], [])\n",
+    "            plt.subplots_adjust(top=0.9)\n",
+    "            \n",
+    "    for j, hit in enumerate(dtw_candidates[:show]):\n",
+    "        for y in range(offset):\n",
+    "            plt.subplot(N, T, (((j*offset)+ y + offset) * T) + (i + 1))\n",
+    "            plt.bar(np.arange(sz), data_12kb[hit][:,y], color='green', width=1.0) # orange = CAE\n",
+    "            plt.ylim(0, ymax)\n",
+    "            plt.xticks([], [])\n",
+    "            plt.yticks([], [])\n",
+    "            plt.subplots_adjust(top=0.9)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(topk_dtw[0][0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/Compare Algorithms.ipynb b/experiments/.ipynb_checkpoints/UTS test-checkpoint.ipynb
similarity index 98%
rename from experiments/Compare Algorithms.ipynb
rename to experiments/.ipynb_checkpoints/UTS test-checkpoint.ipynb
index ffee0cf8e7b814227cf8c06301d59955733957d5..31c3967752bdf06d33485f549318804a41bdc44f 100644
--- a/experiments/Compare Algorithms.ipynb	
+++ b/experiments/.ipynb_checkpoints/UTS test-checkpoint.ipynb	
@@ -240,13 +240,132 @@
     "sax_12kb = SymbolicAggregateApproximation(n_segments=120, alphabet_size_avg=10)\n",
     "sax_data_12kb = sax_12kb.fit_transform(data_12kb)\n",
     "print('Preprocessing done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "# t0 = time()\n",
+    "# N = data.shape[0]\n",
+    "# dist = np.zeros(N)\n",
+    "# target = sax_data_12kb[80503]\n",
+    "# for i in range(N):\n",
+    "#     dist[i] = sax_12kb.distance_sax(target, sax_data_12kb[i])\n",
+    "# print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Importing the dtw module. When using in academic works please cite:\n",
+      "  T. Giorgino. Computing and Visualizing Dynamic Time Warping Alignments in R: The dtw Package.\n",
+      "  J. Stat. Soft., doi:10.18637/jss.v031.i07.\n",
+      "\n",
+      "Preprocessing:\n",
+      "0:0\n",
+      "10000:28\n",
+      "20000:30\n",
+      "30000:34\n",
+      "40000:34\n",
+      "50000:34\n",
+      "60000:34\n",
+      "70000:39\n",
+      "80000:48\n",
+      "90000:49\n",
+      "100000:49\n",
+      "110000:52\n",
+      "120000:52\n",
+      "0\n",
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n",
+      "8\n",
+      "9\n",
+      "10\n",
+      "11\n",
+      "12\n",
+      "13\n",
+      "14\n",
+      "15\n",
+      "16\n",
+      "17\n",
+      "18\n",
+      "19\n",
+      "20\n",
+      "21\n",
+      "22\n",
+      "23\n",
+      "24\n",
+      "25\n",
+      "26\n",
+      "27\n",
+      "28\n",
+      "29\n",
+      "30\n",
+      "31\n",
+      "32\n",
+      "33\n",
+      "34\n",
+      "35\n",
+      "36\n",
+      "37\n",
+      "38\n",
+      "39\n",
+      "40\n",
+      "41\n",
+      "42\n",
+      "43\n",
+      "44\n",
+      "45\n",
+      "46\n",
+      "47\n",
+      "48\n",
+      "49\n",
+      "50\n",
+      "51\n",
+      "Preprocessing done. Took 28.18 seconds (0.5 minutes).\n",
+      "Target #0 done! Took 11.02 seconds (0.2 minutes).\n",
+      "Target #1 done! Took 11.10 seconds (0.2 minutes).\n",
+      "Target #2 done! Took 10.90 seconds (0.2 minutes).\n",
+      "Target #3 done! Took 10.49 seconds (0.2 minutes).\n",
+      "Target #4 done! Took 10.73 seconds (0.2 minutes).\n",
+      "Target #5 done! Took 10.41 seconds (0.2 minutes).\n",
+      "Target #6 done! Took 10.34 seconds (0.2 minutes).\n",
+      "Target #7 done! Took 10.41 seconds (0.2 minutes).\n",
+      "Target #8 done! Took 10.31 seconds (0.2 minutes).\n",
+      "[ 11975  80854 100423 113956   6129  77520   4669  78275   1762  20047]\n",
+      "Done! Took 123.90 seconds (2.1 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "from Flaskserver.main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "dtw_12kb = np.zeros((data_12kb.shape[0], len(targets_12kb)))\n",
+    "data = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0]), 1))\n",
+    "print('Preprocessing:')\n",
     "t0 = time()\n",
-    "N = data.shape[0]\n",
-    "dist = np.zeros(N)\n",
-    "target = sax_data_12kb[80503]\n",
-    "for i in range(N):\n",
-    "    dist[i] = sax_12kb.distance_sax(target, sax_data_12kb[i])\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+    "r,a,sd = preprocess(data_12kb)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb):\n",
+    "    t1 = time()\n",
+    "    query = data_12kb[target]\n",
+    "    query = np.reshape(query, (len(data_12kb[0]), 1))\n",
+    "    candidates, distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "    topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n"
    ]
   },
   {
@@ -381,125 +500,6 @@
     "        plt.yticks([], [])"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Importing the dtw module. When using in academic works please cite:\n",
-      "  T. Giorgino. Computing and Visualizing Dynamic Time Warping Alignments in R: The dtw Package.\n",
-      "  J. Stat. Soft., doi:10.18637/jss.v031.i07.\n",
-      "\n",
-      "Preprocessing:\n",
-      "0:0\n",
-      "10000:28\n",
-      "20000:30\n",
-      "30000:34\n",
-      "40000:34\n",
-      "50000:34\n",
-      "60000:34\n",
-      "70000:39\n",
-      "80000:48\n",
-      "90000:49\n",
-      "100000:49\n",
-      "110000:52\n",
-      "120000:52\n",
-      "0\n",
-      "1\n",
-      "2\n",
-      "3\n",
-      "4\n",
-      "5\n",
-      "6\n",
-      "7\n",
-      "8\n",
-      "9\n",
-      "10\n",
-      "11\n",
-      "12\n",
-      "13\n",
-      "14\n",
-      "15\n",
-      "16\n",
-      "17\n",
-      "18\n",
-      "19\n",
-      "20\n",
-      "21\n",
-      "22\n",
-      "23\n",
-      "24\n",
-      "25\n",
-      "26\n",
-      "27\n",
-      "28\n",
-      "29\n",
-      "30\n",
-      "31\n",
-      "32\n",
-      "33\n",
-      "34\n",
-      "35\n",
-      "36\n",
-      "37\n",
-      "38\n",
-      "39\n",
-      "40\n",
-      "41\n",
-      "42\n",
-      "43\n",
-      "44\n",
-      "45\n",
-      "46\n",
-      "47\n",
-      "48\n",
-      "49\n",
-      "50\n",
-      "51\n",
-      "Preprocessing done. Took 28.18 seconds (0.5 minutes).\n",
-      "Target #0 done! Took 11.02 seconds (0.2 minutes).\n",
-      "Target #1 done! Took 11.10 seconds (0.2 minutes).\n",
-      "Target #2 done! Took 10.90 seconds (0.2 minutes).\n",
-      "Target #3 done! Took 10.49 seconds (0.2 minutes).\n",
-      "Target #4 done! Took 10.73 seconds (0.2 minutes).\n",
-      "Target #5 done! Took 10.41 seconds (0.2 minutes).\n",
-      "Target #6 done! Took 10.34 seconds (0.2 minutes).\n",
-      "Target #7 done! Took 10.41 seconds (0.2 minutes).\n",
-      "Target #8 done! Took 10.31 seconds (0.2 minutes).\n",
-      "[ 11975  80854 100423 113956   6129  77520   4669  78275   1762  20047]\n",
-      "Done! Took 123.90 seconds (2.1 minutes).\n"
-     ]
-    }
-   ],
-   "source": [
-    "from Flaskserver.main import preprocess\n",
-    "import _lsh\n",
-    "\n",
-    "topk_dtw = []\n",
-    "\n",
-    "dtw_12kb = np.zeros((data_12kb.shape[0], len(targets_12kb)))\n",
-    "data = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0]), 1))\n",
-    "print('Preprocessing:')\n",
-    "t0 = time()\n",
-    "r,a,sd = preprocess(data_12kb)\n",
-    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
-    "\n",
-    "for i, target in enumerate(targets_12kb):\n",
-    "    t1 = time()\n",
-    "    query = data_12kb[target]\n",
-    "    query = np.reshape(query, (len(data_12kb[0]), 1))\n",
-    "    candidates, distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
-    "    topk_dtw.append(candidates)\n",
-    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
-    "    \n",
-    "print(candidates[0:10])\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n"
-   ]
-  },
   {
    "cell_type": "code",
    "execution_count": 34,
@@ -513,37 +513,7 @@
      ]
     }
    ],
-   "source": [
-    "def permute(A, P, n): \n",
-    "      \n",
-    "    # For each element of P \n",
-    "    for i in range(n): \n",
-    "        next = i \n",
-    "  \n",
-    "        # Check if it is already \n",
-    "        # considered in cycle \n",
-    "        while (P[next] >= 0): \n",
-    "              \n",
-    "            # Swap the current element according \n",
-    "            # to the permutation in P \n",
-    "            t = A[i] \n",
-    "            A[i] = A[P[next]] \n",
-    "            A[P[next]] = t \n",
-    "              \n",
-    "            temp = P[next] \n",
-    "  \n",
-    "            # Subtract n from an entry in P \n",
-    "            # to make it negative which indicates \n",
-    "            # the corresponding move \n",
-    "            # has been performed \n",
-    "            P[next] -= n \n",
-    "\n",
-    "A = [5, 6, 7, 8] \n",
-    "P = [3, 2, 1, 0] \n",
-    "n = len(A) \n",
-    "permute(A,P,n)\n",
-    "print(A)"
-   ]
+   "source": []
   },
   {
    "cell_type": "code",
@@ -558,12 +528,7 @@
      ]
     }
    ],
-   "source": [
-    "t0 = time()\n",
-    "dist = cdist(data_12kb, data_12kb[80503].reshape((1, data_12kb[80503].size)), metric='euclidean').flatten()\n",
-    "np.argsort(dist)[1 + (2 * 0):5 + 1 + (2 * 0)]\n",
-    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
-   ]
+   "source": []
   },
   {
    "cell_type": "code",
diff --git a/experiments/.ipynb_checkpoints/Update test-checkpoint.ipynb b/experiments/.ipynb_checkpoints/Update test-checkpoint.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..27f5a7e40aad53248d5c5ab7fccd3aecc3577f48
--- /dev/null
+++ b/experiments/.ipynb_checkpoints/Update test-checkpoint.ipynb	
@@ -0,0 +1,546 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(900096, 74)\n"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "\n",
+    "datafile = 'data/21.csv'\n",
+    "\n",
+    "data = pd.read_csv(datafile, header=None)\n",
+    "\n",
+    "#and convert it to numpy array:\n",
+    "npdata = np.array(data)\n",
+    "\n",
+    "print(npdata.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "window_data = [npdata[i:i+20] for i in range(0, npdata.shape[0]-20, int(20/4))]\n",
+    "del npdata\n",
+    "data = np.reshape(window_data, (len(window_data), len(window_data[0][0]), len(window_data[0])))\n",
+    "del window_data\n",
+    "data = np.reshape(data, (len(data), len(data[0][0]), len(data[0])))\n",
+    "# data = np.concatenate((data, data))\n",
+    "print(data.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "targets = [43895, 33430, 42575, 1060, 11975]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing:\n",
+      "1730\n",
+      "0:0\n",
+      "1730\n",
+      "999:59\n",
+      "1730\n",
+      "1998:70\n",
+      "1730\n",
+      "2997:78\n",
+      "1730\n",
+      "3996:81\n",
+      "1730\n",
+      "4995:81\n",
+      "1730\n",
+      "5994:81\n",
+      "1730\n",
+      "6993:84\n",
+      "1730\n",
+      "7992:84\n",
+      "1730\n",
+      "8991:84\n",
+      "1730\n",
+      "9990:84\n",
+      "1730\n",
+      "10989:84\n",
+      "1730\n",
+      "11988:84\n",
+      "1730\n",
+      "12987:84\n",
+      "1730\n",
+      "13986:91\n",
+      "1730\n",
+      "14985:91\n",
+      "1730\n",
+      "15984:91\n",
+      "1730\n",
+      "16983:91\n",
+      "1730\n",
+      "17982:91\n",
+      "1730\n",
+      "18981:91\n",
+      "1730\n",
+      "19980:95\n",
+      "1730\n",
+      "20979:95\n",
+      "1730\n",
+      "21978:95\n",
+      "1730\n",
+      "22977:95\n",
+      "1730\n",
+      "23976:95\n",
+      "1730\n",
+      "24975:95\n",
+      "1730\n",
+      "25974:95\n",
+      "1730\n",
+      "26973:99\n",
+      "1730\n",
+      "27972:99\n",
+      "1730\n",
+      "28971:99\n",
+      "1730\n",
+      "29970:99\n",
+      "1730\n",
+      "30969:102\n",
+      "1730\n",
+      "31968:102\n",
+      "1730\n",
+      "32967:103\n",
+      "1730\n",
+      "33966:105\n",
+      "1730\n",
+      "34965:105\n",
+      "1730\n",
+      "35964:105\n",
+      "1730\n",
+      "36963:105\n",
+      "1730\n",
+      "37962:109\n",
+      "1730\n",
+      "38961:110\n",
+      "1730\n",
+      "39960:114\n",
+      "1730\n",
+      "40959:114\n",
+      "1730\n",
+      "41958:115\n",
+      "1730\n",
+      "42957:116\n",
+      "1730\n",
+      "43956:116\n",
+      "1730\n",
+      "44955:116\n",
+      "1730\n",
+      "45954:122\n",
+      "1730\n",
+      "46953:126\n",
+      "1730\n",
+      "47952:126\n",
+      "1730\n",
+      "48951:126\n",
+      "1730\n",
+      "49950:128\n",
+      "1730\n",
+      "50949:128\n",
+      "1730\n",
+      "51948:128\n",
+      "1730\n",
+      "52947:128\n",
+      "1730\n",
+      "53946:130\n",
+      "1730\n",
+      "54945:134\n",
+      "1730\n",
+      "55944:134\n",
+      "1730\n",
+      "56943:134\n",
+      "1730\n",
+      "57942:143\n",
+      "1730\n",
+      "58941:143\n",
+      "1730\n",
+      "59940:145\n",
+      "r = 1730\n",
+      "0\n",
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n",
+      "8\n",
+      "9\n",
+      "10\n",
+      "11\n",
+      "12\n",
+      "13\n",
+      "14\n",
+      "15\n",
+      "16\n",
+      "17\n",
+      "18\n",
+      "19\n",
+      "20\n",
+      "21\n",
+      "22\n",
+      "23\n",
+      "24\n",
+      "25\n",
+      "26\n",
+      "27\n",
+      "28\n",
+      "29\n",
+      "30\n",
+      "31\n",
+      "32\n",
+      "33\n",
+      "34\n",
+      "35\n",
+      "36\n",
+      "37\n",
+      "38\n",
+      "39\n",
+      "40\n",
+      "41\n",
+      "42\n",
+      "43\n",
+      "44\n",
+      "45\n",
+      "46\n",
+      "47\n",
+      "48\n",
+      "49\n",
+      "50\n",
+      "51\n",
+      "52\n",
+      "53\n",
+      "54\n",
+      "55\n",
+      "56\n",
+      "57\n",
+      "58\n",
+      "59\n",
+      "60\n",
+      "61\n",
+      "62\n",
+      "63\n",
+      "64\n",
+      "65\n",
+      "66\n",
+      "67\n",
+      "68\n",
+      "69\n",
+      "70\n",
+      "71\n",
+      "72\n",
+      "73\n",
+      "74\n",
+      "75\n",
+      "76\n",
+      "77\n",
+      "78\n",
+      "79\n",
+      "80\n",
+      "81\n",
+      "82\n",
+      "83\n",
+      "84\n",
+      "85\n",
+      "86\n",
+      "87\n",
+      "88\n",
+      "89\n",
+      "90\n",
+      "91\n",
+      "92\n",
+      "93\n",
+      "94\n",
+      "95\n",
+      "96\n",
+      "97\n",
+      "98\n",
+      "99\n",
+      "100\n",
+      "101\n",
+      "102\n",
+      "103\n",
+      "104\n",
+      "105\n",
+      "106\n",
+      "107\n",
+      "108\n",
+      "109\n",
+      "110\n",
+      "111\n",
+      "112\n",
+      "113\n",
+      "114\n",
+      "115\n",
+      "116\n",
+      "117\n",
+      "118\n",
+      "119\n",
+      "120\n",
+      "121\n",
+      "122\n",
+      "123\n",
+      "124\n",
+      "125\n",
+      "126\n",
+      "127\n",
+      "128\n",
+      "129\n",
+      "130\n",
+      "131\n",
+      "132\n",
+      "133\n",
+      "134\n",
+      "135\n",
+      "136\n",
+      "137\n",
+      "138\n",
+      "139\n",
+      "140\n",
+      "141\n",
+      "142\n",
+      "143\n",
+      "144\n",
+      "Mean: 16672.21312363323\n",
+      "Stdev: 7180.272654591725\n",
+      "Ratio mean: 0.9379277278060563\n",
+      "Ratio stdev: 0.15076175892196642\n",
+      "Theta: -1852.8903252134187\n",
+      "r: 166.7221312363323\n",
+      "Preprocessing time: 14.979660749435425\n",
+      "Preprocessing done. Took 14.98 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import sys\n",
+    "from time import time\n",
+    "\n",
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "import importlib\n",
+    "from main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data, 1730)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "doing lsh\n",
+      "Target #0 done! Took 3.11 seconds (0.1 minutes).\n",
+      "doing lsh\n",
+      "Target #1 done! Took 2.91 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #2 done! Took 2.80 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #3 done! Took 2.82 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #4 done! Took 2.85 seconds (0.0 minutes).\n",
+      "Done! Took 14.50 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    print('doing lsh')\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Target #0 done! Took 5.99 seconds (0.1 minutes).\n",
+      "Target #1 done! Took 5.71 seconds (0.1 minutes).\n",
+      "Target #2 done! Took 5.76 seconds (0.1 minutes).\n",
+      "Target #3 done! Took 5.65 seconds (0.1 minutes).\n",
+      "Target #4 done! Took 5.84 seconds (0.1 minutes).\n",
+      "Done! Took 28.96 seconds (0.5 minutes).\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "from time import time\n",
+    "\n",
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    dtw_distances = [dtw(window, query, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05)) for window in data]\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i]\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())\n",
+    "print(candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "20\n",
+      "16\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084, 4807, 1325, 14433, 5422, 9312, 5421, 4603, 18938, 3578, 9928]\n",
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579, 18528, 8084, 4807, 3578, 4603, 59898, 9312, 15662, 4601, 11974]\n"
+     ]
+    }
+   ],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "18218\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(len(candidates))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/DBA_multivariate.py b/experiments/DBA_multivariate.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d5fc16e4d317e17e4e62d13a7cf6674b8bde824
--- /dev/null
+++ b/experiments/DBA_multivariate.py
@@ -0,0 +1,216 @@
+'''
+/*******************************************************************************
+ * Copyright (C) 2018 Francois Petitjean
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ******************************************************************************/
+'''
+from __future__ import division
+import numpy as np
+import matplotlib.pyplot as plt
+from functools import reduce
+
+
+__author__ ="Francois Petitjean"
+
+def performDBA(series, n_iterations=10):
+    n_series = len(series)
+    max_length = 0
+    for s in series:
+        max_length = max(max_length,s.shape[1])
+
+    cost_mat = np.zeros((max_length, max_length))
+    delta_mat = np.zeros((max_length, max_length))
+    tmp_delta_mat = np.zeros((max_length, max_length))
+    path_mat = np.zeros((max_length, max_length), dtype=np.int8)
+
+    medoid_ind = approximate_medoid_index(series,cost_mat,delta_mat,tmp_delta_mat)
+    center = series[medoid_ind]
+
+    for i in range(0,n_iterations):
+        center = DBA_update(center, series, cost_mat, path_mat, delta_mat,tmp_delta_mat)
+
+    return center
+
+def approximate_medoid_index(series,cost_mat,delta_mat,tmp_delta_mat):
+    if len(series)<=50:
+        indices = range(0,len(series))
+    else:
+        indices = np.random.choice(range(0,len(series)),50,replace=False)
+
+    medoid_ind = -1
+    best_ss = 1e20
+    for index_candidate in indices:
+        candidate = series[index_candidate]
+        ss = sum_of_squares(candidate,series,cost_mat,delta_mat,tmp_delta_mat)
+        if(medoid_ind==-1 or ss<best_ss):
+            best_ss = ss
+            medoid_ind = index_candidate
+    return medoid_ind
+
+def sum_of_squares(s,series,cost_mat,delta_mat,tmp_delta_mat):
+    return sum(map(lambda t:squared_DTW(s,t,cost_mat,delta_mat,tmp_delta_mat),series))
+
+def DTW(s,t,cost_mat,delta_mat):
+    return np.sqrt(squared_DTW(s,t,cost_mat,delta_mat))
+
+def squared_DTW(s,t,cost_mat,delta_mat,tmp_delta_mat):
+    s_len = s.shape[1]
+    t_len = t.shape[1]
+    fill_delta_mat_dtw(s, t, delta_mat,tmp_delta_mat)
+    cost_mat[0, 0] = delta_mat[0, 0]
+    for i in range(1, s_len):
+        cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
+
+    for j in range(1, t_len):
+        cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
+
+    for i in range(1, s_len):
+        for j in range(1, t_len):
+            diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
+            if(diag <=left):
+                if(diag<=top):
+                    res = diag
+                else:
+                    res = top
+            else:
+                if(left<=top):
+                    res = left
+                else:
+                    res = top
+            cost_mat[i, j] = res+delta_mat[i, j]
+    return cost_mat[s_len-1,t_len-1]
+
+def fill_delta_mat_dtw(center, s, delta_mat, tmp_delta_mat):
+    n_dims = center.shape[0]
+    len_center = center.shape[1]
+    len_s=  s.shape[1]
+    slim = delta_mat[:len_center,:len_s]
+    slim_tmp = tmp_delta_mat[:len_center,:len_s]
+
+    #first dimension - not in the loop to avoid initialisation of delta_mat
+    np.subtract.outer(center[0], s[0],out = slim)
+    np.square(slim, out=slim)
+
+    for d in range(1,center.shape[0]):
+        np.subtract.outer(center[d], s[d],out = slim_tmp)
+        np.square(slim_tmp, out=slim_tmp)
+        np.add(slim,slim_tmp,out=slim)
+
+    assert(np.abs(np.sum(np.square(center[:,0]-s[:,0]))-delta_mat[0,0])<=1e-6)
+
+def DBA_update(center, series, cost_mat, path_mat, delta_mat, tmp_delta_mat):
+    options_argmin = [(-1, -1), (0, -1), (-1, 0)]
+    updated_center = np.zeros(center.shape)
+    center_length = center.shape[1]
+    n_elements = np.zeros(center_length, dtype=int)
+
+    for s in series:
+        s_len = s.shape[1]
+        fill_delta_mat_dtw(center, s, delta_mat, tmp_delta_mat)
+        cost_mat[0, 0] = delta_mat[0, 0]
+        path_mat[0, 0] = -1
+
+        for i in range(1, center_length):
+            cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
+            path_mat[i, 0] = 2
+
+        for j in range(1, s_len):
+            cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
+            path_mat[0, j] = 1
+
+        for i in range(1, center_length):
+            for j in range(1, s_len):
+                diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
+                if(diag <=left):
+                    if(diag<=top):
+                        res = diag
+                        path_mat[i,j] = 0
+                    else:
+                        res = top
+                        path_mat[i,j] = 2
+                else:
+                    if(left<=top):
+                        res = left
+                        path_mat[i,j] = 1
+                    else:
+                        res = top
+                        path_mat[i,j] = 2
+
+                cost_mat[i, j] = res+delta_mat[i, j]
+
+        i = center_length-1
+        j = s_len-1
+
+        while(path_mat[i, j] != -1):
+            updated_center[:,i] += s[:,j]
+            n_elements[i] += 1
+            move = options_argmin[path_mat[i, j]]
+            i += move[0]
+            j += move[1]
+        assert(i == 0 and j == 0)
+        updated_center[:,i] += s[:,j]
+        n_elements[i] += 1
+
+    return np.divide(updated_center, n_elements)
+
+def main():
+    #generating synthetic data
+    n_series = 20
+    length = 200
+    n_dims = 201
+
+    print('Important note: the data should be structure "channels-first", ie the series should have shape (n_channels,length)')
+
+    series = list()
+    padding_length=30
+    indices = range(0, length-padding_length)
+    main_profile_gen = np.array([np.sin(2.0*np.pi*j/len(indices)) for j in indices])
+
+    randomizer = lambda j:np.random.normal(j,0.02)
+    randomizer_fun = np.vectorize(randomizer)
+    for i in range(0,n_series):
+        n_pad_left = np.random.randint(0,padding_length)
+        #adding zero at the start or at the end to shif the profile
+        b = n_pad_left
+        a = padding_length-n_pad_left
+        padded_pattern = np.pad(main_profile_gen,(a,b),mode='constant',constant_values=0)
+
+        #chop some of the end to prove it can work with multiple lengths
+        l = np.random.randint(length-20,length+1)
+        padded_pattern = padded_pattern[:l]
+        padded_pattern = randomizer_fun(padded_pattern)
+
+        series_i = np.zeros((n_dims,l))
+        for d in range(0,n_dims):
+            series_i[d]=padded_pattern
+
+        series.append(series_i)
+
+    #plotting the synthetic data
+    for s in series:
+        plt.plot(range(0,s.shape[1]), s[0])
+    plt.draw()
+    plt.show()
+
+    #calculating average series with DBA
+    average_series = performDBA(series)
+
+    #plotting the average series
+    plt.figure()
+    for d in range(0,n_dims):
+        plt.plot(range(0,average_series.shape[1]), average_series[d])
+    plt.show()
+
+if __name__== "__main__":
+    main()
diff --git a/experiments/EEG data test.ipynb b/experiments/EEG data test.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..f2454028fa2548906c5507e816bd016ab4d93b2e
--- /dev/null
+++ b/experiments/EEG data test.ipynb	
@@ -0,0 +1,563 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The autoreload extension is already loaded. To reload it, use:\n",
+      "  %reload_ext autoreload\n"
+     ]
+    }
+   ],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(900096, 74)\n"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "\n",
+    "datafile = 'data/21.csv'\n",
+    "\n",
+    "data = pd.read_csv(datafile, header=None)\n",
+    "\n",
+    "#and convert it to numpy array:\n",
+    "npdata = np.array(data)\n",
+    "\n",
+    "print(npdata.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(59999, 120, 40)\n"
+     ]
+    }
+   ],
+   "source": [
+    "window_data = [npdata[i:i+120, 0:40] for i in range(0, npdata.shape[0]-120, int(120/8))]\n",
+    "del npdata\n",
+    "data = np.reshape(window_data, (len(window_data), len(window_data[0][0]), len(window_data[0])))\n",
+    "del window_data\n",
+    "data = np.reshape(data, (len(data), len(data[0][0]), len(data[0])))\n",
+    "# data = np.concatenate((data, data))\n",
+    "print(data.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "targets = [43895, 33430, 42575, 1060, 11975]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing:\n",
+      "1730\n",
+      "0:0\n",
+      "1730\n",
+      "999:59\n",
+      "1730\n",
+      "1998:70\n",
+      "1730\n",
+      "2997:78\n",
+      "1730\n",
+      "3996:81\n",
+      "1730\n",
+      "4995:81\n",
+      "1730\n",
+      "5994:81\n",
+      "1730\n",
+      "6993:84\n",
+      "1730\n",
+      "7992:84\n",
+      "1730\n",
+      "8991:84\n",
+      "1730\n",
+      "9990:84\n",
+      "1730\n",
+      "10989:84\n",
+      "1730\n",
+      "11988:84\n",
+      "1730\n",
+      "12987:84\n",
+      "1730\n",
+      "13986:91\n",
+      "1730\n",
+      "14985:91\n",
+      "1730\n",
+      "15984:91\n",
+      "1730\n",
+      "16983:91\n",
+      "1730\n",
+      "17982:91\n",
+      "1730\n",
+      "18981:91\n",
+      "1730\n",
+      "19980:95\n",
+      "1730\n",
+      "20979:95\n",
+      "1730\n",
+      "21978:95\n",
+      "1730\n",
+      "22977:95\n",
+      "1730\n",
+      "23976:95\n",
+      "1730\n",
+      "24975:95\n",
+      "1730\n",
+      "25974:95\n",
+      "1730\n",
+      "26973:99\n",
+      "1730\n",
+      "27972:99\n",
+      "1730\n",
+      "28971:99\n",
+      "1730\n",
+      "29970:99\n",
+      "1730\n",
+      "30969:102\n",
+      "1730\n",
+      "31968:102\n",
+      "1730\n",
+      "32967:103\n",
+      "1730\n",
+      "33966:105\n",
+      "1730\n",
+      "34965:105\n",
+      "1730\n",
+      "35964:105\n",
+      "1730\n",
+      "36963:105\n",
+      "1730\n",
+      "37962:109\n",
+      "1730\n",
+      "38961:110\n",
+      "1730\n",
+      "39960:114\n",
+      "1730\n",
+      "40959:114\n",
+      "1730\n",
+      "41958:115\n",
+      "1730\n",
+      "42957:116\n",
+      "1730\n",
+      "43956:116\n",
+      "1730\n",
+      "44955:116\n",
+      "1730\n",
+      "45954:122\n",
+      "1730\n",
+      "46953:126\n",
+      "1730\n",
+      "47952:126\n",
+      "1730\n",
+      "48951:126\n",
+      "1730\n",
+      "49950:128\n",
+      "1730\n",
+      "50949:128\n",
+      "1730\n",
+      "51948:128\n",
+      "1730\n",
+      "52947:128\n",
+      "1730\n",
+      "53946:130\n",
+      "1730\n",
+      "54945:134\n",
+      "1730\n",
+      "55944:134\n",
+      "1730\n",
+      "56943:134\n",
+      "1730\n",
+      "57942:143\n",
+      "1730\n",
+      "58941:143\n",
+      "1730\n",
+      "59940:145\n",
+      "r = 1730\n",
+      "0\n",
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n",
+      "8\n",
+      "9\n",
+      "10\n",
+      "11\n",
+      "12\n",
+      "13\n",
+      "14\n",
+      "15\n",
+      "16\n",
+      "17\n",
+      "18\n",
+      "19\n",
+      "20\n",
+      "21\n",
+      "22\n",
+      "23\n",
+      "24\n",
+      "25\n",
+      "26\n",
+      "27\n",
+      "28\n",
+      "29\n",
+      "30\n",
+      "31\n",
+      "32\n",
+      "33\n",
+      "34\n",
+      "35\n",
+      "36\n",
+      "37\n",
+      "38\n",
+      "39\n",
+      "40\n",
+      "41\n",
+      "42\n",
+      "43\n",
+      "44\n",
+      "45\n",
+      "46\n",
+      "47\n",
+      "48\n",
+      "49\n",
+      "50\n",
+      "51\n",
+      "52\n",
+      "53\n",
+      "54\n",
+      "55\n",
+      "56\n",
+      "57\n",
+      "58\n",
+      "59\n",
+      "60\n",
+      "61\n",
+      "62\n",
+      "63\n",
+      "64\n",
+      "65\n",
+      "66\n",
+      "67\n",
+      "68\n",
+      "69\n",
+      "70\n",
+      "71\n",
+      "72\n",
+      "73\n",
+      "74\n",
+      "75\n",
+      "76\n",
+      "77\n",
+      "78\n",
+      "79\n",
+      "80\n",
+      "81\n",
+      "82\n",
+      "83\n",
+      "84\n",
+      "85\n",
+      "86\n",
+      "87\n",
+      "88\n",
+      "89\n",
+      "90\n",
+      "91\n",
+      "92\n",
+      "93\n",
+      "94\n",
+      "95\n",
+      "96\n",
+      "97\n",
+      "98\n",
+      "99\n",
+      "100\n",
+      "101\n",
+      "102\n",
+      "103\n",
+      "104\n",
+      "105\n",
+      "106\n",
+      "107\n",
+      "108\n",
+      "109\n",
+      "110\n",
+      "111\n",
+      "112\n",
+      "113\n",
+      "114\n",
+      "115\n",
+      "116\n",
+      "117\n",
+      "118\n",
+      "119\n",
+      "120\n",
+      "121\n",
+      "122\n",
+      "123\n",
+      "124\n",
+      "125\n",
+      "126\n",
+      "127\n",
+      "128\n",
+      "129\n",
+      "130\n",
+      "131\n",
+      "132\n",
+      "133\n",
+      "134\n",
+      "135\n",
+      "136\n",
+      "137\n",
+      "138\n",
+      "139\n",
+      "140\n",
+      "141\n",
+      "142\n",
+      "143\n",
+      "144\n",
+      "Mean: 16672.21312363323\n",
+      "Stdev: 7180.272654591725\n",
+      "Ratio mean: 0.9379277278060563\n",
+      "Ratio stdev: 0.15076175892196642\n",
+      "Theta: -1852.8903252134187\n",
+      "r: 166.7221312363323\n",
+      "Preprocessing time: 14.979660749435425\n",
+      "Preprocessing done. Took 14.98 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import sys\n",
+    "from time import time\n",
+    "\n",
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "import importlib\n",
+    "from main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data, 1730)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "doing lsh\n",
+      "Target #0 done! Took 3.11 seconds (0.1 minutes).\n",
+      "doing lsh\n",
+      "Target #1 done! Took 2.91 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #2 done! Took 2.80 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #3 done! Took 2.82 seconds (0.0 minutes).\n",
+      "doing lsh\n",
+      "Target #4 done! Took 2.85 seconds (0.0 minutes).\n",
+      "Done! Took 14.50 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    print('doing lsh')\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Target #0 done! Took 5.99 seconds (0.1 minutes).\n",
+      "Target #1 done! Took 5.71 seconds (0.1 minutes).\n",
+      "Target #2 done! Took 5.76 seconds (0.1 minutes).\n",
+      "Target #3 done! Took 5.65 seconds (0.1 minutes).\n",
+      "Target #4 done! Took 5.84 seconds (0.1 minutes).\n",
+      "Done! Took 28.96 seconds (0.5 minutes).\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "from time import time\n",
+    "\n",
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    dtw_distances = [dtw(window, query, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05)) for window in data]\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i]\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())\n",
+    "print(candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "20\n",
+      "16\n",
+      "[11975, 18529, 3579, 2144, 18528, 11974, 4602, 11976, 9108, 8084, 4807, 1325, 14433, 5422, 9312, 5421, 4603, 18938, 3578, 9928]\n",
+      "[11975, 18529, 4602, 2144, 1325, 14433, 5421, 9108, 5217, 3579, 18528, 8084, 4807, 3578, 4603, 59898, 9312, 15662, 4601, 11974]\n"
+     ]
+    }
+   ],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "18218\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(len(candidates))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/MTS test.ipynb b/experiments/MTS test.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..33bc8ee095dae509142446e0b528d18c4949186f
--- /dev/null
+++ b/experiments/MTS test.ipynb	
@@ -0,0 +1,368 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import json\n",
+    "import h5py\n",
+    "import os\n",
+    "import sys\n",
+    "from time import time\n",
+    "import warnings\n",
+    "\n",
+    "# Ignore warnings as they just pollute the output\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "# Enable importing modules from the parent directory\n",
+    "module_path = os.path.abspath(os.path.join('..'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "module_path = os.path.abspath(os.path.join('../experiments'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "\n",
+    "# DNase-seq 2011, hg19\n",
+    "bw = 'data/ENCFF158GBQ.bigWig'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "./data/ENCFF158GBQ.bigWig already exist. To overwrite pass `overwrite=True`\n",
+      "./models/dnase_w-12000_r-100.h5 already exist. To overwrite pass `overwrite=True`\n"
+     ]
+    }
+   ],
+   "source": [
+    "from download import download_encode_file, download_file\n",
+    "from pathlib import Path\n",
+    "\n",
+    "Path('data').mkdir(parents=True, exist_ok=True)\n",
+    "Path('models').mkdir(parents=True, exist_ok=True)\n",
+    "\n",
+    "download_encode_file('ENCFF158GBQ.bigWig')\n",
+    "\n",
+    "download_file(\n",
+    "    \"https://zenodo.org/record/2609763/files/dnase_w-12000_r-100.h5?download=1\",\n",
+    "    \"dnase_w-12000_r-100.h5\",\n",
+    "    dir=\"models\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(124621, 1, 120)\n",
+      "(124621, 1, 120)\n",
+      "(124621, 120, 3)\n",
+      "Done! Took 0.64 seconds (0.0 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import bigwig\n",
+    "import bbi\n",
+    "\n",
+    "t0 = time()\n",
+    "# data_12kb_original = bigwig.chunk(bw, 12000, 100, 12000 / 6, ['chr1'], verbose=True)\n",
+    "data_12kb = np.reshape(data_12kb_original, (len(data_12kb_original), 1, len(data_12kb_original[0])))\n",
+    "# data_12kb = np.repeat(data_12kb, repeats=3, axis=1)\n",
+    "data2 = np.copy(data_12kb)\n",
+    "np.random.shuffle(data2)\n",
+    "data3 = np.copy(data_12kb)\n",
+    "np.random.shuffle(data3)\n",
+    "print(data_12kb.shape)\n",
+    "print(data2.shape)\n",
+    "\n",
+    "data_12kb = np.concatenate((data_12kb, data2), axis=1)\n",
+    "data_12kb = np.concatenate((data_12kb, data3), axis=1)\n",
+    "data_12kb = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0][0]), len(data_12kb[0])))\n",
+    "print(data_12kb.shape)\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from utils import plot_windows_from_data\n",
+    "import matplotlib.pyplot as plt \n",
+    "\n",
+    "k_12kb = 20 # Number of KNNs to be saved later on\n",
+    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
+    "\n",
+    "# N = data_12kb.shape[2]\n",
+    "\n",
+    "# T = len(targets_12kb)\n",
+    "# sz = data_12kb.shape[1]\n",
+    "\n",
+    "# plt.figure(figsize=(12 * T, 4 * N))\n",
+    "\n",
+    "# ymax = 1.0\n",
+    "\n",
+    "# show_predictions = False\n",
+    "\n",
+    "# for i, target in enumerate(targets_12kb):\n",
+    "#     for j in range(N):\n",
+    "#         ax = plt.subplot(N, T, (j) * T + (i + 1))\n",
+    "\n",
+    "#         ax.set_facecolor(\"#eeeeee\")\n",
+    "\n",
+    "#         plt.bar(np.arange(sz), data_12kb[target][:,j], color='#008ca8', width=1.0)\n",
+    "\n",
+    "#         plt.ylim(0, ymax)\n",
+    "#         plt.xticks([], [])\n",
+    "#         plt.yticks([], [])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing:\n",
+      "0\n",
+      "50\n",
+      "100\n",
+      "150\n",
+      "Mean: 1.2309004688213228\n",
+      "Stdev: 0.7529859787962313\n",
+      "Ratio mean: 0.8834137208749415\n",
+      "Ratio stdev: 0.07732486974072242\n",
+      "Theta: -0.711803356472954\n",
+      "r: 0.5\n",
+      "Preprocessing time: 5.429347038269043\n",
+      "Preprocessing done. Took 5.57 seconds (0.1 minutes).\n"
+     ]
+    },
+    {
+     "ename": "KeyboardInterrupt",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-24-8b395f9f4005>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     13\u001b[0m     \u001b[0mt1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     14\u001b[0m     \u001b[0mquery\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdata_12kb\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtarget\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m     \u001b[0mlsh_candidates\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlsh_distances\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_lsh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlsh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata_12kb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mquery\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     16\u001b[0m \u001b[0;31m#     topk_dtw.append(candidates)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     17\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m60\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
+     ]
+    }
+   ],
+   "source": [
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "from main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data_12kb, 20)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb[0:1]):\n",
+    "    t1 = time()\n",
+    "    query = data_12kb[target]\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data_12kb, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Done! Took 15.48 seconds (0.3 minutes).\n",
+      "[80503, 77574, 3128, 22594, 47036, 111653, 473, 17658, 12967, 21104]\n"
+     ]
+    }
+   ],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "\n",
+    "t0 = time()\n",
+    "target = data_12kb[80503]\n",
+    "dtw_distances = [dtw(window, target, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05*120)) for window in data_12kb]\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i] ** 2\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7\n",
+      "[80503, 77574, 3128, 22594, 47036, 111653, 473, 17658, 12967, 21104, 54908, 18303, 27633, 101051, 113445, 113957, 100419, 90491, 3100, 78022]\n",
+      "[80503, 77524, 18303, 12354, 1254, 113957, 117630, 45225, 21707, 77377, 111653, 12058, 103318, 3128, 77574, 13215, 47036, 12624, 80593, 101463]\n",
+      "14\n"
+     ]
+    }
+   ],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n",
+    "print(candidates.index(77574))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 864x5184 with 18 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "k_12kb = 20 # Number of KNNs to be saved later on\n",
+    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
+    "\n",
+    "show = 5\n",
+    "offset = data_12kb.shape[2]\n",
+    "\n",
+    "N = (show + 1) * offset \n",
+    "\n",
+    "T = 1 # len(targets_12kb)\n",
+    "sz = data_12kb.shape[1]\n",
+    "\n",
+    "plt.figure(figsize=(12 * T, 4 * N))\n",
+    "\n",
+    "ymax = 1.0\n",
+    "\n",
+    "show_predictions = False\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb[0:1]):\n",
+    "    for x in range(offset):\n",
+    "        ax = plt.subplot(N, T, (x) * T + (i + 1))\n",
+    "\n",
+    "        ax.set_facecolor(\"#eeeeee\")\n",
+    "\n",
+    "        plt.bar(np.arange(sz), data_12kb[target][:,x], color='#008ca8', width=1.0)\n",
+    "\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])\n",
+    "    \n",
+    "    for j, hit in enumerate(candidates[:show]):\n",
+    "        for y in range(offset):\n",
+    "            plt.subplot(N, T, (((j*offset)+ y + offset) * T) + (i + 1))\n",
+    "            plt.bar(np.arange(sz), data_12kb[hit][:,y], color='green', width=1.0) # orange = CAE\n",
+    "            plt.ylim(0, ymax)\n",
+    "            plt.xticks([], [])\n",
+    "            plt.yticks([], [])\n",
+    "            plt.subplots_adjust(top=0.9)\n",
+    "            \n",
+    "    for j, hit in enumerate(dtw_candidates[:show]):\n",
+    "        for y in range(offset):\n",
+    "            plt.subplot(N, T, (((j*offset)+ y + offset) * T) + (i + 1))\n",
+    "            plt.bar(np.arange(sz), data_12kb[hit][:,y], color='green', width=1.0) # orange = CAE\n",
+    "            plt.ylim(0, ymax)\n",
+    "            plt.xticks([], [])\n",
+    "            plt.yticks([], [])\n",
+    "            plt.subplots_adjust(top=0.9)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(topk_dtw[0][0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/UTS test.ipynb b/experiments/UTS test.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..31c3967752bdf06d33485f549318804a41bdc44f
--- /dev/null
+++ b/experiments/UTS test.ipynb	
@@ -0,0 +1,562 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import json\n",
+    "import h5py\n",
+    "import os\n",
+    "import sys\n",
+    "from time import time\n",
+    "import warnings\n",
+    "\n",
+    "# Ignore warnings as they just pollute the output\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "# Enable importing modules from the parent directory\n",
+    "module_path = os.path.abspath(os.path.join('..'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "module_path = os.path.abspath(os.path.join('../experiments'))\n",
+    "if module_path not in sys.path:\n",
+    "    sys.path.append(module_path)\n",
+    "\n",
+    "# DNase-seq 2011, hg19\n",
+    "bw = 'data/ENCFF158GBQ.bigWig'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "./data/ENCFF158GBQ.bigWig already exist. To overwrite pass `overwrite=True`\n",
+      "./models/dnase_w-12000_r-100.h5 already exist. To overwrite pass `overwrite=True`\n"
+     ]
+    }
+   ],
+   "source": [
+    "from download import download_encode_file, download_file\n",
+    "from pathlib import Path\n",
+    "\n",
+    "Path('data').mkdir(parents=True, exist_ok=True)\n",
+    "Path('models').mkdir(parents=True, exist_ok=True)\n",
+    "\n",
+    "download_encode_file('ENCFF158GBQ.bigWig')\n",
+    "\n",
+    "download_file(\n",
+    "    \"https://zenodo.org/record/2609763/files/dnase_w-12000_r-100.h5?download=1\",\n",
+    "    \"dnase_w-12000_r-100.h5\",\n",
+    "    dir=\"models\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "\n",
+    "def knn(data, target_idx, k, metric='euclidean', sax = None, ignore: int = 0, sort_only: bool = False):\n",
+    "    \"\"\"K nearest neighbors\n",
+    "    \n",
+    "    Find the `k` nearest neighbors of a \n",
+    "    \"\"\"\n",
+    "    \n",
+    "    target = data[target_idx]\n",
+    "    \n",
+    "    if sort_only:\n",
+    "        dist = data\n",
+    "    else:\n",
+    "        if sax is None:\n",
+    "            dist = cdist(data, target.reshape((1, target.size)), metric='euclidean').flatten()\n",
+    "\n",
+    "        else:\n",
+    "            N = data.shape[0]\n",
+    "            dist = np.zeros(N)\n",
+    "            for i in range(N):\n",
+    "                dist[i] = sax.distance_sax(target, data[i])\n",
+    "\n",
+    "    # Ensure that the target is always first\n",
+    "    dist[target_idx] = -1\n",
+    "    for i in range(1, ignore + 1):\n",
+    "        dist[min(target_idx + i, data.shape[0] - 1)] = -1\n",
+    "        dist[max(target_idx - i, 0)] = -1\n",
+    "    \n",
+    "    return np.argsort(dist)[1 + (2 * ignore):k + 1 + (2 * ignore)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.signal import correlate\n",
+    "\n",
+    "def norm(data, zero_norm: bool = False):\n",
+    "    mean = np.mean(data) if zero_norm else 0\n",
+    "    \n",
+    "    return (data - mean) / np.std(data)\n",
+    "\n",
+    "def norm2d(data, zero_norm: bool = False):\n",
+    "    mean = np.mean(data, axis=1).reshape(-1, 1) if zero_norm else np.zeros((data.shape[0], 1))\n",
+    "    std = np.std(data, axis=1).reshape(-1, 1)\n",
+    "    \n",
+    "    return (data - mean) / std\n",
+    "\n",
+    "def xcorrelation(data, template_idx, n, normalize=False, zero_normalize=False, ignore: int = 0):\n",
+    "    unknown = data\n",
+    "    template = data[template_idx]\n",
+    "    \n",
+    "    if norm:\n",
+    "        unknown = norm2d(unknown, zero_norm=zero_normalize)\n",
+    "        template = norm(template, zero_norm=zero_normalize)\n",
+    "        \n",
+    "    xcorr = np.apply_along_axis(lambda m: correlate(m, template, mode='full'), axis=1, arr=unknown)\n",
+    "    xcorr[np.where(np.isnan(xcorr))] = 0\n",
+    "\n",
+    "    max_xcorr = np.nanmax(xcorr, axis=1)\n",
+    "    \n",
+    "    # Ensure that the target is always last\n",
+    "    max_xcorr[template_idx] = -1\n",
+    "    for i in range(1, ignore + 1):\n",
+    "        max_xcorr[min(template_idx + i, data.shape[0] - 1)] = -1\n",
+    "        max_xcorr[max(template_idx - i, 0)] = -1\n",
+    "    \n",
+    "    return np.argsort(max_xcorr)[::-1][:n]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Extracted 124621 windows from chr1 with a max value of 1.0.\n",
+      "Done! Took 27.24 seconds (0.5 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "import bigwig\n",
+    "\n",
+    "t0 = time()\n",
+    "data_12kb = bigwig.chunk(bw, 12000, 100, 12000 / 6, ['chr1'], verbose=True)\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdAAAAKFCAYAAAB89rjZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3DU9b3/8dcmUDaQkAuERAwYrkaiIAZsJSCX0hNQELkqRwSRMx5QGIVabz9FQD3joLYFPXBqGWwQKh0RDlq5iNUgxqo1EDgELSUQLiEabiEkYSEJ+/uD6ZaFJCYf9rv73d3nYyYz8L3t53t9fd+f/e6uw+12uwUAAJokItANAAAgGBGgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKGCxoqIi3XHHHYqPj1dycrJmzpypmpoaSdJf/vIXpaWlqWXLlho8eLAOHjzomW/evHlq3ry5oqOjPX/79+/3Wu7gwYPVsmVLpaWl6eOPP/aM+/TTT3XTTTcpLi5Obdq00ejRo1VcXOy/lQbCAAEKWOzhhx9Wu3btVFJSovz8fG3dulVLlizR8ePHNWbMGL3wwgs6efKk+vTpo3vuucdr3nvuuUcVFRWev86dO3vGTZw4Ub1799aJEyf00ksvady4cTp27JgkqUePHtq8ebPKysp09OhRdevWTTNmzPDregOhjgAFLHbgwAFNmDBBTqdTycnJGjZsmAoKCrR27Vqlp6dr/Pjxcjqdmjdvnnbu3KnvvvvuR5e5d+9ebd++XfPnz1dUVJTGjh2rm266Se+9954kKSkpSe3bt/dMHxkZqX379lm2jkA4IkABiz366KNavXq1qqqqVFxcrI0bN3pCtFevXp7pWrVqpS5duqigoMAz7IMPPlBCQoLS09O1dOlSz/CCggJ17txZMTExnmG9evXymvfQoUOKi4tTVFSUXn31VT3xxBMWrykQXghQwGIDBw5UQUGBWrdurZSUFPXp00d33323KioqFBsb6zVtbGyszpw5I0maMGGCvv32Wx07dky///3vtWDBAr3zzjuS9KPzSlLHjh1VVlam48eP68UXX1RaWprFawqEFwIUsNCFCxeUlZWlMWPGqLKyUsePH9epU6f05JNPKjo6WuXl5V7Tl5eXe6rKHj16qH379oqMjFS/fv306KOPas2aNZL0o/NeKiEhQVOmTNGoUaM8Dy8BuHoEKGChkydP6vDhw5o5c6ZatGihNm3aaOrUqdqwYYPS09O1c+dOz7SVlZUqLCxUenp6nctyOBz6548npaena//+/V4V586dO+udt6amRqWlpVeELgBzBChgobZt26pTp05aunSpampqVFZWpuzsbPXq1UujR4/W7t279d5778nlcmnBggXq2bOnp6t1/fr1OnXqlNxut77++mstXrxYo0aNkiR1795dN998s+bPny+Xy6V169Zp165dGjt2rCRp7dq1+vvf/64LFy7o2LFjmjNnjnr37q2EhISAbQsg1BCggMXWrl2rTZs2KTExUV27dlWzZs30m9/8RomJiXrvvff0//7f/1N8fLy++uorrV692jPf6tWr1bVrV8XExGjy5Ml68sknNWXKFK/x33zzjeLj4/XUU09pzZo1SkxMlCQVFxdr2LBhiomJ0U033aSIiAitW7fO7+sOhDIHP6gNAEDTUYECAGCAAAUAwAABCgCAAQIUAAADBCgAAAaaNWXi3NxcOZ1Oq9oCC+04dNzr/707tg1QSwA0xqXnLOdr4LhcLmVmZtY5rkkB6nQ6lZGR4ZNGwb+GLFvu9f/TS7MC1BIAjeF9znr/luvppQ/6tzFhLC8vr95xdOECAGCAAAUAwECTunABAKEndsa/uovpHm48KlAAAAxQgQJAA6jOUB8qUAAADFCBAgA8Lq24JaruhlCBAgBggAo0TPG+DtB0nDe4FBUoAAAGqEBD2OXvZQAAfIcKFAAAA1SgAGAT9BoFFypQAAAMUIECQBDjc5uBQwUKAIABAhQAAAMEKAAABghQAAAM8BARABjg4R1QgQIAYIAKFAAuEexfZsAX3vsPFSgAAAYIUAAADNCFG2KCvfspVNCNBoQ+KlAAAAxQgQKAxXzdI0FPkz1QgQIAYIAKNAhZeTfL+3XA1QuGCjEY2mh3BGiQ4ySwB/YDGosb1tBBgAIICw3d5AQqyKy+8SKsrUWAAoAP2L0Xwu7tC0YEKICQRWjYXzBXyQSojdR3IHERCG7BfIEIF5xj9Wvo+K1vu4XLcU6ABlAwnLR2fN8IQGA09pplem0LtptNArQJ/BkmgQrXYAj1UMXvSwL/0thrUSDPk4AGaKCqGytCorF3TqEUUI3tvvHFtrFjmITSvgxm7AcEisPtdrsbO3FeXp4yMjJ89uKhFKDwH1+/P9zYYy0Yjhtf37yZ3gxZLRj2BQLD18dlQ7ln2wC9lOkb15xkMMEDXNaq7wLHtoYv2DZAc3Nz5XQ6fdYwAADszOVyKTMzs85xTQpQAABwEb/GAgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAn7wj3/8Q06nU5MmTZIk7dmzR3369FF8fLzi4+M1dOhQ7dmzxzP9uXPnNH36dCUlJSkhIUEjR45UcXGxZ/wXX3yhW2+9VTExMerZs6c+//xzz7icnBxFREQoOjra85edne2/lQXCBAEK+MEjjzyivn37ev7fvn17rVmzRidPntTx48d111136d577/WMX7Rokf76179q165dOnr0qOLi4jRr1ixJ0smTJ3XXXXfpV7/6lcrKyvTEE09o5MiROnXqlNfyKyoqPH9Tpkzx38oCYYIABSy2evVqxcXF6ec//7lnWFxcnFJTU+VwOOR2uxUZGal9+/Z5xh84cEBZWVlKSkqS0+nUvffeq4KCAkkXq8+kpCSNHz9ekZGRmjRpkhITE7V27Vq/rxsQzghQwELl5eWaO3euXnvttTrHx8XFyel0atasWXrmmWc8w6dNm6bc3FwdPXpUVVVVWrVqlYYPHy5JcrvdcrvdXstxu93avXu35/+lpaVKSkpSp06dNHv2bFVWVlqwdkB4I0ABCz333HOaNm2aOnToUOf4srIynT59Wm+88YZ69+7tGd69e3d17NhR1157rVq3bq1vv/1Wc+fOlST169dPR48e1TvvvKPq6mplZ2ersLBQVVVVkqS0tDTl5+erpKREn3zyifLy8jRnzhzrVxYIMwQoYJH8/Hx9/PHHmj17doPTtWrVStOnT9fkyZNVWloqSZoxY4ZcLpdOnDihyspKjRkzxlOBtmnTRuvXr9evf/1rJSUladOmTRo6dKhSUlIkScnJyerRo4ciIiLUqVMnLVy4UGvWrLF2ZYEw1CzQDQBCVU5OjoqKitSxY0dJUkVFhWpra7Vnzx5t377da9oLFy6oqqpKxcXFateunXbu3KmXXnpJCQkJkqRZs2Zp7ty5On78uNq2bauBAwfqb3/7mySppqZGXbp00S9/+cs62/HP91kB+BYVKGCRhx56SIWFhcrPz1d+fr6mT5+uO++8U5s3b9aWLVu0Y8cO1dbWqry8XHPmzFF8fLxuuOEGSVLfvn21YsUKnT59WtXV1VqyZInat2+vtm3bSpJ27Nih6upqlZeX6/HHH1dKSoqysrIkXQzuQ4cOye126/Dhw3rqqac0atSogG0HIFQRoIBFWrZsqeTkZM9fdHS0nE6nEhMTVVZWpokTJyo2NlZdunTRvn37tGnTJjmdTknSq6++KqfTqW7duikxMVEbNmzQunXrPMteuHCh2rZtqw4dOqikpMRr3Pbt23XbbbepVatW6tevn2688UYtXrzY7+sPhDqHm74dAACajAoUAAADBCgAAAYIUAAADBCgAAAYaNLnQHNzcz1PCQJW2nHoeL3jends68eWAAhnLpdLmZmZdY5rUoA6nU5lZGT4pFFAQ4YsW17vuNNLs/zYEgDhLC8vr95xdOECAGCAAAUAwAABCgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMNCkH9QGrBQ7o/4f0QZgP5ees6eXPhjAlgQGAQrA58L9worwQIACAK5aON408R4oAAAGqEARdMLxTheA/RCgAACfuvyBwFC90SVA/YzqCQBCA++BAgBggAoUIStcupHsjv2AUEWAArhqfAkGGhKqb13RhQsAgAEqUISNUL0LBvyFngZvBCjQgIYuGKEUwtxcAE1HgFqMOzb/Yntbi6D1LR6wCm4EaABx8gS3xoZJoELH9PjiJgSX8vXxEErXPQIUQc2Ki73JMu1yUfBn+HFhhS8Ec68GAYqwFMwnbbCze+Ue7uiBaDwCFAFlh5M1kFVbOFSqDWlsO+yy3XyhoXXmpiG4EKA2Eqonj10u1v5kGgyXuvQYCMdt2JBQPVcuZfoEuMm24fgyQ4DaVLBdIDgBfc/q9xgRvHyxL4P5eLDLx8sIUABBLdhuNv0p2EIy2Npr2wD19Unhi+6Qq53HVFPe/7na9l4+XbAd0AhvvqhMrKhuOI9Ck8PtdrsbO3FeXp4yMjJ89uK+Pqj8GWoAAPvxdS9EQ7nXpADNzc2V0+n0WcMAALAzl8ulzMzMOsc1KUABAMBF/JwZAAAGCFAAAAwQoAAAGCBAAQAwQIACAGCAAAUAwAABCgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKWGzSpEm65ppr1Lp1a3Xv3l3Lli2TJO3Zs0d9+vRRfHy84uPjNXToUO3Zs+eK+c+fP6+0tDSlpKR4DR88eLASExPVunVr9erVS+vXr/ca/8c//lHXXXedWrVqpbvvvlsnT560biWBMMTvgQIWKygoUNeuXdWiRQt99913GjRokD788EN16dJFZWVluu6663ThwgX993//t5YtW6Zdu3Z5zf/SSy9p8+bN2r9/v44cOeIZvmvXLvXo0UPNmjXTV199paFDh2rv3r265pprVFBQoJ/97Gf68MMPdcstt+ihhx7ShQsXtHr1an+vPhCyqEABi6Wnp6tFixaSJIfDIYfDocLCQsXFxSk1NVUOh0Nut1uRkZHat2+f17wHDhzQypUr9fTTT1+x3J49e6pZs2ae5VZXV+vw4cOSpFWrVmnkyJG6/fbbFR0drRdeeEFr167VmTNnLF5bIHwQoIAfPPzww2rZsqXS0tJ0zTXX6I477vCMi4uLk9Pp1KxZs/TMM894zTdr1iz913/9l6Kioupc7ogRI+R0OvXTn/5UgwYNUp8+fSRdrHp79erlma5Lly76yU9+or1791qwdkB4IkABP1iyZInOnDmjbdu2acyYMZ6KVJLKysp0+vRpvfHGG+rdu7dn+Lp161RTU6PRo0fXu9w///nPOnPmjDZs2KCsrCxFRFw8pSsqKhQbG+s1bWxsLBUo4EMEKOAnkZGR6t+/v44cOaKlS5d6jWvVqpWmT5+uyZMnq7S0VJWVlXriiSf0+uuv/+hymzdvruHDh2vz5s16//33JUnR0dEqLy/3mq68vFwxMTG+WyEgzDULdAOAcFNTU6PCwsIrhl+4cEFVVVUqLi6Ww+FQUVGRBgwYIOnik7inT59WcnKyvvzyS6Wmpja43PT0dO3cudMzbv/+/Tp37py6d+9uzUoBYYgKFLBQaWmpVq9erYqKCtXW1mrz5s165513NGTIEG3ZskU7duxQbW2tysvLNWfOHMXHx+uGG27QjTfeqMOHDys/P1/5+flatmyZkpKSlJ+frw4dOui7777Txo0bdfbsWVVXV2vlypX67LPPNHDgQEnSfffdpw8++EDbtm1TZWWl5s6dqzFjxlCBAj5EBQpYyOFwaOnSpZo+fbouXLig6667Tr/97W81atQovfvuu5o1a5aOHDmiqKgo9e3bV5s2bZLT6ZQkJScne5aTkJCgiIgIzzC326158+Zpz549ioyMVLdu3fSnP/1Jt9xyi6SLFej//M//6L777tOJEyc0dOhQvfXWW/7fAEAI43OgAAAYoAsXAAADBCgAAAYIUAAADBCgAAAYaNJTuLm5uZ4nBAEACHUul0uZmZl1jmtSgDqdTmVkZPikUQAA2F1eXl694+jCBQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGCBAAQAwQIACAGCAAAUAwAABCgCAAQIUAAADzQLdAABoqtgZyz3/Pr30wQC2BOGMChQAAANUoACCGtUoAoUKFAAAA1SggE1cWklJVFOA3VGBAgBggAAFAMAAXbhAAF3ebQsgeFCBAgBggAoUXniQBQAahwANQnzuDeGGrm7YEQEa5KgYQxc3SoC9EaA2Ut8Fk7tvmODmCrAWAWpTdglNqiDUh2MD4Y4A9ZH6Ao8LCy5llxujYGCyrai64U8EqMU4oREOOM4RjghQQ76oJOxSjdilHaifL7pLTZbBsdF4dGmHn4AGaDAccL6+gFh9QWrsg0h23d6hIlDHdjAEnj/baOV+aGg9QvV8C9X1MhX0FWhjT0aeavVm9/eXGvtagWxToATbRcyu260+DW3PQN0AB5LdrxWB5HC73e7GTpyXl6eMjAyfvbhdTixcvWDoEjQ5iUP1GA1kSAAmAhXCDeVekwI0NzdXTqfTZw0DAMDOXC6XMjMz6xzXpAAFAAAX8WssAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQo4Af/+Mc/5HQ6NWnSJEnSl19+qV/84hdKSEhQYmKixo8fr5KSEs/08+bNU/PmzRUdHe35279/vyTp0KFDXsOjo6PlcDj02muvSZJycnIUERHhNT47O9v/Kw2EOAIU8INHHnlEffv29fz/1KlTeuihh1RUVKSDBw8qJiZGU6dO9ZrnnnvuUUVFheevc+fOkqSOHTt6Df+///s/RUREaOzYsZ5527dv7zXNlClT/LOiQBhpFugGAKFu9erViouLU79+/bRv3z5J0vDhw72mmTlzpgYOHGi0/BUrVuj2229Xamrq1TYVQBNQgQIWKi8v19y5cz3dq/X57LPPlJ6e7jXsgw8+UEJCgtLT07V06dJ6512xYsUVFWZpaamSkpLUqVMnzZ49W5WVleYrAaBOBChgoeeee07Tpk1Thw4d6p1m165dWrBggV555RXPsAkTJujbb7/VsWPH9Pvf/14LFizQO++8c8W827Zt0w8//KBx48Z5hqWlpSk/P18lJSX65JNPlJeXpzlz5vh2xQAQoIBV8vPz9fHHH2v27Nn1TrNv3z4NHz5cixYt0oABAzzDe/Toofbt2ysyMlL9+vXTo48+qjVr1lwxf3Z2tsaOHavo6GjPsOTkZPXo0UMRERHq1KmTFi5cWOe8AK4O74ECFsnJyVFRUZE6duwoSaqoqFBtba327Nmj7du36+DBgxo6dKiee+453X///Q0uy+FwyO12ew07e/as3n33Xa1bt67J8wK4elSggEUeeughFRYWKj8/X/n5+Zo+fbruvPNObd68WcXFxRoyZIgeeeQRTZ8+/Yp5169fr1OnTsntduvrr7/W4sWLNWrUKK9p1q1bp7i4OA0ePNhreE5Ojg4dOiS3263Dhw/rqaeeumJeAFePAAUs0rJlSyUnJ3v+oqOj5XQ6lZiYqGXLlmn//v2aP3++1+c1/2n16tXq2rWrYmJiNHnyZD355JNXPCiUnZ2tyZMny+FweA3fvn27brvtNrVq1Ur9+vXTjTfeqMWLF/tlnYFw4nDTtwMAQJNRgQIAYIAABQDAAAEKAIABAhQAAAMEKAAABpr0RQq5ublyOp1WtQWAgR2Hjtc5vHfHtn5uCRB6XC6XMjMz6xzXpAB1Op3KyMjwSaMA+MaQZcvrHH56aZafWwKEnry8vHrH0YULAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGCBAAQAwQIACAGCAAAUAwECTflAbQODFzqj7B7QB+BcVKAAABqhAgRB1eaV6eumDAWoJEJqoQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAzyFCwQBPvsJ2A8VKAAABqhAAZvyddV56fL4TChw9QhQwI/4cgMgdBCgQABRFQLBi/dAAQAwQAUK2ARP2gLBhQoUAAADVKDgfTgAMECAhim6C/3Hjtu6oaeBG2ovN1jAvxCg8MLHLMKTHUM+UDgH0FgEKBpE927jcNEFwg8BehkuhPVr7LYJ9m3Y2Gos2NbLF0wqVSu2U33tsPq16OrGpRxut9vd2Inz8vKUkZFhSUOacmI29uAMVLeU3dsXSFZfWHxxgQ/H/eJPvjgGfB2gvt7noRqgVtw0XO22t3pbN5R7AQ1QLlQAwkFje2tw9XwdqD4L0NzcXDmdTp81DAAAO3O5XMrMzKxzXJMCFAAAXMQ3EQEAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAGCFAAAAwQoEAArF69WjfccINatWqlLl26aNu2bTp//rzGjRun1NRUORwO5eTkeM3z6aefavDgwYqNjVVqaqrXuNLSUk2cOFHt27dXbGysMjMz9dVXX/lvhYAwRIACfrZlyxY9+eSTeuutt3TmzBl99tln6ty5sySpf//+WrlypZKTk6+Yr1WrVnrwwQf1yiuvXDGuoqJCffv2VV5enk6ePKkpU6bozjvvVEVFheXrA4QrflAb8LN+/fpp2rRpmjZtWr3TpKSkaOXKlRo0aNAV4z7++GP9x3/8h4qKihp8ndatW+vTTz9VRkbGVbYYQF2oQAE/qq2t1TfffKNjx46pa9euSklJ0cyZM3X27Fmfvk5+fr7Onz+vrl27+nS5AP6FAAX86IcfflB1dbXWrFmjbdu2KT8/Xzt27NCLL77os9coLy/X/fffr+eff16xsbE+Wy4AbwQo4EdRUVGSpFmzZumaa65R27ZtNWfOHG3YsMEnyz979qxGjhypn/3sZ3r66ad9skwAdSNAAT+Kj49XSkqKHA6Hz5d97tw53X333br22mv1u9/9zufLB+CNAAX8bOrUqXr99ddVWlqqU6dO6be//a1GjBgh6WIIulwuSdL58+flcrn0z+f8Lly4IJfLperqarndbrlcLp0/f16SVF1drXHjxikqKkorVqxQRASnNmA1nsIF/Ky6ulqPPvqo/vjHP8rpdGrChAlauHChnE6nUlNTdfDgQa/pDxw4oNTUVOXk5Gjw4MFe4wYOHKicnBxt3bpVgwYNUlRUlFd4bty4UQMGDPDLegHhhgAFAMAA/TwAABggQAEAMECAAgBggAAFAMBAs6ZMnJubK6fTaVVbAACwFZfLpczMzDrHNSlAnU4nX0wNAAgbeXl59Y6jCxcAAAMEKAAABghQAAAMEKAAABho0kNECE2xM5Z7/n166YMBbAkABA8CFF4uDVOJQAWA+tCFCwCAAQIUAAADBCgAAAYIUAAADPAQEQAEGZ6ctwcqUAAADBCgAAAYoAsXAIIYn90OHCpQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGCBAAQAwwHfhhqnLvz8zUPhZJuDH2eV8hTcqUAAADFCBwjaoRgEEEwIUDfJ1qNEVBViLG1H/IUBhzA4nKr+FCCBQCFBYzp9Vpx1CHWa4GUKwIUDhE1Z39XIxRagI95u8UDq3CVD4HO9zwhdCKWg4J+oXzPs5LAM0lO6A/MkuF4HGtsOf+5ljKnAaOh5M9kNj96Uv9nlDy7DL+XYpjnNvYRmgl/P1CWhHdjwZm8IX7a9vGaGyj4OR6X41vYm6Wg0tL9jPMRONrR5DddsQoE1g0tXQlAOnvrtPLvDWauw+unw/mFwUrL6Dt+PNoJU3P/4QqIfggpnV62GX66PD7Xa7GztxXl6eMjIyfPbiphcuK1/LjsJ9/eHNijt9f3Zvw3+C+drR2BtWqwO0odwLigo03E9A3nfApaw4H+xyR4/As8v11o7POlwuKAIU3uxygCP0mXYJc4zaQ7i/R2m1JnXh5ubmyul0WtkeAABsw+VyKTMzs85xTQpQAABwET9nBgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAhb79ttvNWTIEMXGxqpr165at26dJOn8+fMaN26cUlNT5XA4lJOT4zVfWVmZpkyZonbt2qldu3aaN2+e1/jBgwcrMTFRrVu3Vq9evbR+/Xqv8a+//ro6deqk1q1bq0+fPvr888+tXE0g7BCggIVqamo0atQojRgxQidPntSbb76pSZMmae/evZKk/v37a+XKlUpOTr5i3tmzZ6uqqkpFRUX6+uuv9fbbb+utt97yjF+0aJFKSkpUXl7uWW5JSYkk6auvvtJTTz2lNWvW6PTp05o2bZpGjx6t2tpa/6w4EAYIUMBC3333nY4eParZs2crMjJSQ4YMUWZmpt5++2395Cc/0WOPPab+/fsrMjLyink/+OADPfHEE2rZsqVSU1M1bdo0LV++3DO+Z8+eatasmSTJ4XCourpahw8fliQVFRUpPT1dGRkZcjgcmjx5so4fP67S0lL/rDgQBghQwEJut7vOYbt3727y/HXNN2LECDmdTv30pz/VoEGD1KdPH0nS8OHDVVtbq6+++kq1tbVavny5br755jorXQBmCFDAQmlpaWrXrp1eeeUVVVdX66OPPtLWrVtVVVX1o/MOGzZML7/8ss6cOaN9+/Zp+fLlV8z35z//WWfOnNGGDRuUlZWliIiLp3RMTIzGjh2r/v37q0WLFpo/f77efPNNORwOS9YTCEcEKGCh5r0qGzgAABVKSURBVM2b63//93/14YcfKjk5Wa+99pomTJiglJSUH5138eLFioqKUrdu3TRq1ChNnDixzvmaN2+u4cOHa/PmzXr//fclScuWLdPy5ctVUFCg8+fPa+XKlRoxYoSOHj3q83UEwhUBClisZ8+e2rp1q06cOKHNmzdr//79uvXWW390voSEBK1atUrff/+9CgoKdOHChQbnq6mpUWFhoSRp586dGjlypLp3766IiAgNGzZM11xzjb744gufrRcQ7ghQwGK7du2Sy+VSVVWVXn31VZWUlOiBBx6QJJ07d04ul0vSxY+1uFwuz/uehYWFOnHihGpra7Vx40a9+eabevbZZyVdfDhp48aNOnv2rKqrq7Vy5Up99tlnGjhwoCSpb9+++vDDD7V//3653W5t2bJFe/fu1Y033uj/DQCEqGaBbgAQ6t5++20tW7ZM1dXVGjBggLZs2aIWLVpIkq6//nodPHhQkpSVlSVJOnDggFJTU5WXl6fHHntMZWVl6t69u1atWqX09HRJFx8omjdvnvbs2aPIyEh169ZNf/rTn3TLLbdIkiZPnqzCwkINGjRIp06dUkpKin73u98pLS0tAFsACE0Od12PCQIAgAbRhQsAgAECFAAAAwQoAAAGCFAAAAw06Snc3NxcOZ1Oq9oCAICtuFwuZWZm1jmuSQHqdDqVkZHhk0YBAGB3eXl59Y6jCxcAAAMEKAAABghQAAAM8FV+CBuxM/71Y9Snlz4YwJYACAVUoAAAGCBAAQAwQIACAGCAAAUAwAABCgCAAQIUAAADBCgAAAb4HChC1qWf+wQAX6MCBQDAAAEKAIABunABP7q8W5mvFASCFwEKAD7GjVJ4oAsXAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYICPsQCAxS79WAsfaQkdBChgMb6TFwhNdOECAGCAChRhiS41AFeLAAUCiCAHghdduAAAGCBAAQAwQBcuQgpPvALwFwIUAHyAm7fwQ4AiqNn1omXXdgHwHQIU8AECEwg/BCgA+BEfXQodBChgyNdV5+XL4+Jqb/Q6gACF5Rq60JiEBBcu36Mqqh/HG+pDgCIoLp5WXsR8HfC+Ul+77LqP6kNlXT+2TXBzuN1ud2MnzsvLU0ZGhs9ePBgu3I1l5cXO9CRraPuaBJLJ6wa7S9fZrutlZRXvz31ueq6Eag9HsF8T62N67AXqhrKh3AuKAG3sCdJQ0PgirO1yYl3KF8Fo+lr+el00LJhDoiG+Pt44fsODrwPVZwGam5srp9Pps4YBAGBnLpdLmZmZdY5rUoACAICL+DJ5AAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGCBAAQAwQIACAGCAAAUAwAABCgCAAQIUsFhRUZHuuOMOxcfHKzk5WTNnzlRNTY2+/PJL/eIXv1BCQoISExM1fvx4lZSUeOY7d+6cpk+frqSkJCUkJGjkyJEqLi72jP/iiy906623KiYmRj179tTnn3/u9brHjh3Tv//7vysuLk7x8fG67777/LbOQDggQAGLPfzww2rXrp1KSkqUn5+vrVu3asmSJTp16pQeeughFRUV6eDBg4qJidHUqVM98y1atEh//etftWvXLh09elRxcXGaNWuWJOnkyZO666679Ktf/UplZWV64oknNHLkSJ06dcoz/5gxY5ScnKyDBw+qtLRUjz/+uN/XHQhlBChgsQMHDmjChAlyOp1KTk7WsGHDVFBQoOHDh2v8+PFq3bq1WrZsqZkzZyo3N9drvqysLCUlJcnpdOree+9VQUGBpIvVZ1JSksaPH6/IyEhNmjRJiYmJWrt2rSTpo48+0uHDh/XKK68oNjZWzZs3V+/evQOy/kCoIkABiz366KNavXq1qqqqVFxcrI0bN2rYsGFXTPfZZ58pPT3d8/9p06YpNzdXR48eVVVVlVatWqXhw4dLktxut9xut9f8brdbu3fvliR9+eWXuv766zVlyhS1adNGffv21datWy1cSyD8EKCAxQYOHKiCggK1bt1aKSkp6tOnj+6++26vaXbt2qUFCxbolVde8Qzr3r27OnbsqGuvvVatW7fWt99+q7lz50qS+vXrp6NHj+qdd95RdXW1srOzVVhYqKqqKknSkSNH9NFHH2nw4MH6/vvv9ctf/lKjRo3S8ePH/bfiQIgjQAELXbhwQVlZWRozZowqKyt1/PhxnTp1Sk8++aRnmn379mn48OFatGiRBgwY4Bk+Y8YMuVwunThxQpWVlRozZoynAm3Tpo3Wr1+vX//610pKStKmTZs0dOhQpaSkSJKioqKUmpqqadOmqXnz5rr33nvVoUMHry5iAFeHAAUsdPLkSR0+fFgzZ85UixYt1KZNG02dOlUbNmyQJB08eFBDhw7Vc889p/vvv99r3p07d+qBBx5QQkKCWrRooVmzZunrr7/2VJEDBw7U3/72N508eVJvv/22/v73v+vWW2+VJPXs2VMOh8O/KwuEGQIUsFDbtm3VqVMnLV26VDU1NSorK1N2drZ69eql4uJiDRkyRI888oimT59+xbx9+/bVihUrdPr0aVVXV2vJkiVq37692rZtK0nasWOHqqurVV5erscff1wpKSnKysqSJI0ePVqnTp1Sdna2amtrtWbNGhUXFyszM9Ov6w+EMgIUsNjatWu1adMmJSYmqmvXrmrWrJl+85vfaNmyZdq/f7/mz5+v6Ohoz98/vfrqq3I6nerWrZsSExO1YcMGrVu3zjN+4cKFatu2rTp06KCSkhKvcQkJCXr//ff16quvKjY2Vi+//LLWr1/vCV8AV8/hvvxRPgAA8KOoQAEAMECAAgBggAAFAMAAAQoAgAECFAAAA82aMnFubq6cTqdVbQEAwFZcLle9n59uUoA6nU5lZGT4pFEAANhdXl5evePowgUAwAABCgCAgSZ14QKhInbGcs+/Ty99MIAtARCsqEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAG+TB5h49IvkAeAq0WAAn50eYjzSzBA8CJAEfYINQAmeA8UAAADVKBAAxr64W1+lBsIbwQo0EgNPYRENzAQfghQwGI8/QuEJt4DBQDAAAEKAIABunCBAOJBJCB4EaDAZYL5PUsCGfAfAhSwQDCHMIDGIUCBIEdYA4FBgAI2wWdJgeBCgAI2VV9lSbAC9kCAIqhRtQEIFD4HCgCAASpQBJ3GPjQT7g/XUJ0D1iJAgSBjxY0Bnx8Fmo4ARVCg6rx6jQ1JwjR0+GJfNnROhfvxETYBykEA/IvpDQnnSvCyYl+G+81W2ARoQ8L9IDBl8jGLxt7IUEnaUzh8tMaKm207XmPsco7Zcds0lm0D1BcHsckB0th5fNEG06BpyNUegHY5qRBc7FqpmnRb+2J5jV1GYzXltQJ1Dvvi5rih7WvHmzeH2+12N3bivLw8ZWRk+OzFfR0SXPwbj2oPdmDFTWSg+POcCqXt5mu+DtSGcq9JAZqbmyun0+mzhgEAYGcul0uZmZl1jmtSgAIAgIv4JiIAAAwQoAAAGCBAAQAwQIACAGCAAAUAwAABCgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhTwozfeeEN9+vRRixYt9MADD3iN+8tf/qK0tDS1bNlSgwcP1sGDB73Gb9++Xbfffruio6OVlJSkRYsWecYVFRVp8ODBatmypdLS0vTxxx/7Y3WAsEaAAn7Uvn17Pfvss3rwwQe9hh8/flxjxozRCy+8oJMnT6pPnz665557vMYPGzZM//mf/6kTJ05o3759+rd/+zfP+IkTJ6p37946ceKEXnrpJY0bN07Hjh3z23oB4Ygf1AYC4Nlnn9WRI0f0hz/8QZL05ptv6g9/+IO++OILSVJlZaXatm2rHTt2KC0tTc8884wOHz6st99++4pl7d27VzfddJOOHz+umJgYSdKAAQN03333afr06X5bJyDcUIECNlBQUKBevXp5/t+qVSt16dJFBQUFkqQvv/xSCQkJ6tevn9q1a6eRI0fq0KFDnnk7d+7sCU9J6tWrl2deANYgQAEbqKioUGxsrNew2NhYnTlzRpJ05MgRZWdna9GiRTp06JA6deqkiRMnNmpeANZoFugGAJCio6NVXl7uNay8vNxTVUZFRWn06NHq27evJOn5559X27Ztdfr06R+dF4A1qEABG0hPT9fOnTs9/6+srFRhYaHS09MlST179pTD4fCM/+e/3W630tPTtX//fq+Kc+fOnZ55AViDAAX8qKamRi6XS7W1taqtrZXL5VJNTY1Gjx6t3bt367333pPL5dKCBQvUs2dPpaWlSZKmTp2qdevWKT8/X9XV1XrhhRfUv39/xcXFqXv37rr55ps1f/58uVwurVu3Trt27dLYsWMDvLZAiHMD8Jvnn3/eLcnr7/nnn3e73W73li1b3Ndff73b6XS6Bw4c6D5w4IDXvEuWLHG3b9/eHRcX5x4xYoT70KFDnnEHDhxwDxw40O10Ot3du3d3b9myxY9rBYQnPsYCAIABunABADBAgAIAYIAABQDAAAEKAICBJn2RQm5urpxOp1VtAWChHYeOe/7du2Pbesdd6vLpEH7qOzYuF6rHisvlUmZmZp3jmhSgTqdTGRkZPmkUAP8asmy559+nl2bVO+5Sl0+H8FPfsXG5UD1W8vLy6h3HV/kBQS52xqXB+GADUwLwJd4DBQDAABUoEGQurTgBBA4VKAAABghQAAAM0IULhCi6egFrUYECAGCAClR8DAAA0HRhGaB0bQEArhZduAAAGAjLChQId/TCAFePChQAAAMEKAAABujCBQB40L3feFSgAAAYoAK9zOV3X3wuFMGE6gHwHypQAAAMEKAAABggQAEAMECAAgBggAAFAMAAAQoAgAECFAAAAwQoAAAG+CIFAPXii0WA+hGgP+LSCwgXDwDAPxGgQBDgK/oA+yFAAQBXLRx763iICAAAA2FTgdIFBgD+ES4Pn4VNgALBhps++AvHmhkCFECjheP7XEB9CNAm4OIBKwVbFdBQezk/EA4IUMCPwuW9IdhfsN2w2REBClisoQsVF7HQxI1SeHC43W53YyfOy8tTRkaGz17cn12iVl+owvEEaez+C8eub4KxfnY8BnxxjPpin/ti29j92PP1/rf6ZqWh3AupCjSQB059r335zmxsGy+dzy7vNTW2kmpsmF6uoXUO1Ho2tk12v2jZSaBuqBq7j+x4HYE92aYCvZzJicXBZ6ax29ou29c0uOpbT7usF7yFQzUWjqzer1SgTcAJYi07bl/TNtlxXVA/094KhCY77ucmVaC5ublyOp1WtgcAANtwuVzKzMysc1yTAhQAAFzEl8kDAGCAAAUAwAABCgCAAQIUAAADBCgAAAYIUAAADBCgAAAYIEABADBAgAIAYIAABQDAAAEKAIABAhQAAAMEKAAABghQAAAMEKCAhd544w316dNHLVq00AMPPOAZfv78eY0bN06pqalyOBzKycnxmq+srExTpkxRu3bt1K5dO82bN88z7tChQ4qOjvb6czgceu211yRJOTk5ioiI8BqfnZ3th7UFwkuzQDcACGXt27fXs88+q82bN+vs2bNe4/r376/HHntM48ePv2K+2bNnq6qqSkVFRSotLdXPf/5zXXfddZo6dao6duyoiooKz7QHDhxQ165dNXbsWK/XPXLkiHUrBoAABaw0ZswYSdI333zjFWg/+clP9Nhjj0mSIiMjr5jvgw8+0MaNG9WyZUulpqZq2rRpWr58uaZOnXrFtCtWrNDtt9+u1NRUa1YCQJ3owgVsyu12e/179+7ddU63YsUKTZkyxWtYaWmpkpKS1KlTJ82ePVuVlZWWthUIRwQoYEPDhg3Tyy+/rDNnzmjfvn1avny5qqqqrphu27Zt+uGHHzRu3DjPsLS0NOXn56ukpESffPKJ8vLyNGfOHH82HwgLBChgQ4sXL1ZUVJS6deumUaNGaeLEiUpJSbliuuzsbI0dO1bR0dGeYcnJyerRo4ciIiLUqVMnLVy4UGvWrPFn84GwQIACNpSQkKBVq1bp+++/V0FBgS5cuKBbb73Va5qzZ8/q3XffvaL79nIOh8OrOxiAb/AQEWChmpoa1dTUqLa2VrW1tXK5XGrWrJmaNWumc+fOeYLt/PnzcrlcatGihRwOhwoLCxUXF6e4uDh99NFHevPNN7V161avZa9bt05xcXEaPHiw1/CcnBx17txZHTp00JEjR/TUU09p1KhRfltnIFxQgQIWevHFFxUVFaWXX35ZK1euVFRUlF588UVJ0vXXX6+oqCgVFxcrKytLUVFROnjwoCQpLy9PN910k2JiYvT0009r1apVSk9P91p2dna2Jk+eLIfD4TV8+/btuu2229SqVSv169dPN954oxYvXuyfFQbCiMNN3w4AAE1GBQoAgAECFAAAAwQoAAAGCFAAAAwQoAAAGGjS50Bzc3PldDqtagsAALbicrmUmZlZ57gmBajT6VRGRoZPGgUAgN3l5eXVO44uXAAADBCgAAAY4LtwAQC2Eztjudf/Ty99MEAtqR8VKAAABghQAAAMEKAAABggQAEAMECAAgBggKdwAQC2cPmTt3ZHBQoAgAECFAAAAwQoAAAGeA8UAXXpex52/KYRAKgPFSgAAAYIUAAADBCgAAAYIEABADBAgAIAYICncOFXwfZNIwBQHypQAAAMEKAAABggQAEAMECAAgBggIeIbIqvuAMAeyNAAYtxMwSEJgJUXOAAwO7seJ0OqQC9/DOGdtnIaBw7niAAUJ+QClBfIIRhpYaOL449ILgQoEEg2C+sfPtQ/dg2QPAiQG2EiykABI+wDFCCCgDsIZivxyEdoMG8YxoSDg/bBHu3NYDQF9IBCgAIbYG82Q76ALW6ygyHas/XQrXy9zeOPYQiX1wf7HKNCfoADXfh0tVJmNhbuByHwKUIUARdOAVDe319h+yLdW6oTXbdjrA3u1SCgRLQAA2GC+Glgq29JoLtIuvP9oZyleXrYzsczhWr2WUbhntINsQ2FWhTLoR236GNPfADuR5WVkiwVmPPFX8+H2BXVraxKaF2te1oyvxXG7bBsF/twuF2u92NnTg3N1dOp9PK9gAAYBsul0uZmZl1jmtSgAIAgIsiAt0AAACCEQEKAIABAhQAAAMEKAAABghQAAAMEKAAABggQAEAMECAAgBggAAFAMDA/wf6bnHeYyXbdQAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<Figure size 576x810 with 9 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from utils import plot_windows_from_data\n",
+    "\n",
+    "k_12kb = 20 # Number of KNNs to be saved later on\n",
+    "targets_12kb = [80503, 43895, 33430, 42575, 6112, 91938, 82896, 1060, 11975]\n",
+    "targets_12kb_ex = 12933\n",
+    "\n",
+    "plot_windows_from_data(data_12kb, window_ids=targets_12kb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Done! Took 85.77 seconds (1.4 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "\"\"\"Compute the CAE latent space\"\"\"\n",
+    "\n",
+    "from utils import get_models, predict\n",
+    "\n",
+    "encoder_12kb, decoder_12kb, autoencoder_12kb = get_models('models/dnase_w-12000_r-100.h5', loss_fn='bce')\n",
+    "\n",
+    "t0 = time()\n",
+    "predicted_12kb, _, latent_12kb = predict(\n",
+    "    encoder_12kb,\n",
+    "    decoder_12kb,\n",
+    "    data_12kb.reshape(data_12kb.shape[0], data_12kb.shape[1], 1)\n",
+    ")\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n",
+    "with h5py.File('data/cae_12kb.h5', 'w') as f:\n",
+    "    f.create_dataset('latent_space', data=latent_12kb, dtype=np.float32)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preprocessing done! Took 115.74 seconds (1.9 minutes).\n",
+      "Done! Took 13.87 seconds (0.2 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "\"\"\"Compute SAX\"\"\"\n",
+    "\n",
+    "from tslearn.piecewise import SymbolicAggregateApproximation\n",
+    "\n",
+    "t0 = time()\n",
+    "sax_12kb = SymbolicAggregateApproximation(n_segments=120, alphabet_size_avg=10)\n",
+    "sax_data_12kb = sax_12kb.fit_transform(data_12kb)\n",
+    "print('Preprocessing done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "# t0 = time()\n",
+    "# N = data.shape[0]\n",
+    "# dist = np.zeros(N)\n",
+    "# target = sax_data_12kb[80503]\n",
+    "# for i in range(N):\n",
+    "#     dist[i] = sax_12kb.distance_sax(target, sax_data_12kb[i])\n",
+    "# print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Importing the dtw module. When using in academic works please cite:\n",
+      "  T. Giorgino. Computing and Visualizing Dynamic Time Warping Alignments in R: The dtw Package.\n",
+      "  J. Stat. Soft., doi:10.18637/jss.v031.i07.\n",
+      "\n",
+      "Preprocessing:\n",
+      "0:0\n",
+      "10000:28\n",
+      "20000:30\n",
+      "30000:34\n",
+      "40000:34\n",
+      "50000:34\n",
+      "60000:34\n",
+      "70000:39\n",
+      "80000:48\n",
+      "90000:49\n",
+      "100000:49\n",
+      "110000:52\n",
+      "120000:52\n",
+      "0\n",
+      "1\n",
+      "2\n",
+      "3\n",
+      "4\n",
+      "5\n",
+      "6\n",
+      "7\n",
+      "8\n",
+      "9\n",
+      "10\n",
+      "11\n",
+      "12\n",
+      "13\n",
+      "14\n",
+      "15\n",
+      "16\n",
+      "17\n",
+      "18\n",
+      "19\n",
+      "20\n",
+      "21\n",
+      "22\n",
+      "23\n",
+      "24\n",
+      "25\n",
+      "26\n",
+      "27\n",
+      "28\n",
+      "29\n",
+      "30\n",
+      "31\n",
+      "32\n",
+      "33\n",
+      "34\n",
+      "35\n",
+      "36\n",
+      "37\n",
+      "38\n",
+      "39\n",
+      "40\n",
+      "41\n",
+      "42\n",
+      "43\n",
+      "44\n",
+      "45\n",
+      "46\n",
+      "47\n",
+      "48\n",
+      "49\n",
+      "50\n",
+      "51\n",
+      "Preprocessing done. Took 28.18 seconds (0.5 minutes).\n",
+      "Target #0 done! Took 11.02 seconds (0.2 minutes).\n",
+      "Target #1 done! Took 11.10 seconds (0.2 minutes).\n",
+      "Target #2 done! Took 10.90 seconds (0.2 minutes).\n",
+      "Target #3 done! Took 10.49 seconds (0.2 minutes).\n",
+      "Target #4 done! Took 10.73 seconds (0.2 minutes).\n",
+      "Target #5 done! Took 10.41 seconds (0.2 minutes).\n",
+      "Target #6 done! Took 10.34 seconds (0.2 minutes).\n",
+      "Target #7 done! Took 10.41 seconds (0.2 minutes).\n",
+      "Target #8 done! Took 10.31 seconds (0.2 minutes).\n",
+      "[ 11975  80854 100423 113956   6129  77520   4669  78275   1762  20047]\n",
+      "Done! Took 123.90 seconds (2.1 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "from Flaskserver.main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "dtw_12kb = np.zeros((data_12kb.shape[0], len(targets_12kb)))\n",
+    "data = np.reshape(data_12kb, (len(data_12kb), len(data_12kb[0]), 1))\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data_12kb)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb):\n",
+    "    t1 = time()\n",
+    "    query = data_12kb[target]\n",
+    "    query = np.reshape(query, (len(data_12kb[0]), 1))\n",
+    "    candidates, distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "    topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Search for window #80503.... done! Took 16.87 seconds (0.3 minutes).\n",
+      "Search for window #43895.... done! Took 16.10 seconds (0.3 minutes).\n",
+      "Search for window #33430.... done! Took 15.50 seconds (0.3 minutes).\n",
+      "Search for window #42575.... done! Took 15.87 seconds (0.3 minutes).\n",
+      "Search for window #6112.... done! Took 16.19 seconds (0.3 minutes).\n",
+      "Search for window #91938.... done! Took 16.08 seconds (0.3 minutes).\n",
+      "Search for window #82896.... done! Took 15.96 seconds (0.3 minutes).\n",
+      "Search for window #1060.... done! Took 17.08 seconds (0.3 minutes).\n",
+      "Search for window #11975.... done! Took 16.38 seconds (0.3 minutes).\n"
+     ]
+    }
+   ],
+   "source": [
+    "from time import time\n",
+    "    \n",
+    "with h5py.File('data/cae_12kb.h5', 'r') as f:\n",
+    "    cae_12kb = f['latent_space'][:]\n",
+    "\n",
+    "    \n",
+    "with h5py.File('data/12kb-similarity-search.h5', 'w') as f:\n",
+    "    f.create_dataset('knn_ae', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
+    "    f.create_dataset('knn_eq', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
+    "    f.create_dataset('knn_sax', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
+    "    f.create_dataset('top_xcorr', shape=(len(targets_12kb), k_12kb), dtype=np.int)\n",
+    "    \n",
+    "    for i, target in enumerate(targets_12kb):\n",
+    "        t0 = time()\n",
+    "        print('Search for window #{}'.format(target), end='', flush=True)\n",
+    "        f['knn_ae'][i] = knn(cae_12kb, target, k_12kb, ignore=2)\n",
+    "        print('.', end='', flush=True)\n",
+    "        f['knn_eq'][i] = knn(data_12kb, target, k_12kb, ignore=2)\n",
+    "        print('.', end='', flush=True)\n",
+    "        f['knn_sax'][i] = knn(sax_data_12kb, target, k_12kb, sax=sax_12kb, ignore=2)\n",
+    "        print('.', end='', flush=True)\n",
+    "        f['top_xcorr'][i] = xcorrelation(data_12kb, target, k_12kb, normalize=True, zero_normalize=True, ignore=2)\n",
+    "        print('. done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 3888x2160 with 189 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "import h5py\n",
+    "import json\n",
+    "import matplotlib.pyplot as plt \n",
+    "import numpy as np\n",
+    "\n",
+    "with h5py.File('data/12kb-similarity-search.h5', 'r') as f:    \n",
+    "    knn_ae_12kb = f['knn_ae'][:]\n",
+    "    knn_eq_12kb = f['knn_eq'][:]\n",
+    "    knn_sax_12kb = f['knn_sax'][:]\n",
+    "    top_xcorr_12kb = f['top_xcorr'][:]\n",
+    "\n",
+    "show = 5\n",
+    "\n",
+    "N = (show + 1) * 5\n",
+    "\n",
+    "T = len(targets_12kb)\n",
+    "sz = data_12kb[0].size\n",
+    "\n",
+    "plt.figure(figsize=(6 * T, N))\n",
+    "\n",
+    "ymax = 1.0\n",
+    "\n",
+    "show_predictions = False\n",
+    "\n",
+    "for i, target in enumerate(targets_12kb):\n",
+    "    ax = plt.subplot(N, T, (i + 1))\n",
+    "        \n",
+    "    ax.set_facecolor(\"#eeeeee\")\n",
+    "    \n",
+    "    plt.bar(np.arange(sz), data_12kb[target], color='#000000', width=1.0)\n",
+    "\n",
+    "    plt.ylim(0, ymax)\n",
+    "    plt.xticks([], [])\n",
+    "    plt.yticks([], [])\n",
+    "\n",
+    "    for j, hit in enumerate(knn_ae_12kb[i][:show]):\n",
+    "        plt.subplot(N, T, ((j + 1) * T) + (i + 1))\n",
+    "        plt.bar(np.arange(sz), data_12kb[hit], color='#d24f00', width=1.0) # orange = CAE\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])\n",
+    "        plt.subplots_adjust(top=0.9)\n",
+    "        \n",
+    "    for j, hit in enumerate(topk_dtw[i][:show]):\n",
+    "        plt.subplot(N, T, ((j + 6) * T) + (i + 1))\n",
+    "        plt.bar(np.arange(sz), data_12kb[hit], color='green', width=1.0) # orange = CAE\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])\n",
+    "        plt.subplots_adjust(top=0.9)\n",
+    "\n",
+    "    for j, hit in enumerate(knn_eq_12kb[i][:show]):\n",
+    "        plt.subplot(N, T, ((j + 11) * T) + (i + 1))\n",
+    "        plt.bar(np.arange(sz), data_12kb[hit], color='#008ca8', width=1.0) # blue = EQ\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])\n",
+    "\n",
+    "    for j, hit in enumerate(knn_sax_12kb[i][:show]):\n",
+    "        plt.subplot(N, T, ((j + 16) * T) + (i + 1))\n",
+    "        plt.bar(np.arange(sz), data_12kb[hit], color='#a6227a', width=1.0) # purple = SAX\n",
+    "        plt.ylim(0, ymax)\n",
+    "        plt.xticks([], [])\n",
+    "        plt.yticks([], [])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[5, 6, 7, 8]\n"
+     ]
+    }
+   ],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Done! Took 0.03 seconds (0.0 minutes).\n"
+     ]
+    }
+   ],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/Update test.ipynb b/experiments/Update test.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..9c4e40b88dc61e886cec59a60b83ac1890d77128
--- /dev/null
+++ b/experiments/Update test.ipynb	
@@ -0,0 +1,231 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n",
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n",
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n",
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n",
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n",
+      "/home/dev-laptop/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py:35: RuntimeWarning: divide by zero encountered in double_scalars\n",
+      "  slope = delta / float(length)\n"
+     ]
+    },
+    {
+     "ename": "OSError",
+     "evalue": "Failed to interpret file 'samples.pkl' as a pickle",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mEOFError\u001b[0m                                  Traceback (most recent call last)",
+      "\u001b[0;32m~/miniconda3/envs/pseudo/lib/python3.8/site-packages/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)\u001b[0m\n\u001b[1;32m    446\u001b[0m             \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 447\u001b[0;31m                 \u001b[0;32mreturn\u001b[0m \u001b[0mpickle\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mpickle_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    448\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;31mEOFError\u001b[0m: Ran out of input",
+      "\nDuring handling of the above exception, another exception occurred:\n",
+      "\u001b[0;31mOSError\u001b[0m                                   Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-1-ce70ae319d2e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mgenerator\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mcreate_new\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mcreate_new\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[0;32m~/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py\u001b[0m in \u001b[0;36mcreate_new\u001b[0;34m()\u001b[0m\n\u001b[1;32m    478\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    479\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mmode\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'single'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 480\u001b[0;31m             \u001b[0mgenerator_single\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_samples\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtspan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm_range\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml_min\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdropout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msigma_bs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_gauss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_sin\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0musuage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcategory\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_plot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    481\u001b[0m         \u001b[0;32melif\u001b[0m \u001b[0mmode\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'pair'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    482\u001b[0m             \u001b[0mgenerator_pair\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_samples\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtspan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm_range\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml_min\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdropout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msigma_bs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_gauss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_sin\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmutate_bs_local\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmutate_seg_types\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmutate_deltas\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0musuage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcategory\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_plot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/Dylan/locality-sensitive-hashing-visual-analytics/experiments/generator.py\u001b[0m in \u001b[0;36mgenerator_single\u001b[0;34m(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, usuage, category, n_plot)\u001b[0m\n\u001b[1;32m    292\u001b[0m     \u001b[0msave_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'samples.pkl'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    293\u001b[0m     \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msave_file\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msamples\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 294\u001b[0;31m     \u001b[0msamples\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msave_file\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mallow_pickle\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    295\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    296\u001b[0m     \u001b[0;31m# plot n_plot samples\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/miniconda3/envs/pseudo/lib/python3.8/site-packages/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)\u001b[0m\n\u001b[1;32m    447\u001b[0m                 \u001b[0;32mreturn\u001b[0m \u001b[0mpickle\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mpickle_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    448\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 449\u001b[0;31m                 raise IOError(\n\u001b[0m\u001b[1;32m    450\u001b[0m                     \"Failed to interpret file %s as a pickle\" % repr(file))\n\u001b[1;32m    451\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;31mOSError\u001b[0m: Failed to interpret file 'samples.pkl' as a pickle"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from generator import create_new\n",
+    "\n",
+    "create_new()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "window_data = [npdata[i:i+20] for i in range(0, npdata.shape[0]-20, int(20/4))]\n",
+    "del npdata\n",
+    "data = np.reshape(window_data, (len(window_data), len(window_data[0][0]), len(window_data[0])))\n",
+    "del window_data\n",
+    "data = np.reshape(data, (len(data), len(data[0][0]), len(data[0])))\n",
+    "# data = np.concatenate((data, data))\n",
+    "print(data.shape)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "targets = [43895, 33430, 42575, 1060, 11975]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import sys\n",
+    "from time import time\n",
+    "\n",
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "import importlib\n",
+    "from main import preprocess\n",
+    "import _lsh\n",
+    "\n",
+    "topk_dtw = []\n",
+    "\n",
+    "print('Preprocessing:')\n",
+    "t0 = time()\n",
+    "r,a,sd = preprocess(data, 1730)\n",
+    "print('Preprocessing done. Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sys.path.insert(0, '../Flaskserver')\n",
+    "import _lsh\n",
+    "\n",
+    "t0 = time()\n",
+    "for i, target in enumerate(targets[0:1]):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    print('doing lsh')\n",
+    "    lsh_candidates, lsh_distances, _ = _lsh.lsh(data, query, r, a, sd)\n",
+    "#     topk_dtw.append(candidates)\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "    \n",
+    "# print(candidates[0:10])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.spatial.distance import cdist\n",
+    "from tslearn.metrics import dtw\n",
+    "from time import time\n",
+    "\n",
+    "t0 = time()\n",
+    "for i, target in enumerate(targets):\n",
+    "    t1 = time()\n",
+    "    query = data[target]\n",
+    "    dtw_distances = [dtw(window, query, global_constraint='sakoe_chiba', sakoe_chiba_radius=int(0.05)) for window in data]\n",
+    "    print('Target #{} done! Took {:.2f} seconds ({:.1f} minutes).'.format(i, time() - t1, (time() - t1) / 60))\n",
+    "dtw_candidates = sorted(range(len(dtw_distances)), key=lambda k: dtw_distances[k])\n",
+    "print('Done! Took {:.2f} seconds ({:.1f} minutes).'.format(time() - t0, (time() - t0) / 60))\n",
+    "print(dtw_candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from collections import defaultdict\n",
+    "\n",
+    "dict = defaultdict(int)\n",
+    "for l in range(len(lsh_candidates)):\n",
+    "    for k in range(len(lsh_candidates[0])):\n",
+    "        for i in range(len(lsh_candidates[0][0])):\n",
+    "            dict[lsh_candidates[l][k][i]] += lsh_distances[l][k][i]\n",
+    "sorted_dict = {k: v for k, v in sorted(dict.items(), key=lambda item: item[1])}\n",
+    "candidates = list(sorted_dict.keys())\n",
+    "print(candidates[0:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "accuracy = 0\n",
+    "for index in dtw_candidates[0:20]:\n",
+    "    if index in candidates[0:20]:\n",
+    "        accuracy += 1\n",
+    "print(accuracy)\n",
+    "print(dtw_candidates[0:20])\n",
+    "print(candidates[0:20])\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(len(candidates))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/experiments/__pycache__/DBA_multivariate.cpython-38.pyc b/experiments/__pycache__/DBA_multivariate.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..823bf717a1900cec3f300397f6f1ec7b8a1481b3
Binary files /dev/null and b/experiments/__pycache__/DBA_multivariate.cpython-38.pyc differ
diff --git a/experiments/__pycache__/generator.cpython-38.pyc b/experiments/__pycache__/generator.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bfb74bd787d589ff27318590017d9897dc7b0755
Binary files /dev/null and b/experiments/__pycache__/generator.cpython-38.pyc differ
diff --git a/experiments/__pycache__/utils.cpython-38.pyc b/experiments/__pycache__/utils.cpython-38.pyc
index 852f5dc77ec7f4f7247ae3603a2392e28f746c38..95ceaa445e3e8f75c2833f3a904a01a3709cff61 100644
Binary files a/experiments/__pycache__/utils.cpython-38.pyc and b/experiments/__pycache__/utils.cpython-38.pyc differ
diff --git a/experiments/data/21.csv b/experiments/data/21.csv
new file mode 100644
index 0000000000000000000000000000000000000000..b32f810ea3a22e35971393cb192467019a0d1fed
Binary files /dev/null and b/experiments/data/21.csv differ
diff --git a/experiments/generator.py b/experiments/generator.py
new file mode 100644
index 0000000000000000000000000000000000000000..15cb65660a333b0009ecfbea3827b13573bcac45
--- /dev/null
+++ b/experiments/generator.py
@@ -0,0 +1,484 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Wed Jul 25 09:28:32 2018
+
+@author: dt3t6ux
+"""
+
+import os
+import datetime
+import pickle
+import copy
+import numpy as np
+import matplotlib.pyplot as plt
+from random import sample 
+from sklearn.preprocessing import MinMaxScaler
+#from itertools import izip
+
+
+#%%
+def gen_seg(tspan, seg_0, length, seg_type, delta, f_gauss, f_sin):
+    """
+    generate a single segment
+    input:
+        - tspan: length of the whole time series
+        - seg_0: last value of the last segment
+        - length: length of the segment
+        - seg_type: type of the segment
+        - delta: range of the segment
+    output: 
+        - seg: values in the segment
+        - parameter: slope for linear segment, time constand for pt1 and None for step
+    """
+    # linear segment
+    if seg_type == 0:
+        slope = delta / float(length)
+        seg = np.linspace(seg_0, seg_0+delta, length+1)[1:]
+        parameter = slope
+        
+    # pt1 segment
+    elif seg_type == 1:
+        # time constant
+        T = np.random.uniform(low=1., high=tspan/float(10))
+        seg = np.array([seg_0 + delta*(1-np.exp(-1./T*k)) for k in range(length)])
+        parameter = T
+                
+    # step
+    elif seg_type == 2:
+        seg = np.full(length, seg_0+delta)
+        parameter = seg_0+delta
+    
+    # gaussian distributed noise
+    seg += np.random.normal(0, scale=f_gauss*abs(delta), size=length)
+     
+    # sinusoidal noises
+    n_sin = 5
+    omegas = np.random.uniform(low=20*np.pi/tspan, high=np.pi, size=n_sin) # at least 10 waves, at most with Nyquist rate (2 Hz)
+    phases = np.random.uniform(high=2*np.pi, size=n_sin)
+    for i_sin in range(n_sin):
+        seg += np.random.normal(0, f_sin*abs(delta)) * np.sin(omegas[i_sin]*np.array(range(length))+phases[i_sin])
+    
+    # return
+    return seg, parameter
+
+
+#%%
+def gen_ts(tspan, N, bs_local, m_local, seg_types, deltas, f_gauss, f_sin):
+    """
+    generate a single time series
+    """
+    # initialize time series
+    ts = np.zeros((tspan + 1, N))
+    
+    #% initialize the parameter of each segment
+    parameters = []
+    for i in range(N):
+          parameters.append(np.zeros(m_local[i], dtype=np.float32)) 
+          
+    # loop to generate data in i-th channel
+    for i in range(N):
+
+        #% loop to generate data in j-th segment of i-th channel
+        for j in range(m_local[i]):
+            
+            # indeces
+            b_j_lf = bs_local[i][j]
+            b_j_rt = bs_local[i][j+1]
+            
+            # prepare parameter for gen_seg
+            seg_0 = ts[b_j_lf, i]
+            length = b_j_rt - b_j_lf
+            
+            # run gen_seg
+            seg, parameters[i][j] = gen_seg(tspan, seg_0, length, seg_types[i][j], deltas[i][j], f_gauss, f_sin)
+            
+            # integrate seg in ts
+            ts[b_j_lf+1:b_j_rt+1, i] = seg
+            
+            # for j==0 when seg_type=0
+            if seg_types[i][0]==2:
+                ts[0 ,i] = ts[1, i]
+
+    return ts, parameters
+
+#%% 
+def gen_samples_single(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin):
+    """
+    generate data with single time series per sample
+    return: 
+        samples with
+        - ts: axis values in time series; 0 - sample, axis 1 - time, axis 2 - channel
+        - bs_global: array with global boundaries; axis 0 - sample, axis 1 - channel
+        - bs_local: array with local boundaries; axis 0 - sample, axis 1 - channel
+        - seg_types: array with segment types; axis 0 - sample, axis 1 - channel
+        - parameters: array with time constant / slope / step; axis 0 - sample, axis 1 - channel
+        - scaler
+    """
+    # initialze output data
+    samples = []
+    
+    #% loop to generate each sample
+    for i_sample in range(n_samples):
+                    
+        #% global boundaries
+        
+        # randomly initialize number of global boundaries m_global
+        m_global = int(np.random.uniform(m_range[0], m_range[1]))
+        
+        # randomly pick boundaries, length of segment at least l_min
+        bs_global = np.zeros(m_global+1, dtype=int)
+        sample_pool = np.arange(l_min, tspan-l_min+1)
+        for i_m in range(1, m_global):
+            bs_global[i_m] = 1
+            sample_pool = np.setdiff1d(sample_pool, np.arange(bs_global[i_m]-l_min+1, bs_global[i_m]+l_min))
+        bs_global[-1] = tspan
+        bs_global.sort()
+
+        #% local boundaries
+        
+        # initialize local boundaries
+        bs_local = []
+        
+        # dropout
+        bs_local_drop = [bs_global.copy() for i in range(N)]
+        # loop for do dropout for each global boundary
+        for i_m in range(1, m_global):
+            
+            # choose one channel to be forced to implement the boundary
+            channel_forced = np.random.randint(N)
+            # mark channels to dropout for this boundary i_m as -1
+            for i in range(N):
+                if i == channel_forced:
+                    continue
+                else:
+                    if np.random.random() < dropout:
+                        bs_local_drop[i][i_m] = -1
+        for i in range(N):
+            bs_local_drop[i] = bs_local_drop[i][bs_local_drop[i] != -1]
+            
+        # dispersion 
+        for i in range(N):
+            
+            bs_local.append(bs_local_drop[i] + np.random.normal(0, sigma_bs, size=len(bs_local_drop[i])))
+            scaler_t = MinMaxScaler(feature_range=(0, tspan))
+            bs_local[i] = sorted(np.rint(scaler_t.fit_transform(bs_local[i].reshape(-1, 1)).ravel()).astype(int))
+
+        #% number of boundaries in each channel
+                
+        # initialize segment number of each channel
+        m_local = np.zeros(N)
+        
+        # loop for bounary number in each channel
+        for i in range(N):
+            m_local[i] = len(bs_local[i]) - 1
+            
+        m_local = list(map(int, m_local))
+                        
+        #% segment type of each segment
+        
+        # initialize segment types
+        seg_types = []
+        
+        # loop for segment types in each channel
+        for i in range(N):
+            seg_types.append(np.random.randint(3, size=m_local[i]))
+            
+        #% delta of each segment
+        
+        # initialize the delta of each channel
+        deltas = []
+
+        for i in range(N):
+            deltas.append(np.random.uniform(low=-1., high=1., size=m_local[i]))
+        
+        # generate i_sample-th sample 
+        ts, parameters = gen_ts(tspan, N, bs_local, m_local, seg_types, deltas, f_gauss, f_sin)
+                  
+        # normalize values in the time series to [0, 1]
+        scaler = MinMaxScaler()
+        ts = scaler.fit_transform(ts)  
+        
+        # delete start and end time point as boundaries
+        bs_global = bs_global[1:-1]
+        bs_local = [bs_local[i][1:-1] for i in range(len(bs_local))]
+
+        samples.append({'ts':ts.astype(np.float32), 'bs_global':bs_global, 'bs_local':bs_local, 'seg_types':seg_types, 'deltas':deltas,'parameters':parameters, 'scaler':scaler})
+    
+    return samples
+
+
+#%% 
+def gen_samples_pair(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, mutate_bs_local, mutate_seg_types, mutate_deltas):
+    """
+    generate data with paired time series per sample
+    return: 
+        samples with      
+        - ts: axis values in time series; 0 - sample, axis 1 - time, axis 2 - channel
+        - bs_global: array with global boundaries; axis 0 - sample, axis 1 - channel
+        - bs_local: array with local boundaries; axis 0 - sample, axis 1 - channel
+        - seg_types: array with segment types; axis 0 - sample, axis 1 - channel
+        - parameters: array with time constant / slope / step; axis 0 - sample, axis 1 - channel
+        - scaler
+    """
+    # generate measurement data
+    samples_measurement = gen_samples_single(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin)
+    
+    # initialze simulation data
+    samples_simulation = []
+        
+    # loop to generate simulation data
+    for i_sample in range(n_samples):
+        
+        # extract bs_global
+        bs_global = samples_measurement[i_sample]['bs_global']
+        
+        # mutate bs_local
+        bs_local = copy.deepcopy(samples_measurement[i_sample]['bs_local'])
+        for i in range(len(bs_local)):
+            bs_local[i].insert(0, 0)
+            bs_local[i].append(tspan)
+        bs_local = [bs_i + np.random.normal(0, mutate_bs_local, size = len(bs_i)) for bs_i in bs_local]
+        scaler_t = MinMaxScaler(feature_range=(0, tspan))
+        bs_local = [sorted(np.rint(scaler_t.fit_transform(bs_local_i.reshape(-1, 1)).ravel()).astype(int)) for bs_local_i in bs_local]
+        m_local = np.array(map(len, bs_local)) - 1
+        
+        # mutate seg_types
+        seg_types = samples_measurement[i_sample]['seg_types']
+        for i in range(N):
+            m_i = len(seg_types[i])
+            for j in range(m_i):
+                if np.random.random() < mutate_seg_types:
+                    seg_types[i][j] = np.random.randint(3)
+
+        # mutate deltas
+        deltas = samples_measurement[i_sample]['deltas']
+        for i in range(N):
+            m_i = len(deltas[i])
+            for j in range(m_i):
+                deltas[i][j] += np.random.uniform(low=-mutate_deltas*deltas[i][j], high=mutate_deltas*deltas[i][j])
+        
+        # generate i_sample-th sample for simulation
+        ts, parameters = gen_ts(tspan, N, bs_local, m_local, seg_types, deltas, f_gauss, f_sin)
+                
+        # normalize values to [0, 1]
+        scaler = samples_measurement[i_sample]['scaler']
+        ts = scaler.transform(ts)
+        
+        # delete start and end time point as boundaries
+        bs_local = [bs_local[i][1:-1] for i in range(len(bs_local))]
+        
+        # assenble data for simulation in a variable samples_simulation
+        samples_simulation.append({'ts':ts.astype(np.float32), 'bs_global':bs_global, 'bs_local':bs_local, 'seg_types':seg_types, 'deltas':deltas,'parameters':parameters, 'scaler':scaler})
+        
+    # integrate simulation in samples
+    #samples = [{'measurement':sample_measurement_i, 'simulation':sample_simulation_i} for sample_measurement_i, sample_simulation_i in izip(samples_measurement, samples_simulation)]
+    
+    return samples
+
+#%%     
+def generator_single(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, usuage, category, n_plot):
+    """
+    generate and save data with single time series per sample
+    output: 
+        - samples data.pickle 
+    """
+    
+    # generate data
+    samples = gen_samples_single(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin)
+    
+    # save data
+    # for test
+#    save_folder = os.path.join('..', 'data', 'single_'+usuage, category, category+'_' + 'mixed' + '_' + str(N) + '_' + datetime.datetime.now().strftime("%Y_%m_%d_%H%M%S"))
+    save_file = 'samples.pkl'
+    np.save(save_file, np.array(samples))
+    samples = np.load(save_file, allow_pickle=True)
+    
+    # plot n_plot samples
+    for i_plot in n_plot:
+        t = np.arange(tspan+1)
+
+        sample_i = samples[i_plot]
+        ts = sample_i['ts']
+        bs_global = sample_i['bs_global']
+        bs_local = sample_i['bs_local']
+        
+        fig = plt.figure()
+
+        for i in range(N):
+            
+            # plot i-th channel of the time series
+            plt.plot(t, ts[:,i], label='Channel '+str(i+1))
+            
+            # plot local boundaries in i-th channel
+            b_values_i = ts[bs_local[i], i]
+            plt.scatter(bs_local[i], b_values_i)
+        
+        # plot global boundaries
+        for b_global in bs_global:
+            plt.axvline(x=b_global, color = 'y', ls = '--')
+        
+        fig.legend(loc=9, bbox_to_anchor=(0.5, 1), ncol=N)
+        plt.xlabel('Time') 
+        plt.ylabel('Values')
+        plt.title('Sample '+str(i_plot), pad=40)
+        plt.grid(True)
+        plt.show()
+        plt.close()
+
+  
+#%% generate and save data for comparator    
+def generator_pair(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, mutate_bs_local, mutate_seg_types, mutate_deltas, usuage, category, n_plot):
+    """
+    generate and save data for comparator
+    output: 
+        - data.pickle: samples
+    """
+    
+    # generate data
+    samples = gen_samples_pair(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, mutate_bs_local, mutate_seg_types, mutate_deltas)
+    
+    # save data
+    # for test
+    # save_folder = os.path.join('..', '..', 'data', 'pair_'+usuage, category, category+'_' + 'mixed' + '_' + str(N) + '_' + datetime.datetime.now().strftime("%Y_%m_%d_%H%M%S"))
+    # os.mkdir(save_folder)
+    np.save('samples', np.array(samples))
+    save_file = 'samples.pkl'
+    # with open(save_file, 'w') as f:
+    #     pickle.dump(samples, f)
+    #
+    # # load data
+    # with open(save_file, 'r') as f:
+    #     samples = pickle.load(f)
+        
+    # plot n_plot samples
+    t = np.arange(tspan+1)
+    for i_plot in n_plot:
+        
+        fig = plt.figure()
+
+        sample_i = samples[i_plot]
+        sample_measurement_i = sample_i['measurement']
+        sample_simulation_i = sample_i['simulation']
+        
+        bs_global = sample_measurement_i['bs_global']
+
+        ts_measurement = sample_measurement_i['ts']
+        bs_local_measurement = sample_measurement_i['bs_local']
+        
+        ts_simulation = sample_simulation_i['ts']
+        bs_local_simulation = sample_simulation_i['bs_local']
+        
+        for i in range(N):
+            
+            ax = plt.subplot(N, 1, i+1)
+            
+            # plot i-th channel of the time series
+            plt.plot(t, ts_measurement[:,i])
+            plt.plot(t, ts_simulation[:,i])
+            
+            # plot global boundaries
+#            for b_global in bs_global:
+#                plt.axvline(x=b_global, color = 'y', ls = '--')
+
+            # values of time series at boundaries in i-th channel
+            b_values_measurement_i = ts_measurement[bs_local_measurement[i], i]
+            b_values_simulation_i = ts_simulation[bs_local_simulation[i], i]
+            
+            # plot local boundaries in i-th channel
+            plt.scatter(bs_local_measurement[i], b_values_measurement_i)
+            plt.scatter(bs_local_simulation[i], b_values_simulation_i)
+            
+            if i < N-1:
+                plt.setp(ax.get_xticklabels(), visible=False)
+            plt.ylabel('Channel '+str(i+1))
+            plt.grid(True)
+        
+        fig.legend(('measurement', 'simulation'), loc=9, bbox_to_anchor=(0.5, 1), ncol=2)
+        plt.xlabel('time') 
+        plt.suptitle('Sample '+str(i_plot), y=1.05)
+        plt.show()
+        plt.close()
+        
+        
+#%% main program
+def create_new():
+    
+    #% config (only modify this part for generator)
+    
+        # number of time series to generate
+        n_samples = int(1e1)
+        
+        # duration of time
+        # t_begin = 0, t_end = tspan; default 99 (0 ~ 99s)
+        tspan = 120
+        
+        # number of channels
+        N = 3
+        
+        # range of global segment number m_global
+        # HACK: large l_min and m_range at the same time may cause conflict
+        # default (3, 10) for single_analyse_cnn, (3, 6) for single_compare_cnn, (3, 5) for other pair
+        m_range=(3, 6)
+        
+        # minimum length of a segment
+        # HACK: large l_min and m_range at the same time may cause conflict
+        # default 5 for single_analyse_cnn, 10 for pair
+        l_min = 10
+ 
+        # rate of dropout 
+        # neglection of boundaries, not dropout for NN training; default 0.2
+        dropout = 0.2
+         
+        # standard deviation of boundary dispersion
+        # default 0.5
+        sigma_bs = 0.5
+        
+        # factor for the amplitude of sinusoidal noises 
+        # default 0.01
+        f_sin = 0.01
+        
+        # factor for the amplitude of gaussian distributed noises 
+        # default 0.01
+        f_gauss = 0.01
+        
+        # factor for displacements of local boundaries
+        # default 2
+        mutate_bs_local = 2
+        
+        # probability for mutation of segment types
+        # default 0.1 (10%)
+        mutate_seg_types = 0.1 
+        
+        # factor for range change of segments 
+        # default 0.2 (20%)
+        mutate_deltas = 0.2 
+        
+        # mode of generator
+        # 'single': one time series per sample for segmentation; 
+        # 'pair': two similar time series per sample for comparason.
+        mode = 'single'
+        
+        # usuage of data
+        # used to generate path to save the generated data
+        # 'analyse_cnn': data used to train the CNN for segmentation; mode must be 'single', default n_samples = 1e6
+        # 'analyse': data used to test the performance of the time series analyser; mode must be 'pair'
+        # 'compare_cnn': data used to train the CNN for identification of segment types; mode must be 'single', default n_sample =   
+        # 'compare': data used to test the performance of time series comparator and interpreter
+        usuage = 'analyse_cnn'
+        
+        # data category
+        # 'train_raw', 'train', 'valid', 'test_raw', 'test', 'debug'; used in the directory and file name if needed
+        category = 'debug'
+        
+        # number of samples to plot after generation of all samples
+        # used to get a quick picture of the generated data; default range(3)
+        n_plot = range(10)
+    
+    #% generation process
+    
+        if mode == 'single':
+            generator_single(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, usuage, category, n_plot)
+        elif mode == 'pair':
+            generator_pair(n_samples, tspan, N, m_range, l_min, dropout, sigma_bs, f_gauss, f_sin, mutate_bs_local, mutate_seg_types, mutate_deltas, usuage, category, n_plot)
+        else:
+            raise ValueError("mode unknown, it can only be 'analyse' or 'compare'")
diff --git a/experiments/samples.pkl b/experiments/samples.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/experiments/samples.pkl.npy b/experiments/samples.pkl.npy
new file mode 100644
index 0000000000000000000000000000000000000000..2c9e45e1dc75939c0448fa97ba763f6fbc23992b
Binary files /dev/null and b/experiments/samples.pkl.npy differ
diff --git a/experiments/utils.py b/experiments/utils.py
index 0dc7a11e38c4b728387bbd43d87615e6e3155c84..19b0333b9dfa969a226598125126a7a02031feb4 100644
--- a/experiments/utils.py
+++ b/experiments/utils.py
@@ -1438,7 +1438,7 @@ def plot_windows_from_data(
                 axis = get_axis(r, c)
 
                 if predictions is None:
-                    axis.bar(x, sampled_wins[i], width=1.0, color="#0E689D")
+                    axis.bar(x, sampled_wins[i][0], width=1.0, color="#0E689D")
                 else:
                     axis.bar(x, sampled_wins[i], width=1.0, color="#808080")
                     axis.bar(x, sampled_wins_pred[i], width=1.0, color="#0E689D", alpha=0.6)
diff --git a/lsh-fast/_lsh.cpp b/lsh-fast/_lsh.cpp
index b830c25edbbcf80adc18e5822181a30e1b854b8d..ca36d04e214350c88ee45c6989d3c50e331fbc15 100644
--- a/lsh-fast/_lsh.cpp
+++ b/lsh-fast/_lsh.cpp
@@ -48,13 +48,13 @@ MOD_INIT(_lsh)
 static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
     PyObject* data_obj = NULL;
     PyObject* query_obj = NULL;
-    PyObject* hash_obj = NULL;
-    double **** hashFunctions;
-    double ** weights = NULL;
+    PyObject* weights_obj = NULL;
+    double *** hashFunctions;
+    double * weights = NULL;
     double*** data;
     double ** query;
-    int * candidates;
-    double * distances;
+    int *** candidates;
+    double *** distances;
     int nrOfCandidates;
     double r;
     double a;
@@ -64,8 +64,10 @@ static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
     PyArray_Descr *descr_float;
     descr_float = PyArray_DescrFromType(NPY_FLOAT64);
 
+    printf("Parsing\n");
+
     /// Parse the input tuple
-    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &hash_obj)) {
+    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &weights_obj)) {
         return NULL;
     }
 
@@ -74,16 +76,20 @@ static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
     int channel_size = (long) PyArray_DIM(data_obj, 2);
     int query_size = (int) PyArray_DIM(query_obj, 0);
 
+    printf("Loading data\n");
     /// Convert data, query and weights to C array
-    npy_intp dims0[3];
-    if (PyArray_AsCArray(&query_obj, (void **)&query, dims0, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims0, 3, descr) < 0) {
+    npy_intp dims1[1];
+    npy_intp dims2[2];
+    npy_intp dims3[3];
+    if (PyArray_AsCArray(&query_obj, (void **)&query, dims2, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims3, 3, descr) < 0) {
+        printf("ERROR\n");
         PyErr_SetString(PyExc_TypeError, "error converting to c array");
         return NULL;
     }
-    if (hash_obj != NULL)
+    if (weights_obj != NULL)
     {
         printf("Using weights");
-        if (PyArray_AsCArray(&hash_obj, (void **)&weights, dims0, 2, descr) < 0) {
+        if (PyArray_AsCArray(&weights_obj, (void *)&weights, dims1, 1, descr) < 0) {
             PyErr_SetString(PyExc_TypeError, "error converting weights to c array");
             return NULL;
         }
@@ -96,17 +102,13 @@ static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
     printf("Dim: %d\n", channel_size);
 
     /// Initialize output parameters
-    hashFunctions = (double ****)malloc(L*sizeof(double***));
+    hashFunctions = (double ***)malloc(L*sizeof(double**));
     for (int l=0;l<L;l++)
     {
-        hashFunctions[l] = (double ***)malloc(K*sizeof(double**));
+        hashFunctions[l] = (double **)malloc(K*sizeof(double*));
         for (int k=0;k<K;k++)
         {
-            hashFunctions[l][k] = (double **)malloc(query_size*sizeof(double*));
-            for (int t=0;t<query_size;t++)
-            {
-                hashFunctions[l][k][t] = (double *)malloc(channel_size*sizeof(double));
-            }
+            hashFunctions[l][k] = (double *)malloc(channel_size*sizeof(double));
         }
     }
 
@@ -116,34 +118,47 @@ static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
         return NULL;
     }
 
-    npy_intp dimscandidates[1] = {nrOfCandidates};
+    npy_intp dimscandidates[3] = {L, K, nrOfCandidates};
     printf("Number of candidates: %d\n", nrOfCandidates);
-    npy_intp dims4[4] = {L, K, query_size, channel_size};
+    npy_intp dims4[4] = {L, K, channel_size};
 
 //    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimscandidates, NPY_INT, (void*)&candidates);
 //    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimsdistance, NPY_DOUBLE, (void*)&distances);
     // https://github.com/suiyun0234/scipy-master/commit/da7dfc7aad8daa7a516e43f4c7001eea7c1a707e
     // https://github.com/fjean/pymeanshift/commit/1ba90da647342184ea7df378d7f21eba257a51d9
-    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_INT);
-    memcpy(PyArray_DATA(numpy_candidates), candidates, dimscandidates[0]*sizeof(int));
-    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
-    memcpy(PyArray_DATA(numpy_distances), distances, dimscandidates[0]*sizeof(double));
-    PyArrayObject* TEST = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
-    memcpy(PyArray_DATA(TEST), distances, dimscandidates[0]*sizeof(double));
-//    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(4, dims4, NPY_DOUBLE);
-//    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
-//    for (int l=0;l<L;l++)
-//    {
-//        for (int k=0;k<K;k++)
-//        {
-//            for (int t=0;t<query_size;t++)
-//            {
-//                memcpy(numpy_hash_functions_data, hashFunctions[l][k][t], channel_size*sizeof(double));
-//                numpy_hash_functions_data += channel_size;
-//            }
-//        }
-//    }
-    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(TEST));// PyArray_Return(numpy_hash_functions));
+    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_INT);
+    int* numpy_candidates_data = (int*)PyArray_DATA(numpy_candidates);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_candidates_data, candidates[l][k], nrOfCandidates*sizeof(int));
+            numpy_candidates_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_DOUBLE);
+    double* numpy_distances_data = (double*)PyArray_DATA(numpy_distances);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_distances_data, distances[l][k], nrOfCandidates*sizeof(double));
+            numpy_distances_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(3, dims4, NPY_DOUBLE);
+    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_hash_functions_data, hashFunctions[l][k], channel_size*sizeof(double));
+            numpy_hash_functions_data += channel_size;
+        }
+    }
+    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(numpy_hash_functions));
 //    Py_XDECREF(data_obj);
 //    Py_XDECREF(query_obj);
 //    Py_XDECREF(hash_obj);
diff --git a/lsh-fast/_lsh_BACKUP_125136.cpp b/lsh-fast/_lsh_BACKUP_125136.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a42602dec8756af5bb18739caaabf73850f9485e
--- /dev/null
+++ b/lsh-fast/_lsh_BACKUP_125136.cpp
@@ -0,0 +1,261 @@
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include "lsh.h"
+#include <math.h>
+
+/* Docstrings */
+static char module_docstring[] = "This module implements fast nearest-neighbor retrieval using LSH.";
+static char lsh_docstring[] = "Calculate the closest neightbours with distances given a query window.";
+
+/* Available functions */
+static PyObject* lsh_lsh(PyObject *self, PyObject *args);
+
+/* Module specification */
+static PyMethodDef module_methods[] = { { "lsh", lsh_lsh, METH_VARARGS, lsh_docstring }, { NULL, NULL, 0, NULL } };
+
+/* Initialize the module */
+#if PY_MAJOR_VERSION >= 3
+#define MOD_ERROR_VAL NULL
+  #define MOD_SUCCESS_VAL(val) val
+  #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+  #define MOD_DEF(ob, name, doc, methods) \
+          static struct PyModuleDef moduledef = { \
+            PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
+          ob = PyModule_Create(&moduledef);
+#else
+#define MOD_ERROR_VAL
+#define MOD_SUCCESS_VAL(val)
+#define MOD_INIT(name) void init##name(void)
+#define MOD_DEF(ob, name, doc, methods) \
+          ob = Py_InitModule3(name, methods, doc);
+#endif
+
+MOD_INIT(_lsh)
+{
+    PyObject *m;
+
+    MOD_DEF(m, "_lsh", module_docstring,
+            module_methods)
+
+    if (m == NULL)
+        return MOD_ERROR_VAL;
+
+    import_array();
+
+    return MOD_SUCCESS_VAL(m);
+}
+
+static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
+    PyObject* data_obj = NULL;
+    PyObject* query_obj = NULL;
+<<<<<<< HEAD
+    PyObject* hash_obj = NULL;
+    double **** hashFunctions;
+    double ** weights = NULL;
+    double*** data;
+    double ** query;
+    int * candidates;
+    double * distances;
+=======
+    PyObject* weights_obj = NULL;
+    double *** hashFunctions;
+    double * weights = NULL;
+    double*** data;
+    double ** query;
+    int *** candidates;
+    double *** distances;
+>>>>>>> mts
+    int nrOfCandidates;
+    double r;
+    double a;
+    double sd;
+    PyArray_Descr *descr;
+    descr = PyArray_DescrFromType(NPY_DOUBLE);
+    PyArray_Descr *descr_float;
+    descr_float = PyArray_DescrFromType(NPY_FLOAT64);
+
+<<<<<<< HEAD
+    /// Parse the input tuple
+    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &hash_obj)) {
+=======
+    printf("Parsing\n");
+
+    /// Parse the input tuple
+    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &weights_obj)) {
+>>>>>>> mts
+        return NULL;
+    }
+
+    /// Get the dimensions of the data and query
+    int data_size = (long) PyArray_DIM(data_obj, 0);
+    int channel_size = (long) PyArray_DIM(data_obj, 2);
+    int query_size = (int) PyArray_DIM(query_obj, 0);
+
+<<<<<<< HEAD
+    /// Convert data, query and weights to C array
+    npy_intp dims0[3];
+    if (PyArray_AsCArray(&query_obj, (void **)&query, dims0, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims0, 3, descr) < 0) {
+        PyErr_SetString(PyExc_TypeError, "error converting to c array");
+        return NULL;
+    }
+    if (hash_obj != NULL)
+    {
+        printf("Using weights");
+        if (PyArray_AsCArray(&hash_obj, (void **)&weights, dims0, 2, descr) < 0) {
+=======
+    printf("Loading data\n");
+    /// Convert data, query and weights to C array
+    npy_intp dims1[1];
+    npy_intp dims2[2];
+    npy_intp dims3[3];
+    if (PyArray_AsCArray(&query_obj, (void **)&query, dims2, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims3, 3, descr) < 0) {
+        printf("ERROR\n");
+        PyErr_SetString(PyExc_TypeError, "error converting to c array");
+        return NULL;
+    }
+    if (weights_obj != NULL)
+    {
+        printf("Using weights");
+        if (PyArray_AsCArray(&weights_obj, (void *)&weights, dims1, 1, descr) < 0) {
+>>>>>>> mts
+            PyErr_SetString(PyExc_TypeError, "error converting weights to c array");
+            return NULL;
+        }
+    }
+
+    int K = ceil(log((log(0.5))/log(1-exp(-2*(0.1)*(0.1)*query_size)))/log((1-exp(-2*(0.1)*(0.1)*query_size))/(0.5)));
+    int L = ceil(log(0.05)/(log(1-pow(1-exp(-2*(0.1)*(0.1)*query_size), K))));
+    printf("K: %d\n", K);
+    printf("L: %d\n", L);
+    printf("Dim: %d\n", channel_size);
+
+    /// Initialize output parameters
+<<<<<<< HEAD
+    hashFunctions = (double ****)malloc(L*sizeof(double***));
+    for (int l=0;l<L;l++)
+    {
+        hashFunctions[l] = (double ***)malloc(K*sizeof(double**));
+        for (int k=0;k<K;k++)
+        {
+            hashFunctions[l][k] = (double **)malloc(query_size*sizeof(double*));
+            for (int t=0;t<query_size;t++)
+            {
+                hashFunctions[l][k][t] = (double *)malloc(channel_size*sizeof(double));
+            }
+=======
+    hashFunctions = (double ***)malloc(L*sizeof(double**));
+    for (int l=0;l<L;l++)
+    {
+        hashFunctions[l] = (double **)malloc(K*sizeof(double*));
+        for (int k=0;k<K;k++)
+        {
+            hashFunctions[l][k] = (double *)malloc(channel_size*sizeof(double));
+>>>>>>> mts
+        }
+    }
+
+    int status = lsh(data, data_size, query_size, channel_size, query, L, K, r, a, sd, candidates, distances, hashFunctions, weights, nrOfCandidates);
+    if (status) {
+        PyErr_SetString(PyExc_RuntimeError, "lsh could not allocate memory");
+        return NULL;
+    }
+
+<<<<<<< HEAD
+    npy_intp dimscandidates[1] = {nrOfCandidates};
+    printf("Number of candidates: %d\n", nrOfCandidates);
+    npy_intp dims4[4] = {L, K, query_size, channel_size};
+=======
+    npy_intp dimscandidates[3] = {L, K, nrOfCandidates};
+    printf("Number of candidates: %d\n", nrOfCandidates);
+    npy_intp dims4[4] = {L, K, channel_size};
+>>>>>>> mts
+
+//    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimscandidates, NPY_INT, (void*)&candidates);
+//    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimsdistance, NPY_DOUBLE, (void*)&distances);
+    // https://github.com/suiyun0234/scipy-master/commit/da7dfc7aad8daa7a516e43f4c7001eea7c1a707e
+    // https://github.com/fjean/pymeanshift/commit/1ba90da647342184ea7df378d7f21eba257a51d9
+<<<<<<< HEAD
+    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_INT);
+    memcpy(PyArray_DATA(numpy_candidates), candidates, dimscandidates[0]*sizeof(int));
+    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
+    memcpy(PyArray_DATA(numpy_distances), distances, dimscandidates[0]*sizeof(double));
+    PyArrayObject* TEST = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
+    memcpy(PyArray_DATA(TEST), distances, dimscandidates[0]*sizeof(double));
+//    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(4, dims4, NPY_DOUBLE);
+//    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
+//    for (int l=0;l<L;l++)
+//    {
+//        for (int k=0;k<K;k++)
+//        {
+//            for (int t=0;t<query_size;t++)
+//            {
+//                memcpy(numpy_hash_functions_data, hashFunctions[l][k][t], channel_size*sizeof(double));
+//                numpy_hash_functions_data += channel_size;
+//            }
+//        }
+//    }
+    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(TEST));// PyArray_Return(numpy_hash_functions));
+=======
+    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_INT);
+    int* numpy_candidates_data = (int*)PyArray_DATA(numpy_candidates);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_candidates_data, candidates[l][k], nrOfCandidates*sizeof(int));
+            numpy_candidates_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_DOUBLE);
+    double* numpy_distances_data = (double*)PyArray_DATA(numpy_distances);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_distances_data, distances[l][k], nrOfCandidates*sizeof(double));
+            numpy_distances_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(3, dims4, NPY_DOUBLE);
+    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_hash_functions_data, hashFunctions[l][k], channel_size*sizeof(double));
+            numpy_hash_functions_data += channel_size;
+        }
+    }
+    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(numpy_hash_functions));
+>>>>>>> mts
+//    Py_XDECREF(data_obj);
+//    Py_XDECREF(query_obj);
+//    Py_XDECREF(hash_obj);
+//    Py_XDECREF(weights);
+//    Py_XDECREF(data);
+//    Py_XDECREF(query);
+//    Py_XDECREF(descr);
+//    Py_XDECREF(descr_float);
+//    Py_XDECREF(query);
+//    Py_XDECREF(numpy_candidates);
+//    Py_XDECREF(numpy_distances);
+//    Py_XDECREF(TEST);
+//    free(candidates);
+//    free(distances);
+//    for (int l=0;l<L;l++)
+//    {
+//        for (int k=0;k<K;k++)
+//        {
+//            for (int t=0;t<query_size;t++)
+//            {
+//                free(hashFunctions[l][k][t]);
+//            }
+//            free(hashFunctions[l][k]);
+//        }
+//        free(hashFunctions[l]);
+//    }
+//    free(hashFunctions);
+    return ret;
+}
diff --git a/lsh-fast/_lsh_BASE_125136.cpp b/lsh-fast/_lsh_BASE_125136.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lsh-fast/_lsh_LOCAL_125136.cpp b/lsh-fast/_lsh_LOCAL_125136.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b830c25edbbcf80adc18e5822181a30e1b854b8d
--- /dev/null
+++ b/lsh-fast/_lsh_LOCAL_125136.cpp
@@ -0,0 +1,175 @@
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include "lsh.h"
+#include <math.h>
+
+/* Docstrings */
+static char module_docstring[] = "This module implements fast nearest-neighbor retrieval using LSH.";
+static char lsh_docstring[] = "Calculate the closest neightbours with distances given a query window.";
+
+/* Available functions */
+static PyObject* lsh_lsh(PyObject *self, PyObject *args);
+
+/* Module specification */
+static PyMethodDef module_methods[] = { { "lsh", lsh_lsh, METH_VARARGS, lsh_docstring }, { NULL, NULL, 0, NULL } };
+
+/* Initialize the module */
+#if PY_MAJOR_VERSION >= 3
+#define MOD_ERROR_VAL NULL
+  #define MOD_SUCCESS_VAL(val) val
+  #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+  #define MOD_DEF(ob, name, doc, methods) \
+          static struct PyModuleDef moduledef = { \
+            PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
+          ob = PyModule_Create(&moduledef);
+#else
+#define MOD_ERROR_VAL
+#define MOD_SUCCESS_VAL(val)
+#define MOD_INIT(name) void init##name(void)
+#define MOD_DEF(ob, name, doc, methods) \
+          ob = Py_InitModule3(name, methods, doc);
+#endif
+
+MOD_INIT(_lsh)
+{
+    PyObject *m;
+
+    MOD_DEF(m, "_lsh", module_docstring,
+            module_methods)
+
+    if (m == NULL)
+        return MOD_ERROR_VAL;
+
+    import_array();
+
+    return MOD_SUCCESS_VAL(m);
+}
+
+static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
+    PyObject* data_obj = NULL;
+    PyObject* query_obj = NULL;
+    PyObject* hash_obj = NULL;
+    double **** hashFunctions;
+    double ** weights = NULL;
+    double*** data;
+    double ** query;
+    int * candidates;
+    double * distances;
+    int nrOfCandidates;
+    double r;
+    double a;
+    double sd;
+    PyArray_Descr *descr;
+    descr = PyArray_DescrFromType(NPY_DOUBLE);
+    PyArray_Descr *descr_float;
+    descr_float = PyArray_DescrFromType(NPY_FLOAT64);
+
+    /// Parse the input tuple
+    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &hash_obj)) {
+        return NULL;
+    }
+
+    /// Get the dimensions of the data and query
+    int data_size = (long) PyArray_DIM(data_obj, 0);
+    int channel_size = (long) PyArray_DIM(data_obj, 2);
+    int query_size = (int) PyArray_DIM(query_obj, 0);
+
+    /// Convert data, query and weights to C array
+    npy_intp dims0[3];
+    if (PyArray_AsCArray(&query_obj, (void **)&query, dims0, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims0, 3, descr) < 0) {
+        PyErr_SetString(PyExc_TypeError, "error converting to c array");
+        return NULL;
+    }
+    if (hash_obj != NULL)
+    {
+        printf("Using weights");
+        if (PyArray_AsCArray(&hash_obj, (void **)&weights, dims0, 2, descr) < 0) {
+            PyErr_SetString(PyExc_TypeError, "error converting weights to c array");
+            return NULL;
+        }
+    }
+
+    int K = ceil(log((log(0.5))/log(1-exp(-2*(0.1)*(0.1)*query_size)))/log((1-exp(-2*(0.1)*(0.1)*query_size))/(0.5)));
+    int L = ceil(log(0.05)/(log(1-pow(1-exp(-2*(0.1)*(0.1)*query_size), K))));
+    printf("K: %d\n", K);
+    printf("L: %d\n", L);
+    printf("Dim: %d\n", channel_size);
+
+    /// Initialize output parameters
+    hashFunctions = (double ****)malloc(L*sizeof(double***));
+    for (int l=0;l<L;l++)
+    {
+        hashFunctions[l] = (double ***)malloc(K*sizeof(double**));
+        for (int k=0;k<K;k++)
+        {
+            hashFunctions[l][k] = (double **)malloc(query_size*sizeof(double*));
+            for (int t=0;t<query_size;t++)
+            {
+                hashFunctions[l][k][t] = (double *)malloc(channel_size*sizeof(double));
+            }
+        }
+    }
+
+    int status = lsh(data, data_size, query_size, channel_size, query, L, K, r, a, sd, candidates, distances, hashFunctions, weights, nrOfCandidates);
+    if (status) {
+        PyErr_SetString(PyExc_RuntimeError, "lsh could not allocate memory");
+        return NULL;
+    }
+
+    npy_intp dimscandidates[1] = {nrOfCandidates};
+    printf("Number of candidates: %d\n", nrOfCandidates);
+    npy_intp dims4[4] = {L, K, query_size, channel_size};
+
+//    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimscandidates, NPY_INT, (void*)&candidates);
+//    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimsdistance, NPY_DOUBLE, (void*)&distances);
+    // https://github.com/suiyun0234/scipy-master/commit/da7dfc7aad8daa7a516e43f4c7001eea7c1a707e
+    // https://github.com/fjean/pymeanshift/commit/1ba90da647342184ea7df378d7f21eba257a51d9
+    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_INT);
+    memcpy(PyArray_DATA(numpy_candidates), candidates, dimscandidates[0]*sizeof(int));
+    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
+    memcpy(PyArray_DATA(numpy_distances), distances, dimscandidates[0]*sizeof(double));
+    PyArrayObject* TEST = (PyArrayObject*)PyArray_SimpleNew(1, dimscandidates, NPY_DOUBLE);
+    memcpy(PyArray_DATA(TEST), distances, dimscandidates[0]*sizeof(double));
+//    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(4, dims4, NPY_DOUBLE);
+//    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
+//    for (int l=0;l<L;l++)
+//    {
+//        for (int k=0;k<K;k++)
+//        {
+//            for (int t=0;t<query_size;t++)
+//            {
+//                memcpy(numpy_hash_functions_data, hashFunctions[l][k][t], channel_size*sizeof(double));
+//                numpy_hash_functions_data += channel_size;
+//            }
+//        }
+//    }
+    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(TEST));// PyArray_Return(numpy_hash_functions));
+//    Py_XDECREF(data_obj);
+//    Py_XDECREF(query_obj);
+//    Py_XDECREF(hash_obj);
+//    Py_XDECREF(weights);
+//    Py_XDECREF(data);
+//    Py_XDECREF(query);
+//    Py_XDECREF(descr);
+//    Py_XDECREF(descr_float);
+//    Py_XDECREF(query);
+//    Py_XDECREF(numpy_candidates);
+//    Py_XDECREF(numpy_distances);
+//    Py_XDECREF(TEST);
+//    free(candidates);
+//    free(distances);
+//    for (int l=0;l<L;l++)
+//    {
+//        for (int k=0;k<K;k++)
+//        {
+//            for (int t=0;t<query_size;t++)
+//            {
+//                free(hashFunctions[l][k][t]);
+//            }
+//            free(hashFunctions[l][k]);
+//        }
+//        free(hashFunctions[l]);
+//    }
+//    free(hashFunctions);
+    return ret;
+}
diff --git a/lsh-fast/_lsh_REMOTE_125136.cpp b/lsh-fast/_lsh_REMOTE_125136.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ca36d04e214350c88ee45c6989d3c50e331fbc15
--- /dev/null
+++ b/lsh-fast/_lsh_REMOTE_125136.cpp
@@ -0,0 +1,190 @@
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include "lsh.h"
+#include <math.h>
+
+/* Docstrings */
+static char module_docstring[] = "This module implements fast nearest-neighbor retrieval using LSH.";
+static char lsh_docstring[] = "Calculate the closest neightbours with distances given a query window.";
+
+/* Available functions */
+static PyObject* lsh_lsh(PyObject *self, PyObject *args);
+
+/* Module specification */
+static PyMethodDef module_methods[] = { { "lsh", lsh_lsh, METH_VARARGS, lsh_docstring }, { NULL, NULL, 0, NULL } };
+
+/* Initialize the module */
+#if PY_MAJOR_VERSION >= 3
+#define MOD_ERROR_VAL NULL
+  #define MOD_SUCCESS_VAL(val) val
+  #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+  #define MOD_DEF(ob, name, doc, methods) \
+          static struct PyModuleDef moduledef = { \
+            PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
+          ob = PyModule_Create(&moduledef);
+#else
+#define MOD_ERROR_VAL
+#define MOD_SUCCESS_VAL(val)
+#define MOD_INIT(name) void init##name(void)
+#define MOD_DEF(ob, name, doc, methods) \
+          ob = Py_InitModule3(name, methods, doc);
+#endif
+
+MOD_INIT(_lsh)
+{
+    PyObject *m;
+
+    MOD_DEF(m, "_lsh", module_docstring,
+            module_methods)
+
+    if (m == NULL)
+        return MOD_ERROR_VAL;
+
+    import_array();
+
+    return MOD_SUCCESS_VAL(m);
+}
+
+static PyObject* lsh_lsh(PyObject* self, PyObject* args) {
+    PyObject* data_obj = NULL;
+    PyObject* query_obj = NULL;
+    PyObject* weights_obj = NULL;
+    double *** hashFunctions;
+    double * weights = NULL;
+    double*** data;
+    double ** query;
+    int *** candidates;
+    double *** distances;
+    int nrOfCandidates;
+    double r;
+    double a;
+    double sd;
+    PyArray_Descr *descr;
+    descr = PyArray_DescrFromType(NPY_DOUBLE);
+    PyArray_Descr *descr_float;
+    descr_float = PyArray_DescrFromType(NPY_FLOAT64);
+
+    printf("Parsing\n");
+
+    /// Parse the input tuple
+    if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &weights_obj)) {
+        return NULL;
+    }
+
+    /// Get the dimensions of the data and query
+    int data_size = (long) PyArray_DIM(data_obj, 0);
+    int channel_size = (long) PyArray_DIM(data_obj, 2);
+    int query_size = (int) PyArray_DIM(query_obj, 0);
+
+    printf("Loading data\n");
+    /// Convert data, query and weights to C array
+    npy_intp dims1[1];
+    npy_intp dims2[2];
+    npy_intp dims3[3];
+    if (PyArray_AsCArray(&query_obj, (void **)&query, dims2, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims3, 3, descr) < 0) {
+        printf("ERROR\n");
+        PyErr_SetString(PyExc_TypeError, "error converting to c array");
+        return NULL;
+    }
+    if (weights_obj != NULL)
+    {
+        printf("Using weights");
+        if (PyArray_AsCArray(&weights_obj, (void *)&weights, dims1, 1, descr) < 0) {
+            PyErr_SetString(PyExc_TypeError, "error converting weights to c array");
+            return NULL;
+        }
+    }
+
+    int K = ceil(log((log(0.5))/log(1-exp(-2*(0.1)*(0.1)*query_size)))/log((1-exp(-2*(0.1)*(0.1)*query_size))/(0.5)));
+    int L = ceil(log(0.05)/(log(1-pow(1-exp(-2*(0.1)*(0.1)*query_size), K))));
+    printf("K: %d\n", K);
+    printf("L: %d\n", L);
+    printf("Dim: %d\n", channel_size);
+
+    /// Initialize output parameters
+    hashFunctions = (double ***)malloc(L*sizeof(double**));
+    for (int l=0;l<L;l++)
+    {
+        hashFunctions[l] = (double **)malloc(K*sizeof(double*));
+        for (int k=0;k<K;k++)
+        {
+            hashFunctions[l][k] = (double *)malloc(channel_size*sizeof(double));
+        }
+    }
+
+    int status = lsh(data, data_size, query_size, channel_size, query, L, K, r, a, sd, candidates, distances, hashFunctions, weights, nrOfCandidates);
+    if (status) {
+        PyErr_SetString(PyExc_RuntimeError, "lsh could not allocate memory");
+        return NULL;
+    }
+
+    npy_intp dimscandidates[3] = {L, K, nrOfCandidates};
+    printf("Number of candidates: %d\n", nrOfCandidates);
+    npy_intp dims4[4] = {L, K, channel_size};
+
+//    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimscandidates, NPY_INT, (void*)&candidates);
+//    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNewFromData(1, dimsdistance, NPY_DOUBLE, (void*)&distances);
+    // https://github.com/suiyun0234/scipy-master/commit/da7dfc7aad8daa7a516e43f4c7001eea7c1a707e
+    // https://github.com/fjean/pymeanshift/commit/1ba90da647342184ea7df378d7f21eba257a51d9
+    PyArrayObject* numpy_candidates = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_INT);
+    int* numpy_candidates_data = (int*)PyArray_DATA(numpy_candidates);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_candidates_data, candidates[l][k], nrOfCandidates*sizeof(int));
+            numpy_candidates_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_distances = (PyArrayObject*)PyArray_SimpleNew(3, dimscandidates, NPY_DOUBLE);
+    double* numpy_distances_data = (double*)PyArray_DATA(numpy_distances);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_distances_data, distances[l][k], nrOfCandidates*sizeof(double));
+            numpy_distances_data += nrOfCandidates;
+        }
+    }
+
+    PyArrayObject* numpy_hash_functions = (PyArrayObject*)PyArray_SimpleNew(3, dims4, NPY_DOUBLE);
+    double* numpy_hash_functions_data = (double*)PyArray_DATA(numpy_hash_functions);
+    for (int l=0;l<L;l++)
+    {
+        for (int k=0;k<K;k++)
+        {
+            memcpy(numpy_hash_functions_data, hashFunctions[l][k], channel_size*sizeof(double));
+            numpy_hash_functions_data += channel_size;
+        }
+    }
+    PyObject* ret = Py_BuildValue("NNN", PyArray_Return(numpy_candidates), PyArray_Return(numpy_distances), PyArray_Return(numpy_hash_functions));
+//    Py_XDECREF(data_obj);
+//    Py_XDECREF(query_obj);
+//    Py_XDECREF(hash_obj);
+//    Py_XDECREF(weights);
+//    Py_XDECREF(data);
+//    Py_XDECREF(query);
+//    Py_XDECREF(descr);
+//    Py_XDECREF(descr_float);
+//    Py_XDECREF(query);
+//    Py_XDECREF(numpy_candidates);
+//    Py_XDECREF(numpy_distances);
+//    Py_XDECREF(TEST);
+//    free(candidates);
+//    free(distances);
+//    for (int l=0;l<L;l++)
+//    {
+//        for (int k=0;k<K;k++)
+//        {
+//            for (int t=0;t<query_size;t++)
+//            {
+//                free(hashFunctions[l][k][t]);
+//            }
+//            free(hashFunctions[l][k]);
+//        }
+//        free(hashFunctions[l]);
+//    }
+//    free(hashFunctions);
+    return ret;
+}
diff --git a/lsh-fast/lsh.cpp b/lsh-fast/lsh.cpp
index d4a515a5fcb8f3e68f6cc20ff3c7846e55ce9171..907b082afd810e2039ed1e5889d5859b11413326 100644
--- a/lsh-fast/lsh.cpp
+++ b/lsh-fast/lsh.cpp
@@ -13,6 +13,14 @@
 
 using namespace std;
 
+double l2(double* A, double* B, int m) {
+    double distance = 0;
+    for (int i = 0; i < m; i++) {
+        distance += std::abs(A[i]-B[i]);
+    }
+    return distance;
+}
+
 /// This function is from the UCRDTW code
 ///
 /// Calculate Dynamic Time Wrapping distance
@@ -106,9 +114,11 @@ double uniform(double a, double b)
 }
 
 /// Algorithm for calculating similarity of (multivariate) time series data
-int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r, double a, double sd, int * &candidates, double * &distances, double **** &hashFunctions, double ** weights, int &nrOfCandidates)
+int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r, double a, double sd, int *** &candidates, double *** &distances, double *** &hashFunctions, double * weights, int &nrOfCandidates)
 {
     clock_t begin_time = clock();
+    double time_spent = 0;
+    clock_t end_time = clock();
     std::random_device rd{};
     std::mt19937 gen{rd()};
     std::normal_distribution<> distribution0{0,1};
@@ -119,7 +129,7 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
     int threshold = T * 0.22; //0.8 => 18/67
 
     /// Create hash functions
-    int value;
+    double value;
     for (int l=0;l<L;l++)
     {
         for (int k=0;k<K;k++)
@@ -127,18 +137,18 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
             for (int d=0;d<Dim;d++)
             {
                 value = distribution0(gen);
-                for (int t=0;t<T;t++)
-                    {
-                    if (weights == NULL)
-                    {
-                        hashFunctions[l][k][t][d] = value;
-                    } else {
-                        hashFunctions[l][k][t][d] = value;// * weights[t][d];
-                    }
+                if (weights == NULL)
+                {
+                    hashFunctions[l][k][d] = value;
+                } else {
+                    hashFunctions[l][k][d] = value * weights[d];
                 }
             }
         }
     }
+    end_time = clock();
+    time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
+    std::cout << "Hash functions created: " << time_spent << " seconds" << std::endl;
 
     /// Calculate ratios for DTW approximation
     double ** ratios = (double **)malloc(L*sizeof(double*));
@@ -167,13 +177,16 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
                 {
                     temp0 = 0;
                     for (int d=0;d<Dim;d++) {
-                        temp0 += hashFunctions[l][k][t][d] * D[m][t][d];
+                        temp0 += hashFunctions[l][k][d] * D[m][t][d];
                     }
                     hashSET[m][l][k][t] = temp0;
                 }
             }
         }
     }
+    end_time = clock();
+    time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
+    std::cout << "Set hashed: " << time_spent << " seconds" << std::endl;
 
     /// Create upper and lower bound on query
     double ** Q_U = (double**)malloc((T)*sizeof(double*));
@@ -199,6 +212,10 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
             currentMin = 10000;
         }
     }
+    end_time = clock();
+    time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
+    std::cout << "Query upper and lower bound: " << time_spent << " seconds" << std::endl;
+
     double temp1 = 0;
     double temp2 = 0;
     double temp3 = 0;
@@ -225,9 +242,9 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
                 temp3 = 0;
                 for (int d=0;d<Dim;d++)
                 {
-                    temp1 += hashFunctions[l][k][t][d] * Q[t][d];
-                    temp2 += hashFunctions[l][k][t][d] * Q_U[t][d];
-                    temp3 += hashFunctions[l][k][t][d] * Q_L[t][d];
+                    temp1 += hashFunctions[l][k][d] * Q[t][d];
+                    temp2 += hashFunctions[l][k][d] * Q_U[t][d];
+                    temp3 += hashFunctions[l][k][d] * Q_L[t][d];
                 }
                 hashQ[l][k][t] = temp1;
                 hashQ_U[l][k][t] = temp2;
@@ -235,6 +252,9 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
             }
         }
     }
+    end_time = clock();
+    time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
+    std::cout << "Query hashed: " << time_spent << " seconds" << std::endl;
 
     /// Generate candidates
     vector<int> v;
@@ -278,8 +298,8 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
             v.emplace_back(m);
         }
     }
-    clock_t end_time = clock();
-    double time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
+    end_time = clock();
+    time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
     std::cout << "Hashing done in: " << time_spent << " seconds" << std::endl;
     std::cout << "Number of candidates pruned: " << 100 - (100 * v.size() / M) << "%" << std::endl;
 
@@ -298,8 +318,6 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
         for (int k=0;k<K;k++)
         {
             q_ub += ratios[l][k] * sqrt(T * pow(r, 2.0));
-            q_ub += ratios[l][k] * sqrt(T * pow(r, 2.0));
-            q_ub += ratios[l][k] * sqrt(T * pow(r, 2.0));
         }
     }
     for (int m=0;m<v.size();m++)
@@ -336,41 +354,48 @@ int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r
     dtwsim.reserve(sim.size());
 
     double distance = 0;
-    for (int m=0;m<sim.size();m++)
+    candidates = (int***)malloc(L*sizeof(int**));
+    distances = (double***)malloc(L*sizeof(double**));
+    for (int l=0;l<L;l++)
     {
-        distance = 0;
-        for (int l=0;l<L;l++)
+        candidates[l] = (int**)malloc(K*sizeof(int*));
+        distances[l] = (double**)malloc(K*sizeof(double*));
+        for (int k = 0; k < K; k++)
         {
-            for (int k = 0; k < K; k++)
+            candidates[l][k] = (int*)malloc(sim.size()*sizeof(int));
+            distances[l][k] = (double*)malloc(sim.size()*sizeof(double));
+            dtwsim.clear();
+            for (int m=0;m<sim.size();m++)
             {
-                distance += dtw(hashSET[sim[m].first][l][k], hashQ[l][k], NULL, T, 0.05 * 120, INF);
+//                distance = dtw(hashSET[sim[m].first][l][k], hashQ[l][k], NULL, T, 0.05 * 120, INF);
+                distance = l2(hashSET[sim[m].first][l][k], hashQ[l][k], T);
+                dtwsim.emplace_back(sim[m].first, distance);
+            }
+            sort(dtwsim.begin(), dtwsim.end(), sortbysecasc);
+            for (int i=0; i<dtwsim.size(); i++)
+            {
+                candidates[l][k][i] = dtwsim[i].first;
+                distances[l][k][i] = dtwsim[i].second;
             }
         }
-        dtwsim.emplace_back(sim[m].first, distance);
     }
     end_time = clock();
     time_spent = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
     std::cout << "DTW sim done in: " << time_spent << std::endl;
 
     /// Sort and return distances
-    sort(dtwsim.begin(), dtwsim.end(), sortbysecasc);
-    int count = 0;
-    for (int m=0;m<sim.size();m++)
-    {
-        for (int n=0;n<50;n++)
-        {
-            if (sim[m].first == dtwsim[n].first) {
-                count++;
-            }
-        }
-    }
-    candidates = (int*)malloc(dtwsim.size()*sizeof(int));
-    distances = (double*)malloc(dtwsim.size()*sizeof(double));
-    for (int i=0; i<dtwsim.size(); i++)
-    {
-        candidates[i] = dtwsim[i].first;
-        distances[i] = dtwsim[i].second;
-    }
+//    sort(dtwsim.begin(), dtwsim.end(), sortbysecasc);
+//    int count = 0;
+//    for (int m=0;m<sim.size();m++)
+//    {
+//        for (int n=0;n<50;n++)
+//        {
+//            if (sim[m].first == dtwsim[n].first) {
+//                count++;
+//            }
+//        }
+//    }
+
     nrOfCandidates = dtwsim.size();
 
     /// Clean up
@@ -479,17 +504,14 @@ int main() {
     int testt = 0;
     while (testt < 5) {
         /// Initialize output variables
-        int *candidates;
+        int ***candidates;
         int nrOfCandidates;
-        double *distances;
-        double ****hashFunctions = (double ****) malloc(L * sizeof(double ***));
+        double ***distances;
+        double ***hashFunctions = (double ***) malloc(L * sizeof(double **));
         for (int l = 0; l < L; l++) {
-            hashFunctions[l] = (double ***) malloc(K * sizeof(double **));
+            hashFunctions[l] = (double **) malloc(K * sizeof(double *));
             for (int k = 0; k < K; k++) {
-                hashFunctions[l][k] = (double **) malloc(T * sizeof(double *));
-                for (int t = 0; t < T; t++) {
-                    hashFunctions[l][k][t] = (double *) malloc(Dim * sizeof(double));
-                }
+                hashFunctions[l][k] = (double *) malloc(Dim * sizeof(double));
             }
         }
         double a = 3.1549093441462044;
diff --git a/lsh-fast/lsh.h b/lsh-fast/lsh.h
index 4150199c32fa65938b3cd1d88e4b9a71856a1e3c..b15e087435e0736f97867c86a78de3513d41f3b6 100644
--- a/lsh-fast/lsh.h
+++ b/lsh-fast/lsh.h
@@ -1,2 +1,2 @@
 
-int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r, double a, double sd, int * &candidates, double * &distances, double **** &hashFunctions, double ** weights, int &nrOfCandidates);
+int lsh(double *** D, int M, int T, int Dim, double ** Q, int L, int K, double r, double a, double sd, int *** &candidates, double *** &distances, double *** &hashFunctions, double * weights, int &nrOfCandidates);