From a4d9328379d3998a26e0055352433e5dfb4a16e8 Mon Sep 17 00:00:00 2001
From: lmz <limingzhe@iplayabc.com>
Date: Tue, 8 Oct 2019 16:16:16 +0800
Subject: [PATCH] add upload-video

---
 src/app/app.module.ts                         |   6 +
 .../upload-video/upload-video.component.html  |  95 +++++++++
 .../upload-video/upload-video.component.scss  | 130 +++++++++++
 .../upload-video/upload-video.component.ts    | 201 ++++++++++++++++++
 src/app/pipes/resource.pipe.ts                |  28 +++
 src/app/pipes/time.pipe.ts                    |  19 ++
 src/assets/default/video-not-upload.jpg       | Bin 0 -> 33779 bytes
 src/index.html                                | 126 +++++------
 tslint.json                                   |   5 +-
 9 files changed, 546 insertions(+), 64 deletions(-)
 create mode 100644 src/app/common/upload-video/upload-video.component.html
 create mode 100644 src/app/common/upload-video/upload-video.component.scss
 create mode 100644 src/app/common/upload-video/upload-video.component.ts
 create mode 100644 src/app/pipes/resource.pipe.ts
 create mode 100644 src/app/pipes/time.pipe.ts
 create mode 100755 src/assets/default/video-not-upload.jpg

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 7d45083..efe0b91 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -21,6 +21,9 @@ import { registerLocaleData } from '@angular/common';
 import zh from '@angular/common/locales/zh';
 import {UploadImageWithPreviewComponent} from "./common/upload-image-with-preview/upload-image-with-preview.component";
 import {BackgroundImagePipe} from "./pipes/background-image.pipe";
+import {UploadVideoComponent} from "./common/upload-video/upload-video.component";
+import {ResourcePipe} from "./pipes/resource.pipe";
+import {TimePipe} from "./pipes/time.pipe";
 registerLocaleData(zh);
 
 @NgModule({
@@ -32,6 +35,9 @@ registerLocaleData(zh);
     AudioRecorderComponent,
     UploadImageWithPreviewComponent,
     BackgroundImagePipe,
+    ResourcePipe,
+    TimePipe,
+    UploadVideoComponent,
 
     PlayerContentWrapperComponent
   ],
diff --git a/src/app/common/upload-video/upload-video.component.html b/src/app/common/upload-video/upload-video.component.html
new file mode 100644
index 0000000..e39116a
--- /dev/null
+++ b/src/app/common/upload-video/upload-video.component.html
@@ -0,0 +1,95 @@
+
+<div class="up-video" style="display: flex;">
+  <!--<nz-upload class="" [nzDisabled]="!showUploadBtn"-->
+               <!--[nzShowUploadList]="false"-->
+               <!--[nzBeforeUpload]="beforeUpload"-->
+               <!--nzAccept = ".mp4"-->
+               <!--style="margin-right: 1rem">-->
+
+    <nz-upload class="p-image-uploader" [nzDisabled]="uploading"
+               [nzShowUploadList]="false"
+               nzAccept = ".mp4"
+               [nzAction]="uploadUrl"
+               [nzData]="uploadData"
+               (nzChange)="handleChange($event)"
+               style="margin-right: 1rem">
+
+      <button type="button" nz-button nzType="default" *ngIf="showUploadBtn" [disabled]="uploading"
+              [nzLoading]="uploading" >
+        <i nz-icon type="plus" theme="outline"></i>
+
+        <span>{{ uploading ? 'Uploading' : 'Select Video' }}</span>
+        <!--<span>Select Video</span>-->
+      </button>
+
+
+
+
+    </nz-upload>
+  <!--<button nz-button nzType="primary"  *ngIf="showUploadBtn"-->
+            <!--style="margin-right: 1rem"-->
+            <!--type="button"-->
+            <!--[nzLoading]="uploading"-->
+            <!--(click)="handleUpload()"-->
+            <!--[disabled]="!videoFile || uploading">-->
+      <!--<i nz-icon type="upload" theme="outline"></i>-->
+      <!--<span>{{ uploading ? 'Uploading' : 'Start Upload' }}</span>-->
+    <!--</button>-->
+
+    <!--
+    <button type="button"
+            (click)="extraCover()"
+            nz-button nzType="default"
+            [disabled]=" !(videoUrl && videoUrl.constructor.name === 'String')">设置封面</button>
+    -->
+    <!--
+   <nz-divider></nz-divider>
+
+   <div [style.display]="!uploading?'none':''" style="position:relative">
+     <div style="width: calc( 100% - 20px);">
+       <nz-progress [nzPercent]="progress">
+       </nz-progress>
+     </div>
+     <i (click)="cancelUpload()" class="anticon anticon-close-circle" style="position: absolute;top: 50%;right: 0;transform: translateY(-50%);cursor: pointer"></i>
+   </div>
+   -->
+
+
+</div>
+<div class="p-box d-flex align-items-center p-video-uploader" style="top: 20px;">
+  <div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
+    <i nz-icon type="upload" theme="outline"></i>
+    <div class="m-3"></div>
+    <span>Click here to upload video</span>
+    <div class="mt-5 p-progress-bar" *ngIf="uploading">
+      <div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>
+      <div class="p-progress-value">{{progress}}%</div>
+    </div>
+  </div>
+  <div class="p-upload-progress-bg dddd " *ngIf="uploading"
+       [ngClass]="{'smart-bar': showUploadBtn}" >
+    <div class="i-bg" [style.width]="progress+'%'"></div>
+    <div class="i-text">
+      <fa name="cloud-upload"></fa>
+      Uploading...
+    </div>
+  </div>
+  <div class="p-upload-check-bg" *ngIf="checking">
+    <div class="i-bg" [style.width]="progress+'%'"></div>
+    <div class="i-text">
+      <fa name="cloud-upload"></fa>
+      <i nz-icon type="loading" theme="outline"></i>Checking...
+    </div>
+  </div>
+  <div class="p-preview" *ngIf="!showUploadBtn && !uploading && videoUrl " >
+    <!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
+    <video [src]="safeVideoUrl(videoUrl)" controls #videoNode (loadedmetadata)="videoLoadedMetaData()"></video>
+  </div>
+</div>
+<div [style.display]="!checkVideoExists?'none':''">
+  <span><i nz-icon type="loading" theme="outline"></i>  checking file to upload</span>
+</div>
+
+
+
+
diff --git a/src/app/common/upload-video/upload-video.component.scss b/src/app/common/upload-video/upload-video.component.scss
new file mode 100644
index 0000000..b666406
--- /dev/null
+++ b/src/app/common/upload-video/upload-video.component.scss
@@ -0,0 +1,130 @@
+@import '../../style/common_mixin';
+
+.p-video-uploader {
+  position: relative;
+  display: block;
+  width: 100%;
+  height: 0;
+  padding-bottom: 56.25%;
+  .p-box {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    border: 2px dashed #ddd;
+    //border-radius: 0.5rem;
+    background-color: #fafafa;
+    text-align: center;
+    color: #aaa;
+    .p-upload-icon {
+      text-align: center;
+      margin: auto;
+      .anticon-upload {
+        color: #888;
+        font-size: 5rem;
+      }
+      .p-progress-bar {
+        position: relative;
+        width: 20rem;
+        height: 1.5rem;
+        border: 1px solid #ccc;
+        border-radius: 1rem;
+        .p-progress-bg {
+          background-color: #1890ff;
+          border-radius: 1rem;
+          height: 100%;
+        }
+        .p-progress-value {
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 100%;
+          height: 100%;
+          text-shadow: 0 0 4px #000;
+          color: white;
+          text-align: center;
+          font-size: 0.9rem;
+          line-height: 1.5rem;
+        }
+      }
+    }
+    .p-preview {
+      width: 100%;
+      height: 100%;
+      //background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
+      video{
+        max-height: 100%;
+        max-width: 100%;
+      }
+    }
+  }
+}
+
+.p-btn-delete {
+  position: absolute;
+  right: -0.5rem;
+  top: -0.5rem;
+  width: 2rem;
+  height: 2rem;
+  border: 0.2rem solid white;
+  border-radius: 50%;
+  font-size: 1.2rem;
+  background-color: #fb781a;
+  color: white;
+  text-align: center;
+}
+
+.p-upload-progress-bg, .p-upload-check-bg {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  & .i-text {
+    position: absolute;
+    text-align: center;
+    color: white;
+    text-shadow: 0 0 2px rgba(0, 0, 0, .85);
+  }
+  & .i-bg {
+    position: absolute;
+    left: 0;
+    top: 0;
+    height: 100%;
+    background-color: #1890ff;
+    //border-radius: 0.5rem 0 0 0.5rem;
+  }
+}
+.p-upload-progress-bg.smart-bar{
+  height: 50px!important;
+  margin-top: 20px!important;
+}
+.p-upload-check-bg {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  & .i-text {
+    position: absolute;
+    text-align: center;
+    color: white;
+    text-shadow: 0 0 2px rgba(0, 0, 0, .85);
+  }
+  & .i-bg {
+    position: absolute;
+    left: 0;
+    top: 0;
+    height: 100%;
+    background-color: #17a2b8;
+    //border-radius: 0.5rem 0 0 0.5rem;
+  }
+}
+
+
+//:host ::ng-deep .ant-upload {
+//  display: block;
+//}
diff --git a/src/app/common/upload-video/upload-video.component.ts b/src/app/common/upload-video/upload-video.component.ts
new file mode 100644
index 0000000..b947e15
--- /dev/null
+++ b/src/app/common/upload-video/upload-video.component.ts
@@ -0,0 +1,201 @@
+import {Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SecurityContext, ViewChild} from '@angular/core';
+import {NzMessageService, UploadFile} from 'ng-zorro-antd';
+import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
+
+
+@Component({
+  selector: 'app-upload-video',
+  templateUrl: './upload-video.component.html',
+  styleUrls: ['./upload-video.component.scss']
+})
+export class UploadVideoComponent implements OnChanges, OnDestroy {
+  uploading = false;
+  checking = false;
+  checkVideoExists = false;
+  uploadClicked = false;
+
+  @Input()
+  videoFile = null;
+  uploaderInst = null;
+
+  progress = 0;
+  // @Input()
+  // setCovering = false;
+
+  @Input()
+  videoUrl = '';
+  @ViewChild('videoNode')
+  videoNode: ElementRef;
+
+
+
+
+  // @Input()
+  // extractCoverFunc = null;
+
+  @Output()
+  videoUploaded = new EventEmitter();
+  @Output()
+  videoUploadFailure = new EventEmitter();
+  @Output()
+  extractVideoCover = new EventEmitter();
+
+
+  @Input()
+  showUploadBtn = true;
+  @Input()
+  item: any;
+  // videoItem = null;
+
+  uploadUrl = (<any> window).courseware.uploadUrl();
+  uploadData = (<any> window).courseware.uploadData();
+
+  constructor(private nzMessageService: NzMessageService,
+              private sanitization: DomSanitizer
+              // private cwService: _coursewareService,
+              // private resService: ResourceService
+              ) {
+    this.uploading = false;
+    this.videoFile = null;
+
+  }
+  ngOnChanges() {
+    // if (!this.videoFile || this.showUploadBtn) {
+    //   return;
+    // }
+    // this.beforeUpload(this.videoFile);
+    // this.handleUpload();
+  }
+  ngOnDestroy(): void {
+    URL.revokeObjectURL(this.videoUrl);
+  }
+
+  safeVideoUrl(url) {
+    console.log(url)
+    return this.sanitization.bypassSecurityTrustResourceUrl(url); // `${url}`;
+  }
+  videoLoadedMetaData() {
+
+  }
+
+
+  handleChange(info: { type: string, file: UploadFile, event: any }): void {
+
+    console.log('info:' , info);
+
+    switch (info.type) {
+      case 'start':
+
+        // this.beforeUpload(info.file);
+
+
+        if (!this.checkSelectFile(info.file)) {
+          return;
+        }
+
+
+        this.uploading = true;
+        this.progress = 0;
+
+        break;
+
+      case 'success':
+
+
+        this.uploadSuccess(info.file);
+
+        // this.beforeUpload(info.file);
+        // this.uploadSuccess(info.file);
+
+        break;
+      case 'progress':
+        this.progress = parseInt(info.event.percent, 10);
+        this.doProgress(this.progress);
+        break;
+    }
+  }
+
+
+  checkSelectFile(file) {
+    if (!file.lastModified) {
+      return false;
+    }
+    const delta = 500;
+    const isOverSize = (file.size / 1024 / 1024) < delta;
+    if (!isOverSize) {
+      this.nzMessageService.error(`video must smaller than ${delta}MB!`);
+      return false;
+    }
+    return true;
+  }
+  checkHashFinish = (hash) => {
+    this.checking = false;
+    this.uploading = true;
+  }
+
+  uploadSuccess = (file) => {
+
+    this.nzMessageService.info('Upload Success');
+    // this.updateStatus(false);
+    this.uploading = false;
+    this.videoFile = null;
+    // this.updateSource(url);
+    this.videoUrl = file.response.url;
+    // console.log(this.picUrl)
+    // this.uploadFinished(url);
+    // if (!inOSS) {
+      const vid = document.createElement('video');
+      vid.addEventListener('loadedmetadata', () => {
+        const height = vid.videoHeight;
+        const width = vid.videoWidth;
+        let duration = vid.duration;
+        if (duration) {
+          duration = duration * 1000;
+        }
+        file['height'] = height;
+        file['width'] = width;
+        file['duration'] = duration;
+        vid.preload = 'none';
+        vid.src = '';
+        vid.remove();
+
+        this.videoUploaded.emit(file.response);
+
+        // this.resService.updateVideo(id, {width, height, duration}).then( () => {
+        //   this.videoUploaded.emit({res_id: id, id, name, hash, url});
+        // });
+
+      });
+      vid.src = file.response.url;
+    // } else {
+    //   this.videoUploaded.emit(file.response);
+    // }
+
+
+
+  }
+
+
+
+  uploadFailure = (err, file) => {
+    this.uploading = false;
+    if (err.name && err.name === 'cancel') {
+      return;
+    }
+    console.log(err);
+    this.nzMessageService.error('Upload Error ' + err.message);
+    this.videoUploadFailure.emit(file);
+  }
+
+  doProgress =  (p) => {
+    if (p > 1) {
+      p = 1;
+    }
+    if (p < 0) {
+      p = 0;
+    }
+    // console.log(Math.floor(p * 100));
+    this.progress =  Math.floor(p * 100);
+  }
+}
+
diff --git a/src/app/pipes/resource.pipe.ts b/src/app/pipes/resource.pipe.ts
new file mode 100644
index 0000000..d7f5f8d
--- /dev/null
+++ b/src/app/pipes/resource.pipe.ts
@@ -0,0 +1,28 @@
+import {Pipe, PipeTransform} from '@angular/core';
+// import {ElectronUtil} from '../util/ElectronUtil';
+
+declare const APP_PATH;
+// const isInElectron = localStorage.getItem('electron');
+
+@Pipe({
+  name: 'resource'
+})
+export class ResourcePipe implements PipeTransform {
+
+  transform(pic_url: any, coursewareSid?: string): string {
+    // return pic_url;
+    if (pic_url &&  typeof pic_url === 'object') {
+      return pic_url;
+    }
+    // console.log('resource', pic_url)
+    return `${pic_url}?t=${Math.random()}`;
+
+    // let ret = value ? `/api/resource/${value}/file` : '';
+    // let ret = res_id ? `/resource/audio/${res_id}` : '';
+    // if (isInElectron && ElectronUtil.hasCached(coursewareSid, res_id)) {
+    //   ret = `file://${APP_PATH}/courseware_cache/${coursewareSid}/${res_id}`;
+    // }
+    // return ret;
+  }
+
+}
diff --git a/src/app/pipes/time.pipe.ts b/src/app/pipes/time.pipe.ts
new file mode 100644
index 0000000..af84a0c
--- /dev/null
+++ b/src/app/pipes/time.pipe.ts
@@ -0,0 +1,19 @@
+import {Pipe, PipeTransform} from '@angular/core';
+import * as _ from 'lodash';
+
+@Pipe({
+  name: 'time'
+})
+export class TimePipe implements PipeTransform {
+
+  transform(value: any, args?: any): any {
+    let ret = '00:00';
+    if (_.isNumber(value) && value > 0) {
+      const minutes = Math.floor(value / 60);
+      const seconds = Math.floor(value % 60);
+      ret = _.padStart(minutes, 2, '0') + ':' + _.padStart(seconds, 2, '0');
+    }
+    return ret;
+  }
+
+}
diff --git a/src/assets/default/video-not-upload.jpg b/src/assets/default/video-not-upload.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..31fbbcc7703958c0153d883aeded25e2a53e0542
GIT binary patch
literal 33779
zcmeGF1yohr_6Lq1LXZX}q+1%KyF|LXySqVB5D@9^mhO;l>F)0CZV>Q)P_O#lyWcUM
z_rCvc{C;EHtz+-G=A557*P3gt*!%2r_%iin34kafAS?g?0RaF&fd2qrW&wNv7|6#^
zk0D{8prBx3VBiojkPs0N5b@BSJ;iuVKuY?YfS8E<1t&c@6)QCnF{2P8D>v^e{#Ru5
zqEaF+B{}(C@je&<fq{iZgh#|hLc-;xB&Ov3?c+-e0O>LK2S^4m5F`L75(pR)$d@(%
zCa{vAU=P*(aXf+m1p|ltDg^TXO$aQ4KZ1b#G6R4G0}2tr5P`UKk00QFh<_sRPXzvn
zz&{cACj$RO;Qs{?z_m_XHIPm~2U|-I%x{tUpVtU;XKHtB%Wmh;Zuh`4-OyZd9lbOZ
za80^Oex_cWt}B~hC>miZ7-Px@#q&S)jcc9UFA*5RT|A#YIxjHv&Gt3viTRe*p-p-%
zRuY<t$N$bDNMlg0grSXO!t}KK(jR7NyKB<WM^^;SSgv~h;Qjq8+qvTgD~@jyUtR~#
z4{KoRk?r=cY1K7QYsP*s|0cmkI-9U^BXR#msp}U@5Kr?6OE*6_Ct~S8Z0-IB2fBbQ
zM+iSv_u*Zj$FJtV#BWMC7pYq7`hMm9b=rRCaEb-zqkH4jzuJHmIJ+uQAEfop|5yHB
zEXAxlLlu!^eD?b{JV?5(Ov4sO2=zedze)Z|5jLIm9xXp?<KjQSx}-dpw;7gv!T%xo
zea1A5nY-iE`S#g=LUqupHqveuT>n$@yBzbP&ol`a>KL=B|B2+g;Mk)v?DzOj$?tK%
z^c|J!7t6OM=Kcit*nKd`XV0nRPei}PLKkqbWZq}1U~c{s*kg&!*!Md}e<JxU7Ory1
z^%sCT{=lxspWr|e72VK6LKfElMD{x@5c;k&Sq@F1KgGOAk`IwwVLcrGQ|W)t+#lPT
zcAYHO#rso;t+~+zC$nEC?Vn2jYbJeAbPCOZqjcGyBapB|*rBFRwf<cCUvj|@pN@%~
zxHSK{I+p?CL%1C5JpNq%-*Lh6RUL*mI9t*G4|P^%*7Fe2mB9Z){NJ%D8*QgAw$7UW
z4{eHj->!}`mZkqg{9myhjqUc5EvG#mltFDXJ4@`U-`IXFJ#avdV<q0`H1r%i6o3bV
znaQ}Dp!ap+x8h$r!!RdYB*m-aJ)psg?kr!OYamdz{j}9#q+vPJzHP_zjfL_Bz`K_2
z%%SyD<F_gJ2J>C+n9Hv?U7T#R_1cpvQ_UM!o^O`$f={b~RNj`o*14m11Z@Fd%Y1DT
zPLTN0gB)vCh0#)Sx%q+qiwDV-Mv-L9>;oDh!5PDi+xH2{9}i)8k~UuhBdtIPVn9L6
zgtl7Tz`n`pF8_6rePlR#70g-q7rj2fz*wfuPuxF~Dm@gQ9oX7CTOzX!ia(TqhbQ|0
za0UcTwtm~EAfiV-sj=wb>ns{F-c#cNl!6<|`hv`#qyovmc!0-nmuj6ZJOmd2!Jas;
zk<bp;nUliv)f@<@W6}};@Q8E>hE|y@v`*c{%{i%Hx9o@i7iD=d1xL>|@V=`5r4yyb
zo5?QQTA&*MfOc+U=WKyg&pE8*n=M2Vrv+eyo&@XsQh~H22Vv`*8pRhtokx}<uLrOf
zw7#kTm9tx0;ezDirh4iF7*#fZ^eWME3@6p@n=MfAL-u9>z{DW58C9oD7T>XljT7UJ
zhrXzrnp=^41E>V9sOtG>_Vk<jUpa$J<~JFh;(T9b5%|yDpO)P{v<;YY-{MbbI(3qS
zD*$9b*iRF8?yRdd0|1ar6H%(8S6V>sUp!*g9XGDrzfTk}m)Xa3F0M;oZT;alUH?g8
zGlRfZp+!#I%&KARtpTQNsXrgvUij*{O_3G=0K1aD>+V)$@9`D(S5A~12&#nrd*2Lz
zIGwq(>Ang7W(ZH>v>q5=YdOG;lF2N}tUY8)jKadaMP<*$yPt8O0A{SU`RO+Uf29Vf
z#k2>`jE+3tur-di8D9XB@4l73S3y}3(A5C?4#5XIX{N#L=I+JM{(nq;8127f<?&7b
zFPuLI&fdlh+4y|7pz7jo&^>wD{MFL;?Bk0nfejcU)w+_Np3k3LEFJ|Is)wt&7d^~C
z{<~Iqb?#bU)&I%~F0^)j&E4ZW^rHjEd2z)C&(|V2)Pf^W;6ss$j+QF*=_vhUonmp5
zW)=W_QZEKKKgt#W@@Z&IkrN^GJNox8U|B)El2MmD-;gi}vc6V_PTxx3a}ZAm@!#4G
z@?-d~&23I_(){~f!+&23u#d872B%z8-w+_o!)x;m2;Xl4umn!6008LY#~@+Ok6>}3
z+1V?cKcC-d{TzZAOpN5o*)9LQyMNOJnav(9yDm2Q&W@PdTx?)||5Hh!%L>+-tI#5W
z+B{itf(!Z1qR7sUE~ps*7^owvzEjJO#ju#jy=emf3HeP5(jrBmccUTa8w|{SlTCH>
z_0P@(hsd_zDlDOGD{1TKRy_C2WAXq_N#CPSo3(F}l7GbWn=XH<J8YksHJZ)<O+Fk<
zX4_piDUZJu0021YIyo~8ZM)~$rmJ}0n149tWHyz%(|r4f=5JsBt<#gDgq;tQJ-(Yk
zQkho@vMBjs^joH9&6^bG9Hsu?{w`rBU1f68xc3bPav>dg{sq8k@U{4`y5qwsMX4t3
zaMAs=J5a}LJgs`h#qg8$n-pAV<-@qv`vyZO5WYDCyXXg|Gyt$i(nY@nSa}iL{wC-w
zBrZGo9=EUgn;!5C$7IrOaeefo{JR9#M~f3po`E`^Z$Rw(kWP!mH4k73yv7e10BB)W
zxYk%Scf*a#PrfJl#j(wN8g|t$o6K+c|NgAPF<7-Tw)h=jF*|g4c8}K#EP^UE12_35
zK^4JovIa2OxA$H9)h>^@zIDKZIu<)tGF7tD1NoN@&^JCiYu9dnq|Nq@H9LEwaxBmm
zNZ8R801z;_!?$zZVKu!dX)2#MukdrRB4lRaxY+jiOI{y9#7;@m3kbR2@gQY)=6BT8
zil)Fa$nfY201!C2-MVvrPX{?Cxk9=0T@3(=`=)Q1y!nsfZ(p(5K1Zie9eDf-jJnWd
z0e(iCxww-5HOaooAf9C5zWE!^A|U4sX4g3{dWwH_^`x<P69B+tsJoT7_=Ue#mxNo@
z@eAWONf522n;L3EvtMB%pJ{;mBae~8WBKZzd{AafpMHnXpN!w7px|%{0|s0Wf5CxJ
z>@`{eKN=QoYFAkL$#)gNOxtib!28MhU5c))Fj;cZtZ3;MAe5#)Fb5Ga)bGiwezL*h
z_aDzU;{9a&HbugcoU9u0#}NDq|MR>cxMabg8vAYgKLL>Zm=48M2eDm0SpZ_Um;nHQ
z$Jp^I@B3!@L1-F<gn9o<O8x@)FG;1_%i_b$^X8xGf8JT3+@=BDZ#aIc{XS)HYB9sn
zRQ=0J0Ql1sgm{ui_@@6>>-RnUM8KedO$yn%{A2*Yi_5N?0gvIRzW`8FJ$?uT&8?j*
zH-DCY2>yG5dGw?4$-*va-%kkM9d7V=Qx5>d+k9vEa1--~eMU(Q5|@D=#h-}ZpyJk?
z$&zU@ej=bZ^N&=DCjbC;J2!})iyzi?C>#g3KmPTp|G@*~oXGHoTa`r7(GP#14Lhz}
zNkK0FU{!)cn=sAa1t6Vo=)Fw;#>DYp2R_NIjyv`eT|n!*RRF+vdNO#|rcneBV0b|E
z2NzEE1BK(jEpSNut%K;gA@?4#;HM3fsSoUhz1NgKIa~&`?2RsJTR%B}i2`->+g^9#
z{24`vLVv>Axu)>uALfwiT&YdVJ${t`8i8w_fR=K8cY9y*0}rOqjx=wf*{$^l2h7Vb
zth4l&eEmc4dsmQ1L*3Jb)+)iQpSbbTSB|PNCqI&orIOW^o#St21<<@c`qb@Z$^P&!
z`w2!fY3zyh+vxAk!9sN7K7IUk&iq-c-=ffU6yPBXLN^_LqA)5+fjM|D`kiC7ck;TD
zRqLnxuTo(2YL<euooCN^epvXI07ACuUR=#p8U2v{4dMv~w(&he{*TQo(A2NKK#Jr#
z4y?{4)&7QyA5buR)u*?(inHmXKUu#dAxN(yx0h*1u+9(Z-y$M5F0!tY6Z9Q_Sb<YT
z7PPN<L+k<E^4nwsT@6~q{t*5x0wj?#cI^h;LegdL#~vFbU+4Wn70p@+01T@Yn1#TJ
zaKq|vdHDs*H11kO(LmOFU<kwWo&Ccf1gkIc?E+`81*^v|h`&d|uIh!bmy-1F+ixGn
z{i{R%nfe&pnxf(B*#Dh707zp}@*RA!Lx?Q!fkouEi5Db@dH2}jl!dv*RkePO_{U`O
z_geNH4LK*8t!bOD=m<Q!VXEd%O{-70ES82EKI_5Q%U6%ws#8tTl}-8j9)fu7(*MNg
zKSutEz&{cACj$RO;QwzC0MoWAva7=bR4S6+9=qq+!Dx3U0w7c6xw$KU@yQ91dwu?W
zXIwkUR<H_G`g*{?5(i5?c@LyPKg(??G=Jm%#+j2XffTjXiv=@8`okb;V;vT;W}+1U
zY>ez<@4+uO7?8QrhS7`PRy4>oc{cU1<?lB!kFuV$6-eL#T_T8Q4bs(qujOx4p`=CD
zx*vWD#?9tR&Masrci7ycMv?Vu6Eu@$cA18zw!XJtHll-{t*g0*K!vq#lGEGW`c)+c
z4_j%18gUa8tYHF6sw$kJ0=;XV+iT+<KQqG9fK1zJMN%@|frDazYJQaS>y?2=wKa;_
z!ME(zaZ{oho1_k{5iDoq*`j3}tnJB9Dqd<@6-zMe5-_9HW-kVAQ^<yld}KLaW$wuy
zvPBx{gtt~o)LTtxx1F*vL>9&G53QP{K-Tw@OEiBG6Q}<B3%whsMu2P4O+|7sf3m8Z
zbBI*dAWdyul<lGq&XgNXg@hpb$>;ntjBF@M1w-u4Oj&)1E~DO2vXpprc#f5JD3vrC
z`q~oq(iGJXgA}#ZxjNHoAIX^n$F|A>%<%R7undQDQ)1LL5*tJUI4W<N(QdM35_R=G
z-{jeobtt0ODRR@)Hd3yrur|qaQ#Lm7=GoN|l3`7!(XiFli_Xig4v<|4jvAMx>uC|=
z1adMZP@J|?cR44aN|}3$mCgp<1To1_`nXG<-I$$<rgbNZ2{JoxZlEce7s)((=*Mx{
zm=4#<o#x+2fp4m6`6*o1ol)=5Q&mBBkf+x#6?g2E*Q+LvFeOE@24B=R=}%UEWbwog
zY!$_LHX5a34K_;lageGw0e?Pl(F7PArLYbQlpbK(q|tCz0)XZqtkn|T{xt|&j1p-q
zJ*(^`xyp#ZNPlFRSteHx14e?g604@U>l}mf)D#%{f>Y6a&`(ezt1sw+lAol`0;tA&
z1(agg*5N2YbiC`cZte);uHDX;U<bt>s`mR?kNwP9pUHNeuM+9H`5f8|*x%=Dlqa*h
zS8%?WqlU5Sn)$=Pvl2ReHcQ1MwOKy>dz>ioWH)oyY4|;ZL$&&yDd2TmEss8^?8)h8
ztw$X-R_i|-+mo%FsH5+>jXW(}_N01Xj@;oD%(`r$1XHz0jGpDV<iLJ$3jWzSIpwM9
z*T$;;Xl(qGG*tjqMX!V=(0(=xNCd}pCvfn`ENTF{&SuO`Ve)^wUjdw`xo4|fy7pSm
zK1@z-<8%4RD<OJxG*J?wU-O(i8-!Ak1lu=#R3CN9gcB$3x^VndpB-y<HzjUf345x4
zp~h*v1b7{(aXK$K$1qD%ew?dYhkoX72+Wae8krA+RE;ITiD;+8IQpdm>p8jENq&A*
zhegF;Z&7gsOJuO+xn!?p@sLRpbyrU()8oy-!gs_AHQQtpe4}J#X?l2>L07=u;2A`&
z!w04uPbHE}rv*JQ1%=B{u7N}0W50zjwKW;m0tK)_>a{hFx(uRPG>j6u=qIy(Asoc%
z$<bQGh}7c)5qgh$Y6b*ZqF6gr(KDuDfiqobhYdM>kh}Gh<Nk@74eN*LCLNE>s;osG
zlYq^tv_+nsa58XVCxzFOzY=M>xpAD^2Yw19%q7p}S)YY<YocPdU-jlk^w8F9^f9S@
z-{;n5Me^O92^3<)2HuUKbnQ%CaP0@V7rJaBW2<LH5}dF5PjdHJPv4{KhOqcV6RjpR
z*!FFbRsyF-)SGo~bRGF@bS#4yz2EQjKSO{HLg~q8BmSA_Z}Vb<ZSeIy{<fKa4Ez&;
ze<JWt1pbM@KN0vR0{=wde;ENt;8)RQ5CI@yprBw72=I@<z#qPo4g&llI^Yom(i2)~
z#HYwSa@LS|_yjNL7<py1t!zC@%TQ418D2`+ybX^?OaC-X$n?rC3{6&tPgieQ>qB#7
z3Ghqmj~}dX1HJ%Gh&&`x#UXIm;;imuUlK*+u{UW=f<<*Fe}<^WDiXV#Vr*WwF>L&l
zj><F9+N3pX{Hd@4-g@0gR%(rNhAv%PnW(smjGtLsu-8e$-(naJV@Pqp7%`oBrp%MK
z98O5+Oo7L4hHQ#Vj3F(|9CBE+ich2Rsf02ijkF3`FLcv(JtxC{ma22Y2qtf4`Kntj
za<cV0KN&eI(G%kUvFwU;9&>qGU42eP1x2ye;I3T^$)_?;O2fmEIdqaM+FbHfhq;e;
zWG{$K^@m(VvX_N)mof0nPvS6;{kS2fdyU7X3yiQ8C*)Ve>9M0B#F-+Gb5W;?cP(G-
ziwl==1m}~(Lt9sr7ot6palj=#rYa*gk$CG$EGPQPfi3@@pxzDuh6liM+Q4ulrcNc5
zt9xD{s5#DXN=^4622sW}t=;=JJ;G?`wV*s-c}a(e<}upp_$g*V<%yjdk5q2uOL{fk
zlv_9|7;}CKVG-Zg*WBh6wI$v}xq|iNaFHa$-8(6uq26iuWB`y;hMd4235oRB%XaaK
z224hhVoReF7l?(kk4x!|>C*Tgk<givi`@j3uk+l}5DZq)@m<(El8ns?(%K?(oLE5%
zCu|Cm!s#$t$jG3CM0fzM)6|4A!ylG56kX-Es9QDF=y}JApYK;zDIj`Bk&ahRyl-aN
zf_9v~Zs-`=fkq9@NYWY~n8>-V9WXJSJ~74iC1SxeXN^#}f@>A@UY;mU6av>X*){29
zUJbT$q7T6CrhYez9`6N}W4`7YA7WOVL_JY|>dtZ_e4-1)vSFGTi1WUCZ{|%xP#js<
z#IC*{=Od)`dMt%_pDA1IF;Blh;gB?3VG+)>CWi*q40@NIeG?g%C=byZ`6z(j(p9r1
z|LA(ngBRQYPCfNmk>&d<Vs{)-%1}mOJ2#Ni*?#<uu~{#M_#_l*T&jG9@}%@``8=fP
zd&8yCSt$@a03Fz7uQx-lR`z;uo;Ve>xjr;HDc1WFsa_GMu}aVQNShq%Fck0d6yX_n
z_r{lfR?(eu4)-FIQkRu|KEXBW#ms{{LNX$9^pH9HY9F43L%Z|tWL!V5Y^PiE#u>7g
z=K=SCNc#e4rnUypX>%<<mwlxt#3gJ_`<g*YXm@g4@e2U7p?yJfQHHIP(_NVI`1Pw)
zIr^7u+3%-c>_&v*x<*gm$_uqRgwoOa*Xy^tpC4KbcXQLeX>ge>w~_4AJk+?@$BH;b
z`#jlDCrEVLe*gbX1wptOCz=h4%lrupT2-1>Vk3+p`(x$Ow%A^?-NV;GWW?lTQe7cL
z4zY6>c!QOiYOj4hkjB|)d*zDkoWd94<3D~Z)CCfX<?`gE7<+gNgpj5hOW_66IiWjt
zesU9$LiOBp6~S&vxeI$r=tWm~AH}2_=E(~L<n~wV&)jH63SQ-neIl_ecR{7n<D@ET
zqV%z%`JD3Yq;|9j&|+`7?3+xFzKq#bgSp>amM!9VA~Us6e#U;IEXVpjG9t8_PigOx
z^!7Qy@QFvC6G2Jm!fH%#6{mWfAW_mBQz6Wp>=yvx4u>qt8*$)^pduxg#36<IIPLGF
zlG^!n1P(~9-g0c6WA~OmU%6&CncFr#Nh^!Drp^}TOy0%y>Qe$E$}hqZLN}}3QN<Xu
z$qL0ZC&dV-+Z%B3br>jw$p9L+vKEuSW1hStZ=H+gsw#IuSypjGs~4o2lRO4@8s1@#
zk=Wuq%Oh#QG0`7qC}?L`QI`mJVY~}sSspHgJUZdkHgt_vV+&<xPfDAAYiCeW7)*4}
z0I!8Z;@^~Y^97Kp<PzRFaS@`EXqVMkn9p9Fvhw&eeaw+MX~<<;PSTrWHn27;DmE)o
zG<QT&->qbq!t6FJii#LU2EIHoB<wRL`y3~Ip&{46rjerx8+Ga)-k5CyTv9HU<iAFw
zWx2Zo+ha6axE(v&@#!ruj-7Mx`e-eJ8@b<+Z-RY{+{j1dQ9pY&;k~LX$J{(ZnVUwz
z(C|#~;Oi_*IJ$Qo8G&`I=p&)Bb(T_cs0erEH`U4H_X)fAQQ8NhxT-Up?_|me*$VwQ
zpZ^i@Y&)DAc@*#`=_7PI@d`TMf*yhRF@e<O6RQ(Wc}3%Zr50;4nW08fg^yv163f5Z
z^L;}4p_7)cdGD9z>(($fw%D^8*z`H!v=$ny2JfL;i!l_kQ$VInwjC>;Eoz?SBiJb2
zEDZ0l_+&H~gpc@v2;<aVqB6fbyvD6?3BYW1ybYOYXb)PhyBFM-*?-JOY*zRx_@qkZ
zBV#Iad$DL!7|H>qCEVf(w+WNc0%p^i``F4$H5q|aq4{5W7YY3>*+s7;RTKF7nnQEY
zGk$lB>a3><4&HFy#~lBXEO57;=9)qt$f@D<;A^G}K>?xnCSL%~m+3ld-0@9|_UgI0
z2(`GjMc0CpVk~Ncib}t_L0N8qI(XAtbi!_K>Eb<fY}o!n=d`Mp1LfbGz!NG+v5t>0
z9{Fu<%g@Az9s9b+osV&is}oY^W*U%XKiRR1n6ieZbAvZWcfu0t=P_sKu~UBOKm<?r
zmWv9X`}E&)rPXghY8F%RPb^aWVv!b_UOUr_q-#xYTgc2@YNZ-q-PPOrU)v8)dIjO0
zA~e}Tl9H)tVj|dqePcK&^;zDo?`Kj=x}i6d==g^9n%HGCaJVWyq98kjEByC1l5&Hx
z2{a;c+>zJG%5c3n9ObI@oypJs*(=VbIRjwz3xbrZ>;YUU(ks=x%Id76Z3hZ#k|Lmy
zGSbPf<XE-?&|&eyBQLO|-UN4j0fhW##T+2iWkvdAC5XqiNiwTl`M&^CU4xbDG6u89
zUKgP&C`NPW1+)7N*vw!ejj){PX4Eza?@Tr=cbP68tuZ_%d|`{}zc0>>#yrQSNjho-
zmyJKAY%fkhyZvo!ZIiePe*rKRD~9zl+r^#TgrIm=Fq6T&^p|5qv>~Xr8&LQHSio2w
zWmWwGcx~z{wr+X1T!c*@)pYsp|69UhM>0v#VLGh)XT6;CYSfaXj{EV;Hcos^W|J@x
zJ=mWOqECxpqjx4aOi1kMaCy3ESi(w3zl*BnlBEu38H9-<rlucaC(aThn~^lV_~cE0
z{`i_r|NL_|uJm?YdmKr02U$3W0}zdEK47@sc>QsevFJ;KblM#kl~(bOv?V$=_}Qg4
zj%_KYCg)CAA20b+By)}xf+a`-)v2LH0$@`z@`%EPSIvGTrns7fl;#a&*Lw9<ztPoI
z9=rA+-^b?iCWc2BL019|`)@YfHSc#9ChrZ`zW@&YkMj0LFAY_CAv776zr6|-nd&1l
zei3rE?!M!Rhf2wJuNBR#gxd$!2Me-tO;4q@^W$xJxT?nwBZ|dG51O#8+saR@B-je`
z89y?VIs_4EkR*9=q2Z~qH^(ZtL@}S>OM3gr<)hU)u1B#0HCE~ufTxJG%tNC$#MzHb
zHs(}b`j8Qm5OzL~_=L*Z;4TQ#<t0WT{BFDg?^r2d#K;^w0oK)Rkiku-l*EoJb$gMO
z?&Asr&P+Tco6I+4#{qPAU}XwnWj1pc6)vip0)5@gt>8!PaPadD`*I)-9b$D1Z_RVG
zSL&4^)R7~mvLGW^Y-R?jjHhtdaejDhj$n4z0j{kGLD&*SfIwLK1dYNBI8yB1dzD#*
zaAX+=uP8DR760fD>E+4Er<CAUc39o}RjSI8Kr4N+cL$7|%3Xw7U|k0|wj>h^W1H=>
zPUaU`5ieXb6k#oO^4~F+%C}-p<t+#8$y;??kXP%vps3L{_!m7}X#Z8AD0$u5Ix1Qf
z9T(b<oG2oW6Hgi=1k=gcB3D&1Y*x2!Y$7VhFzh<-@VK?Vb5X&ILNTE0h!xR<qVCLL
z?kF6gpZQHNjs>^1hB)|Z!LB>ceU{9|n?Jam&XQ}4MEYy)9T(>>h>|~aXfn*-vp7|s
zycZD(PJ8H(;4<42E}uwBDz;C3a*lj`_-#8<*B`z*D}p!r_<=FM8}6+@gs9f8q@3%p
z<JI!U>ZsZxF8k9l93k_=*pbjp7mgs%$9=AYUu9)j3vn_HVBOf!5?=slJQw}vT!wYG
zR;SjpUbPYs9T_*bVY5U>%EHq7lG2*=U+c0u01+><6)sGod?KtD)6}^T>3nggNw5A;
z&$Y|)$p)`6$>MHGGV%a?>JXtBvWm>MM;RNB`>eM|ap@Eyt24lJGQbn_efz#nNx0vp
zB-iir)#>;7>Q`ap=U#>Id6nRC(s*MPb06zm8cV9Di=4b`$?fzv@+oPZnXbl%EXA5y
zK}Te(GRcccT#v`slAuYYWF%f;wX0_OS-0FP?T}he7v|C>_2K0C6$G~`W4|k7htqSw
z=-Oipn=&HWW9SjVgyJx8xrW<j8)zbaL7YdptXnabCSFLLN(IRf7RzBHW>=qb4JQz}
z;7KOKLr^a8Nrh0W5UE7r{S?J3GnCLNmOfuEswl_LEs-LAL>rRf`3!f<F0I*DCSwjb
z?D!rh4x}aw8Ih!!d;}~zV~F9ISRT0uXo=)(b*<g{@vDs>*sGJlWBaRR&k*4JF@W1?
zXyA4_n3Yc8rV#nU>-a<^T!t5tfPCEQNmxU*jh#D(10TrRp5p6~aH$Vbu<uu8^)?fP
zI3=!6G-k#|T83<-#!RNI#M+GVbG9Z}_TGVYPo?Gjq5G6rKfyfNcCEb%6{z|l3htGB
z<&vM#u%gP=1k>>}Eaba(U_--wkaP3|QR8SRXU)!CHoN0dvnEiz!hPj1D(6OtAm;I@
zKdS*NF}5c)W-Lr9E%NS_wXn^3TKYio^VCpV6tg-|Fd0d@E$ePr$cR!t=}e+DesXlA
zHo4SLVOHoU%9;tnoD|K70Q=#tY5cy4$rZAg1UC@#95Rw%AuW!ipD`FX?b2t>xgooT
zd42BeH@&t)nXOYSoT*>#7{puik%B0>wBPq91U!?Ea9U4Hgl*zPCf8JEOfEeRc;kJv
zs*Ha-5!7%j#x>?`TwapavGxK76PXc1Mg&<VEezXlGIXflASJrW7OYS*5<<h;$EUn3
zLh8_%m4K(~>Sbs-OA-+&>FesTAAuB+qa(~#8S#vN51Nuxz`)6niGnpI%q6wj?M(O4
zSkF0+c%P&&G%&=QEIYx8O}qdI?)w$YNifH!%a{Z0{KhG5o1r4NHQtX)dd9v(K4Ydw
zVpzJ^B0cAZ&&y~BBgDr4J{we`-JTTds{S2Vt4>`<bokqs?_SA<$6Km=WPilYYO;f8
z<S!GM9`8reqx+PI_Q)bf7HtxOcjE24VX=AOd*S+!I=S$bjl;%@v?~(5!Cn0p8M2d=
zNMq*E>fBC|hsF`EW7$cXW)(QL>%zeM0b^<5V_8KqbCcI8nd4c9A=y>t6t`q`yMk55
zFT-BHYl_S`^%rj;sNnJ!dncdU7C#~}Tq}gE#xs#75`&Gt&EY9h!zX!Xmu#YbKsttM
z+<WQKdCjoCBU7i24DF!iYdh*>*q#Dh>X@I=X_|4#p_7B?vo#;CD<(cgCC=TpN^u*n
zOnQM5_K1@jtp#?zu%1qJkO8?2^YIk<DGq~Z!tn<x3x<($(3pa-qExN?mw5P3Flabr
z<C8`SijI70Hwm68#2V{?mD^1<wwicpyIqwGjpmYeYb0~)mZ+q(Qi(WYpdRbLD)!S7
zWvpE{cbg8AIcc2+b@I``;6rmNC{IG2b!*Eo0}=FFQbM9;HdK!7asqjq3O`RY!R(2;
z_*#?}9gay^qzu!RGX_bi(Aw%_+0;94F2re=O&M1&t$_E{Q(n~e1A_NYZjBG+Z|2M$
zjgh!s%Exp0jn~1`M-W$_r^U}J@tln>@F}^#Q#kFQCcx33Rls#A&1^q;91uYr2^+fd
zX&}X^8-Z$5L1EROTqeXdIRX0%fU<j2u$<){>t0f~kLG+u9nK|;WbpoN@%&u%8@t2u
z*C~7!2i$jg4H=5BG!E1ING6JU{l5Uh7f#Jxgiqi+E!03SqN8n0B##EUyNljm%riZ!
zAyj?SY8$&Vzh!H_nAKpdwEGO>@r^(&!QAC_ziOy+2SogR++6ExgK=&IS~|W*l9V)b
zr~;Wt)gUBz^o&}~y>1|%KlJkKXmeI&jO@SGm}0;+d8*;2mC_Lu0;?X*_c%~uY5*X3
zRUqoU_|c2l2W`dtT4=Mt@%AH063)<^c8ng!JLQ*&)`moxgmmJ{R+#u8vw1y}_dW1D
zw(+!9iIU5dsxl5#!q1ahS)8|q)f{F{!(x;IU_{F{P9D~*R*ccXI<3}G8jGaeD>ITR
zCl%iVljl!LRpUm(J&rNv+}tE*yv4}y4uw$LBNkqUC8-|~F^4LeD{Bve=tW}0Azjfa
z;)wEBNf(l2l$XpU6fj|<SMF}Td^aQqQlR-RmB-^#WxK}xo_ED;lwqvA^3f}WXUohn
zwrsuHPWV_Gp@FzZgmZ(flZt^z5URwx24d_5u%|C~_~1L-%sAfqBHGDCEU-uS+9hO^
zx4&PAAG{KpF`4u%ER{lIiIZ@Pln(M9a{NH0wMQ;s&kdox$)JeF(#sY-+|TG-)>qcO
zkde-iJluAXKiA4+#!WrYd)ljgBA;v-dAWmZWTqN{LyLt><Qaa7Zadj9M^XVCQ#to%
zM<N<lgcZ<u7E1wewfpdV5y})YSOC2;@@w>*7$@skbf(!%GR$g%R*O2m(6tGXF<$^W
zrGKM<3GsrO0fczvwg|sgubFD$w3ryLs&;sRCt-eU0pB~DrjM58FL+czO!~qh)zadg
z7hX}1f+SrmH6oT46l~#189pvJ<eU4r&98RES*EIQCG5XB!<(O3DW4}DMAh&pNU%Pw
z9DCqhLs!Hm@Rvyx4-VA0YaM6UV{IY1ZO!SjC`+GRG-7NiS<M%My)mHUuu=RxRIVKm
zN~#|#aqSb>InDT{c{g|_V`d^dl(DR6cDN3n@HFEChe1Ga!P*n@VNd)LkGk;QgDWUj
zJek#HmQ81+N}@e!3401Cr6Myle7%9rXBy!qsAx9S&x1hMCa%%vIikaPl%SrMw#UPz
zS%W_h&~7d(n2=a6nkL^R6#(|uK$$&}`SZe9f@!$anzkO>y;Nz#$Ek;cbEUvWzEIC{
zA)bO++C4<ZX2AHQ(5+A)Nx)F9SBj$6gJE3szF|=?R<ckvngY3Zb{!V*ZgjS`P&g-6
zpwrw?LJ7g#`h1O))?0&p2(`?WAH}Y@@|r5DS@~<o0->0uMS`e4%=&!+fSY4h!XmDf
zKNs&e)&7{9HXF|rNMj0uPyyG(RU-UZ{(uRs_H8s0(wo_85Zsm0=Sc1&UgUJW$AUBb
zI!$X;^|Klyu3p6a(9ptoUa<seY!ig7x{^2V{Lxm_h4igctbGMU&H15mXnCG0WMQ;c
zTUpLbo7El$$<v8O5VI4H#?LD&pB-o|u0NX_a50(Na?|76l^;KjHQOrVa4|*K$yRo9
zn6){Bb`Ig-d<oq6$oLT@b~DUO%(ToZzZ|iJ7Vh%@bQL*wTA@~EJra)i@e4r8j4}8N
zAX@J<eFifYwC5fE=bWql%|@6u|Msb*>k~C!xRLipyRHXo!Z!F^xc(>8R*oa4uo^RM
zFR*lE5H)#*ov_!vl!7PB(F{NAT2`6u3+KOrq;^EbuPSWUllZjAXq^B9qb!3dC=JFN
zeak36vQ4*h?X24F^7KTukNHIhd6<b4rHD$hw;OTOvjS~HlVg+RK)vi~fdo@rDr{ok
zx@h3S6o26(X8(SVTrBYIvq${|jP~ST0PZo);c_cI&map7>zQ9XTHi1X(9Q4n{WydJ
zn*ZSyas?a57=o{`$n~i3qgMbZk{m!jN+lC!SqyGB#n2)Vt5U#|-un7f)GQs>cY?sQ
zFrAxaU$#!%<x&-_P)CA9nQB_vIxDY@L+`Rl3OwrWh?FW8*!VutZ#!c+vS}ux0P`W1
z<a*uWjN!npiG$+l7r+b2)1D$<&PB~w#RB=0b&Ou5?t@gc$8Z^NrkrX%>K3CGgE9K`
z@=NJ!>9H0{w6MJttGxQa2NqNj`NJjS6Ubt+I--H0!V(EEQ-!``#zr!z8I*__iSIdA
z|9x#S1y_D*UmcSoV4c1u(VkyV@oYubh{qRU)fCr`>@q2IC&{V3dZi-Qkj@xd1{oE&
zceDrYS1BNLvWeNKs!%qTuSi02Cb&yK(0|y*M#mqGXw|7a(1zh-QWb=a2*<U@T+LVP
zlIUrh`XD~PUe+?!$H|L>8>AXa(o@BS`~D<eX*%cBzg01s=4fPR$dk-#GF!VVu-#7l
zN(pN~1~D5o5)Xw;5D(IIJP%onMptG54>?=>d|zJk7`AtGQ(V9L3jjYXf3*BSrD)Wg
z##e_!cA0RkI8i=$9pfCXW*-j{Kq_^ZdQOirj8?aG3U!{B`pU+xLx*v;wj@kO-PeZ_
zTZbMlFqHj(a(rNuZX2(OYUSes_S%)lT<cY^e%umhK&iVb$ytG@g)X9!ckDFPSh}0`
zo2(5$8G-I@b+>@|3mY?YbzKgb>Hzu5h5961=tHj+<O(tq3gDv!=ZuIr1|KqLXyEf3
zcrC9m6fbMG4N8@RS1c8Q@z$C&ZKfC=fn-#KQgEM*PY{L{)>A)UjPKZ96`ls!55v!X
zDtaI9IU#(}u9aYk(8!b-I1_R!e;+lBv);gGFcV~n&CK<F{!>#AZB63Ec#RRkv{#%H
z;nE6P0}+bML}sC=GO-A2xXY#k#clv`E*w_$NJ}S6fkjC@<;_L(U0O|ZbEOsPgbGN~
z78%><STC*S_8zs`-J9%^8r$>x<d*fp@c?LA{iK$-=#y?<UXlC{reG{IcMKR?Ce7*{
zs`p^Lgd?UOC^PGvUs;B>^4%s!0D9>PKwwy-v8d#S!!S0fymyS(Q=O3o_J0gM-OFB<
z*XehYG9k+It)>fyNAQzF+}%C3#M$h6@_WuD`A}i+wJIA_4`Qx%CSUpK=j$TzUOCcp
zbZ@g^h$=-<qjkxEHHO+0xHlUjMtL6f6B~}#_;N=~ox<EXYrIPuh}rbfd9wj^@1)uQ
z#~w$z?_A1#3jPJak+)?#e}3)b+-@fnSur;iaDrhfIU*@MG$O6090s2?5tTivR1?}k
zl<0k>{l*CFKgI~)MRduI0%Pq;q?^2bbnYY>U8L=z8j-DIm8!KlOAMy8$k5Ah!Powc
z$a5uLgGjR-2q7kgVp;qngfKgqokL!Ia*uScO@p+k(p3*22ALWoKzd}K`DJxvk7Q6x
zsy}r{g`|)2ekOVq{se6~>Mm5=P9!?xl^>#sy}rqrT@su=6&fq8J719T4euZ8kNnVn
zWZfGIwi#_vT#o`iEsGm;(GfLcI0GI**LdJB>S)_+?%r|w^rjS_U7%6B7gUbTXc0WY
zQO)5cCe~o9e?h38^#VeeuNN$VK1w?jPn!vAswbJN)@i(cXWm*x6qvjY5w*Pm`eSS}
z{t7;ii1r9dUD9rGJ}+QkC|;|$dd+6Bg4#Zr*^gIJJfL{;ivJXzO3Z$fhpS&p)XG!u
ziQ<@A$_j4!LIJNevufQ*Bd>z^9a6p{#1{Z*$A;~!!g>Zw7QAt!Yqd{`&?AQOT;Odz
zzA!7IOQ!=pOay)w26|z;H%a0IGmj;7V~|gik%gxJrncj}f5juJ&=Y7*=ptO^Xl~#$
zPuB&duMb2|opgau_>7-Y!#}}{Al8FDfsxM6;JO0YOths^F?n8#!G*-7ii63^H)Q$&
zOTWSm!PPe&+?h=b1i4ge5e@izg(FP@d9@rwbL)*s67>}!B7XBFmo|%cqZ&g+e%P(L
zpEEvF{K8T13fk-}Glg!9rbR|6R=7^Tca9n+CsTV|CXl5@#;uyMWsD+VR^ztDgmD&;
zq<h&q<(+;P9qzR|*P7D3=j3zWK*L9Dh+)G-g%Ti}_I}f;f5BG_wLsKr$Nn6t5Aer=
zpvaeeSlmZ3LGj_0KEX~~O6ab#GcRx`@T(AtMccDvq;dJT4?-Rjt!KAB{)`8`Wjg1_
z_2vx4{b0TIbGBQ$63AMeuaswDHfqFfex&@%6aw;h{MpcsQc+aAP>)2UyFeBhoj_;3
zlJpIiR^D;4f{*8}b=0)Ex#e4?8OD-gbRH|*dASMRLB1Shma~h6r(0|jD=^U}S80$R
zW?t5^WmV!mEA_*taz_`O0atugou?)g-jNk8RSX<iGjx-75hQC&1HKvYTLJTDPTn`;
z>hKGqiYH!$6Ud%d7+e1O0x9ShDfX3fM%hG^p0SLr8z-IjN0SH%y||xS)wnDv-yFiB
z#{fJ&J{NjfL0YJcp%PhvQphjDDI?q$-%2FeV#ZhzMdv2BYpOq9zC@-1yx}hinn+L`
zNXr_Ls|bw@%9x-wef??h;}SmbH>P~Dy9D`qW1uRjp$9cFrx=3{2<CNUsn)Q<Zh_<Y
zMhx>d9W!pwTr~-y*ht%?f~(%kS2$vIT4@l5ZMC;XHGzVBr+&mO?G>UBApzNA*?`9{
zMIt45K;js^j=C#1?P}I${lL>8*Wj{B7f<?<?Ogb50SjT|Xf>88tMoH(`ceFkS}!^$
z$tm=$qOLUvYp{JY>Z6s6EvgHJh5F)K9KfeO6se7P5*zPcFvPdX>JHX%-3myJvaTf|
zMaKl5jwdhGsdxJYojX?83k)x!I99c_E9g=A3chPifNzyu5~<=+itdS5n$5ZT^l(=v
zzkJ5Bf;{%ZRyG;Uk1@caZ<_KJnn}oM%+egs)!TfVl5?)=3&3u&oZ^F^)ztkqSI?!{
zPnMz$q0{kRyf7KQFcG3Hxcmn@HCY{5$u$Mp)Eg%33ilGRvPQlf3a#YQ<(&IYn^B_#
zM^}2J53a<?<5(LBudqn8kD2e)m2<<@;>f0Hu;%RfMSe;A-0lzu2l9cJB5Wx_3fyI!
zEpFr5kIZubm+yn`*WZ4kKD&C%%Lh0=#D1Atg+Wh%tOKf>K_Y0-xBKt=qKj$Z8s9~s
zgaAPGTIAhXGubqaGYM6S?&dwj4KIGi9!&w<BP>&<riD6R24{?q=!sEi!<8124QXSa
zQy8DetBh6TngZYQpp$f+<kMIaJ_UZ3lYi+*jXTf2kI{TtuCf`8t029$26cq8z!>zR
z=YYiblY|YRyY013qPaO`<qEP-#v1S`6EX-9fc|-j0g8Q9m`!zRYI<HT$%N?#xNU^$
z1XY+m23wbHv$+;#14{)jXbDlL3`>hNO)5;&C(Ch6j?t^e)U6~1wx5nEY>-*$7h(DJ
zC8}Mz3uyHXJ|Qyg4C!}qI?eEqyi$C%=;PV9j&EXatO6wxZVT=hq>|Ovj!NKLMl3w!
zhJBWAxkG-Z6{qj&E2Z#>Q@2(6E_gj}oNgbF9x1#D>J2g0Mu9_DrP6zkkxzDSSNtX#
zvT6w~-Eg$ID&(Lnc;fpiT^u5j$<1EBE^C1i-M_gQUo>}tQ!^jg4~Ka&O;voP7>M1A
z^45I)2%VP?muiJ=Sn-mo5|#!3kg8^4i*BTuHNS;D7WCqMNZ!nKchz`;pw2Fawjoii
zg~Az1wL5y+E^;dHRgK4ZYrGl6z`qLuBIDQf5HtrgHU5CiJ|kq<8FP)1d`!dw3d*1$
z;C2Yf$HIMGBhJn6dCV=dyI+B+1OLcj1O<$?XX;x<?CgxzsiIknl8=w>KD+T~WSC2{
zdxY9T5-PyjWFbDQO|$UKT{AuNSGy&%y{9<fRjI56mA{&-V^JA^3e<hH7aTa|Mo@}F
z5%s$Nou>|o=b|R3j;o@1t#Yy-ru(9TY#}E6Dgrz98b?pB1>Qy!i4vnhXCPI{`1m83
z!+OtnNtO=>2r;+vn2s6X7%X0JDyjr@Q#VKn1%m$T8X(%KN`6a@lY@1>$FOyn+0OSA
zF#FS7r6r@!@;=!azLXYWsv<@Ynem$9_i9X?1;GRr&aY(mZh@xCp{ZLA3x6aYN8lRO
z9lmWnzDtr((fGcKC0uQgH#@XKzl0Q{<5~2hjj1`KgoAhunBCzOh5f=a{+hP%4QDtG
zpL{A$o(bAEE1DPRI?q36`PvP{J5t4vDdfHs6J$VT+>@H(SG8^^(^Yvoq)W4(I&Axx
zrkD%(*_5|jpRQgNecIEjH4{G4Zbp}ez6Rk%y~NPu;j~=LYWgS5CKK<UYQVBgXcId}
z$G4fbf({b#A+iW#8=OJ75t^z>5Vw(L8sla1DG?OJ?)#Ku)Pc^X9HbgV$;QAE2)nrg
z^84Nv%WKe%!qF*}GxqIt2ur>wAoly9iXPQEaWd~T&(S<kER&Gn5JgsSS*1oUVL!B4
zw|feG?%#0<rO+pdAtnfoN)Tc$4~9NtL21b>z(=$TBamR=`Kh%SXTu%Ex?>`T3U$eg
zSXYW?m?uATKz>3xf~uc5iN{1}3StAk&5CjeM@QpxR+U}HTa&FDVzu>dOHN1)mC@vu
z4~{Pm=-uZ$F>GMpL8PAyQOqaOI`GicpuCwQB;f8RSoblnsqGC_Wmo1Qza_s5R=7cK
z&wZ3?-`F@iL>ewkwBd-~>kb<!6u50ZhSlPuVm(JP3pY2UWZPIm&zni}n9Fe-({hPi
zf}&*R8I|ggucSu{gX}irQ)IS#q7a+vi29FNVCFkKWCW#|C)nH8V&WX}(9olpj#P@Q
z3b{IB{9DD+kTUOD$mfF!WmVt?A?OB5(z3i>Ev-0?9vFTBXv#}=I3(C&_LrvKyi4`o
zVj^$#yUgFc#LN%SNFXjjWVGk)f^MHwnsiBxK$GNQK$;8;)=KJyyHF21siadC-Jem&
zlrvM*t}Sg4?=CEC3>@WIx)_MPr2hiQ%@1a-Xf=Ha3L6!q3<nNfGnc7Oj7~Q<sytpw
zs0Dm}VYMdroU<Rs4NSJRDs!$RbM&gX2FhgS<fZ)8P@T3a4@Iz!&lkXIDw*I2#S@)r
zG%MW~Fh~e9nw*-};+5`LHel=*w^APT0xbv;2j6dY6<-A((B9>_WnLS!#28RkF^Yuy
zqP`s#5cd$*nQe2K@2;T@-9e1z(_;a!zLop}NVo*Pc*%wYeDM+l90CgT5%9Ikhu1nE
z{_GDDI3g|2qbGRyyjD+<fp1+(Nz0_6XfwR@3@fGQ)3GMhYX0_uB`C<(7c9FX^|ad3
zIrz{J=I!6RtzN<u@Ezh-tLxytzH50Zcz|0AZ`^!pekw4CBsoIM47WWacCV0a3>6IV
zekRL-T0k(FJlj-xAx9jqIdWES_4N5R83aLYt$0&hZuFFTJ7mQaj!`%Sxu_ZCs{Hc^
zrz7ysV#V##Of~(@Is2pZL2}OG*&WEXoh06;bjqs%ZF03j%g<yaiINH9{bw0mO+Jj!
z*4bV@uV#_M(d{=4rj$5mY!p1OSn?ymI<sk{SBQcSU&a%2(I6k~V>JxMpCNZ~4Vjy7
z?OF{RjxWz)c+Z|8Ze^9T{y7nYTs~dsUa84$6AdHf`MY5vk}~<^sqQK*Cl}7#(4ec_
zeVW*d`n-Ni%DwLT=bXhT#_QvG3z*YEXh40+w?kLrDyijV+I2XpHJ?6YsuX5P^u9Q`
z;Ot{GRuDCcDcf^0B?=0v9UvbyvFqI5z#CTDubuZ}HKZ)`s~u1X5Y1*kIu%8!`fOv<
zA&iM>pIC_ME3tEQYKrm^$Z8mXLm?kGrmx%IM8(vo-dYTyD6A}s++haU#0xb+2_AcH
z4o?^r{aK!S#c+4ix@&6=YaG1Az!Y9yWgisPt%oQ=b~9R)*XMl66CMRC$E6iRP3{yu
zS<Usc;LMxy!_g>=m&3Bd%!8ls#wZw8jCMOCC*o?K^;UlnX5>DD!Ma0E(d{ucyQ7SJ
zhH!)O);*k4_We3>rG-D|RANwci$2ES9AXLY{xwC8@?8_LJq&l%T2Y$e#ck9W<^5uK
ztxwAAiK5iU&+Z~SsBbL0)n5+&Kc;G2VghG$QfVwE1Bqus&MIi0kQuW_hx+<Pm`@4-
z4SQaRkChdRRTPq-@z5lcJPm&Wm#cEq1@cw?v*Ob$DJ3>^u=9M$O7~IS?Jl-4O_47E
zZl4FqPfBdKwx#w90D4s44$}R2acX@l6EadoMBVTmJodR?+Gsg0iB`IN5iOA&xlo^h
zZ&R7*NE-qv&QeDV4zyrQb@k;0LL2k>Jx5Y3*)6$H+gl%D^uVFZ8738ukCTxYFU6H|
zcNeF)5f>+~P8_tdkLHPVcwc4&b{M%#rQ{r~!SOqBXXs7DD2_IjxZ^h!AFu6wl3Z^5
zVW$$EaT(V_@+nWIdtGmX%T)$#J%^RlK(~*IYg{Z@BK*D|;S*>SA_IE91*2}}XdCB=
zJ0UfjXj`Rs4w6uZM1ex2a$&Lk2#$L08O<jy!i|A&JxW1Z7Is0}{6ma(aOz;P%K$kI
zJS;_?@gYXcwLkRj;NWDj3x*CPwn-GEIO(Fnlmx@<#Lm>8ax$?!cP2y6vka%jOOp}M
zW#An5n;C+an3*r6FN<fGAY6aC!t}$fZMwQruM>-v3`TuQqb&aw_JdUK4=2_i28~-I
z!ZBVX76q`+aeQzU7z^`z1RYL~o;Ew&5n*F9V*E5%Q2=N9#P1l>Mt}(UYX_LL7{6Fs
zFCT%_x3kV@l;$F={-Y}FOq#pQcPBRUSB~x}0}3t1?5^JN&_yYGwQnjvrR*iHtjf-H
zKMR%0C8UkV4&XkIyYD2STJ&|?zFjxtesAHRm}CN4F~9Tee}G@x0@iZ7Y2CPK-DLeA
zE|{mk015^#SXnJ@*_$LcDfAfPYQir9MYff9Y89Nb#UNm?%KvCX?cklk7eHxuuTcSf
zPm9r!?UU|i!#_d;T?XB^AffU|$ExRJ+f#9Vo3<gt3}9g7qX~L>AR|IhjC*{b3bfW!
zmYErb!PM3?XuGHRah5N8ridr~lj97pM79nf-eYVmV;4!xs^-)7Ol@xI<u<4CqM$3r
zGt6yFEE#zgnSl7M9fX?`!Jqdk?Kj|RUp-8-`p@62qt#T@a*PoK0j2u7@V%`@;kY1T
zBgq%Vx$RquW6Nh0J61O+=PYi}H;G(6ZW6dJ8?zD8G-Z8<igR0kC}7v<;|-Y&8O)H9
zb<c`2u2`Mq)+=8?SHny8^$WweW?7=TBQ@5ij7X3009SLeg!U9~>H3ta&SEI8WLf3_
zjz?0+$ZOXCe-sK>ODZmD<^WC@lbsV^Vg8pyI1i<#Mhj9i1W!6t-lwIVIMpjpFe{I(
zV>e<8GroiD-Z(bYHh<(KXyTh0SoKiCnAeq%nOz!luWr6(SfE^^N-ZWcd@s_{l04Fh
zns^@Fi|Ch8{zPEfh{gM2r#f)Ve1ao;1l2h>s;S6%@DBA&+MMVrYtD2Ys{{{$k4ox`
z#zgu`LoXQPEfo2$$4jStzrL2iJ||ft53zok<d#m<I#%!v!V7Wtk{t3(xx6TuJb4NI
zzzI@lo4k4bZHPK+^eGbBlrm#@6!amA>gUXIvQg2y#N2C!yGd_t(bGOL_(BJ+iH)Oh
z6cXf3>(OExEdS(>Ngs0*+w%E9S4_h`Pj7t?e10CfEFJ65MG{SIWR<2+hwnY6{evI<
zz}JI>MlmgYRwvfV4!%Lp_x8cF(8`LFxk-up>n5|kr?G?64^H2sNCTgTpRA1Pn9X*q
zWCRT-DZ;KjjqQhrDuPGB{;Z<@Ru|04o{}<B`jZN!WWehM`cMg729^i^3uOe3k$`75
z7sFbnmmjTVUR?!Y(OXIAa_fy?k+Wx&)PZ+-IeA<#t^`B7VRvv(vj%IYzcYaX&YR#s
z1*T>a@GiG5Xj^!pIK1??2?ED~*&SE?SY&Zu1H$;JC0z^DO5AtO0}NibCg^p#k6bNl
z@R5bgRAz{e0{ZLk;e;x!&T4@m1+d0m5k|Bj$20mi8)cM;%{`J$cd<rCB#$$Ux?&Ve
z*Kif^X9pMSbcQu*wiWWQmMnXDtCEzi!-7F#)afo091=^Y7wayk6{>@p-arFLL=4&l
z_{7V4NtH^xA-4#MTzP2`h#S{k%Y_ttHl=F-_61PA<bD^!<^zl5#4~2j5N^BPQ9}|A
z{Y-Dc=qa3_^N4AeAv7|aK=XnHC8k*?m#Z?#$~$!Cr8r;bMKt_m@}~$e3$LHUB(A`%
z-}@Jl7eN)}88FA(kk^<Z#_ues^B0Kh<9z|hF#)@Q1X**dPKe{UKAzwNc=d*}ux6}N
zo`omE_c<WKe`}5Ryv|;PhUC!<?>d-jivKe;O@2ibMR45R5{=i?Bk=fW7CB->bK*!&
z>KQmMt#ia$R*WkAfV322ebcafyZk4{aq(jtTrj5vshX*|(@%``;s@r;-hCEMOYt)r
z%dbYI{8D+)kO63{72*u+kTCINww=hW)@<#J<<%Yv7m?IlR54l0E~8eGpFrdQXsB;J
zshGKuUq~`Q6&4;?BF4T}Ta}5QQRA0JmY$O+<xN%NA@zT*<$sL)h?*+TIIU*$t?BE8
zxdnWB9KL#MG4_ZcP_2fkImbHv*u|oXiCXHsAWnKX-<5Z0iBD<km*V^#pkntp>0v?w
z^tY=u&gPyTiA_0MKwYK1bti>}^Q`GwiVJQ%lFrtOD>>_Xdc-qqT4-P7m-mcBw+tBh
zE}%zAMzRlYFLkZw_M>&J=Hx+B<)GhgW@(q)O0}H6HDCt1k@!Tfy&bFOs!Ai?a=DW5
z)*UL=jFTDsR_YTsG84ol;adZCgiiuVZw*?H#6EF@xAWwnfTq^W2KTzEy?-r+!VcfD
z8BA8RWNDjU{ahCqtx1JTw%iY%NK&5Tq!@FX(hPEYSYI0x^#7~v%EO_0+y5k#Wn`Mn
zWbBkmOvx6bFk~s)AY>^+kx7Hb7DbXJGM12RSu(cBG8ju~##Xjr?7Oj(K?xChNAI`a
z`}^bl_r0#?d9HKLbFa^HU+20$=iK)>4VXAVV8fG2Qil6Cms+g8Djc5O&J+pcRUnaA
z54cw`{qo7x_dJIqv67qSIQK=ta+gJk>5C(}hm#0)VfjL_frX8qBzuz6E)o!dA37$$
zveTNuNW1g_nG<6-=5r@<CzFOGi9rvYG8r-!$NFgBhYC%g&g{acIb8(7RvNVvNi?{4
zZgKFC#<TP@eo6PtMlnkXzEaBUzB!5{G194tL@5yZIGo0Pn$u=BHUtW}jv}KP*?pHF
zzHl1wBxX6?fR(wuXxq2P4Nq5kvfNE4RTP-*i<^9sJ(CuW=fs~W%mj+|zoL@mcyJfZ
zB*TyFjMp(C&E<Va!@|PG!Oq6Y{AKAskcJh+Cd+$NOx+F4Cwf6+AJCkaLo@NrF>!hK
zE~KdgUBXV&{vTMwtUueY8=KYxq(p~kzBKCMywRbrhOFa2?UwyGyBaSt{P*N^x4s;D
z`<R1Io3KptHThKYc;O?6>OPJ{iGac{i3V~wsD5USqyAwna`a(<idEsI=bc(hL*U{?
zC&z{z*rD6HMxRD^c}&or(tF7{+8dt1q|5{E#m02cqZ`(nD7%s<A8cmUQ+R>)?5qN%
z18PE#qj_0xnA+im7y3<T21jgb^`GLMw<C@13I!acq<k_K6^DC%da4dah&+9BC_dRi
ziDL-|Op*49G6-$IjI3|Scab_?QRl1<kXBl-!=s%d@>2vVz~4=fKk)^Pq);Or8I3ZQ
zY)WS6y^XY~1jto|oACVN2Ws*nS{urt*D1}ROAcua^N4u8punx1ZOM{%utJDXJ4%mF
zy^K;&e<$ef(3mjISkJ`EMOZ2cFXcEG<QnB^j@Ey*)>xb;@d(@NQ$p|MIcmE#w=GGO
zx4bhNFCWuWK^0N3xN=giVrHt|OP1<YaHS=^UI5Vl^4`bMu?<D-gjyS^9feNYZw%Mr
zkYdVK+HrC@%DD9PNBFmuqvwj>>2UYf7Vk83PXw;jp#n`%rLQZnk8?iAN-HU6h>++n
z&VO_YIe*{G;|0MnmrC5MI2kf0uem9BE)pL@E^Nz(Nz%$DaVsxOf=t$QUfreNg(`9Z
z(|MI_cOAx0ut=LrAe~2x#`5TnV9kK7@$V~D_Ac+F{jXf_R!KtEQ{G*E(etG;UrwDp
zf@i1bEuZW#@pcN0Vzu-WbqpIrk8I1g^6G9nj`#)5BFzl0(X~N(xnnm5Q)+hGc_32N
zaoty~2L~w_m}^6ez~ImmAVlN`H!{u)sor)wtdhfR=q6Gig}TcH$)3*c$Lc&wyrXnZ
zp+nQXsA2d(k7K_?c<<H+mN~0BwRD@W7IQziQZYMwfw;n3Z#v<g1#8=E9p(N3>Q#O3
zsq;{k-mTsLIq6~ha(`F#+!EB8o>%Bm%mkQX878BsDpBveb(n1p;mui9bzG2{#G&V2
zHC{Z}*2#hsC^~2KrL~1Sl_JIIf71=Y-p!b6a)=yy2Wx#3(9EoYF_-xnrf-!{*Bp@9
z5Wq<rwH}|W+T8K4TfnXS+zp`3jepy(^`X{H?H4K8IKA{L%E`|vx?`+3pyO2eKIqkx
zN}^i?dyt8Q7-M7LW$T%nI=Bw(Z$Qo<`T;~=cU9lVhqUqYh2V>6FQKewpyJP~<e^Nv
z$iSeoVf#0416r36Y1q2%rDA4nNx&V!5IMKR)o<>Ml0=2fqdXnFcB@~h@9B(hMl`jV
zO(Ck%t%VKCfDdXFVbjt|98pK0!hLreViJUVW)n!n4Yz>95hg%a5!Z14nBRbNq~(W9
zTxe8Uzq_zYY!*Y4{+L2~Ym=%`p%c^&6+P`RJ;lAcu||=6(d2jC-~@5GtQlv}zx_C#
z70z1wLn68f3l<iJUm_^+4GgL(y7}=$#pT`|J!@Tn2yK2$fX08MDRTiS4)u-AW$&Zn
za@;01IE2RLmJ<`pO)Ce+9NgS&=;xmN?Z*ADRH(39VV8dc;<(^$uRiT}$z-CC>}Sh=
z>xqFvOv+w9bPYY^=4i#T0<N~7>^((7?%dvURj=b$OYZbwv-xC+SjuyfyD%q9_^Z3L
zVKC2R1wY2qDQA+J<<S&OI7A;k?tOjq@ZUvhhTX}&x1)0iP*oa+Y3f=PAY4>K9PvPp
zT6j1_7mrA)s@nK*->-BqIwT6C5g&QmxcQr>&DU2KE$IBSYztE?KgMOrEg;_zV7~w~
zIA`jQhKv7b5R%rt`FcdKo^5e(?H86r`k=Ni-0!aeLa>!?wGCB4N}W0N&A>7#@x$3)
zA&O9vJe(OQgE;TK&k@d85jURF5J<x)YU!^{9?T>dqf<-%Bmc+vW<kU?bi|eDcD{it
zc)99uZPxsMhGYSOUVyW#wm~a$TKs!d=KhdF#3SqfgcRZZkMI7?407Aqb(gJO{8yV%
zj5ly5T6Zt^R#0+F-65s;E67a|YO&;#E_BUbx4SI1AF4TQOw1m?Z`R(2_8CzMS25PE
z+59{$oBXUfG$PpMzW#5(!0Lmrp^VU}>Y9Ah#uV)(vNzxfz|ysZxvzYW(rFj*JjnYJ
zMh#-sJ(cE8NAL`TmE>QMVC2dB;eLYk`Hb&nBZwLDCl_pn7tuiNK=owjcidMmp`n8X
z5=M=jzX1>e>7vb<442HtOL%mz*XGTyI<CSzbZS4rdGy{w02p*oHdd54uw2abnLX^3
ztjN=QLBW(H&{-GLfmtC7SIdZs@>(JCEuU+Tco<>mOxG=muaCR;r?`Y@PY?PVFXW^&
z_%opcl(RO1=z6`VwwX>Ifn2+KV^Znif_N?@`iz?zqh_%xHmmJYKyX{UF#78b{C4iz
zky~`!Nu5OB-vF-HQmXa+KW)CCW`*l0vsa_eukS%Gm^}=AzxrRergHRj`y;(Y0Rt+)
znD)guJ;^!W`0W+=1cNmtRny25<yW}pjnSSWPq<+7rf2M#k?YarSNI#i`#4cxio64}
zy?ad+L5LW2U8nXXj0uWR9H$on%EAkoo7QV7FxpjI#Pd@@OYZlALhYZTq|sBA)u%u7
z?b=Gd^ZlqQMs}*v*D3pR#X_<+=aX9q9>+?a=e^R5V=CFmG&H=h45BNjzEcTR+`I&>
z9>15}=byer7h=<)&+;rWmVM88el!q$9{f4hfXZ<`smL5|Fo>UJ>Yni!TJGWJIZEq+
zJ=A306@~;y@VmCQ%Bk)5!T>R4gfBNc@{DzFzqq(^UG9N?oh!$xZ;h}9Gc{`a{rXY=
zxs|2UyY>D7kEfHRURPO+mpx;+JF`l`GEDh?Y5OrejP7VI%bmo$VatC6$y>F`A^$n#
zb-;h(LvXvZr_NUU@fg&e$;$VX51fMc3JgnV4#$k23M`EZmt{}pEf<*h|1Ai1L7-iW
z0=ZSrOcF`sLwk-yRGnHk{3S20@l6YoEVSOi&DLln8^5V4P5HXsEFt+gd8zaHp+;US
z7w?v8yxC%<7^PEJiHqkwAFwCD(s!i{c|zov6>~PfCHXg?sRLTF>=2aX6|8Y{C}FXt
z@MHVo=tn3vLbFdnLFKd)x8<fRxm{7}>4$QevWknYf4DWAOGfh-8D4TB_ubJvSWM7S
zmnjni{ICDWzM9{<r@L3Hz&?yjZw&ZGUDte+1QPw3N$YkXF(3NQnDxF^J9~lN2$B4$
zc6Ouuiku|24A``_@6?rSLi2E|oH+DBT1K}}mD^$(;i~t&^ZBY*RU$(jD!*hLJrXV>
zqj<T`x3m4lkm=Z5a!n}Fr)+Acl)=eA^}4!EX>9hH?&Z@&;=r#nj<=D^Qofa~#V&&C
z;T8=HM*+TTFM_rlMdX{yCmBj(gni1V-45M;Lu7A0g@-NjHa1wFP@q<{K$A;eNwk;#
zWwegmNhtc`+F#q!w_r?CnSk5qOUn;yqCitI-;#?5a%Erhm!dq`C5#lcn<qn7_Nfio
z2#tEz!3eYX6>n2}Ttp-lEMAZV&x*6`ZmzxGV_Aq;Q`C=-T1;M6Dvd2VzTLrTgOOZk
z>lq+^_w<rDJNkO^rOhnE88yiVnx1aMp!)y>2bW7;gvp)`h8X9z!%GSuNH7Ib^T;EX
z<-&PK)BFi6mSZ4ZE}#&>pTlpHGnJ-&YI2>Yg?u^RS*1g5Zz}i$FUTs3pkA>DsF?1m
zRuI9cR~|@?y~G_7>Co+E{j>D}MtS+ZA$2H)#NES?G3*3XMEBag;}k>4h!xluYgy|;
z&AIGl=AR*f)*x(jka=T12+|4YLU-QPxrRI~&U@DygptrhQPnZUoMgxk<~Q2y3d=$1
zT<N_fm}gz~scBE(?;s7<oj`NWPnn?BCtHyccC-tfozH2UURE%Wibk~<TeL+dr}*xH
zw5P5a*$8!r*0{RjjYtW21d4hM)vhFO5TkOSwCyfNnefaoA&#ETCGHXA!8mBQPp5&n
z#19l51i5EqfZrZ_Fo7_Ait&m`2z;eAlXD$YXvX&PrD-*=HC@iIRkvN4ySo}_NL6pm
z?7`7`a0cy&bmpidKT>__1h{lwNq$<+a9#l+Khg!YD!7hG59jwVv^k7GVpO!P*locH
zL9g`kM%iaN`E#84bHtLoHSz}M`8}-gzSgnIgxS<iriEEaSX*!`$DoHm(gXe+4_Imv
z)_GKnY0amQtXJxHGO|H$S(k|Nneu_Rjc+U*0AruDBXrvl>O;&`W$V+_WtzrxaGohH
z>|->%6b8dPXM?gcF3z*hM~dF~HysPhm%;fqXO{UT7z_nd*MYOLJfCNgd8_PVaRBV0
ztD>3E=mt`v0plqH5!GVg$IN!%kW4ro{8%&#8}@*7<?}I9oQ}dfNMqq!0cRcyPCC@%
vAd`o0Bhxkgm|%sBU7*%HdkfvgY7{WzR>T6=TB5Jv45!X3YK{MScQ*Jhrndac

literal 0
HcmV?d00001

diff --git a/src/index.html b/src/index.html
index df57d46..b77274e 100644
--- a/src/index.html
+++ b/src/index.html
@@ -8,81 +8,81 @@
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
 
-  <script>  
+  <script>
 
-      window.courseware = (function(){
-        if(window.parent.net){
-          window.net = window.parent.net; 
-          var id = window.frameElement.getAttribute("dataid"); 
-          return {
-            getData: function(callback){
-              net.getData("getCoursewareData",id,function(res){
-                if(res){
-                  res = JSON.parse(res);
-                  if(res.msg==="success"){
-                    let callData = null;
-                    if(res.data&&res.data!='null'){
-                      callData = JSON.parse(res.data);
-                    }
-                    callback&&callback(callData);  
-                  }else{
-                    alert('数据加载失败!');
+    window.courseware = (function(){
+      if(window.parent.net){
+        window.net = window.parent.net;
+        var id = window.frameElement.getAttribute("dataid");
+        return {
+          getData: function(callback, key=''){
+            net.getData("getCoursewareData",id,function(res){
+              if(res){
+                res = JSON.parse(res);
+                if(res.msg==="success"){
+                  let callData = null;
+                  if(res.data&&res.data!='null'){
+                    callData = JSON.parse(res.data);
                   }
+                  callback&&callback(callData);
                 }else{
                   alert('数据加载失败!');
                 }
-              });
-            },
-            setData: function(data,callback){
-              let str = JSON.stringify(data);
-              net.getData("setCoursewareData",{id: id,data: str},function(res){
-                if(res){
-                  res = JSON.parse(res);
-                  if(res.msg==="success"){
-                    callback&&callback();
-                  }else{
-                    alert('数据保存失败!');
-                  }
+              }else{
+                alert('数据加载失败!');
+              }
+            });
+          },
+          setData: function(data,callback, key=''){
+            let str = JSON.stringify(data);
+            net.getData("setCoursewareData",{id: id,data: str},function(res){
+              if(res){
+                res = JSON.parse(res);
+                if(res.msg==="success"){
+                  callback&&callback();
                 }else{
                   alert('数据保存失败!');
                 }
-              });
-            },
-            uploadUrl: function(){
-              return net.getUploadFileURL();
-            },
-            uploadData: function(){
-              return net.getAjaxData("uploadFile","");
-            }
-          }
-        } else {
-          return {
-            getData: function(callback){
-              let data = localStorage.getItem("courseware_data");
-              if(data){
-                data = JSON.parse(data);
+              }else{
+                alert('数据保存失败!');
               }
-              callback&&callback(data);
-            },
-            setData: function(data,callback){
-              console.log("******local********"); 
-              localStorage.setItem("courseware_data",JSON.stringify(data));
-              callback&&callback();
-            },
-            uploadUrl: function(){
-              return 'http://localhost:3000/api/test';
-            },
-            uploadData: function(){
-              return {};
+            });
+          },
+          uploadUrl: function(){
+            return net.getUploadFileURL();
+          },
+          uploadData: function(){
+            return net.getAjaxData("uploadFile","");
+          }
+        }
+      } else {
+        return {
+          getData: function(callback, key=''){
+            let data = localStorage.getItem("courseware_data_" + key);
+            if(data){
+              data = JSON.parse(data);
             }
+            callback&&callback(data);
+          },
+          setData: function(data,callback, key=''){
+            console.log("******local********");
+            localStorage.setItem("courseware_data_" + key,JSON.stringify(data));
+            callback&&callback();
+          },
+          uploadUrl: function(){
+            return 'http://localhost:3000/api/test';
+          },
+          uploadData: function(){
+            return {};
           }
         }
-      })();
-    
-      
-    </script>
+      }
+    })();
+
+
+  </script>
 </head>
 <body>
-  <app-root></app-root>
-</body> 
+<app-root></app-root>
+</body>
 </html>
diff --git a/tslint.json b/tslint.json
index f29eef2..4fcb4b1 100644
--- a/tslint.json
+++ b/tslint.json
@@ -89,7 +89,10 @@
     "use-lifecycle-interface": true,
     "use-pipe-transform-interface": true,
     "no-trailing-whitespace": false,
-    "variable-name": false
+    "variable-name": false,
+
+    "no-unused-expression": false,
+    "align": false
   },
   "rulesDirectory": [
     "codelyzer"
-- 
2.21.0