From ad69d3abc24e22608c14c332ec81e07bbe99a124 Mon Sep 17 00:00:00 2001 From: MeowFei Date: Sat, 25 Nov 2017 14:39:39 -0500 Subject: [PATCH] Connected to E2E pipeline (#85) * added RetrieveSentences.py * removed index * connet to E2E pipeline * updated code * Some modification * clean up * config * documentation * added documentation * update documentation * update doc * update doc * add js * updated documentation * changed doc * changed requirements.txt --- anserini_dependency/README.md | 90 +++++++++- anserini_dependency/RetrieveSentences.py | 49 ++++-- anserini_dependency/api.py | 122 ++++++++++++++ anserini_dependency/js/Icon.icns | Bin 0 -> 102546 bytes anserini_dependency/js/IconTemplate.png | Bin 0 -> 1597 bytes anserini_dependency/js/IconTemplate@2x.png | Bin 0 -> 2099 bytes anserini_dependency/js/index.html | 71 ++++++++ anserini_dependency/js/index.js | 7 + anserini_dependency/js/package.json | 17 ++ anserini_dependency/js/recorder.js | 154 +++++++++++++++++ anserini_dependency/js/recorderWorker.js | 161 ++++++++++++++++++ anserini_dependency/js/speech.js | 182 +++++++++++++++++++++ config.cfg.example | 7 + requirements.txt | 7 + run_ui.sh | 22 +++ 15 files changed, 871 insertions(+), 18 deletions(-) create mode 100755 anserini_dependency/api.py create mode 100644 anserini_dependency/js/Icon.icns create mode 100644 anserini_dependency/js/IconTemplate.png create mode 100644 anserini_dependency/js/IconTemplate@2x.png create mode 100644 anserini_dependency/js/index.html create mode 100644 anserini_dependency/js/index.js create mode 100644 anserini_dependency/js/package.json create mode 100644 anserini_dependency/js/recorder.js create mode 100644 anserini_dependency/js/recorderWorker.js create mode 100644 anserini_dependency/js/speech.js create mode 100644 config.cfg.example create mode 100644 requirements.txt create mode 100755 run_ui.sh diff --git a/anserini_dependency/README.md b/anserini_dependency/README.md index 53ae9dc..0b51ecf 100644 --- a/anserini_dependency/README.md +++ b/anserini_dependency/README.md @@ -1,15 +1,20 @@ -## Retrieve Sentences +## Setup Retrieve Sentences and end2end QA pipeline -#### 1. Clone [Anserini](https://github.com/castorini/Anserini.git) and [Castor](https://github.com/castorini/Castor.git) +#### 1. Clone [Anserini](https://github.com/castorini/Anserini.git), [Castor](https://github.com/castorini/Castor.git), [data](https://github.com/castorini/data.git), and [models](https://github.com/castorini/models.git): ```bash git clone https://github.com/castorini/Anserini.git git clone https://github.com/castorini/Castor.git +git clone https://github.com/castorini/data.git +git clone https://github.com/castorini/models.git ``` Your directory structure should look like ``` +. ├── Anserini -└── Castor +├── Castor +├── data +└── models ``` #### 2. Compile Anserini @@ -17,15 +22,35 @@ Your directory structure should look like ```bash cd Anserini mvn package +cd .. ``` This creates `anserini-0.0.1-SNAPSHOT.jar` at `Anserini/target` +We highly recommend the use of [virtualenv](https://virtualenv.pypa.io/en/stable/) as the dependencies +are subjected to frequent changes. + +Install the dependency packages: + +``` +cd Castor +pip3 install -r requirements.txt +``` +Make sure that you have PyTorch installed. For more help, follow [these](https://github.com/castorini/Castor) steps. + #### 3. Download Dependencies - Download the TrecQA lucene index - Download the Google word2vec file from [here](https://drive.google.com/drive/folders/0B2u_nClt6NbzNWJkWExmaklYNTA?usp=sharing) -#### 4. Run the following command +#### 4. Additional files for pipeline: +As some of the files are too large to be uploaded onto GitHub, please download the following files from +[here](https://drive.google.com/drive/folders/0B2u_nClt6NbzNm1LdjlwUFdzQVE?usp=sharing) and place them +in the appropriate locations: + +- copy the contents of `word2vec` directory to `data/word2vec` +- copy `word2dfs.p` to `data/TrecQA/` + +### To run RetrieveSentences: ```bash python ./anserini_dependency/RetrieveSentences.py @@ -44,3 +69,60 @@ Possible parameters are: | `-k` | [1, inf) | 1 | top-k passages to be retrieved | Note: Either a query or a topic must be passed in as an argument; they can't be both empty. + + +__NB:__ The speech UI cannot be run in Ubuntu. To test the pipeline in Ubuntu, make the following changes: +- Comment out the JavaScript part and run the Bash script +- Make a REST API query to the endpoint using Postman, Curl etc. + +### To setup the demo + +#### 1. Installing libraries for demo + +```sh +cd anserini_dependency/js +npm install +cd ../.. +``` + +#### 2. Flask + +- Flask is used as the server for the API +- Copy `config.cfg.example` to `config.cfg` and make necessary changes, such as setting the index path and API keys. + + +#### 3. Run the Demo + +```sh +./run_ui.sh +``` + +### Additional Notes +- This is the documentation for the API call to send a question to the model and get back the predicted answer. +- The request body fields are: question(required )num_hits(optional) and k(optional). +``` + +# REQUEST: +HTTP Method: POST +Endpoint: [host]:[port]/answer +Content-Type: application/json +text of body in raw format: +{ + "question": "What is the birthdate of Einstein?", + "num_hits": 50, + "k": 30 +} +``` + +- The response body contains answers which is a list of objects with two fields - passage, score. +``` +# RESPONSE: +Content-Type: application/json +text of body in raw format: +{ + "answers": [ + {"passage": "Einstein was born in the 1800s", 'score': 0.976}, + {"passage": "Einstein was a physicist", 'score': 0.524} + ] +} +``` diff --git a/anserini_dependency/RetrieveSentences.py b/anserini_dependency/RetrieveSentences.py index 74dd1ef..87ff2d1 100644 --- a/anserini_dependency/RetrieveSentences.py +++ b/anserini_dependency/RetrieveSentences.py @@ -5,7 +5,7 @@ jnius_config.set_classpath("../Anserini/target/anserini-0.0.1-SNAPSHOT.jar") from jnius import autoclass -class CallRetrieveSentences: +class RetrieveSentences: """Python class built to call RetrieveSentences Attributes ---------- @@ -27,28 +27,51 @@ class CallRetrieveSentences: """ RetrieveSentences = autoclass("io.anserini.qa.RetrieveSentences") Args = autoclass("io.anserini.qa.RetrieveSentences$Args") - String = autoclass("java.lang.String") + self.String = autoclass("java.lang.String") self.args = Args() - index = String(args.index) + index = self.String(args.index) self.args.index = index - embeddings = String(args.embeddings) + embeddings = self.String(args.embeddings) self.args.embeddings = embeddings - topics = String(args.topics) + topics = self.String(args.topics) self.args.topics = topics - query = String(args.query) + query = self.String(args.query) self.args.query = query self.args.hits = int(args.hits) - scorer = String(args.scorer) + scorer = self.String(args.scorer) self.args.scorer = scorer self.args.k = int(args.k) self.rs = RetrieveSentences(self.args) - def getRankedPassages(self): + def getRankedPassages(self, query, index, hits, k): """ - Call RetrieveSentneces.getRankedPassages + Calls RetrieveSentences.getRankedPassages + + Parameters + ---------- + query : str + The query to be searched in the index + index: str + The index + hits: str + The number of document IDs to be returned + k: str + The number of passages to be returned """ - self.rs.getRankedPassages(self.args) + + scorer = self.rs.getRankedPassagesList(query, index, int(hits), int(k)) + candidate_passages_scores = [] + for i in range(0, scorer.size()): + candidate_passages_scores.append(scorer.get(i)) + + return candidate_passages_scores + + def getTermIdfJSON(self): + """ + Calls RetrieveSentences.getTermIdfJSON + """ + return self.rs.getTermIdfJSON() if __name__ == "__main__": parser = argparse.ArgumentParser(description='Retrieve Sentences') @@ -61,9 +84,7 @@ if __name__ == "__main__": parser.add_argument("-k", help="top-k passages to be retrieved", default=1) args_raw = parser.parse_args() - rs = CallRetrieveSentences(args_raw) - rs.getRankedPassages() - - + rs = RetrieveSentences(args_raw) + sc = rs.getRankedPassages(args_raw.query, args_raw.index, args_raw.hits, args_raw.k) diff --git a/anserini_dependency/api.py b/anserini_dependency/api.py new file mode 100755 index 0000000..f8ff62c --- /dev/null +++ b/anserini_dependency/api.py @@ -0,0 +1,122 @@ +import argparse +import configparser +import os +import sys + +from flask import Flask, jsonify, request +# FIXME: separate this out to a classifier class where we can switch out the models + +from RetrieveSentences import RetrieveSentences +from sm_cnn.bridge import SMModelBridge + +app = Flask(__name__) +rs = None + +@app.route("/", methods=['GET']) +def hello(): + return "Hello! The server is working properly... :)" + +@app.route('/answer', methods=['POST']) +def answer(): + try: + req = request.get_json(force=True) + question = req["question"] + num_hits = req.get('num_hits', 30) + k = req.get('k', 20) + print("Question: {}".format(question)) + # FIXME: get the answer from the PyTorch model here + answers = get_answers(question, num_hits, k) + answer_dict = {"answers": answers} + return jsonify(answer_dict) + except Exception as e: + print(e) + error_dict = {"error": "ERROR - could not parse the question or get answer. "} + return jsonify(error_dict) + +@app.route('/wit_ai_config', methods=['GET']) +def wit_ai_config(): + return jsonify({'WITAI_API_SECRET': app.config['Frontend']['witai_api_secret']}) + +# FIXME: separate this out to a classifier class where we can switch out the models +def get_answers(question, num_hits, k): + + parser = argparse.ArgumentParser(description='Retrieve Sentences') + parser.add_argument("-index", help="Lucene index", required=True) + parser.add_argument("-embeddings", help="Path of the word2vec index", default="") + parser.add_argument("-topics", help="topics file", default="") + parser.add_argument("-query", help="a single query", default="") + parser.add_argument("-hits", help="max number of hits to return", default=100) + parser.add_argument("-scorer", help="passage scores", default="Idf") + parser.add_argument("-k", help="top-k passages to be retrieved", default=1) + args_raw = parser.parse_args(["-query", question, "-hits", str(num_hits), "-scorer", + "Idf", "-k", str(k), "-index", app.config['Flask']['index']]) + + global rs + if rs == None: + rs = RetrieveSentences(args_raw) + candidate_passages_scores = rs.getRankedPassages(question, app.config['Flask']['index'], num_hits, k) + + candidate_sent_scores = [] + candidate_passages_sm = [] + + for ps in candidate_passages_scores: + ps_split = ps.split('\t') + candidate_passages_sm.append(ps_split[0]) + candidate_sent_scores.append((float(ps_split[1]), ps_split[0])) + + if app.config['Flask']['model'] == "sm": + path_to_castorini = os.getcwd() + "/.." + model = SMModelBridge(path_to_castorini + '/models/sm_model/sm_model.fixed_ext_feats_paper.puncts_stay', + path_to_castorini + '/data/word2vec/aquaint+wiki.txt.gz.ndim=50.cache', + app.config['Flask']['index']) + + idf_json = rs.getTermIdfJSON() + flags = { + "punctuation": "", # ignoring for now you can {keep|remove} punctuation + "dash_words": "" # ignoring for now. you can {keep|split} words-with-hyphens + } + answers_list = model.rerank_candidate_answers(question, candidate_passages_sm, idf_json, flags) + sorted_answers = sorted(answers_list, key=lambda x: x[0], reverse=True) + else: + # the re-ranking model chosen is idf + sorted_answers = list(candidate_sent_scores) + + print("in idf:{}".format(sorted_answers)) + answers = [] + for score, sent in sorted_answers: + answers.append({'passage': sent, 'score': score}) + + return answers + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Start the Flask API at the specified host, port') + parser.add_argument('--config', help='config to use', required=False, type=str, default='config.cfg') + parser.add_argument("--debug", help="print debug info", action="store_true") + parser.add_argument("--model", help="[idf|sm]", default="idf") + args = parser.parse_args() + + if not os.path.isfile(args.config): + print("The configuration file ({}) does not exist!".format(args.config)) + sys.exit(1) + + config = configparser.ConfigParser() + config.read(args.config) + + for name, section in config.items(): + if name == 'DEFAULT': + continue + + app.config[name] = {} + for key, value in config.items(name): + app.config[name][key] = value + + app.config['Flask']['model'] = args.model + + print("Config: {}".format(args.config)) + print("Index: {}".format(app.config['Flask']['index'])) + print("Host: {}".format(app.config['Flask']['host'])) + print("Port: {}".format(app.config['Flask']['port'])) + print("Re-ranking Model: {}".format(app.config['Flask']['model'])) + print("Debug info: {}".format(args.debug)) + + app.run(debug=args.debug, host=app.config['Flask']['host'], port=int(app.config['Flask']['port'])) diff --git a/anserini_dependency/js/Icon.icns b/anserini_dependency/js/Icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..607318a7bfc3479403403c4ba6a93249d781c959 GIT binary patch literal 102546 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

%goTChYSoe|XXN#>gxb8+TuYzbO z6q9ob-Zn|jB?TD#RrC_qu1(kb^j1{we&qlPS!*8@E^HJm$M(n!#_~FFX&hf<0Q%SX z7FN&CU9B;{){q}v1EJt!#|z-l;dBXU7b_&ix|Mu%u?e(i35_hhQA<>Vfe($stjDYW zQWSwOo)i7Gkmn}XJ~chYsM-PxIy@^6YW%fLiegukPyvrGc_X8$!oh26JRQ>f;(C#> zQ=w!dw7?)9uXH?ewUA2(Hh%~2PDK2;4EsashF-F#QMg^sKGUXYr|u5Zwk0jm$x_kx z#aWvnfRA^3i;TOApk3HH&FdTI=qkgQ0;YP8hi%A8O1LF{6%ueqU|>cR!F9C1Pco*K zTT&QmqG@_7x~XiZf3@tSS@=@NJ_V*UpAEo_f;STQI1?XDQulaf@eQ5vLsSCZ6@<<^ z_Myq}^uFqr<@Z+1#7KV&#MVh{N-um(k)BM7&UO)|KN?DQL(j6jHscW(or{NrCD<>5 z(XA_pdLJf?H?{Ybzn)yrh+^)V^=s%Y|ArfYIYr9>#T9h*86q#@>@Dl5cCls4QSTHP z#gWZnY?;BY_{X^=AELWYXx*}kg|l4I(1A7~~OF~Fmn%XZ^6Wxn;} z#Y6yBePH+yiG}j9gk^_5t^4f`gmdltk>|iOeneiB8rl-BTw-p~_0{q3s29;k9c~PF zixhO+?p;f~!Kl0Ntbb0=n&aw!QI6 zUQNUS1D8^1WhNJ2H*+xIga(Z9dyd)n$Hb({WQN(S8PfTz|~-n3{VNGZ7x5GyAqEfsrn% zTJ~&e+y55S*pQ<2aKUWXA2_BWH94_ufdoCdANw#DewxO0vj4`eG5BU*fYQu<$!RhM8Wji;- zHM(c`Y#*X25!jxZp%(An={0&aacqWq7w*>$novD2Y*@gMB; zHYbt)J2CkmZ}sZ9+b|!!P~iaI!r4~8GXud1xtDIF!lUu=#&1D%`XvaezwiMAK7U

L$d;dQ@E>vDvCJdg_6^wB z-mCop;lxAlq`n8L_DS&dG-HX=P&I~_JT#%Opplm+B^hU%rL+h1@|~oWKZfm!sA(HT zOY2)dDM8ATUK-MVvfu2~cS+t26y@i`=UCQ5O zHi+k2cye-%d@;*Rknvy+nX}+ko>9ev*)9P{+b?@%A4VDzsOWJBJa=T-vLyj&Nxs{L*en;qAHBTlRs2f+mxuIR2q3_O zX+>S(75o+Ub6d{V0NyB?teyc?@Wtda8I*NAZiAh(wNOJ!+w`tn2$}de(FvfrE)qY2 zVOo%6r;LT19N7EDz(|)NK~XFr>fc{}r$&9MRZV0iTR9j5KsY0tkH3w#c)ACvYM`06 zRgM)qed;|ZQCs|nftm$P@2DdAOG@Wy57AINqblkAF8DwpI|4f0iJlNSWpl zvGUv=Ch{b74VSng<8e$n&y7mx;n+Rq^w91e~03rv@uMXDO;q9x7Wf}Mi; zj(gWfD8c+Cz?jXya99noX|Gwv;x{E%P8{cA>?PN6xYCCOc$K;K9z1x@0QU0qv^Zeh zOT6t`;&{t}hZKFwy)S~^L^E{|Qu>A@Gx@w52dX0&wPsZcU1eTs-7=ia_ zd4tR2f|sve7K(+9EE_a{wEz(be^hIyr=k6YEJmfpEiy?gM9WinJ*2UL=NJ2I713h~ zWLILf_ECE}MQQKdq2NJ~mm~>Ds!zH1^X@N!3_87LnJ7t+eBRC*AZ?Yy*l;6s-bX40 z#BrLxU2|NxQv?~{;}Kv;&zpn?HeGP{VW91IkMxgkqTajkPWNG&B7+M~lp&-& z>#XoKe{q&^GXvUR%d-J?ksp?vztIAL1jvstb9JpI22k3~aQKNL1TFmxYO~2pY13hsh-1{ivOURs?8TzfS^>gVo`v&H{(2A`3B|WOi2>$D(Uu2*Sypkj^wswzm6?xk z9H#p(!tAFLtVeRG-m9b=u*Fa}q3c`=%Z$_O|KT!Aeq2(-pg1B`Y2T^NNL5;`D4a_2 z%P25Be>hvBPi=pw@?`adIU@rP{*WxbTHRA~6Z#GkycFfHLRf*jOgL9KJdbc`87qFk z*&Vk+-8I=Hny0-a3KS^8Ivu@e6x243B}k8O(ON-(FgD*Lzm%G`ar zh{VM9d@4$K_5Cm8*N_@cg3yVdGCU%~Ppyw^I84k{rnUbd53@8L;}|y_EnYggrr5IZ zdF(CUnZh|^6&~$m>lW+hqL(IcY4-<4gkR2XO zZk?c3^1=t6cl$5|#GZBEeIt+PU^!WH%j6|?hx2kty`i+HapE9o>9g&m01WX4`2^U2 zM;}}jK-QpZPS?~2y;8rgob+L_chIqE>3t@rKb`e-+KP0JnHV}226v52zOR1P7b>@N zsZIJXk~BWG&+ z2FhgwDckCx+p!Nzwc_)a)A)+%tbH_11VlD?np)mtKcPst03oxiO}8IRYax^DI#nym z?&Mz(jL~s<$?bdOVRVe8_QmjyQW4G z+$d3fP(BaFVsTIx2`(u+{rsM8XL4i&)zD{W-_O;6f%202lRbhUyzdkYE{kD_`w42# zh_$5_4;gKg2>YSJ(30xb;9GeNR|m$-fK_=L6B?>!`YOEVscPQxOmx2!`WI>I2VEL? zH)mk}?Vka~3D?X%a+jXGkI)$r0q};R72n=+q>?xPJnW(PH6ds$Gsa?k4_XW{I5U_| zfdzZ1$xOKDzgZ!Z+h;Zflj9?d8}Hn{+V;VP0i*-R`C@N?`|ID-5g~tv|4q-9bK8Sq zQkF9lJuC<39Xgbm@Y;|5ciKDx3E^ZF#i1jK^+vzbw^cH49ByHlT9@4(ZoN6q)Zk^( z&S>RWIj|=#p5LLRO(8kjY^7R*Ii22I^~$b^l9t6!#!lvgw_tkoDi!Fg;{BbZsB250 zb0C1(im84WLs9wGMb#_HF8nJngb0@8hn-23zR7ji--r-4LtWRxctg+0tmflL801tg z28|+)u>eoyRd|(dJgJDG_;r{)^-feZ&)M@?Hh0LE5vd+=Rf4Nvv)`2u)#p;4Gm84J z0J#dPKtpdpi4Y*U2j!x`7u-o$3Y>euo<>zx%3x&hoY|oDYo77x;&*{|yA;^qG!7YF z69Z|p>ThrH$qO4X+e$a^kW^Kjz>9MMo(;l0HToWUgz#g=l6H-KKD=|SgUo@=3tg4V zPu90hNI=93aDgA1%On*01-9T@v}(5a|3H7#HlRcd>H)M*FvImdoQ=RNxeT6PP9*8=jrjyHW`J}&+yKG=T@ zP6Nlbhaa}LyLfXjUh2aR4e@NL?mHD!L2N%6J-!ZoTGAoEMJ*!?O2{!bBm^zen5(Hm z>gnJm{Dd=?ZGwjRY(;V&)*sYz|L~YIrl!+B&eImXLqQjY+S?eP2t&n_&*=Tyq-~(D zN!!{`@?p&I41Rs+jpokZPhpY#axPSGnRa+2Y+ii7ox_~IyT4BNb7oLS8`nS7LZI$V zCdn-@)^+mSc~9MeUx&_%vNI<30PSAaD1Yh)YR(86iEc&RX(@IGTFu6Gb_S}j& zy0izOKY|wK+rEvMcStiII?-GkC=(P?@b0?z^lairt2lCO!O*;z+v#>TA4A+L7><** z1R#fa0Y9v?`m;r8K8Ax)DTDcn$=@iL18V1(W;_6)fDZXLmH9E-CAx8Df#StwE%#UF z+BJY#2>bQ0tr0}+bbo)#eEvJir)Dtk)ZLG%JIDy@lYR^%62$_Erh}@}?#zKl|kinfXZNx7|hSB=DjQ`WHrjRZn+5Mx1nH z_Sc{XL&r-BzS&IdTdsVdG<;m~FAVUsmyr8=~NTB=oRYo5;3{PhYjnFw+m z+aCQPdEZ&iKS;M`(3WdHLel&(Py1;&Z!b}VD~5|De_DL?n_8i?Lf_X;dbHeaeq$@j z)~FQx^Y*LQ)!@a3aP883?gRi>kx6~uq#~aYau$h^$%C-K1ff%i9E+Q_t!i0(O>nQ@Q{o=1JV%=mTt3+TcRv;;H~o-0 zf;Iy)LGQ++%BQl!TTA^3Q}ge2*bYR#0L>XXG5NN~Jg0vUY(RXQG@2+j{&br0;D>w`$Ig~3YiHxsZ}!4-G#QwU&cgZD(PuOCSP}DC@Xf_ zEE|i4b`Pd_lMu7BeR5;9gAB{#hZMB^^!pqmMW};Ql<+D5Lfa}w_ul6seeR2lzSFiG zLA%Vye-&Ilq6|XVJToH=Ue!T1b%o`!hHZ1_1Q=tfVD=cr3)~eoKgAPg3`eOd?+my> z3i-{6sWYoFIcI4y-JC-{YPNWz$0Bbc6&`XK)Z;Z0$%EqcvGTiUc>s9*Ig<+6Ea zG)&*5FvkM0OFosoLWv50bXyr1udW<4_kvCs!%`1d0^le|>iiHFs;eYv8>WrAEJl-5 zLN%t*=w;iCd4W?PL^HoGq$2%ziqPP`2TGQhR6Lnw_&>)v6Sam%#Z7Ps(zD*9@<=GQ z4PBeM6o6jylYypEz397y*P8CJeZH34h%@cKp6%Pm-d4Vc)fH!8o(+Z~ zpY?VuKoNGhJhsFK?RkOh^d><>c|!e(Tt(DU{B&;SS6VGJ_+{6j@~!HoaarzHn#O`x z4|^&Fl!Y7EXjmb=5i3B*-#RFVY`Sl*0mzd;(*Qj3dxG*7ligq@c0PpP|I+W@o-y}6 zSK30BF8R=r{10`*W{fogx_Mvx3hni>5iW){y-6d@L^!gz84lVDy3X-PGMdL)K=U*i zpxvmKWZmXtw9~;_Nt}C-vbO;@yI#2r86@Hbvi-mX5XvP!Xgyo^yH`SD^6vkdg zV1~Iu4OBBNGlb##xk4lP<7^2>e+sV;_4co%CEF3#V)xgt|Dognyj#O2$q&(8g_J7Z zTxtqW<1qa)*u(_R?!E^ftdKY;SO}V}Hph}LNzMBN$7HWn;-rzG^Pc!tj5X+~V{q74 z=(_`DdaKmE(YY=fbPG?Eg7EkrE7r^`Gp-n>-g;sZKvL6?4A6p4*A6#HW8V`ZRH6gSa6Sk*cp!Z2+{u113No4+x{`+5DfA}+Q$Y#ji zl*_EMeKNqNL&k)PFhl4i(7q3~t~i1iLbo_&Wbu1#c`LdYLzL3K<_}^>=5R@QqOndw zQFG)F;~e-1cdVsOCb@FPp&SEO%uR^i1aD@Krq)d@bmA^s_wWf;i0TxWnqTimVC@b} zYZLGM<3DMrLh>`0JRYNUoanvSbutMLn z^+9L&Rg}2<0tVC6Au)xhs1iUPp<%2QKTjB;iqw~!B%4dHRg)z9E=(rFV58sULPh#6kJ4vjXyRJZv73e5 z1T8-$Q1OBnkH8gkjr`5u<=&R<^E6H*$Z;|`=1)xa06&W%H1-_^5$rG7S$1@w5398X zYp}XYafz88zcWJS$KMtUq*cputP-KAe74LlC%9O2TwX)DuSb3gmBx5Y`611QTHbOgM zSmi-%C$y2f&|;&CN}mnNgJp9c&37P#vE=IiA-R@?JXaROp@~mkSx7UXORYs&mp$md z1-N#SrktpFl+}is*f)F%ObXpE%(p;mLr$02o2RLyf;&goChg50${zX%kKUTugTZQF z%Yh!oZpF@AKHnKG!A2`%;us1#?)}6D9Xt)1@-LpaePyQR&Rbcr*a~#Qvzdxgq~i?zb~}Y}i~H%x%`2D)uLN={5D4Rr;HK3>-pe-m zGcYhm%l>x{-PVWt)RHnj7(pwg?%U$cMOZmXso59wZH8oB+JH3t zwmL-2T_$yLL@uuN#xX@YQ0o%eVai5a;5RAB=i6bnf3Bp%?claa03ZG1vw;_fIO0%( zKk}t-gNKatF=e*&`&deM69Ab87%t`7MMQ=bTR7-b8JfczQQ4peB(n04(r``|TTQr( z$QW|7?nw>!lbFYXA$I_Rh#|vlB$TfwR-hJ+J01op;(e2S3~j`j9Wy-MQ3Tzq>04vY z4iysSs>wnRkrk~^I}2NL2-qSnBma|iDCn0({~980ffY4y6(43-lJRhq_FcsnzR9Ea zRL-|1h-dY@X2r1Xf=TUQ&H#4!MZh?l;!trhwY+p`_a|60V?{wB*h3}4PCbCDBi)SZ z>sAtQgJB!sF)L$O%w@r9&{+?3@j_qfwJd!)TRxP$o2626>+{rLZ)-AlVA{>2L-6=B za?kYAJ^q*6@{AJ-lk@006Pu=rRt6hY*6|wB%v=WjK2k%C;nWOn=hNm4{(+n+Nv1oX zMXgv1ZMzv1=k4)NlF%V{r$_DR`Gn)6?=@*+3ccbu7xHnU*L(KaEzH zId0Ks1gf~Q1F}mx1nWh7+fM#e3A#~$hIV_H1P^8i`l=~opD)64w?O&_MO!e-!P^-t3vM%0&m0@tJN3?xh* z|I52!0b%>1hQSIVqQCrf&3=3Y(@$2{{17wX<){JX=WR zha}HdJI3fFZ@W$2sx74>3~RcD&7t7c=Rynhqf-s7WoS|jppu0(C{;j&FLm{`1ne##give=Hvta zOOY4oZnXLqvtKV?wzR1&P|{b==|yL7w5l^Mx`t!sP~7D#MK#$S>OT*8EYz{JXz3$P zb=VG5l2x#>Cp&qguGxCn48baLamP>gx(9VPqn)EJ6))k)iTfw5@9d>Z7|x#%`6B^;%=k3r)rMf( zk@Z0rE|oN<>}Q(z@nfFX^)gz>aLhD92N!@Yecby*_%R5aC~v!FV5g|(sW0!3{Xysu zRRZZIODPXlE`9#0OqJP{lCZ8iPF>Rf%4L_QM!LjSre-!SxFgB^H?0Vm_>E=0nc3#C z^e#-MDd{39>gtQQ%X*(neLPiHI(|HSNxv>ic85T zC!R;J0Jd#sWNs&0(awDQhwiF-C*XpIH5anANdEM$qE1I=Idr6sbEm|jlOMKVj@s@b z-m@S-zy9BBQE3ER9>0E(e?cVb#oxZ)CcZdDF?Kyzbp;iIf!U|&sK^bu1u>lEn%q^Q z8G51hmLZ*@cQ&@4-;_6d0$qjp3JFg>9|tqNF`X}PJaM7ag>@S@s27n5;jK&6)oxAq zJ{4Zv`09Aw2v0Ps{v-H}^k;iiAOhyNE_JWGQz^4FTflXy|L*4b zA3wab_gsF|`RK3=1^Qh6 zXv&$WZL54fp?q8ay}Dwr_FjoB{`MH|KTbesI^M3QWe+juCt*0U&>^#fj^M1qJ zsZrxf+65dSYMNHrCS>bQvD{uzK6@sKed1nB%GCR9EN%&Z4kXh$4cUMVs}fcfmIO~? z)nsYn8KnieS8xkxl2LfxF{jx;*NcQN(-T5bG7ce~|7C4TpFaX!U4=|||7S{}twY*D z&4RiQd;p{q=AbK6U7m6814yiPjsk=L^jSOEPjEakQ-CRQvQ#03?`9 zPBQ!K_D06w2+i^&k~zxCN^WA#4&)xmo9|u=lIU7Q@`RMLt!}}`*^o?@w@pfLv zQ@DoBc)t^PC**Ak>I7%A&-Kww+<8UemRAl%_>Ov#jU99UJkB$dOwNSMKfANG z5H19R{_5Y2jXlFry);d~g>iaI^%WO6);;DvnO@A+FUe0zNS(_!&g?1AxXssvc$|Y_ z(8wo1&VxGB``f>2`{5+;RRC0=MmzMzo!&dbpBxv7HA)ZC%1~q~ddZ%h)ZnI7YUFx^ zm;&Zy>7ZMH5y<;Jvl)%3a-&GvjREZl-cpidtS0eA->vU3ZP)0u-4NjJ%}$QEmTT(S zfJA4MqbOj~vW> zPrwm8>~urPIxNGj>Nmys2OsaQxCS->H;Qii$>y%FsWvBC><_?0f0|y;sY5nZ2YtVqv^SIAcYv7%@ZlcfDj{UNj8g(k|gpSD^y1F7E` zz1TFel31riJ3|Ys{^O!v!&+JM1_#^=Tu$+&mhziiU z%Mpio<}UlTL(+^BJ(9+Y@4gZ7iy3h%?&|d4>@cvMx6h(FNAsq8qog~BS%%--bhRWs zmSdYS1JTy1HOgZz+BK2Cx!ghKZ6*>AG7FULo~=?{TqKW-p7j@aX7)3$!3dY;V&S~; z5{4B)8$7f#cc8CrDsz=SxGO`8b`Aa_kps#+K$KZ2$%}%Qp)siyo_kBF*sV%rdf?t?aPCvoTF!Khtis0 zcA6gElA#Sl)i34PXTXufYQ58whr{!z-MqA7aoZf}dci8~5j-5=JoSLk+SXR!cC5DP zkMmGk%eX2hdHK22H?>he%nCNL_NyJ-sw8r!f1QYgO#}709W96#=26)j?C*7R=|34| z&K6aafg7dOGHa8HLX!=f$NpoDd=&vnO%U}p$G)dAdT5ov&-K>LcRQl zo=w9Sj+WVa4CwJ4b%KQEQ-awM+>BuwTaE9 zwb~M_G0hlqcWs)Ro(mc`W>+#wfaPuHirT{?SVp!_tFBsS_umv^xUUe(?~bTx%U?## zCOy~+7Xyiq%^vDKG!ISme&xcC#v<+|Z-Va2;ZjrVdP!%~5F3HjVu>&+jWn!$F-lpm zeXz%(=q0C1vJrRk@?eQrvnxnU&vub2QHApa*Av~G(Ov6b9xFzSU_V;mS+%lw?1sw5 zoiUapC`T`FO`);Ke1oeVu?u#jTthS9C@vj6>uwS}g&%stpN@31Qrb09*Rq(Q>m;oI z*jp0iI)*OR{iMO`Ak*0M@sTh;=-;X{F$Z(0mq zl6sFJujqPLxrF$gh-G$!y9+|dwl`_hm;lL%f|-SHRU^e4kf5DBh1RN9b~mUDKW+D1 z%Rc4OD8G_b;16>(xnD7MIz(;Q6jdd`^24xqk;j6Yj8-ZXCkPgh!@S0C6*X*^lBoJi z`ljva9+v*jGqEao~<_h@bD}Yaa-!y zfiF}_#JAbs<;6mSS|Q#7q1sW!gVYmwJDP=&1Kh%?u@jm#tT$`7iDnM7CYFP=G~XgW z&zMfCW4YI&*0Rr;sa7$}x;t(pz;TZBB`)&JJfwI*AF?ZbjEVk)cyYYvWzwKH!VD$$ zp}mKxpX%n9ZNqwx65mZ3@^JFB%jacwF_qt&yt+`CjsR=r3LHyVXv{OKRVyHd-}`au zB$5hC#W;N(`**^Q8}MkvAh8X0tZ><&Jk#N zxnfP+#3t^wELDdMyFO`AwBCK$aDQ&fs;0!GrjsGrN6n5&tL*!1u`gN<=owG@9>fW| zd(M1?PYpCP>Ue#II$Ju{|V zrV3e@WrX{_ zdB(DipeYHVzGF9@v!^YPeI>ku8qp=V#)Oi=^_=()Ve+Tj8=5|Ci2t=o_%2lJ8=~%_KJ8&s z+LLcFjJKV-{!aKIfYUI{wuG}3Mb9qM&U?cR#gI~w@O7KBdT;4H2;EivpR{d^ONCcn z8df_1(OmXpp5BKmdILWARS^>;rXxa%$>}S#uSL0Y2aD6$p_Up<)9ah1y+?%~jTTSX z`iT?j!0n2wd@0H!c$=&$_2YS6A&)!d=Dth>;_xN}XfJ&Ik>0vf)lH7t{UuVv33LuOZ_vhJp{3EgFVWVM_#URO&o_hh0eD>uHEvYh zrK%%33m>e|a(dS4`RFCyCxq&`om|a+_XPMTyZ8UOgB3zY8a>W43YzMB=a&_QB-M;f zGR9rfx(8))ZlJ)+Ul6%w&HdZ6?&6)k7!7F01-msVq=tr_RhM{Msn+3i>`2B9kX-n3 zj$be(km*h;X4n|DXWnY%zSgdavaSK&bKIDB2)exTE&_|&4gL6b7E2dx8GCX!T^01x zqmW!W^)t;KuC{w@iH}vCd)B#nqP;DCc=0$h$u@q#r9%c0ia> z&jnpPPbawd#g+Z(le4v67|Y)5@5XtnkiAF9=i_d2y#rF{IR=+{Wm(ya@dKRer03-A7gI<4)yo_fzOP62~kM4 zvQ^dy*-2vTON;C($-eLFq>_Xf`(E~}S+X;gXevvLJxo!Uu``yz%>Qkv??=D?^Zfrk zkF~e=z4zR6&ppfQoHO=W3osmkmSeczt-4fWPH&IN?}u=jnd`)wiG5SH&1F}nS$HZ8 zECMI)Wqh1#b8ulCk|8Q6Y-Odjta3p(fV!s26clPnl%7|uh-;HqqTY&tKr(93t18!b zkg(AG2hMV7BE{F0rtm#CZZ;7pU;c;(j>TI(qh>y{^rdP2xmwe>mdp7HpO&C@VXhSp z*a9WsF6c6zp@NlBqSA;l0zR{v;cNT&m1`nPqjSqz$dKs3Zf}4Y`Lsgl$`(yK{bDj!u__28zRWG#-OoC)s)N+5Y|Fv@R|}4BUZJ#CQ3mjE z0XEWJrax|vgjAVd$+MC#Mb7Po^BcI zn8>^x2;z|UB%Cfgx-4Gb=aw>^s5{eS`uT>gYW~ z8cEe87cT4K9`2EwNx7qr_w&=kk0d!0tYtAD5?Y?$J(h#r$CS zDIy7y1a7KFSc={U0WmQbCJ-lLQKuE65YHfkzhNasg+7f;CK_ z$kkPQNYKfliyTVgMbg9rx6~Qez|T8(ejc+pJ=y%?g5IY{g3lSzwbUEbO=8{SK?$b5 zafnBI0+({cn$lClDrW6h7?MO5C1Ac6Z{DlIlt#eUwlafIlwbLmu=2~IRSL7qWHgS+ zw+8Y+r$v3~Ei|mILKYxmXEhqn^f1Ai`??!&eeV=z%boWEK!^vV7-pA{SmPc*Gz4t}+{I|=}A)`#(A&@m2W9*8(I74LzqquiK-Xh z2+CMjGVrF@^Zy8tVn&D!HKWLknJC>gHFQ<*{dTGA;kMnaNp&QBLr>>@Z$N-5MhVf= zlxvpg7x7Eqrs#G>)%L5Q0^KAfR#K<=lZ4PU7QJPFHI09ZRAAy_jV4TIJ0IIDotpc$ zIKoL)VuG-oxv}k=sGLQ%t~ad|Ki5Bfc5NTE%FMS^)P!GCn|~K+da{t7q06ym^WtE$ z`8pBPW)5zrb=nZ50lZB%Ofd|s4-q^@ZLv`E?fn`GK>A&)=5Rh%H}Yzydc!r}-= z4L?%6lwLlLshv5zq|{C4w@U9zi!8Mwg+FL0Ja^#wbP_0 zbTx~)&4(nZ7i|ZbzGX(3H%|0hth<)3;dPPHajOBhVY(Z-z&n~xi*xXc_e2e;hb?+x3B0w=2^U$S{VXt4TYk{Qn76!hIZ{+kf=BBl3>&~hB z;3~TTQG=KF$LpefB3GMa7(_Mf&ng2u58O&M4VxE{j3-F1al77KH%N+?=XFc`L8)vz zq?VBol$6WAsGIV`kN!Ao3J^`acFj(mlwYL6E84hV2S_;~i0GwHfB{k41BLnLtpA#N zqPwnJfWP2sFB^Q_Qf>ks?2;DTaYcoweU<#2Dngj+~k^SU|PhWE_%+LE$;l%GRD!P(If{0L3{TR-cA2G1hrS8x5j^ zF3DJ3>F{LTlRPuw%EI`KTS&XznKFxYZS>&mq9SycV9*-#VDfn3=;c9DLAkRU;Y&%ZVYdKVJslVB-C$Z5HCQy zqVO3^NsKXz9oA8Ec*NAB+yy!yERYh~=d(}CcK!;R^_^NI7cVwy{+#zdtR;wf(@d6F zmENhC}N6$O6?H!xawXsuHIa6uKnkdtA zA*6dZ*j|PAYeKHrxyAEP^F_YIE^Rq|W6kT%65 zpF9A_u)Ysz;o}HwXOWZz4DULViM$OJrY$^fToH=(X4am5OnOa3pU4#CwKAToi#zBZ z29#%w{z{I!rp+T}2P^hK`0(QLub*yJ9y^8BL4IftIj0W98zewarw)VC52uCWc#&vHyGr)oIvS+@znT zR6Vi8;`KD=b$$z#ydX#LEqDD1*|PmQ`eHX=dcS6rvh3;Eo4jBRoV%+?w^CK@3WAP% zNvrO9D*7Uay)s16j=jg~LY@!A%OS~!UsO{HYrc43z2={H^`j#^X(L5kQh)bGEBj`C z`4{j4yd>$tBugPQ6!3tOeBzr_O6Q@40(ZoVYevFBjD@BRO?*XU!~u*^2W~%kQud6i zq5tv*w0XIgQri@*J`2?L&d48&eG=X3U|)*MX-P2~)*sU}-}CFKLHuQ4e!#`J8_v6^ zWuM=4(+fa_?d@wIsq?3HF1_f??np;10D|7y+2X*6hDB7dbx=0HFWdOC;U%RE)JE^5 z?%qm7JO^0h{=H>x*c(d6%;pwuzko`dakSNb8<(DkKpN0W0(7_N_{=lJ$61Yx*p;O= z3U>JE1QL(J8hE*YqztgPdBAjTtN>T|CsNKNg=S$tO~YEZeJ9yI_8C4PD&S)NDYE$q zA{l7<74HQ1H+rq3i!PHvRek}dQ;ErJSa2dql|{pK3Icd5?&I-uxn+IdtJHS~_LG=r z@|AbpiS)>bvAIkONfCXf>q=10__`BT?n<;??H@VdCRX_5+=Z^}S*y>)WmELNYoeoh4jev}knqFgl5X zly}l~bK-zDz(BTv$Y;et4NS==yir=Zaz>PYdF}x9*2gJ2tVR$+AsG+gm0=dBP_rPs zo}!P#?}d|q8B8+NNy(K;be6Gpbj`zomtdkE1hMU|wWW021zB{8bbndxhALL2&dZOz z0L~s8n`2(I8k#VS4S;v>Vq<<$dLMwAf(7(lvN6YQWZ2xS7q3_RM(KG2-R?Ozlsj;B z{PrCPpum#t1~~Z{o`Jc8TYPJ?lGy4g&4%=Ur93 zgS`wx2GWRHaaD==%mlobyS1UaHWP1p7s65E8U3*eqy zPiq2%z|>?MTp;9u`dli&kY!O%37+QJ%s1=RS3XbmTs>H~`AOsT`z_<&2d}E=(4y`k zR_cW&i1+I|Fx#n@3zf>D_How3_f&WN#(Fz2%Xt6ciz|88fL_*q@Y z0xhY{MCecL&^O{fA=7~WMCqFU5TGyiCD`(Yq#93^%T2x#00h%sM`HgEmP{0141tfX z3&!iyWLjC}UR0Q`kMOH2x%>>6?ve0o*`!js1Q|cypd1}FbfgTXijgKl_i^iK3g8}$ za_fn72DID-1tC8b_d#c$8wb!S#C6g{9cI+4yVF9Q^;=aUT7?qy7{f=aN%{Q8s-?&l z;wzP6=LYU?WfbB+%zmVSrw;Y8?Rn79*@Au+kPYNOxz0k$Wg908PpJb4A`t*TF^kAK zWD|DO3=7U?#Rn=a-{+-_s;0>83el3X%N-X<+*GaNp(}yr^kCTOx}sXiNHzo*|az!G{yZJT|*QD@|=2$b5es^ifJ)er7l>Lbg+Jm^jhdK6)F_;VPx4H*Bmm>dj)mR)ZBI7vmDwv5V55dxrLCv` zye^&$vu?wsf%zJmB~bGzTZ$HDLV;dIT6{QHkaPp}X!JO;b-i*!wwW88=*0BNO|FL6UaF z1eKdZ76y7cNH2v3Xy|Ozu8hoDUmU(M@0b~&p^|V}{pviYUzLGVN^8{$R(eD2^k+sS zFn@TRkDRYizl?eP*VlImb;)Gu}cUayD_j_up;x&51MUKiq6 z2@3W03@6XuxdzxQ5|zHLRuIWzvn*zm03l(FsUU?+<>0s}FdGX7mDdE&>9nM!XFb?G zQ71b_FmN|Ebh%nHONk1FI)}$RH!`2f(Rfq#smK%Vl>KF~ckhkCyv{h~Vukp8EH%Zl7{`9GxrQLFJA8M%1 z@A`DvN!HvI{<16p_UNk`QYwgHNGK!FdSwuKmvJ!W4`HH!Sff8S@qP!NuI0ia zpbk%;=B@FqlH!1wJXobe+A>8#bZu$d-LEr&?poLMQBga_-&GLyvs@{>H`A1 z=zn!3bLwfX;<8Vv@gM%FL--dFy^$B8=6Yo~qwED*eOt(Pg(B%!Bc7z|pRALFsV`@6 zUdCvU1scj4>dK`7h0JBzUm~;kd~^;OClsL#q5m2tNtKN=&E^MB8NS5E#HBk*BOJ6(zR(pvA8f49Zwr|;@00(Trv5L3(nw1Ysj6RHQ-NA;Sa4}z) z;-&?>1hZMZ;$e#yFSEk+K=su?o5Cwm$~&rj}5Q z$T1T=vcOj(eX!HUwGL=2fqcq`2l_gt zkV$s%V4*`|YxRu6uu2lCuC6WS!z;W(?{*3@>gzQblr20p^qc<$G}AyPomqFIxyus0 zE@z^=;PBZ4m2OXe0ixXD6#QOzcVX(nW2$I;{PO4A@h>|_F-?rxNu1pFK=VwIZr35s z^SO%E*xafca#6tR*tg#ihx1@yEkMu>`{_UeUD7GuEJo0nW%9I~tG`@?1UZRA8h?q^ zLKC%ryGD!K10p7exuz9p)inN6Pct)aE*5o1{*WxnR*Vp@*P9$nOdxnq=G?`yt{()c zBI(@n^KZj4S)3u+(FluN8?R=lC0N5SFi7r>T|dJ?p5{a4l8nMMzA*AmQP2)4Jx}@~k)?C}+lwn_<* z)U5aDLU*@DuLAykbGoJ1Q_lcbdTN9eC#B-fc0Aq)!9Qpemj>NetS?gruNSLEWde#^+xkK)|IYANm(>8!KAGgY{=)F z-Z)()2<+i%`ex>iP4Z6KN?6MA9fo6;S+$)tK&Ia2H~E zf45hLlyOm&N#gEp;?04S9RLCW3E^#gabtkFj>2;ll{oV&dt0P)RcTW`?;Hvq-ipge`YkF`{WRikh zW1aJIf(&)B!tBY@Z;Lmd3w}f4!uSG5+T-xE^B&P!PRTsfKE6e zn%gf*RnWci9=}#d(49;BE;=kxq-BlCtlJ;V6A+$c+a1fA$mDC8h-qR#ZOgSOPn4GL3xHDSj znnk$l2(Rx79CgRN1Bi22DAF1Uj=-jeWqVyiudPkV?VTeT8Nnjy9l^|otnmEtL>+R} zL|zAfaD6iV#S9=RNS)6tWd?4<79 z0q#t)CItph2;d7zN2SF(#Wk$o<`L6@$?{d*kJr;tObFzYQ79q~UvC(h-tbIFMWb*X{tokikaQaGCEb14?tG-yu2dGV6DbkAa7Xoy{jxg!& zvO(j)_xI`b2tq~JL@bk56yg$DS=T!(P#_;J%1=y4PeRS6Nb?3cN=6vio@dXvt`N=( zD9rJw3#k3w(FR(3fu+G>9NT3axaXcT!_elJK{}N;UzJ*9E6yaNY?6u>qlB3cP<+k) z-|(~ZBFGPM1$+U#Y%se$U$#eFmOz#^L1OEMc$>G)v)9m27d}0mOgPF$`d|c$Y`_hD z&1Gf5T;a}`@XRr&4t4XnBC4}a{SZlOLuZp1z%#VwyL7V;r?axd0oY`E8d6%9AbpI5 zdaKxD018q%&cDyH0A16IdH$qfeN8DYi5Is~Dbl!zbOE5Xz%QE_U64$_Of84va z;y4aQ0MgfhdXqOXcK;?TBBxA?1HoOU{~o+Wa6`UC!jQ5N*Q`t+0>2Ts`$Pw5^A^$O z)$W3OC=X;gkageOxd`~Ua~n*xc8MB16|a2_~H%|(h!h4hmg#+B+Fe-+603IJ-+ znqBqHvB3{3YesRZabrwyIhCILv#tiw_>WT_NF=m*wpHYtGjpNCj72O;G^bqqt;YTh z&swe=bnec#$z`?;zeTUe2_do3WIiWKm7OEb*JMYkrW zIFZ1GW7P|&N#ARbZpe-}+0Na;h*2Rj>yz`JWox+^JD6LAggt^5%CE6QnEi1|uC0AE?scJ}IORn=ahyWbapNP>N3jpA%SWr=1s z|1;nw(W&fsE#){>znIsB?|DO@vr}LZqZ!Epmq-)5?1__bTi#JVHW-xV`wNl*JFJrC zcv7HD{l#z00>}S- z3lsvNyd>;ed!4wOPj*7d5_W9m;UKS`o|LYM1MXe7IoxCtdO8%im=@^nWH9aoAammI zTGLX&Dn0xn`dMosyhT`)FhN{~kl|4%%Yz<<%jNO_j`3_NSU|yN7b%0Hv+BaG6LS>< zb23&axrI%FMJAztIATN@xUM{1xE&IgpH5LB$0M+?uxy>{Xbk(j5wZZD3c4)$jbBtB z9*T2$H^D!!mE6?I17tgC!zl7gWYctb0PSmR<<+!6NF3@{y{e0n7EIF4d%TCnsi@^< zxy|ed>jXcCiD(ga8~c`Ln-|LukeA9ViKPF$g_nPb`KtH*J12?U+Hd+BKrVVB+T*E? z2jm4JT&N@t=c!EYmYHy@V{ zrZ2d38{)b>f__u1H=A2^jHw6i|%(J*O zRWNn80oT2>sWzr~-XoiWuUo^u#sy#rQp^crLq_K}=x$iB-76d*^ge7)PI)1D@O@4S zdl1P2(g7_O46U|pqnEw0|7eP=PD|IhEgM4z68TF-l7aYf#Y9NU*v8qlko$Ya(42U* zy7U)a%Q$(VVIOvi3O$GfC5m=|1&~xBW`NP<5+!XztJ^OyH19`3DR_nQMfJNEbMz973Lp7X<+|9e(XzWyc z*Q{lv^jfXTuDb=3G2DLew=(XU4PzpXI4*m0%_m0Y>B){eeGsohr&XMjrN-AY<3U{AlrpwZqM+@eD=C_jMur`j|!WA?zZ+p}_ zD%EsRCu>4`;;l9ywtt^-EpRjqd8fXd)T4O03}c(UfW+qk=BKXYK^S6BNoWw% z_W=dmU75UhqjgeevL4gN3784M6y74ez5KiN;_PcKW*yp_z_`22 zg<2$>S%DXBzh#}t4M{53N^~d{2kO(vP|jsI5d@3+#RYbg`jp?Dn(*_O~N3~B$r!N zT2-aW1MVu?2a8ro!fsHb&J%3;EH$DvF{xsI?9IKbO#iUpq^WmM;Y%$>hPICeI64L_ z@YCA0%q7T&c>P&SuHtMt^idTYuTbT@ddr8WhYdjSiPgR9CA!YYm6 z7l9YIt{O6d_mz>opaPKSM~2ZMDk61}16srqDwxTM27a1EUN1ZMUB%ljJJ_gT;iX$i z@fN8M02GZFxB}1hsDXeNM!qbbKrxfv6x6S(kR;juHMKdFd+3VYQyGA0#Soy$l%#IP z`r*BhEyd$stM(oqbPEy!%mV=d7XJTD0bmqLK*cL7@B?(|-fM4Wo&;6T8W-HjcpT|6n88xh4}&U!#{7<%4Qze zv=^U{4ti^Qv-ZZ8^~&#i1xMxz2)q)o>#FNqf+$hANR4<2;&F0QO{%1CM=60l1BEF* z`bN*|=;O1u#`r%7Y|;K+k#KbizKJ?*QToPKY!p}wW+P+j6w(e zqsxx`cv)xER(&1!mf1?ry|Fg`Q-`jjLmHJU7rWRmB%LWX-Ia-IY*lKUoY}G&o}EPw z#>Mb<@EutY`I(A#?$^nd$2You6O(;cm6U4FxCD7WlRLkqZ5X+2o_=J)KsR;=TM&Ed zH#za)i{B{OnI1NHP1M4PI*GhT-b%S3=sg- z6{s`($ow7{TFuykP^VjN@y58gdyWd>N8*D_+^?*ZLxX zw(tfZyZfzjMlT>shzdmsJ0Y1zUdr7QidZOG4v#P*hCAukE(Lf1S!-cOmVXfq(4S!Wvy&(vOexzi zTi#c06la23EX?HxAEhFb)$F;r&7btogYzAYVCVwX>0IVYNA03(oN3IG z7Wyv`a1lfUHXI-F|fWTMZ9(M|4drKe#Z@>^!W=>($B^H-B0gd{YNQk32V^< zp$drMygpejKi*~~BO+vali>Ka)|P?)k{%FUO=KAS@+9LR!KWMj==m23xU8z`p}+di zlaY+R`WDT+7r{LoVS?hEI?T4!cdXT{y0)I>ZkjqAEeHwhfB*9CtUGg6h0pwj+ zb(z|$Lwv0i+uEetp4xBX9|_GSipgf+R`(H4uWH{e2;^L{2bif1l5ZFbSF3< zFu#C)F_9~4b1g)cJn17LDgwI`_P2Pzfk@sYrTbhastv%g#?f+aAsUssulArUhkLm% zV(|V{%H}RD271rKdpjKrKaIx8juF#ep2(v+I;%2-Q(sLvzv6Dz^LMy61aEia-a)Dy zPxB*Wg0)bwzn~)uT?C5-hc$ftxd_J{cqjf)kbGg!K_%vXSW2nP63#|Kdl!I2-U@S%qDuC<=nc3|@FX+@&P`rr-mSB~yTJ1O3i3ZZ){ZS<0qV$Ow) zuX8gg$cs56FaH#XI+&YsD=A(atiSuc#~ggo(tDm^iMr))V_Vr~liRJEVAb%^>qyi%5{Y2g_!#RM1sGPJQomJWRvh zS46-NBj%wC9p%^|VbEpiu*Hw|8|PzEKKw5ee{YR2KcH;GEwd~j*{WG3=x3|ZQ3eLV zh)gqI_&{m79YMFt(L~pRrH@FN-|)D;0$0cIgDQ51#D~%C&D|=E?zDHFLqQ&oo|f)k z{OMozYyk36vgPi+NzOD&Wg+^x@7(eJd6@8ixH>U2n4&i5yX=k}tq&!$`S7pd50(O1 zrfZpV|2tNDkCF@aB<>v$^!nnwEdp`T zjOO`MdgE}gCub|Xsq2NdN_Vo}eS0&+edJaKL|{589>6)t7Ugz9dV&R((sq^;r>MFA z!??hnS(QP8fQ=CS2-G$3yQ-8b+Um1f+j90l0tHxkG0V&cQbfaf;L~Dzr6P`a&mFhe zf;;R2^@m7e(tBhqQK~ge9l~s0-}=CR;RaCo@IT`{zn)Fc1gfFTmH+`Ro6|p+#->(c z38X_nDUbg=b?Hn`I8~_ZSn~p?$A9|k`;eHFxKLaUSS?^7{?m}J)sII>>_;@%I zi_}*OATi=U?03`EghYmDmKbkdb2>SE&e*7tr7js+fv_gZ$(M6Lc zQtv%7vgQSyij{V zhu9(P@b3sTfQ?XL)ezBKF`!&1cjl-9vR9rDpi|+`;CeK5`0^E?*a@rpjU(d&U|?W; z!7GD6SQ~a^YCx+&vOV!p3zpBD9-x^gl&-$lVZq-iKO&2O0&l>X2zBTkgrDZDjAAP@ zpZzG-IFhw2Ejuk0x-Hioc_<^9gI>n<4^x0pa>L+^$x_zNXr$j&!T(Q^|{ag9y zi!}Dgc!J=E?52>RE*7;PbUb1L?eDzt3*{_+P?z502@Cy%-H>nX=dC*kNiQM)D~)d9(M>vn|xrE6xDXYAp8m;|+_M$mZz( zvKUbN%?*O?I7T;G`508|SmDigWMx3s2wn=Tp9DsYffAo*ueZ$KDe&C<5rnNK9D*?p zR;VmZ>O30d{I!^6&<0Dvd%6>QV|T(gBi_|%B_;PG)eAyQ_F>by1NIhEgSBLU^{-p% znKYk9j2UfnK0c}=fM8pcYs<8uuNT{=&LBr{I;u`#D1S}EB$a>pV+n$5CvHyF9{b%` zw*W%dglHZ#H81V=vM8f4dFa zqN25iWM5Detaqr?3hFa1ZahUpX?q@l%98Kj`(k5nPs!kcoVO(Ud86I(;va1m18WoBzsDC6Zh00g$gf_6C|k zJ#j}dz5%;%h#i{xQ{u0=5*%p@Nl$5@*Zr3=zOWj@AL?<;0-)Ewnc@z^Xa5_J)*_p^ zZQFfszTb+P7ov|I7XYZCY6%q7KGV!U!JhRUNIBXPVB7NV&hrYE2pJ#J=mg4^{g)G- zka_FOXK9(pGohcL%&}*xFD=8}kIwnQ4Xc6^7PchSm#JKxFv0HsYB>C)>(B%xjXeUL z^HR!>Ft~a2qTH)F^E||{_a`r6t7tp;AA<=Pu!dp%F9hR|n|mH1$ct7opr!E>BUcerMO)ebnvFV?j>#7+=ph5!2huEr85=x zUk3)eJNNbu0|{u&4g&uu_R0VTrI@RYZ+NP1ssma|Q(@P8rC0*|I%qzhh(GL6dN}mj zUQLVdPs$ayh__d`pu+LBA>wOV5N9|Wz3%IEmw!*i1I_HRm=ODw$lS+TkTQ*o7`-Qo zKVtu7R-llWv)@ee6#m`}6S!3~ivAz!&lCZf0L+T6EYo?!Odw@y41O%`<=ZI3p$zyU z@AR=64X=L`m3}Hz+GMT3Ait{O>1^gJW^XTBwd|Ms_#aCu2LN>drqlrp*%NsxeHw^! z+CL%*D8nXfxN9lk6@kzffGEO8r2Zhv{=5XJBvM-Hs=Tr__4(cdApBw2M*)}o*Usa% zI*wSTHEjM-{&7Vy)-2vJ!7-Kg*D;SVM%PvVo!gd+IRH8Tm72<{K!zL923drB(M5h) z2`4Y~kBSO{{UY`LGT5!7tNTR!xU08)z1~q)170Nv_@ZI8ig0gt3Ke^4gv<~@9?_t6(AQ;-QkE;p;xp9wEBB?~^k<>?+&8B}Rt7&(V4 z?Z4OF00d=IzaAB2`c%V$tq64GVYOY>saN@c)PA!rm*RIN`ax5n<1X`wp7eBT1bIq&s-xCP9<}2*pHao0H zBVFRk^hle8gUm$#5Anz-OA-d>5}JgzCZ=BBgZ9=?!KMrJg3LaNjs4>eQLY67M%&v0 z>VPYIkk>q!vW|PV?(R_%0kq~}E>zpF$V8cwc4_2G9@n?!ZMyJ(M!iUlx(%k+7*9qy zkzv1vLIGGoo2q$g#lIBqAT=u(djmdY?K9BX@>b7VcOANr&K^IP^1O2QvfQ?YyXOkr zU}31`h^RQs>l?-?IHl7$S6XKNL4GGRRsMWmE+7J$|1!6AU8p2|}2JX7=X;e_!~X!D z4g`!j%O){ivxvt{WHbc?{DZ3LUM;&~_0aC_#fu;iq&GreSN#|@8#VA>$DkTl4S}!R zdmohKz-JGC|25zX*uzl$3aG4$eHQqE%2ngG2MEN>xAy^t8uBgyuW{MS(=?{~n53g| zL*+!rmx9~ZxY(XPI=>Ev7Sh~$`S9tFx0GJPnz?VCE>W70or*x~-g<>)emryb!K&1g zJF~BJ9;sa=KV$dmq(Lk3S2XRQTis&IwgpA7%kNB&-{~H3Z zW8As8rVLHinCID~(Ni^lmr7%Omha1Z)}{*2@)@ot521XqN@3KlFK3mG1@z?vr&g*| zsOcf>9la{kaLb$gQVJW-g+6$<-_`r*8GB9%QA4^q6H^fPk!gxms?@7G)N;n8v(B&& z`lf$v0CB9xME#faGnZ>AH^E7izQ<(I)ahYXNqyJyAZk1%YR8~u365-1XJq?Zu-0&) ztW$MrFANIB-?=}~n?hqfo1@n0Hy3(sPrF`=Dw=!mA{{eT{9H%eLB%h%AwfP4i~G)a zRddrrAZAMLc|SbP`17ePwm=7Ll@4zgJDp>JPQ&u0vd$aIB3wM%u0Njr>I?d~Iq-|2 z7R13RYYx7HS;LIEZ?y|&C%)?}15wNbzam-ST+g}5x34!( zZ8BbSn%uM`Kj}P0#j!Q3<~epQ$cdz#qJob99SeT3)FDTyFr#hosl|i`_r#(r^LiVB zeK4n)V%L?r+QZhG+~T3sEzub|KI(G@4jZ^nWw7I=Aza@nb}f5k+_GlaiR33VZbU0H zozQ9clsm=svgW~U=ygW^K69<{cZNNJy?Xp#bB+mo!#k9+crGhVU4Sk=++{sk9UWqi z#lFyp!`+|R^nik$vJJC^` z!y(+cWRd@hwdJlk__>4$#A zD;KXqp-<7j6ILFk4ps+;xZdlk+fb}(b?KI#2%M%5S^qjGS#`fuA>e*z=9sq;Hs=`A zEyUK6y6^GzQ`L88!&7TQzn(=a?p9K#m1xsL)3V(34Zb_pQCe7j*4VbXlBh2so1GE;xknu>RQSnB9`&N! zc0)D;Px8ZWC_WilKK{^L|3klz-D-kSn){W$A5j15V-^ov+EEv3b5lyPG;FKm?e3TL zXIJ8GHqt$nqU;h05mgGk+wM!OUO3!qo!?v#lY#1HqSPFEd z2{2f)zdBhnd zd@C_vU{rr#cJUft;RqQ2{xr30uLX5Y{kPli9Q0MkpQLl)!9#fe-0)aA>eV}|{+~tr zoCl^$=-Got{B$3W7rK+4+hPAzTAz+?d>WEyU=wbXzuEfXyn}|fyvh0p|4es_F_96D z^t&Iw(`LBeRK3XVBxjuo#>HcMrcxjd3%@ddgH1cYD>gA*G}li|#4Ts^EGQ?;&R3hS zrDCkq%YnQ+9-DV(76li)6K*98woNnL5b2r;yY{h9j5Raom;PdtTlU);BlLs9kVmUM z?NOyYD2ZF88WO7)`c29teQ8jQb|)S;Sg3>(78L11!n5AHiP2mDKol*7+B`MR@>gln zew>=Q@Me`-6{lKde$xi;G}09o9AXqdg9#8VzvA*s7HUq}`jF-2Xa(}idA5h5A1JIT z%t(QJ>ipN(!Rp(OPJN$y__js**@dZH_g94u$F7I@ZAP4COQhBh?quktKBIo_@5s=(p(9p7}5sC2}jT zg57TL!LJyV($bB0iH|M97qhXTW6M;+4mCE(Et4D%-;#_ASe}Tu-QTAdjd;}h(k*mg zB6c?Ih9hj(Q|~N3oUbe(PvCfQFeCJFEcq?y1D(NMzH@Xl6khK~3o4i$YL0&^<}PT0 zY_tEqyS&l!m4cezgwZcH`+5J;pfsW0mHs=qDIJkSP!8_R;vYT%h|2%UR|yb^t>yp9 zSMZ)h1?|gMGxx&#|9|8wo9Tgkoj0dJ-B3G8IL7tp*|S%7Rv6TdFB@E^Waj=^9Nyhq zE&g8UmZ-3BO;Y0h;R~H+HZ>Qt>=@U;E8-;$&%HUUE_L!_BLxt18OJw_B#(cbjim zbjeiNc72tZu)vxULlzaPHZooAuct_q_vL7vC2vzMp`{JGO99Rz@g_+m(IY7bGhXB- zzwjAh8e3k3xP!*=e~<2_Ald)rCq(S0zEx$94~v8pg;2fgVvC>SSPLadEUzvkfyYh< zG!iWlUZVr4!ZsGP*Pp`rUL<)(HIHrB-aJSA{EW3wn8fzX^gNqi!Q!G?gO|gXRB;jV z3kc)Va4ntUfn+%EReEU-h?NQT4+B(80NiVVepEYU&3?_|bzeaHy& z*{aZw$}6->*Syd7d^ZnUUsvNPS9n?4ljIHVRQ`%2YSf9qi3|yZ%Obw#+M|Ojm zdO6A0NCT0k*_#)#Gw4MoL}BAETiBBs`0xHIf;LPn`8 zfOdHc6hj%)L>kb@I0Gx?9OWD-E$E7tbs9D3Wu)eM$th#U(uycWDe*fKQmsi_Uc^`J zr+)F?;kF^S&>r^Vnb=m*dzn@b2{oY7(6OU+wG14y@nGm_q@@l$9a#HGcXKcx`6p!!5o zK~S4{_KFA>NmQ8hYToOvelv;}*ie14P|S%I_uhUl3XNnVkF)MkBBJW zI+$C~s6pf;xvwJPSkYzdJ3UUFmK!&lsX@0>dcDqHbXC*rV%z>K)v0<#A_Ah!pXzCF zhxR*V$h5%ks=P*d9x?bi(7jhs7QS|b#8MJaj68133|Lab%~;HIV^<7V)JE8XEVM*> zwgJV8R_2bOEl(3tf5O$3YWMfIroqI_)IM^8A}L3TwAy(PtC+~iZ{lK-Cfz$S>okSI z!&&}z%p|j72qyO-*2J#QUq!5+x|Qj9e;8O7NzVxpJh<8ln@-Fg z=N7%&pvXsV5mwb_=w6pyPRq~%4iQYYK(;B{oEoB#`QlEYvz01w!PNhAGOO#o(9?H+ zgU?GZ>9$xtYFai>-;-&l$$hUW7hH?SxXi7r27w-{-32`^GJ5}rwNBxTWmUsx^B8rK zlv}$sh9#h$XD5ShNs`~cDXjXbdl1xoqUIr4vCy!D7~_Tdt5W@C!BrFAXX3X|TmiCq z2DG^!5mK&6=D&VFiT`QK8Pbw;a@U`<;*O#Jo%^AY_g+`ZC#q+TS*g8+gr0==GD(mG z+6)O^luQ0lYdLA6*p>Vg5=s?ic$WO3SOw@N!QKuEM#SmNK1+b%(8j-w-0yUf?))qy zP9_r0gN!TBo4*mSpkgn6FCw$BI*rInIR{EMIInhG0+D31_I#+dq^z^c-+BOh0#qrU zhc&!!W%jwtXLYyUnV7ay46?eC6Myw9f_!Nn{dD)sWa^go6NoY=-plD3Ejvj;t8-jS5JVnAH*~2(U#CRn}SBcsxS_4 zCazVXLPozuVqFats^Jy(Kc@qM=vCJ?%Ac@k9VktY~=5h2@ddrPr= z^>z>`LZoRcp4oFi_m|3)Q{i$euk2}`t3DASyWF4K7?jSQ{vTW^^0CkQ>8ERHk(L?H=_>j@;8>CJIY$0nO6Gm00PuEpF{4OG>a*q5O zqNf{NHkNc94xU~w=2VsxZ0~qciUmm$>=Vmxmz@B8Eqs3E_#)*589#}<%q>GF^7I%A zpM@*e(w%f=v;y@9)f9PTHk~)*;DaYET(% zVpe9j`wlbu;z%4`tb+7*&^O7({oki$^6a)!43WG*MZ%I^jIo$im4MKnt^8*FG6`Iv zrJp@i61DE3?S^jBXSYGl^<6qm&@(+`MJ)?bmDZL}5J zA+?V~s6os^_`!D)Xi;+Sbr(%$Myt@UR#5?Tf!QUiP!;?j0{if?G6x#ksS0K?phrBq zR<79snOFC#;r<2O1v2SD+VRE)hb^x|%g_gsCFlO6 zb(Mc&ByYd=GuwcoZoF0RBeuD+_8~0hr%MhRcgsvZ0&gYzt00kCl;r#OoU&H7Af6@B zt3k;OE?x~n0B$*r7S}t30Ts|}Y`a*ZfsTs1z zK4ANupP^o%i=Hn~Phpd>woRA#?{nYxx!3cYL$uV*+*T$QM+zcmxB?H~JA^yj5K_$Y%x8BxP&jGuM&OhI&O1f- zpy>PzW7>ub%kLlUZGvQ{x>olp$~@wh0=>>oo-&D3r}pXh7z9Jq=Y8j)iQ|#>R~Ui~ z_OET$Ef<%jPbWva@cH+3Cc1 z!X;9VG$|uKV!odj*VwOiuyTO%W<{v5;uOioE~OM%&B$I^5csvF!3$8IM!U%3*x_{M**C zi6P<7 z$}c0N#F(JJM#uPNc1CJ*I+47Md^)S|O1go4i#*vn%a5CJ zyiTxd*7x17AFE-Uir70{latsiqkqrRh+HcB1mQjUs$Bz~>lehiUZt`_agzM_h6c)CT^oOXl)6`HOr z$&`znXHcVTUZ~lZg&K1N^Qfsor|u3UsF0aiNz;C0+wW_l`U_T;Y}TW0<|ZueQZApR3vJDP1y$`v*2beDJk(2E~tg5D+h zof98i9iP~>myigD>M9EO=a`VcfVtJ@G*IMD3I2GGS3DLqcHHiGKj|OA*$*cr97X-9LN-s?l!Y1TE*m(r z=ax%DT(U2om{u;fziX^LBlGR1$H>faD_M(l?mzlo1lZ(SiBBAVQ|B9?xLQBVKe z6xL(F#3=Lg<(8`-77KA>CW`Vu_A}z1P9_jf!yNKib_Bv&2Kv~yt7>kOx?@i;#pj)) z*1gN`gYUFabP;Vu^wLoFo7de88@I&%=JDtKYGa5pGlE$H7j^TZWT0EKB*8b^uP+6c zOt{;pavq3eu95jMmsED-k#aD0pZiiR1+_7rqj)Xz?vtjzWAALnzuj(*sj>C^Y<2t< zmC>W!*^yrDg`vW+2=D-iph3eDRpphnGe!U+O zCHnN4hJE`e;YitP(>v#9R~e!8gWJ?9g0o0a#7|HMF&@N%!`voFxy`8IgZ}7vre<7~ zr+0u9MO9Rf-6!>NJW;p565V!d_w@B%&668W4}^pE!TS<{^N4Hm(v;=E&pu=39<9}BzX2jrWB+pxdYguap)JufMUx`toc|E1Q*9T68bFwb1*?Cxg& znGKi6kff*oq2p0;8tjmxPg|SoLnT&}obMabPrN5zH4l3;*MY?=W>R@2XB<#-XH-gg z_;Sy?*taXmFZ-4SJZiD}y}io!ok@O_zUuYuX}rmeoTj(i%$=T}$3F7nGTG_0RF)3n zQgpQ#FXcE}kFo9uzJ7Tm{4acz=yLV-#bfP<<%?LI9H6-mol--Sn{*$zShdEOopSjc z6%RRItn|P!F6!Y1MNFukT7dJ~{uGrQJl)#()*#Y}sd&dIw|DrJ3Kz>L zUDcD^E=1mL?%tpAQTE_29%pW^a|(wDR-YBkMBVTLsx#2H*dvi!YT7C>&3zwY$HQs_ zPTdXp>AZUw?aIsSr(j?FEr2P~Hgg|)WgWXyWNgzBUjuLUT_&1r z$rD^2v7zkp1tW{6tFe)GsT#j`1wPyyx#*t9)}iM*{RC>h!Af|`NhhGMz<5WEezKOm z;wA6P@pZcyodK8MPxb?uS51YjW(Q9{KW7mhgI`8CkIN;b5vW87tJgYcGWP`t%s@2K*O^k1{wdtp8@KvUqZR|bFurY#NJV_>F1T@yM~Ln+ zIl}59L^^j>mBumvv~}Mg(+`i*O!>J=FOs~2cNp>(0!yIkgHQ=WMO!K zD1=0&nH6WA`Tu0vySv7fsjKj!ad4FmT4vH=Hff%m++@w(QpHK1SJ>jg_cjNruLm`s z$s`aqNd?~cUN~c^ajTVMdb#%OSPj$TG=;hi=h;RFqyF27u@&`4A;-!(53@Qkrb7Bm zA@XBrN=>wa!De4NpZV)=VS%eQZW^Sd&^gPj5#4)Mw{l-AQXo?8=OSJWgD1n2hqX)L z2xDj0Sn1Y%e$x2$7ae6-{%TQH!R!;1B#2y4`6|7o>PiyS+xo^y<+-6=JdN<1b%LwvEWX z8f0#_qv^-g7Gr#S>39VrC=$g1B+!~TYO={fd`1!$BepH za#96sLRkj%pb(Dj?E7U}-$=7buH#|WE2rJ)uRZIcT*3yl{ZN(Us-G=-yJ|J`=VKIQ z!h%Sd5f-Iraq2iT?Xr^GT%`FJ4I&yyW#?tRk=?=V&$mm)mCnhYH@dv8b!M-v^4ia@ zHf&$c6@2~bvbpTkPPsE4lD9NO-VtrS5%lX^kOq6!I$p&DAw@TG>Dp!G$A#G|!@m{W zdA8XgW^G9=wrF{VzlbmxqeRL=_>_JzMZ4`(ro1qR8* zqjarqfzc#qHx1$jU6JuVGg;k@4ts+ySx_VsWq0WQ)^8W0PMu8XVJ&Nq<@dzdMbi&5@1&1>GH|twMjJyhrYE}0#BGR!Obe@WV z49VM)neqfPGFQa7LoT$Gi#nA6b(rO%wh#SmPWKhKB;$CkHJIWpkth<_vF$(J7b0{mi0_FZ zOFY4pkD|2ebJVG}UF*PxI4+2iaj0bq_ev zLkwAdV!h8sIq5FA(bK(I+2kgQLZc|{!n(d%T>wR#NOU28xwjI8RH!S7S*FlXQC&#JPI~BzB)Ec`?gB9v48)(p%Xg?#XHI#ZTR;2=3{ItWYzbEgs^6?J zI3q#pM@M%9CW_VT4!w>8-`3~YvBV?TXuXo$qML8BMVzmkp$ehwY?W+O=_Y?crIShW zsBOC+eCd&(6p^SxtS0i|zCgr0QA!k}>&oci3f?L{x`?#XhkpH}nvqP)-iOogi2lUj z!x7@Ng?}K%l3#f#;N8*pIX}G|JxF%}VhNNIezj(FlelMEi_oL7w^~^dPF)j<0KeIl zpHmq8*b@MNH8(dJ<=6d`=SO}v85VU%Pq@%{!^_L8dx$QPf$&wVJ8qPn?m`)s?oImV z=@ud<)3CiV7$zBK`=XbjRWb> zr&nvSU~XZdU^c`$$FN5&HzYtvEChO#L2!@EZELex3pR_o;J&2c;H33PZ?XR!U5T8@ z8F$TC%F?*L?e16jc+Wap%NF-P!?9v;?FUEdgm7)v^2MD!ji}k=3!V1=1w4oxyZd`N zvw3bxYIqhs_{@FqDEbh<2!KvU5cZ}gzxEpng)5Yf-`&p5l>YZSKuO$`WU<=)Y&(2z z^wrPJc;w_eiT|Ci>^ECZ^Ww*yAInz;!4;X=|7SjSg8Fn%hOKUKSY21dvAc~|=>G%A zMvl;(xEoqMl-e@BSC=j~QvQ!90EIpbVtg_>W+33wSnrkIo-qcwcS)!J3uyznE4%vu z%tk5eil_|RhG;kg+!}Di_T7>B-D0g>M`k5=%zt4VBi!JMEG%y4gme|$+FqPF|KbIU zJI}wyPVxG3ozt#o^a~7D-+1nNGp9BB6D}niLuD9`Y{UK-U zvY9|GN(^^mX*VseV7{fWYL*0Dv6c9Twuhmc$W~a+fc1mbqEtSa zww=bU8nJr3XxnL@r#H8X=SR+7oplUaIkJ;gA^Ah~be>eO{Fxv+4o!dnp#a@-_Vw`} z)yWSR*lKp@Y<*uAKL1{C^)SNQLp*K3MOT*k%`bzaQskdN8o?$#!M{`IuKpnV1)MsQ ztWxPcE^?)ktH76YV_A@s<;6d_#U6m$9HJ`*3{Cnig&cdnnMhDIBh;s1{L-yQ@U{x z```|(>!;j))UxsPEFU-J`X@$J@kA+Z-#Q`V_j{4*6KdYiP7D+CY@+02JuuDwX&p!M z(E+2kXmUlkjf$|`xV7ZAT|M4j*_-<}dnV8J$g7^}(Z`!1K1n9rT?1T*NzQ+)yd@Uc zShF;6xV+($b*<)!RZgZ;(hKhsO3e-{@xSG%BQ@$Vxve1niQWWy?HtwaK%%W0Jb0CLYqkW8R)EpXs0F zl3O6(wp-t{9@Sl3E?i)D;SRs1GzS0u?Gr{IfNmGz{p)w!Pa9h8@V9I^JD=?7ucA(QQp!i|>H@l`|C%KNM*ab3XaO+rw~))j8t0!9WKJXE(}w6Hrc( znSjCIzv$h#uIJnOMfi8CRLhnvffL%s>ha20%u|0eNIrG^qL;BJ4Q4_lo7fdsQhRY1&u}kp{K&t#GP- zGj_|#M`S^7%TwfN^E|_lQ8-=MnNMdp&t8?P&xFa_sFO@+9M?x)nl4t9BuH%}ICkI1 zxm^))I(m=+gLf)_LPwiY1wq{|{kA3c!oiqWD-~u$l#WGWnJy;N^dN5*v3C0w((Qzn zeWaq%mrTfRa0+Y38y#DBPXP^)A-cK|RPCxT? zk_{|KjIh9ct>FQ25T$lM-!XMs7L7a7|NS3Ys)U{OFRkv;AEmfCoE)AQ-;lwgaYmQ8 z@9INvHzxE%$Nbl(e|%83>qRO9B$alNp$QLo)Ip$O zb5UF9^=Ao8{yDu2DEs@0LuvA}K2q)qpT&Y5P^Lv9UcV@RK~GKz*`D@SAf%b!19 z*}x08Q_t|_9rg^KCS)616F~=r@M)7m=w`qVh37Xg5=d=oUa>Q~t zIj>Nfpw~bk6dS=PtC`dM+j?Qwz|C&CPx*Le~T+ym1>C=b!^U&=eys-De(!P|IL(@ZIm zglsuP%)04laDb1KECJ~XR;}p6eQLHcG`#zG37YntY>YlEmvXruN!Rh9eyO8zsG0#Z zjTU^c3pY9WV$HqW6X+wN?Rjj!H2=3z9d18qZ++ZR=$NOmoB!4VBi%64K`oRn_Wi9;e)wo)`re-S-eHouF*2sJw1M0078Mwt z>I`?B~`?R%t7NYn@BO3;!k{ z%e?Om(98k$2!f5?mHiv?xs)*}Wc9&Hcd0m(@LYL`w%32hKxv@il*(-8yt?f*)-op2UUHwma4Uj&eRCp#Uqq|4CO~JAAbeSthsoJ(h;4 zAi>u@XBkyCWk3?Rx{)0*`tB5saO|cTL=W}p4JaR(&q$~H-uv+jYjI;}*dOudA9ad| z*X)0tgv_^*5kILanF@%8Gk|vQ(yq`3r*Je@KPjk^=0c?PMVvIhuwe{z!lx6hG?AOY zG%7t-f4HGXIwBOLFWg11ehZ03ImpnEVK2rH!Km%^#@`${o@DRXp!)TzGUqd(@_q~j z0oDQ3*5-WR5|TIh{QLW9w$qNckM{Zg6o*GY9tt#0-w&-W44=fGcOB%?4hl@N=Duisq?xztNU?gm!wz$3g>VHiAtd_|EaKpv=%vesky$;Z{M*0NKSK6M|& z;5`Z%y8bQD&`oKv)x+APKFAb)8T+s$q1g;7C^HqJp*k#8f7>~Kv`rvX(GZWspZbrd zdJo(^oyeVh&4S1VnKvuK>DSgsf;2dfQ506Z+^gZN;tL$1%DH!=7So}1i_}RPoN@!w zr>mZ=*G8+yIP2c$|ABFD9vQ%jCt|2H9WZ6#rqHA#;kuc$Hi{<7R+|{X>0!*j{wdlO zH04`6TXH*dsj(!fZ7|O>Q(hc0JI?l*w)FgTV%PJoRnDb%tWVJ5g(@dD?KjuU1)7<_pl<17uAWHUEJ8Y|p6^9_WBL>9IG%13~A;f_m?-ZaWn z4DW#^pr#KYwML`M-#(WO zievB}`B_6~1biz=8tGI`SIrxfS4ZTZy*Fh>Ts!8FyJR^SX$;x=@$JSyNOLKY*@axq z?U&|-rak7_$|%YXxZ4=gyd2m0Ipve~i5muRC}8*J@h-5yEx*;@KeaEf3%x zUKA)C2At49HL7gZh51@~%XuH`7TTN0bespSFSiJJD=<1y+7zwA{ zUrxB;VtR?WduTZ?FJgzA9`@rTYvDgtOkp6PTy>7svjKHu?sig$znApsq3qenungP(GxNyfc6N1cSf>XF8z110Slt8afDE`fcK^D z_Iyf?0xDY+McEA&wSa95gD^-Cu1F)O(8?Rz(O&@yelnk=PGW6D5!N=AHDK@C1(8^g zH6Z%>wJ5zPxfQnWjG>1sILRLNrqOa-xD7GlOYa$S}j+lK}gDNan-=BPDwBU0;>_Y?P7&Fc2`OE z2OQ|oM7LcvepmwIgwwlWJ3eme(s&CbGme@NIT5W>8=Rl)f4Eu#BXng_8kKEI6l#xN z5tjb4lJ~viZ8nUkL;ddY0mh+$K?hfM6%LY#QW#xR_ul((nq3E}4>&U{QSnM&pr9(s z7?KoyJIgLzNK9o~?&(+cj5E8&Zh9MEM-7+5e*+tS!4gl$?gc`Nr`r;M7UO-1jJ&b9 zR%EWJ2=Iit&LD)b>}mKq-Tg=FSGs#PZNV0zAP=SlTy;nihn^{)XGWTflU%o4o({d) z>mH4B7WKLigX2L)B>64GBFi=;i3k)@ij>pEnlUCcieUi5{ZWc=-vNogfPLGNibf`3 z8*K`v%$w(!8G)9xOKxARzlAMV4XDKPj3*!{upysG}Anxtb-Ech<$)3RSSF z&ckh5Lt!v+ul>MFnL)iWde~|zvY0BE@VPyffhdj)6DJKqXP2Xa26!^~T?kI#a5CB# zlwZuucWng0d$J`lvd#oLBlqYM_K`7gho&sutec|S3};J2G$$e>k)xYoW+Vqd*IJ4a zE1?Y)3TH%bl#0uJbvz&lLe2&=YyuK|WbIc1f4_}eMml^IF)z+*I%|DL@YS!l7)|?AreG2DK~S3`wWyN48NA8fW=H@X3rm zDe~(2QEwl4)=3aSf#~{D!*Mju`u%r4c$!nqRAk@qO#QA+0y{iN%aAODAQTzPhS$=F zoMNQ*chT88h5sStQEO7dOzodm;5?4qxq?I%NRp&(3LTEDpG&M}0}g5?(co|>@DcQ7 zNd}*g2OY>=rmu!r2;W6)_z)QU2mYc!5yb-Hg<-OAf9ic*k~R`+bCke%Dn6CtpVaz* zG;hq`4^d|ac(s%az$W=>8(%sCo${iOr~-R=S=0XBTHT}R1Rgj`vQ-=vQVGTUcc5r} za?GB!_hdngqyunD89-_*us1nGuFVZuW<<$!?1L%5GAIN3qp4e{e z6^ta%C_0GV{dWJ|a}$x~Fniju+<8&OybkR%!%dIt6Al8s7e}1lK9YdO|II+U73EHd zq1MgZRE0ts8$wFEfX^*DWGl&Ge|Tk53gy z=iSEH9zfnk{dqubhY!%)qx-0$`|kvEOz|GUI7RG#aU=ag5Bwa9wk^; zgNiwm#f$CJBDmXm+7`DPfS|hVZuJv+IE#C!-C|*oTlEXj6X!6EE<44e(`_e1#1Qd` z0`Bx65K~%oaC5!|w%JhwQmOr?tWS1>m*qYpymFh2j1fHuG=&nZP+O^8eoCPB$*)ApbiblaO>GR( zHnG2bcW$@V%RlB8&J}6(^`zOO-QyZe#*i`RFKuL}l;Q)O{W}dilvgW<0fm(ib(_m0 z`6)`QhY#p$D?xjB{cd)F)eHG~l9lzer5_wb^Ck3&8v4hJSK?*LzhWvh__D z&ybuex`FI3 z_Yq{v3u=gj2KB{Rc!%9Ik63&4Qy%Ks@7O1H7)n|?pb`A z8OlSSB(k+7a=7;M_+>Nb1OX;|M(WgkDh%0=e?)V%!QNtEG^gf?F=Oz8XAhLRvy(*+ zm8P6W(cHEd$bGXCsjc#M|9EA_G6C~HrvwP}+~nB)u;=tvEug~?a^E663K!P4Ach$M zR^cr_G9(jA_Pn7tTWWZUgamP2U{lNXt!%&9fSP0|AEt-vIKS&FM2kHc9$z>SN{>Lb zSh*FrEJ^>QY*%WzD#7WOUj4ex3$IlVFPmQ5KTolhMP8L6m&25@?8w>W+gOAmJrmMJ zjLf(9@~|Q;khq3b)S9HWu$Fo@C0IbGRRydVvGu9*yTaZC==v!MP&m^iC`jK5m=*3^ z;829g8q6+(7DV5@XpqaU+Z4oJMJ1b%T-VQ^EN;Ikf#9v{-gopF^yhrX1=&)x@A!GM)@2o5c0{ zU`gTobGyD?-WP7+0+9QTufp$^ifTsRccU@*Ip#Z#;3{re%?(`v(Yz3PwER)qkB%mZQtL(7)XjOC&82J&vJQ%4^x2?khCl4 z2(!}t$;NOliij9QuPP&wVnJNk`?{5u6wfAN!%bM084j@LUa_f9h6cXRZ*;a)>TllD zW&W0ge-DOpAfp}+?U*Vge|Pv~VGPxH`@r0UUSPtCnApK3^Ul(X3idy?Wc_C#Ubun@ z7LffgZoX#6A*Tm;Fv-#ABHU)s9NtoFPEF>(_n*zD+(t*ZDE!`y^Cs&e=OqH$^*3Ah z?E!tFW`LMgT!YWb5ZB7pE!eUtV3%G&Ydx}VMSX9YT(a+uONQ+F`?%xgf_AaMt(eHd z_laQPH=EmEx7dnV#i8AE*;a18^o^(H^e`a$RTM#t&u`vGZ`OD*V(^LluR3fZ6BeFf z+V^EIN9f-sqF||o4c+9>UJDL4R_K9VH}Zu|;H-r>B=J)DiJn^o-2Syo(;_Xk{cL2Z zGHl~oIK;IwF5{#@EjUx;B%-K-&>arZP52yrQ9e4#1nxsH6((ZqtM7$g;>chJj(;B; zf#-UkR7K&odgE<(Q^?0_TEkt-=6vtDOTP_4A}yYH-qzlFbK&{m9lAbQrN6xdqQ=!# zTW@pL&l6%`xEi8&Zv{nK@AQ?g(l>^fd`{@!(IZWU8O`d_0jCY{t&3~%0Z>Nhf?}i_ zjEg7|B2=%2*8OSeJP*X?FdSEP&$qDV;Z&F@WbXe{!+oc|!=?OlUjjco$f;(6OnqFU zp9kgB^+`wv_rwtIt*$b8HyvqtX9fnF!PYfTAC=b@JZzY1=0!+1U0+D@V~ag8>+1T7 zQwe#3R0`l8`b=*Oh2h^lHsj1cvMiseYBg+81hRPg?2X1bVbj)WuuZc#5rxYu`!06_ z9(n&JC36$Q2qdZ!O*tIx3KU(qxCPuNrWkCUi8p!rH;?y=`O_PLOt2ohsCu}U$>(n0 zhpmny4d-Q<7d|BpvF(z^s2})C0&Atn$tX(3c=W>(Lt%*bUqmTxLfTu6|E$||@wEtW zivweh^lfb>+~L6MyuRY3j69er)wU53>!H=b0YVT4f{BL*=iCe4PVC|ts$Gma-- zNrMMun}>_MMBLymAl%^VNpXmdINA3N{ZXFnuisB*L7;RmaDrr5bc$cY(Qt97;m1k`eL{RIbg2trdG=8LZgj6hc#!o5A;lsFc- z{SuL7zh~q$8e5Z6Q%V19*ypdE)P;4#NSG9;*J-MxdX?e>c19jY9w&o@O1vq_{>L_9 z-Q2Lys8AFk-FzeIz|y(IkIc|XFgOfFNr-NLEHz5b$b@cPN{+pV{#ZT#_woyKAHYOq zELmlX;>-|raZ(ih&pa6*zYS6a41g0;l}J35_&2*oG?o1b8i#zJ@0Cpqw=Xn7fP)P< zZRBVBs^f#4{zax{&_rOTxe8LUwxGDMI`Iqunhf5_$^dtpo5Sgrr+!tTDBZ5L2JpWr zj~a!ax92cn%0*%^ULTL@yB!}?HW52^5}5LIX2kdo)l2^K%#;)w7*qR~b!)N_x2X#{ zjPY$&@PluB!IUa9s6(YwUj?bP7CjB>AHdVVa>5}!y-6x7$25Z*Bb$@FHM-FgP ze4aB{kFr-~6DJdQ`pwj-q5WBBA$HL?1FQ-ho!uVdITPftv|3SMA7nrG z$2l>qOGZq}3pHR#WZPfigbou>=@1gOc%H)HboSU2inY61H3~k>P8N$+_|Wk+xmXPs~Z2PKcQ> zQwGH-@k06sw^0wPs6%lKz)KP$^l&K+QR$9@B9I%=PM4kFcda20sst62GtoywH_{jd(;~K2Dfb+1FHGBNhLZoqO7UVJDl+)B)H4$mysl+M&&#PLDA!D%} zoLB^^mzQ~uTz}8P}Tozs*`gEP2Y;( zVD>l_hcL1Fir~`G5fR#<5H1|a>KzfrW$0N>RH)sfwGrvSgf1Ov4nt>gOcH~)J6mbhuIl)GZGcbXq(NC2Yz37(D$zHD00Yju z`{=_XR*j6BfHf7EdP`@&`Sc9T4spfqe%tPlyZ}7Xczh{rnqUgZ2wigfS%g5@bC+NcjR;AP=!4f&(>@GAp=*4)=czd38m1+5r6S0o(>PT~s_K z1H_+(-}Cvih=uD3j!-$k;5sJM{QMew*?T{0n4M2;Mgv3Mph{>)br^$z46ryP*Px8X zG50B{Gb3(OFX?qKpzMr@XkwPVQ4y|Q96}$}pO*i4m-4cz2=U9HEEw)Z5!Z)B-lmo! zv8q@8q)65`s8TQxJ=pkp&=B>k7YN}FmbqV*gbU|?!YY2h4uAy-AZXa#0oZ{R6~+?3 zJ-d9KMpOY1r5*&g+?CP)&M(pB^6boE9$DKwkCfwvP?hnD{D;+Q zFY;i2yTEIprto-_7Go?0G)|~=P52_e4Mg|Q(F*c-R6WXu`2naD1EOqQf=A|EKkHgC zpm0QF2{>5`MC8h7|tTd^HwFU1@56F{gRK7Yz)_la z&B6f+#{hjR;QAaabM(JT|E}G5ngt~c(*AeAZN?X8IHo~b51gss(<3HPkEl&(D*)5n zj8;U~SNxSic%dWSU3^)q7OW4d^BSCG3iBT&emj&gzO$IVkD|QR4d8p8@)8j0C-UMc z%DRzU5gjf75%x~f(cw?6y`b)0;2uB21nM5$d06-ZQvg=$)iI!(iFc$Hh66(fTG`nV z+xHGy(UrY~S}$aswHMT+jR9|9qsvtCNN3HU7_m+wJEC`Yc3bxWV7p=go)ctIk}EO4 zwEr0$iVETS#`4p8KnQFf0m@_0#GzZgQ~MaIgaNg*cC9!>&)6m<#zkX}| z-c;C@ov`zIK6D)+=fdu*>m6pV1In#U_cb-`!t6eP<2DU_7ie-^*Egjp zlYA$gmaCZ_Cacc5R%Em@vI&1 zaS;QMCs0|RDelh^JI)Xm**d?0dh?4g&vx>Wf~Sor(CqOnE&4&ehi7tRlM4Za6D0B0 z?`OjTLk(_GOY>50mbWLl)uK6_MK8x(NV^Us#>DNrmAGC%& zwlDf>G2KDK&1MxD*?DSIpcH@QmZU zqnA$}le^?pGkUa|tc%r7$KD?Q@Zc-wdXIe5+N?5es#AnU2+<(f!{0v1B<9(OkX(Q4 zm>-u+p4eIa)XQ)B=tPDAVE)-yBvzT6__6ielQ5?=upm_E`O@|rd2=nNI-St#_jKfo zt6bkT8^Jc0zrNtl@2x#|b_1GZkGCM9?r6$C?rwXym3r&hj)wBCo`lwbv{nU!TslN6 zs$67uvaC}rT}kBuX=c3UKzpyWVJ|(o7*WkVe$4PcD*aF5iN$KCNJ{{>A0661-c`Zn zzqydRaea8@mw!lV<9Omzqf#yowR*9R$8WPs&+dTq7@%8C%Vd?GJ-Tr2{=HE2a~C-7@VcufZ(AI7k61SF!S-r=9Bg!%8-tIp zmsNV+J~7o&Q~pGj^{eb&q~;{$)Cou{?7bE~UW(gw0Fc=2L(l$_lU~s+r{jbju6?PB z7ef@`a&CX2DH6WRpR3-#=8zE{>BhxA#%f4{gg*7R(}_%x-hvZRyFvY>n9U&3%}Vb$ z9;xB#*xsRl*B75lnn5*w+nsc-7RTD^R?bwj!`>WfE=#*dcR6QkQUm+$EJB+j@SV%e^VEIdl&yEA z+y`|JqiD*8t_tT^juCNTRzO})CRlEy#i97_ zX=2eC6{9ZmHE^J$;b00+@2K*|IqxT-l24F?-$<*>cc<>1O>rkLsa*_vq5L4#O*^CH z$wm~=y~`ifCXT_b{n45TI+&i5eC(?3blt7f)Z&7})0cSv9EsCzkH@5gj<`m8$33fe zf8WJSiXBDe;}rsax+pTaely)Td|Tkdad7-1Vl@M#A)VbeT*$MG;P`?K)<%XvJ?W-< zKNnoLPafxtEpwTHqa-mc&?* zP3;WGie?`Arl>UG2~P1%YxzZ-@DKkT{X*+!moM!+-O- zt;P_XDfsGk6k*-G<(RM&V3PGKvKnb+=jNEr@62=M+~_+UzvZU|g5O{IN!7CvGSL+N z-&wXFhUivO{(7$phC0pem`hMkhH#8z4$pE_n>`kpZ#K{gQ&KiJK=LBIP#%cE7E2{c zUf(YLTYd0yQ!Y_yc;%aai2OBO1%_+h3{Na`(%QIa;R(NZeewKT#wj6au(Z$+JD0=71=A!g%4bhcSm z)L~S$4zHKTPN*npNMgx~->jl{$i*kaR)Mg{z1@u&8l2Z=^hw$Er*CUtKk*1Mez%uB zRwwsJ(92uWVqlKdgr@gy7l=g4e?+@o&apaJ?`=g$Ohjmn28A=h=vZcej3A34DR3~{p{zORad7C5eQT+~!$PArsU^`H|>v3)9p$!oW=AoELbns<8AV}ln;Y)?li^3vXX*a)= zTpi9a-4+YXX4R}{H>lN^_cnTkZ?H5z86fXU#s19A=xt;oxFHYPf7*X4@Hu@;_~5Zp zI+wYtv2M|R)AoO!>n){U)wr~j*h*+jmYy&XNd?9*FoObdu^ z-?*uPyZ+MA+H+f?2{2&-{jnC+E~4~Rx7}4%BnokIc478)&-SZOla+Dk7rdVKR;6O} zb2ZQOT3pBZyBAUAdPL5`&$(B3=-#;wAL&#lYwr1dEbc7zdEr7??as1I{_E3!d-)=E zOJKIa9YazJRHk^DY=yS1|7D4IXM}3dBO&=VY*fK_4vq_b%j?mhz9v=~(~}aem@-@$ zFT8KG#yxksx;yz!GwF1{I%#3Z!YunWI#i#;ZJRpV^=NhH(@n8522_K!+x4cv$Jvv@ zqB>vwm3j%nFR8OjL&%8(>irule(xv=H?OUlSD}I zmw?JzDv`cs{`X8x(wVP5PyebUFzOk-OMN1Vq7Zm=GhH$+?8kH*Yzfk4+_fn@ZkBx! zO;MVlN==8kgnrI04K?LJj8Ev972=m)Yo8ppDv`2vjH>3Qt<+YX8+sAjFJF+%J2;A9xDXqduX&H<1ov}RKx>MbBE>7+=m;%dm^jU+G9r#Dpgvz@ihgPPq_-!iSh=rdfZ?Qog!VGv*`a|d%#nZ{?1yM zxYd-7gMk5udl<6iHr3VQ(3$edIK(VYeU>P;UAUjxP;M8tB|x9Q*0g}UIMgqYK)<_Z+<2SGT5PmY?))75(+Qf1<^o>MYZLGlgrgJF|{+X4fQUxj}dqw>%3T zEgp4{X*yva=yLV=?AqjsEnVyG6vN9`(3i16Ql{$G+1*=g{Nro;`tsF#qw4bfn+sCS z&kuO6=p3F6?zs_pvxI+i=-%P;sD~9kY+3te!%nM_&uCc$7jQKF_aSs+l^b$tw=OF< z>#FnNKFi7Fg`^5iaV8{4u$27WKi(~yI9)_Pskzvt-nXkB7}v&gFvDCy*bcAmx};^l z-+p)9ShQ^hb-A*}D!U|?GI0wr3(XRpW{EomJHuwpmDW9)bx)5UjLUu*zV(|st8xS% z&tCSQp_|B)WY5O zy$6ypUp;@q@4Wv#=iYnn1DU-IvPBO6D})cSQaetZaPUWt)?Fx<$39ND%YScBn+DXqsZ*m)I|YUZes0||76c$! zneW_Mp0@l%J!8Son&B=7k4>gqz4!J->JIt)>Hal3w#9}by)GH0+oaj-SuD^NBWu{-+n3Q4)mAh2yIn&B!s8!_&h(QF**w8I6p##$-x(W1Uk_u8c4+@#Hf^ z6lwo!3@WpaF;;YPYm#}>i3TJ_Cj$BG575fomV{sO+g~(a{;YpgU1bXI?c)`Xjvw!7 zCJYQEm)C7(9q2F9UFYGe#jV-VolP)nJrS5dH9@#(Pa8h84lT*sT{AgS-A3OyY{;+( z9MBr&v?@pRrqqAF*M7pBsFDsXZ*9bI^^A_0PJsZF-*mt6{(f{R*1mpy*T%asn7)wd zpxa}E2X5kPXsNvSo`h%rj4<zkiSfARaGy8UPKFjnjRaFrSs__8DF_$8DWQP+}a`2fc%GX+`E?N(>g8|F;ynU zG%9lTZ}%PD@Jk8!qWE3+QvY|`G~{U(#|c(BrC630Q-! z4`~RDZp3-_wtvWq?>u}(Sh=BjYd-T}WbbgmHs!l1vpAm4xmk9beCF2;MTFS(3}I4;wez`}wKy zE{qn}ZnE?fo#Cj+Blx0{9IHO zv+V&^*K=+28w1~NYMgyTv^8z&A{?ZFjYayBX3D54O0_P7eX-+a!{pM+>fMJO?`8-# zV2SBC4HK=18IPCBT^rNptj+C7yG1o!PlbY5+Oo~7GB?w*GFN3>bNKkd!gR3lY2B%6 z@@H`WRO0SXM-xOFzU*yC7(K{`ai3k@8djg?nssa7qoNQB5yiSMhoS&V`g{_*T4OZd zZz3#LzP$2?Z=WB?MOq5C&khXWidV4N?5K+sxo<_ zr$)?pohec5K^xsT`z*V5c(v0TPQ8$<&m@i(tz06i(DJealC`0CSqaaTncEholt`vk z_wIxjaJUDX5gg$TyTNOTM#t2`VqN;1B})6+Ad}HGUe7mU4$(En80378usbJzvtOEbM1He>M`9e z?G+6ejIqf4&%~Y$WEP8jt+Lns+|&hl2EgutZf5Q1;@bv(GVb5sU0=E{Zf&j$e38&XCk-*ZC=1e6${uwrUUkE=RZ0`#F82QZBG7n_47Re zkjhFES0W#j-BBOlTaSW%$)6{6g934Ij+N-P@I@yuRw*xCHORHxEu9~{tnn|h$S4GV zb@X!?9?zqB6o(V}RGh)&M<`@N|Z@gwl_WeDA75G6?ib8=^&zQ zSSJbok>J_IJRPyl<-N#^-`L9u@^WnTzWyZU;s}sf z!ym8}DT59*W8*<5L9EFOH_520$D1Kf*WoXda<9Ku&@p$P+NGSiOIBPD)*e}i0f3sKcKV2S6BvR0~RmI#sB=-vtwSv6RGA|ZHL!KMC0d%@(g~2 z1H9pW(k!{DOL|=OGg0gdns3Tc6%Fv@fDAe0P;>#@dIl9(mt|@c2dApQ#jX65Wk#tq zE96nujNppRmu}c8qK~Q1%-kRgl{R;f22P)qr(Ub-10vyIbI4o?2AvK($#AG>essYQ zGa|EP-p7tg(0OM^tQ9x~R-tCtGUAzHNkv&fA*m=*PF}UXjJ-gdNPtb#j8~MSWOsz# z&(o5%kV}_LEGW8714HRIZ%eLus0!+sEcb_Y3E^pzwiZ%gD<^OpqdE)}9t#eHu4#sL z^x!sOMLK6zRIAs%+!N!T#QbCozo&t_2~9=XMPPyjZnnoZSw1~7-zIaoO&o)|PVZ&M zT-)W9_NHhY{6Vbp+$i2%wXg4KZM#S4waC4{0l=aP_`3j>2JvHJ%@gSJUdU8JX95$r znR{V>`w;HU+E{&=YXOQ7nei1`tSL`5%|163zu?&>tfB!zKnGMV9Ng6OPSt<)pU^g^ z*sFIiZ63KDByGX$AG6oI4)`yXfI>MV?4m9BP#uJ9l6>0KeD#X&ow+wV{@H^(N)O?5 zw{N%yZU2dStVm@azcGU=Dbwb9Xe3?@6L%QS`Fj3NkNuyTyHDC~jX;~y;#v#Q(WY-y z2|ibW=F>~gktD{UNU)Pr)nzC)M<#lF;v*cgCN8gmeo}~c%jm!(Khi=u_Tr@y^0Q(N z+u)C=>{oj*TvWqN6ci0Co_S}T{Z!gxcLo{CP1y0GP2eOlcs^3uL+Q*~FJVYT?t{oP zPnovHLy4{E1#9UPWs15(Xe!depflI@oQj8dFyVcni&sES8dQH6b$De`+}jz>M$SCwY1C>;(U+W0f<8X(EOrV_Mdj&ts--T}kweL#s5?S#)qS+NO4csy*C%jN z2{dV(*~*I)(tXoA98l+JU6LGe2zX-!2ixOpg0$o&jw~JVpZ`t)AYKEx_5%oo5mPCN zzsyg1D1SzatBY3CVj49%qh`35FU+T!!)CNAibJM%;!H9q{fENGR|PcvN8(=1in?D* zdBpzP7zD?<4gX~wer_6H^?2?up;VhI-|p@5)p>+*$C%fEyuO{LK(^h>`3p${;u(F3 z>cbyor%$<}Tr*Q^;9zrjRG`oFz7*Z&QCc33XzoJt_4ZnFw}?M@qca874hPqZUpA-E zrFulxhAyqstCa+(h6569C>;qSV8qv_-=bY|MTNQ3PbO%5QL>SHVptz%4C=Q85R@OX zhi^11Y+Ps&0>M!bVCu6Se0jwMhx}^Kce*XWHSuOVzIjV?Q7-1!}@{Yg}ydg*t#91rGG zo4$=@RKuoV{u%oXt`k(;!iOnzIQ}0uygDjIqQ{tjbK>w<6ac|40 z;DX>Yq%_~RfIm6OUjW-=r8v4_fk#8%p#zR-e$8bI7cgfr0H}{jIbU;r!ifrH=s~7a z!Etwq0S(Fk2)=)_U?CU!9jYpDS-DST*}>%GvuDpFC7n(>0)gefm&wCi z=><6Q`vy_TZ$4OoJ>Qvz;^Lb?);IMeCy^B4(eJ#>=8Kp`NV`g+DSD0&tpkX!)`7+H zfS&zVW%OTP>c0Dxtnd~J-A8?O0&;EEm%)<#Dc~gt?w4TK$1||o&dkgECdE$l7t24) zuLFh9h``4&G5xSsECRJ+xnW*Z8G_{-g-v1^bqN;#k=r-~4>i)Zrsuyxp|JDVqP$xO g0GZR|k6E&Qy^gLXfHDAp#m%^REAvkVmQwQn0QWj8?f?J) literal 0 HcmV?d00001 diff --git a/anserini_dependency/js/IconTemplate.png b/anserini_dependency/js/IconTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..bb85ee9271ed28b8b44e7744dca11be55f37924f GIT binary patch literal 1597 zcmaJ>eM}Q)9KOLc(#nXN;1D&(l`t{T_WEfL3ZoxDqs3agS@DZ4oq|BCW60dht_Zk4#@^iB`@X+C&-44t zZBymvM$_ig004+qD1XVAX`rqVW7gQGh%8? zr!Re{9m@cK$Rx8yOKO$N5tOhpbzuzCWwlXk0LaL4*>tD{Bf%ofXvW3R@aeM7lGlFvEpV0#=OFfiCMN+<~~n(6}x_ox^4p1dc;U zix_$ylvb$%rGy;=`Alva%7$T3AYj5gzCZw{f*dx?VX>)4kOuP*z5w9}!HES?-t2k< zqL$@M_@ZuN$V8GhgvD|?olGZ}N!X1nSR@jKH8`9!3X$e0#Yvqj4RGKqFF&#k+P0Cgh89xKfdX2g7pSQVvxsK3gW?%3-!FTQJF$5on1O z!^ugm{soseEjK(2RvYD6hS|;UV)`6AVFkyNM$FU40#BB8sicH07TR&WZ4?mjZ=I2EW31bFYeg)*eK0YCYe)a z$A-Gs&+`vOL{;_#hH5=;QIIK>|K+7U) z&oSce&fD^4;pXBUjcut-K3^WQcKgQnXKYMbR^ZJ)5?tYzf_pC+_IbUr=&@aAUu#^) z6ll(H>vyihm50^NZ>~QaX|BUVS)LYK*PW0l=yEm54HnA)(G;Vq-oJoD+wOlv_m;>5 z>6QzlEf#HJLId!}7b`u#@D^>HQRjn`kGEgy?9A}Ut0S)(eASKp#r69%OFpT{Idpq$ z%s05qb-sX3r}Okxmkf;R@3LD8cb+QvDtMv?w|w4pf6(x)$edexG9_80uew?s%c06s z$u@p8cs(&Q>qPxiM|_}F$_wBJIciYwhW`}(?}8aLv_FWw1VJgB;#lE0zh?PJmJ z-72pCy>Q_cLe=_KD}PO!iT6xfQ1EB!-)^YpfcmH`Jw5&9+l;a@?{G}>vYgnum8o&U zt~qz9b+5PgGh64H3aiAa%0idaey=&I`LaOV=y7FcW-c-b_dfAN?ru*iZ{rGuwUT2c zkH*gYn9_DXkj`Y&L+)PWX@~Kgo)hJ4%0H4Y_gUYa1|SmnG$Jpg@Xd(||IiikeAx*} GVdX#dhi*~; literal 0 HcmV?d00001 diff --git a/anserini_dependency/js/IconTemplate@2x.png b/anserini_dependency/js/IconTemplate@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2e1e8270b723e6c107fc35e14a82f0a7695b5c20 GIT binary patch literal 2099 zcmaJ?do){l9@mmSQmr;isaNlW>J&*N2+~9kk`NV@V1(+D$3>RpMsiD1t<`7`rqzeX z4&APCs^(D?ZRvDlhD=$d+LAFUm};5Q8kRFPZ46U;(7RBtQfSK!7FTCxcv& zFH)s;Zp(s-z$S5)kGCN=cejK~d7M?{q21-e@LZ zfp-u%m4^L2C>}ck2!iAw;Engh2|b8JfK0{{y}Zd}qB}tHAd(0k$W6u(y(r#f3dsj} ze_;`Ca#0e6OJ~0Kg`8;E6d0CK2!zbcOnjy%9+D>$h<<*4Mhy}PhahkYl@#VHaZ-iT ziUJ)}2<2iKEQX|jQIRizj>0r766xBaC_!?N4@2@O2ufS2VnhlALy8ng1_VWt zfe+byp;&4(?0d&xvned80_IDFAd61JA{uzHSVZv*qWgIJF_=MqfnG!+!^@Y1)XLj~ z9_Yy+de8&ND_lAxJSqXD@CsM7%4K@2$u$mxM22{#gK}{OC}PSX3Ggmyig@i<=xge| z=Ze;hg~3>pOF)7l7+d>atzI!9^JCnu4lZ(79eq%W%)1;JY};%!@==*pv*-a)%Ax6U zNyy=3%g#^R=~aE?q1ZhshZDF_>$mh=LTAf?BTZ3t_fi60xCc&F?jEoxKG$eL8QAGM zbms%oM-IA=1Gl&`(AAcU%yi4EaBbjYriM{{BjtEOp?*2O;;cpnJ%OU;+Rk5n^JKEC zb+STH@rrtl>S!?>{@Kuu7N^0^kOl(!u)QJY@}Bhi_-gLg-~Xk_dTe|=x@d?TF!zCM z_pMj61%RVHs=g~P(Z(6F(st&Y*>Y2nemf^O!700@zJ62_ZFacrR>)<`o2I6we%zt{ z&=0va-@7|G1sO^jtlM@bemvjN(Q%?k;Z}ODprF7Vhb!Dw$V?)Y+Z1(WWfgYHDr3s+ zJhdV_J3IB<&`{ifPWSEnv9ArUB@JWAhW&F{VW{QFhfUrSFlAS0so`g{vR9td`&%w{ z{vFG+cfnSj<#n7!KbiJ8vDwe|G`)6Zbt3G?jysM_$)6zd9{>U7U&T0{j!?GI?0cP2KHlDqh(b~$kH_I$>}@mH;_mP|YRAXN zQJn2zGZWlF^-oh%yx`!x?ZMH}(dy0x9h+aMY`p>7PP9y(Y&-aNc7H#4ZuT^3qZ{W>OEh21SXpX|t@45P_F`Z~ zu6eh0N$Avo*_FOJPJJ)h-y;2Tt`F0d)1qVEv_5`6^Ijbag-XuK%6i;47d*{(Fqn;) z2i3lz&S1Vm*IxPQhvR)f>Z!a|ZANHNuo>Og@d@ghb~AoZ^UH~oR{wVV^JoHZ(anBa zaBPlho~pMw5S;aG>+)8A(*wCTo*AIn-MU?joE*A={mRSQ&!Y5BoTgXEcidUbz6nAawOMQFpz85JE zSTGn)LpEO$7p#`dTsk%aUc~mExViz2N~H?B{?aAyVo3guUok_Kf=7F^MFVN%OkMX> z=bfL`lM@sEV}gCL4|5&=T72O`X{nXVW4L(JKMyHU-(C4p6T*3?^~dcMB`mj~;s5-w$&&tRIGZdd#bCcv7h?N6qf;Y}@zE zFAKVtus`Fte|JxhNUzriQn~!y4i2TbxlsMXgo_zwP^NYn?O_rp + + Anserini Speech Demo + + + + + + + + + + + + +

+

What can I help you with?

+

+
+
+ + + + +
+ + diff --git a/anserini_dependency/js/index.js b/anserini_dependency/js/index.js new file mode 100644 index 0000000..b3c86b7 --- /dev/null +++ b/anserini_dependency/js/index.js @@ -0,0 +1,7 @@ +var menubar = require('menubar'); + +var mb = menubar(); + +mb.on('ready', function ready () { + console.log('Speech to text loaded..'); +}); diff --git a/anserini_dependency/js/package.json b/anserini_dependency/js/package.json new file mode 100644 index 0000000..7d3b5f6 --- /dev/null +++ b/anserini_dependency/js/package.json @@ -0,0 +1,17 @@ +{ + "name": "speech-qa-demo", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "electron-packager . SpeechDemo --electron-version 1.6.2 --icon=Icon.icns", + "start": "electron ." + }, + "dependencies": { + "menubar": "^5.2.3" + }, + "devDependencies": { + "electron-packager": "^8.5.2", + "electron": "^1.6.2" + } +} diff --git a/anserini_dependency/js/recorder.js b/anserini_dependency/js/recorder.js new file mode 100644 index 0000000..8612da8 --- /dev/null +++ b/anserini_dependency/js/recorder.js @@ -0,0 +1,154 @@ +/*License (MIT) + + Copyright © 2013 Matt Diamond + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of + the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + */ + +function run() { + var WORKER_PATH = 'recorderWorker.js'; + + var Recorder = function(source, cfg) { + var config = cfg || {}; + var bufferLen = config.bufferLen || 4096; + this.context = source.context; + if(!this.context.createScriptProcessor){ + this.node = this.context.createJavaScriptNode(bufferLen, 2, 2); + } else { + this.node = this.context.createScriptProcessor(bufferLen, 2, 2); + } + + var worker = new Worker(config.workerPath || WORKER_PATH); + worker.postMessage({ + command: 'init', + config: { + sampleRate: this.context.sampleRate + } + }); + var recording = false, + currCallback; + + this.node.onaudioprocess = function(e) { + if (!recording) return; + worker.postMessage({ + command: 'record', + buffer: [ + e.inputBuffer.getChannelData(0), + e.inputBuffer.getChannelData(1) + ] + }); + }; + + this.configure = function(cfg) { + for (var prop in cfg){ + if (cfg.hasOwnProperty(prop)) { + config[prop] = cfg[prop]; + } + } + }; + + this.record = function() { + recording = true; + }; + + this.stop = function() { + recording = false; + }; + + this.clear = function() { + worker.postMessage({ command: 'clear' }); + }; + + this.getBuffers = function(cb) { + currCallback = cb || config.callback; + worker.postMessage({ command: 'getBuffers' }) + }; + + this.exportWAV = function(cb, type) { + currCallback = cb || config.callback; + type = type || config.type || 'audio/wav'; + if (!currCallback) throw new Error('Callback not set'); + worker.postMessage({ + command: 'exportWAV', + type: type + }); + }; + + this.exportMonoWAV = function(cb, type) { + currCallback = cb || config.callback; + type = type || config.type || 'audio/wav'; + if (!currCallback) throw new Error('Callback not set'); + worker.postMessage({ + command: 'exportMonoWAV', + type: type + }); + }; + + worker.onmessage = function(e) { + var blob = e.data; + currCallback(blob); + }; + + source.connect(this.node); + this.node.connect(this.context.destination); // if the script node is not connected to an output the "onaudioprocess" event is not triggered in chrome. + }; + + $.ajax({ + type: 'GET', + url: 'http://0.0.0.0:5546/wit_ai_config' + }).done(function(data) { + window.WITAI_API_SECRET = data.WITAI_API_SECRET; + }).fail(function(req, textStatus, e) { + console.log(e); + }); + + Recorder.speechToText = function(blob) { + $.ajax({ + type: 'POST', + url: 'https://api.wit.ai/speech?v=20170308', + data: blob, + processData: false, + contentType: 'audio/wav', + headers: { + Authorization: 'Bearer ' + window.WITAI_API_SECRET + } + }).done(function(data) { + $('#question').text(data._text); + window.setTimeout(function () { + $('#answer').text('Asking Anserini for answer...'); + }, 500); + $.ajax({ + type: 'POST', + url: 'http://0.0.0.0:5546/answer', + data: JSON.stringify({question: data._text, k: 5}), + contentType : 'application/json' + }).done(function(data) { + var answers = data.answers.map(function(a) { + return '
  • ' + a.passage + ' (' + Number((a.score).toFixed(4)) + ')
  • '; + }); + var formattedAnswers = '
      ' + answers.join('\n') + '
    '; + $('#answer').html(formattedAnswers); + }).fail(function(req, textStatus, e) { + $('#answer').text(e); + }); + }).fail(function(req, textStatus, e) { + $('#question').text(e); + }); + }; + + window.Recorder = Recorder; +} + +window.addEventListener('load', run); diff --git a/anserini_dependency/js/recorderWorker.js b/anserini_dependency/js/recorderWorker.js new file mode 100644 index 0000000..fbb1cdb --- /dev/null +++ b/anserini_dependency/js/recorderWorker.js @@ -0,0 +1,161 @@ +/*License (MIT) + + Copyright © 2013 Matt Diamond + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of + the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + */ + +var recLength = 0, + recBuffersL = [], + recBuffersR = [], + sampleRate; + +this.onmessage = function(e) { + switch(e.data.command) { + case 'init': + init(e.data.config); + break; + case 'record': + record(e.data.buffer); + break; + case 'exportWAV': + exportWAV(e.data.type); + break; + case 'exportMonoWAV': + exportMonoWAV(e.data.type); + break; + case 'getBuffers': + getBuffers(); + break; + case 'clear': + clear(); + break; + } +}; + +function init(config) { + sampleRate = config.sampleRate; +} + +function record(inputBuffer) { + recBuffersL.push(inputBuffer[0]); + recBuffersR.push(inputBuffer[1]); + recLength += inputBuffer[0].length; +} + +function exportWAV(type) { + var bufferL = mergeBuffers(recBuffersL, recLength); + var bufferR = mergeBuffers(recBuffersR, recLength); + var interleaved = interleave(bufferL, bufferR); + var dataview = encodeWAV(interleaved); + var audioBlob = new Blob([dataview], { type: type }); + + this.postMessage(audioBlob); +} + +function exportMonoWAV(type) { + var bufferL = mergeBuffers(recBuffersL, recLength); + var dataview = encodeWAV(bufferL, true); + var audioBlob = new Blob([dataview], { type: type }); + + this.postMessage(audioBlob); +} + +function getBuffers() { + var buffers = []; + buffers.push( mergeBuffers(recBuffersL, recLength) ); + buffers.push( mergeBuffers(recBuffersR, recLength) ); + this.postMessage(buffers); +} + +function clear() { + recLength = 0; + recBuffersL = []; + recBuffersR = []; +} + +function mergeBuffers(recBuffers, recLength) { + var result = new Float32Array(recLength); + var offset = 0; + for (var i = 0; i < recBuffers.length; i++) { + result.set(recBuffers[i], offset); + offset += recBuffers[i].length; + } + return result; +} + +function interleave(inputL, inputR) { + var length = inputL.length + inputR.length; + var result = new Float32Array(length); + + var index = 0, + inputIndex = 0; + + while (index < length){ + result[index++] = inputL[inputIndex]; + result[index++] = inputR[inputIndex]; + inputIndex++; + } + return result; +} + +function floatTo16BitPCM(output, offset, input) { + for (var i = 0; i < input.length; i++, offset+=2){ + var s = Math.max(-1, Math.min(1, input[i])); + output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); + } +} + +function writeString(view, offset, string) { + for (var i = 0; i < string.length; i++){ + view.setUint8(offset + i, string.charCodeAt(i)); + } +} + +function encodeWAV(samples, mono) { + var buffer = new ArrayBuffer(44 + samples.length * 2); + var view = new DataView(buffer); + + /* RIFF identifier */ + writeString(view, 0, 'RIFF'); + /* file length */ + view.setUint32(4, 32 + samples.length * 2, true); + /* RIFF type */ + writeString(view, 8, 'WAVE'); + /* format chunk identifier */ + writeString(view, 12, 'fmt '); + /* format chunk length */ + view.setUint32(16, 16, true); + /* sample format (raw) */ + view.setUint16(20, 1, true); + /* channel count */ + view.setUint16(22, mono?1:2, true); + /* sample rate */ + view.setUint32(24, sampleRate, true); + /* byte rate (sample rate * block align) */ + view.setUint32(28, sampleRate * 4, true); + /* block align (channel count * bytes per sample) */ + view.setUint16(32, 4, true); + /* bits per sample */ + view.setUint16(34, 16, true); + /* data chunk identifier */ + writeString(view, 36, 'data'); + /* data chunk length */ + view.setUint32(40, samples.length * 2, true); + + floatTo16BitPCM(view, 44, samples); + + return view; +} diff --git a/anserini_dependency/js/speech.js b/anserini_dependency/js/speech.js new file mode 100644 index 0000000..9e2717b --- /dev/null +++ b/anserini_dependency/js/speech.js @@ -0,0 +1,182 @@ +/* +Modifications Copyright 2017 Anserini + +The audio recording and analyzer visualization code was originally developed by Chris Wilson +and modified for use in Anserini. + +Copyright 2013 Chris Wilson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +window.AudioContext = window.AudioContext || window.webkitAudioContext; + +var audioContext = new AudioContext(); +var audioInput = null, + realAudioInput = null, + inputPoint = null, + audioRecorder = null; +var rafID = null; +var analyserContext = null; +var canvasWidth, canvasHeight; +var recIndex = 0; + +function saveAudio() { + //audioRecorder.exportWAV( doneEncoding ); + // could get mono instead by saying + audioRecorder.exportMonoWAV( doneEncoding ); +} + +function gotBuffers(buffers) { + // the ONLY time gotBuffers is called is right after a new recording is completed. + audioRecorder.exportMonoWAV( doneEncoding ); +} + +function doneEncoding(blob) { + Recorder.speechToText(blob); + recIndex++; +} + +function toggleRecording(e) { + if (e.classList.contains("recording")) { + // stop recording + audioRecorder.stop(); + e.classList.remove("recording"); + $('#question').text("Trying to understand your query..."); + audioRecorder.getBuffers( gotBuffers ); + } else { + // start recording + if (!audioRecorder) + return; + e.classList.add("recording"); + $('#question').text("Listening..."); + $('#answer').html(""); + audioRecorder.clear(); + audioRecorder.record(); + } +} + +function convertToMono(input) { + var splitter = audioContext.createChannelSplitter(2); + var merger = audioContext.createChannelMerger(2); + + input.connect(splitter); + splitter.connect(merger, 0, 0); + splitter.connect(merger, 0, 1); + return merger; +} + +function cancelAnalyserUpdates() { + window.cancelAnimationFrame(rafID); + rafID = null; +} + +function updateAnalysers(time) { + if (!analyserContext) { + var canvas = document.getElementById("analyser"); + canvasWidth = canvas.width; + canvasHeight = canvas.height; + analyserContext = canvas.getContext('2d'); + } + + // analyzer draw code here + { + var SPACING = 5; + var BAR_WIDTH = 3; + var numBars = Math.round(canvasWidth / SPACING); + var freqByteData = new Uint8Array(analyserNode.frequencyBinCount); + + analyserNode.getByteFrequencyData(freqByteData); + + analyserContext.clearRect(0, 0, canvasWidth, canvasHeight); + analyserContext.fillStyle = '#F6D565'; + analyserContext.lineCap = 'round'; + var multiplier = analyserNode.frequencyBinCount / numBars; + + // Draw rectangle for each frequency bin. + for (var i = 0; i < numBars; ++i) { + var magnitude = 0; + var offset = Math.floor( i * multiplier ); + // gotta sum/average the block, or we miss narrow-bandwidth spikes + for (var j = 0; j< multiplier; j++) + magnitude += freqByteData[offset + j]; + magnitude = magnitude / multiplier; + var magnitude2 = freqByteData[i * multiplier]; + analyserContext.fillStyle = "hsl( " + Math.round((i*360)/numBars) + ", 100%, 50%)"; + analyserContext.fillRect(i * SPACING, canvasHeight, BAR_WIDTH, -magnitude); + } + } + + rafID = window.requestAnimationFrame(updateAnalysers); +} + +function toggleMono() { + if (audioInput != realAudioInput) { + audioInput.disconnect(); + realAudioInput.disconnect(); + audioInput = realAudioInput; + } else { + realAudioInput.disconnect(); + audioInput = convertToMono( realAudioInput ); + } + + audioInput.connect(inputPoint); +} + +function gotStream(stream) { + inputPoint = audioContext.createGain(); + + // Create an AudioNode from the stream. + realAudioInput = audioContext.createMediaStreamSource(stream); + audioInput = realAudioInput; + audioInput.connect(inputPoint); + + analyserNode = audioContext.createAnalyser(); + analyserNode.fftSize = 2048; + inputPoint.connect( analyserNode ); + + audioRecorder = new Recorder( inputPoint ); + + zeroGain = audioContext.createGain(); + zeroGain.gain.value = 0.0; + inputPoint.connect( zeroGain ); + zeroGain.connect( audioContext.destination ); + updateAnalysers(); +} + +function initAudio() { + if (!navigator.getUserMedia) + navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + if (!navigator.cancelAnimationFrame) + navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame; + if (!navigator.requestAnimationFrame) + navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame; + + navigator.getUserMedia( + { + "audio": { + "mandatory": { + "googEchoCancellation": "false", + "googAutoGainControl": "false", + "googNoiseSuppression": "false", + "googHighpassFilter": "false" + }, + "optional": [] + } + }, gotStream, function(e) { + alert('Error getting audio'); + console.log(e); + }); +} + +window.addEventListener('load', initAudio); diff --git a/config.cfg.example b/config.cfg.example new file mode 100644 index 0000000..d842c39 --- /dev/null +++ b/config.cfg.example @@ -0,0 +1,7 @@ +[Flask] +host = 0.0.0.0 +port = 5546 +index = /path/to/index/here + +[Frontend] +witai_api_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3c6d5e7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +gensim==1.0.1 +numpy==1.12.1 +pandas==0.19.2 +Flask==0.12.1 +nltk==3.2.2 +pyjnius==1.1.1 +-e git+https://github.com/castorini/Castor.git#egg=sm-cnn-1.0.0 \ No newline at end of file diff --git a/run_ui.sh b/run_ui.sh new file mode 100755 index 0000000..c7d7d0d --- /dev/null +++ b/run_ui.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +echo "Start the Flask server..." +python3 anserini_dependency/api.py --model idf & +PID_2=$! + + +echo "Start the JavaScript UI..." +pushd anserini_dependency/js +npm start & +PID_3=$! +popd + +# clean up before exiting +function clean_up { + kill $PID_3 + kill $PID_2 + exit +} + +trap clean_up SIGHUP SIGINT SIGTERM SIGKILL +wait