From e088e02dfe604761784f3ecf8f74da8dcd773544 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Wed, 18 Sep 2024 15:56:34 -0700 Subject: [PATCH] v2 search --- screenpipe-app-tauri/app/page.tsx | 8 +- screenpipe-app-tauri/bun.lockb | Bin 369614 -> 369656 bytes .../components/natural-language-input.tsx | 78 ++ .../components/recording-settings.tsx | 4 +- .../components/search-chat.tsx | 1106 ++++++++++------- screenpipe-app-tauri/package.json | 2 +- 6 files changed, 755 insertions(+), 443 deletions(-) create mode 100644 screenpipe-app-tauri/components/natural-language-input.tsx diff --git a/screenpipe-app-tauri/app/page.tsx b/screenpipe-app-tauri/app/page.tsx index 41fa8117..18b9c832 100644 --- a/screenpipe-app-tauri/app/page.tsx +++ b/screenpipe-app-tauri/app/page.tsx @@ -63,10 +63,10 @@ export default function Home() { ) : settings.aiUrl ? ( <> -

- where pixels become magic -

- + +
+ +
) : ( // 4*qekN|-sCbST$I6*|QgIm}rDot7t zH6jAH1rSjX8!CzoMMWTpii(1WzQ1#?H8J}5-0ypQ$M>iE;LN$MbM0{Rc6FAI-P8$Tg)j4$Ggw+Sbw=T69;n(iAzYy%Qp11n)) z{;1-NwA=~P#`}Da(kd0CNX1Xg96Li5e?u!S#I9@0s{*S7r7dUXCXCCTFv_=#%*ywh z*N})WzY(RYz+<*$k7KJxqb8?~PS5rEnp83wGGR63Iau+BZ2G7NUdNW6lRkM|dTXCA zTJejxLmnBMmOEt<4V|2xm#a2Ms^CGjxHJAQ58n+_cK#Ditw4jwFubekYLkSN`Dx>4 zuc!13OfmtDROR}HgV^%Z z3T*P`FNRg&UUc!DOdA#OA*_6+p#Qy`DveA-{$5UFJQTW!0?H9kMGG6_R(Lv0r}O(Y zG5Tod!i?t3rrH>qQx5wE#y~?JX>a_H3oG4quu7?&;`23w&vr1id;)89w!ri> z--YFl2{10s?@vB;_olE(mjUCJNPeGG6VVp|N9MPKRY7%FyVkbOrr)i*7(b34Jt1%W z6rb;M8YsU_PEQ++>AR(?Y2YDP{_A9U;^fTSoUB}5dN)%~r|yQ^z-6^48WX5OhH5>` z3@C#wM}JF(T5xnguf>)}zUgTOMb@~wl_ z!iBJ07$RO%?G)vzWiRzNJ*+Xn=(Z=3{AgF6Ac4A+J5L>Hp468R`?D*X3*y`zb&ZO7| zk@#W8nrQi1Sk0X>x$R}R&{q#z-B^V~)xFzbjd*!<@$W;8zrVi5%>8e%Rok>{P5h_W zN=GBTwK4oUGcMI(S{cdzj)0nzlbMsAFlLnRb8KxUo31wnr{&HVKl;YZDbWH-(R?+q zXoM-~Jy>h}fg4Ok_Ezq@1zYJ}CSDDCYNTnv`1I+T^1h@|+9R05^}K*DzZ5LTo=7wN zE?g7)Im?g1ni==P-Yy2qBjaJsv>}!cr5k%nZgwU``g)_6Bfc}Nj=nS2*h$!-2txEw zGAb{3)Pxy6-^b%j0cTO?BUnRF9%Dd-*w(3srGM>t!d8RR7#GzuHxK`- zqTFediSqfT<{8%xp<0dYX1EI6#`2X6k1}q9tuIrmr%~3}F*&dEjYm zmA4AkB+pHwrHY8o;^=HmN0;kzX_*?9J2gFf3T>-$vvHvxR=yu+n{?3z9mOt>{wb`< z_U>%wwel?^!>mL4Shl75HqJ2)S&2hyll*a}jM{alb@*hX%&`+L_ot?+1M@OdWeA5rk)d^#>)5h%~y$YC?K5Amx z=o@__?liZ)?ywrVi(%Z$UsU-Ft@_!JqCi1*YF? z?y;9pa82Sj-e>0eVpvlpVz~>fwQxP$7_LTo#rt42p#1%2#!Q6EVQ;fMh5E{Cm0#tU zkx9$)W}5E@Z1v<2tf}@ETnWyboSDEa*Ecb5{EX2P#-w*ezX08D3ygZ|yG5qFDe04Q z(rX?;2~Lpg0xVa-DH-bk0XlWzi9h&i%i=f`}Bqgoy4ozfqt@D$Bh1_4TD9jZ6Zp zIlgg&Y0yGgbGAIX_V?&(p&4n}*_pXheBVEAP7a4)`6F-q#O%Crnd7f{!uV@!=J+uQ zd69{}*e8vr&l4e!PfW<3Fq-28oSBn3#dqGukD0)EZmQ20eKoh?DU&|>qASO~2+Pak z#WvSwR=K9)I#^R`spT|Sp1xPM7SESYn-+No)`ZO5_ps&aq-RVI8p2wQ$2S?f47T>6 z85E$^c`@7s4n1pD{YS7?`@zko0Vm-4*tr>*IlN-_<)-IM)uO7smBph1P7qLr(y-?2 zS<%#1GGRIFz_FYXrd15vN$HT+mrf^&MB6!xz z#?=+DwYZKxXBxC%x7nV~?8g5Zi`_(M<6CAEl(H_p30tnc+Ul(=m$m%We@uZB_L>I1 zgspOVlV2W--mzxAW>$X&tT{1*TZiI5iR?48+L!gu$C{GInTBNe`za-QI(db1v^~84 zmTAa~u!eMv<>+Z7bmM) z{m8wan>jWS)~dSFayeK-n*^(#+rBUzj&2XpXEIa1H2ZIT(y7|$MtSZtGZ0I^GVzl$ zb0(*a{d2qNam0&v%2bbwtoYij7Y-9srlgPYov?YckD4}Qx>6a|JlP9tVO;!^$rpj?Y9xOu0cHG+j2FV=CQS79eV;Ax`O{`F z+SrDr{cH+8d&X2W-b1_3 z$e;#1k5C!j0ILTpy#&7eRL94aZT)_)0r$c3NJVtH+6SxRpJ{+be=n@`+h8?( zBdj5FU{!P*>JN9B!Uj#OZ7Dcu-5{mPQA2KJpHzqiJJ{*D`$diWt3wb|^0 z)x+_ydeW$z-|N{=OinHGr!8+N@Aqy@*>D5&t6(+ck_x7$(al0MwX%lpD|-LxuxuR&R`T-^5p(}3%( z-5b^}*1xLX^UUM0@>Rdk*oCl$tZJm1-y4&VWhO^%`V>97PRL1{=<_{HLJh$@SPhs0 zYjP&p3Zk#=ZmD6)`4ZM-{s5K-_rR6l$7`DWY17jaMzcx9kzbzf{qAftDVowVwRmf7 zlW-X$1V4VQY)i?2< zz>41i>pr&%)(p4C%iZ&~V_9r~A3(GR|bSEqHt7rq7#A4>c_P;h~4`8dGiRlP8a* zd^`S{jSp_kAGoj0_Mh%c8kKUzI|+%KrngECjBMJk(ejs5KdIX5j^-WLw@n&vmZ3Y}SMKth=i9H&1q2apC46&C5Kz@bxBhzg}6d?)k{Vf}?v6 z)ZOvP;AdWb?0o8=y<0Qf2UADQ8-PW6A~ zWG1HuTbJQEk8`q9N@y%0r7Pu3N>1`W zPj=!uq=t^7boGiZY@Za0WA1eHtW)ii{JGBY4ykHLN@}25Stlzc9Gc4<;BHDwPIXEO z9>?nFY)ncCG%e@EcMONJ*eKf)9Z&;88?a2-iIja3%a+|K$sgy$bxI8lXO0deeJO|9 zgX^)nt0VrC&T(Q}u(ZO&miD@n>12jeL+jC0O2A2^h9lN0<SJpHv`6lS)ei^HS7e`0^zdOe}r-nK(4J1$ebdOY%nKXX&)W6ip z?3U_3?5yvW8faM6De4yXk9Fd@rv@JNjL`cmMYV;RQj&r#*du#83HT+?iR+Q-f6vL} z??7ige^)ri`TKzr*E2QLj4ej(U~sx6g(hNMh85!!rY42f6vriYN(z02B~O)7&jZbB zI9Zp6L-}kliHK#LNjUQ-tgB36IG~pk*DE!&h83?0$d*DO)+*yUvk$vPYvRn%&n~ub zU+77!o?e`0O@Ia7)tj%~2_>V)s2Tp7oVebp{zFb?@6=E&?i-3>XlTnIEIB^p6wXsDTigmTu(u!Upd(hx%FzKVZ37#naCJrIXn|HPnDjP?eE> ze{w8_oo9^ZB3WL|`w4X>5%Y#lHsBbhG52YPghpej!jN;Sb5dx9wMsjQy^=zoVX1I4 zdbJum1p~wW$DQK?Q<8+>GcC4$Tae->_PW;et=!*F0h%u)Axz75bslgY}dV1qO zriIUU9a)$p6#h0=uc#I5bP0uf1GTVdr-a@h)YsGLU$EAtKHr_r#`KP{1k^R-*B`OuS2i|^x&(jp_bfSKCRTT>80XZ% zr>3AuB`3xL>d1)g=OZDI#j@js(WVVEZwHK;ly2oHKI7*R;)k$T9y&D`A9hy zE2}u=+gR5Wm-%M95oF`%Fw=+9>=2rYIAUN@ zC>aZn6US=uk8$Eg>fV((GBxxuF`B^aggER1e5ciDoOvJC6rY3W$NJMXgIP{vi}SsQr9opJF!Vj?lgc!+cQF=YqZ){N4Qn`7 zCFc}Q9KiHtg!3=(ZW{MuQIKw0S0;syViixBV54qW&dF{m924TkrG^TyHS@f72m280 z?riLu61 zi|Ky0q^G@82ss5jxO#UV~>-js@Ieuem za4jR>TI~pZNJu{MX}b+n=agt}%1XaLp#EDm_%lS^Ur*RB)% zhR`tG_(S{2i8FL-XU~o&t%~yLE)|-Nbrlwq^K5b~hTMY77|yx`WtpL#O;D|4ILWpH zi-~Nk;5n?m-YsMJAhQQ~+e`2TtZTe2um;P1m{*qiHUW$A)GER&o2*3>eoBtTP}fYQ zZ3Z*y#nx;r^~1#N!ZKS+;r8TM`e649_QY9O13f3~BQ(Zq!KFi@9o1r(i>3B^Q`P^f zlbM$q2wd$HuJ(>pg-+bm)X-Vhh??Ww(nIZrno|*noV+Cejn46@sTG!?u|4IN z@^RZ^1;rPp$I@j5)8kg`%SC!Ke$ zb&6((0}ZZo;%^QI(yw!}ZVrdmTvuXI2F_mR6cKmX^-g>w9L%}iTV`1)p`CKT$kr9tl}Di-(p?m?U!9Am>tNJSBPcGQ#-0mjLr+J;PqJEt{+-U zNV^uB#Jr?X$4SL=o;<6uOs(2nj$`S3MT@#5g%T%6j~qJuF2a(>c%8wNddpf~JA$EH zTI=Qn{2gNnb&d8SxB@He-BCUxB-hdg#<$WGv!yW;dM1U&VVO7`iPmCiC|TJzaqq*@ zlJQQj!3KF8HJqF|DS_2_PQd~Ob*ib3+XoJvfMuF5_in*zO;%3%ost5_r#b}-!-4kG zoFZuIG$;Q4aB$-^YL;IE$EP_32$|Dyp|kP+l;A6bxK$D=KO-6%L#UUu&?|)0P47il zu-;7VSR1obg2M@Q@KQL0)NuCcfl0xASYBy?db6DPMd9ELv+%oD{4PSKqR>qgDlO3G zCMSMzICM7xcOr%(@y4XUhc`I|i^GB1vz;R1hR!Z_+K^=bY$wYN2b={BDV0PiRlVdT|Z1Xa_L&SL6yiS;jrOlT0!AyA8TAuTQKVT(08&gw4@%iQq%s4Ji z3XaA~c217#$a9hShr*!`u;p^^h!+UWaS9#^2fEL3iXI9FBXd}PPEJ-z@C!m5?>eUh zl5cSemWBfl-{KT44F?b1!Y<=%T$&O{oal7h0zg2rBLNJd| zn$iZ}_cVo?%+pq;*y)4@cqP3$&&hf;9H?}=Qvi*=-6?_|zuk#n77iZ1U8fN4_n}7f zjg!iF2ZnSkJ9JE(N9H^6%fo@HcQ{$g!@*g1vSvL`d`d{Giotm(DX`%#Cw@gZc;YS% zYr=|@Q2V>h{SH@jP6|%IVr0-?A|yAn1+Yke#~LX;IN~1f$U%x{35BBt2dmtxrLPqC z5X$n(_=QmKXo}FD`=a|44GGm;5M2YZM*hWGhjnFfzF)CMM6JNEg--nHaOjDJW~b-Q zmz5N1c)uyyyyl#RrG_!~FDA!Yg9*as5OAVXNo#GS;}on32bMcd(VB3m`~%U~DwBV;d~B)XW7F*BPrramtxC&g@>#E_LFc2!~Q0HU}{#&(+ELh(@w^ za(tUmH*&H`E=~$neIz;`XiZ@BBTm+n;ZOmh3MUCCq^}-viV*8RYJAR;=j3-K)=(#5 zc}nnWLK74U3|ZzBJrxc-vCN4t3MyDYsH&>flaHN_-DeQryetn=20q- z*S^APZL)Vu3RGY16p>``YI7s>=0$KBRtG2HnUqlTH6`@Glr>J#=5X*M#9`XJ1FhFO zS?HI`2|T~vDcTwi{f?ks(f=Mv!43sjPR_F_!Ks8O|5;9rgiNOj*CYjh z#0pCfCT{R{i)VPzMuLnWTjP_g= zww_Q=FZ5lp)@`#6RymJ$EJdJ?A_L8yb>er0gSS2F?bW+dg8nT^lR&5sq0R~g?%LwS zzZ?!-y45&_;b$XB$I`aPorkm8gIHG@i`V@z+srA+oDZ+X8bln9>5~+C9!pyobB|R} z>OVeTCu4C_>4MeENq9LWcn2ZV?}Qh42IAy&1%&!*2trj~G21WG z_sOKd;8&dZH^RX}#Ia7o8!5pWuX^hX$4&D>D&_-1UTmP#9w+NfUd-%q3ZT$l&zim0 ziGM2`d~UB+m8z)qnt3@?+k0uS6sxn>1r7GcSengVheFl%nR^JUlr=FEtFKAPu{`c| zbI&w;5K$gJ!B@%^(VVO9&yfIPP<-t32z}l4Sour|83Q@Roz#rg5-iEP?*TNiX`a*q4mRL@f1{?l;a-cOt? z=#@{Lf=|Q2m``b-cS0KQsS|&QQ~ak+)}e6dAbLLWXxBl8{X|II2el;MZ7z+nvib6JeVfWVXU^MN*qz`h`Fus?ixqCAy{To zP3oK+i($7kHopVbq8Hr9D|}5M-g^mM2(_X(wr2V>$yzjlv*F`dnmFd^V-eP6rWtJF z4Ud|=f=>2N3PrGtA9Pau7)vR=w{3z|j?oS$A+=*H0c|hd0WP%CTIS~b1(sPx@=L;T zvxv>ByKz|RaZq=Uz|!MR{LygW-Q!NyQ68HWnK;hD?Bac}wD@_KiYEfguzF&dt{uVZ z?$xfNTiglL7T)ILjk8QFb(ED&XVzlL-yDgTCHqe}S;xbnzTZTrH0}#MfF-AyL-Wg6 zHa#x%oirBHorT>IOD*EA$SahoSaOV4PvG&B-fTNuoP-ew*7;W6(#yQTgp}BvHSe$% z!g#u(Gfir}asJncq1@-*E5yo+GR$CU#5;eEz+Ybut{ReTwFI2feEZ zF)BPfeva;_DkmFD+cRx?BFSIYIsP4Qah|0QURw$XX*F=B>z)+&;;d8feK^$c*XS0* zCnjPsuJiJ%wMAH7&fvgvtaz0XJV1yx;Im4klT;GAs=c(~}kX71q_x#u*)Be~<3L>h=OG-sPb3PY7M-Y~+bV@*i?AA^!p= z?sRJC3v4sbaYL}V&(FZ}UP)*qp+6f`fOVO(v0F;$b3#{{iq|BCdhq!%rDB>fc&o6u zy^!ihLYfS$&#p-^?E-%1#I#PqnE}6E0PrT{vxH13a(>wuzuod>U5TZYZnn((vD7~A zjkVxGEOVM_#wX5fDjYBt%e(`$k`M>l(yHQ9YDW)*pR}nw8{##5sOm zAMl9#JvEfbr`T-!X!{JTYsiK7pG*o>;Dcv6j+iGtZ(&_;t>jof%r>|<>MktJDUrq9gw?hH54V&>SSp=!d5vEO~;0)Gw9kxzJ{&sUO_{7EGPPuX~} zihtVLVpYEtsG8@1(mxM$iKTCs!Bvu#ZigJHz)qk`tPC#$>AQh0vGhGMxc(a}-99gs zVKw*-YyVG*1!~|SpzFV}(tYNo`YWs4uWkLluWbUc zDmZ4j2vz|c+r6tKtAHPX(*Fe1z+bG*iO|dUE3B!>fyTSU>KF$GFFwL~z`Mi>a@+Tq zJG;l+)4d9~FMF4`JRvr5FP<%0AIJ8^!z#F?)h~tBpw_T1v4U;*qXxHwD{K6FNaYeM zLoZkb^|d_E@>Mo|D9k_KF#WNt;Bae;6}*N&nw%qHl{*?%x#M7YWC9%2LY_i^f4)3V z@cCxK%9sx;;e1#b?}p`a$J#EeZRBBCmsk}ov-)F}*Tc%c5!O|bOSeMUM1Zu0R*}hLxnBwfn;= zXP`vOs&I(4OR}VT`lSgaxE_`;l0PaqP3+FA>u=CrX1d}m%N}c!jkBC#In#0$T*W<2 z_K2FJZYomdd}Zzb7gm8^+w@{J?5MTHYS;-_ z(zjOsJ4Z?iD)4)ouq12O(a-Pb604%Kux|cA)$;$HBY!DC4Jbo_svs8DX`qI!;J>lj zR@6(8%2&jObu&#e%MfJAvVinxi+G6GJXSu)S0XDuQOB!r-v3G~L$_gb} zE*grif`{37u`0d>*0LLElYkN#Lz zhBvX5?k!jay<_9W8siUa{6VY#H&zEfijYtReF`hjVarEgRrIyBi!6U@`3G2+Sizqy z{|c)ie^@&PLlp&Kr3+cE0Q1imxq!c_sH)`)VY$4Hwd=yV#44a6%cN&>p4j)ZlIRnTb5V__AT0rSt7WA%wvpDd9}td8W` z_^GgN{t;{60_zg11NXzRntu-w&`!1n)~kn2uqxaPmxFg$`z2T#(tcQ%Si$%CQw#nM zR=!iPJb1?PAF%hTgzn1&7w|{Nq^7X9{`D)XYIzG-660{%6~VkODqrG2UEB20UN)_#*0ZWig|EX(_omhV ziIwgx;+6j$o9|s%Sw1Xn*FOR8605+Etu0mopIH9X>LpoY{I%7^N`KVaVwHE?+G52Q zS-YsT_FpR~;)IP5tHs~i4BuJ3B&*<4RxintezCe(>CVC`|5vLQbL8(r30oP?Sz9do zH&_M!4y)&7m}#0LwO}pJdYXCv3oCzp;?=Q6uu-cviD?SXjgtKk@B$)CezR4!w%Y}7`Rq+&Si`BE~uo^Ji#@}o?VmTj{ zXKu0fTv(S_4Y|YWcUpS^>^&D+L_jTEVtJ|MM`2aG(%P$GRj}6T8(>{xrF+uyCaa63 zZ?U#m9ouSooAic20Y&@=Rt3+)YS4DL)Rsq@`+o`i`?#MM(zrx!`lrYI$eykVk}rcR zA1M7CAh*u7_N}lkvGm)3(%r7vsEdGiiM7w(XH1WkZ~+ki`?%jYX1gKpvA_JXLylBn zr;QM6Lca{8?*_WW()Y;V`fsds`@B^DKJMo}f+sXJ|9#y5@8f<}lor)LJ?7VXk*@fX zkNKs`*7o=B zecV5?lsQTM`?&w#$Nm34?*I33|G$s>_1Ir0q<Ejr_^j~{rE}^(QK$2PpTE2FuDC@*zd8NE2IusJuU*_Pcf$=g zeg9(bd){wy-Q?LHw3zr5zYMg@U(-Fm%HPKy<6iNYf2iAhxxa$D@iBy;dsf0h3D>Vi zDC4eQjWB-&LWMO5A$Ry1gyfY7FGwiohSnk+laR9(p@O?j!je^l^41|#a(Avn==B&v z)Aa~d+)3*Z&PX^Qp{m=c0Abx~gn0!B)!h9OhOI$pw*jGsJ7)tz>{^5)5^A}Lk0WfA zu;_7wI__Z!8S4;wY(%K%F5HMvb3MXo2@TvXPay1(u=)vvM(!yDe`EKGC!r?p3eiRG zSy5AW&{I$|cfIIh*Ix)VcZZAO+(O7r-bg{!o~ED{Zralb$0Y2Qkll_Gt<_@+<|lcN4cD zY?ZKR3qp!}SVG1ogdSTFI=KtCBGh~a;k1NQx63w!JrY)LL+Ik3k}!QU!jS(UbaPky z2ch}12*KwNdboq0LpUg5vxLiC|MLj*w;-fHk8p)sC?R<(LbVqV`nYK?ARLphTS7m# z%8Lj~wjt!bh%mt2DWTVY5SngB801dcj&Mf80SSZMMmrGJJ%=!F2f`3{zl34WBedIz zFw~v1lRvR9_$x%VuZmyNn_6z}c;e|>*EgPeB2X{=v5YOHdvwpe^Op-hxi4q?w&bS6 zdQ6`6*yC>wTHJ5L;7jU_{pO&5*<(2mEiOCl4Sn?3@B6)yJ}ImZj7P6hYd>8XadJ=G z(Cghw4=s3T-Xml%ZF=SGoO~GVe~=Tx;vCabINgANzKVCu?uL zy2*b|-ulHQwJ$pnY5tSD@dZ}c5w-VPH}NIfoADwYSo9LY_3mK_HMb-5*oAO|yKoo6 z9to!VfD)hquo;yn(ssyvKt}YU9lVCpoHKn2;$z^j8sXbPFXMlTd9BLXMlZ2Vu#}2)iXraI5S^=(QUmZ!f|mcc+9i5}Lk-kn2u* z4Po6Y2nQtOxsCQA40{z}-adqB?tTfedl1^ajxfWW^E$#-2}dN%aueS`$k>ap=naI~ z?qLZvUqk5eCPKtr_$I<038y8@al5>QFnu4w>bDT)x~C*Ge;r}S+X(aA6>lRPln~sH zaJxHbKf?Ss5H?G=!}Y&|ko+b>`a1}BxrGvrNvQTN!aZ)zKhWA1B3_NIUgWw zm2gDDQaAA+LdJUtiw+_@;vSYz^8iAR4-uBR3qM5IBjL1!6>gW05T?J6u=*o}RqiPX z%|AdG@-f0{cg4pD2PFhQL0Ib!`UGMAL4?f`*1P^s5t2VdNdFXJgIg%!n1pJF5H`AL zhY*&0gs@w}lWvvI5PE%#koOrvp}SMU83|24N7&>}`W#{1CkO{5Y<3$RMi}-f!o0%> zTipE;Vhyx<;|Q1f$tMYrcy{@(uW?!vDS z_Iyr?(_fKdr`zQS!t}!ktB)Y;a!*NU{sqF2uMu{;E51fJC?R+h;Z=9gQH1$lB5anh z*YzJmNd5{T{TRYNw@|_{3Du4xyy2!DM_6(MVYh_0+$u!~y}m}sD?-@s?v!vwLemon z@4AytAgnuza6rNVx6wBU!;T@$`v&0ycfW+#;|T3eB7Er1If<}U!Vw7{yNTZ-WE3GR z`WE3+_b`J0klX${=rebr=yUhD=&;-6d*}=ILD84)DbZK%6{nyh?h42~c#?vGKTyz7 zchC86Rkb+?JWbE}+&zIQW4r`(;8d*&1c zHT{`_esm}OjIizpgaZhH(|)({FaE3DVLzhG`vv6}zx$4q*q>0^ok2P4cW*g^vQ^3v zDd+rd>$4~sr%@K2MLF+xzmQV%XOtelqWs}^@BbBLkCf9We!tu09F5t4sJNdFz7oLea2n1pJ7AXISE z{y6i?F0L!fpwdx>d>{^eTgpR}LZ3-6`RWgr?;Y+PIU-Bdm)> zI3S^&+o%GLO1u6gyt0yhFpNq!(DL!!a)hastA|6gQ_CT zuY|B!!WFLnLWJbX2LA?UF06yFN5W|dX>OOg2-9mKtgeeN+C3$qc`bw?^$^nC z74;AfN(k0R80QYEk1)SB!e$AXuD=07avg;91_(F0g%XZQsMZi6$4zU9u%s@+ZV40I zDvc0&)kDZ@gfPk7DdCKSri~GD-ARoR*40NiAR*6f)C6Hz1B7`^5T?2NCB!yFXm=69 z40p~&2wNo_kub|mY>JT42w_oEgxT(42{jud^k{|(2*ctL z=Cwp{-Te|`TOhQ%6yZU4&ZP)jB^;5k)J<%KkZ}pZqE-lxxQ8XwOhD+7h_K9En24}P z!f6RB+%ByVrnf{`-5Oz)drCs{OA&^&L0IjsXoGN2La;5uT6a)eg!!!yHcMFV`r9ES zCnBV`L)hRJN;oE=+GPkE-L%UPmb6CLE#XPGN)ke^HVAo12!-xW31=iUO-9({PD(~t z*B0S`gw1ZF_6Wn;Aqa-)pxf^vE#x6Tg( z?k&qvwn{m&9OdJH+j<2`Mpu;8JRb;r8gRR=LaEseU~hy|?x5ZXXC!Qv@S{t6aY}E5^galu z-9ib&`XE&6i|~t^))yhRFT!pKXWc6O5VlIl>xXd8-6v2G z_#@yp9uUAGQrh80P9QS|kYxG*gii;MC&rB%h|qi>!aV~Kg6@YB4oc`Wh(gN5xbH0U zU%h4ipup!1gU$JDXIXd7w19qry_Ea# zO1alf4Lt9k=%y70hAKxWk&m2{Fh6C>>}i3w0{)-2^qU#Dp|t;&EgSO#gUfiO*1aPT z8%*b8!WC6hs;6a3J3Eq3j+-jBP{jhjqRQ&qRea7o-<{&#JT1`G)1v=(^bdLN@Am|L z4aV{*%xcQ{ftRO38vn)CcwSX6&FAyT(j!KX{*T6w@FB`ds(r9m`|I~pd+-igq_n#N z?!$`^B8%yZgd4rg)uaDc?&$2ymio_s^)aQU54$bhz(*ApFEjmK4tw4D(JQ#&qk-6J zs~+<{5TCE~(f_^g)-8=T1Sa@P>&1WUO!v`;0xbhu3%0!ZP~bIxaBQLVgK4#^Qi5J7 zYR&e5oU^2qM&U6t3YV-2vc`ve25rtf&FBl>XsaI0NpHGTWyTB~{A0i}NZ?|i;{Y{kuNLVZJ7 z-<8yLvDNg=jBKklw^|Lf=~j!gn!Y%BTs`87x0=2tQe?FjR;!H`Ibp?1tXK!}8>=Ot z@lXGGobRO7TG@2^Qq%WVOSD>jG<^wKpAT(~Cf7FrldKlD=^CPSLt_XdzEmq}vK7j2 zT%E1fm~cgAiLNeIYeKlOYT)W>HBHKLR_lgF+4|3QeT#sGu!q%}5k9Ax$91`v7yoPa z)?muYz4|(>GHdoeZ4>INv}#uzxP`E;J~mxE;kj0ee$}=G+AuT?Lw}o2Ghbh^)i4aS zS^{D3d%hZnE3K$6Drmel3|GOb_)?&6Fl!i8h#IIBGM9i{KGdd5Bz%X})Bxpe4eqkq zaI3XJyVq)wYixo1c$4owD_&<4wnNK9(-`V|z$#G7@OuTgMp#YDF#3}cH=xOJT84*# zuF*DKd&2weL?2@`w?$4W9X#&~yo!6!rn`Y~3)ep;rmDZ?mTF^SF82q!A$50$ zr^lr9&`)9LmrD+U{}8^IH9;@FrbrMD8?R@!|u zJ*IU;H#yzZT(AT@2p$4Uf$nRMfOJ|h7K{U$dzxx;u%?Kngl2$7TqCRz)d*^E-2=69wNSM%wGb!i7aJxM$OT%3(|~S_x)JKer~91lYr2np3%&!o zf1Lt90{x_fen>+5O6gZ3WkB<;2JIWYe9E+=eU?U7c?c< z3|tKK^E(X!?$6_58b{tG{2tJ6^gIEc1Wy6o`t*ZB*MjT72=FEzehVC8;eQ6+pg(Vc zw}IaHKLhl&yz^iv>Gj>gZ-BnCr>|=F0s6vWE@kKoiu+2lN&P_JNANRvj)=8j9asYO zmVgJr?O;B*6Wjyt1+&1-U>cYLGC(HKDw@f->+7s%!8!07(D!x+gW=#>z&DR0-fdmq zAg%_ggPNcgaPh%IU@3SQJOUmC%fSk;608D`fz@CQSPRyH^`HPe4hn%z1o{U02%rsD z8>}|exiPF6-ALO4Z3_DRk@G;m)S{nt(NDpQ0{Sr={XmX>L`OfY(+;!(`ducyNqC6t z`fZ{U?#8T`CS6Vw{26=!z64`HI(UanZRVI1Ii3UxKfIexhPKtlNaX@vkr6z5zC%6##wL^%$5( zcrJL0@Y_JQ`ajC}+@&|h46pYL^H*OLtqtmcy5N4aPT(=OLUv4@$d{BK#N0y}d%JZRAqTiuv1$11f4ET9ZAHU-1s|qdz`sU0_Zdwk5 z`#ixHfDQ}~g7Y}X56=O!z)fH_*nzH}Y0wvuZzKE(tZ&S=1&zT)K;M*21)V`x&<%74 zSAgE2FSrT}0at^eWjG`aCvYve4qOjLgE1f-=>JL{2Qok=$O1P4eS>x|BV7O&x^d%U znnX6zrZu1za$Qg#?8ANp%mDh*{Uo5@KiCfjfmjd%Wq}So+B|&r_RC^I5fn?ADq<~b=pN8uD z?C*gC;2_Awp>KkPAP-!N7w-o5fCWHbWu5_Mf-LMCflgzasNc64JPWpf21Lw+-%%yt zJ#YZL4_*X1T_u9fpbJO>$)G)`0cwHL-~^po1J;4}!H3{o@G4jZ^a807h&1Mpj%Rhj zFnaefy%|9xMuIf(Dvfy&^q|m>Nb@n+1Fl2MgEK%n7z6ZkP{+Uz;3uH(mFRV;UWfJr zU4dSIHU~>6d!>Gjp&TwL55575DD)068;k}c!9p5zp33!7QAc{c!WshfLbn;X7{mj; zQu__))!D6J9=HwM4(0>BLendIJsY`yv|Al$KQjdO@_D2CM*g z(ST@JFLu7C!k>W-$d`bY|G*`+!zv#<1(t#3U=f(5Ut=l*c2N0FunW8lil|gSp6~=* zlZJ=|{f@~tpkH{=YmjQ-D3u=pDWDVR47z}dlv@c@233Gw5?lzXfeJuR$Rhf(U;%iB z!Ut1WH_#9qq=5IpV9*Ej1vNo+GVUhr3*cq26YK)pfR5;uNpk^EoS<~^=q|6@IpB&@vnjF(U!mlvRAZ}g)_7~& zHU75%{p#9ma1+okvW)=KfrdL5=*+0Q^L+jIwr!-)Nln2JI7m9Hbjkb)Xwj^rlqJ>hL@KkODl?XMzM>R`A#=mR=|-rx#wIZz2bK^XJ^T|sA4N*9$FhZL3iNIF*W@i6|Ne&5_tenANqs7Kz&f#`&m6|NBgNb zg$IFwCDLn8jg}S7qh9tZkw*E3g5e-nKTSTFz^z~|m;xq&G%yk{+};ZqjdER}QNPxW zi*UfZf#3*mJx~$KHVUZT(QpVrt4%}$NnQ#WENZYks6`uo2 z=n=1A6{L(AB>KcAoQORED3iisI_fo2{qXt#t1;5m$7tWADNVFPc{bfG@Ki7dxPXEe!46QR+IJoR z?a+01b_p*5HONyId_?#mppJY9_JD)n18@Oospnz)3A_QG2I}?e@ILSw*b80-kAYXf z%isyH5v&CdgQY<6tH4UI96Smh0n5M&uo@_C4NyAi%CkW(SH$C>0IUZpbRAHF;)H}1 zuQ=&{ugELR>Pn{`zX+ZK>e!P&FLdRNr$8b24~RU&pG`o#6>I^|g3VwXs03aB&jY!3 z7f|6Zf$d-?*a5~-xGLC9SY8xVfp%ND{Vnh&cpJPA4uJQxUB5%%U7+n#Lm}5IlWyG? z0G&}amdDXP1)qSAfhOruH~_u|M?f#Mui!7i7vM1X9DD{2fmOsGvpfwxt?~bZK#&Ro zzz=@M{t5g5z6B?NGJXS}07c*w_#S)*P6L$@&8Iv{|0Arhbfr-Te};bn+X>75K7w%$ zoCRmVui!Uu9w@Vq28pBYRalKHg|3%yYJ?gp?UTYVO zx>pTs1KNUU>!Xcrh1L$J18S5StA^^aj~Xjmy2_V_1U(vxmJ^X6qdU-pf)t<(3WtH# zzaAcR16@HE&>5tHH}H-;p!CslN`_TtNxPS|Ri^cv+5e-7`j8;nG9{2_`r1r3Lvj4y zdr~r9-cgw)wP+oG)fxZ43jfm{VhdBNmG&BJJ%-I7+zk&5Bb-B6H>Bv!r?@7>Nt;ak z4ImRt1QS3y7z0M>h066nNA;25I=9OmJj%b`&EB2A(~XtrrY&YikvnL$Z4a1qNjq9UZsuxUQsk@ zaV4IgYDJr@(iEk-XMk~Dblfb0|5Q>mshVk$ml&KuS24!QsirA+KF}~m$2Qt@l_Ff|P-)izIZe({4I{nAgp|ZAvX0$BZw_D}s$ zAD;s1lk#oUIpIkHPlH0R2|NpQciRf9aSFc$bijNG`(>~T>;!V+b|780SPoR$=<5bG zKu7%xV>kv7t_N3x<=h7X7_YmN?u)rJq6SsP{2YD<=v4IvEa&V8Z-ckMn>Kt1J^tMF*0hY9P^R2A^G z)%Cbak3TDdXeDY~1?+O5EKpe?I2J_9G>uC&t<(GOL2!hGdbF%Z%x4M9Q77P2z)#o* z)YCt}Z{Sz=o&_;AB0m!R0elaRfiFO`eP0n)onHbuLsc9F>eF{X+HvqLI0?Q1s0yWzITUb-AWSP+hXr^dpC{E!>$wYEdHAFr96Km1w+^q##GF>g= zq78{QT3X38s!-+qU6-cLXr9!M@ii;n%9>C>W6%QV&4C9kOGejjKD|fVMZLswYLv5hhuf5{$P1Taqx>wV*)HKj$nemDZ zTkqoiil#D^MuV?+^)x{!D^grp)X^#=8E6e_;5x$^&{PlxXVJ7QHRH5~+7s3i&@*(s zTcqdddgn+DRfQ@;VR1L~=m7U5{Gq0C4+0udRieT*$|}4&TyouON|vlJ>WOIK(F)Z= zl^Jc222AB$jwX+&5%Q{@(bsf)EaJ|jODSp8L~Jg6sS>$BUkAU4?TR>m}*l4{t^GDweJpy;&}h&_V!Rg0TqzrPKqrC1nC-k zL2QVcsKJJ!qN0ePsMruSF?KOVA6pQ6?_G>yjYebd1+gS5HY~BklJ_$^JDeaF$?yI8 z&$v6!JoEH<=9#(0*W1_I2b!Udv$c9dD=>qlJh`^x?a59KmF)oF2LNBB>og4jfnxvw zN|RSq88h*l7lukI05A}GU~tJBpI;rj{?B`{DsBv2N7or{R^(!ndlmhveR>1UHPhrb zspK539#_ph(HQK&Cxo7SqH@E{CoT{CQi1bhL{_3M0KiWbI6y>V$jN7SvTK?UwL%YM zn7o4qJzt!;;3NLbMbFsA%}N|w&}_fj1G7(Np2-HS9d$Ew{iOE8P3YKRoilnu(xT43 z@EMdSX;^lLI&ty2qh;J0T>Iy*!p@;5z}pund|%Vad0Kx-mPwwk^(qns^RjT1srr1a zpX4S}%zUkr!3U>Q#ejFXQ_a7le`wQ_;jIprKv1Ct^D%K_05EpfdapZW>tA&u0|@jE z#Kc|DV}%~Cj1^axmhp{NCT0{_MAIV-H6#FlsdHTv*}R`}1}cGt2QYv!hPA3qyv z`?IzYes4AJXYEDJaq7}ic9hY5o~EQ?d?pS~*#sL)xZIgAWu+IJ+S`xG<{s?>faV!J zl4ZS-UGZUXhLxjkth>7vwM0n3hk24EF19bwIt7-*fh3dO!~uPN>D=u8VL##1t^%}QT|T?S_k(u>Ac!Lmq3Hm?k55*!CYpw)Y4w!3 zKpiv6}--G5X1j1DMeIXDoAj2YzcDJFRMcPo!8vF)M)=TAWDRmJv8V#Rf z$mDRpHosf0Is|0U7L!IgoyIuLI(mS{xW`U8@JilWW!{yVZJn9{j!D;Fk(%3Lt)E7b zvLi(=)|SPO(|%a2ZDCla4w}^Cr;WR>9K9iF5G}j|VJ`LP$zmX%OvRP}&QcY4>bUfV zE8g2IlQc>Iss5B z=Rkv(f>2L<6-3)2s1{tAg{17(-G{fDR5=M8fp71xkU1fmF#Rumnb_kSo5Lj(UKRb@ zI8v2mKxJ^GkY!pAs~&)4{-|}NVatGeBduKqE7*ld#@xhJx)ss-@#8ok_zH}p{(69J z0zh+u-ZHpMz_G}+s`!Nu|1>-wV45g}sxAlIJZice?3dG1(sHo>7ad!!^(>Z-P{X3l zdHRO|O`?*~vL3GgzA2g*+SmupP&$StP=_^x5%@kvvmvfr@DL0iy-bhT(4(M%=`*bA z{zdxV4%h=Ah)-GoIjZ$@AsFm1D+?AKH1n^9yjs9CsroYq(9FX1Gg)sa>CT1K{&3LO z+0EWO1e_1t1AKL-Um#8VaoZ`Dav5!a#dLbgo?DRhYBb7I89BhhrXtl_4QqC;$d|eC z+l(uEHMtT3L@JwK(!ka5>O|74N94#@tqs$BN49I=;rx|mKgAyd${RF&jWQvF6ED?K zuh$^nL{jOs7=>T9t_8q%v~UBO`Sf%nBet2=6nNg9$M0U$FTqwvd0z zd&2kc4pMY0mSQl40J+L!2Ce@U1o9`zsS34P52;nG!k3-RmC86wp4WX1hA}ne4ikW4 zoJyhkXfRKsC%H1|)S(ia(0olDS;J|daT_2^E*nYmrrjIBiz-Hcs(&2Tp6;#eYLdN- z-$%@zmeCkwG0Oy598O5emad`}nHf+&43uJk_#FJ`_ z9I<%GY0n*~vhoqt1`n({2m{Gs&FXt3haH=1Qbl7byUoN;1hr;QgQzcSRPCzV1x*JM zIC}E21-czwY^EMGA=!i;BYKv^_h?XJ)aezb9wFt9RCNn57Q}VIKA1V?B=M{}i0N2Pj9TUHy=4g!0HL)oH+@eFT%g-IqpsEQ@wNN$EacTXVs8#ZqVSZNZ z!T=5C4MjDBygE>j7wA{QdIoWy$umqSxu8Btm9FGihcfmcrwy#bHCF5Snc(a+Kdj~= z6osOPnXZ*(&$TV@zsoT7^rjMfA@dOcV6J16oD{MCMg+@g)hNc*Dm1FZdoeMO>iRr= z#^!bTT2O4}U!`i!X?_NnRI?GrkQd{>Aaf|9tQYylsp86=)q9^dz_7C(-`>`)GUU+W z_vs(as=BwZQa{?b55Y=ZRE*{qmGTW{?MLABCH;OZq_wHneq?1K4S3uggKt7XYMJWe zy%iH}FI=!h=5PXU>>$UEbaFo|HHz-+Q zB$$(*a_P5@)5_wL4!J$$f+^+zRzH70up}jH`1oQl56}kDLSj-jyhz>i1ve~yewiGn?dde!N(=4$(o1M_MnoUOkj;K{lc2& z`1ltjswM^$@++L^Db+m$4=vVQsi-8^^Yg89t?T8Ez$)Qtd75V^(~^r( zS0p|qz4od|NyG9^Y|AWS=w~3xFN}hmR1-|=A7ko*M?eG%f77)hsa&2!)v&ZR&)quo)l~5F8`IS!k;k+bhyp)dm4wL5=U05F zp#a}erOk5#2`<#>c)>2D0@kK!NaX?xa3O)|Q}0uI3YKR<8W37C>}kt`$k(@*_5G>a z`gRZo^y!bSuo6~0i=p0vWZPGLgoBkh0nPQMFHUG{;fD8^pGukLehO89xAk>Ck8Hv@;{-G^?cOP}y7;51(~X>*QB9oNuk#U(g?l z**k8f0>G%T@IViXIVmrfrtK=L9i!r|Mp@^yWr~2}>K1X~RPT&7RN59!Q_pCfg2uJy z0?N>bbHF)9iA(Dphh9$&*cA#r#P=FfJk?hVQuXOB0 z9%u2~z7s{DHD=)?kGV<9As!0?Pp|&~G8j_Sq@HvlpTD#YwC}98thBi^WwGIWn3Hrc zf<~Of^SKD}W^Hx^H8}^g;{BK|H2Dv$6XiTW!tzrWihF>E3J>wHp(|yu9>??A0I6Ce zg`U?s8S6!IVMxnze(TvAU#-!wO*Zmyi)N9O42Yn%fMEO_Yd7onGv~&1VQz}L7$9QR z9{(S^58L;1+DJ(gi8pLNJ1mk;u(4C|%&G*b;WaKu2fDk+8s7l;IMlcVJuD5oIL2{f zv9ncVQ%`y%883jcvw&drxXW)}9kzOO`+F0_gGg!xh#_!g(flr3IUex*< zGov{BA*=pbY24Vr7HVR(7KEuYJt_90)R>Rf{Ac16avq0;HUJZbyuLH1$}u4kNoaH^W_7&IC8&W*0ZTEwW=fA>zJJ=a^^#ffci0XoI!Srp+B!`BmRRhp2bkT8(KfIyP_>+RwAk-{zU?UWG-7LiKBIr zPW7X->;Ef)gi1`R5-KWq`u`#aL3m1ks&NPM=z3FIrO;x`Pf-46C)Jn>L(pGwv;k%> z6_2Ns0NGD+kEajp**Bgt17r`ZB=2u)^;XT>@nnBkJoUV#4VK0O?6%gasCZAOZfmQk zz}65xRfQ$zKD|LaTRu#vTtik zbg{9EbaYNDYsOaxvm=mGs3nx++6QlUz(D=9y*=H7C!9K*t z8&xVm@I}Q>tTZ_3DDkJZQPFvrjIFWM^&E;O34cQHC-5;)t-I7@Fdh680l3Rx9)QbN zNUJZ6A2d}JIS3X^bHWYO_^!60)%77f3_B%~&pk+_d?Ky83$FYV`N|wxV_%G8Az`L5o&Y^VbKEm=9b|&JVJ8j9~bgHcE=;G^B$f0_p zd2Ur6BugJOy6U4l6l)-SV7)PzFfNLutO9RrjyKSQ%_8P{RAdieAo9Eh|Qsy`s{2UqF6F|BF zvcnH_@Hw*BqjWtCXQrjcQ>hmK%N|d|UTBl0W)tY$3y|>51itXS8^8R=ODEzT6uZW; zme_ z8n&+jlNMXi!;H$&M<4%pqrS>D2Cjt{Q|K`pYkvNysl0}5bt33$+X&merg;VJ=I0e$ z)}KaG-~20=ou|oBXS zh6EM8F#Aq+^<%R_#(pnF7UDaJbbXh4BGG( z=}Ma!bmuKf8z*OwT@%?s2LsKVL80%UkY_Wf=R0kv@ySf?$j6G_uhcB;x8sT_E2%ER z$ccAAvS$`a?~%k6aG(k+WT59}Q7bHjLH@)U{O+Hvsc)Se_zf-vR~_`Q6!Ff(UCtS9 z@7c8}HL1j{2h$>|H%y+*E&5I3*r&HErs_>6jJZoHs{u;j(Cq`*;1SD#T7E$JP#EiDQHV7m*iNh zmpvLj*?C*hiXV%LC6Uyzz&mSO^TkE09el;IbAP3hv^RBTCs|Df_0k^;W~SiDW9CZP zUwXM)yzzT{$DG?Mj>x#@;;)1)$26*FO2SxUC?MF1 z)A&|QBaeOCcM1p}i#0>ZMOH3jbyz~j8EiCQ+2Z5;y5FOf&C9U>s?6hOk+@`*7DbTn zmXNbn4whyup{`oFhIDx;&1dglETuRdTE}H{iao1@8_g5WCwG$6sU;#2EPlJ^QKs+0Zj7YSddd)9CTmM%4k}G`EM@0hn({hm?rXuu^wo6D5|UiInuqQFNi!NN25;qir>@C^GDtZa6DFPXN`pTHOhTHXFW9bh+ z-?w!#X)$LFWnqvZze@rFYbZ1Q^HjR1JlbeJ3+b?qHWUSe@7HmcY}fi&Sft$+7F5)` z8%5XCouYE6^nN}06@z&faIK0}_OM{D-ayI4;FZetDtk-Z?!k90lxtBUla%shgSpT7 z-W$(tQZ4s8`;L`{tu>gkL^UVP9jWG(((O%j#!B{({@z3%tYkOo{$_GR?iy5N3$Ls` z7~W~|UkfjlGGTH<4~qt0Hym~5Z?Em0O+D4NP%OrpquOYGq&ezTYRqB$-@WffDJ8)5 zrLAg~J=1GY7w5!MusIZjS#JLTJucw7{IAx|>uM&=K@W=H%$30k&O*dwl*Ws!}Naeb;>%=s+mQU9wko6<0uAWjSJMV(?<@x7`xG_muc*wbV_5` z?+Wbqd%geeR@v?fgi>BBu^T@s2KFzDgk`TTk8kg@c@^vdyXi3-8x9C|tHi7L&xdEv zXc}&U7>OPa^w_1i{b5X7fD^NK2YPup3@C}K;GUFIT zG1wp5)JVTn{i|E>_vg9Jm`8lP^L@OV_5eE9AJzTsC(#C0RIfB>*8Re_8O+NJOI|rFJ%jSD{sC)VSwywUl`#m)oov`?WK)@)j@09Qr!;%7XN>w~T2 z20xOf?WInL0BSu!;gb26B>K6uouqad^so$g>z~1s$Mh2OzWnyct%fWLD=UXZVg`M1 z;Brzh^v@taM|kYZ3`%yyLNsI__wj?{&zcrMGARoEBP2dne-DO8dDDOy}M@USK&5pztmUt2{#wwRY@#> z!Tcfn^&z^}7{baQnCvw2VG*(mMO8l4=MmK>3zBK+_|#F<^@#C;#l$aHoQ0H5q2WJ= z&rH9u|50vuD?7BFQ1Xw}@oME6RS&Ml0z@fRzuv!5SXl^r_;1|m+m4I0>9cL~SVe(K zeNwHk)7-MMa{*Oh7G9ucwJPjU>^mT0NlfnkQCyu7m3rlu2A)L8`Y zkz|@DUSB&#v%i!hD!j!s-XQ1Gb6U{@1n7+@FP_aq@+m08O%5ppUX>xT@{*mE^G@mQ zF^Y4S{j9`HIJHdq0*ia`0CNyRC^+59@dISna&m}K3@?b#yc4Lhkv<+C{%^y%tcIWD zJ4^ld;SI~`B3S8Pjbqc%!*-*^t)l7}d%I#cjHR3{Y8HZ0p*}IS%A+7bT6U6JRe*l> zoTLv`(Ox)7-&H7-o<3rN%QIJwz|p26HjVk^t7^6ox|(^K!Yg6F=R=b!;kQ6pr};_F z%9dqM&;RiZYGO!ul%(P5Y09VsvPEm2sQh-FUm!TDUiC$x82`jfav2wM*q$Rdn1@*( zGUGGs*qj+)uG6U8{0HYTqjuFB3+pO^4`Dp}&XEgqV&VJweBF5E9KV^6A!`n24eEKx zWQN@R3*+`;PII!$PeXqFsWbftZxl0{ky)-5{ya~yb-_J%k%<2=!=ejhWU*At^f}%H zPa4dEHMD>1tvHd5mGvzJwPrHQ2L)-u3a6r-=!<#SBQ{o1>Gy*S`Z&39{ z$Ud9i*q+o#4%Zmw-{4!RgYA7@Sxw$HO_@&l#riIK8iGB_(i>D98(hPB0J2j$x53Re z46tvO0YD#I4g+2MXRa>TSM5|`+FritS<1CJzc->($CTd!JL*^kk^ewF=m21?fv>7< z(QdBOH)kvOaPt-)eVf4d`Sa#f*wbRh@)zjAxeKd4ip};3jAf@d_LHvMYJ2?9Qb4fl zKA?pkW;z940|Yy}aj@H%K5Sa-Y(M}vOa33A#|}MFN%w~gXn%7#dax&C^X{R}P4IK$ zw<>^N%;x96o$QS=o%p$|brx6a-E~8!e|sw)8wyN|J7)O)E3L**>n!Tl6xI9VH)(29*-fLU&c257Gxc$|c=}mq zeCtJTy2OmYD7HU>G$(-&CZqOyAM564KB}zX^Tlb31^*egG2u2>`OzsOY|2RI6ItO< zna^V09r9}?pTI<#=CBd<=t64r2L&~kdrAxcq}1l}T&e3_su7BvifT$RcWFExr3v?F zcPJQ|b&o6h;p=YKyOb^(ps=hIH7new96(68ykgY?BN}8=ofdcoqv0)N53BF9c?Cy3 z)HRwvx^;a>8Ngut@*%hL44bISxZ1A> z3UvvN!^!9e2<8ISXL@14dXG4EQXnOOdoNhLE4ZMjAT9x#?IxC%hwoT@oZKE z5EOexKAq7zKcjkW(Dr{uX{T_*;oUPHO3xcJu6?uR;1Y!?#XRkvlU-ZfXaKIt&*|~k z7T&1(%kjfQmGMd$ttCxqgYhc2nx3=|kD3v5wGFNn2!6O| zammLdS7*&QnwN-pIYUL=Z|-jQ>5+T(t2O}ZU-XLBv;{9~Ur|;!v^&wZg-slNMH{+9 zQHZ%WUXgb@blrPJ86D8RL{}VIi`O)Qy;oJQu_5<LtpUJlNh_Wu{t!OLeY+|I_(f0h{T5s& zQFAoL*?=nrxU<(0qf z)E=l5)9=Pu&WT=aV9%UJg+Dz=t=$2naw}IjSKT+)6#j)@A;ExxB$yx1zs(`MOm*p8 zE6nS@!j}Ye{#ce5T6K2Z5f-rytlKg37r|#kXPh(Tm4`qrVvg{$&!KGklvhP9WfdN(%TRon|fsxg38>QzLUtF*n9>AET#{a#^N_kCl@ftMaiRLYNtF zqxry&5g!Ymn}>rNJ0b1=jC)tb7Vc>W>s~9Zu%HBGRphR4C-dQzhf%gvC^P&^ATHQK z{e*>5j~;Rua)Ql0JcLkiTfH{hz2;I@3ip-KHEFZ%GcLkW_3@mXgTxO;%DaX5O}TXyCjLK`MzzIv zmNsI|VelEw6)n@dbj<=h?1<&R1>8ttA9?~^%1tDsQTRXq*b_wa(TAA|_+3U4yJHH= zQ&LYSqg4)H>mJqb7#`Tt9wLOJv2C!$mnA8nFB0bGBl%9w_&V8o%icAkky7L06`Q;o zjmAfb)Nd1Mnvv&V7|)5mvU6bPk{ab)y3N&Ll|7Bsdn&R~Sm~qoO!7SKydpOnl)&obaz{oob_S*Kovb~W3|mqGGm$`p?CB~xl1g)f>+ zi3NG)vltP+KZ?gS^{Wwxk%hDnuDmU!=VWa7HtM761yj{%YFlL@ood_}vC(=8B^=L6a*s zXvS+3ilp+StolGR`6?{S{QAi=x4aU}Z+iJ;A|7*hHNrF$?pm;DX)_2rKYWUA5L7mf zI%mF>0p7*L(AGelq0t3lXMau1jOo=YKv5g0yo z@;;ct4r1f3tQkgY5fK8-dvtvSA9j7kvrOEKPTvfDtday3kEgeTWzV8N0wDvSWUcIM zSb!%zo)+!9HMG*%seu4z0oB*nVh42}Vm2le=+(Fzlj|-bl~c`CM$xbz z#Vz%LX7r74^SKWx8hW5&;R?RqWmJ1}EUI-6MGVS5dknQ63NOR=0Aq%l-)XXj021PJMaT93Ya2U{Hx{Ah-0XQQV zHN1J6Jn6W;oeAz5*^Xd^Jpizv{`(r8zRGp$7bXA$%FFET-iw|7eVbf+n`P>$L!B|y z&{;?0p zJV@?Ia$SAOb^iLh>Vd~Ki8de7l4OVnf0beT&?LE?hPp)PthetSC6AGcN5&3}_DbmQ z)jOeI%=Y?YWVwyZzK}{yFUT$wcR`NazVC{>RJ(m{ro7n6wp(;;)sIGyW|q!KSwG7< zXB9zTgf5s`Md<9Pb7$Rd(g*7d z+ZRXZW;qn=9vKtkg{gYbR|&eFMWY6KMGY9xe*kIb$wr!ZNv=V=5_DB5{)%i*eJ-Oe zb3Z}XgIZmZi_ntGauD6VB$uMmgLE$R`m*d@qE}RcS9EN`fM~GVofck{@3Wz;sQwk% zhYntnUFok&awNSPs4KU<%^=;cnxX(77#Gz&VY|Z+T>~q!9i%HlNf+fhv~Gs3$o7cQ cx+D$Vz95HENN=5ip7hmOZht>UciQd$0d|%yfB*mh delta 68137 zcmeFadz?+>|Ng)C9-Ga+;blPBRR9oW>!Cs6<5>3}zUI8RHb~L8607D=pqB zA?H*RLT5>+R4P)GRD_ZyDN^}8uXW#hn)-TwzMtRY@%!udXw@~>{kraZ-G|qGSod0c zukGxPD(~&6^3c_FmQQT6Yii57-@NqXl65zH+pyQm-ER4$*p`{K_U1lW>9?0p?+DMk zu2p1oF`uuZ&zCo4%ut_>Td^x)uOM6s?oiz4s|r60mxYJqh<$NGF_(BC0_NqBVH=rI{XeGy-bO_-gYGiKC;bYELy zYmuNCtc3OXqk>1I<&2p)+UJ`{t(4KHl&bi#8N(*4;O*F#V4tA?r9T0y0f#JSSVK`t>zT!Ktt+7_O=GbW8;T za{O`2Uywk4nsT`rl4D>MxRiMD5QdF1cplbyCZqqJ&xzWmBLB?iJe?A{f(*VPKqd1s z>-v0DIAJn_j=fmB33t@HM zpRmp^faQuZusV0j#0-Xx&v#|K&xaQyd8M!R`DlLLBe16b0U{FMs<6i7w-lg)ieYP- ze;a2Sc?MPiXPfwZcp>i;tcqnY;8l@hWTFClVasK;U^T3{jsKJQI=*JUy!Q#nm-n^s zYLu4=*U^dAPK4!w+LmLSdBLiYZJecQO-wSy9;7;@u#@Nmb$S0*#t%JUrE38zm(#6% zz6S7zuu9not9KrP>59Cuu-wrV#>IIJIZu7sH*C_ihjB|J?}`)?Q6B+E=9Pt2z^S%o z)q1#{X?Lmi#*agWjL986p3JGB{Fa@bHU!gmYX?)oO|bk|#q!wfjGU~@9ACJjDW^&& z!=>SpniS`WsK5z7AZP@9i7iL(fUCpN4sDJtk8JO3IwT)f$4(lbK6)q>Sct6(&9w1R zPe#XUv?8O%OdORle8l*Ys<2bPM5V~@G)=y_;#xB_Di$;L&EzVd_v&tH$f`en^4N4= z3G6cHXGmWWzORQlZ#t|RX2NpeS2n-5Vb$!hUZ#aV!Wx3MC6T;nQ)UyPCZ+Z^1=hq? zLAkIBs@=zM)HQcvE8~m%_P@J!0Qt$aUA^*>eR**NE=P#^E`$fviEdxR=VHt#9LnsC zA2vGY6t-Hr(-{|AD>5zzM{#uQZ~XNPT$b1+u&Un!M`}!Wgq7<8bn%0h``%*w@itsd z>0mW?_?WTkSlPbvrGnC&^0!O zWDVs^pRf36(|}R|Q^9w!wH(#*n~IMZYu3B7aBcK1a2>o8H4}T zXLHC%Egdo{XOdd9gchpcsGWw3bwu~4rSY0P@Hwo4hKxuXC0D$Kt&E4$x60R#t$cGP zW>d7!HzC(}@}oP9rb3F)IWupXRlTo!?K;y73dqZLZW z_68rU!PRHFlUe%e$UgFuLv~rVx%#f0WgIdahh9qjJcfwsHO4x)pXIjyh`$V5J@-55 zYr)^bvfqQN!%xE+0l6^Mi{uTs*ED=TtU;bVX4I(Mu|8k4XXf2!+QG&>e%PqA;hjmR z3?`-z9-B5~r0?Kdb8USCRz<5kXojR8R>A9FwfDOR%z4coG7a8|T~C+7)dW=2E@Yq{ z%${d5{2JCpd<}Xv_)5o&?Mq+{l|LRf{2HvWe*mrvJET|qovztF%D_j}GI-Jxrob_<%8A;a+4yCP@xKb@RxoW;+R*ez z7n=-bz(p6#J)EEnc3MuKz;wbBBd{++Z@bjzYY0atRa0!W(EpU_g721@2JVB^C9hk1 z^|B<>SC80;8L(PB9#)ISW{(-p9c9iCY|YN^R+ttwT9X zGT834;4xueI9${n6D zdVjw0*RYJyL*sKJV|{l&Z#;d6<+1Uj#tdP<0%v4pjQ8EK-oy_b!-kRJ9lc#_yus+v zySglUmzSH%-8@G#X1Ru916V_@8;2_kYpM_M5O(feiR^IA=sg7PsWSob;>-np6v3V)7`1 zjF-&`cOhuZ#=T;?U;?&We>(rCSAtp@kzdq$w;0!|C-Mi z2k(RH!_UK4z~^=tSKo)-5IY@Kh05+S%hQBi5tE=J5gP3^ZGsurrN6yuT>CMs6Q8j> z$MRsyC*L&{Ylp3Tc5=Qv5WQlZ+ihn5QCMAaTfoHM5_#W@>i@Ql`RDfKpSzOiZln|W zXc@ZkBU6z!uvYvlEJt@Q<*?P|=RP#)BbD}=z8(WtRLx+`XJ?GDi|m)YmPNNq-DrU_ zn)``yWeaSLo&NjHv`m53HMP)Hv7w(D{fyt(wLkO99hP?xK?&co5&ztWMfX{2iNB0= z4y=|d8FYtW-x`|%gOM&uMIy1SHk`PR)uOEH7$#-1JS2DWxh2F?IzNxfzcK55o|4R z&5xP*?2N4Jv|)d(D_@`!@2srcIMVurnHcOE#*a@Q>buLH8~o1HAu}i5d)%0oJ$!5$ zm&$XbFHPRpd~dietO@iA9D*~3j~_wk}K8!zJOamiL}Ajl!X$ai{McY{hT3{06KF3{7WU&ET%yp4S5Q^f5!mXJ?E~ zPtVC6pTXrNJ!f2Qdbaakm6DOIUzt^7&tcP{-<~#A%KF)~aVV@TwEkwX@@M9Z8Qp>^ zd`3F8ea#uu-3wuj>~6o9CcJC&*=OxR=S=*|a5>Tq8#BR76ycyPzUk$6KJkZTfAD%vG0k#Ut$Vto2PMhqTfvvgsnBVW|zrdQKx#;rD zNLZZ|w&|{hRpGj@Mo}zWjukTRJT2D=1+Y#yU_J3BTorpGtcr{X`n{Gc!&b{4fK}1S zmNQ@#kOXV$)P}3UFVYoC|MO2~SPxAfoI9K@TtU}IlyImW9?M8r6?;&~@6EvnvDKn% zSd)GzELWC*)q-D3`n>|@l2LW+?v|&Q_InqI4sb2>I9L@4l<|A#Mdvct`pDqHlYPFv zW&K{C4b8~*9-i;RRv+h#^6plBX=G3vyCMZBqv$3f`e^q&gI5(l0;@}UR`7cjY6r`+ zbt{?*G_!VXxDxsml_Gx6H8U#ty%WEO<*M12n3f%f)g^~4GZu2v$Lkq&d{)|6p0T5= z3vPu~fooxnkutV`=si~dswST;uo|`wmIt4R5K!OFsAe)qo0J|ughk{+dDGW@rkgSG zDlJouAGp+{%Z26g=%*RCVXLCOVQ;j<@>E$^gZr22#?GbR)g`P(Ue`HIE-N4D!zwQK zHiZ>=39L1_;BvpW_1Oa}{&`sOkHR(J$*{)7?XU`I59>TC;CUnZnT}J>%#4|^2I!Fr zrFM5+_~fCaldTsHEHQiiYnSf{dpd1-5EneU%% zyX2CMeH)cnH1FMdGmkEun$yfxqMs^7EDlW(RRtdw%wPZNIYxcKQGH_dryVeFBl zrDYdv$({RByK0N?SU7jpjZObZ>9cF|2zTM$8m}L`VZ)nGIj`3n6kGk-yKC*aVa~wy zwXf(MSfAHmQt06()nbc(`o*IAhE|@izFL!{K>4n3wyn}DyH~$@m%RG;;!pN`zwEiD zerI#DChLD}mK5X9a~db6_;))Qi7A2Ki#cl&!~WsUaip7_#z`suSDcKblwhe6K3{WZ zUEAbP3ZY&!y_hpDDbYXIY1}Hszr)FBl@j`unD)d3orDWX&T;gqPUF@oq1R)5z7FVq zC%;ul*68$}#Lvh2)gL4k^X#f0lIO z+Jr+LSrVHQ9Z>n9yRb~&3FQ42mdTq_{Q;+O+mujKMrUu*7gOo}8P4jqDZ#hU!d`2N zF{#4D7WZ1y!N~}xgl3>Amw=N%39nkKm_vPoB^VJMoONHdi6x*!WSf}etWHS@?L<+< zVw`c|#87eOg5pbfne@i$gcWoO4kg86wDzJ@%TJu+?NUOO7){bBGda=U)5&O`;$P{k zZl4l5K#XdLSE+w>r*VfA|41i;zfU-;`TMbRyhBQ;K6AYtsXQP1$2%DvQ~WPFt2?Fy z&Q)|ybPW4boW`9}{1cty9aBQjGXGQ?udrY-7RGCx__oRZUQXlG6#qIWgTIZP)%=~} z9Ov(IPUFrgp$jYzs)*ky=$IJl#_H4(E5^xBNeo4>Ok6_S#Lz2P>Xc$?d*DJ9C$md9 zbTg|;0%A#L96hxg>qaj#`Jj%|xNAx%!ZcSVoR&-`)+*t-^9q)Tro@?Ezp2pT?9d#n z&R!f=@BkJ)#7M2lOin_NQ8oO1oyOOu_%}Hj*QSJivN3cHb&2E3A>W6bd>WR6Wpbmx z13NBrGLyogQZ-Bx`u5sH|6u2M_mt36R*Urp;s}-xWm3W$wd=6jI44^rhfXVmPR~=+ zHJ6)iV)ArM49>&4$*bzOgw*s{ogJ#r(j*HAX zX2;siNyTJ%MXw>GG2xAz&{-^Xy3d=1ZR(gJLQX-u#LyIL6?YQ4CWba+DRa|(Kh<&8 z^bY%HImdgaFjyP+NeQ;C=ZzRzH=B^0<=2V+{m$_|DIt9jc(u_|6GMsC3VIVP-C2Eo zN@z8j+E?6b?WOg7zC^52p8GSf)Y0CA3~k3UBT19JL<661FmcQ|{E~sy3X47=ZYh>o z7V`1)J}foe45ca!3uh)NueBC+W|-Y+Ed~~|_Ia!(oX5<#J1G{UzgIxQBT2E1%rX-2 z%KicCdM}-7(yp;dNFHmGVli%tMg@Lo?8Nm8hw8=^_7}r_fU~+^O7Ky%&R*}gz0&6! zz$rm5@6}jcqgJrWRpjk;=V(Imh4I>RSeiiI91eAfFKm5>#LyjBgSscC^Q?DspCTY>TSn@5NCchvq>E&7S*bP{nu$Wd@E|#3+jn2?z z%<$2kCBNK*Wd@S0nRKgKX;L1-GWAznvt~ZuZH4E}!}`m+Ut^i`lrn`*&MZv18tazA zJXf|T((X_RmZ!f`j>9VSNoWsNVJC$eGW`CsreSH6nVvp`MOEdA-ie_KtS2~LUS}@0 zbs7)S#Vcb_N@xQy8pW)Kc^<@*RcwROYk>Y&dH9+>=7CdPYKQJ7`BOfdhdv{O9~e8Ddo`KNJ+aC-31gCCF*Hd{7krPU0cg6X5vi`j@^%NoiCDd~@C3IL z>aR*eo_>$XvdIPdHHmi3iZK~W6ZU8IhMM*xYwU&ti`16kra!r+EEOrEyQBj z8Y}oQRu3nhYev&PW)kcxjt{WZIAfK* zfqpj@Rlra?Ow=MQv#cnS->}SLp%HW=P3rA=;VD8xy(+}^Eo>>1VE~pI;Eh%PlTJo% zO5i|WXH9N6aQ#i*rs`g&@r0Dnhs+UG$GfP9%JwrGBlbDDiT+N`@d+tqCZVx5&GEp^j9jciV^hC_d{e8}NzqAednL-`BLEDcIGZ?pO!p_Ii zoH5q>g;oMB4AI!u+ByeE5bEWeY?mDTico(i>vWsgTTL&}SF8eeV>R)z!BN2%uzGuQ zrT74v=EQeS4)suo6lQq+2a6GAhu2Xooy~BeN>v6%ui5$S69e}QbkylLoXqLr!0HTV&Gc~SN8&W_eNIAZ zV&KY5CvHYKFfh}}oDmK!%8ZVK1ojXyBcmOxV7DGlOfs|*l z=yxoQ>szv;qeOW=fmK*S@Mo+Wy>-58j#)ZQew(mNembY>_~@XJw}xPO*Q?MvLRxOw zaZFDPb;vE82b{AOtCLp;t%|3xx|$lbXKy_rx=+%Kc??VLVwq+OshO|u#44>kxc_19vG{rdq{XE5qdoUcl@(wbW`vSx7 zaMmDvi_pVa_h53c(^PMk61ulA^cA75iVby|X3F(0O~J>ocvdhfIrs@7mOfHcxYNvL zt|Pq@gWa&$89bOAc5>+bfmc@nSiA(Fb@kh zW3@9Djz5dl#D|tW1>xX;yIDq@ zbqkUM&))51E(`|)vss;-tc7&YZ07{R3WS~#f~N_kDQ)n^InoqbLa477`wOA#JT3Je zzFy?4d##QCUT4i?;lSa0ofA;peNNn>aPao~yp0lmT1-d-o_q77NwFA77-s#x?0zTi z@o-??{Z8iN;o!Ns%udf2w>}V^a|v!@pz(uF+!Nto#)InF_$QJ>n+Ub^GGXf#Jc&i$ zptpO-xR%MzG?Hi7rR7 z9>p@#K-L$3vl={NrY=K@xJg*IQA5uP?0dwCTN(~sHQ%h|T=X(oZ?Jlk#M~F3!wO@W zdxZ{<8jBgmI*^BD29xI77mqq?mW2bCyUvMa;n2Nq^j=D<$x$rj$@QpxVzA``&oS&W zrxI$8j@Qwj!}7*l;Mf8ub9p#$^+IRO@^EPKLeo(^gJ96Uf~8WuyQV;i|2UZ|!hxax zan?X@{l_`6A{+`l7WHO9`y~HkPUgyR=ngdbh=pTXVqn{2&I!b-i_G#pUZhH~x$f@|jNes=y zl83$O1P(vxWIi1ZHChr~sI@^Fyu>+yxCl``=hDYK{{X9>6aRQ}aOhH>Z;V2LkCr+o z)`bICEpy_Y2?wh@#r4~Xe=bTyCqnKo379qEIG&S*H1k-%1JA8-GS`O#Kdy1sK#kTqC)S69 zBi3q4pL{+!_%fjm3I+aL>#W%j4mEi?>S$eZ@~}ElC{u?;|4l3gFst$Jgu+gI*W^I! zbhP zf>0|@tNKDTb^)QAoUHcAfgfIQGG7e`8*TFWQoKYT5xUU}HQX#0DcdYUM%zm0T2Cvr zMT48zz*AeCxYxtMVlR4&_3O#O2qE_7gmw{Xr%)jDk`uR;4eCqAF${lJlCQCv( zuSVOw_H`c7I9VN&1NF8#C$_PWZjFxJg2xhrUt)1hejqv6@(u6WxhgrZ@(t(2n@odk zPTclzVA3`xb9*>c>`hY=Gm9>0kJXHFW1WH(Jg>k~A2W)uUcpMjA|*S@Yqm!(S*qb= zEH*od$)T4Bbuu+)XMMq1-n7}&GRiF-R7yyk5s zjDMTOiV)Ka$DQ#)%BJr-Ha76mJ5J_1;Xs{toi)(xcRlO;yH4D@;b5!Xnp7&nC3GD{ zTX$5rXsLQ7pW_#-Wz>ppH1 zOW>~zPW;VE`na(6WOo-<*TSOS#p;6P?e7Ei_Bto_ghSK!GS?8fdCyD?yuR1T{4gB) z15uYs)0UKdMXR_NYj9zl|C8vbQT0=?YaKM zVqZAqJ6J>v-H7#(Ljg%fTi}CeOJrR3tP*KnUAF{U9kS@)_GXA z1oAxeR~#N}d??xyHS!Uxzp8uekQ4V=IMDD*Clk8;OJ~hz;ozb#si3z#I`*X#cOV>S zaoEW`5DtwyY;Ib-2MPh-*UkyV9^aTp$7a~Siq+S1Mge72I%0Z@>j?{99+v9pec}~( z?}!ukc{r4O)GU171|e|&Q75hyySt;#3F4}LYc8c+R>*$r zvATL6X@rlNb9l(ZIa9Ejn<8<`GgwWq`23G6`VUxLu}sBV9xq(bSo%g=i#RUgE3le- z4*@}06=os-221DhVH&spNk2pdGNBIVp>Qch{d@pdyw3aze zi`rqeA&y-!i}}=3PUg{Y=m?@5%!5-N0LTAmoMkr71F`H06tvJS}qz<}(b*={A>ypt(3*yp@GEx3u$^~xaF=6A0JRD6O7@%;8V zLOey_{Ii5?HMt^m_#>KjDj^=?(8w1FnFUK7S^Q7qB<28fqdOKGEmAE}$g4*|c2Y46 zJ`thtju)t&vyMjtiwUt6&rJ6J>a6}bCDhI5x8A}B!3VLD^n^IHgV0|Us=znLS~}}G z^4SWZ8%;x(v0cPcD!Mu;F<3I-*Yjmk-9kt`!ZN``UWC=gJ0~GCDHg+IAg5my3oXs#HCTVGN|MfdcZ^E83d`h~&sFy463&V9 z;ZTQIzcTQZ*A*jH&*9IFa zGtr;p9REXKbZGo%N~lDsXa!aI>#%Mioww%-eT~%xiw!OnT+SEM1{PXn`F`6Cg;pAt zW|~R40?Rl*fjp05wI(j)&5hc8-K_Eg@@?AMIWfJhj0xUCFG=cv7D~<`| z@~yb8UJslmq_JuS$u*S=E!K;XSj`LL7XQuq2usak^%$8LY*2;%_41oa$jlHe3~yoa z5gngRT*BAt%(AY_&tNQDDo;kb8d%P4GO|NOXg-<>Ce#AC6 zqqILIaG|EVrnEmC9LJaVhPvxY`;&uv2@W>F#M*w}AQN;6W}2YCPGQ<~f;R0Af&)x~ zdUctkCODm7e-r$apvf%Ms-EcxpIcDM&mI=DAJyfnG4$7;SiPN-seD(;ZCu`;9N|%q z9`~>adY1_P8kWtJ(N{5jw}Jp*dU;1tE{2k3^^3928vm<4nc zWmRZ2@VkGM_gAf>=&}04aWVG0H7oe5`U7s?3jSIVojehUCt02h>$n&P(eLzP4ePuJ zP-~_G*)xC+vGluu^jSbh5svs`5$1ZbVI_P3h#$1NSQ*U&CBOopqbSQej{%*x$nxW` zj*D?|^krVvy?`lTxl(h8mEkI&3|9jkV%ckCa1>=#@M%x|J1hMEnXnC19b~_p*JBU}b!j)#G8gtO=|`tY89vRN-cDdAOrQ%SzuFTlrjTxtC?V zCZqVius8p2BA`R8U_Wb%73|NS;_z*-PE3Q9aXKuIWWhl=8|HssjF$Pg z-o3CqKF?48OPG(K4E_V_5UZfat-jRqN?7UjB9M-vtb+2<74^L3^){VY`MqFmvC_Zn zm;b%MUo4ltY7_oXtO{?l>BI`YY3+-#qPE-kLYDtk;0_xhR&b}a#R~4SwzxF*URdXS zV)de|iXB7`!AD>vIcn4WlOqz!k>HF?_=`<=F_z1Ix9R?{>BMEwOHvzEsI>n4gVpz! zSiLACxreIyD@T-Z4J_qZ(bu%Dz7DJ;^=vw^;u~1|VqB8=Cd4cM1XyE8Z>#Bm zBi`U^ZH0@mT$)0>Dw+x_qt2GQSndj|BHdyB_w}@VoeYkmEUAyx`vmMD{7WzeTu%ZO zbc5v^?FmI$(oHtLpN$u*BDYxmR;!DZ-vDbDa>Paqgyotvn?S6V53}~gSQ!qt@#4zZ zQ?32K<;edgq4K=bW_&SLRGy75%JRfabXD{&8!whU%h(YwAmMHsG212-%Om$$eh}6e zm~ZWcunJfNSAw6l`g*Is0Bi8QZuK`|m9yQ(?}THu3HgA4mc&nN#AlX2hgIO$HvR;x z3jF}<5UTSOwLv z=hcK&@p`aMZNMMZsgdP4SQWko_Qt;gIxfaq$&!dyg<8QXNI%)23{$M$4pxDkVP)Li z>OEkk?+q*c^>A5ukhKTLNOm8u;jh&P$v2!oDrba^&y>g^R=#7bU6dtd+xUsF>?!>5 zyJyJOyT;xr6FH(d%d+#VKHc&R%QG$C1#43<-`bDDI>b8Ph1INu*8Y!;7pvJ%#Ngg) z1YWQaV)^N1Ym1f9E7lgve%0C+V-@&1@k+AIrW0$Se+O3lZdeuA6GQjParkun=)au{DI{!O~|Am$B_cs3fsLLftJH;O*_|Ya1E5n~*)%+K$ zUyK!h)~5T-^6xgiSn+>aJIax0;9{&3ywWYJVt&=evVuYWD9>1{|4*#^O4@XmBc7nX z(XUhK5UZd{uyzx*tp5K6s{(aw{&nGUn%)Vvfd7fr!sa&J#aPQ@vW*ujeHd1O?O;W9 zvU(R89Aa;I>uLqDTHej_wN@8P?+#14&gxKU-4yDi@fE5o^#AA&We7Qi~h3NGT0(k+Hn&XQuZUm31a>_1ou*IHey;Iq~) z%BtXV=r!Tpu+IAcRs;6I{O|jWKT3B1R{R%M|0<$bj;~;ya12($)8jS}v{9IK>bqtzq3UUJEPgI?Ff0YDqs>1>S7!0oJ|^mIsGg zdziIH!MdhSfpv(L&oqze|2zW9a0bl(zS&*`cY;>GUm}NCEtzZMAA)u9Uuf+`unw^r z@HDJJxB=Ee_ByP)k=?M$dmk>P`S+O>4#K+K`3}}0R`5suREI+}PbZdw<-&@VtHa8; z0nGottN5dBQVOi|JHe`WDqITg4eJ5nFgQ|?z$5~y;a#w5d_SxV7g~KetPEDbI>d6} zYFGt4W8?MHvpU2o=tZ~z{H4{4vKsPLajm~5;AMEkCKRi{qp%Vlv--tY>5dbx3Vm-}vVV#RlWuh#lAmVgFPF02zKSe^*$5KEtAZLumc71nvv zZTt+&GcDf*t08w=dp4{?EDz50bo&1RD?9=#!-cSFxXAKi%S&Muyu#Y6VHL2}>d(SD z#7ei`@+PZ`rN0ELK`)DI6L`fY5G&$USQ)<#$837Mk^k2~q$9SV_)b8FSavG-_kq72 z{L33!QRKbp)}8_D5KF%cDBUceqX_@|z~8v!IY?9F-v|ExKJfqdf&ae`{QrI6|L+6; ze;@c4{UAUaiHkkx*Y#7n;`8+9AFO@lzYqNXec=D^1AlL7cn|)y)BN{=|Gy9X|9#;9 z?*spTANc?K!2jO|{{KGkzu1F*?HHu%;oZLv{QrI6|Nqwq{<}N+2i@B4^DXDA#`V}V zG=VOsFu=07Hl_%^B3)@fCKTsOR+ z{<{n3@4jVa$~`+;x><|;)q0+f#MS%wfoI>jefV7suJ|lHp-1N2O)p)w_SCT85rVe|G6pOkK9nR@~X9>#26qJzPy|g1r(o&RZ9Z^d8 z-RIk(9FtO6XO;20Z|JNA%TRJV1iJgnxswhxlnz`e1XCw<-b)E@^ETCcmIZ~U&d9qU(IQ*6eqM`m4q|67x9+ji!}?;HAF{_s!E z=6eq{n|a4A3u?@)zu|{ZE_Da4@>g@0ldr#~Td<6Rs;#D=zE2_4a+f@Xuv0>CIYJ$` z&vJi1e_eOAsGjRz0bSwVEUNG3iyFA0l~6-BP1MNUB5LebSVcxj>&Pf~6&YRWZk2FM zLjBbU@$R_Q2n(J;*el^0x6T^QY~oH9CAfP;P2I+8p=R!MQFHfGQ42TWX{e=pk0{YS z47st-lTqqAGHT_{TZgb&!Wjw4Zu@5tMyy9z{tQA}w?IO*4G4XoMM!a%Jd3bXLhw0+ z_HLi&5GHLz*eIc+>(57M^a4V9K0>OSFJZrg%FiQoanqhhn6n9CyM%6Th4lzYn-Ox? zBXoDSN;oE={sx4e?zjyI3$`Ham2jO~XCp$_7ZGM{MCjx0k#JT*ix&`XaHqe3u<9j* zBNF<$37Zi5zl<<{6GA`tu!PuG5K=cI-0aTVjIde4840(#?YAI|cokv!7KDLrfrM(W zA@qF_;dXb)iwHX<1Ybf(bNjr6FzI!KjS_~q{+AINZAD0b86n-xm#|;L_E!*wyA@tV znDYig?yCqH?p6s&+Ysu%hA`3{_Zq@6340}ExpiJgSnwvotk)67xO*gY-Hy;=E5bN; z`c{Oq5{^j7aTDG^SoIdd{5KGC-NO?4??6c1hA`2cw+$h7C&C#Clil`jB5anh{7r;A z+yV(Bb|LiLjxfz#vK^t?+X%t85F&1$w-9zp*eGGT>)(Me=^cdh9SAesdYI_DY!R)_DhE!TSia z-a&ZK-6Nsv2M8_RMVRMKe;47bgd-9hH(@uzsyztvcO%Sq4@>C(AwueV2(CNtJ%reg z5Y9+g=(c|!VY7tg?;||s7DyQJF+$%D5FU4ze1K4GFG6q+!eY129)z6|HcD9H`aeXN zv=1TuLxg2+zJx}fAXNScVY!?35yE~6+a;`YD}0PFXFo#j#|W$4trC(xMX0|QVXZrE zFTybidnK%M>+C~V@EO9aeF)FGdn9x{fY9O-gnW1UCkSUH9FefzP1ujH>L9}W{RkV~ z!xH*`j*$8(!X|g#rwFlMAe@n~#clr?!e$A}KSOxQEs!wc5JKMr2(P$H4j@$f(qGms ze$aod|24PIL4=)Ol49dQQfzhopCe28X@-(!Y+5Kgrsi}>VJvwjyvv4gkuu+O4#kzIgGI22*Rwx2=BXlBy>HB(BdnE zJ?`|c5Y9?CBH<%9;cJ9d-y+Qa8ey+{SVI3}2&vy7eB#dg1|jx1!Wjvly6ul3Y?iS6 z2*LrkK*ER<2z`$teC{qe%1Zo&drox7?ei`4rMp^m*!3TSzH)CCeeLFpzHvjxp(Ab@ zK0hJsl&}#Yzzc$b)4UBj=~tBW z(jQ=LyaF6``EFM?%-%5n7x@sNhaNi*Q!L5eb#tgmVb1{y><24xzGp zSVI3l5mJ9csOrx94I%ad!WjwG-S+1ZHcME39^o>#0Ac=!08aTGyQaJ3cM??dBLx3I zsO9$g17W9xjS}j({yz~W1rXBzM5yQHOK22>Q27EveK+j_!hQ+cB{ZC0A;7pO7AP}6 zmu*+$`CBoQf<)K%V_)fx^CKLSuvbF7TPJ|9pg6*;0Kzry9tmAbAhd`iAC5cVWWihu0Mn@sSHAT2%)2!FQHLcgvuomQr)zY2>T^$ zm(aznPzqsAIfUF&2;JPR5|YXz)Gv+D-5pmN;h2QI5_-CI${;MLfH12J!gcN*30*59 zv?z)~2$QNIq+fzC#Lbt` zs5(OB$_VLhT4jX&61Gbi?pCORFy~T)+$sne?p6s&mm$=ziZIe0R~6xyguN27+&a|| z7SuqPRSjW`yGKITng}hbBaCyWS4TK2;fRDBH{nu*RhJ{ozZ4l16S#DZwg#8k>OPK9esDm)4K0I!q^$}JzMwnk8 zVZPg{0Yd*cgvT2oxbATYu~#CTREmXe`-TXcB`j}<@R(a5VZ>DkeH$S>?k;JBP%R!I z*cf54+ov(YP6-<&EOGsD2$QZxNRLBU=H^RibPYn~D-o8vX;&ibm#|&JO1HvQ2y>bs zj)v?QU92 zg#8k>OW5I7;8$ARImrmQi3q#gtrC*jAk^ z+qXs7EMa+DgadAYgb^JO`i2occb9|_s&zyNa@(%WMhe1C31!+L9CmMRhcKxV!d`CU z*>cqBgwQAzVOA%EBkmpv`z5qUMfld8o{BK1Gr|!G$K8a^2uWQK=66Q;&OI#Qn1s|W z2q)cnT@V&@MK~kjl-s^5Lf38x%ex{JxCIixGcp6XAlpRl-gQ z_4Vw-ALC~C;+e&y>rmpaBT0-q`8tv`>W%QZgrM8FH^P1ib9*C{a6d)ZG^bDC%i2MG zgSezSePTdABVNp1lpV- zs3hM8=gqymOEyiL7h z7(M!L2w!#|-&t2PZt$9Ma9$ubIP-qKaj&%70`Aj~ApEhA`brq-om?gQuhR}0m2tKH zxm|rxV%cIh{Al2_GM6kfZMz&UtBg;388>-65L>y1pfXHp>G|0;j*)GZVyPo) ztFg5uaFn%aAYVOC!JAeqhTXtw<*lZ#CpWZO1*_@f^DC`Z5l!bYwj%lmL%gGkO{j17 z^NnlosEVeF=o{YrWQ=!Ix9L=2eoV(ZF16|OZT^;4t6|gWje+Pl{%hKFdTZc0)kt5% ztz|{Meer@P@^x~1vfgv(u5=uAt)`bIdU%R?HB;Wx>xDh7c7;u+ucPzZDBe-uYI@({ zW~=FSPVdF4OAuDtf*aa|dIwnVE$Yzwo+?CNp1#{^jjdJ{?P06weNd&-tBNsJyV7cU zF{7B(uCm&tXpx{5JhH15;!_q?Fz!BtkwyQy!9{G z`W&Dx>}<6Lgez-wa&-01rT;Zj6ArGa5!*w>D2D#pLRX6ArS)CgXdg#SU^}`KT)W}!s)eU`NWq1wHyTj^+n{2u! zgr6W6xxBwkmq7R_tKDq1rf4gyc8k@Tp{=%B!P4zvk1y&ghSAKqp)O|Ktp zH{EWvM6~GdL<~ZcW)H`R5ctk#ZjS=+Uv&AAa@d&K1!I@C`p zqytz%SbaR!Y8?ry|8$Ill}{%Sq%?UZ7fs_e6%TEdysK&_l^H7!>4ZR=)OO^a2W)n-~virGe#QO9gp4ebMJTkRg3?s~KeM9M?=TI~kH`r^Kh`>YnZ z5hLG|SS+mA7yEgjmd~}?O@uc99S@+XU@fs5C2%}s)Ac8uVp}}VYFc)+YUT%pE?4U1I$gB%(w$z!n+qNQ4}yolJn%4Z^zz&z1nvg2!5!dE zpkFM>0GVJU$O73Q2Xq6?fLFU>eV`xJ(RZ`;(=%`T-5-X>)Q#wecb*38z%xMCKK)A2&EOU= z0K7}{cY`mO`G>%_RP{JG0rW~;MW8p~s)D|x*ZX?Kf!>nS+tKMj@Ai!&53NgjVX-t^ zrUYB8@&vY^F9$2YN}%`pekaidz^dfS1Nt(@1 zyb0a{?*MHH^wRev@E`i%F`zBM<1s86;|XXFpv`Dypv|j(3`Jk0)|aiP0sZcbev3xG zQ==cV=?(N_H%)+kaY;WHb&yu;CxwoK@4)x&lFXQTH-Aa+Fc=JmfDcIaA@~S<3{Hce z!6!g(Lg@FAbWz>_?gRIOx!?itAb1F*gJEvXkug>Ke$Q#Az~|r)_!1ljUxDvv$t$py zH@#%9_g%jQtI<{g-6RIUOv2NFzV>ngeCN&^8FPDey_4A-v;Zx^!;Iv%V3k{DRLo_O zKgczR`4(sH06W1_umJoAOaKo6rm^oQ{B#=VH(c}r^b%^b6g&l1fH<@YAPD}zJ_n9~ zqu^<<4m<<&hW=DAO|SOfNnkJ-0!jhx4$6TFU@?_j0+xbhK%0b>U^Q3+)`Dliv*0<9 z57vVXU?Z3WdV@Zo2G9=+^#}T8qh6r7ez~X$0YA`=K|dmOHPB9>EZ~;IFGk30R3{xWH1HX0bWJZ44T+fM;F1{4Ed(|t$4tKc=D-!Rb@N;{@6 zz?3wRN{1hkX75oq@`0MrDRgIb`re&wYO0sY8SNl=yUst@$bXfJ~n zpe0BGtw39#-?-3g3OJ!DMhNUc4X71rLF#Xw$%*AQO8e(3UKp@_p;U z2B0lfEg~kt->VSt12_eK1p9%uSlz)b;8xHFTn}yl37{FM4T9ix8ukYG5u64m!C~+U z(6&AqMB4DDF=z>HqIG%!{x&Kx2&94SROV%HI~nSyX3l`GKpfCs?m<|)UTtW--838k zr9oMs4V!LIbwfG=3jM^CL zUQhQ7JwQ9q9_S`iw`^5_ZqpWnC&3c16f6U}Ra*g8f>mI3pq#k{(=FE!u+i-^E~ZlC z3Cdgymec5HST{N)L3yx(GCG5<7vZAX?_~KQcn7=)UINd7M}h8N^h15Gfvw;TaEvnf zrGkj}i=5SP%+m;hel_GHpx;x`{l_)H4=zxFzMvn_z2>bzzhzejlm+F0ZU-uYN}v=d zMnU?ezg6IQ^3EckfuJ?`iSvJmVbhsKARP4cUFI)ko2KWWp=eI+|4B~p`eKO>3it%<2lQfHMxBbC>Ak74Uq%3L64>6gnM0S|+D zK>hU~cmT`=_kcOzZlI0iU0^zh0Btazpv*_Wm_SD(D0{0$nc}Y}%a@v#mr#3q}o~Z;e$4T12XVNBP)hBxN z#MV!S>b!H{6VTlqH!Y^BzlZxdxwjfjtkg94dT=x74*G+Bpf6AkH-aAE2GASyGPzvm zRcf+&5U0|mBMWrT0@w(Y z=?0(#g$W5OUUAa@S&)~R)s;>yejDrnYS>F4gT~1lFN0UWTOjf}e_jLPH^DaW2G|O= zgPLF$*a_s?_kl8h54;0*gLlDjGFJh62+NCt3eegrw;uqXfrH>Ha2R~4E5a894gsy6 z>I%7DC)J|=E(g_YU!Flb4vv9ufd=VmxE%Ni6o9U1KfBKvpse+dL_v5JA>AQpsxPSy@d9Cfe4s$6-X9g`}dipo2Ri&k1(nRso6A9F3Q*aFp9(w^9G=_BIJ5f|fvu z)PJoAYr&DbG~bi4r72z*OgLKbAi}o;-7e_1VE|xt^X?LFhHnCW!42Sg&wh#+KN3W1rUdeg zo`)#jo=_P7&z2O8mv{c#Ie*vb|Gx|Wr=4aqQ>~SD78)NeL@t&C2pz=0${fPu8fM{J5r7XsP@gN6ed#Bcs6fGsYNI0rxc*$B!B1#p~ zCUy$p$reRVkG4Kq+BEOfRz>TsBzYiOF*(U|4jesAzEQTuKV_mx6>U6JQ@O~+Gl5(@ z8Yp@O7-gFE&w`>!3k&g*xpG|fXuXxC;#GlJAm^_%jb~$DEYE0qRk+AGg`L`GFvCM9 ztDef>exMN$9Tw4cC?k31KAq@D#WzUt9VH1yass{Z99mf27+WT0Neti z-59OEij%wK51pzkypiE$5%gT(1zQ#MiV9bSRJp&6X>8>Z9nxy-{l;sB9;m5dQ#3PW z;MfyQYf>-f+5cOa>TH#(+W%E~83sE^dLzmJ77o_}niX0Fvy zfeS#k|Gn^)cr*?)wtX27caLG`>UNvUz0W74 zQx`u8Yg_j&ybtK2woMw?3qA(bz*cZMaWBFjfe*n-um`*i`VqGa?gG~YI|=UqTAAMh z+A?m3H-mV#6uzekJO$Q*!EWi!yXv^0%%kA zDXb))gM;7z_{@ew#D7Wn5QrsQ7L)>qv7>Qc6Rt>}6~Hm8mnU2f=)q=b((7FEhVwUaAc&|BJ7Yl^!pgV=C=T>^M<0k52j7xu5H1GJ6V@lEC*jjTPf&}IUKR2a{uBNk z{07c}v*1_o3pk_B`I*2^-~{*vL~DGMuqtr`Rs~e(aiCTfSnWIbM{o-K091+ZfzsE-hLS<)!rMt{7NjMP5`I>0TFGor>XqGL~!g)LX8TtCUEr zObSmV{=bDa*c7M2)Y@o48Y>zbic`2~8hNC$KE%)?y~;#ZhPA)e#3`DvI&sm8L<^8s zG>r;WhX2&1sWBQC`sCzEco}8XBU~3;c?o~&fM`Sm!ijFY6H~RaCcV-<0qbr@9~->x z-t5GTDV($#(+T$MXw{lw>$5w3u&eQ}N&U~N>PrMw$Kb(-sR=nA0B^-)IAnXe&Ow7{q*qM1hvR11}7v_k4I<<|vG9#JLa zRedB@%}t%pV@NHo8W+uxw2JD3Q>~N@~k!5>s*Sy==XhzB)8jfcA&%yXl+Z(iQ%|~Mr{rxxfeKaN%s7ibC z%Ab37YMGIM9_C0xya+)KF+E{Lh#;(Ak&ym`eIHK>sv$G`VUf@W7Y;c0-4S#{Nn zdvEypvIfL7`Tu3aD5fDAMh{#sG>@gAGB&iURhE zV2=f{gkvQrD)t`HXcT)av5URO-mo{+?|0|kVG&u&`(FOYxO2`u_w;*i8_-lg0|<7Y zeWCZ*z4589M+@3OSV6^RYwb1r$PEtz)2Ti1^7Rj%7Es~zRU_UD4Ta9u+WA^QP-r4{ z*oX^9yIJpFZp3f`gz+CTxY5z4|K6)^g!s}b5ZC_*1Sm50^!QW%MAa*QNkIUgm?qOT z#>4=6hsVfiz{6rl?2yFh1{Ud3qNEv(H&}>_WrYOmqHW>whAktf1W6iZR1C1OY{X@Z zA4uLcr&7MocO(rPzZrz(HrA`{nT!EjYW!Bx*oH-z6Ck4-H!XbV_oll91l}F1hy7Wj zRU@zYubI?ln2{WFPzOL7C5NAU?lEAnr18KTEc?c?jVz|)JIx;jwC!79_tdvM^pyTePwKn=8I^3Ni>;&DA>N?n=O1ZMSAy1aaTwzstm(F4BVO%+uZ1 z-ACCxwgA!jF^*}&@5L06APxU7BC<ducn%#a zZwDO`o%o^xqji#O?{``t=$DPWvikNPW�hUIB!uENR@<`b*yzSpo<&;O>RmLq{RM zYwe^LI%>ZdI~`h@_B*;PMl0~pJ7Evk673A$R#nOzbD58JzV2R3u1a);;nkxx$y$4| zO4d5y_D{uR2)CNTlC=RG5`arGV9nMMJZvbyy~XWxO5fwX*0%>OPflwuc`ne}OXmub z{{pSQrVP~$l#6RU%)F_@5ZNBr1OHh7x`Rlw5OfDqvxPu@TbOz-1oBu~rI+pXSuhXN zP0eTN>keA_b_emwJcZPw`@q-FL|ic?yH;wF^}3z)Qw2e>(0Fo6K>{Gi$wb{zVea|r zt?Zf#_Pm+$sAY=Q3zvw-r+|-O+M1#b@EtGkCv};*Zrk|-S0oMe;tpe&*<&nc@i#vI zf06=H)~70zJl(5ev4mjua5Ym9a($(@p86Q5@KkcI+C=Bj8^z(es%6CFoQ@ho=Xw8M|mm zaZAB#3!00E?_~p*h>9V5u!&g2f-SaJK{{0|Nm!w*jPz#PpMC_Cc4ntuEC_Zvez9 z9C0W;WL|pF%O&KY2fT87l{f_gLFEqpY3k6tMtjKHLS0Q{DCG#Equ1 zhtj1tTki1Mj_#iyX~w~ z>9Gg3Uk{PgemE1-YY+0+Y3x=gURY4@vYXsCz~F-3QQGcH%?TnWY11#6~z~4}>tw6z0`>mM+)mhs)3tiv+~fCw8aw%~}VEcc5zL zQ~wZ-!8`jDMQtYl`agij zOt`k1%MOQQXIZT$Oml)p0>SVM2xWn=aPRBVbNbe+WJC~7Dv}IWi%G408`dX2%H05; zaZ;T9b6>`-;yfZq^$i{zpL((IGZ8qS!c;BlAJ^n_f)5iu?v3BtpI0A>MT$`29Z*@B zTHG(q^L1U->~2=NQ6qJ!E)ekPgLdp;G?k8-O39(0O`s@4hY1)+ zSInJ0yKpwwfeXI8) zjekj#&$C{Jzz^sh&9RsO31?<8AWlM8+Y26As)#D>hJA7*h zbxE4|d1vXwq8SA)aS**%9G6toN9j$b3L_KK-sYynRF%v?S`WFQ!hLW zSAmXNC^q5j!FE$i;8Ovt7*h=Qu0AF2*4p_MYQPBw4x2Dem$HKu#{$C^5XO6n0bx^i zM!x#X2zk_i9-*zT>9!YLd8yLk=F0{1&+K3|o(Q4QRDBN|W_BY!`Ey&=`R2<3DJe#T zbrcB%+`0dCk5UQz#UAGPz?9b8;L?;2e}$GGJ627e$CyRgf)UUR19P3dS}(&vV6aK$ zlwZ;bmXYrDrWC&yCg55d&QJhVVHoc3Lik41JLJq z(&M3D2feczwAq%VjSi<A)W-yIr)k?uJA)pfQGp~RWuAfIh2?zq}GTQ3%2q=N^xjsy3P}Q=YTJfCH;>MC* zGdrzm4XI!cZ_I9#EaQy@2P7Le#ZUV+ zIu<0`8CIhO z^O1%_>do1@vtePSg(pkO0+X*M*h}@>P(nM|Mu%+e--eQcWjp%NTy`+jZ>ucH$J+fq zZ1$9;ExkmSs84bc5Iy>}LIV~UnQ0ReW*4~0=4EVk19Ue5!ou;iA^qad8}}^Yys)Wx z-lV8!3)w+B*p@t+%QjBXlxbc>=S=L${UNq#Owkqj2Z46I_B86K)?b>?o{k-bI|p~* z=Ih&Z%cBZsE3RPXQw9*T0e~>x+bq4mzrljTgCtE4ykQFin?uO)7?Sai9eG>JljWUy zyZmAW=|uiBgi-`Bq>iDK%rI|-@~qQrkn8Wh$JcxiD#Z%hi%@#RFt&tot62|@(YqvH z#j-+-V1(1KlMZ&G?Z=Ve&v&9I_RQ==6OW@0_5Fm-be8>|)0vvz(ArV#UDW=Yx=@`H z5VvMH#h-wb3oYayGql8kG$qOung4O-)!k4DY#mOw7avTtij;r#mv1Nkm7)x z8D+b!;K>TI5wbI!LRi~#z+fZWxp%MjnLoTS)`;;05SIJbj2wB#s^H^UMu>S=T8XxX z(p~vH|W?BAhPg;9Q>nh#oNf%FHt(Gr5y5_mGheU)OkzSnC zz`I8h;%BV8Lz(|*4N_zTg`CzpOVxT)>}i-Qy*F*dQ=fYUmT}0JKb%ODfzc&jABwsR zyZU5c{;zOrlaG07R$U4`k34NbHP2#EVP1x|kxOJBuI}7KEj21cw2}_@A?GvN2Ijfm zlk;V5h3uCTA}PcjDMoEHBa$-Dpg>w2$pb%Z%JXNSb^Wo-Z^Z zSw>Mh`^{yrGq^?ZDn0d&&UJPdIf8`CLWr@`IEsp#17`OqDt}HJ@*Vnl9Yrx0zNR0c z7lUbis4NRsB~I2(%7~`x=l>TBskZslaH_%b?%s=HUF8bjp$wJ##C|mVn)Z8}=gC^0 zFNK9eYN=jn+K=D$=iahsuE*ZjqY9KkyrL#!@oF`I3SB{fl^Z~HuE6${2T! z7YZ%qKiRZ~-6nqmNAzDh_!)Zy*-zvTeKQ^4o-!kGGTt{&I7OmgtLeZKJS)GGQ z&&R#8S>+Lwa0@wj11-CSl^d17)EIhnPm3KOkFPd0EtW4X}zT2>f%2mmclm)dIJh10k46O$FWrfE~YJAby zDi>yU%eqvO2VPx!jN=wn*t``^XFriX6hMoz6DhVJp57Cwc_vymnn*n}wOyt56X`@Iijm%+ z;EX=cP9*0is9lvEH*3BeIBgR3c>>(-lPTkgHrDU&$$YTtaOQmEyat*fFtHc%HR{vj z0+KZ$b^6&O(KZSMX9ko>$>gVy&Gek${A5Z8hVL!VV8J(cw#)W_8L7{W^NFVd5_fW+ zA)nTLC#YlY%cSJt=!6{q0XS^_Fv>P?d(|uHcYwp@3&63MLPxS7x&0Js{|uazpTZ|l zso@W&H8}USji831t@0E~0ES;$DPoZNkfw?T6uQDI%HzlQaP(e%rm5pORoTZIV z1cG!wo+4fWQ8SgZQ@TQM!0GT`CL0lLr&2P*SOpAoblSgAh2aTnwsey;OmC3L%sYWR zUI3%-G+y3p4z7B7<~E$x%H7$GX%quQKhs>9?nISn$8=tBPwh3YW7)U6QRPD-B|5l7 zeiwj%1R6Ux&Em{d&!-3u72!P~OtB#~{RTfVv_j@pA=Wb}kZEJr6mn#;y3OEgyu&9Y zO=*$kgcTSSQ)T0;jQW{o)HENWf7N`__ZmrUXfWNmAo+ee6?m=nH;nv^XXE$|y?e+t zZq$M+c~wR&<7@VGGDW?{XfzQR*3eq}OFbgSd3*l>43TVtDCM=*+wYMeaVoj?y}H-3 z*g+H6gGE&3L{7Zqg-RjiLQ38SgiZYcNl&CgZ&2o(NTfP%uvQR26#oW_Z%@3la}&yb zsMT&lLA1cB3YH(Dh;}i|-m}T_Elh=+q#2I4QuA<1e5dvD zi%jDAFKk!Iy^Uwtzd%oH6%IWO280DsubML_M4!C4UxC247=%86hTrEa9s_2*?Rk)o+DH&N^B&W`aLiY6>TF-qdUd zp6_HKXO~;ZwX^Y!`3P(At=1xx1?dH_VM>#{{ia{PeOuzw0w`v3!uN})aYzn3hAOP?TdG&dhbhZ$&`jY$`d*7Jy>}@8xmUsvL;>k_`3Eo6Yv6dvQTtQtV*-QWV{uq2#i4MN#Bnb`-3rlcE z39Phhq5Z+#*5Hv1var*%Nr|i~wIF+~?2S*P2WVw`!+Iy~@yCOgAN%q7?>CiH%I3C;LmoHc)&%*$YR> zcIK1qrT=WCi)fhlkuvNA;8vk>-b+#|$=vm!`dfX9y3x>LlW_Gh*6qp;U8Ofxn5HO& zZ6fyqva2+B6SXZMJ4@ZtXgDfS!`L)F{kcD^eaedkXR*Ys)~ZQqw3cD~0Sp}6ify5N zZ?kFBWz?4{hN-?pOOsNGzD>eS(f!`{Sn7CS4hdRs;j5TMf2%m4qr+e;OP0%#K|IZR zY$0b0+0Jh~Fc4|6(qENcbZRj6v=L*mm>@(=4fM-w^lGLN(s~Q^L0d!cpL|`rboBD= z@yBK=Ri8rK3^RyKhS3dc(^jC~Zf$|!@E&6#EHzPR!%~%?A$=WFU^F*PtK(LlxL*%= zaC(c+EQF;xlNksI%b+KRS7~r>nrC15EgOry@P&x2G`SGMVb)e!QV9MFjU^YuHc_F% z$PzuaQTf8Mzrl2g?D`ia6o&eGY~w1}>V0#`_-$9Jiw=-?atQkdAprfv$i>Bho4RkOYGqNP8-qhOrLdj z-HdJP@1QKSHG~U{LwCEqA9K9~mTW*>Sw@?*gFK3Y`g&lvfcIq|s^5xVh^uc5Lm31z z04W1V#X|G<&6@FJuo3cZ2gR_qWzuoM1sEPd&D$-w=ANKnC`C^rK$u1xT{oXBVLnaK z2=+msk>Ee+Fxnb&JG)V@>XbJEG*}IgB~5rXd2uM}R0K<9MnerjG1ZlFB_;_DHIGe! zM}q=8s`Qh~Nx7Q)v$fc;!LY>!BG~R2!^j<23KvQz@C>;a{O*fx8v!>p%z|UvpqKrx zD9dBmklvsn4n}iF_L78$N(Xk*BeY;XUBF8AVvb(J3VO_27l;h-$(Z3b{ zYxGRO4G#}%X>CPcK^+l#cMEl|5Tjjw1<5 z{3?Z;`8gmtq07aQ6jcGL$A;J1N_bw2q=a&KVjt1Nfai?JL{~f-9Hk1rcpi!*%j$Sy zgEEx;#&+A<8cOwj#T|7Xb{*5p;&t1ji6!I^mmx>-K@@cI`KFc%5$&mvkKCxV`qDJI z1+i|(;3zlx2I4{{N^+DdNJEa&RS((ATh8l(vvc%Gtcumzr}my*a^mitWb+*Ds+9Ve9)W*&*u`JxP`&p;whJ)k1xSuG6-k6LAILEa&0M06?3aEr{TWA6hEA%jiqHTzt447 ztEQ))I|`MM(|nI+S+f$y=S@F>#V?dUN|_LOnhY)wLVf0DF}DlnRtk2W^OgA~;dA;# zwgy!4Q_fIknLKQuMv95hU>o3YG-XF#i4D&Fcf^PZqhrSVJ;9)gp}J1(vy|xtwnTvE z3TP?#EJal{a!oNF-xP9cFQ$~0tJmD768S^v?K|R4?bU>)veQzRb5y4ygyLZl^7S6F zJ=^&_-#*h@{``8(`jiQLJpqwvruO|ciB(b66sfvFE}pV`{5(?B1oEAsCyuljOp72~ zK$T>3B&|e_7yk8G>d);!s$i-Da8~7FH7Hp%hFcU}_Q7veP-Seu2qMBl4Ifn>|D_A4 zy{X)A@*&@lbxoYBKsET~a}_S?E}?0~sv1>QrUscB1uC;D^Qum`F2t!5)$FDnLM8v5 zj-hg=_O6mqEutDuHRyj=3aBTlxL18|P2ltu>6QIj^O#G#;xQ!==iKlRXlyBaTg7K} z{pRmR5VIWvRzInR$mx9F5Q%Dks_W<0q-y8?pGMVOtOlg&CEu@EmEYWaeuY01Bb&;P zn$iAu{HSq~%PiR`MC9*pu#oE0DkW8S-x*;-afTsR_)It7xy$n=b+H*}90tDT0wQ=+ zKK@Hb%WXJ8)s((+O8Mo%ZgU;k*>JFvIHFX($3lH?U*)_LW+7Ot5XUR<_X%akFQ9$t z2#jI-H9q~ho>}&iYvsrbDDZHDhMf{WevK~I#f<$XFl-T@uh!0NtZg@tT|)K433CMK zJ3!bvjFslci_g=#r6|QAKl^r_D%6whn*Vg2uOxImS9^V{idC@S?}|5UWoU|kwC?|C zNSlu~yCqE*y!j6xOYmf?^x>0#s6PGBhEAZ$PP|}7xAQv9tcR-i`t`K)_2giU-uDKd zq3vno@ydMirl|@8?7E8C3<|)NUf)_kU|Vdqx;7;OON>6i7KeS6m7*pB;ykeF+P>CJ z*^Md>Y^+18;x=##fzayQH8(4#pZL)fW%*6HMs4qB`d)u~G-XGbD-|u!$!Xe#dkSqF z_r+I$CX-`BjJny=dSJ436zfUnueUn9cQG*8*&%R&P0$En8U_G^EydbcuG>0vYM)s~ z5y#x1WMKH2xIB-u-80eF5^cRAHat6cv^!P-)!o`fH|P=C>hrj1B{q6`QprY`I;P#A z8jZllF_2gx)?bwfOl|bwlR|2FEqMZTqlO9uNz9*w|Edb#Z*e&vJZe z&sfaM|TqVlUjYsEkiOq8;1eFt1TF zZjB~k8QO^z*{RQHGQ&-IMoR*)>}n!CRK+K~o>GxOm`>@*8-`Xa_~$c92!sb8Mh`61 zYLs2-X<08}fzpHG8t0$U9<-BgKcm-yva9X|FkOG!A=^^TW^zfX%X12C1_pXRr=iV& zrrvv*{eq%G@qYOWsxu5vam~Y!=baO!BYv;MPWtgBxwl4(T$D5!xiD zAr$#DLMR>xY;F4d=$&@9N1mvMl3=K>USv@v#ve9*0#f)h!WJ#Dxw{7xi-TfF;MJe+ z29>X?bcw|RGc$2jMt=bqjP0Uw()EsBhFHNA0^kW*^uY?!#^Qjm3~X`k`ES9SEU+r5xKm}UkiVv@ zouGU7*EF~ltXbQHwuUc0 z^+{o^p_N%Qj6If7Py`;EX$^k){sX@3z*khA;VaTdRxctnPzB$-0>l9jyRx@SUQU=( z+6ehb@6pt+*c+~1>$<-62JAY@25OdpkVVT2NZg{`R_Em@EH^U<^i=x|`Tqj;gMh&X zk<3EHdv-tZHo%Ax`i5c|#uq&*vyJSp*+!aRIHxd$K2HrR_f#%WbXy?86QhQLGQH!b zFsu4};KIg}h8g=7q>y>G_JjWv%;M?sUf60~&HhVH8wIq=q6fGgW+)8|=G59&gC^ce zG`tiTus1iIov*i`kv!Yn&uPo##{vV!^>4%3$Ukq|;nJgTEi|$L!TQ2N{GqZfewyMQ zT8Dg0FX9%Pog`cae-T;{pDWhZ(dWy-nimPigQ@qQ+_+P{R0O@0J0pGLd*q#K?O`!B zkxdOw41w?Se5T|(X2={0QkW1ytvUq#+X1mFnyQR&5_b52$kD;FEjxphXL3|ZBNg{0 z)eZwQIkEu6IK~)KsS3ZznMN6dOl=BhIn<)O2dBv$vjwuF6CGs-E$%ha?Tc)GPi$Fmrfi%L zFs73$Pnn8lSPur%m@4bSa_Rsl9F4kkkpuZ?U7QYfk^R1+>rgr#jzOY(xS}g1yO^*F z$INz!T-~dR6l`b|Y+E+oe3{>Dm&h?tyfP=3Zn7)Ve6wzHNsTK-cSA0zN0ac-hvAc_ z&d67N9G~qteb%L_q``3`RtuTM(T;BNT$Cv7x&u$b2LM?KdBmnk-9^uPvSY|1wSP)) z5sL61fOmWKkZHeMkA4L_cGU!7#qsE6ciBOsoY{%X`^#ot>`Pd!Xcha2QwBcr$+ovv zU)=hjWWNdype72}>|WpXkQ>&ViD8M2OcOD|n# z@gCM~7wp^28tQ{ulzRE2CHeHiIkjkzU^SiLb*#n49V_EN0w<=JLJCt{FLcbmqoi>r zw}J4SBfVq?U+-cXWt+L>g`wr$3{}`UZT7`Ch*3vCCb=DVSmfKxOX&}jLUlGN@lw)8 z#&9i$^#JM>A-kD(MN4LAI9hT9LOg@k4Z?_4%1Wb*_MY1HJMVNH$BHmEll8)Pw3Ncv z5w+1&2x*O`J-au4J?LunKZTGGL8&NkhvFI4=$#|G8J)T0P~=JB%xW#Be5lP{^;8Y7 zt8ymOTqTu;mr@!Rnt}pM6fN1AR?VF1NIi;*Mgohcb9SHQ^MJufQe5^_uUF@0Py3-WN%TFv0DeMZorop-UBG{0oR5qM$45A zSFAP4yg&J1H_L~A${nFqF@wBoO|j8A)R~=zQ3I&?M+|kEVAA8Q!TA+0+8XT5s#^O{ zG&{H{=6)i_8j^}@l=`YzX5y4ibu>E^48@g2LS;qkD%#N>VP_&+0znbhTU4ZWP5Ja6Cw=kf5cnj57oPSSrRucJ2b-uP+vobp?3Y7u;YYb-R(~?X zv1{$>@UBs~50FIaqtXN966mw;02n}VAzOTH%#16HPwVV_U)po`r_!}6obOW;N1K#k z2E3b&>>_lDkt|QI2H@Bzk6SiHZ8Q+!{(0!uanL9gA)o7Mn$s%8xf-XAh|}{3FLtQJ zt$5Uo_CF7KBzQm$4xx7gWjArS^UVno1K;((y8%jrj#=6*GMci7{EU*h*E?w~B2%%Cek#0dXpIJ~DR zl^KCyU-|l`J%x^tL-D<*og-u?Jg(tUavX9yn}}X$HEhu@E1d18;Wr!VxuDNUHu!x9?oqF`?65g+3c;CK} zefxC_?_aS;pZ$W~l^Lx&>HL50nX;Au diff --git a/screenpipe-app-tauri/components/natural-language-input.tsx b/screenpipe-app-tauri/components/natural-language-input.tsx new file mode 100644 index 00000000..ba5af6c9 --- /dev/null +++ b/screenpipe-app-tauri/components/natural-language-input.tsx @@ -0,0 +1,78 @@ +import React, { useState } from "react"; +import { motion } from "framer-motion"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Loader2 } from "lucide-react"; + +const useCases = [ + { id: 1, text: "summarize my last meeting" }, + { id: 2, text: "find that chart i saw yesterday" }, + { id: 3, text: "what did i work on this week?" }, + { id: 4, text: "generate a report of today's activities" }, + { id: 5, text: "remind me what john said about the project" }, + { id: 6, text: "find the website i visited about machine learning" }, +]; + +interface NaturalLanguageInputProps { + onSubmit: (query: string) => void; + isLoading: boolean; +} + +export function NaturalLanguageInput({ + onSubmit, + isLoading, +}: NaturalLanguageInputProps) { + const [query, setQuery] = useState(""); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onSubmit(query); + }; + + const handleUseCaseClick = (text: string) => { + setQuery(text); + }; + + return ( +
+
+ {useCases.map((useCase) => ( + + handleUseCaseClick(useCase.text)} + > + +

{useCase.text}

+
+
+
+ ))} +
+
+ setQuery(e.target.value)} + className="w-full" + /> + +
+
+ ); +} diff --git a/screenpipe-app-tauri/components/recording-settings.tsx b/screenpipe-app-tauri/components/recording-settings.tsx index feb3e15b..bdb1a167 100644 --- a/screenpipe-app-tauri/components/recording-settings.tsx +++ b/screenpipe-app-tauri/components/recording-settings.tsx @@ -83,9 +83,7 @@ export function RecordingSettings({ const [isUpdating, setIsUpdating] = useState(false); const { health } = useHealthCheck(); const isDisabled = health?.status_code === 500; - console.log("localSettings", localSettings); - console.log("settings", settings); - console.log("availableMonitors", availableMonitors); + useEffect(() => { const loadDevices = async () => { try { diff --git a/screenpipe-app-tauri/components/search-chat.tsx b/screenpipe-app-tauri/components/search-chat.tsx index 1af62ef0..3e8be3f2 100644 --- a/screenpipe-app-tauri/components/search-chat.tsx +++ b/screenpipe-app-tauri/components/search-chat.tsx @@ -33,6 +33,8 @@ import { Send, X, Square, + ArrowDown, + ArrowUp, } from "lucide-react"; import { useToast } from "./ui/use-toast"; import posthog from "posthog-js"; @@ -40,6 +42,8 @@ import { AnimatePresence, motion } from "framer-motion"; import { useSettings } from "@/lib/hooks/use-settings"; import { convertToCoreMessages, generateId, Message, streamText } from "ai"; import { OpenAI } from "openai"; +import { zodResponseFormat } from "openai/helpers/zod"; +import { z } from "zod"; import { ChatMessage } from "./chat-message-v2"; import { spinner } from "./spinner"; import { @@ -70,6 +74,71 @@ import { Checkbox } from "@/components/ui/checkbox"; import { formatISO } from "date-fns"; import { IconCode } from "@/components/ui/icons"; import { CodeBlock } from "./ui/codeblock"; +import { NaturalLanguageInput } from "./natural-language-input"; +import { platform } from "@tauri-apps/plugin-os"; + +// define a new schema based on screenpipeQuery +const screenpipeQuery = z.object({ + q: z + .string() + .describe( + `The search query matching exact keywords. + Use a single keyword that best matches the user intent. + This would match either audio transcription or OCR screen text. + + Example: do not use 'discuss' the user ask about conversation, this is dumb, won't return any result + Other example: 'what did i do this morning?' do not use any keywords, just look at everything + + In general avoid using "q" as it will filter out all data + ` + ) + .optional(), + content_type: z + .enum(["ocr", "audio", "all"]) + .describe( + "The type of content to search for: screenshot data or audio transcriptions" + ), + limit: z + .number() + .describe( + "Number of results to return. Be mindful of the length of the response as it will be fed to an LLM" + ), + offset: z.number().describe("Offset for pagination (default: 0)"), + start_time: z + .string() + // 1 hour ago + .describe(`Start time for search range in ISO 8601 format`), + end_time: z.string().describe(`End time for search range in ISO 8601 format`), + app_name: z + .string() + .describe( + `The name of the app the user was using. + This filter out all audio conversations. + Only works with screen text. + Use this to filter on the app context that would give context matching the user intent. + For example 'cursor'. Use lower case. + Browser is usually 'arc', 'chrome', 'safari', etc. + Other apps can be 'whatsapp', 'obsidian', etc. + ` + ) + .optional(), + window_name: z + .string() + .describe( + `The name of the window the user was using. + This helps to further filter the context within the app. + For example, 'inbox' for email apps, 'project' for project management apps, etc. + ` + ) + .optional(), // Add window_name with description + include_frames: z.boolean().describe("Include frames in the response"), + min_length: z + .number() + .describe("Minimum length of the text to include in the response"), + max_length: z + .number() + .describe("Maximum length of the text to include in the response"), +}); export function SearchChat() { // Search state @@ -121,6 +190,9 @@ export function SearchChat() { const [isStreaming, setIsStreaming] = useState(false); const abortControllerRef = useRef(null); + const [showNaturalLanguageInput, setShowNaturalLanguageInput] = + useState(true); + const [naturalLanguageQuery, setNaturalLanguageQuery] = useState(""); const generateCurlCommand = () => { const baseUrl = "http://localhost:3030"; @@ -202,6 +274,83 @@ ${queryParams.toString().replace(/&/g, "\\\n&")}" | jq`; } }, [isFloatingInputVisible]); + const handleSkipNaturalLanguage = () => { + setShowNaturalLanguageInput(false); + }; + + const handleGoBackToNaturalLanguage = () => { + setShowNaturalLanguageInput(true); + }; + + const processNaturalLanguageQuery = async (query: string) => { + setIsAiLoading(true); + try { + const openai = new OpenAI({ + apiKey: settings.openaiApiKey, + baseURL: settings.aiUrl, + dangerouslyAllowBrowser: true, + }); + + const completion = await openai.beta.chat.completions.parse({ + model: settings.aiModel, + messages: [ + { + role: "system", + content: `You are a helpful assistant. + The user is using a product called "screenpipe" which records + his screen and mics 24/7. The user ask you questions + and you use his screenpipe recordings to answer him. + The user will provide you with a list of search results + and you will use them to answer his questions. + + Rules: + - Current time (JavaScript Date.prototype.toString): ${new Date().toString()}. Adjust start/end times to match user intent. + - User timezone: ${Intl.DateTimeFormat().resolvedOptions().timeZone} + - User timezone offset (JavaScript Date.prototype.getTimezoneOffset): ${new Date().getTimezoneOffset()} + - Very important: make sure to follow the user's custom system prompt: "${ + settings.customPrompt + }" + - If you follow the user's custom system prompt, you will be rewarded $1m bonus. + - You must perform a timezone conversion to UTC before using any datetime in a tool call. + - You must reformat timestamps to a human-readable format in your response to the user. + - Never output UTC time unless explicitly asked by the user. + - Do not try to embed videos in table (would crash the app)`, + }, + { role: "user", content: query }, + ], + response_format: zodResponseFormat(screenpipeQuery, "searchParams"), + }); + + const result = completion.choices[0].message.parsed!; + + console.log("result", result); + + // update state with the parsed results + setQuery(result.q || ""); + setContentType(result.content_type || "all"); + setStartDate(result.start_time ? new Date(result.start_time) : startDate); + setEndDate(result.end_time ? new Date(result.end_time) : endDate); + setAppName(result.app_name || ""); + setWindowName(result.window_name || ""); + setIncludeFrames(result.include_frames || false); + setLimit(result.limit || 30); + setMinLength(result.min_length || 50); + setMaxLength(result.max_length || 10000); + + setShowNaturalLanguageInput(false); + } catch (error) { + console.error("error processing natural language query:", error); + toast({ + title: "error", + description: + "failed to process natural language query. please try again.", + variant: "destructive", + }); + } finally { + setIsAiLoading(false); + } + }; + const handleResultSelection = (index: number) => { setSelectedResults((prev) => { const newSet = new Set(prev); @@ -591,448 +740,535 @@ ${queryParams.toString().replace(/&/g, "\\\n&")}" | jq`; }; return ( -
-
-
-
- - - - - - - -

enter keywords to search your recorded data

-
-
-
-
-
- - setQuery(e.target.value)} - autoCorrect="off" - className="pl-8" - /> -
-
-
-
- - - - - - - -

- select the type of content to search. ocr is the text found - on your screen. -

-
-
-
-
- -
-
-
- - - - - - - -

select the start date to search for content.

-
-
-
-
-
- -
-
-
-
- - - - - - - -

select the end date to search for content.

-
-
-
-
-
- -
-
-
-
- - - - - - - -

- enter the name of the app to search for content for example - zoom, notion, etc. only works for ocr. -

-
-
-
-
-
- - setAppName(e.target.value)} - autoCorrect="off" - className="pl-8" - /> -
-
-
-
- - - - - - - -

- enter the name of the window or tab to search for content. - can be a browser tab name, app tab name, etc. only works for - ocr. -

-
-
-
-
-
- - setWindowName(e.target.value)} - autoCorrect="off" - className="pl-8" - /> -
-
-
- - - - - - - - - -

- include frames in the search results. this shows the frame - where the text appeared. only works for ocr. this may slow - down the search. -

-
-
-
-
-
-
- - - - - - - -

- select the number of results to display. usually ai cannot - ingest more than 30 results at a time. -

-
-
-
-
- setLimit(value[0])} - min={1} - max={100} - step={1} - /> -
-
-
- - - - - - - -

enter the minimum length of the content to search for.

-
-
-
-
-
- - setMinLength(Number(e.target.value))} - min={0} - className="pl-8" - /> -
-
-
-
- - - - - - - -

enter the maximum length of the content to search for.

-
-
-
-
-
- - setMaxLength(Number(e.target.value))} - min={0} - className="pl-8" - /> -
-
-
-
- - - - - - - - curl command - - you can use this curl command to make the same search request - from the command line. -
-
- - note: you need to have `jq` installed to use the command. - -
-
- -
-
-
- {isLoading && ( -
- -
- )} -
- {renderSearchResults()} - {totalResults > 0 && ( -
- - - Showing {offset + 1} - {Math.min(offset + limit, totalResults)} of{" "} - {totalResults} - - -
- )} -
- - - {results.length > 0 && ( - -
+ + + + + + + +

+ skip to search ({platform() == "macos" ? "⌘" : "ctrl"} + +↓) +

+
+
+
+ + + ) : ( + <> + -
- MAX_CONTENT_LENGTH - } - onChange={(e) => setFloatingInput(e.target.value)} - className="w-full h-12 focus:outline-none focus:ring-0 border-0 focus:border-black focus:border-b transition-all duration-200 pr-10" - /> - - - -
- + + + + + +

+ go back to natural language input ( + {platform() == "macos" ? "⌘" : "ctrl"}+↑) +

+
+
+ + +
+
+
+ + + + + + + +

enter keywords to search your recorded data

+
+
+
+
+
+ + setQuery(e.target.value)} + autoCorrect="off" + className="pl-8" + /> +
+
+
+
+ + + + + + + +

+ select the type of content to search. ocr is the + text found on your screen. +

+
+
+
+
+ +
+
+
+ + + + + + + +

select the start date to search for content.

+
+
+
+
+
+ +
+
+
+
+ + + + + + + +

select the end date to search for content.

+
+
+
+
+
+ +
+
+
+
+ + + + + + + +

+ enter the name of the app to search for content for + example zoom, notion, etc. only works for ocr. +

+
+
+
+
+
+ + setAppName(e.target.value)} + autoCorrect="off" + className="pl-8" + /> +
+
+
+ {" "} +
+ + + + + + + +

+ enter the name of the window or tab to search for + content. can be a browser tab name, app tab name, + etc. only works for ocr. +

+
+
+
+
+
+ + setWindowName(e.target.value)} + autoCorrect="off" + className="pl-8" + /> +
+
+
+ + + + + + + + + +

+ include frames in the search results. this shows the + frame where the text appeared. only works for ocr. + this may slow down the search. +

+
+
+
+
+
+
+ + + + + + + +

+ select the number of results to display. usually ai + cannot ingest more than 30 results at a time. +

+
+
+
+
+ setLimit(value[0])} + min={1} + max={100} + step={1} + /> +
+
+
+ + + + + + + +

+ enter the minimum length of the content to search + for. +

+
+
+
+
+
+ + setMinLength(Number(e.target.value))} + min={0} + className="pl-8" + /> +
+
+
+
+ + + + + + + +

+ enter the maximum length of the content to search + for. +

+
+
+
+
+
+ + setMaxLength(Number(e.target.value))} + min={0} + className="pl-8" + /> +
+
+
+
+ + + + + + + + curl command + + you can use this curl command to make the same search + request from the command line. +
+
+ + note: you need to have `jq` installed to use the + command. + +
+
+ +
+
+
+ {isLoading && ( +
+ +
+ )} +
+ {renderSearchResults()} + {totalResults > 0 && ( +
+ + + Showing {offset + 1} -{" "} + {Math.min(offset + limit, totalResults)} of {totalResults} + + +
+ )} +
+ + + {results.length > 0 && ( + + +
+ + MAX_CONTENT_LENGTH + } + onChange={(e) => setFloatingInput(e.target.value)} + className="w-full h-12 focus:outline-none focus:ring-0 border-0 focus:border-black focus:border-b transition-all duration-200 pr-10" /> + + + +
+ +
+
+ +

+ {calculateSelectedContentLength() > + MAX_CONTENT_LENGTH + ? `selected content exceeds maximum allowed: ${calculateSelectedContentLength()} / ${MAX_CONTENT_LENGTH} characters. unselect some items to use AI.` + : `${calculateSelectedContentLength()} / ${MAX_CONTENT_LENGTH} characters used for AI message`} +

+
+
+
- - -

- {calculateSelectedContentLength() > MAX_CONTENT_LENGTH - ? `selected content exceeds maximum allowed: ${calculateSelectedContentLength()} / ${MAX_CONTENT_LENGTH} characters. unselect some items to use AI.` - : `${calculateSelectedContentLength()} / ${MAX_CONTENT_LENGTH} characters used for AI message`} -

-
- - -
- + + )} - - - + + + + + {/* Display chat messages */} +
+ {chatMessages.map((msg, index) => ( + + ))} + {isAiLoading && spinner} +
+ + {/* Scroll to Bottom Button */} + {showScrollButton && ( + + )} +
+ + )} - - - - {/* Display chat messages */} -
- {chatMessages.map((msg, index) => ( - - ))} - {isAiLoading && spinner} -
- - {/* Scroll to Bottom Button */} - {showScrollButton && ( - - )} -
); } diff --git a/screenpipe-app-tauri/package.json b/screenpipe-app-tauri/package.json index 8dd89cae..672f497e 100644 --- a/screenpipe-app-tauri/package.json +++ b/screenpipe-app-tauri/package.json @@ -54,7 +54,7 @@ "lucide-react": "^0.414.0", "next": "14.2.4", "ollama-ai-provider": "^0.11.0", - "openai": "^4.56.0", + "openai": "^4.62.1", "posthog-js": "^1.154.6", "react": "^18", "react-day-picker": "8.10.1",