From cd6c3ee1b53cf2e4612c3c562689b521a76189aa Mon Sep 17 00:00:00 2001 From: yuangn Date: Thu, 7 Nov 2024 21:28:57 +0800 Subject: [PATCH] feat: add edb --- backtest/load.py | 136 ++++++++++++++++++++++++++++++++++++++++++--- backtest/load.xlsx | Bin 33324 -> 17496 bytes 2 files changed, 129 insertions(+), 7 deletions(-) diff --git a/backtest/load.py b/backtest/load.py index f7bf842..b2d4981 100644 --- a/backtest/load.py +++ b/backtest/load.py @@ -60,11 +60,36 @@ def create_table(): FOREIGN KEY (indicator_id) REFERENCES indicator_description (id) ); ''') + execute_sql(''' +CREATE TABLE IF NOT EXISTS edb_desc ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + indicator_name TEXT NOT NULL, + indicator_id INTEGER NOT NULL, + frequency TEXT, + unit TEXT, + source TEXT, + remark TEXT, + last_updated_date DATE, + update_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + ''') + execute_sql(''' +CREATE TABLE IF NOT EXISTS edb_data ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + desc_id INTEGER NOT NULL, + indicator_date DATE, + value REAL NOT NULL, + disclosure_date DATE, + update_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (desc_id) REFERENCES edb_desc (id) +); + ''') + @xlo.func(command=True) def fetch_one(): ''' - 全量抓取:也就是根据指标一个个从头开始抓 + 从第I列中的指标名字,全量抓取该指标历史所有数据 ''' ws = xlo.active_worksheet() ws.range(0, 0, 5000, 2).clear() @@ -105,7 +130,7 @@ def fetch_one(): @xlo.func(command=True) def save_one(): ''' - 全量抓取:也就是根据指标一个个从头开始抓 + 配合fetch_one()使用,抓到后,全量更新至数据库 ''' ws = xlo.active_worksheet() names = ws.range(0, 8, 50, 8).value @@ -131,6 +156,7 @@ def save_one(): return # 组织数据并插入DB data_df = pd.DataFrame(data, columns=['indicator_date','value', 'indicator_id']) + data_df = data_df[data_df['value']!=0] # TODO 把值为0的去掉,或许这个对某些指标来说不严谨。 data_df['indicator_date'] = data_df['indicator_date'].apply(lambda x: xlo.from_excel_date(x).strftime('%Y%m%d')) conn = sqlite3.connect(SQLITE_FILE_PAHT) # 删DB数据 @@ -148,15 +174,12 @@ def save_one(): @xlo.func(command=True) def fetch_increment(): ''' - 全量抓取:也就是根据指标一个个从头开始抓 + 增加抓取所有指标 ''' ws = xlo.active_worksheet() ws.range(0, 0, 5000, 4).clear() conn = sqlite3.connect(SQLITE_FILE_PAHT) - # 取得上一交易日 - date_df = pd.read_sql('''select date from tdate where is_trade_date=1 and date>'20241028' ''', conn) - date_df['prev_date'] = date_df['date'].shift(1) - date_df.dropna(inplace=True) + # 1 取得所有指标及其公式 indicator_df = pd.read_sql(f''' select a.id, b.date, a.name, a.formula from indicator_description a @@ -168,6 +191,11 @@ def fetch_increment(): if len(indicator_df)==0: print_status(f'没有待处理任务') return + + # 取得上一交易日 + date_df = pd.read_sql('''select date from tdate where is_trade_date=1 and date>'20241020' ''', conn) + date_df['prev_date'] = date_df['date'].shift(1) + date_df.dropna(inplace=True) indicator_df = indicator_df.merge(date_df, on='date', how='inner') indicator_df['tdate'] = indicator_df['date'].apply(lambda x: f"{(str(x))[0:4]}/{(str(x))[4:6]}/{(str(x))[6:8]}") indicator_df['tformula'] = indicator_df.apply(lambda row: row['formula'].replace('date()', row['tdate']), axis=1) @@ -212,4 +240,98 @@ def save_increment(): ws.range(0, 0, 5000, 4).clear() + +@xlo.func(command=True) +def fetch_one_edb(): + ''' + 从第I列中的指标名字,全量抓取该指标历史所有数据 + ''' + ws = xlo.active_worksheet() + ws.range(0, 0, 5000, 2).clear() + names = ws.range(0, 8, 50, 8).value + indicator_name = '' # 在I列的指标名 + indicator_row = -1 # I列的行index + for i, name in enumerate(names): + name = name[0] + if name is None: + continue + indicator_name = name + indicator_row = i + break + if indicator_row == -1: + MsgBox('I列没有加入指标,请加指标') + return + conn = sqlite3.connect(SQLITE_FILE_PAHT) + # 1 取得所有指标及其公式 + indicator_df = pd.read_sql(f''' +select id, indicator_name, indicator_id, last_updated_date from edb_desc +where indicator_name in ( '{indicator_name}' ) + ''', conn) + if len(indicator_df)==0: + print_status(f'指标{indicator_name}没有待处理任务') + return + indicator_df['tdate'] = indicator_df['last_updated_date'].apply(lambda x: f"{(str(x))[0:4]}/{(str(x))[4:6]}/{(str(x))[6:8]}" if x else '2005/01/31') + indicator_df['tformula'] = indicator_df.apply(lambda row: f'=thsMEDB("{row["indicator_id"]}","{row["tdate"]}","","Format(isAsc=N,Display=R,FillBlank=B,DecimalPoint=2,LineBlank=N)")', axis=1) + print_status(f'正在处理{indicator_df["indicator_name"].iloc[0]}') + # 填充Excel数据 + ws.range(0, 1, len(indicator_df)-1, 1).Formula = np.array(indicator_df['tformula']).reshape(-1, 1) + xlo.app().calculate(full=True, rebuild=True) + + + +@xlo.func(command=True) +def save_one_edb(): + ''' + 配合fetch_one_edb()使用,抓到后,全量更新至数据库 + ''' + ws = xlo.active_worksheet() + names = ws.range(0, 8, 50, 8).value + indicator_name = '' # 在I列的指标名 + indicator_row = -1 # I列的行index + for i, name in enumerate(names): + name = name[0] + if name is None: + continue + indicator_name = name + indicator_row = i + break + if indicator_row == -1: + print_status('I列没有加入指标,请加指标') + return + conn = sqlite3.connect(SQLITE_FILE_PAHT) + indicator_df = pd.read_sql(f''' +select id, indicator_name, indicator_id, last_updated_date from edb_desc +where indicator_name in ( '{indicator_name}' ) + ''', conn) + if len(indicator_df)==0: + print_status(f'指标{indicator_name}不存在,请检查数据库') + return + indicator_foreign_id = indicator_df['id'].iloc[0] # 获得外键中的指标id + + + data = ws.range(0, 0, 5000, 1).value + i = 0 + while data[i][0] is not None: + i += 1 + data = data[:i] + if _is_fetching(data.flatten().tolist()): + MsgBox(f'指标{indicator_name}还未完全计算完毕!') + return + # 组织数据并插入DB + data_df = pd.DataFrame(data, columns=['indicator_date','value']) + data_df['desc_id'] = indicator_foreign_id + data_df = data_df[data_df['value']!=0] # TODO 把值为0的去掉,或许这个对某些指标来说不严谨。 + data_df['indicator_date'] = data_df['indicator_date'].apply(lambda x: xlo.from_excel_date(x).strftime('%Y%m%d')) + # MsgBox(str(data_df)) + # return + # 删DB数据 + execute_sql(f'delete from edb_data where desc_id={data_df["desc_id"].iloc[0]}') + # 插入数据 + data_df.to_sql('edb_data', conn, if_exists='append', index=False) + # 更新数据最新日期 + execute_sql(f'''update indicator_description set last_updated_date='{data_df["indicator_date"].iloc[-1]}' where id={data_df["desc_id"].iloc[-1]}''') + # 清理Excel + ws.range(0, 0, 5000, 1).clear() + ws.cell(indicator_row, 8).value = '' + create_table() \ No newline at end of file diff --git a/backtest/load.xlsx b/backtest/load.xlsx index ee2e317202bc2bdb033bd3d564c5a0b559fc9047..5310de9fe25bc077aec6b32cd66c243ef79c2d71 100644 GIT binary patch delta 5970 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 OWDjHQL9&u~oc$MV(c?q_ literal 33324 zcmeIb2{=~W_cyLoLZL*NLXs&%B{HW%xf3bMoGCMzXUY&M86)!)QW+zelgydPOc^rI z^ZY;i9QQ3f)$=^>_5R-X_x^w1uB+R=&pCVTwLWX@wbovHU-ywhVedMGwFhf278VvQ zmaNG4klY}%~N|xnV*ZJ3(lP^7Zk$auZ>SZyWRL9l)P*3Vx z2U70nd1Yw3_hk6Lq|hdjrF9y3rgJ&*n1jR_vS;D1$;uwr4dyf!5?e7R%+Q|bRe1hN zORTtt-cgywI!*bI(3cJKm+~)Tds8N?gSSWKe`{VQTWcpYy&1J3z zJQ~{JevaeN^o_ea-AaYIugmBMxvHwuIrP_B5@kQ@ygv3$VKif;W>0(fiMfxdmLJF8 zca@Vfj>|-Mzv}O+i1lNqt%|tt{ML%h(U28I=T|acjELX5ML3EE84Y0L5A{?&^=dSp ziZCPMCN8rR5FlxlkolbD0gaeBDI_OpFWoH$B#xAQn7H(~sMeeX-R z*GyR}hmKW@HPH5vqHgQnld%ks`+Cgw{v}dnuSlw}`2&_^N2!S{tv{TgAX*rU_-56m zKTLX%vYV%UDXKM_|BYSprEoWfOlC9e=KD)7tTXo`R(E4zZERp;No||-88RGnvydfU zh2}IqH0f1LH1$o{*}&(2Cj0;38UBOlZ+s;ri#YZ@oVdK|R<_X8=}mM2Whs0)hxVq! z{VN@W8J;o6DLM-nD2Z;8J7bGE<~giZw0H7*4wuo+_i(;>eDDw--8;*~hk?t+<~YnJ zOaerW-+cRYz@llcX+B6y+?vrM&x`r>`9ZsA#L~z_PtC|k55z|FoY?^dNQlb+ z?0>nwRl1)z_PI>B<~!Hr8T+nFRq)y}x#qoV$Kgml=q91Bo*-ns66`AP2cV)MQRA=BRFG${6pmEPQlf6Jd^5k+#A{#qbO^e<&NsXNI z#}dv--w7&m_P?n>$*CzAi3%(!6*eVTXK_v<%odURz7+PP;A~{Djz`#aBFpdOpB(m; zFButhb1Hdy;IS?zSD-be4I16BB?HwAfP&nU3do4#e<=Vd>i4bJn82`)N@GOvQ;tQ!rLl2pVCzKqoTee zeeDyMlU8T~!(UiWhHUV2EgX(1XIYF4O=OH9@xT8pNp}8bo#RTkC5!llL+?o2USv9D zlE)`EP<&mz{c!&Cvc)`M3i>?!q(^5irC#roD9F7N>cwir?O8v0`e~SZ(hAGfSJ6y$ z$3CfKcu3tcdlX0U^>NWc=fz}B(Iq=&Qh$T)TT^|wYIKVX$;z&|YIyYTQAdVWWL=Be zzc4059msoXtJr*e*G#3g92@bO#CefIBEiY>8NWCkdoITZ=sAlN0l->N8bh7_q#z(L2CjOzEayB8&-VK4A ztF8LX$6N!>#m#DrMk`K!R&Nk6f@0+_e8FLRr{_ITux#0bg|#2isHvH?zNRVg0WW0o zpuC8v3xAes*SLqn$*gy@OfP%)?yV)=?YmP+=TX|DNwLV6jfQoJ3Z;UVGOOj5x%StV z4*K{S>}CpnF?Gkcw6}C3zcfQ*xK7zk0+$)D_-RI_+@Q2HA^_Nx$@kHrM- zY~vqHRn$f9BYI2vfM&#sFEraLkV7&^P%G~D)Fh*0a1xFc6c5KDnR;~6kg805DkmCld3Q3BU7SZ zXOLyQ`R2%!@zBzbp1zociQ`ObYuF$I(KX>CeBAxh`Pr^{36yoyp(Afki%40WNX}u} zRWHexYp6QurcE`E^~HV8>bBO6u_>c4f@rstHfqazN^i$P0@xo_7<4Xpb^7iJ#%48S zO7$u~C3#MSyScfb!12M(5o?~xfYTDiDmSq{o0!%%aqBe2?YLdMka<6sKH*;FY_Y=` z5w|5h>G}XS+vLnyab0|$=%U=2v@d9C*~J z!>{t**zB~*$>{{@WrhfxwL#p@G7E_^GomW;Jp!n?!g<24kI z-&!2WaPmXERzG-_SoK^hiD{|orBQqmv!oMRiakEHVN7VpzBfC-sI2si1dr;?QIm|y z+FHCTPW?ho98oP-t=uG~=W%{D8Tw7M7bzk4_Hq{%7TuP6Gu77AG&9|dk?@yOmXseA`_;&b6-EPeci9XHzPSi~^Ed+=&R6)B&ND2qwpklq8nBFTu-cfR&bM7FSRWAD zC|X)>3QRU~T>m!aCMhK3xUkG#qoTagyRfk&WWO>X8L_e0A3rdVoIFnKus+>65|Qt) z)*r%cl%KmYwA9Un>x;pPRM`*t~87Cw#W+a$z zzcDisI$1R!R=qge>ow6Wurc0{BV=#4zNAM0J^XE~IcFm2+WR=c|#ayO_pdiw+47C6kT zWeVjMsB~5umA|g35pq~q&KwKre!7;BXQ#8KzOk}46H&10xUtq$IZ-kpWWU^7d3e3w zZ9-WnZxugWh`+#g$=rHwe%;H_c0GQ85J0OUU*IUVQKM3`7C*)LrC_?Mn_zvtePf|} zW0`$vV6NRNbM4zwX{O`yd%8JVf>t1W zxqci!_;x!go4>>}KsIN6R3P8J&EQ6n($KU>!Vp*6_}W0n>cIw^kl+dNKz8x{@9UgG zf+xiT4I14k65qcjNj9^tyU8+cHD-QTMc()pi!$g(Vu>`I`u zrV=(s^h+v^-{eek^SO7%Mx+fHi#OpBV>d@Utn`?Db3_$0)_nAcbs3A&@QCtLBF#N0 z7+wN_+XBaJBW*hdU#{-z@4X_Cm1s4`(il$Z@W#sCyVr|h){6m$hDDj%WY_eiTi@sV zh%|~vM4t+W4-R*PQ@XsdYQ5~#<9wCxS1pa-Gb9nG~X zZO8cQ_9nMJT_q1zQFy{Y{_Sjgs>;O$y~oo>ja;UiDc9(g2~3Q`wLdu$UtE{jmz`-y zfJL0F5}ZRJjIB?wgE*NYE9ZdOhwn5T5LeJee0>6JVs;810{y`U1_!!(D@70JKiviQ zs0oM0JlRsayFFTPO3$TPU(9*GK?>_QvFBv)m{m#?As3FzqrieS{I#QwI@&H(w5mPk zbe2`34Eh9k&^YA<7u+1(s#R4lvg+ew6;F_NY4LIBGd?t+jnsBoXeHQB@k-TH|GCvt zdjaF*RNzCC7D}oU5TwoejYZ!V0edS1CZ&4s=srDs*g}f$(S0`eE}y9WpnH|DT2DXw z{Kvvl6>@ns)925vI?I&a))9wb7k?TN9S`=5YoTNYloncXl;2XFI7aH?%UKtqkV+-XeWXzi--=CiXklc;oWG|{`UFP-o_btu>ZXgETu_H#mjN#Fd>$vYF3f~IBp^;EH`nrh)Qppb zbE}pn=M1<#9Nby=hi0W{H4PuRhEW9#psyJtY_XsXz|GX>EF0f<8n!2L4a+@2kmRfs z`_uTGujc9>r{?Tq*dHc5Uoi6~N`Z@9BhZUtdgdWSNywOynx{{TAWYc8VOUDgqO69B z*LifcFUoF~2bVb=1w2@D(gL97*^xGtRSbkq z^Ep%Yw1y3Hb*VUCYHCUk5)_QSR^MUijV81}bzHE#1wGJ|P6-0q3cx=0RF%4tKYZJWK#0{ zGohW&9QV9BQ#NJkfcFY=AI_B1I8oD*7nEKuPKIrKjc{dlJi@%e+34yKePC^El-7}k zdE*lDO{oAdHtpqprtASCEVoIeC|a-y8XR(j-^=zm80Log(9ixWmZ#Uxlg;hfDTo70 zo6o7`jUC}kInD#mOhJnMn{bRn_#+^Uqb~wEBZUbN%L4|5hGw<=m3mZ9@51J#Ih1KL z25QJ>z+D18Lxl;@_`~2JMv!x0)%rE)?RaSu^}z4I+5l}}F4$;>&=-LlEs6NRONtl{ zzzs2+O^pJ>iHEfJTC@QoF(<6sO1$5M7pV9}fBWdsH_OFHyW(8Y+!bI{aZ7u$s}=%52n^G&ye zfe3REco?*9awrOG?7`R@bWVsyfEA-ff_)W&9~5sl1%e!l!@)kqmy3%un=m6*76Kaz z_#AO=OylM(tAcfzF}i=hi78P3WmemZ&KP;GSyxt+upu(DpwRgDEugCo*<8WP_TLN9{JrR!Yp*y9?_02<>u4-D^M-%Y0uB+%YI1A|U>(gL zt6ZjmoCI3B7hM!ko`MkkHAMeMxdf`hsP4}#V6#x>hNNr2Qvcinp-3hMe9j3&K^J@f zG@LtJ&f|u{;Zd~1gn}Cq4uBL{v^hYT1QLWGb9l7J z8e|Z_940HeG8a_Bw9iM z6e25VfsBS3%FN4HZGANDy={#8&@w{~6UvqV@onAblDanmf-Gl_@Atg_@8xrgrvSzi$E6Vu*I6)oqghQwu<*tnD3$QSINifNt11%PJxJMv~gUZvn_K5<;u% zO|>xx`OZD80QT7>>E)>pGspFc-fQ}T_08`UwIkG zPZ=xfKt1Q{7SovNw{V@^`keUwHNjzeLa_uRrimEk>3ja&4nCMVof$uxP{8ZLEqg1tN=nLpiEPpmap z0p0A}YJS^l_QOrP&I(~I+Y3WmLT1cBLOzWUu%?Fo^uV7&D|3R7_)Rn5Ga@h73!=XS zf3E0D5(qg~H4~e!T2s$W$74VB)l<2HCsv*j^PtPMzwOphd8p~!1&M+*UALNU?-+2R z3%-xYKD{&%V>Lz~G7+;#Rn{NcV}ISOZl(Jeg!H5y!~>U2CPdU)8)^z}HAUOPDSg+2 zlNESQ)9onv3h9=1ziQM z<;C4RK)mXJwgAsy*<1^q1W(osR*JKUR_I4`<)_+WW4YcT9dB)RWOhhwkq$|3?EAL6 zLXS^D*DoL#(tWc9{1`+rc}zb+LSA>;oCT(M1tkHggO3b-8w~g&_5`rAR+voGGev}o zU8lIbt~$z~UfK^phfslLKp1NVLL}pDESF9~Ik0Vnr|f6xjU~S$2Mki{Cu)EvgZ^)f zOX2$zbWI8Uy1HLZ*`BTxEzZP3hJ$q9?WelgYgz!qHTq(*!WEPOnzMX{qQ4(}TaVw% zvZ)FP8I?@mfHnkS3^c!z1wjUdlE~L@iiH3b%bJkp6AFYh27%jQnGhC%f)oisIiAy4 zT@wrG7ea19Nq1mCItS9;h;04V<9%&QS&eKFu&Od%D5+-A-in@UT!LW)p z2_Vct7ZK)=v4Gmpomn#gbB6S+klv8df!^3y&u+>JGYYH#u!Ern523Zm`d`R_nf((r zXhNkoLPqs#a=&5@SOH{Il>=x)Lvsv?TPaF?xC`b6f-(@A7>f(-fWL3Mvn^>LJ4J(l z=5Ty%9zAx)${0iylKH57)( z98kaW-^&V^Thdy6su|;jZv=ZYb;xrp9Gb@Mvju1EyN0U!kc%E+t+BLmS5{{dxWrUM3mLb?9|Wh4hcrx_H# z<#~%TV#fe05HCDg&40u57G;cRu;rHoY)9i4lmTe@qa;tEd2fVB{i8S)L-lAHJW5c2 zM^qD!`k8rH`G}6Tko*N#h>dnalU3y%9Q?$x_=2Fx2uEZS%hQk|;aJ;0t^w%^jueo2 zjOr(Va0VE&+`I}~9VU(gg2=d*7}o$ggSm+&31&_<9Oyta9>;hDKpDXq8X3kJ%@3HI zzoU%cyct-B{{iJqM!9AFzTVSoUvu-lB{+ARroS_N~&}(ZKM$MHvBY0SXsF ztRb+;3YS83Ivl_| z^A=@ff`iAvWPt+tHZ*=kc?&c!Spd$P88y4DYfLB`lxZP@HpHTVH_0|bOM5Ml02u<^ z7wv=*9sUk*C^A6KAH;`q6-w<;z~7Ah<)Qis@$hua@#ATgmV|X`$zYlm8;(W|eHFNJ zOe~*+vjo^6FpdCp2B?LjNrE7O2}w4X=np6(sDY6IYG{6di}@X81U0|_kQ|EUe@hv0 zF+g(Q%KiQUWq7&*24EvD5BMF=7|Mtv0FS{&tbr2PhQ=1p7|NRl0o*Y#VgzRdje)ef z(ui+xiiB7Klu#hLX^2I04_U%5RHOB`cmzU7SIUCVZ;X}(1ufF-h^BvNGMJ{uD#NOQ z+=Ch_4?WM&S3&Rx1Q6lrF?NRu{-86MXL)Gqz+zD7;6LY!UIPHi$UFl~0EL{i&I6 z*ncuZC@Qu~1zo2Lz?93L{;3H;{Qsnor8THLPy>ZOOCzRiL8&yr27K1Uc7fvO51+~W zS8pa!v1SPIpw`Ypbz0~-bfFY7Jos5mq4bw1Bc-;$#9-L7WX?lnwhq$-0cb7xr3)%f z*|NDZcp3_H=@LqQwv&VB z{`Q(9aAsV8U&7pCZkrJQ`^$ctZYCr3?`4I3A5`#V?s|F`7BpEU5-yu=>hmOqh!zG! z9*hDi*H+>8(|j&D-ze%@fGa+bKZ43ratsC(JR>avhygE6=Yz9YDk^%Fe4~BV~Sx&4GtIr zC_4hxLFR_k9VawewwD_bjcqSp0&_xF^3YTe|NWcdB`~L->wQRw_$NGpiZ~{_z$~Fa zrE!ZnU{1dm@fXbftLh=9P@Bw8N#AXRu5C&OqQPpUM+0d7XtTswz5vZkkk3}ig2WiA zJiQ}yU^6d+i>l*of>4#vjt$hFl0a$fr^|4dgNk;2rpQtQ>Ikn?0NQ^lJuYT#uSX*B z6>xz>_-*A#fZ2blo4#tM^IDkF zDGvY_r0trok>y9?X2I(sOXfVf?AMWjxoByyS(yaW3tjsH3g1>VM7;I??ke8~yXHa~ zMY-`E)kT?I0w3IsD?ek2wtd#m<@kC_yS;IDxDFocM`vqWoZibUrG&EuH(nE5aQieQ zoho=Y0Bu~`C*;=j9{9JDKjPocWygQJhq9XWZ?{DL3xrtDZOk{A9dYG`RT>f4mI>LB zRdWLpCI&aw?h7h3ZecQEYzUz5HpuC2GvIOFl*GzdGtc;7Z+g@M&AeJ zi0zBZUo6!A)8jV_@&8*`r8cp`WhuGgssI}!inV2YBd{CY@L<9q`JTVR3Un3OEY0ZF zPsrSy`p89iu3+vD%!jbf1)$TRJWQ@+1eZF%T0#LbG2p_CkS4Nt|4$Fp|4pn)WxXJs zeq+>1AXFHp168H|lXI#l`*)rWd6Q6`NKkOBnbI|aU{#;uteE}k*nMCc5r}CN1uR4P zAZ!Il6Dnd4%)7D9`2Z_0sTsqN3~#4?*C+<5AJI8>x~@Am^3n@B26@t)YR(5b2HDnp zofcat5?ZZvNcgF5M{h}rjjd#RK3O$ln$h(Q$zcI|`_+N}97 zka}w;yoSy;Rs*=x8=IgKUA%fvS=lY?PfI>fKF5Xa2=$i zPXn@{!$cFnD8x`o&|wctP;7{aO@hetIfCk9USw>N+xF`~U3Jp8pyPeNVWTE7H1^%$ z^u{^wf56@kY(SR#wsGDmAp0o9_7B&8&E5}e2tmcYHsxCB=8F*9KV1J?lm?)ZZ9BgF zu+8P)q4#Sx);pk@kgYJJvfrZjYc?XFQt$tg64hTHgA<9wyp&i{OC??W~R`teF`qxm6uT@V}Wk~`Y)6?9vl!!5CPDSd$51S)>4sJXuB;jQ z6eQg&?-~Ko#hsm|wyG#rWP2nF3;@T7g%0Hwqz|+%AVr?l?pH29wAlnZ;PRNb0*E7J zHgx>?_`AD^4?@NR8!sZ8nG3`;9NT~o+I|=IK^d6x2;dL+AXcRBFYY2f2uKGX;s9*I zD@e3#zz1!+3)IyLOZ(qj2z?ol`a!NBQ9nTjgnY;lHBpI(?znN76?C7$=|O;etMqGF zB`Z}ADgxv;op454tn6k2kk6K3NU>&v?8(iTCz!Xt)R~*w*a-k@j{RZ~6GyWC{X9f% zbqU{pi<~X}4K(GyX@cdX?7K#0j1n+OE5aB!@(MEx^bI5c%SjB|f4PfP8(^8?vMIDL z36dj>^uUs~-9_rAXmMdiAYZ7H@QgJBvt7IG?xwA5WAneG5bCeZ#crBoH^GVJh(*9B z%8@R|v?j5m@;plN+-kis9c|4@NsEl}s1ec&cF-y#TL_;TI(gB#>I9XaRV+!r#)QTu zRlb{I)JYg2zlBtxp=$biu7$PIpHCmp2snfQF9NBSE5FpJoojh+JQSMGHDh*O-R}$< z(|ZOipnZsmsrGkJrDL^&jWuIRz@h!!^#+fKcIX^6)CW3qv}z3wQg`=e8X#T>Y=bQB z>}SCoHC8E4*(~ZWi9dw*MqpK=4@OU$L#Bf{yJP?xKTtpBFc#Rj*w*7OcM;>@!X(4s zP!uqZf3<}I!|-o*M1Y0=^K;GrOG2o>1_kgdKUq%i6M(2=&0$8 z^a^Auc#fu#U{#!dejz&#*}(X*URbf_54mb&lVF8ubB6;u)_vnIoc|Y8^tL#MH!S`; zmL;hb_Csb}biEobX~WTA;yk*p*WdMka`Sw0MP4_i-Uyx4L{2CJp#Rl|0i4?Zo72tk z`s9y?mAj$s*{tSY)jh}K8__*GBr(O!tO$&xAe2yThLV4ENE>*Ie|P5kzhil|Wf;`I zpk?OVvL$M5JTpQ?rF&zgVI`h=eWp30Td*L1V>+|IZs~hzX3d1-@=B@WY{BfAz$q$o@#ZOMAd~I{m0Wd%(_1_1+8G`pSyEOk+5%gzIf(Nb@cke=;-CwLEIF|K=F-9&?Tq?XXebWey|VaaWq#}7PiUJ)QVZ5*jd ztmRQSzem&4o32%3CzYBk;rZ)c)aGSMBs33Wop9zNH5{B`Ju6XG0ui4Yow8i54QBjm zDj89&HIn==Rn;w=5OaCMjUYe?}lDtSnyzccR`bC1n z23XoOMILdNJx|w{(!MYzW>69~zJEH@1Q$EDAM)Be9p{XS?OtimS%rQ5$j^7EB8%1l z*EcFM=oJpNQ)48S_1x^rElKJa=s#7rt%==4eDBJF*TkB(CJ%9@F*ylC{_6Z&p@QWj zYg3COfrR;!y_yF$+6g20SLRHGh=%pD*9TMtm)FW;1_*`hr#i6-?QVQEJkS+|>ods9 zb76)5K?Ygr`vAYBbL~&AJxMr&T}snVmmRByV`c9WMA%G|G-HSxNlHCAJo!|8MEK-G z4;#*jPmi!W`a{pYpX9wGHo|Q6{>)Xn0+UlGd*)9G&JG#&G~ycQJ>L<3p`v;vpNzQl zv%td}u5`W!U1!e-(tJ8I#ufWi#ZrgyeV@In;f=-*jU&DUW4wWFxzkbdfW;Gc+7DdA`bEKR0vvIEs|IKq#k4C?`kWe}7f8CV(xoQ_1IHL9Nb4X)qvMII54`#t)4!jsZ34mUbtpDRPaEnLeH<4?=aj|A-aXlcbC zH8gTL?E0NKGU?=eI`bTsD&OT3`uFqe+rp!!MczBoJ}~;Gnk^Q2_xqJuD#wD}iLXL6 z-H&ybR^@EP8$Wz&5bQJ?EB_dmCrQR9MJJkcr6Cj55^iH~gcAqP^i?QjPudZ|?_#@f z4&&;7rzva_yIG8LsyecmJ%mpCxM`iwC9=TUr4Ut9@)Kv$s-^-is2g2-C1d|E^)qd1 zTfYEbt~CGaYoDI`>1k9Ksf)14f6#fBsA$8dsj1g=Au|ibLea2~i5C@el1%Mf0q2oW zE8^v&yE+eAS(A+KOCP&O{_)9ddiNNQ10`wVvf{<#>K$~}PiC_R)NgVLlMhs!^W;BO zKTu7qcC%KtL9P2jyN=V%o44d54Jq?7AJs3W2zdG?wFjAK=%k*L^LRQeoS3b+U&{Th zO|6?cm)+IV?%9orC+;3llywzvNf%0eE|GmLMs6lvlg#kio9+S9(aG~CUbKBY{VqZE zXg|{jX;Y>8VP!(1t{|I%9f; z_X)j^_J0q_`0^Y_Z>G(V)N(%dxvx-s?4gE5$9ISFB0lUc7MB#Gae1xzz$dBM=7XyT zPl^<2LkjCx`Ko(38u*HYMe3KC-+$%W*v-?pVNfMU7Wd{`Xu`aX%P!Zo%f(LK0+IB7 z_6&Pj25bXK%1wk%#Nd6e_#E6x@8)98iIX&(Cvg7Mi)>ZD&^`MMxi&f`taqE!b@r{^ z;Gd<9XuS&GavKda~a@ITX zUP;!Qn3jZ=?u6&u!?tfL9}@R=*|*H&3CpUac;eLW(iuv{_w=JmFMlD@`jCFYuqMyb ziDEjpA#Bi<+1~Hk!jtN7POT)~cv6*a`|zsPEH^5Z!+c6!ucNfJP&YHhdYzx(KC!Nn zwL4IfV@Xr1Fj=8m=AX_^JpM8ESm^0d6h5N^h2k0WUiM!`u{;I`tR(0S1m~eB_M0Cw zg+p0KQ03Ehu0szOb}tjWnoqr29+;}iclpc_Gg1TRtL-N}qQ92;i(EQL;t`ID$QMd@ z9DCbC35}fmh>_iqfP;tu0!z9oLO#dMeEE zMBWNWTq=1teukwZFo)W)g&%Jz-<|9R!J#y@krMHKy&9H}&tub{yN7C89mEZic1@oC zN|L2vW<(zQXh1R^pFNh}6y=&h8ABWG?lvm#QtGey>X6ULD7>k|r)nO{kLd`B8?g`3 zEz6fS;7w)Q)eri#%Gogy#xh=daU$w+-s$ui<)mDh_z0bIaWPEKCcKvL_YMqp2uQxS z;p#LG<5cWEdYX2~-igfm*ctM7(Juz3dwX5#4b|@sdYawevEmswX&lcG{JzWZ?Z6Ss z{g3J7(#=(T=EgoZ6JCueIA?oOUQ?`Yg)bmQDpg?6gi4|+k7y#}8|$mMwy;yRzMMB# zALQM=l4hPILnnz~jMF*NuvM*`H9W?Jh0crFJ*+%gTVB ztjisoYKB-t#)Ix(3;ay-_HuljP1qMWA@ihOKW#FK=qNsYy`@YnL4r=-EzilN+X5;Q zWv-&aO?xBE>7;G4wOq5m@y<%xgvsn&e6ySMa9%WBoa5pfiX|JnYTJQlbm|Y+f|;}1 zFHa5LQKEfyEZ(NcZ%$WR;}mb({4=gE60`S)JQQw5YVD3&SLN=sB79y&n-rn4l z19c_#$50dp3_2L1Yl7-J!Ph&+x$a!!#I)zISqHy-$vbWF_(g^|@0m+)0-RFEJxlPc z>W}49c#?d1QEYyz1W(!Y;H*Ujp33P@>^j&_tOtb{gU9sU@6?MfrhO(Vda-{>Gl zjjQ;u<`eU7q7?%V_R4+NM>Co7Pd2pG<&<6s>8U(@@zCb=Hd=3wQdhJ_0Gc*cSKTC$DgG}pF0wLE+x9<_JXLoh%v_{WB9sfiAT>J_nr^n zQHaUn!dhj@+ki$4=+O39OZE`ONWS)6@JE@9#lxr5e%9eeoT{dvcj2n{4@7_6;6^6qN-2$v5{7k_PSCH^Wd#X}~Ki_ee2b6LsE#{g6rG zvci+c*bh5Yc?)&jU8Lp$#TT9?sE_w?YE3`gz!`XsN6S;sZ+a%h+?4j&3&pJEH0&J> zeY^v_8)kjMbh_3#>@)4BM}(S!`?yqb$OUh4?~K=aFix5_bqlwr{H5Apic`(-g6*vPs#r!1U4Gr2J6On)&N?q*VZk`*+cAV?5W_^Hc3=(Tf%*YncP zwDHd+nQVAuo;xd=_<83L2rwHL&F#i|H5bUu-}quMlq8Tr?>^VKgVc zI&IiZ{uE2a;^pZNxlj3apBro(Q*LVOO^C}-TR_O;IoJmd&h`azsKLc>K<;< z|EwtL%pXXklVtMAkgT+OS&enW7zFt9t=ic~y~{iTqR z^DEMVt~b0CjdoW~a=(1Nl=iUa2E|R0zMzZxMi+?)^`$g~WwnkLoOwCOiU^D&Ft5zFIP#N{8Gt&xeB}DMgQUc69HIRB16l?yG0TnF%^>~B+zH^ zEQ{{hb9XuGQINGbUinh2HT^sB6XJNW)@g>|Q7g0J{|y;E80?s4<(Rmu~K#kYE83F!>n%k~C3ov;!) z>%h6X`gTk+ZV!ImYa&J>8?2&THBXpu!s8prSlzpP=}A6R#WK4;h~k|+EkYWZ{Z)Bz zB{d!;awSg7Ke*GwS?gdPzbBkw{m{Beu=M<43h!_j5gO)s)C|<3y-^> z&#ZbWS9YL(HTANVw9JhxUlEa5UqWoh_P6+~W5@4X1q>8%46bxm@2;i6&Ww=KeGdtl)6%8#lC* zZaWn`YUdjZ3wz&<*B)cc;xXTrnBP5-De5ES(L442u%%eH{1AcRBk!O4 zPR4J-R(P{Q?or(ZpVNiQO`(h)2R5WXl<&>C&ga5>&pGn&Jl4}jnd(_)xA*GU%TGRP zD>GZ1b1rjcR#FUkBxgKK$(G2@)$2li;la5bn(wO;`!zTn39hcS$;y&&?E3zZ7TX>7 z=!fs0occ!O^wPbAeXM&*Zl)_=#o|mnxmTUjd}UA5o>~6Fo%b5mUa5(tG+ekwxx3Om zPHKqb)>0(BR!}Fg-nG|7L+%&5+~=m$4u43{t2~DlaQ?1LedvqGp;51ijpdorY{jy$ zeNsD8Z&Td0vRIyJZI7t#4h`L~QL7{)c&wSjpz*osO+seO=B0k z)Tx{~6LMQIxiZ5y@2TNY8gth;g7i|C8Kx^<`UYJOzHQvPLui}oh`Zc;KhK^!-$LCg zOF2dGP)mCl2VQgT_2HqA5Bb%TYxf26cZ}Z0A>1>XD!@l^C)qb;$Gjv-OO2%Cxs~yS z{qJrS$V3L&evQjBbTK+R7G^jZE@7M8U~qm(DR_Q)zi}l;`ud16vtIB#4Z*Udd_MJi zOQZX?D?1AFa&|08G_Q9LwmGi!Pxv)RRIdAcuxa!R!GF4J^Sy`du0-Y0OR5w0Z0cXW zEf*-3ycuf678>r-S#o$!P|%RvS#pWceI##xlF_}jhSIrgosHX3ot=X%j#v*je(9zZ z_?YCQArCeQy{86B(!r~0FmB4iK>rfrvQDuSBuy;0i3d;xtbOf0x% z^1E{OjYYM@?%nw?T8--vlY4sNtYBXX=?<>+Qq?0VBkRs<+!FWK58EEN;LBClR$g&luxa?hcGNumJ!u?^2d=ZWhmXo! zO1yt}&9wy26mOQOQqjuTey=dW-HF#+$i>4IPE)(()TO6;wF|#Sot~r9^J(23w3{RA zYmbKNmD#eI+@pBUrh;9%!s?35MJiQ^{cme!V~bOpq`cTvL-oTW*k*=Nj310b^oFx)u&Jki}%@u~TKoou{TraNzg?#1IiyvWRIOqMl99(Aqn#IR279u*T46BqH-3(8+n;&^s>uEVKu2a-WInG@xvQTS4lKuLz3Y+7yDPM=g z{dYUs^s=zm<0jK(M)xUA<)AuO0~*I9q8-h1g2bwvxx;2ZP*G8}qswIlCyalY+-qlqtrt`g28>(%>g2dh>D zjOvArOuV|92d!1Y^W_>QFKC+*2rZx*Iv=(hSzEg1A6TuD+<;QAzrIOCZ1VY@Flb7r zK>x{+sjY5iqAz7)bkCF>-GXzFeNRsjeB{`NWqEv^$U2_s>Y+N>osWW|_-S4c>_2Wy zLeaP${)W4wGfPEHO6c<_Q$|X%uGI6Bo`QMuR{JtL4;*@YB?i|&#g&9?*)WHPuVPC4 z%4t_y*<#=Ku2(b!b*d~rYQOjBx~pa)E$0y&IzxK4hODZLIQmm0p?T+^s8}yCqfLHY zMM^cj*^-Bp>Vr|O4+4}2c@sgh>mis5+|R}&R}D*Ld@f5#)f)6b=}3Ax6e zoELWAPeiT+Ui9==4l?bn$Ie55Ux!`?bpU!ToQ9G5CZt9tn&8bW&>Iy0^ENmLIy+w# zy&{@J#oah71ceKi#)M?ANVkYa$R0Tvqiz(PX>gk}+EAxp?P~p9CjSTQU8ds`N7>_E z$GnQBPDy%W{!sgZ)GqnPw8oWvd51?9cZgJ*vRcdNmDS=>%J(l=CU9JBBvm#r_^^CX z@zCYAQ>v%UCc8MEgq^$J!-h*h^-0NqWZ|3cLd(6W;)VMRE+7QDbu{!XW@|7V}Wu-q947U z>b-maae9!q+x!>mTd3Q?LG%!Q1*QPY#5-I~ACihVsP2Dq^n|6%(PRAihG-4N zx?Sj|iO-e5w}0}~pvS8HVpL|(lAB7zUD419ijWK>j;8gDR(nb8lMl##z?9@x}Vid7{0yJr-zh$B@*s_h;1AF{r4{ zt0ouX36kutGdSNZ=8O}BFDOwg%7V{wI^bCv?k-0rca&6T?U#yA$3-4jl5#FTr=K~m zu8=b7CtmyQ&>NXLMmLwHjQv-r+r2p|BD}gC`0bbG=5oHiAj}X9eRoZLMwV@P58hJ> zKIaF{F6ti>h4F{t>MZC)3HPA2KHCG3U1%|`uk@@CftOH9QkvmC8WmBe>|c@ zw!qW*FtI>tZ;i7cn}XnMET*h%0GA9 z{&LwLJCZ~1-245jW`Cyh^Q%U;DBZ+`>HPTO(Vsj2{8r1Y&L^PvnnFx$z2oxdu0Ov6 zaI5PX0?fF7dL!V^1b=?--4;P_C=uLzgX$*1t+(L)Oy%ce6I)aQm0&7AAENk~z|T8Y zTLhFee#r)$K>tkT=bGpi6=7YN%3ms^KT}ZrseHIa;kF)30kcZ~v6%QXm7iDlTU0iT zwp00Ot^YHjp9A$4p*B;P5PCiF)5_v!IzOlHTXd4mU^+h~@9aN)hm-lAiEhuxw@6}P zoifM5`b&QPbNAoN_R{h