From 85d8df96ca624fa00b22ae61a89e53c2b270c2d3 Mon Sep 17 00:00:00 2001 From: Andy <88590076+AAndyProgram@users.noreply.github.com> Date: Wed, 1 Mar 2023 20:35:52 +0300 Subject: [PATCH] 2023.3.1.0 Add 'Path' plugin UserDataBase: changed file names for saved posts; removed 'Self' property; add 'MyFileSettings' field; added UserSiteName; changed download envir algo Twitter: added MD5 comparison; duplicate images removal option; UserSiteName parsing; download icon and banner Instagram: added a new option for token 'www_claim'; removed requirement of token 'www_claim'; UserSiteName parsing; download icon Reddit: UserSiteName parsing; download icon and banner PornHub: fixed unicode titles XHamster: added channels ffmpeg: fixed max input length error during files combining; fixed encoding issue Feed: added images centering; added BackColor and ForeColor change MainFrame: added BackColor, ForeColor, and BackgroungImage change; added 'UpdateLogButton' when load completed ListImagesLoader: fixed wrong notification when no users found SettingsCLS: updated users loading algo --- Changelog.md | 22 ++ ProgramScreenshots/SettingsGlobalBasis.png | Bin 20182 -> 23465 bytes ProgramScreenshots/SettingsGlobalDefaults.png | Bin 10873 -> 11544 bytes .../SettingsGlobalDownloading.png | Bin 16922 -> 17640 bytes ProgramScreenshots/SettingsGlobalFeed.png | Bin 11504 -> 14349 bytes ProgramScreenshots/SettingsSiteInstagram.png | Bin 28013 -> 28106 bytes ProgramScreenshots/SettingsSiteTwitter.png | Bin 19758 -> 20578 bytes .../SettingsSiteXvideosAdditional.png | Bin 7059 -> 6527 bytes ProgramScreenshots/SettingsTwitterUser.png | Bin 0 -> 7121 bytes ProgramScreenshots/TrayContextMenu.png | Bin 3704 -> 4399 bytes SCrawler/API/Base/Declarations.vb | 3 + SCrawler/API/Base/Structures.vb | 4 +- SCrawler/API/Base/UserDataBase.vb | 195 +++++++--- SCrawler/API/Instagram/SiteSettings.vb | 7 +- SCrawler/API/Instagram/UserData.vb | 37 +- SCrawler/API/PathPlugin/Declarations.vb | 14 + SCrawler/API/PathPlugin/SiteSettings.vb | 49 +++ SCrawler/API/PathPlugin/UserData.vb | 45 +++ SCrawler/API/PornHub/Declarations.vb | 1 - SCrawler/API/PornHub/UserData.vb | 7 +- SCrawler/API/Reddit/SiteSettings.vb | 5 +- SCrawler/API/Reddit/UserData.vb | 39 +- SCrawler/API/Twitter/EditorExchangeOptions.vb | 5 + SCrawler/API/Twitter/OptionsForm.Designer.vb | 73 +++- SCrawler/API/Twitter/OptionsForm.resx | 16 +- SCrawler/API/Twitter/OptionsForm.vb | 4 + SCrawler/API/Twitter/SiteSettings.vb | 3 + SCrawler/API/Twitter/UserData.vb | 229 ++++++++++-- SCrawler/API/UserDataBind.vb | 2 +- SCrawler/API/XVIDEOS/Declarations.vb | 6 +- SCrawler/API/XVIDEOS/UserData.vb | 2 +- SCrawler/API/Xhamster/SiteSettings.vb | 19 +- SCrawler/API/Xhamster/UserData.vb | 17 +- SCrawler/Download/Feed/DownloadFeedForm.vb | 36 +- SCrawler/Download/Feed/FeedMedia.vb | 68 +++- SCrawler/Download/Groups/DownloadGroup.vb | 13 +- SCrawler/Download/TDownloader.vb | 4 +- SCrawler/Editors/ColorPicker.Designer.vb | 141 +++++++ SCrawler/Editors/ColorPicker.resx | 135 +++++++ SCrawler/Editors/ColorPicker.vb | 113 ++++++ .../Editors/GlobalSettingsForm.Designer.vb | 353 ++++++++++++------ SCrawler/Editors/GlobalSettingsForm.resx | 82 ++-- SCrawler/Editors/GlobalSettingsForm.vb | 28 +- SCrawler/Editors/UserCreatorForm.vb | 58 ++- SCrawler/ListImagesLoader.vb | 8 +- SCrawler/MainFrame.vb | 78 +++- SCrawler/MainMod.vb | 2 +- SCrawler/My Project/AssemblyInfo.vb | 4 +- .../PluginsEnvironment/Hosts/PluginHost.vb | 3 +- SCrawler/SCrawler.vbproj | 12 + SCrawler/SettingsCLS.vb | 255 ++++++++----- SCrawler/UserInfo.vb | 15 +- 52 files changed, 1769 insertions(+), 443 deletions(-) create mode 100644 ProgramScreenshots/SettingsTwitterUser.png create mode 100644 SCrawler/API/PathPlugin/Declarations.vb create mode 100644 SCrawler/API/PathPlugin/SiteSettings.vb create mode 100644 SCrawler/API/PathPlugin/UserData.vb create mode 100644 SCrawler/Editors/ColorPicker.Designer.vb create mode 100644 SCrawler/Editors/ColorPicker.resx create mode 100644 SCrawler/Editors/ColorPicker.vb diff --git a/Changelog.md b/Changelog.md index 3543ed6..2820ecb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,25 @@ +# 2023.3.1.0 + +*2023-03-01* + +- Added + - **Path plugin.** Now you can add paths. *This may be suitable if you want to add a collection of media data to a specific user collection.* + - MainWindow: setting a background image + - MainWindow: setting background color and font color + - Feed: setting background color and font color + - Feed: (Request #108) center the image in the feed grid + - Users: the ability to use user site name (if it exists) as a friendly name (on supported sites: Reddit, Twitter, Instagram) + - Users: the ability to update user site name every time + - Twitter: ability to download images using MD5 comparison to protect against duplicate downloads *(this may be suitable for the users who post the same image many times)* + - Twitter: one-time duplicate image removal option + - XHamster: (Request #107) added channels downloading +- Updated + - Updated ffmpeg to version [5.1.2](https://github.com/GyanD/codexffmpeg/releases/tag/5.1.2) +- Fixed + - PornHub: (Issue #106) unicode titles + - (Issue #106) problem with non-Latin characters + - ffmpeg: maximum input length error when merging parts of files + # 2023.2.5.0 *2023-02-05* diff --git a/ProgramScreenshots/SettingsGlobalBasis.png b/ProgramScreenshots/SettingsGlobalBasis.png index d8b6f12a289879bac1fbf0b125c5af666dd0b2d0..9cd66bcd728de8490717808fe0f55258357c02b9 100644 GIT binary patch literal 23465 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 Z{%ftji2nX%uf&x**q*hivbuQdKLCShq&ffq literal 20182 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 CV=Kx4 literal 10873 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 C=MOOe diff --git a/ProgramScreenshots/SettingsGlobalDownloading.png b/ProgramScreenshots/SettingsGlobalDownloading.png index 17bdf7b66e22746704c92107886083df23ffc2af..c8717ea0931621af5ad176642e8e80d28afdb7d8 100644 GIT binary patch literal 17640 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 literal 16922 zcmeIaXH=8lw+0w2U`J4t4$^y(-USq-cccfY(xuk`N|mY*LkH<1O?nR~O}ca;KvYU- z0SOQYAuuoe%KzS3Gk4uDvt~XFOV&x=b>7qV-p_va-Ur`kYbxKoMtuzg0^L-3`dAkP zx}XXI5gA?~2A;r>)k{D_*uOC0Z41B-(@~N>W2z0CS z?3bw5?V}9{BwwlWSYF@H0^N4K(Z;|ZWu6?AX7f-`b0rXCOPlq=?)M-iy{Eqkmm=KF zs>e^><;j)kJZ9TVt&i+lZ)-nheQnO9s!aWaNYT^bw(2dhHCO5Q`8m(fihDE(s-Ecj z2&JVW%gn@IS^HbFPSdk3Q?n_O2HxwKz>(dJ*}!t&HYao&)&dW9LVGr2v!}OsfmMRO ztFb_D1$A!|0iQ!JDqIB`M$rGzbUX?lyIMK|(;GJ59=ZthPSrmmSB;`;)RhgyiY@(V zpks_`#Uw7Nm2WJUB3m^U_9LJ5>ud++1g(^&^oN8HxZ7;c=3AIUwr}1u_FU7bKH5OS4qClK+>FoGr;?kb9dHm_`L6S1{ier6 zZqzri3Ve3$c8Hm43reTSyEosX^S5I42^POJMzbAbmy!^Ge21wJYg1Y{X_hQL7uy7H5Ij~48os?b z{VcC3ZJ(bB*>|blN-rOqZ8aZm^pH2qYEhB(>yKFQyP7l0Vvb+|@8O`!boTwOOYI}sTX_n1ZaWp6sYMepzpY4WXy3RZ z@#i$Ksde&C?qY_=QDMWk_hR#`p3`n(3Tr0*BlweIF^k76&b00}Sd{GY(!rmG>bK+y zGmtYWcn7`y$ndTJdQY|gLC8)oW|G_O{q|;%>d8sc5N3*S`l%NccDmc?(X-s}Eh1yK zdcDc?NEpK=^vuqP?LVqqS6n8X3S%&+)NmHK@o29A&oRtwXl=(cdZ9%yp8| zIFBZZjFxQ1JP*7PMl2r&gZKEL<|`XZGe@!>TM#>bzT)8e8^BSi^DtAW_Txz4;$=cr`%a{`!D1Fa(8~`7F+R?2=-?MIyG}3$3^& z^_W`ZEVZLtLRd?O+mwbIH`$n>uJ0GM+8-}eVMIzO{T~ZSaYZv#{l?#HlztAKAL$#o zqv~#A4|`K6cBc8A>~TjFYJgDWLyqtszl~D{QYwtz?l;IVit)+vOuGhZ^EG2{;qcc{ z%h28Ff&2VT@|uLBd$?Hxv4QniIB##ZD0>Lu4gbKa{nMZE{y&R{y}DHFuU52ltz=C0 zk;%#6pZLE5G_E0Ic#s^B$kJQ(=p!<<_jb?){8l7w@M^BdF(>$4Y{ML@Y5l2o#Y{lE zb1T}S2~))IjWwg48=T&vqbVC=anj5FY(VOkUo34aGNY|Z((96%)mDrA%yNVHcI@;r zI)y@&7_}`{XtClmmU8Ty1qj5lfCs^l>E%Bnbqh9mAI$H>*CuhK2SQoY7z{UK?%_85 zkx6&p0TDr~(A_08Uh8|vb8@rwGvhKY;?LcCb-=*NUQU3uo_-_k1Gf{(JvQ(2!}2wc zVpa)xtuui)WH9;-xdu!|e~@%2dDtHi!9 zr;FpGSTK6`p~TO4C6;AEZl5hXp&`l0>I~}`AlF%eCe(o>_Y%77fU z8}As7f0BGBfqPyB32@z31u-iy92toyau9WRj59;$+&n-6MxPy5q@o0<=SVJh@GMfO zR&noXFj)+%SK3x_O4?@Rq2B+8ho8*w!D*pu(RN_lXE=`gzV{c^6bl7Kia z4Yr%t`_9RDw92}zY@wJ9Uq=7>234&#b&}=pzbAy=S4A6CH{e}-w;HO6oiA=qy>7EMmbiRZ|RAG>Snb(!4)HWacZCq7S@R@w7a@0!A0ViRApC zOaf6gYRCAJxa7j!DjmJ>knP5ilnslm`~}BpFAc1PL68PYw<^8~eKA##>sn!C?PhRk zqP)YSi^e;QdbwE_9mg4eL#d_bC1cjTc9YRC;Z59H!_Yz_RSuD^pT*n}g4ejtcQmY9 zg2bR|f8TvBfVOFcf^K6udX{VjY|VBW4f!2~lAW)GIKwxb8uC+>zpXQ4-!L>cXWCcK zHwU>-PBHxAx!kinL3;|p3c8CV#NYqKuUBC=&~5x+cOMe?o~m}R$!&)JX3+@E5o=zK zpu_Dwf8N6}=16xfgSa$=Y$#QJNNz1OYKWYZ*5*^KCuNv!4wOpznaCc(QtkJGpsTEO0S3MgYGby!K18c3RwXP$hrt7|g%FtkT)(o@CJeQc80uaYtx0_QFTAn5-EG!_5WIr zwSbT+uRXQ2$r}QhO~a*#F!hgFY?W2MbDAwI_v`wcd({M8@q}KA zkU$OiP|vp4W807q8W?TC!8$6NFq$D28Oa@Ke3hBQuRYaG#q;GE>?< zgg{2;UVCzdIn^*@Z&(vGU!>i%X`h*e5kn}i4kpTo`Jc>;h_|rIX=+X;Tf^bo=OHbP)X2 z=V^UcTl||JqJ;D?u4Ar&j1F4v}I>oVpo!Q-wwf(bl_sBpwFU@EmA?&v=nW^uC9RU96_5QO~j+ zuTE{v_S9xm(g}!g`f%)D)kVrPRD;(1bKt)v*dsd{j1~HO6I0A=lI{Cb##aYSne=qV z325;wW7W1!D7Tq{yOfYI_WqVnSwhN>pcB_tZAhBOyGBpK1wa?|+Z)4=cor(=df{HC zvR~S=BmFc`lXR*FbYV0?QFBnPu~t^qOv|sJi+rDIoK0dnBslKmbI8o_!-_6tA<5lpZakTFwO?VS&&=~uE(^zaz#+DP(YK-}0_K(r8+ozg`&zTBQhY6L;V}-r z7=(dJQ)9NDHkL2!@<&lWNBrQ$V&^O$M9P$>tMlolVR?(VyhTkcpi%FKV`U5Sd{%?8 zjaEqgG;KNiv3Xl6x47Sc>2yfmYrB-q(efF0B->m+*u;Na-cXQu0g}0{*eeIM@RNDp zatrEs&`kcZg=4;rAv?YytWa;L7#koU zAtisnS*dSm4E|iQHyMtlCovpqoK7L>VG8BDQYiTPOW#Os=6#u4W$Esf{G@SDK<2kq ztuOs=J*P@|(gGz&!0g=rfe?kQJOQpNQmuXPy7Hsw8uE^MyZRzaG!Wij&#v4N`Nx)P<_&_W?K8koCvkg z_9xDT_IlL0P={aseFX%H?D`(AYsgZv&kM~Xd9FykpFZJ8T$6Q}CY@nXIjv!F+~F)z zPyr|NcBq{lQ}6GU)ijQuaqbn&`cXpixd!Q)-t4?-*HX-@()uyZAyAPZ)QdVSp52PI z9wT_Cd)h!27uBar1l7$lR=Qkd-bt{(OKiWX)3QjZK_m95a=iX-T6GrI2|U$;GP0i8 z{k5C8p_-68s`|TuTBLZPL(rywI-|UCen;ZkB+WFy{Xg&+bF3w$Ut^+BnhIi4aZyp| z3o5##xc75YngtzJ>C&acBx>3w_JBr2G0R zXQg`$;+DBq;zhW0+R|an8OzSiyIzgk+%2L za;;M|8}|pd;gcvZa68WJ0PUg4vl6sZZL6^6BX_qqsl0}xo<>X`EC+XOo^NpYf4VEq}D>EAAT0C{iZv z8dlezma~}hU`VYm+YQzc8%cVT%p=mRz@yqgdiqG(&CGOo8mryXKjCmWPp=qp3n>8% z?i@G^+tmKcz8Dc0Jkd7g=j#)hs-Y^X_F;)?2f>QU%2r>g_A{Q}-x01$#Z9g{ zs#rrN_w;=v{$;5Y|AHi`@K9`u=DN;|W_C<-gcMI-| zHE%B!{BBWTrQzQuqJ0tg(LBQ2k;Y)I(R&uXI_`Tb%QJ~{dU0a~k4@go-2G%r{>6U0 zKTGU@u2?wR`sDyggXb*3_$?`ga_@HReh-gPKbFwf>C~kHf#P7S*9$*2E~|xUn@A=H z-SWO#e=l7Fux?6vHS%-o9>4KFq(lCDs^pRFc|ahb_VED}*f2=?qXD_<6qzOL=WLX5 zgcE}uMQPv!fB~0ZqC3mJ){)l4Ov*T3VGX^|h<$GO3+U6mPA?Kp{)os7FHm~c$I3gA zTH)#kPz5B_;H*zov+~W{OWL4m*+H(eK1TETk=hqHLeGXi>r=L+vti0HDSOn`-?&V~ z7SS5jy*1ymoFKLJHp8`9rJ`l4c~$Q~WFAE-pz`&DuCauVss9Qz zaz?_6u41G({h{DcH18(PFbPRX$q0WvbUcS9oRQL;ZlX_!0GL zq~s&M{^MDH;|Ukjkw(&QVUA#(Om{g_wGXSaBQ;;0pdP^jU()tApimOYg*4%=JR)QL<%`0xEvUq+>J7eNTr&I_WR|ToB&Wh9^V1|~N~!Q)llm<1 zNA!_=f*(sbnh97$;Ablp!UU2x=d095i7+rlq{O2mt3-UL^hYd3H`T%J=S!Fh0uy&D zmf5H8Yo^7V~fGJe2>W0k7{l*{wRA`)XxY@0<~6{bRS*>C5H_KU;9@?r?QP_Zt~8 z`{OW_0Ym0a@QkOR{HkCheya{_6EO|XgWTPZ$X2$;@p_#ouJLtlO2y|+=b36IKERpv zi~IF*KRuiJNyKD(KK|vaj?fE@`}em@%LBk@OE;qM{&d{ z3sK4sZ>PT+En+7P&e-np9q7Ke(`x=(d(?)wF~a;+K&xOTT7QmwdH#z&$*;1+{hF%$ z`fi6UpB(R^VZDde#VAHRC}t#?*M62dfRWur1EW^!^!i&1Hn!}~tk{d3A0#!dzA&T$ zs$ISPM$NXc9NchDT5O83Vupp+lZWaRa?!1!bP6@c%-qD!eo2bHl(${`6DC2o+6{~y z9=siKygL?aXE9ej<7Y5Xj8&rzb2F9OU3W$lO4>n*pI~Ph*5i`M_$9xyAQyfIR>o3= z->b3x4H1LQWQ(~cdCUZ*Xv_F~u94N;)Q1=h1pZ#GpKK`4DLH~-yxD4=9x)CD9@-oX z`8+q(bJ2Z>PG_toY@JxzLnRd$y(_9wdR6#bua<2!&x0Xs(vjwq#~4;-z2W-%`5c;M{7nX*YT7o6RqTcx}n)x&b@D0I{kcYwkb=Sc3N=2mp=g(e{MwH=;FtY(lk0N zv7vyIhdA_|=;AdID@(QmI4c|m-!u~B4;OAh2PZ5-Bpv`5EqYHuMTJ1ey4#WXIG+3N zU3=tyqV3kJcWqcm z`+iY~m{JO2Z#;&jE;x9jyoGiG*E4UrWJ8U{#b{B|rUdE5NgM_pnw zR_Z%x8a@O$%6&JSMz)w&Ya;z)FdA(|L8w-7Tc+PXb`+Vo?&IFSa7y#hxcy{0IGe&8 zKVMkyY=WZuu&~RpeqU_s?a^?SM*qr;3)sZ5rK|3p>MpICs*&9>+6TGcgjZ|@6bkTZ zJxUz$Nj{|y>XZgDNZzsrqPe-E`;U34&d~f9-BYj6Iz;)nor~t%@^~v7eY;_mZMsG; z%No6(YbnpO{FGQ`tUAR{~MMg`o`51=hUaQyG zrOwxz3b8;BwC#wkxG_`v#SA|zvQ>mQxtV#Y-M-iL=Wq|{J3F<>^G0vjr3Rt7 z?K4{U&LxpA#Q0P^GPW|CYrhGeM#!B{xuY-<95y?6g%v+t7bYYJBC4K-SC@rkiAy!g zGpt%>Lk{I(RV`Q|rEtJc19ZT^ec+<{HF#9SlazaVGB+R&-ZrO53Izv;RlG`(R#=V7 zTLGVG*^cPX&C2C&xt9dE{~z@8K+5oL2S6dNopAxfgEPi)?Z46tuB+#%N@IC|FaT8K z=f7=vl6G~1K-2fcaUy~^-CqslMGlwal|rhp;LKaAy=$R=HHvtB9Yu~I%DqLeM{=4Z ze>DuV#WBZ~OzayRv9EB~(i_}gR{LhHMz_PVk6e8hc zaq|C;2n@WJ3;FaBh*w<5ByRj|D@XsufGl{Xgt_+d@halvJ?6n?^J+J<= zzqptv$LG7?U+j#i*T8PhFt;Ce^Di}_vSVev!Q&!eLbdJrk?L+ro^g(6T#|6P+Z+^^^1eG(pSl7=V{<4Z>$cJap;z_|>Q zO%%=u7}A%x51Y@|yQ;28rPqGEOw&dhFFs4LtxRg>2{xpYqH?;|z0>qa52M zJ80gBe_BpX?5tqJXO8Qm^)(Z!axf-DqIK-G!T`P5zF@U5 z<dBsT%vNHp9!A0580=K zJuC`d--c<8;}j&^;BPlodvr!p2DAC|*m#={_SE7ve2;UZT7xI3Sm?xRUNoCLmy7KA z(wHa-7R`dk?rz>6mJli$^PQ}kZkx3kheD5);XP)7O9NW?m zhXe#RU&Nr6jP9-K=9V@Y`zTUSh$xS&5uP@NjZ+oBK*EFssZ~rA(_O?2+1p*m%yT&E zi_0|J#5S^o%k}IV0<2P-=j-vmyKK{MvKw+&Ow07pRudY}IDsa&C`8aGB(|Ry83x~8 zlYTl5R(}Y8*B;1E9g?*+v>O!-Y+zaRpA7``J`sZVK%j#?r9b13IPZOPKjKSH(EgMl zGwry@4NVe;toDeNWo*IT@KK_^+>no)O}wf`rn+ZMRZS4DZ?s~T@79)K^m}-Lbz>v8 z*g*+ul=JkGh>81*2}V<2Y@STeeFj#!Wg~T)ool1jvoMbzQGWq=^9NO-aNou8wu8Gh z;KL^q`%(0mBlkuj)wSR_tm2vvgX;5blDeI{syl9N-bG|mq~=nkpPjz=)*v`n;!>-3 z7@vP6q<$~f&infeDd?{{5)4sBD91#G5h{`H(R^*2XWxddL zx7lskD5n#o(2!RW9K6YZrt!Nf{!JS%mU3Whh2(EMX&p!>7|$#?=Uu-*M`3@ z@4Vl;F&&dKbj=Q`;0}b(?Uw+xTXJhdn+RAh2L*xG;J!*Fo|P-XWE!}z#JpgAoq`Y{ zmA}0$JY<76BYV>xwy-Dp;gsu+OxO*_#RpJJ8vx>f9rVKJ1xIn^4Z|(cS!sn^NyhoU zN_~8RGsvXfH)I-W-JCUhcJ_r6%H1Zk)A2dZD4w<^mz}zD5Lj+KtacEI)M~x3wVo<2C-Y1^&E}sFy2hoO=Qj!4vS$kW~ROH>8Tk@g`i)ZrJQ1CvY?}BmW@w znfM_u2ECxx&`K+y5VPGeAgw7Ms_+1|n;q z?Fch*$hA4kPk@T(!hzB!=n?3jX6){(=aiAp7oFku(~V);=}Z$qBrOgU0IL)=atu-| z0@gY{kH~>7+JB_p3m?0iYsas2mM^5aKX9#(gdylLQaL7x#7T2@fm>L zd?+)j%6n*{`Ol-}tA$xozWw=$vRqnngj(s{K_Rk4xs%4t**fm!l*_rbw6z(!m6HWP zqHxUFKS(L`S`JsF_E#V;*)tOpK6V!1=SGDvkz_sOKRx=sYirJYpG(a65>h&e7Ht+{Ex+ zXiaqJaxPT)iJ;z_<-4i|^w@z1w_?_5^)u$gZLRovn>qw;Wat9LaKzREZ>5}j*yePr z(t;;Y+AjCaVjnr(Mm?!fO_V+gFEjPcb)NMq&-9s1A5-WX)-`wUrtnxvvsb#HayhxE z+_ZsjOo$6wZFMyls%8p!HsN$$2ZS-JS_|vVa2Ih-zw$P^G{Meuo*9_ zoN?`Tzr!Hr8k$C~`b6}jXp?(?7j3U6pcSII_sCVbEJcx3dJE2v$EN5=`|RVy$7TvT z+k>*^2tS!IU5i>+R_G>XwyKw&yE1ToV`*<(D-pKC2S2o$2{|R?Pg0oo2Oj>4(p$c* z`h-$`qV_Ahab(Sf{^?V0mR62JdCZl(+7n(2|!=1!5%9Khowx`~AeviaEhKD={J}={wV1jhpEoH>us9?f8JVx?(d$cBWk88neA_#JjB5 zIA}r|(hc`&`_iZ7>P@G`)e^F;V+V==PUOTp(z`^FeLsgZ^7)TAlWgr-%zPH+e$H`` zvuIAgm|L3`oFSGa<&%(Vb8Ef-uARis(2F+9{qH^YMwOMVF&p61qZdUgyEWTf51?G% zT}3jDnG(ObkDKQ%9Yu~^r~IfLLyzIhiaHcDto>N>`RS!_3KlNDgf-cpE*5534^vS= z=IFAQF+t4=?5yc|)tYhoa}^(=AE$8L$v~=XnS7ITat)#Z{FcPYuto1{S=(W?4)%p^ zKr=+HUoFfz*(>%K*-~Ea&|6tX(z(CeJlVN}S-PXOA6@WCK}CnGKuAe!?qyi(ubXaf zpS2%NR&T@c{kAFQY>CpCr-@H>Z>zrlo|Ye3tH9K&L3%Y$JAf!ZO~+$wKB`S)8cqL> zB9?YrQ7*eq@WS(w~Hpn8R>aXTzc-;80h(coz_$m179fD!H7NhZ=?WX65Oyzb;6Bs``-LJx)#Ukai`LLnM?A)PJ5wR7Gpl(F3q;u&5+enj;ejSXy*;R*Qu*1eX%RnRD31zC6L7Y2u)yVx0rT3S-Wq%dbf2pW40M6Z`2^ zqSb)g1?Ah#g^#hMX_YM*8-xIu?>qx+4~j-K3`ikynw3whTMyc{-!IDgm=*d$H<2p3 zUkV0ZifSBC5HeI}9$qQDDj%U`P@4(3pfi6V2EbeMC7eC{-PRzMCPOR;O|e(zUHx6XAfHzOAa4@Lz@^yw-l*4+Ml~ zVC^mxP9AsJF+dPVX~)qx9+l||KIGWk9Z8wy7cByAemt=R9NZ7_jO`hbEynYt^@ac5 z=->OxU4~N&oqwSEKNq`hUpg<5jn3IWP`LW~|-2E4+vyI9XuaIC37bnpOzb@*tKL#IZkMpXi)R^ zx|N){KCwddfa$fc7^yNWCxun%pAxGpKx~^TGNHr<)xRr3eX~Ri;clWvT?b^91K<88 z$_>{(OW=bXnaNdM9HtEJQn}kOENv-5-u`}Wq+p}%9yKXjsNj6&#wny2anGbnAC0-4Y=^`frCZPH53ip!~8Ue z^E;M|40Z3W6#CR~Q+r971P@$E+)|IG&~x|CD9%x06fS@CR67JRQj)wd<(r#ll;)-9 z#>+aTKC{|Za!6OAF7xKL&W`oC=i)53EBrVa+jLTuXby`DFQ9h{8Z_i+Mig4(&#&?= z<%?d(o$ycfwNtg)d!8-58L#Do*pH8X5~g*j(RQAo-8|zeBKi9%GQ&|+qxl*g#baY4 zRBXzfXALxxrPc`ZrJNL)#(|6dK*VpqM`w2ffdPYZ3rM#o;$p8A$NlMx3EdnsnPTUk z--;UZmLh+`<>&=YX-!uW=&rGNvh&&<&GR;kf(w&)py)8;h4iU6<47R+`_vWhtM=)d zifV*h9A>`|0L#6Q$M~S;xIpdsyBu~IGG{Kwy{sHfi#_{mbH1r_0Riiz-IJ+1Kt3X1 znEV5c98=&R066>Ji1*X5>>t7BDvA4e6R0GH%}M`3lyJXspGK=YkxZuI!)lNFfXOSe?Tr>0!^gH8Re09`#)_Ey0=ni)sKY=6iaaO{ z@rG=cF9uC?mOy!%IQ!imYAOBq!2)Rwoxf*&0JXbIA!{(|0aS7Tt-K86LA0*|RUDvH zd;xg$G5nlo+7SVd^c99IgaLb_6h%jBzgGRY_5`?9_OGdYIkQ(|;REC7GxY^s3H@)4 zw(*$+K!fDx(||yvj_<>hyf1+$FULuNKGOn5Ysq9eM-;kzb}8)+(c&!-4+*fK)GL&} zAWI3#Xl;`!t0%T|7!c@*z!s>(LqGtiM^kJO)b+o*j3b7?LPa$zLAHxu!t4CPcb8JVw=kg}xRff~CFti^9V3Tii5a zt~?@^B^)n=sefezP+l~gr17{a_EIbGnsr@)j?>eD46#RZK0Ln;$(8&xpEpxQXs0*1 z+e=XX+PQG!^}8#q+(`+5Q}zdVo9YdtbL*vazuhdaAg0AJAEZZHnwI(rO*LsLxEk=O zhi20KYnNb9ZdaoaIprP8uawQ&{Xly3E0LO8oYH{vM#r*xSjL`G+dW>nNsWM^1?k*9 zp3$53#4&zXOBb9~gl0vNOr|TQFi*vGG5-BGnBQ)eG7eL635YioD8!d<4yNUwU2=^i zGw$|&u2C&%oEJVg6qfNTTX!QK3LtMtUQoB1t?xn)m5c<=k)`?Nit|13#uj8Wm&>V( z0Qwz(9-3{;F9_0*me~^b**3D;>Wpibx@VMAgc6q&VCz^C6v!=5bL5KFr!?Mu!%~+= zq((v<*ty|j|EbY4Y$hrQA-yCerpVDI=IYg%Mk7XbWzL1yT5jI9;+s~3jDu^_i?=Z( zmnays>sj|#ePDS;CDm!xQ}QY#hmFp9<7l5%BbT;&8Cxst2;BZYeFM8|EkpF;J}J&n zyjZ~ChAGFIh^XhH<`PYV@_|s5p0&zde$TnIst=2cQnyTV^pt_#sI%S@7NP4m)HzCS z>&n}7>po>EStd2giiPjGbOkF$yO|yQZa7ci|6ak>C)YOKv;#S$x`m)$+}cl2ZLipxUE%({zJ1|;m*Z`z(F!Dzs!fOIPFdS z=52A>{;nFltI4+p^&6qAfUXv-#1y`LsyjgUd5;MwAAQf@^ISA(|0MP%1BKXnV_W9?!*01HQ#N9CRz(Wc0J@>|#^kJ> zs*jPi3Lg)@tS}@d~Oddr1k|jyDSuPs%g<+#$X8J}>8^4|`eDOOv_2EvLTff{= zhNiuGsJzh2T>YM}7h$L(-Oc#CoSnUwfJLadMrsG#J0RY7k#gXoO-kKi97|r|M3uAi z-#)ZBKbteJAE&_*mG3Jr zaMc1NFbv!_F%UchXOKF%H8a#C9=IGsPt99-YV>!>o8OJ|2G`c-S(1T~MliEkCrIE| z+^;y@b9T|{Pfsiu$|uqzENk-#Ml~hzvA^-4`vaAJOAnznegj7mT4Ilh7-KYAXBCEYJB zKE9YYv{TX|2(hhm=@V?~z3=7(uSDwv$Y-4M3sPFoPY@WuD=apK49(hmUKFppie>qT zXk_yb9re1G9)yjvA>E7mea6Sp0=;h!!x7mPBMxCTaubWO{XR$YGDUV$?3(&hC`4czOY1J$z_>8LLACC zIGnD&n%T|P@9CYGr0P<%6`7|Elf5!IedD+!>gh+cN=tuj-<$i+;GSnArS+UGS)UMV ziGO2O;a=Dq+slea$G8N!VmcjlFhZ&-`Djj*1>Y$RKQu`=Ui8eykaqR;Trb39k|oV^ z1|>8q-hFTKnJtAczPx!66c>6mO=tbq+fkmRTi+#Lu0PtiHL>-`1bPlBgn2?{b^Sc= zZhT8gjpeKlB(<@IBG*sC-Mb|hS&tUOFol5A0h`^B{_JI^Xzx5b8aAIirKd?yEkHoP zCeLRweICQ%^-_Cx#Pr!Hxfe!?*6PtUmnei^iRT`srAACE)Cc*p9l0gJusC8a;MX1 z_m)T^kW$Ce)xsB{3GLp^xG%5jgrvULuvijw;mtYN1Aa2UAZhQyfpzz_mPc9A6agg% zazQSnw2ES`C^PSrPaZI>xx*OK;xou%u+gETes+dgY+dp1W3pWJJ~Qa{S|B<60Y_ufiHH-Ek7hSojp~+Mvi%7_t@CMCdS6K#0q-jcf8QtL`WcPy_{UcY?d5D-jYLjF+2id|}5^gf?RBm#Q;ohe>A^(V8hC1H)6nK5h zW73}-$O(i1+7DIg@XPU&HIQmr0L+v?TI`4@QC;vdH$1NJb(Cay7B-2 z_W#cDg!Z315KEXgH|sw)K1Xk>o)PuP=S0`9orxRt=L&1aSqq~3D*(PVB8zvvaQ32Q zmvh<&hM9*g=Ycbf=vj0eK2ht@;I%Ua3AOE@U|Kv`ymPze>$sL&{CQ+5QgOTQ#Ox*h z@|biDr*g>V3*65rSq}EhfY(9$>6QJFy<*}P`FQt;PUhlluInMky%@_H&ePMn=^~67 z{pmO5r6~L+b7Hn{wseDk&9ptaACTW6JB!ZqdnlN&sMiR-w`vtlMin!n>>Jx)?vzd0 zC&K}Mj3l;6*j1bmDa$k&d`UH;*)kqqY@T!`KC6TUCP*mJ8`Y_9NgTZ}mi~3gKVY#3 z`q|H?li2_Fcn+*r4yS@!Q(^BLZpYEg;BX@Y{3|HE;N-7b!I(Q|GVA#09ua*Kw47e~ zZ6!jZ`p>T0w@(akwFSs_PTv=~Lu-kj!*WnU1L0LGE)tpCDcY{!BOO$n3F)5BOzJ$X z%KHUNf$MMK4||utEG8r~WclT7o~$Y_4{HS}oJ<#Kyct={If6>>H;wdZ#cKzwyPX*lPOowaY%~M~yw{xiBUg6_$<>!zsMir~8)^gLD=`PD_`5wwyk`)w;W^ z#E52fGdUc=NHQng`hmGNv-jP$+VNLqq4!1_rn@pkN0bnhe5V^XQ?Kh7HA#+b4#-Ll ztS*yw=9gH1(9*7%Ao=Am%iE(BiMM{zNys^=4LX(CerL{ri#}fcVQrg8rYI$MC~qum zwN}z3;eUL%xO|m4FIzW3)+GBVqy3$RTX0R#^87Zeg};%J^-*(K^2WiZzN>YqZ3#&X zfrQ8}eI5=j{7u1G{FR+RTK`{>Zd91CH^>UHE6)*BC0^nOmU$5;j|};am1homP8lnk zu&fwlMR1k$@nGj@Ncm10F0ubh3gL}e$nL(!C^j~eV@Hc6DIh}o84vIWWPSFw5&GMS z6gMS3Yv-eLv!dv^NU6wbd!q|-Xg%Ykt?GSS_scQRzQF!y4vME*ke?SlcDccvIU;c1 z3Ult$CDQ;?Uufp@uF*pF;_(XKgDBN1?b#+z_P z)Z7Yt4TuV}*^gANG94&ihGsp9i5Q#YF7)}T!&baOanu(>0ujVl zBtq1KYmvd2WWqs;^0TtH45wJPfy9vIXG`zEc#)=)W&Xs+V_47OtLHCt!=g z->UX1uFHMy0X(h=CTUAq?h}&5W&xc1WL7(y2JG`wraaIsINtRyBdlV2e0r(liEj?m zDH_2Kg@_&_F{c(d1ZGSv*gQMLRm0*XcKazlyI#5#^#I3jzsY;Lxs-l9<{*Nz2bc8? zv}3qEP72dfnhiMoyA!3x3lvIrw{%Aa^?vrUGX_hFu^&{Lagv^{SN1cv9}i#_Q|I~p zUYQ-%H}q)~=VYH|xN@1PwkIxKqn;PF>b+K+Y#?C#Yn)8Q;g`*T`0H=bwL_qq(cS&z zKa15Io8CH-Dgp1CdJGOl^;hOtKORhr6j8bngck>3CYZ0++&gZLjg$N2R zXA4Y2Uk_3!*^C<#-LG@N$;lG!jFW~K(FZT=>M}VbK2Ld$vIy);FetsC<|@c)2bE;{ zHhiH;p^rjrIGDrEQIwO7+yoGR3zES1ugZp~V;JtGV{&;(l=+=b7dyoUES$h>{3g3n z9!SN5{x+%YcPW|J?Im!gX)?;(C>hltxfwF4w)B;ISnIb}@Ta!?3I81gd)b&=#mhtF zGcd0f)w{iK*TFw1R8BGAentLZcb25BlR|Kk)C~k6`9Po&klkK0QTUUt5W1>^EWE~= z!@+$|6;bcb z!T9y`;|yGS>#C^;4&y7!;Z)fVA9M*0=+d$;;oUQJ8@)b%d7G>0t9(c)`WNyrzT#=X z!tT-*0h=7}7MQUaG&8UyrNlCC)2MlQJm;ij&J)x3tNkb42&I3>hQ{vZm>G+g>XpK| z!Ul3R4|>-YwCI0i*pHoV_s?xTsBV87;*9~KRcBM0H-)Hdh~{wne&%Xh0Sc_2d}^Oh z_EcyXj#AEm-eQtpq@FyV9?B}Z23pti~7E_pEWiJlb+0e90 zNjK!q!HAMW^%0>Lgr|$PPZ-*%H zrL{lh3;g+z{p-t+vKM~UlSxsxq_u;OTiUtNeryiE;)HbD=Ziw@*Rn@~lwAG0xowhn zoZ6OoJ%*#?cu38H+y62~DNoYd`k*hoF3GJUzVBRrV*|E$HI;ow&El zCB@lE_BoLHXB-Y^|F1&_Pd*bT>vnuJ5&+*Lfc2aUR#@nWedj@D8aR zAP`6xdg=T%5NNY02(+nin;`IHF~L0w__fLRn#nm(X}8P_@I}DQ=!y{tRGzSN?e-7OnGo7xfYTtFc0H_-D&Hy%1MMnkHOx(3ZJICXTI_Q$LzLYOAj6-mXZ z$;qj$9ki@OEe%~oiDb!d_z7;g`?7$5%(qPfp9K9TPdG#u zUD|i=26#uyg(&U=`OQ)n&@98grG8}5YFJ^BdWc2f{5%=iKNn0d!4=kJ7E()p4QY+> zrv`QcGYrNU!D%qw9^m6<0R`aSEk@fxppR!QH-kVYL{oqVyZ$_Gu?;7c(+Nt7IgPq{ zA|TMMo5JELV+86P^JOJC$=C+(n54aCp<5F6Hfx3Nm1-Qo57GVc)tE+x)tujbbDh)c zx(NizZ?!a!WT*+#jjY99oC)uLYP2a7yktrTx$fbS@)_f zth|E!;2G@@#x-U}njsP`!e)F{zNMGFs07zrb=NZk;IP1gto5$>&vlh$iAM}WkbVs# z!)m8&>?f-TtB3`pe}j9(8L&uaeqh`Qz&$c{Sf*ZR(wF>)8X3F~5ZzO!zV z&C;l&ILKm_gKv9+mex^m z@#&@!S487S7W1pE4oxf7mWV#-Bmeo2=njr+VZ;O8=`YeVeBh#$IGcFdr`$nY9hdGE$i$y=}bFiy;qX zkzA?X2nDZWkwM(6D<9pupRx6SUg6sthKvjQj9KA23LGt0zq=7sJGjNdhE|S<`4G!@%8Mc1FZP_jtScQ(V<%k^ano=ZwGN5|Jnyoy z{EH}IXkmb*9JW57@Kr?NtrYQM2MLoKTL&_=$m=h;C(W+3HA`BNRP?2u zl0NL^N<6S?dUwY0WSO!OhPPAD{l|1Y$$>7c5=a_i zl$GaEJ8`@A7Lnu1+iF96Htm&$;tyZ(A=#9rt2?cF>aK*l(|-0i9u`8au_}Cqmzw=q z(fo`txB&=}^==bdCq+I<#VhPAK8V%GtfnIm7C181bjL@EXiqii3PWxPyIM|8Z+Tta zV}-Kc^+q%bVyJ=aRs5<{I%UM~Hz#ukY-;zg$$GsxU_T>96-4JiFm==Xi)8hNtLC-K zlo|A99d0MZwM82NY<;b1e@-pb@b{4K5Ubjt>*)FKGi%j^}Vp zkJ^5XaFW3It$o^NWjp7+4Jz04X7E=1{mHKIw};|Bl9F+EHKJ8zeP=pO%_{xpZb~XH z?$Yc%thC9vNIpf6?lSNjm*psCH}GuH9+b-O-CdVGj2iGKJ?pZ+#pAdS{J`(3WiVU@ z7OSDd3oFTYb2*g8i_m(pd1=X2P00n;DS7Uxls%jy+NIv6$}q)(O7P2&l7KF!f}r6v zyr4tboW1Lwlt<4_-Lf>zV-!$~Wm4Mw4$@H-2X5)N`#+Fv(cy8-EOs>Mt(ItHp&Hige1(qaDE;J zi_$Fho`!RQLH+B~N{fS8OE;G^z6S$CnMEW;<%}o~%^vRV0M9--^iDdza9FzHzHeY# ze^(JOte*Hm4hlZr%!s^-N)(8P(=84uJ{+bnzN z05^$%UztAsla6+yP*|(c^q9D!=ls%^_0^Zkp}UKhmWmbayUU95e)<0ji#ugS*P=Sp ztKV0Olv*Hn&3IkU?s*JsGVQkFyPV&74rhlQdgbExNc%o2TpQV};q@_h-+H^G%$ZIe zDdOS+2)0WsF=$*eY|&uoJnp*1Z_J~&lqB|mq0xz_vQJr_1M|2qqr0IZ&!PGmRN=kI zhUQRQjz7|1PZ&o9hQeC-_s?)zAqmwhG~VM;YNryv-^p#4Ga&>^0WhKa|o#;5fki%stJlNfVu>QOcHgF)`t)#5VArv-! zqtSfIXR7W9uMk`9BVTA}v1BMzhe&l5RA{WYQCJudzW2ob7TDDt1*5D_vS*nOlH_kJ z*6M#RcCU|sVxMdFB-k5MldpK_lhH$L+K5rvT4PkGbbU_B>}g>(Q~PwLu1DM%gD%W{=+SDRts6;ztBr+NN;RN!!AFDq7gR>C#Rt}=* z^?b)MY%TjT4{g*Y1(gVN{kBSJGX*$AbHXg@3|oo;ke_F8URYgUn6qaaNR^{8iNk0!L0Z zf_cL{KWHEQMoppEsezM|_)o*`vc`pwKW2C24b=@TldyerZ5^9ONmgdHZv=M1ciE&Y z9!wc63S_MI1k~F&RYY7LmU|-Zp0hx)xeS=!Pv75QPJ4cheGRL&?luUawhbaz;1V}R z0;c(gkHf(B76F#vk?ds9w!N7$H?FUX zyd?phj;gI3DHTfp4*I6iQ&td#SIqPnVFu(2-3ZJzqa1;K`jVdD>HGoaOW(fx$+*tk z%1H3k@DBR3pY<>djg@>ui{O?$_pwBX-Q3skAgh`6y&4MBKplSGD46J7;<;@)J)e#g z6hsjs%I`N!_j9xGc;uIyqQEA1OF8E;wgOvDMgCj`T;d#4)M|JjRL?`ZO%uYeD@Fvq zE*m5^;4zwGkYa1#a7EJ$CSE6OW3XHn>CD7*t+eLy)li^A5W8ZK&S$k18-9v*McwUtJCQwxx&F1A&MF?f%i#zqC8=>8M^LRpjEU^}af&?-cxWT1Ul21|52DqLAQI$hio$~4{8BSh`C@X75I;)2JFGJ z+f0pr3~Fov9-91R!E1R2@Vn{Lubx%uEm1PN@-uCuG#o7sLw`(Z?uDnf!MTQd>W=wp z(8-_z43X}01^V2KcT=V~>UcP*1~6an_XAO2eSf3(i`1ph?QvBJ+X&|dP28JuF8CH; ze$L_}a$=hPy-1@SSveW$x!lYes(}9bNBcLeP4_dDWpkHp5J%FHa=gcG zqEulDKILK%O%p*thL8}8Jt}ROu4A?$1Q88bBN+wjBNlXLRh|P zpSWoC-`zVHc9pxW$L5}nC-qF!Bp3)_&V{V_;DAJD(6Gx%uJS|9CH`W6W;fYv#Fzig zwoH{qgHefWTW1gx)M}RSR7q-4C2_QAd&^GjmQJ5z4Lg zZpN>JGOo}$`=p1pq~#L`DGZj0CIf%xj8nO&yChEo$4gX|=%ne!s8 z@rRlMFykHS$b57*V~DqL>WW$icGepVb6dQeF?mu#9hbnlX} zW@b{AelJq8(%kG-SDN1)meW16BwJS0javM|J;km?-;}Beme5^K*5+B_L;t+gqonw5 zI;P3(#bKqUD*t2;+eRa=XI(9CfDx@NZ#D+|S2?P6=6-|Mie>7LSLxf?w`b={UxBa8 z)Lqo|zA_9&j8HT_bvRMe%OiymV=y<~>^G4usg#Ln;f3L)3=XgKJp*|N-p5sVlKZ6B zGxbV)iMd5^(RR~q%M-?`O8yXa0EO@G5meyVd-*=K+^2C|@h$ug{_YmR__`^s!K;LY zl9L5YRzAP6F9f#TR1$4p^XAEBRH%{==EPCE+wg_07^I@KHUth-6HskS46$ZabvlV}HmQ++2g2G%+-+*|nKg%o%jR@m4yi6p!I^ zmd(qeDVBf>2w?Pz#h#$k`F9yJ(8{Xk@<(Kf<|=q?Cvp_$CQ}mZol4I*-Ih+t8LU&p zFUHbKu=I2_3422=uVO@yo<~A;Yg*T&;`Jg_HhYj&NV`*ZoxmwNgunz8RL_L(jageTVi8aH4Yi7;bQ1PNlakNQn8qS-=2G~^ zxe6MaDQVDCX|F@0&bHub?7@JCvM4&{TLHDE98a71V9>wcUaQhKoFob?fA|-giLTDI z=+SB7-j1{L8bDjkm&e43hZ*wG>fw9$%NcFIu)ZuBg*N(G5v!!+FEX-f?>kQjrmtIP zp$Kofp+^v9wZ#&d@?m3*nDL10b-ReUk|K|=b%Av1VGV2xT9oX)w!J|=zt$j<7J=`t zYr(Iu?!frN67BT(J&mcU7U@pWo&JJ7OK#&!zVseMqwsHJEBkFvi8j@Oke(_O*?^kl z{kEwr_UumA#2VPUy;jST_%l2F+b5AGmgf>7hWC)qMxBZ(lp>Op*JKp}AN5#llX^As zEH`B5Vg1KX6f>%NMmmfvq*f3;{%L9nd%CrAqA53*PgSuyhGSvaI1iH`8Pprr9f}w> zIxH+CX!JIf=}QG-oAw8g|toZxFc8@Ug^qmT(prZ>81fNC@q3o%TINGjX`1$bEN8te&}f0rOS zYhfD4;y`+5f^bpwM;E zSnBcJBC&b<^!OnUsG?R`srU1%Vi$xR><5Syu5?#-t(Vrto==DCkS|s3AwQIy0gXy? zHn^>NIBjvICSnx}BPdXBjdydy4Az%j4d zfi)JNO%}u`xKBn6HYC+;jAZ7ZbMuHa;`6ZAppuG|nM)iR{9dD!aNiGD9ueTXR%*EdR_=QReU77u3`$YTXZ(~!K9m6kbHO`3Fo zOpMg)JJX4_xzIQRrO|`#X@jqo^1ExKo}b>uz;oxAQ`!W(VFq?2j5Aun84D>O2afuu zpIQ2LJ<_$=Tf)uKhXK{7FCMs@*Y}<}=Akv(Fqpxpb(OvX9UfA{lQI~^YE-Z<5@6E( zeGe$TB=k_tmNC7&caK#9!go_fSXRV}p4kekB&UO>)AgcN_g}ih6f&K|!bvJ-qdkkK z?E3Vtr_D&te7b9Ah0G~&532)mf;`?q)IJTn!Y-*Wq{a^#)_Rs^$y2A#&|8OFXnvXL z{y5{Jc_iHj5JkTH(4j5G2PekA2?gA&@$oT@x!ltqA3BwI%QoIwd@Ikp#HON9LFCM_ zqlh4)y-R`t`^A+^tq!sUWb_~VbuHMEdHShe9-)7=2yk>lbIsYdr>>EQbe8TbXUz_^V^T zqqIMtY?n!P@{Cy$Zg&i|Ng;jMgD*EVhF%EKiPF4l@i3-}JHxbaM-Gn(Ul*46kz`Hj zBChrWQ@5G@B%RX`vaau~$mnW1WsPorHdbAm%qv{V9L=!vwam2fZ|R+~@~U0(YM49E z;a;IJb{35K3X87<^R%LQVJmE-=>d2kxBfEcr0@;=>TF<;gL_t$0fpeO{MYnto19;j zDj6(%5@UXk5b6BYSLBKt4KOQHF0m~?S6V+;mqYPVmI+K0#C*1TS;)4{c>l|}`p{=LnO{`!x3 zHi;t*Og4=i+i+JT$ns2eUrv<}tN|Pfr)-oP={1?qN`3}- zaQXLJVt3q2H3=^p!isr8>X#CnDu6lEMm3D# z*Mb1a2g)l=LjSZI81cL9(6}`ni!g6LRrY-`n;K?_gS7f{s-lUQWTgILP%Dy4>x8g| zd?yCW5ZbEy*%5C9-wg&G-GA>IOEl%i_`Fi>i_`Ihw|O?t7h(7rU;gywH9`~_A}-3d z8n3C8O?lDi3!weJKEj>pJt|*!z46LD@a^ElecK&`h7#OlCvK$SfkQayIY9K^ysHC3 zLDet!z^8N1%`9JeZ@g!P0}u_q{WMGSe@Gm?Ur+2N>w*9O>W}|A_&%}~qhOY{OVvRR z$ahI`GAV+`H&R>1v1G9nJvF$N6iEp>oQOYJ7h0(x%h%|46JX@&4zg{h;9TI)dATdZ zav1BGIg6!u`Lv4LECMGD0#Ad4O+BGf&#Ko@;-_TxoKLp( z3F{(ftp7}3p2sefRfix#W8;*4^};>J1k z9bg(&%^zGMkCsG=m||3nUz_XKXG<(TtHv;zfR;tW&XfaefKZ6RRgIv;Xa$v{@HkDS zR0Mn`@Of3^87hjZgczWBtnYux?gd0zkFZEr-r8VI*f5duG9I`kaBOHW{95)e>6BnE zN6oyK%kxLK^49!5T-JaG0OG$R$mfuPY|(F5FYSC7n13n|VGowk$c|5N$C+Ts2^;VC zPi_>UkG5<0SW4ZfIRot9QR(9w6z9vSe(z6!wF) z6{G?G5q?b{ZklwIhlCKXsB94ejU&)fWF~>9SS9VCbkP$6?F$2i&e| z#jdE+Qo@0!?wcOb(Y-*qu6HreX*eh6^Io_@DH^N!Dyb@@9dQr+*^^+dV%rU4oJxyb zV!+LC1%VL1tbqQzUS)1e+uOUjU5$d!e!|dwH{vfJWaiY=G$kpnx3Vm99gmptPf*QF zI6z0o>3-u*;uNu9XX%*v*bswe&jq3sMMpaa5j&5VWeI>Xc8iIpEauTHVpbbMxFsP; zrWTXKrPSM|7MH9;PTZZD>|1<%w!o1;cSg2AvUA6wBYkO~gdY3Jgn6k+(52x-ZaUl8 zVnk{`8ClNg>Q7G)pGi)TU1TvzQF1=b(@kqRp5^Smgz*8G6HL!@7Trgv65i5iF;n5& zlvl$m_k0%&3-{)&J&;}sDlX{`*bK^V6WEHG>nP?@8u^|Ley6ULC*K&HDLq(Ej|79Vn_z4i;~JmoLz^z2@yYCi zq1v#ALeYh3an&}B>Uc!YsV3i|66&9^0FN|i+E;q|CsftvRD5<`a{$EAt8$fYfwFpy zjwe{9ItIPF37(a9-#LKrv?(67Xdhlxlg75^*r-WR27LIo^_ux;FwTy* z%^mIA#E0W}m8*IR; z2rCli=H+Y$ZI=sW`<{@cTu8|H1scVi7%5CBT{|iX1NY+!NIy2Sv&ZY-_J!UfiHa!2@pfumLh%9_v2822M^jx*?N?G1+urWTQ~ z(|0KMJObl-#6Y+7E`JeMxaD%&b`$884J_IFpMfJPF`Sg7U?#X94BTZn(XlZWP_+RUVv;*{nljEy#pPG& zB?c9elkQe3WY;mA2rChi)3$G4<#`_XROO`&x^?v>C%4LzqBZ1+8=Z_%DSaoNG7P<* zbTkntc(M^Wx11TbDLNKkcx_UCj&B#`r;)-fH&GtaitzePpm(>OB9cU)(Xs&<4a`mz z&G2g`H@nUct5+$Mo4@fl|5A?i&dK1$Y5uIcI0NbCNkvt!+j5V3YJ)(UU+gWFqmP#0 zji44eP>R98$9*G6Uk0@DP~63qY==zJHgjw*J0-q1I~`k~ICcK!GkSq%T>eqU*n;%1 zVgRM*rj35$UA-Ln%BnF^MdJi#p4!d5xSCJ_8>;B_KS22k-%5v9hu{pvscp3jq4uGu zE=nl?svi;~lE$u)&*n9KwoyF_U)pIJyqB#Q1ZWMseuJ6&ASh)?|MJZC{`(?rs@cyo z?Os5q;U7ENk4IIEsmN;fW7aAnPu_n{B|~h}1(Q#ok>V|_eBh>n^(8J(^}Bi++wUD9 z$f{D}*dhf#}kO7Z$C8KzKfOU$>i^^>kF z(jCvh^K&Pndz{HMts=s@OaP&n9a@(?`b)Y+T!A-)(BA|agtqNXsS35NIG1E?W%;VU z&)SQQ6v=-etz#_gnt7!UyM$u@IrEYhhQGUe{U+lQy7fFP;m@%bkp0I1qIZ+i)lNo=7%Y(ujozz4 zTO!|@Yh_2}pC2ag-9P25&y9n=0LY$G*9O^p-!HB}&m&~CfPncw%DxY{noZ1&+D?F; zol9ZS2U@9thV4JG+8MvE+Oqt}$Ja>*q8aKTLf z&JQWGR= zcWb@noc+z$fRM5hQYavU1)iOL_hi$j=;IQ5t58zbNddS7wgsiyVrIV+zM%lO5)Mi> z!~w}Zu8PJh!u8?`Ugx{jn-c2`gSPEh@u$&MyF|F3rU0Ye1O`y&FG?`6J&=??Om0co z^zoUaPZZaf9gzK!i$O>$*STM&3x(ITU;LD4W2x9q`6S}|nKaLG>`5T9%CQfI4J<}h znVuSLvojOZK%b8{_+zLo2@dc=;k_x$B16mvQQ^Hb!}a?XkQMP_4+AS=WSFyOxhIsn z2;b-;RFC_no**SIOa3{r!CkjVn^}^Wf5Oem=zU1+{kczajc;!F+ZT-}E{|PB-1>a( z0@DB9T<6t!pK^R67CVoQyIvbNzC7foT;YKi9uLgFQx?~&m@NbXMV-Xv-Y6(6Q}WNt zMnRwm=@~02Pej4^AwtqbbJK_frt;udv2zahJ_F7_mBanvt07{tK)VwbGTiL>t~#zf zH>H~EJxU+v?&~kW4UpJB+{NavOUZ*k-?WT2T>4hUbD-7`|0_T2*wEA}pZ}BS_HWGc zf7asuTe17Uy!^k9|CTNP*Hr%_(fMCf{YMepx+M4fhKjwfS~B*pPp&BkHWHBNc2hi% zT0o9}ip-BiW%yScbn?T;QuLc>2g1XRI&g4%^TAUy3AT@HRX2ihR^Ybi%S98_v#R^m z32Ub|Qbpu`!9*zPNz-jERIwv)ovBV6w>CrKUCnMg{aiVckYbV!PIc?nH9-cA`u7@= zzqd-jHl&0PUxAK)I@8NhDiB?`$k3qfk$c&MXc1uxbZEs0>f2T3ggQeninw`(J6pN2nEf{;&kF`Q zRL)(g;C*VGe3?uIx0j9TXK0{AUU}Xy8BU5vakYaMfIk_iFAK>Y0giHm&~WCr>lPcfvAuU&^gUO{m)uTU z>0v1LpjUUVBv|mAPZTWHIM<%u4WA6Coo%=^x4mNRh2!LJ#kIvCpXHkah?ea`e)BES zQPJ@R)=0nKP0Y`UCY=)|@@f{fC#o1vk4(x*qy;$mJUhcLPw3bQKF_d}Uwtua+jz5d z$XP^pVst)@i)W^u1HJUk8L2Td?$W39*D%D0+NLAI&_<(sU{&!5(st=iqe9NOafFj@9Xax~r;wbI zMUCiU%1&sHoPUZ(U=MDtzHIgZE1*UcvkBh*I=U0bXCr722RNm1(zJqdd&IOXxS;-l z-@^7*taQsvP#;7IH~@(QQpCq|J0mV-w_6wz>KoQ-wPQo!@^&Z&v?=R%ukZ!p{5HzS z#IqLHbmO%8r+L?Xjb<8%0q+}$AR}yXMvs)m&1mJE{VWd{Om%RR|*_ANu0&IS|@ydd^rP z1Nse_v2pV+#0F*$d^v8gEjALSWIAOlF z;7mPdjQJ%=fw_p_W6$v13CAd?3GK-?2)FX|(a{x}ItBK_yzH1-ddMBtDUPa$SBDzp zkb6&a*Eo?CR3MLZ`rxo&?Iic9qR3`6fH1ahGy|M-{0TQ85UwrNEWW&QSmNm6X}N>y zSxf!5%qL$P9hX8jt6Y&vsiQjns%5&IxwGj9#tfVoou;0yh~f>na?92W&twP91|m(m zf%Amgm2cOJ_?S$=^kJ&WjxBM9fw$X*3dByISouyChPHm6Oy9ma(LSG2fU>Nc&H-*I z0d-8(iKjm&MpPgNE_WFq7gBi_x`Wa`+lZtIXR8bN9!@YSRT_OA7G}S6WdA{@)$c;I zjsZMYG%3eN&Kt|9i1l#9b=T0+-g{qoFCD&Sm3u-da{O2ZwoTRHN@t!?5z2D4Nd&p^ zM?1G(M;c9HuCLo6%e^Bn=_j)04fGMzheJ{;v~-adHrmB0>Y+ZIhEe1$wk&2&g5ca# zxV$Z*MIBs!IiTi66)zAK2tLZ2LUf9ueha}b)y>-=FW~1#YF(b4d9b!%fO3PIqvw^x z&n2*BHI-V=+3|Dz+GPVbc=bk%>ISvEJ}e=Z1=C&qfyzq45{HC7qq4E+&j+}l)6j^H zU{28D6ZBk(79G}zf&H9gIbu%e{3P5DVQQAW+zBlUD;dE}=lHa)bBS08@A^v4PN=rN z_PtxdJUVS%%=`mCJTRbDX|-(3FNdI+E|@K4^q$#oA7}5g2R9b1@>dY<3ClvZK!N>L zg6L1k9+tN5v_exYoYrUUX{i&OqzOE8Jl8GGWCmD9*$MH8Yr_>yOGVqv3{N-seK}dd z;~>jKlf3xtsFdp>y63%CN2Vtq13)Oh)(ZQ)1U~A>@Cd+H`n~sXthZh#*HxrM<$h1I zU2nvEHyf%~O^>BJT zla>IXi1dUIS||yD_u!0oX5P7Tzuf!#-7oJ4LQZn_*=w)8p7pHt?7Y*~RAxEJbrJ*u zv8bvj=z>5;p&-za$BgvAC-GBdv%tS2Zo10yAY?Dk5^!?2!R9(Ggw-6;Z!w>;;M_)5AXO>nP&OUQrr#ONA~i}nh-`9_;iLfQe2KqEecjF7y4czGvYrXB zfVuGA2H*+zod)T+=d$>D7gF=x)2m#1+&Xy?teo5SweI^)t`qpsS%cvo*Ms@uvc2^D zxv&tzY`2Bj2Ps>zI8hF#_oH1aAHEkdSdWPlY<}X;xpsTIrP5k8O$38&LQEGOVzEsI z9p}BF=XsVB89*RPI{n9kof(tfFNj-xmp!$|NKDdQ1# zH+Xj_B(2JMexT8{ryIws&6mWQtaz!MFY*>(go@6slJ@J$8?`x~7rkItm%Q7PY_UKs z1D}39FbD!!=C~ctdMqFFofk0#v7n@y26UOZlIDwDo5uCa4!~2N9NoGb`7aMT8((&N ztY`BxdG3Z)ci?Bovx9Z2eddDgb@TU5BS4@BPd%iN%CG_XQBGlP~^%eCjPTR5c~O|2Qool{rrvX?Gr27wlhTDTBHIt;|i zZdjSW9QnP?CD1O#JU(9o$WBqIB64WwIMZ_L;8c%J_$z05Z~ zK9@Tk0R*P{JQ8IgVfN*5UbnHt!PZQH>uQ5V0^QbR*QkMp_?K_3`_Hv0YbG~I&A76> z4f@=dst8XMgQ_z6m_}6K}KKv1x+oyocR` zYBugYySG*EIGaM<{Bh9yjrxfV1d6a0Kc1T%oh)YCvlqv6YsqkT>&|vUtVBKJQU*MU zr+zBH^($m5o)&e_;8MgvvfHRL`(&I0o^xv4QLkk&!8sDDd*rvS8oWEc;>>i=ukALg+YE zQz4zsKO!mQ(DVW$a_3gWx8!iL>gvw^` z@DCB0LyDXc2vVOce=Sq*u>d}iW*{^?rI)G zd!C+4AL+IRdaCLARsF)1s`&V5NXkN&_OhDV*m$&IK1H=tM)MW^f&Hpsz61km2xqUlV zKMn8swn~z4mnA}V!syl;yy2~ZSs(b+jc|Hl7TMBwWq04+eH8rVX=tW#;`c(yj&H4% z7gEk^T?Cws@8-=7gLBLHnQA+p-JiF`Z&p8Xd{B^LOX>MI-P%^2)>N;%%I#BQzM zp7#^JDbh9>upOY-h;D1_Q6iLYiKEkBm}HR=&E%S3lNQ>*{v*O#NjcYK=Znzw7u5j%Q|~s;+>BuPkxoXKt1)8M#^pE_PvRcq^K?1 zFMY--#8Sz%waC89pNqYDonRAd)z~?_fp-9sxaFfM+)Fn_!DG&f+hXEk;Hmg%or{hW zliMSn&)1h9{fTea;jY>u;SV@pI2JPc_!k&psPxQUO5UxRh!98-PpN%k%v?5oMV8v zO5*;RjbJi!BKhvk@e(guKX}e4f0ScmOy4&C4qcr$;=_KitQLPd4Jp^K+xM!z-R8?= zJ$Bx=u-Gk$-f4jRZnvdUGHQmqk8O;;{c+#!x7yRr(K9>kgmtnbhJURR3m>EHViJsd z(IvrUQL&!)NGM)nS=B8!{<7YDzlB#TCePOBh0*1Rt48Ew!kI$GjoH>(3?*t!pfjPd zUfTWGrk7IMC+K7CE= z$&b?ktz8UsWfQjP@cCjjrukvsU>X0Lg|J^d9f771i$S>?-5%}ZB=32!l2h~2=Jt#I zYs7Fz-ykg4_$?m$mwcRz_*;vMt!BX`u-Z*ed zk%Hg5SwB)!^@u?V>w~ZARJSE2jCy|Vt=}RiAUy$yVAd%q2Z=Fc?ibmI3s~j(ZGLn< zcLrS#Pl7^P0Bk3HVMN)$-zQ+?+1u^bbX%>^k1D}0H5sU9{rDMsqi4<9hg?~x#2+s9 zda%4l0DONTqk8J1&TqHsXE-ugCd(z8_Z3rbXp%WYB5wa-da0 za32SkXklZQ;@8l91wPc$i1KKwv4qVv795_!z|RmGNU>Dkl+wo9`cVC8l&J7*^h5^C zzhJIDy7ez$KZ?qy8-2pD#8Hl^s@r1>q+J9FzzU)A4>H(km@{DkPg&-dzCN9Av$&_HniIDt$-MfZ5*7q^C18B<%=1tFL$DE~asrM&CL$Mmtu*fR!>#FpPfK zLW7F)TjXTz!U@du&b%XMJvWvE&Xg2CJH4giP7JyVO87p000IQPRf$#jNB^b2n95_kF(4<@3uqB0CMgFq1>YIEIv-5V`;< z2*1WzOCEHYmhH{Yh>l$`DLL0`5@CHTSEAW+7NgZ3vVAur0IZ3Ep&#FcU5{yns0N+_ zfgYA%!yNfv1}rc`*-wVZf7BKcLeHLrO4;@T?F*+)#Vji{?=(<&HVXajVg69L|7-cB z>R}dvqDNk2UryQ+BKtP zkL7~1LYfMLZ3ZvVq6g&rH*^@%vF5(TSAhF+{{6m?vZbR*hKVBK*{b5?yt1}TWPv-;wY_dJHF z?OZc|dXVgc<8+uB7mj0YE$=dW?$*APR?|2q%MbtQJr`$i#-SZ`NmlDL!YB58Tl(X0 zTb`^6y-mO6%@HZrVBJbFMZ(vDC$)Izl!PrKF}2}aFwVn==Zb0WU#j-XVlS#w3BP>) zbqciSZ%{FhUa(1hcFCg2hMkRrl;#R1~XkBixZbo0a0qwlX)$R`kMGZB zXGXNz5(T;K0`Sar1?sh_8St`?6zkGVa~PrptJB!OXPjnaQOwqsK7I9X_L|K=`A}kz z&OEw@J1wxqmyhCHui1?T8#(>xER_64XIQCQ$iLc5KGyZdNtXx*UDeN`d18zE1x>!i`fl3|o#mroeBr+usEf^;v3rAH%OgxSpEGp(iQ6i^b^84E2R6j%?{ z(dW8nR5q2KVn*fuywg;8!RyfZ^hItq%LPz3L{{;CtLDb+70ZUF1BzeVpU1Rfv!N|5tyGhOn|YHkU5@$&thR)O&$ z@)GAudTJ>y`N*|oOrQ8SK`6sF%db*|>%q2R=jla(TyYrQE;Oqf;}4Zw-(kCo}=Ti%e+$#^}St zw8dHU`*P@2J9!&gcIr2h5A)OCp+kB54-@P|B-FI=;(wmt9x3X*SO(;${E()w0hU&H z!0q77A(M)0TiU3PHNAb$P9Z3%=lx?}1!T6u)3d2|F6ht)k^@gNrhqZ>A2&^0(iRrM z?9j$@)V)jpl3x#7B@G6kS9tGZX62z_xJ*RBKVb)+6U%0#CF!%;qFfzWi!`#0Gba}np>zNha8_!0c zM$1|+4dg}!>q;Maq7tmD2n~tROWjCT02HiDTV{Lh8-n%&IjUt&xT;AOXxeftFv){H z&azAdtE#c_NvM^->i7Qa68VpJcXmV*4X$GN`p<6!f_fU4mjEwUtZi$#GeLfs|gqBu*iE{{rtK;mmMS5(%j?iEGI zr>k=Ueu)$Z?F?q<{l-K_(Mlh}b>orh29IIIF5&oLdy7URauku73dn5}Ma0Y;hzi|@ z6KW0bb8^Yj(8uT`XT6dsLQn#IlJScx$3EuiA&(K=y$#Y@%@azdph{>*>7JWFLvQTF zAS~`-xDMFR!jI7PeDi!5x_P(HVWyCYPz>Lt^b~qJ@ulQjXl*dK$8{~VmOyyokuhCSXAy{gDy?Aw zD1eS|twT+5@rDya?z2Cee%Mbxko#AP{%_s(-=k&eFgC8m*iA*C(AW2iWtn<$ zuB8{_u%f!_X71~z9j0*84lcsbb%&}9XP*o|g6FX3pa&i3je_TKVe|;%YLg?2I%cLi zvq4Wx<)b#Egp%SFLypU~{wmZ@JxqiaCL`7FxtVF0b78uLL)#WVZb!8T43|}=*5c-j zdWWl!665I<+K+&%I%%H1EEe2#q?(DJ*F_YG;d9W6A_?0n`xgQA;yV0rYO)<{EHA3= z>1d6X0rgW~{N&|wStQ)MN^rN~SbNLl`SK!LZU(9pe1!&2(*nJm{Gks~l{B8u`c&c= zJ>|eruquxvQ!eDK2F-r1rl_0Mhg~|g=>DVOwiZ?OO_@RmqkfKc(1VfahAr_02g0Xt zT>jQW$#JgpEgnc>B!**q&hG5CQ>7FcLcKdXQc}DN$Njk<~Z zZO%b*MrGz^HTD&lE7O{CWwq`Js<9d7R2>e4Cp~oH7 zi#2adsXG~|*OOhi*!vLU>S1D#h7OqWsKxhGd`9+{d7ue!j4RS#quO(rO1U|>bl<|4 zmJYAi$CM!{USn$wiQX>UpC^Y)%&>OSM?kXKjzKYCR@DQwYGX5^o6x)VOVh0d9(OVu zCh=If;O7($@>Bm6k$#DsXuEE+S0Y~(J)`gmZk6z%)+5*OmuZF_b?E+z&l0697$Fg? z&^@dp%~{g6s?{@M8T|a6Pv8FTSUxo(UlwOMmV_!IdV+m6(2|cEzgI>gQ8K@mX?6yY z6|U$0Dtwe9XYsny^_?C$7Z=yzb_c;O@BFXn7=g1@OkQ9=6LAKsmLkyxMiel6@n^N7 zsr}WGN>~GtJZv;*#mR^@D5BLKFRsSbnG?1%{ja0Nt+?A8#{4fDw#%AgN&_3VmcYa% zCDNmj+anfOU~cUL^V}-g`7xzFkA=G#fUf`15$N!o%3FYQ72Y2JLgUdgKXd?j?Llbe zxkJLBT=);*{!_yrCW!xQjyawSRXrJ!h4>uhU1%Ktq*QFUo~)F;+p}nGLB!`d*(;Se z-vL=FT=-X(sSVQ2)kEkOTx@k6zBlFj3O=dSEZWO++;BT<^>iQMGjWz?AcR42_L1V%$r z4pR%r_3!M&1xONJ@&A@KkcVl*2!8Wm(si*g5Ai}szY(8_Q(qH{=X-FsBcRjeWw&^(qON(99eAtSrN%mL@N1DO%2H_1`l!NvnRRh?V&f|KzQnt$)n$nL775 zI$yLuyMc9FXMhx0br$rJm?H#H4gby9!lEK9U}70pAd8^g+OtygGmb7(D?!k$ojP=2^m$6ElM%;lI- z%OCW9^%yA4MC9)T>$>-A$T^ove(8Uj^yCVo)>bP{U6T>|Ax=x-)g$hyYm3bL7<#} z2JJs<=q3>R&BcC=@&w@UZ1LG)P4Ju3H)B>#LWj%P0fqb16P@qplv6$^L@Sqy>0@O8 z`k#FxBjPk!Z?rY?l+6g`ZXcYf_d!>XQF++zKC^~!!6wv@GmQ9r=rZIa=%wJT97yNu z9M#xMomEb_vfvm}mRw8=2*@oji4Gk>y7z%dYsfxiaDiM`#lm@{uAYG}JIC=L0UpFJ zRE%C0>d7if?$S92aMN+wN?r zK#Gw;eeaN8U8Ex)2-K1LFEyi;cG)+OyDtAw8qW=^Wt;eRbH2CvLJBg(b3xCc2vAUk8_pqTS#1m5Iz72}2l z(~_=WOV=t+EC5yhV|Ou;xhtcdh(g_Wav3?%k(&~c7=z~3Q&XKMnwx$yb(sU6%uM-zPCx&Cl>Q&k@SjfJ|L6Aq@r>91mmp9cJS@U2FZRcXis*>^R#+px z$!lk6|9-#54m<4SUJ8jM0aYAm=(mYtutu6k1kk2^y=F4;(4x#|_Ah_|zVMDfa&V2N zN1o&y{+i^UF16xw5^fIMK5k&r5g%>-RjC4ZY`*9cQ&ZKfZ_C47xMvbqKt# zFUo`8?xH+eDsOm>vXniaIcl`Gsh(6fCzG_ltm@kH)K=AIrq51jE z+(EgYca~X+7kSv=&uSL2HeC|2`UHaxO7(o_R~XxemUN!W3^H5yMz@>#I>6j=;=U96 zC+)%rExulq{{|c8p1Jux*&K{?dDy`y+%o}x` zeU{|!;gG%%n)xBOM2na;R$YKxBe!`5ZROF=oW0}Bg=Awfty%m(aME$LIzD|F= zWKI@$R5~}iDQ`Vw?L9i`ETaBlH$oHe?YTwyasbT zm333VNtR+)>sCE6o0>@sma_fMZx%iIOe@|VayMB{*r>WKoliG1cwoLK-W z7mm@N9a7$oL*L#<`#I4r&xtz92_87kwa==l$z9FnSQZ#0QIk3{6rMTNKqmvALBQT? zfhXgo4W5ampWc2%Eey$8<0hhh5_UUp;NPx66b1^KGH?3!f9jT2o$q304KyrM;FFnS z_oie9&*ln6y*Fsw;PrM|xAvxe%ASqXRh?u!I!K_dh<@H0f0TDju;9MG&#(UR%(1i_ z1r;t2z}`n%vWftHEo+iaWgVc1@u4L#XzYRKs6VlNF2i6&#KM$vXFdAPL8Tv_()eDo zmroex?ElEzd+wY!No!IlB;#Dp3uj2feJX5rET!Zf^+e;DR~`EUAe)uH6e0HgURP4V z_Y$Q>zHi5|vQe6rLj!gmdOMTQbHn~y9}JYD;}hgI1-*C8NHGbM8+=CPT@qF*K9+6F z2cb1Bb*eLSR@nNEmYHH@*O`0;vQABs3^@Ic)B1DA+S%;-yKfaeOB~40(7-ZgqUALI zEF@06I<)4pyJ= z$T%RLb8)W9xQ5TxWa}|O<|W?qB9>n~)u2+;$2G!ULq5A`qYn0||0__VRrjCx8%3G< zKiIJ%S~R}Mk4WCVGP?GQt?N;r+!Zb70C^A8V&iuUz<<2+?6Y)n$^Pe8F1k6Vp95ml zVMPjB$rex-q`wYCVzuTieoISF7&f7AQTgup9(fqOH+rta~Q-cygVMevDhrMqcP zOc`+v{gi^f`;qO0V}T;IF?U6r#%n(OPS#R_3J1To#&LOFb$#L;x!W`uW;O1NDUmKd zv#Wu7Ehg)wZeX!MaIrw(x!2ij;#WH?Bqckd8n1Trkz|#gNvH=VO79dh$yF*lH3X8+ z2V~YY*~TsZ%seP0hHRr@*Deyj1j{sRPnKd2FSUv9jjBlwPUm`R2@6ArTv}PuH4CuT{$%mc!2FP09&Dia}M$!5q(SZ=^*`WAb{y zZfjeTl_6yi7Z_vY*~2K8u=$E`a@``H{)oL3!~<0#U_m9f&sF)xcShiNA*zkKfy!6B zL$6#wG$$`X>LR{a%eRoUz((d{F6{~`sD&0(J6DJ@&t9GqiokXEx|EaQ9Enqg7~M#wtUclWs|UrFa%?xR_)Jm^)15irGvit4rT zWq}(`{WrbwNtfsNC1|hNqa-`VsS6=iOW_7lv25KZ>-$g$xGYORdP@JjENN8dnVe5mw^=~i_)d4^W44D>8~GOQxG)(xtDyS5(rDFN zsMv~tv5Iev&V!BRo8LxlyHIAHapxd)-?5DnQc=>H>9x~uYBVH`Djm)p_IcCK7*22G z9+<@FI~sHm*(BmKB&0PP>V9^WO=YFcbq`O)nDEuhV^>${5rW{G0sX7OLGkyuRPdy9WHJE4hwoo-YTxfR1%JN1p_BjfV;bw z1)el)9!%r`6JAhz)-i4|DNrp|YvgR?9xG-jWARKfMO+Ho%Tv|vv;|Z%n;Cm@{xtIX zVv$jq(`eZ@860=``A%8Ldmq={)N~eAht3$`zl9yI0*cmkPCzLvgo)!1yDx14Ie_zu zGivG5A4gB@&z(Fa)C!zN|2}cCH>q}xtDXv|1B)yHzlwbMLH(ibVL=8GaEjOq+#H^n UGs9Ph0o5BwRZ&v`DQ_9{Uu)mWH~;_u diff --git a/ProgramScreenshots/SettingsSiteInstagram.png b/ProgramScreenshots/SettingsSiteInstagram.png index a532f69aaa41a5291a09b6138a1abf783ed9aa13..55a02ee7e7a3c40fae5a2bc0ecb97be55379cc67 100644 GIT binary patch literal 28106 zcmd3Oc|6o>ANEud2_q?yB`HeMLUzI+390P+nteBDEJY;Agh(OTQnrcggQ=9UuW2xb zgselh8I0k*N1gL@p0hm9^M2kx-ak4gnYn-W@?Ed%x_|esXsa{t=GqN`K$tZy!mdIf z+XcX%2?l!bFRIvQE8u_IysxS&LkimtO@bfjZYXIfK_Ep)rgf{G;AcjUi$>lM2umI9 z&o-?4OIrxU)j|WNblu;aNI<;iF$fr^nw^u7xF(^YWtaO6`N{T_-dqdc;sX8IGu?th z@sAItPw?Im7ubyx-v--RXS;XbzLwT);q}lv=2t2jE?L7yVSS$alpgZDmOd}gyRC## z$}1Y_(x`6Gd^Qn9cRF}5`15QJVtJ|uL00G=U+P1Iq}AQ+uDQ89rBHlnI;STn#u!sJ zyK_4P(m}@#GoL@Vc>n@=8z&G6f!wNx!XS_fHVk0N&(F}Yfsb&8GC&{>mx=rfOektu zegILvc*9^W@c`yq@o{%Da{j-tk`w>8O*28mUx z6jCb18g~Vg+()VB{B~mLAdv0?IJB>7KB+ozWT+|6A~2`=+X2i;{O8st_x#n+>YyIc zg+UJW(J-;~{J>F6h?>I2xwP1tP2#y?v9*+SC7=7Id_hVItD$1_zm2w9nuakOTwg42 za^DybU7)zHb5~MgycarlARGPKS2&D()veRur)`?J3*&F>h9Dfs4(hRJNR!`u zz1|oiyY~<~1ai5&Uum>Jk!-LKlO`(|vgBOe#LlXC+%I^g*~>dHK5)Y>Dg*K~2%xkPRId2-rtS>38≥Qt#f4T!_a1G;Cg>K9rC#Riy&pJ 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 literal 28013 zcmd43c|4SD-#Eo&|qUJE~n$gFq_d4s6-dfWPT)YngdL zActBh|EMsqXZ8??+a7JG+O<2@gi)7d9uqj8T5rXhT^1MgE1uuMunqTOoVy)elldv@nIYi(1;##2~nnTSO-WxL!DOQOO+P z*%Qk>nJQlIQ+vv8LkBXsb9D!P3p->~JC~_2TGY6ixlESjYv?YwYW!9c=)6-?(l8LP z8a>Vmf!q~-#9uX=zC#azTsLHfLLleu_JNh=o~34nKzcbs_dy^|2i2${kaLB;OdC&3 zcA&;hoBC!Xj9H8 z^A^*^s_TV8-_6ET8TCdNc))e_ki%;B%bUlS5?9AlOq3R7{0F?6g)Bblb!8aCt;Xsn zF8YsGX)NVAhG>^>FWMx>?V!%QT^J|j&(os?LXM7zVySJ?47RsrU)t?~-0d`0L~M2P zjS0ZkTQjEKhunU$)i#F~_ZtbgxX?_r-I#r@IXy9}Ic@8+WVkU~`M`5rR{!n$v|x=1 zT{M5l^1HAlY_ng7qA&#V$h9`C1GoLTYpGmSjz4ERDP!sb9d8m&Wl6mL*h_2l+C)$1 zr89NhieU>HeNNWB1JptUqRCX^B5d#-SZE*KOTf^rOU>w z44XXlWg6Njb(uaBvctO6A9%V$*5=32jm^d2%joKFxBS1a1y1AfXM}lEquiS{7lHq$PO>DV+&vA7<~_(i43q@}X)jT*mq8#K(yYt|brx^NN%@=E;&O>BKQlaV6Ak}F7W zVx06sDPXB+sp-gkA}*M?zy1y>W~ABAd|@57nA&Wh^gZ3#e+qfDe$sDD%+GDJZfmkL zYKpF>&K#W<&OH8zVqX`NxRkzfs$V1UdwwQXBxV$i38^YB=Z>r{5jzcJ&>F!TuQVi= z=Xb=Vc2*xsF0Y_E-YvqCY_dbNV$0U=j#PiydD~+^z81U^!>B_-sea>;;)C{G|B;^Y z=F@DCk}QE}xzPf5w!1Rkq)t-snX|amyc6iMX)fj_W!+$*U-Z66wHik+k>wRk{1lj^ zoHh47F2NedHtK;6Yzs+51zn7ryGAspf;>7XbN8Ke__JZPDT|O5;f==HiiDgTtU#u7l`RDUa?*kY>>P3 zmCw|sW)4`NB%-~;ww6YY`hQ>2oqlbitQq`+IG!f5Et8t#ZhhuR_Rb#vc`uvfoYCNG z3xS(EsYzTa{Hm({Y73iLVpB6x0*jBb=+Q3(5@`-#^Fi{Z{@HEuzmu z8Z+bLHim^jVr040SE?Hcb2weFHRDfRrnXf#a+bRKi5-)C`=={+mi7E6tV*U$c5XLr zeS1yEa%3tk#1G0F^u=ZBoz#wL_sjK@8<_NJPh$W0iJk8;M1Rb@-e>7ht>N*p{j;U+ zhu1P*+`#l%$j_qHLbV1s;1y--oRGUerVsFXF&qaDxFNffXF1|~e`{&6`B?MT1l=^= zWJ`5vnW%IrcssVJtEa;9m?{o=kr%$f_g16F<^(>cNt<``yNdsOAzx?Z4iUJFRQXEm zQ2MJmI_9Ug1=W&Q1}nsl%G`c*-j?XxY>jgG7W-vojzqcYN3q-QgknA(5@6hM=8v;k zZCrZLTz@S)VCAKfJQ=?e|6F=4pQ?y~a_XI_Ql-`Y{-qKr;@dOm zK-1vOLcgwgp^8gk9f2?HWCZ+3Amf~S4&w8MO+~5=&#-87!?e)SM?ZD{Z)>WlMec#M zN~`ZL2d~zqy-mv5u~~XxP@a%uRd30=F?n<8Rl};M=eGgR`B_+!Vos%ZD8lSQr?S)@ z2;}h<5LK5-&gh0>T&ABl2PP@`;BnK>b6)CZH_T-%edK{96$O897tDQmF?*{;cM8vk zWN%VKzIsF|O7UH?#-x!W%qikRDqvGEqSw504>025M*e zPiaT^fWVP6)*u0yUi(W*vTrdwe8F(?Dq0nvrV!c@-rumb)I|k3uCKde*}T0u7uDX) zhK76H#MJB)VAbym-g_1N{E1l`uxB{&eFhgN`whJZ{E}b5*OV`;sF`C2jfv&yn)!k5z03ynp1+a%0Xw{aG^1utcA5_Dc&DF!tF|B| zJyAT$p)bq*eMeqaRN~H=WaZ$lyc#u^i@y3oZdVn%$Zq~U84DJkMnA@CM~G*og|ty$ z(z07O%)94D5*3Sfnz7u)x3k9v@T6l>rE_y0=wa;3YsDBM>xF?*YY>CxPi%C5Fq6MS zQuZ7z^Xr7U)$0c@_raIGG|Qhd*_sW!IcI_7JQMum!8D!f`aRim>!FCqhf*y`+;ZHA z>rBteesMiE=VVNR{>3I?M4x}!TKEKf(Nha4$m+KCRB|y;w@=~vYT#mbaMK}jgM(M# z(zuu(!}4>g9j!w$@(vx-JHh$SHV4EITi+M@t2W`X9h);H zOW&+e9k7=-Dz-|}7NtuB@MkQO;iU4U4EF}Ja`fht+AxIGP5C?DbLYpJaMVl;g2PDI zxJv!nu*)T;6OqhdEhi%H2Y+c9Rei^wZ?r+@BROldGFso3evnZp#BMxsW;F^v%dL>t zZOdX)QyjdQvgl!&lBH?#IP$PUko0%b^9|`)S$D$nq1oowma#_z{KpPlV7P3g2Ho4T z66Y}Ouf0!R(#v@J6g^)9=hEZ2(UX4Te%7Z|R=#J3BAUomZa5jUde5ix!?j%_Ux%7Q znq3E9sL8;_T-{eQ75z^8ajV%UC$~UP*@`6(5+=<%`13=w9P(a`ep-lV?i`ww4l0nE zI>sOrr9g;Ufqn0$ibB>XV2*UV#A309@CUBi?M}1)Nmz>&nK(0Bk5HZRrfQwb3dWds z#*g~ux>r9mKNktHlf^YOdr5EdR@-HoHE*E?yTzZ0H@pKmguT3{$vx}th>OmlbJ*ly z@skxp=;j6NDU*8Qz+_Y4PGcc%VZ9R>NdDS&St-i-WYDFNvsIqmMh)dFGTHJ5aTRLj zDR|wAvgL8f5X#VfF{{O3P&4{*xi9hS$j7*r4tkKT5aah(TtBNj=}X z#v4r*bTkkyy==@)WJzUZaV}Z+WS_ZDouA4qER7;S;pT2^X^#)? zOlebDVkB~;&U`_-F{gjDUJ^TuZ^~FM!amZ=4R}9#zn^D(wrG0cOxBa{(w*(MOC++( z`uvrRhD|(F$eETFYsz_4uUD40h^0R0t&r9U|F1-4hpuHZ)KI$QBtmI(=85P03eC_; zUPV_kZVBtTdGEo}_cl$PWA?rL`RD9sqA_1uqi()`EL|0};b~TTD}`I`_WAA{Rh#|C zqWL9t&gs>$R?|N4z0iCrs6efa8%Hl%7{_&Ee+{h#^9hp$nCH-sO*%i%7=1`X|4~^B znh%{lyfezMEAD}nad74HBzAH}Dfuxw=?+SfHQs;U$LhX>z{Q9@qpUvpn)$gKjb$x9 z*Q~t;eweqx(H@Bor16$gbAn#%?8})_hkAS^=BD@3YR>o$`LnUg!Idpo{`6eZLf=w$ zkJLqcExy??YuV_b>`bK*&UtkcxU#ho8+1j}M_O=xuu@~;<+8s2d?m(ysOqNt99A_% zUk&Q~SuSAZS*cayr6b^MIdh9cJ6ai4Po-J;nw%`D{afeZ)@>snAOZN3n_*AZ)e-Qgt0e7+{g*ofDnsI zB5C?h{3cL~OG5V<&`LD@()l7IR=;_Q6MUZhW}? zNVzpJtLRRab0cZ>WHR}&H%3d0NdCA(UPZ6Dr*xYrRKT->;qPKsnjOn3jJBJ<+-}A! zr8NCoE15VB3odRua{d&2a78L-ND&`pWKwE+42Oalps|kjJ=w}%{h4`rS9Obsr(^=589#w7;;oBq>Ph#$VjG3KV*c-O7Hs9dmY)NE` z9k~B`?L*4rh9u~M9Px3r&UoOGt?*J!MS5?eNJX8yvWy$bX0F%^d&dTSHX2^#p%9pP zJ^osQ`OUXHtxfvG4IVuAh9{b@%H`_DqR5VqPm2zbYOvVFujD(~@YsRBI2}S9Phq7+4!VX^G@$~+Z;an750a-M~WCrBUySx5T|rz`D)M-Qkjxs z%v&jm=C39KW6W;>ANa`QH*)Mu;854gV{ZZoE;eFm&67*_vY9KJMWB1{j}=zBZJN(6 z9zMaV!K8NoQ$8)Q56d0ojFs7=KsFPBNF}8UKa?+u&w@C*!rs|9wt5-{sa%m~hNJD` zLD0B!cyAPgsC&i*%E1#Ah|8eLX$2L*o9(wgq{Ysad<;ol!-(nVVKr(Yb86=3{AVA^ zt<~(y_X(ID{`L3i(0vzEQ-k;JgI`uaB3net^SnYK_g zI{#vIwAvfu+yLElWMl+KzW_o{?pKj^M2-5mZWn_0wZcWIj?B8kbiP zqk}bTmN%}R-Y65tcEYS13{DB`O#qL(k_A_B)!cSgHxSjiU`EUah(?Ln(`E z1dHPvgPR*SFVdRv!Huk&=GZqLn#`w!tS&V<7)@Lu@_riN(9=bD`bG*W24 zIm^Y$8bUFGEo#(4rtG}BS63lszfKj8u$_U%8r(YAB1wy<}=oS@-5@PtH{)Lr%F^UgeW6*m7yRGRiYdoQXR?+KlsM z@|X%$mz<4k2({g#(;yI!^wYS=sq&6GYpqL=biA~>J_K<84Ol4)tv z6RddAox5kwzHue{07)!Py!VfrNQmMKHa*=qUv*{uwliYA8wJbgFH1kJ8QW2KDdU}v z7DuG^Gc#CdTzTTmtxk^7$0w>v=x4<_NU}R4;Vyf%Y(r0%D-Es%v-%n31Y;b;$I(^}4h}z4 zPC{j%X|0za-0j?IlHulS>*iSv;UZ+sU;`#Sw{zT!~C#`E-9XI7b@V^C$hd{2U3GfBB> zvQ?4RocTi~abZ-<@NnmSR*@<;CNe!|6I%h!Ze_C3?S3_0W5qbU{IvJlEYuZ-O6HZ6 zPV)B%H4ye}5=x9sB1pmeJrccAgx#gm>AEX7me)Zo>d+Dgzg}CtX*iY>TNIGlvy+`w z`Mz>v?)dJ;!@$P-V0ipGx~$hEVf!krNyFH;(~EUMxsK5JMfwlt^HI*O8EE58#S77x znA=Qddjj;n9=MUvUGzKn{m*pK8)YQ@uXK?fM^8^_i9gO5Rq)>knQkBx?E^kc!t?S@ zA`V9LhqC;sOE#fqKDGbP0a>^C9u?%tCD4OoJA+NN-OQiIEd0dyNux-+X=h5AFQ~Y4ux}r$(!K z%x)fGR}0S#Wg?r#|6-B;+YE0UoyxLdesU~=Y z$-y4~F?rq+Q3Jq*eWKvz_hNI^pc)ot)ahsiJy^y8Jr6vpa&drtm z0-WmSZgVT$x$GjlB z!1FZri<;N-dpbR+$ux@BurROUe;`182<&LyK(5-9h-!n;LOS}2!(!~TGGC*m%ANOg zQ>5|6OR;>-vUB}n|CT2b?c%z&$)uaDkqlM-%MKvhKKkABey9=J|CLE0h~58!y#qd3 zPhOY54O{4Ns5AAs_tPTj6zUZ35SG(bYtO|Kr;peKo<_{vnU!-7{2~{4G~m)u{So{6 zNXl;Cis$zvW~nAOlO`0W66{R6R8?+2v|L7~y}g7Q;U|uGox)a_Fjb;%78VuVoNRws z&tGCvAtNT#(7av>o<-%#0mja42`!O9{^UB7K=)F)p`5V^58MIF5X9d2 z=DYALZq^Oh0cQqw=!);95-!NOWWjsa@p{AAku0q2@2==vXk_3P{wRkEsp7vrZHt)~O%HC4fFdF+5k8zXVdz&(VsTypePe;-?NR@8bYFWAX~ zZ`7datJg%Ye7WSgrih#Bq}x$H1P=<+8(;T_*$kWkX^&eojyI*&1^c$@X4ku0i1I|s zy4$aDIs8?opgfsSAvKr;ifJK}I8o5EH?GoQJ`LtUc|jQAC%E>Q=hhIwkkMjZR$+C zRFz{7@AAuij3uY322`c5dK@SmFFPs~$*NGbwjxJ5sP$=KJ6YdHqVFwDLc!)XZ-O~v z$*@FHa)t5%_AE)N3pR~}1%FS*68BDbTrzLLQ_<+huRvXo_M0=ADnDa=EDpZ2cZty^ z_@QMpUZ;MJFZS!^`cG$$nICO5$rqJWJ>+Ua=|z0!2W^oXKSm>`gX0h?5|1MfG8`C< z((R8o9LT0Qpy(j-dCK_myXE6+azubcZ-hN&EOAH?w8(DG1(oqb;OeRyod#1}A*)pN zJCVdrqAKZ7z4MOdba~^#yNIxpO`(XYziUrYWp^8l<5!K;rmlw6YaW8HJgiy_gC%D) zzqARyA{G7(8iqO^y&E|2U+&fi(Yh{=D!D@TN{{u_Mh{cOf`cHly1L})OuMm1*W z<@|ruWXozyuk(Lb9?VdQs+tup4v55X%}S3?)_hdkpYp+98jb%zY5rXf5*`ssvy_w= zmxDmw(SR<;`2|M-U_|fQg5IMpk2V2BVc>Ln{I(-&#H=&QCc7b-sg<*+yiJ7|1` zf&N#fC^jmYYUhH@^Fc?nk-z|J1QG1~F{eOjPW~D=7K~w>gHydi@PpF^tG$Vg?>gP6 z2cYKruS2zra1sYyM$|Cri~b~@=F2u`Ag1{s2bP-v=#r`IURXz)X^XL_M}z9YKAemi zO8fA{Tgiyzb$n6j6{`>06;A?rcj}+` z26I387W8z^C4;SCWZh_y3erx!yVhQd)0}eW?hGzPFqORyL+F>QNvin?n~~lj(q~!+ zhjLaf30q~|_EOVOElR36Y9Qi(bMH2iE>{jIE^f}Q_I|(d-99uiP}wX5KkPQ%XX?|P z_C40-0|vzixp?^J1#T4wQ|r#r7ENPeE)?ZwdKo;MSYBhPYL9qm-sNaU)P zvo(2GV&|JPnpj!H$LDCZH)HA&nU0Emm112v!&)*lTL2oYZ z{4`V|5m_{D>ZHj+ePC;weUcl}%MbXO5>}{#qvOqiVk6JVhq7yjKqV4-dBPV}#uL%E ze=WZFqlYw)U(0rP({P9_1~AUmN;dzF9_jxhnXUE)JQQ zMYpDgxI#G2g2fiSR)^I)eeV5i+jT^}1`zu8>I-_$6ozgE+P1w}JHzY9hO5R_hRa-Y z${1QW>noY3DPvh@=iJC3wt$q^Y`arvwfDTE5}dd2Fw}Bvt%XD8dI2_p=9pJT*HPR& z%J%IBC*&1^VkHdhoafHn9+bGkrd~s9&D?pZz*(ZxNo&T-a@NOD04Ah%EM~%f#CzNl zv*w27=^-q}Fn`mzuiQ;oeX^+XvUy^xP{^;{5+V?S@Zi{ZG@?!!84!hFh4eU&VZ zmZLJMO|!<~PINw6K8izG`6;2Aov|tV8BUGj6zjLq$UY9`;eH5<$YSG)5A9v%3ry*^ zWe`q7yEj!Frqwc{-+MhCt>2>lsBC`$N-)z=;U(+sLNC&5{kpH1&`ZtURk8$`t%Gt% z+`?!%M-OPejB1o|Hgyi<`^OZ0+od9#q$k&EE4&Du>z$R;XQ{4xQ}7=y=(lS<{D~c8 zUS{}uUsG1zYpBST#vZ-F%JfHGj7h_lBT-j0xS$HGFO@apBWQXC+d4-*abhSq_VHRJ z{!o~H2)=Hlc2=BIFuFbv&ktOa)1b09}VHV#b%vqJh9A zawhc!o6h_w9pn*UN0Se0T>SZQ9PoM34$0!dKDTi>|7_r&f(QF7q}4 zakd?AHJLQ?E_ zy}q#rsJmQHFBLr!ZKgB6u1iqHA;T4%0or#jAY+fUk==iS)+F>Sv!p+%e`Fx%?S-Iz00A@G58KKtiz{Fwv;lTQP2Qkb|JX z6l#k%Y)f?~wRbL$K6cjTSlvg1b|YuTNcEPbpR)HZ&kJ;Ak&DLHkXOu-EV&@pk1;_n zPejHjNTUFDQ^bm{zc8Uv`j{3nj@;mu!^qnn8#1}&htYCce}M}3<_=++9m%G5)!G9& z1r$;`?81nH_eIVf%%K(RaXSuq)k`T{Uf;Nk_F#XbPR9&aftu)=GEm*Up!PSY=-=88 z&{_d{+;pG&*XtJm^?i!-pDpJNv0`p*Hz)^#hxFn4SuKi+%L~B1otMM36ccj?5{-r9 zCEQ7*?zC(%L;(ROi?DsT7cxU>U;i*9jHv!Mf@yxPkXjAI*8W)7zAw}ecIrPp$FuBS zS8O_fS(!5Z$xypZFGqD0+^KtC#Xqy<$1fq^5n= z{#xZz9NOcc;ywH@jzx&omeTQj#R1 zlY(bGAQBFLvd>t<%)6t=;!ZQvrI}uOD;ts5LL1x{X5C_oCpTkDs6^AJ9+a@8ko&Pl z@Fv{eYzGdG01!(z@DOyJ&6_{U3+MkEd06K;JtTt#*EK_3nD8E2H2Um zS_?-Li?v566byj`%it*`tzN8{xEqvawA!pTOs3ATdY4 zDM#WBi#BN!THK;sCH0AZd>{2hd|LHKW?kU!t&xXiA$1j_YtbIk9D{S6%E`r;;WfdP zsdf}e8UNi4E3dh2J0R$7kA2K|c1TXCbpLfdVBnG;`S+YzK3}>>We#~HLD4k4-~a{3 zR60&~C|b*JdM`xy=>G=jp~ws$4O4!3{a9Uk7#sNeh0{Ms5F>%fjyIR%;{G;JYA^^8 zv_g$_&C}1f)DadHZ34cw8k^O*hnuszr-c zt)Tb}xQSaJ`u-6#BVp>+&$I(fClA?i0|)%5{%50H4Ce;;h>$)pN-Y2s$AZyx-ZeA3CpeZabZmsYwFQG!V%%(f%$G_2P__| zUdjzD{x2u@%kQoc(h>gltSrZ3Nb0!5o!x%*(xCm-^MCf?|Hc0(5hpX5N(e;P^b#TubRymKNW7s{A+3+^k@ zvl(k+DCK##MBk|~l@lv|7{3`6`1Wzq^BiluH*RjFr~Isy+u2>Cr})tyMo+J}F-#t% zlNs$C*Z&A?{%cEQva6&4aR}=k*jC4>GQWD5PxSq8Qg0I1_{~lEFS)n%7df=ozwNxZ z)h0a**$c4)xMyM>EwIf1{@wJP8#D>*mhpdK;I(0Z8+)aGTS~Kxe_~-TCdX+8hH$_N~O9-?K&{D!#d3LV8neo7FhgJ?jRsM;;LX#oI2ZHQ}Bos5jzpiZdg zRxI_}%OOwAe7&?*XutaXGwm#E86z17_l7fGzrhT>>ru!W#36#?)at`YwP}yPJd~8% zmuM`ON9se09#n8E1HOZ6#+hiuN<|WKV)>$+RgV+6qFC(R6w0kFHWd{80^rKs(@ipv z<5B#3Vk&(gTVlDc2BHEak=&w#YTxB{Moq&aNOJx;*a95uq1 zdz3HL%1`d$I1291RbGt2*rU%xx%GUUN*K3`iAEpR_PU9b64o9V!OAUE1y#)9(0vl+ z-l5%P>IEpr2~O6a0ehPwWh|!rRsng{jIGhLZ*hG@PI{Q&0y!Q5?&tZuvEFlWotE>D z$Z{~;*zj$UmA9Q}41uMma@s2FzSMYI*HMIRg>raMt>oWqrUFRfv(C~R zO!bRs(pTU?=0A05NkGhY?&43fatIUxcE3ON3GJAlFWn_X3oB|z-KzHqJiGAgcL3mX z8kF<;8k4CUXsn;5aC7)vc%}+`xCSS4M9uzi?Qwb_-y{!j9{tSm6S}bnGP(R?(7l+~ zVRSbE1tNUciT?u<;9=<_xoQO*7lBF#u}k_%Uk0erUo=m;6m1-dxR}PkCDZZsea7@) zrJd)(Nc{*vPYj_Hk~W|7S+JNu0O@8xfVqtOh$tWflgcbmk0Dh7tGBAJF8R_ zB$w<@{sEkU4LbiIYp128{)IcnCZW{?leJ8g64!hW7m5iupFc}zP{_B9*xiDG3h*>J zFRuNSsCvw!==;bmILMEC<)AJV}15HzY9#vwk1|1q_1@tkje^3Tqw&E9k zI1Xe;_TLuJ{8yoY_)pitFK3CaS>;K6?=hX2i3#K&QSdm(!4;#o(6nveOEM|&LtIm&#E zD;~Ji<98=%na7)Xq(npa-TLr0v_l*Pfe2r^^3z@RKv++mpxhp4z3$SdUd!55fr=Pp zzpI^far48Sq8ucEfV`sCE&dxeUmm_$Y@j4M~ z{<(0c&vO5+OibcB_mhCpejwx;!7}HY6;J6FP9+ym@NUvgz_V9*PU{TSx}_pG>;g03~(S>RhJS z0Ws~|Z`sEU9)L!K_0)3;ruhU4IB9vwy8#4~ojU<_?W}Kam zzF$2a*!b)QH_AZg*Ny&}FYrxIPft(|TziDSaL3d~&Bq-+BYueNfqOL;+DWKrkhX)R z7oZGAjP}cNOsR)5aI&EsTz5_d9q!3l>v}j_gTo#I-UrcpQLtHtaN-#HH!ad{{GTSC zhH813;mD!ok&8s6mMk=U$c>ftdbF*;0ou*2`)j(b7pf{q-=9~61XvBJ;J50dj2g+h z6+FOAA&;(W1DVF#?Q9^M4ajIm&bmBpzFKexi~-dGMtt}2P}m^ewpX@$qj3(P8F;`B zDj{LhD&+VI8zD@&=!f_5&-Qc5T(lUL#|gj&%Vs1x?%d$HG$tBzS$*faFF$X z6jRT6Kqm`f56zG_Wd;%8!Cyg`TtMtb=eurvy$_)ITxb`OYYhTPx}b}v8HZ_Ql}uz( zWK%#!Q~-V@yelJuVJQ5yc}*4n1j*zm6=YKUPwoy%*@wTqTc0UCD=UQ}_a0uUMK-#D z)%|JZ|C}bNtv~|;dJe~&U(W+%o=7GJ?td5JIC_TBCfwjShB%jp32zoH?lu6feoecW z!b#d7-EhKUCgsUijlP{fCNVd6w#iktt+Ycg{j0eZef7Gt6w?%A`9nbqV7yJw* z=m#q5s6#pY)=0x}yTje%zI(6T`}L5>AU(hGSeY?2YxFHUWr2KG8aZ>aGvdIJmt=Z@ z1H!47O$0NUa=*MO53;vy$y(3CnvI{c3~w;ct9buIIkrs7;o)+|A5QUK*g=QNnF4o> zFqjR2Klh$+{Ij}SSA1Nv&eF|h0AbB;WH({*_#0IT5Hea_3+U2-b=C+S+Do5*4r)3S zZc``yq$e~v^e!zk(O5Tt1jTTyl^rGMg3VkPqy*sBjW6Zu=Xxs<6?*E-Mjaam~NeziX?cU)pqxo0Leh!KaUteSWY^8LU{$B$Y zl*(f_hl2vecJf`il;_&KnY_=pWaoY+&&?I*es`QDb%FrRpv# zDRjoKY59)ozZ_(3tqVA<{q)d$xja?}(I=uoQ>y+C;uD=wEbz@-k zc%(OP*r$p4m~#J|#6i1|g@zS#%LN}{oNZsviY!KM@kwt_qgC!7E4u-E&n@o>m2n%k zH&$MCr+# zEkdc!zbU`>TG7_e*rY*>WAoH~QV=GHXhC*=KQs5jt5IlZJhso#mQtYA>lBYiBO(); z0*Q}}$gCpz_G0{-tmlB5PXf2KUjBqfh!yUuE1dPNzY`~_-`C)I!`R>)|GKa%muVkX z`??2g<6TJelb+UM3V1=g7C_jZAT7Ba`JJA{5Tc|&^>gtvZk)Knij-~rgo(4PXaPxC zf;E+`-rq-vTaqa4Dz=0Lw>a(JwgM{P-AegqXau>l-RUMpPZj;RW4EN=WY`A=X3Z7O zINjw)-A%akAe&zpT6)jg3ebsv8}PbC2k?`-5uY6n0iYA|D*t~m{Pjo1zo@5pNXV(S z;A!aPd}NW$E(l`fnsb1sE4ybOWgH1|{m?#vSEAbLS|w~cuB}n@^lBn8bzkfT)!y*9 zJhEdf?)2JAfv&IH1Bp>z?-!(t9Q|Y)m@TuTmp)hzX9u`2ha&j;+Kk}*0Z5^;matP` zqj37O_u)K%Ri6g*7+PX3V{BNP6jd1Vh1gMLBb9fl`!~Dzn)E-vw0E+vrr{Ag2Sq00_QOOeCMA~p6Z8Q zTVqv)3fv|tBx`2X$0N~KWOCleF@itPxCKcPhLw2Q;E_=b7YU;E$Ual)%{!<$OUEn~ zXC_H}#Xe66Cvebo-D7;^3U8=4+_~NEb+K zn?%CZdP2QEQQ3HP)+dZ)4FXms36vl2E?`tjyE0G-`9 zBBdA9ZI;!WLLeM!;EX`l(+0#5x0&iW{%`oQ7j{IZL@ui`(Kj%AMWJOyAyibqqO+cS ztuFT2sPi1}I8V_^aB*x;`2om9KF||$o&vFp_7DRv5{Oz|zVqj^2FB|ZXVH)84--Vw z5kJ))p<((h^|^UDqn*~R5sH;Xuk)0Ci#_hVUm%HEYOxJX=Q!mg6>DLS2-T*BacR%9o7C68MacZg0j`n82}jv$T_~WS{p3nT~q#q6v-=6 z`r^0eT36H4YjQau7A9WvJ}UvH(gYj)9ULQtpQaW9Yz73f0(h|dv=7ua+NmJ9eE(}V z_ycpM1N8>v`iFlWuoXgwSfThRVy6{Ky96#34Qj(jVgNk{Qj*~W>ax@tNeU=1?uY(0 zm7sReg&T6-=5LMv3hWQ#f4~E!Rpz6jgXjQbnEkVsgX0w9S}jBCi}o_bL$CKhD8OZ+ zH9!o3#^Dep9$VzSnFXp#7>;@r`D($BH0&njAZo}VhYIYQoUad>ESB?jXM2ia+oV&I zEEl<6a~vOJ=ya*{sLjiV8e5 z9t`0)4t8viKmTT{meIZsoT7*VRq1|znI{vzk+UUvd8B^n2Fb*bg?wy*jkLR?P$5Yv zvWaGLb}<%KaIBrXge=`#hc)!jCz?ONI_6Myg2i7qqJH%Vhz#B^2>2Akm`;p@zDTMa z9fv#hXKfMQWTQXfWn8s9MEr=gIP0_Jk&J=L^-)(=O>x=b*(2*{yGw`{jHSMNugqpf zxO{UL$vZxm!Kk_6C^8(c+rtL!TO)A2 zdC`6}^{KBiL;?y9IjD@NOL9_76?M{P5^p5 z)>1PGPkWaJWP#35x`YS+H`-j*@4Z`fbpKH?w~Dj+T|7m`flJxL(;jcJdm)oyz<(kb z1r#djIty^=p9xaOLHxe`ORX1_6+=<$HTFDq5`97VYH2h%yj)bgIVb-BI}hh;gKv0z zt1Vir)(lx(g}izM$SwO1#?WX|Cf4H_Yh|#$@VDJqeNQ7t{JBE;`jAw)dsIV9t{9U8 zTfV_gF;cC4cECNZM{rTLdQk}5(jD1B#(&xmWSb-jKj`2Gw zleZv!_t7sT4Tn_WR=2orXIc}6+(a~uLV!Rph8_eR_H#e&vM~Sl0RcZidXxS|df)#= zdRL;ic#*vuPyL=UZcQvbcUy{2Gh`5f+R?;h77IDy6gfNMA{P zn>jBQnSv?xd&|Ra6&xlSVH9y)?oV-@d(acsT=Uue7qdK~8J}+Ak}fA%IRe&ujPiW% z?Q(w!^bWj|t4e|v1BW0^H>l(|9<%G-)JB`0_B%4 zm`2{cjt0ez>AAn6-a>yy#e~e$Y=Y$>*INK?cALD4WxV9kO%Vx!cN$y)zf1c4P6Mu= zC=~_nYNYh?KSv*`c7Zpb0(Wp&37O`s$pYoOxuntG3^SP5yi~JyC~|dnOVF6rEz__l zEEss4_}o~x5a~@kIIIsUd+{D-3hG9K_x^v4Qn z3AY*R^V`nPDjus@QnLrIF&L_N$O=uoE-76rHRNI~2rslRLUa7Q4^M!zI_>-L%H#WI zwV|d!6g@wuRt=bZgA2<#?T+aq;%E~9pw|B>w)F}w|A(c)^QPjScqe}oXyU#^3ugJ6 z3+D9$v8j*J!jP2rJLs1GU(j-uF>Pgvek#+&LJ%OAd-{ukM$uQlGr79J)`s!tf}6gf z1oBZf|8Y>@4MyrU-WZxl2I|Aqed_mzM<*KyY67!1++A?1v-*lUv9+kMeAE2WxWG$< zphg~S&>^9NigwfiFNZ!^=(_dz6yo3Wm>jbFMUj9pOsI25FI!w|6l2$8X&3vArD;lq zDS!L(-AvUG^kMbGYHu_}Zn9EycM9@k3*HUkS> zMOo$EGaLDGvv_VhjA*P8H)_y$WKj|JWAi`_&}`q!q4{!@GEAEA9AMsKkL5k55U#^D zou%R7wxV;`3fYq5zows`w`RQ(xB9YgvRh@mTAV(hjb;bZyzCPY7&zjw}wS#A^e3Mu^n zuBW$ZTblGib=l=+l8GhErPFiBjfsMQ^<;*594irC`y2>*fD%!0Wp&RQbPg&|O@>@!qC>VwX=w zQ}FtB)Furx1D9iWWf3q zkj5WUXiI7O{~S~j9Ky7KXy4fdWBc6g!=3V?kJbZ@&$(KBTy~>MOEl#jF!tBL>>I4v z6^FcJTyA-y(U*`oiTV4nrIEz_;0-nHEJ*eHUTzNxz!n+(+^&89m4i!o+9;4X&lu)C ztGZ9 zJk~P${R;lH_1{0F-%%v^CVu+dr--=raI*B}qq*K?_VyPezKw3N+8A+nqCy41MdM;2 zm_6!1%J9vI+p@Ho@trkesLubV&EQm!OmeOXA^AP?}>^m+uOAX$J(7@T(9f9zUnJ{hh zc;MDXMlZ8hjC*2c1{PvfvA(0cQ^Qw&2etngb96U9#cVUEkhq!`%>W*@=2HQ#kQ&Js zD3&jG@e{_`43hq`3lv*Ho_HTRBZ74+i{HXKfVNJ%W7?Prs!z_4hY`R5vv zFyXCRkAKsm{PY@@cs*x8D|R-vU-=U$_`#%O#eqe)UKd@bjWDnkhow(|<@`^8@I6g} z?TnQFjXQtb9Ux{t8y@7A$*ucMf$fGJ%52UbhR9H5L@c-yy|8upj_Gd^D5PFNU^HdPw2dV#GZ&w}& z_15>@>MBVH5wazegk;aSi4f6-$}$y^J!GGykWi5=WJ_5>84}ajMxh~P+BBKLT#T$U zlWiDdX5KSy_kHejpWD69KkxgmF=x&>zw`T^@A-T`pU>$LY$4w^|W(B7#K%I z&fjD~zE63qTZJ6T6(#B_G8u1ym*kxroQFX^M7iT<-Qt-K)7oK-E+*+1U-a?u`jA#{ zf3(XEuKjqm@tS|42(%0FhX`zpm33!*HYtT7(ap5%km5{1r5p8D>Vg~XyrTmgb_l7p z`ILb%R44HS;gaLFle}>2mA#B%a-n`gs z;UDeKcpfbEaW{WzxrVbx_bD$~)+XHj7Z={GP8SADS4R9M*BJxYQuX6AwTJI&LibiW zK1o}tZp=o}T-5x^zWV9nJiFPjVZ9-xTj~B@9qqEYez^ku{Oj;QYX1~IfVcjo zGv;ce>qbe2>}K=;mE>zXH~2x19HjSH{8FZqdB2x|5!#L)B>k(2=G)aR`mduIGR6uk z09iD0y>6uv>?-6vrV>G&>I=kO#_dA%R2uW%?9QRRj^MMcx!La@WeJ%`lg&C@ZA5~&(p>JNA?6t zW%u;}lD8V!!d7*v|ISR{b?|BB|6}U(N0dSh1Ed}NUwNXb|KR6WgGjMj)yUlV(u!Ds zxLL8?T4c|)DPZ_$39#bd_(!~@EECvN6E5;zWJ}x@bfZ62EyGc2jD@K%iy=YC3g=T) z@9^<(`hQ2+#{Z?5Dgk^3%{3eN_6Pt-;x~NRVVn7+EyKES6=plXR%#-D|z(33wJI!S>r*y&jTEHxkG*BNVenkD&9NPsXmZhGjw-uwLpPBNV zi*~kN+1(ib0%s!~DYD}}^whC!7LYZH}#Ea1pYXlxX z??-F7<<(DA*h-b+9OvtAb&dtE||gpF`fxm!INCpgfv zK#j}RqQ$KjQ=8vJ3>7?#fGi&9fGqcg2Q(^;6tpF;=aVwx0o7a0D+)xruK$Ejij|Rt5o^r9>e-yP zD2~XBF1R4i?)R;0Gr186#;OKZ-8MH7YjLEHO3tr`T;WsrrU5G(AKV zp94A=Zy{+WfWqmT#5|D`pj67I!vB4RsC+55UzPr731~>WfqLj^`)Jx-djJ5*=!`Q^ zy;X!`a;ldB9SGq{4NAG4&rq{Xe$ROA`;k+y=rH-wuztJYhy|4v%GbI9K*_v?vqjcO ztUUjUpt?#ua>k&t!UT=dsksqkbe!O`=yIqC3mF>*u1^7%wGSQ)G|UMTlApl5q3*(G z2XOtSlOUjekRFnAEUkdxx0WZO1Wh`b`!(hq`*<$R+U#Ken88@+BXtSJX=BeK`>?7C zMn5xiOgah2BKB*K5#4%Kh143-#DKoR7U&xe^AscCJ?QA=@6NvpN7icEy&4R2ReaZa z?DUYDoO4-okFGd$aZ;y{Q32_jGH4!cOWJUC1{7_&zQtHQSURcGWiCzZ6^xd738DX* zo9&8W^gKzT`HMzRDIl41VAz zpqm!?tr(QpPZxcE!(f0UCvBUSs88}zAy5L@rB9a799Uz#uyFwG{0T9U>FiJF46Df7+#IcbiS7j3E2r8n(Z8MfZ6yNA4eLwTnFUFpA}zY|WcOEs9bjo*2G znu)HJ~Ee*Oa0ev8xCCp1<)oL9WDF?Ryd5aN@j^1S~zE*JHY#G@{cLC+9SeM#24Q z*=(ZvvS+1&G%QJ&vNdJqHUU+511#K2+12WbXJ&5k#_|P><;U!#G=WClhbUbwaYuus z^nm;@@(~*ct`U6lnbX42wFw;MqxDDJC4O%hnBLgGcvf$<%jVlj9q`=TodL^~RXv#` zq3*$AQ1|KR?1*MeYvXU)j<;3h6T+SbSTa6a4{f#Wpr)OOKDA+g3rW4BtI6QSqEUU% zlWjX9p!RrD>LKUVPOrdSg={_QnYmd?HUK)Cc(ePGb7xIv(v)e4qK2})V; z_ww(F9GE$A79)|0=m>NK-Y3$HyfYo!L{ZvmUhlU5N5T_45xwUa#j^TBnk{n-i+xOVAcvUg!3ySSADf&rp0d-L9mH3Z{;`Q65A;!=Pd z(Ar;|emrC4t%0*^Hods8#qHPIP}E%zM5XQmYtW|>FaXSq^wHXgW3{O$~GprX?qe2nuT2xzui7F z4wWk#W?yuVVC06G#%zdBR9JH^AW1AIfK=ZPDMOKHBwA=5lhk0NI%CEi4(cFuFl<$y zk0-@eZOtxRH=%nN;H2SpXyBIFKy3*kvIh&ju-i$XmI~P9eA&4#Juay{tiB-8ny=>H z7}!V%YQdIBvYhG~N0yeI{i7=%J-=|Dm8U)FauZM^zBkkCs1wzU9Y&y=6THlM#bLgX zllMBWL_)caPyF*sIMemP+Agx$(}#{C8DIjtdNqUU-$ z8(%ly_{t@^BO5an+>-17C7&HJplcdqy^u!rP7_4d{Cc251j`D)&R1pX*;~IdG`|`7 zNFr!hl^yG`PZvjIm)h?;<4K)Rp2o!6K1GqpAw4l+87>boZtw)XoX(?U3UMq-qtBOh z?$Y_pqEBR<(t6*{YQjZqvUTI)6v;jB154e-DH1DJ_EQJe=p|kB1I#_kNgfo$;B7J<3_RBb!C63!E#FRBFAux(d+VLJqjado7C1|KsXZRys`(xFEe<{?<5Q979&!0b4xe-SR%FuXC65-Xo!nXWL~=}g`& zjHQLnHhV!%CcB2ae)h`fM{?P`=~xOGymY0_3XG}VK=!`kXS-)!fUn<_byQ9HWUnvBIV&N3~50VEuim7+Q{vRpaqPrd@xe8k}~ z%I|)ED$ubJFZt-I1BeCbRQu*%!VvB^YH{rGxa3gNE2OlPT2xk>?djCX4K{p{$f-y^ck}pB$K9CUke0GQ}bdHjNG`-*Ew|jnYDv z3ud=~BGtF5YoK9b@^Ku+tnIk=A8Ox z}9E5+%NSB zA=fUnsUbg3K*qM}!!H+NEmY$uv56+H1Z2Ck^C9fm&iwE}>+i2IAq9_Eu+MiINP)6@ zZ<;e&%qStKyS~K6e3OEdgO28iM{s{<`s$D8lJ|@u*n|*83a7oRefnd8iVhu#?9j+L zbz36UuCuyQDnKNtEq1QK=S{zl)$4URoP!jcDMyocAeJ8DQqOq#9&QA!c(P zvx(pi5_|aa=qyE7GjjmB-2b?F*}dA!+(@{7ImU+5mYb*35!sytEi|wC%Njo4wwVbwGXC?#=Q^ z?J)$E(4a^mAYEy0ShoP!`=D@F8GKp}FM3uu9=7eg9FXIIzil9#5An};fqGdeM-Obr15y5i zuTOGF0gbo6zoCJqkX}ylfx5Y$XD>Z-lS9yrBEPv-QpOvz3{CDatJ7!gf#W9Tn+*27 zfFhRR8|>G{&%Ct74DlTB__Z9ilUiJf_Q(bS#r0zPTpU*ojiv1T8lL!EY~>NCDQJBk z{2+U2oZMn52P4UM_33kjnG-S`Qw(Fgu4mAbw+UR9?e068OSy*R(o6EI;$Vv-@_6=@ zTbzPacO=6rn50v%IyS-R~mbCc_Ywz!vk zB=X|^0`z?|SFG?3%We4thNg>3m7gA@vTv7rUZmvHGw99VuFqx#My2Q3u6dJAUOHS( zR$Gdib>j&PYCr&ONwH^NN`Z}Z1sZ6)g@Y>sI99Y7Jlu}9Jnc1_h(hS1@eALaT9ho) z?g!&T3Ag<=9M|u^y!QKm5#`7wm2vBt5=}VBtyZ@`>?c#0*nII43Cni=9+=oCxZjSx zOCO#qXdp#%~FzZJKh<38U$dw;(>#vS91`-cR~%3N#C`IhH>pJygaPe<(pEgLNe z1UjLi4l@9O_CtVw$B!Nc{-=$h)d_gn=V73x1VVSQ&jWuPw7+`oDhN~>b8P3ePC zd+MehAkfJs>c4%hu6Z^fkSAx*I zAk|taaCx7j?3Jn0oI`Oj8O-8I&PzPa?JMZ<;Re5w+`{2jb<(dQx(br6p-^>{QWpW6Z(^ zVKNh8fLQnFzJYLB;oZgrt$7fFcqPhQ@C#or0-w2OD^ZRt3i!BZeQ1&w)2L-xH-$O1 z0Q}sG&8(g-HCGBi*KQ+s2o*S5{5}xqri}FNr6A#|kuCJi^lYzTK0}t5D{d2plXr59{imNL9@_rCT|*pqflXsJ*IxxpAZTWm8sUd=v-PXS(ts}h7~&|^XpES7DLbV`RA4+6E%14#Wbhza@DX)o zwHX`lcfyqtvQ(x9FzX(KN&l`RwmIRPIC8m@-+cFBvS450kx{ho_ZHgx9^n-7I6iUF zN0c~zU1qRy$jcPfCQk^n`m`$(D0hEvva-lu6d3cuah)qOf?U`hNOn>6jIgR|?MftT zv+mwz@*~Rn1Wjuc(eu!I_RPSE)twa7navt&E4`gb1FI|#yu^w%a#kN0;#}LKh&IPv zvhI+*5@PAi_=#|}6r&P^_3KPaIn$nj2&hZq8H7GuO?xP6c_-1mO+-%(_E?$N_FKAgegwQipzml+5wsvMSC9bF9R=B~!=yCeESF4H;*w)ljNXXpzB4$dODc%lE z14aiOzg^A*ZhFFm;prG#Ke@f)N{*ejU9FSZ6HZBfT?SkL$`LE0ZYe1880;YMa`ylj z_}qixD=^@X=Th`w;3eOa0{Q=l|hu;KAwp<3$wxYIN>T! z0AoH-oejgeVgjA2YoLagtjse{Qs1n$x(r+lyUvV)X561BTYYhhAy9@M#jpGr35>G( z82R>5)>YV1uHdbCD8$3V!+mu^#dmjmb~=Q`^0gdgz2AM|Q@&E2IP&Ph-gA&(dZnG? z3@8cvuC|&r-S$ESg6%fZl~f;aUS2@gatEDu*-a^$Q!yiFFf=zy6IQ-b)-zX=M7BK% z%iVW}79w7EJ*oUgAJ!C-O4n_dh_IXf-qkd-mpp+U54bGY(~0fked*NRHMS}8&h1UD zN^nllk72n1AA91zzK3oNPrr7OVszfkDJ$`R z!+%!nv1J{+gqWo`7~pa#$TGygIxTX`UXMclx>sYor!dXxKJq>DVZ<)G>ef)57^PG# zfbwjY2y0u<%|yzr&#{_rypy%HAj}eGEQnaT2Di+ex=TxM3Lz{amT?raYkb{Gqng5I zX$+k(#3gaMCri1^pXefZPJrh|WzZgCsLrQ^2~`$(4icX$#Q1pXeF^6)3}Q0j5I)SyyVsdchegMB0z8h1!{!?7eFYEn}n8Z8;6A)~~)y>Wb7g7wo%&*b5j z4vFq@&Y&ff73Sr*JXl;lp8?DioZ{NqE*Kfio-Pl?I8Q0VmB$F}o-mP?`=EW4ez?S`C4cjl{S0^Yc+ zePLpD&E`+=F{bfD4=AiLyTa>^2(Imof&@iCgR`>`}=Z?jd8qlq~Y!H3}V ztuOUk7R0r@nOxsywV9_#+~eQP7$%>`DC~V{U|zZC9V5DCf2Hlz%S_}5`J?pq3u2JI zU8m1|im{U;{yC?X{#1$E+#RNHWcqisi$u<;e+;v2Sb&GN>bqN5OT4NdW0 zoyp}Ij@clw#iVOyapz?Rr8b96;w}@0?+5zdIUJ#m3Gz+Fv{5#fN%fgUW1@7|j#iE| z@IBsRX-En1zQNzd=VwJPBXKvY{vO?S#ft>omUWG_&t8bXClSrx;2q^6Z)1=XZ#Qc% z^|f)7?z3~DO`q``d~*EFo_wK5^Vs5pL6_F<O|Tr)ehl@d|5%59azIl2?-J|mkv zm7>+Xsos_c$NzQ+zx&K9pruxQGc@YUySr z{Mchn*m`lT0FA8oQfw$E!laSdu+rZ5LhD$O84>FnhRlBNwge=RH+E5YEx590B5YiQ z{ca3Wo54zGzn9yTvFvd!@M;OZKiTd%G8jv{x_fA@VgM7l@y>|MQZ}x}cg|bsUb=DA zx8!78^;#Cz>vmrlwt03ea2c%9Ov7e|P5dogtB0kOsp-edHMecAUZ1PW=9I5w zEY(>bx<5nKxfDj441twjc*412&u}+B`GjBKGX-Ks>lx7)OL*<?XAMx%kaQP9ab2jrX5Bl??dlNJZ*A zVP^Pycs^dpP#ybW%A&{~%gq6+u@JcIG>8VRij2M4>I@xV9#e+!%*ZP3mO1liNpwZ%Ryg`Hij7XQ|?9{6E_U6bo7u z#y@q;5xgkxED(KcaGRJ0^~cY2=(w1g$+mkPDXDgCkP`G!Tr4OJy>F4FfORGyWG-f$ zeri)_B!%GI4J381+_ye8Nl}<0zC0C_`JOm{N?dNrG$JmyQdp~>u4Rn(-?A)J^j=k% zp-8lK9Zh*@7={cS?Cgxpa|-5x`3`kh@~!xflWkj9@TVPAVC1nX*GwJ_2vj$t6Mkj= ztYj@yZfkv@57#_5odD+Ud{tJy(Ulc8a&AJDMxy822-Q+x_w zum5$bA_vyksBc>Ww0$ufhg-=5&jEjXM&kJzae!KT*B3YUqb@;jI z784i%ED_QaSaaZ1EqSGVUAcr#Lpc!{Nek%%Ng@HLLa#`H*)*Pm(8GQMF}+ro0kFgw z)x{_?6m#qnF?eAnVzK`rQkxY3E$T)}Yc02r{I4MxivKZyj`B6{jF~K*gIs^|aw9e9 z7*O(D$ytNVDL2nVr1~p)t$o;-zXE%CJc=B`4ctT07EBXZPs-csyAY;u7TK2Y6IWe@ z-F(-x1?jt6QN|6-41O2DCnFI{?4*v?sY)^jigPF+b?18pd78LO1aH4}9py0_tN7sl@#0|H zV>*S?2~T2?c}{8a{>EMDvd~w$nU%HzTmtepmazfM#<1Zqm|fhburelm?;M;4L3rk9Cqd-$%Q{ij36s&#iq&uk7Ep^mYLw(nA^+DCoH zxjD&ST0@z^Rap1A9~CJ3`MS~nQ3ZmPC5o8 zzHI;`gLkWBRVrFFR|PEc(5;y>9t2u$E;ak^cGol8Jp-{-0R#o#^{`{^^YivIybu?% zEfAv0ZhxR1s&Gsmosqux^+Ayp#!||8*rv*_D^t;`+T|MnHyH09r7l_pE0<=c zlE?N`QpCm+MG<&6U!HjSOno@alWc2erz++2<(%UnI#JlH(qx}$#oa^;{$3K{4dfUU zk~|y-6Ap_v9Ck5kMzxFzryBE=j+V{8d2~D4x*u*I0Tn5Co7O*-Qrib}ffB3lIX6PC zFZ3r?G4{vQiF&M%*kqh#0$CPuqooOm$&LD%u5RdxY@JkC!>(Xu*-xV|f)GYLy4zPJ zSZpWN8if>Vx9O%keMH(Nk~8qASbY_ketQp747XZz+rmJh?NFI*nftV+^!@M8&8zQa zsVOBKIt5n7X-|zcKRX7?y5_@sE-FgTCcZBH`{XC~#b67DQ#b|2vl3ajO}lKma3qS= z$GKE@Ww_qlHcwE|IJlmC>@$uKiCwLiLR*M%nvQP{M?e1}B_J|A82{7U0TdWmh}L`` zeO7krTPSDJO5lorndf}p{>9G??v_BpzsD}?t^K*k)S7&Qx_Z35RmVbyMT?O4Pr=@4 z*OsDhnp|x+K3GOT+t?6pLFbArqVu&HH0tj;dvgeQ%o z&n4R5(j&i-FwF4N@&VBCPnpXp*Djrj6S(<699xwgwt67g=~xS;19Rb<%s&2WJ=2Lt z;0kvp(03)~h68wC)k7HaL=)f}W~5OS7l-o@%vmEpQf;8>G$uV>~({s=AO zW!I7fsEf1NX{{B9p3mBq43oKeuL%r!M7WATYvKKmjZO(4asrnBy~t#AN(!ss87>-q z%gwUncJdezF|_J0t9k?6+epOYpc-*)?eWkxCi=i5Q7(t(-J)E_owc4Ra%P)>YioP* z`@_CCSFOw0+=Z?Y4!ZKWk218A+83R0MVu1G-ObL>wYIv-%Q|`W_gsw;BL@o82V%xZ zMT#%F?|&Oy+Hfur9^-@n!OZ3hkaq~hu7O&Xd!)f5yv?gXk}#?qeeIlU4;z^c&WoLs ziW2PiP*J=N)I|Hk+aS-oZ4|)FcjQh`Ki;gX2<{b*BLYb2>OQwQ4+trsHIJ^a;C@0# z6HU0)%oU*cx<B&6i2e+`o&`tJ($9OU)QJL@b! z-{GxV&RVd}=H&a2@>#Xp6C_U{m>&ibh(Tgced(90|I1qZ1W-ty1HwZA!?R1wved{v zROx&MXoT$pvP~8pI91eTnP%W4%iya6;1qGmWtM0ldGscz@T{*ct&y(&&*C>t+M^|@PMi~F1H$tp zwQ0`?^M>>2;NE!$IzSmz!pfDstgl?BM?E@6t=Y9~W_g@|a-aSbkTd0T!jYP7OUgbS zP{lQ_8ka%Wwg#(4Wjn+k^Y(B9amJYxhSWsTwq_}Z+Ek%f{zu@aM=6xYx3#H39ApI@ zUolicG)A^x8-}$#J*WcQuqpM$bnzqhv5~kiq40C;!SrQ!BnprL0L786EsQZ{mU>4VVyM=uu*jrT$s0dxi@i3-#g?)){bF&%c}{-XTGyuL3B3|}DG~ySQP_#y*~lC{*Uho_bcf>Ol4z#5B~wEl zlbtSYjb<6%U<6kQOGrp?pOJEkt#BN~CJCDrJt(?Sfkh|W3EVaX!*au~5^gR`o=?4* zW73D14rw&Fp6R?wy;&M)$cR<;R;pv%_sUp1NpLUznK2w>s2NGWl=cxT!CzW-Guc1@ zn|{wEf3-5m9n9~1Yw>ih{K3Kex z(2DVF2-xckoqnje%TyylvFY}X1Y(t&nS@#lM`F~OOT&q=m!oY*YrVX^U~mo3is0gu ztogM_b;WOar%)z++CmfM*<%*)m+6`ei_9PI2|`q|&O66^v6=WvE9&F;^7@y===yrO zXhEOJq4#eo0OG9~0cO$~9c0#sXe}mu&#LMmW>)Jry3Iwo&v}H&-JNQ7g#%55t>4O& zt1|y8Qx@d%5QEwum^+^rv*JRbXMKIW)BO+g0IlH{*M(J|JwiS`zQc~n;xP6Sw`LIN z{*cWmc;0V0nLK%l!+12!6}K*@u62}astkZ|jo#yD32m8yR~m^MbRFY}Rbh8>#+hjp zM&9@iV|FGoFE}r930I{X$5ZNh#9Qzj>EyGsvff{;#~NiJA>H8KBdQYZdZu#<=Fc=# zjeJFz(cRHsPZ{eit#L2Q?A;nz-s+8|E1VJI!>+Le)4SWg)Pyxs@U9*3-LFlAsdUbS zlAztgHRQLg(IZrbs{88aHRq5wAKeg$?8`CG`&!Q2Dt3k9}xsAm}`%kKdnNKdf^ z!81`GPX37r`H!yc-|#2mw&sBw1Kf-YK*#&0*aM(s5n#?a2ox(1J{*UL+X9pdfW3>8 z%H1Jh{od91>1^vC5jf`p8u7$7tMve=`aMvGMBakgxVY#Tqs{q!M!g1af>)tK-U1q* z;?Ac$h!iSER(mJQEm^`5>4E5NqAt0tYT$m}@l z)3Xsz^4$kA=K>O@sv?+Q3u$Kqu1U}w3FrL?#3Wp0SgkFpkcg|b#@P#Lu>0cVhrC>h z^e~!i{$?seUN1KFZAd4ycks<;bm5+5KU`rPEF!b{E{a|;<=u1c=^OKISCJ#TwY zdlwZTMz>gv@Lru6{vz0TCf+>+VRNjZu2MemghU3{mmrl?J%DdAp?11ID5)riG_|WI z2H%-!fEb|Hy85fRIUSt%HkuO()${I634$LkV#g0q7Tk&i>0MNA>5UWi**Gd26}kRaD^t&;yP?hMw%8j;qQHhBH6Cx#l5wR_5D64VYz3 zUZczzS+IC`vv9vn?%U$r<4&3B_xBDzKPQtOir!u+Nvl zy_Z?@X|e_a>s=OYnp!bTE1wVTSFADN)`Nm9YJI%C2w< z=!;`T1NMrqIozJ)zCtT7UO4{JzCN5RxURp!W+4wM`Qi7>`fBJUfiQeWo05X} zMpHr7>U$!52}Ag`b*Brd9LFcBmFAg5YUXhQ6vqe9|3f$UTMr4|&GCMGbmIWPhn%Js z-AobsRLbn_ZR+e=gdupzq`ZMRW7Sj8zLVvS2l24%JMT+exmrM=JM;iz6N^N4e*D;u zO%$9)*DWuILIk+D8rE<=q+-nuq33WGj9ToDWRpH6D|9`tew^m*m}@}}nY)_PD6pvicqL}Z@|fB6VJq)+ z-F#Pnt08%><)%8RMcIMDrDCBMZh|A1KyR5&{#fX_qzKy3@K7yvB}wH7WJ;_oV}VZP z4a*y1ZupKtY3%g2uRv)$t?--HK#~-r-^A4W6|Ii+qODf%$nagK8rmzb6azV4s=)#t zO}|h`yJtwGHrA)R59zxE|XQpgF>u-*Qj^+{F*!I($l&N) z-dDIDtHhVJk0r@&vzEGIU#)1Mxri?40m2{o{WLego*qQKK- z^mBD`HL^Pd>|{@ao%6^Sw@(f$7VzpzquFkh?WdcgjR&mBvoG97Guo{rK%jMMXrE*T zKjjfndnn8ehz6)L0xX$k;{c;-CS9))v#~M=MEb!6|1Hb@&$;C)7@&Ko{O?=X_w*bC z*bX2(06lPfK=s%EHnik}!jeWm8zl;GjgTaeWc5l<^HNEEA!eX8cR>fNF$vIj`z9p6 zaDYHxfdt9+KosI<9umP3O5%^B=7tlW0rQDG0wmG|-W*yM`I8&hf8??D$4JQsWj2Q2 zvRktd;Rj*4>FVsZW*7B^H0rK1r%YascJfWgjr%gGK2bheOhk8(g*NOvj!{y|B$Lz^ zg@^4|p6*tnT!e?DT#f@l{S%PRp9`@XRnNKQWkPJh4q6N z>lNaeJuGC!2sb}mC0}>AP&ScVr%*=NAENL^%5*QCY{PT}bQ54>*{+z17u@Te)KgT^ zjIT}qK8l6;gg`VTr0+RnTMj!r8Zit%bI?dzM?LB(MO>mpmS2q5 zQk~_f9c24}>xRJxn_7+_dH-Y91byCLi_4P$tPzlZBk`JERo1Qy$3 zK|25g(Ea8%)-*ajyVxi2+4NU#Y6^W{wEM#N;V8XtJ&6wseqohDu=k6r@NrtqVnw-F_%!LWB5bh4 zLO8dP$K2=IfU~#qdgU>E4awfMX`-s5D33p+6f_TYht~ zNnepdbeVH%o*8qEAEsEgGO#7C8C5kJZ!z0KyHS{1T4j`A0l&+s@^bvEyjom&9Ud=l z9BDe2<0*>Z%<^}Fjx9cG#)3gt9s@DuUtyCuD7(u+>o(s)Zt=L;wgk8L{^;u^W91ho zp2xcbkiBlNC=44SSY>UrvDng`celiPb7YNIV{$pkU~KlSLj7Pi<#>H-cCJ?l5ZRyX z``vvBVS}PXxKzE&ia9heF-B4<{{C&OSDf)TJ#bzvdPlyegrl|g#w|FzC-3bm{+ab7 z@yFoC1EB~X>*=SC{o$J_&&##<01UtQ#t#HKP5b+T@ay&Pc4v=ZHN8sz&4;xsR0@Ccw&`{`1OSd+n{I)LmE!E!TOG zRmYV5(+dL4#)5E7&hh1pLFC*|V=Lpzi|gAlI~IzRmi3NMhs<&7%Hi9%YHQ%Z4g(Li z6(^>BI9%Pq?ESSybR+rgOU3QFFd5lFdy%xpfEy7;5`4aBWnE=iCBu4 zlRh8Cy42J*_%+l>aJiQTSi$3mfVkKq0H9OQv7^ARhC-^mpXh*)s`U8pGCy$nzd(U< z1d#DTZ+X6_Tb~E70wDwhQq9VQ8-^o;s7kI2C;u-z=Z=hnP_Z$OhO8c3MHY2lGxu!4 z0nlk~Xy#U(2ts(k?f$rJJV#2TndB)eXlJmBBawO0CuyeMJ(eGGJS0T5xaY0J**^!Yhe+3$o|y3O+LLyBv> zb~fa2vQT3)uh|?j=xrZ{-mqLAcb!c%EokAmT{PyuMmqE$e;@E5LSvebbL8d)18tw{ zrs|`;3b}@S*=q(O-^$kjK!SoDl?G`u0h7GmOH=!r7UkTXtE~OqD4ud*Iz-CFh}*HG zyP!HT{^}qLi8Xs9{lHs8AeBlc1PH!-B_t+JKkGW{TvvP|NU0=kiR_eo5RD&=(+97% z=u9jyp>DMZly`USyIDY;gGMDue|IU?sZYntpvsI}f3~>68={MEcI6bnUm8lCeE+!k zA*stvjfWt7+JZ)mm_zu+VI1Wd(NbA_+P}vn%LDXO;QwMbf77o$VWtY$9%y`(Jt9ao zw%0fR1CsWEsBIAqUdfe6M!>-DR664h1IA-4DbqcIAmgob@6&UT3zBS9)X?&T2C`o{huX2f>GbqC_YbKWRhgEO;aEc@ z3fRIAQvpEfEpc_2p;T9fyx?qCdVK#YU7UDgETC8W;trqbcLHlzJ5)e4h9A}n04)`L z2wrdW6hNu`7!;rw66u+ul|xUqFOSw0Kgf%{Gqg(~7hlRlCfMfoLgHFbfZ{>F@8sv% zErOdgL_E{6^`bY;32L=#-2^DK{w!^BpJ=A}jc(*=jp0mQo9$*nJHDnClfTRx%5y+j zENc~D_W7tbutUZ18_9{hZlCxa zRTy54ZjM$8NLzBE13w3`+2e&wags^rMf(vOV`XarOG~??NT&KKfGhj4tQv|yn@rsE z!(3rI0?I+W2w~9G*2O8$RNz0m{~9a5|HC z#B30C7>*9CH1sUn3`!qA z!jV;dU(f53G_6?Y`t1@NNAIe8bEvsoo#b)+!H9$xM*Fr}Yv!*{kR!BdzsV&od(CXq4-F3@5lg1azHc3U{X40&lfmxYc z*wLEMpJoC`5dc)3ENUf!t8z^q8ZsSvV;>V}ITh|_a&bI-o?k2Sc=I;S7w6*Gl-VN) zB`e@~A3FM1*%-p=OXI8kRBWD>(&FEE(EZ$go1SnawyiOc%p)`8U1t7xSjKSJxPsxZYuTmNkRxUXHqs}f)u+rZ)H2*&R-0~; zFJhZ#j&e2=+k9TCMCBX*wOjv5t6k%U!$4Hq7qbRz{}fY9*}cnGS3B5|>dJs(6Yx1H z?I&QAK9IA2xyU2r+nzh_R5nVfg&ubBiE0k!0^q}wu$;9>+UDx>-M0V~MJ2rW0Gdof z=dU8fKUM>O8UR3GG=UJHXnZ^Uyw{g+ohE=#7C&lVX^^#xIoK? zJbFCp=Z^h&YU;C`KEwAH9N3fWU%`O^oEY`Sz8hQPF*~(B-(RWCOVv?SjwEiMgIM!K znf2X0gzUdb)&hD&=TY8y%i_P5={IJIxIAin#ZbN6X>XVE`HUe9EB*+n9c(yZEadRI ziz?-P;PCE$@AAqpzWvlNaiWQ8CoY)I&d#cVt$EMX zCB|qQ_f@;As8Auo+bdMA^@MJT zQl#f}Q_%B)B>O@xX;tmMaKy;(&NcG6vo}Z0cCsbPo0lir+O*0g-QsMo5rc*BEl0bn zr&VCub(Lmfs|y`wvb$bJzZ>`}r?Ew2K#kLQqlKNly=`}f{H8CM!`MPkb>vyE)S>OR zVd&_rin|+iyPu!bK3t6aMMzK?)0y8HiMn$MD$O@@v&i4`p`01&fUsb3y#_ou7G%Oi z-9oktfaW=zoCau5Mqj$w`l09S!xKt=bCmyo_|p&KgVmlMe46bCU2c;GNRsaS(38Zv z*_{Tbq^8DSf2G5OT{rKbh#!IU>HT`|FXTY>U1_D$=uUe#q&gsr9*9d~_>&xnE%*mz zBHs14+0+J%R2OjTXj7AwtukQH8t!+|*4BhEr+oc`ewow;s5YFaS(Qs7lb~@M+M;f% zIgHW$>)U;%7(|29aJdGcF&CNb&J;C=V~|4Y2cxN4cCIz-^M4T2wn0p&&7uk(9Rr6t zBd{8qPnFXRRI_)-%Wm3m>F8@#>B1S+JuQi9`Zf!i?{D%#M9fo5+7d{f)A;7~$>olb zy2d9usXF5yNZvj|AEIYRANz3Bqdn<1y=wfUD*{(&ZV!Ug=zw1zT&r4a;SEb-^r?^T+pR{MzOwZz;f7wi# z%Qf}qzH}8V7GG0W`Q??5vn5*mQzECJ(ir8?qO-4RR&fwVEqcOh$nSc_s2S_e?fn}E zwql1&=+hsP7;33~bnB1`{6OurMSB~cgRGc6-rY0X+xd+c!ST(SUW#mqK=(lv&Z3WS zcUtEI8|WA%#p$(hM5wO??@#Lh*vRVQlpM7fY)jM`yrw#PYnjWaOq~o6D{60)9i^&j zj2==|H4zy5Z1}!a>{77B4c~jy?=*stQjgKVz@63a5Dg@yZ6xL7TCL{4_x`UU07`}Y z`mTLlj%=1U944dGH!8yKl0WA~st?6w&nq|@Feev{j9c>SejTz=9R8)BQ3B_6la}@T zoJm63yU#iXZHama3#x)J_D~mKD~YH;@}@={k2_(iJ>U>*{OTL))|3AAN5>m+Ns>Vd z&CltAYiWktLUBoRzHOhd$_|fQQ^U-wq{@0WBQOC?GnLns|`- z_OAU#c9p`SC}ym|PQqmgmOD|~v#3OstO?x%^2>w*6cz%jaxhQH5G18QrX2x05ZZrO zd!hdiu2H;;N_T(A5n|WT+W~wLAls=l=UV{r<~;hPclnb89|k|n>YWn>YQMLad*|eG z_KS&NJx&9q-*5OEzz+X;0OcP6Jdm#b>AaUV>mRI362phM@&ouk5ViYuKu_by{Ur4X z$)1y-n;ZZH=?_N58Utef_Rz%OJZ|pBfJiggPGiduG4GSK6mYZ(cJSuiJ6a63eczG` z)0*eshqb*hyq(B}`KUy#i-3ag=8YbW%RHb;IdR5v99oRABK@_s#zdZv?1xVud~r^W zP)APO<_j?=3m-z2ney_;IG?+90-5d0OMqvwBNlAn!^wtVkJ+Iud1t>?-MFsPl`A}p zXF$v+kVoH^--LeYxqGEj>D%C9sbc;tLGOl<+n^1ead52lvu%8X;?+{-6@v=6MG+QVoW1425t z@Sz3$1Ba^!Un>O5IkTysq^s?|H9TeOvIyt`}U zjrK90{j1Y||4{_~g$@0?yYQHaT0)v!_$zq%>y#Ag@V$)zc#QTBVljlOEdCcWzW_lJ^0MjS=;CDjsmLxb| z;LMT9g-c&_aYqe#!k}F8TZ7jYF75|iu>#t1J-RR~z?+%EL|!md-PU+R0&ttCXT>{< z$puQ~@|R6kEe5rr%1{@e3GEB%=`S((a-$tBSP>I>uN+HUB3h_8?C6obCq^aA0H)QN z`qToc(dTEoZB)D+i#IW%)UHYt z3@<*N_7}lKFEt9GM_jE}#0snOjx!x95;OzgwaAawXjXRC`)@Y6no5#umSFxt-&uzd z6wqu_ihJtLM8kB_LgnAhwux_AFw7TNk-fEh}Z9*H!AU(R`v7ah16Nv@;JV_osj!M>~Skc$f~ai6X+%& z2S0JMhzjOkKLCEc^5M4OFTRZ0Hv5m$uz%wZz)?`(dQkjZpOeM_k_Fv-_si(1ZUGz( z%-u%?HSvH3ofQhyV?U4i-7LD}nNdU8#I>sWo>T_7ofgV_>UERqrZC`uUswmQg6Dsz zQ`;^Bhx>YdW>r8|PVJrmIU!QwzZ6eD-g^v#*-kDEy>VY2k(Lf5l?z{|k@lF06!x)I zI41Ht$?m;DEuUlutxM9KQ_KBHW|CXPWmF5Qfp}RsY1YsjZmPiZ^DzKXk)e{|<&$S+ zcydd zD4dX(w?GuP!u%UtRZ+^k7L83yZ-*=mS7_;^UH)r5-?8%$K+mVnpsVEf9Xj5ThGa?W z0k8&J!La$v;^2?e+LH2*Ete2Rls$Dk5$@Ox_>s0UNng^)Dpk}UxO`nsYU#|pij%qw%Vya^@yph%3 z`k7!1cL$_^PCWUA-NUjYUfUZFW&ATX3Jt8g*2w2$78f>V;{2@FUjz;vz~m5NhwbOhmS9{g6mr?x27)=AI+UtKC0%;z8D@-*R=s}M0;M#8cR>c zgf1K-=B?LsAODF+fjY~@ab~VJr_60qwT^+IwY12rstX-GClH2C`c!rC`fhSVQ|5!h z=#KL18UmF(ehVFxY7YuWZR6dM`jO(;Y9_`K48aTN**6AQU`YDQ5`Rc&S?vK#wfA~~ zFx_EG-o%T`%KntZ2|WrmIx+3@@r!eelghgc|9HoH*&lh{T5>X^UTHwH8@hblGP~eX z@9yjCsM<~0EfY@Yp)h015TT>bdi^l<0hw8=a=)sef3O3I!qKt9b&RgkZ#2OjvUZQ0^Hap?XOBw(|cgkdxy2ZTmwpUz}Z>t4+E#k zCiIz4LeKv=^6|^zB_ffLnrkXkw7;(V&zg^P3=q&<&;gpTc~>GM2<%S)o|Sr61DcPr zlT@buKTjw}WvNiX<4uOGu6FSRy8%!(q0ROS=!wdBR@2JD!?)3 zp{7(@jY8hyNZwQ*tdlYHjjU~Z+>&`rgLfsqtDYCY_JWds6UC6~hXBypmWs@|jH)bj z1;orlH5~qUCtU7m|9F7LWZNd|t8XL$$wOd$8q+ea@IT!u>7CVk#jMd{6b;r(5{rm&IKFB-fqDdZl2Rqfq^lzFr> z%-7{T{IQp@2p}(6Rl1A{2pSi~TGV;BhcQB@emfP*u81)IaZ=?Zcs@&5!f))j*KK4MifUwC>-#(qyChdw zHJMwQPi*lP&4JTbmFsoLIn|D6CZjRNd}{%uOWLQS5>Q-Ix4EUFFIb{}dCtn2LR!e+?(FRel3iezYka8o^du^{(( z483P=)@?^VjL!5c-co;DN#U{Re(;OS&bX>g;|3#>>-6AwKwos4f5`XgkGVG4|JN8Z zgRfII*kT6<-Y>tKntSflKBoq7=+4zo;fsdev~-0@!#1t?jI93Yv<6#e6`qy-XoMuk z0~T7{O{34%>&ym!IUA06slLqyv*|m|kVuooT7tAOla~J;%?7BB4gTEXYRh$qqz+Nj zM-3%^OrqW?$`NQ}y|ETp?rgZejKu?lZ@%ib&8WO=Pyz!*$lWe>{*+Wpi zX{U3CJU{Yyu;dKmAIg%O-vB}3A-|$--}{B^-r^^UZd4QMEkoWZmehV;R4mlRyQy6c zXY`s)iC?xUAr=nWO{XN7i1pYTl`EQ+IBT^ok99hFmIz}+I7M@M#@10J^Hv%r&RE+S>$%@{Q@4ss=*hip#4LBlO4_j#`Ru^e{%# z%j`d=Uk}OdcJZt_aVij<^M)67?X9sv+H23<4=ajf`ZPI;ySz8SKtxo#IUR5|JWEwb zufyVaL{5Mx`kFDvFfC0KK6<0BrhBY7rAy#i)yPhOIXPpOw9`o%)y;}o`gM~L$Ze?h zS_!cW=X}D=NBon%64IrldmMUe0#?}~;Dg)nMELnpqv+p)+ z4W>5M5$B=?SH2)F1tye8oI;#@d94CzNa;L0qC59%_#Mc8W&qOPocLFPaD@ioZ>WC* z8T7BeH|MY35-SH9^1!#k>>rnYM6EbLuj&8dvSZi?(Z;9L-u;!yYM=1NsWCwoDqF-B zrr0aGS<-Vb@C8-%cZGWuO8T(N^z3=bDeAdX>Lt%Ysh5Zb-EMqs9lA5ny;~%Q;vvKk zN3Q3s`I0PF;`&8>!^}sjba#F2_`cY&-3N}fPm?ck>&RnZAbM5N#$Bg6#OuS5;LS4d`>NG4`xO*=e`}Vc9jFeEG z$vN3f4JmFj`jQ$}617wfGK?ynQ1;`y-Zf;Vl2}~|wxlg5==+fnn#K-9&0ay$$QNw& zg5S2z>rtL+Qx{hYUg8SffY)V@8K7$W`IOtFzVSef-Bk$;q#H3|M2M*~#-?|V&JXxm z87ujz0OBhZaLxATvb=RfjfN>)q0!dHdik1boQJA-h9m>wQ{A{QOXuoRp_Op=vs(M8 z+`I>J($!?fnWmLyjX3TMNz*esQGp@|k-@`bgy=lX7t=0@Z4k&v^7TQ&yW`Xkw zb#6x@+HztP!hhK-!pf@pzWNlMHL4qPRRllub>Lv5A?%U+w~~ZBq-Vz2c~j~9E!t~6 z-IVsswy+Av=^f1Op!+wgU9D}MmK4t2TQ&HLB`D07io!ivTf^f|5FE`chvlWjzco+U zF)=`y&(iRRht;((p7gl(>f=qY@7A|a@J~-HvC7{@C9-%?+i_-;D`GA6mjwhZPYMFd-e}AdHC^c%BqBQQ-+E*!Q;~ewclGmN z`|`M-ucamB;;;lH{fL?JguxC0IuleodD8c@dRxfe7H1s;!F8`VjjX%ZuGyBeH(}Lw z>G*gp>8|fm6YwPjX(*8c8DM_(kje&gFpWkxFw42D&|mRpuh$G{>wf*Xjct9kN0_WM zS0EnV4%KyH*#1;Fl@U}Ab(H^Fs3sy~CT6tqtdy?kX`VzWVCkJK^{9xI-Y zL7PE+8fGqv6UTQ`cPdb^mgQyov5 zo?!giwQM$9&P@9o333~Y*9*t*)PPsA`U^i}@l8d@soBxp_kim0$;dO`uMdy>TAh_f zh5p^Z?b-B_xY;-_LgzKW&4}m(>lL$wioDs5YuNEX;I!ui9Ys$~3GwyF)D~%j;Kt2G zhaa-$)HaHC9T&l8?m7r^g&rsFY{hg~HEvdHzJcw~AZ`H6^3h+Drl5%%@y=1R8O?>~_1iZ1Y--T_f%vbn_ z#hwhxrV9+5IpaSiD2n(Xn7`5i7=&;QbayUh3e^pK2i?}1qUfh>Igi$}?w^oY>#9+y z3Wn?v-`VtE25+@QbsNoZ$E>z~5ct%L!9s@LdDLjI)vrjo{wpl~%(LHHgLYb}p9KlY zbt{mI>bE8$8X(zB)GQtk3tkyeLnGZGTzMg`a%t*6HLIO6-#X(+@Y=gIn1x%7A6&sr#ADp$QkT0qDt3|vajS+#E|Owd zmSdaaF%4J2U`bpbz-HDO)|7}pubhP*1s~riL>rBF{Jx?#z8*E;7iIQ!W^1)_Gn!i0Gxpv{UEW^4Tv}?`PRbyE238b&XJk5g`ZFYY~tr zZsYaN%%u|TP9?%O0zFfu1ZB*@Xn!gpXNT>zW(_|nivQ_gfsA3y&r4^x z=%luG8b~|jE2_D`?a-D3KYihg&m+yi817<4CQ=nwmwID6jP`Mf6O2nmO*Pn$`XTE6$MWokt%&;Z#vk#M$x4s)KRWD!9ATfy6`=s=KH& z1h#}!+lyUC&rg5cNxf!{_c{We41a%Az~GGfHZ{b21gmQQin(tFp8T9*xLO2{^YGqkC^h^xLD5<|YX z#27g0W_kspZoJ;3b|Rw@hn8BU`MA(nsqw&{g`4~M4C7Wb3+Kxa#CTW^-5~EN@ML?x zCR3DvzTg>k=!<3bUiv%&%TExHb{n^>PElOV!{*2Dy%V%X_Ke z@PTQGPrBsfPEsP{_AIMxu>$(5UI!*~np#GDRX-&?x~Dk3eb`bizSa)q!x`^Pt;iEB zm3CLc@U$okFkA~+JEq5|d0!*GhDdKgPNok2NpC&s26N}1%$DFVN!=w|Syt2W65X~) zkp`Ll9gL*)Q}f-zFTP6O&GUJ{2_GJu;~}~TN#junaRx_k!@w_ZgvlY`Bl|q;IQXzW z_CFtbM~+;<^&SIfb#ed0$wF!U$ff1ArB_;{PeEt}h0sRs;Dv9WdDTN%F$v%4d+)54 zZI2q3I%{G_zmj9oU13zAI30%9sl!GCrPG z)O{&Q{9t#5@QIZFQi{iST2c7!)0|{7=+Qeu2yg|tNF8iuraj7OyK9h;5bh(hzn9p+ z$)rNou8D)Q-VJArVYwT2adwT_Dw_g=$I#G8pq(nZULcf75+V`G4pFkN0));|x3?S{ z^vFoG5`B-qy?#(Pydc8ZMk+K|VyCWydTe0nmH4&NWBi3uvkkhk$h05Yo^W1DEMTQH zX#!O&WU<+6L;bU5E`_my>_lUA!;hz@gsV+OyE^$b<0eU^TX@D{Gs9hHw!VC$9XY_a zVo^JcF{zVJ6L-gAyk@2kcHVgZkP&Iibhi^Qgl}O9Utf})%wT4Pa?xk0CPxltsdWZX zawx|uA{4`8F#Ju-?HUE-AfcY)3Ck0enEc=*33uc5#VVDh`W?oqt?z2R40tT>d8XjRcJy-LquuABKN30W>z`iREck~L)YwjoM-E$ zW2&qxDf4LKExN#%M+`<*bdfH80zVe!RxAhdChJ?zhw7TeHb^ZEA8UZCRCqznyfxUM zT&FcB6Op=>6i$z~%e+~m$c)Zc%@1z0o2sS6tn?bbjzJ9LR8AHE!!7j^!wJSPUG+@%f1<;W8I*=|}u5ps1e!+4*xe%j>Ox@SzdcYydC z4W~ES@Y@F`mJQ!1&3*q&k2WmAWqQA}?b?1kTRE~NH~#%PH%|{tlgpui!o@Jphnib? z%O`Ghw&8QBZ*ih&fy4N#`j#m=%P-5jXa^fo>vw#;alX$c_Nq1tDC4};M*P305K?8a z5*RdkKR!mo)5yr!>qqYmDYu>8u<;!csgu6vG-vjd$0UPqn!1kZ*1xiBnIj0c4Q^RJ z(A<}}vGJ`za$~rj8g~N~j@uNxVs>s&1-7)eA6h$g%p@jfv4$|TEY2MMonlI0HW*>w zpsb?OUhTSIwl+UhVl~Lla)nzb{~9;j{becc7l=>_HTDFnF-i3F6u-rIiIpM+7B|{r zNUub3SCu}?;gpI4WNw{*d6D0#qOPufmZQkMQ-<=z)rz94je8-IiQXvMt8E;fy5#o- zt#fK!$ePQIcZHYq)`us2=NR#IHnr%&{(?Y5YnK7ry)MtOioK7cb}@#dihI^$UTzJz zp^VpF_@ATQn_ChVQFRl}3#i@wWH-8sded{umKv+yS{8aUO~-DF%^&qW$=;KisE}GT zgl`b~!T>+%7y2+4HdBR5iDKdCZQll=0{(D1wXK~gC5{xAijRo6BMVb+@1qKTd5Wx~ zBZk|&J(8`&d&_C0!XY(D!V4uMeGynfw(_uozIyRvoigqj78)vNJEeQd^tzA4ghk3f8?$N7_w%M(|C#7G!S9&c^2UB8mpQB)i$DP5;=(%eB zx1Ws-WcEpuS$#fRXur`J?SvnxcW}$LlSM=8%S@P`q}#i+6Aq%k7@Hn4I3l4Sn+6Y8! z%aiF{Wof(M65}GZLF`1x&1tIsg<7wrjq=g@-RY72bEjz=wSwCGNoi*0^NN-t$Y^2^ z4tv;RrK1U=F0&E&CJht$eoc-%Hed3uPrb`yt-k;1OP9CCRkH1TdDb8!{Cm6{8+5CN z!E_e2srj`HkYV)~>%Xa7xwHv4s9JcZ+_ub}colj&8@I!+d>Cg|CU- z8VTfp?~EF3n6`HIXjdvTNi5Y==6L5%nT*sekF3UA#>7pG1ZJi&IcK`!-HWpssC(aE zoZj4skE@a5=U=xRSYlC|+sN5iSb#6%FHTcg8R>Efm`fPv-Ey0g{QiUJikfUtHHo!o z4_zhs+dSLv=VN}>7oa7b*H3yQZ(u%ICGm2E04 zyR^!$xluIIXYwNV2zjO0G&L}VHwcR`J8<*|4 z!j#Ze8-}dD_>s8yF#^gW(uT~~anjSy*xvVxw&}*tYH6QMyI}bJ8)28s+I90lNEzF4 zNu6|T;cVUV;apO=dLZe)oX5tE50uJV8h^DX_`bd87F=z|qhM(myYqUj_lgvYSrQ1n z-;D${HPcEUk>uEzBJYgagFU8*0;Wl^zF@?9o!5rFLL@Bg@-3bGXS25+yKu{gd+aQE z56CiVNiMFiAnp5KyIJjju;!UFgqazq`QF)yYWnd=2fCTX$?Vr9rVULK-~G`@2oR}d z=46hos9!5^8ZSqmUkydj^&%c`;1VNjY4n~As^swXK&%fe^zLH~+0wBw&I5QE^)z#Hj<&2xz z!llO17(e~^qf4;2?dNo>65g8}ayso7E}LV6a;T+54_cRMp$zw%~^t36^_{j_=i!k4V)W#b?n$!!$}C3;wkW6;;SH1|NM5#T!nDM zqjTL0YdKM7us=@ko~Vs1#r1TiNK~|syHB!+OzyVV19vJ}oNO?0TO59P9Oe(}Twfev zsd2*#K&Lv}#DnEQ_Kym;fZM0D#+JPskGK?r2-SEpRu6#y3viZ?L1bT1_HmFiPF84p zJ2yx`DoeWDn8{U}U(R4CFAhr5B-=`h;7fxfIic}g!#15hVrXhCmyF%kb?D5P$@__DoK_gF ztQdcGt8GUZjXK_3rtbLDL@n$OD^P^37F2VcF{rSQxy$GQgYQl=bxt*hDCO%rkL1H( z>fdg9Z@$mJU*54={;2tEsbZP~&4uz*6Nn>ckhJhzOZAI~$JtCEZJn4%WM^Rfn-#Yc z`bP80QyDfZEBE3hinw}D$TH>g>NqLd9a}?%Ye+p`S*)DC;k6cn_IylEv<-UzIX?N5 zI;{=qy0-;}C^l8>6Q1kabu);$$bTs^anO;Ty4jO%@e0CZ#MVC)NmpUvy=X06f5P+t zYm)G!;Mr5kvIfF~PA`=)Z97jRgZ!CIZs_xE4G--Gs-h7)6AwH1(wko%nnQuiO7ZNd z&0}M|LhUoWN@_AJu@I;o$7jT4fU-r-%~_39IcIqor>_TU8(=8#L1lH&0gA}=by*K3 z*`h(5#3HrIjy|P{A;HPrt2wo@+|G)pF3Z?Ja7!^XCT*ZY>CJ=@RSrYZ)Qy^wZy|xc z|9UQDr7%9{DhoaH8Fk~W4&9EO$%7*!+dm7A6@XY!BuZ zOU1G<8*d6(f5B-ZqsK#YFxv_PF-CzKQB_hOEh($)gJ$+Fx@Ou!h5!Br7}97enT&=+7~^ygu8Q%f(p#MDLDcCl8{HGe?2wml5{RM^aAX`x|D}Z_$D2ZxvxDu~QVt zGqQi)#)9-;#VO)+7d_pcKd76Z^v{aFjoN$v*J}6;@94@FY5YbJ2Yr}8eA_V^{>hF-=1*bpuhMe)K-G1{Qs_iaq z7^9T8US?vq1}$;;cOda8Uk+G6j(}L8piYa!*S9`yH1KcKPG2T;+Z4q#_%a2 zkB>)Aw}!`ctQvNX3y?wuj(~@WzIQ|l(S?|)zhe#&W^7XmOq#PRdE77j(G_IVZ|1_# zGzzCllW`7r_#QW5)6yRKQrC!WV|iHp^9BVZ=9OlaYWv(^7PcvfGEc{{0^9;QNe6P zwx6<;ONIBgGgC}n#liEjomaQa=EEJ3%VS;+{UA$Z`(-~l4E$z(KS23lUInUl6R~?4YrW{$wJJWrOtZ6X0V`%VJ*io@&j*Ec%6D3PNtZM6{WPi?jOf z(V#m@@7l*U9DFNqS_m}Zcc1ji65roMYSaLWt}y=(`Q#2Pcb1Jz--iK9X?sy=w4nC0 zZo&}GK-|8{J(=oCDVHhx;$i}8EpIxlGR&nWv!9wICQ|t{N(G0lioT?OP3bBXR_A8u z=bIQQf5cOav}{!vt}Rr8-H%+LY?T{YZS6RTD~e{4NNSTx+KOJ>8@3jG+G`T6BMq37 z|5}ly2SQrBjl;ZVNFG)xbY5pb+;sydO1DmwI#EH z?AK*YE#j<+>H0OhVq^e%Nu)x4Hh*g2clS@rHPjUhj)@N5uB~JlJY|;X;ZDX4P?^Bu zDh0BY$xCagdM%mIgf2p+Ce^AlZW5N;lIOB+p-c?{bRGXcYo9!pYQ?lXHrwu1l{iaS z^_jaFh^ENzk04o8YwKdE7F-JX210uUh-m*$7{=@E%^#_ITx~M7hhxLi#+X`TF+Y_b ze%%MbqU#1=cYd-+MJ!J^=82aa;0aM2MRCh`->Ag{X=u2)(-dk2K$E4$T%|a^7+wRE z*};|M*yLO82{_rOdal%34K|sNNHfu2LgyNhVQJzGJ(9;XqHC51a;RBU6ksK*y9~&B zMxAnjC^ju)geA9FI|}Dcw%<3Sol)#{dL9i1^GE=*y{6sLjf)7QL?!2 zk?PvU2!DJj+szEBiz~Z`x*i|BatZinTw|`R03~*dRQhz)O;CtQZGI%1Ni?ZePpMvM zB#iSLbGt9^rHgORvapF}rzIjd|CvW#5_!Zo#Qah97+jyav#2WiqusqNManyHY-Om9 z@KTZu2C#E*a3DW}&b_f;0rF2|pk3ry?md-B*14y-(Ka0}WgPj!c$EeEl1NYf0_=%g zka*Jnm&L{3dEb^$CH^{>2hw|h=jAz0j=V0@{3wFh2zVcH2i6k$HdtN|ncW{DcZbz+ z^jt+Ux0udh{5{<`pJnphOPu6c$T^r<*X&)Gg@uLL76I!7xZpKvh9+8!DKv zP`j=ky+;3fGciaorEqp;qo0vO+--no!!(<&XnH@v;zZ78-ys`fM}b&bJ$h@v$Hlr1ePg^1Ot6p(Pp&-IjE_V8(KOgVW=ABWp!@Q=CZ z>r{cW_mFK6bHwaim0-<9j}nwU#jqc1P-U{8Be_czA8mJ-y}eYk{cx!7>9-y34U;W8 z5|S&Y!Q6r-AF+dR65t~(o|9~!$w2)rP4YkYGyX%X<3Apv6_h?uuQB%91{Jv8X;9Gz z1UFwH*76USiEr0PjkKUs`utd)g(H~K>g1@(@ore!`*>-nE>MvrM)*Aj9Y|YgdzEal5$mdoM~^T&X#HKn zlz7arqJM1sG@p+prRO8;C%jT;L4IYcMQHH8a@E<}c~U-%nKCfL7g%E^ooj?0PFS0* zv#3v^C%0x#FIZ2-!wL2e4mcYagX98ESqs%jkaxa*^`644qfx7e4b;Ibjhw^ki-WNU zre3CXZykqn-$uA*G#P^*ihlO)aPsTi(Rx-b;eL$d352*pT-0>Ba=EN9&8yITt{2V8 z_hb%&H#olL62hEok|WndiL2#gF|Moq8R9e%LSEySr9i*!8gW=u zkXMIe(h89e7*V}Y*gLV3WDH+NqdhU zm1$B2OZIt>J=B-SOY2SB){V$#8|}L*?eHEs;tNtWs8Tf$Zix@zhVG^3AUw>Z5N=DNeK&(`LxP@j%_}`w~pRsrBPqY+SyCk=W>P^~!wOO+wOlgy=E`um{oE3@1>bpnM?t({VyC`AEWa z_4UplA({PO_t=TX`aiVakIR~&3yr{G5|)pyVTusPUf?<;0Z0DUqyNYC0!Iuz=Q55_ z&V!cggL)#@Mip}B1+erF(nkO>7jPA7H5MVqay#iH2E^8`6M$)YA`1)8d*45OPs&^) zh`u=eqZo+l-=2X?T5qQH@LlU$_+dx;nkPB(%!jy8F5A_cpVi`@AwW0nop&C4Fq;*s zBW>|!7>gz&TMp~@n~^u|Pz%Wm!IE|R${sll`8==K20UM`kBDa0*rgjNWxl!$o=h!- zXgmH@Nsda`lVLt9lpm_1ke1EHjKG#%IAL_>C>p{_#gNVn3q3P!CCaZ-L7ecZ7kN2{dV)~ z=fcfg@^mZrcu79I{@XQvFxK~@Uls4n4o3xi>{w$=8bapUI3H1%_P)^)dyM46i&J3c zyxX%s$%V`8MW3DKuIz@UyxaogDB9xFw{R=WTq%2o0MHnmB2HFJ zC|uwcr2X-C%K8zgBa=?|i7PI)^>=$*!+6YGFJtYQXt|i&l;n5Lgvi@?v6n;wNMQ=n z-H}i^SODxcT|oF*jRzQ@%b*qqllA7&b$M(}GyB zQ{12%;6$*hCVoRX%eDqnSOv_Ve5eOt(1%(g#w$e3Iv%cZ>sPh;Zmq~{W_5w1w6qzB zD;(fufioT1j8yl3#TdAKy$hEvsR;7Uvtp9J%=e`iQJ%yOqEJydF)~}n$)YCgY{FGi zi&-6KY&T}mBgN8tTvm&=R9LhJ{vGE6y1^3TF6ovOewob*&eRjD$z&=tcD>e1C81!w zyUD}no!*_JB(HD(#hAlCs(#HNWU`LHl7!a0-o5_N-2__5K3{|rKf4O>1qHx2IQFF} zT=H|__)Sr5ysPp-N?mbx-B#=VjV0HKOISi}xQ2)Rm(fQ+;4*$2xSWYV?x8;gd_9gY zw7u!t<3U$3!}6+BL9D$)n^o(ki}{=R-)QB=r+lH=v#{`WcsyEn$Z^ti)*VxLyE&bW zuiA+M#Am(+K!{fpaqVw!Jhy**F;-ip$I~`lhQmdow~1{hg>_5#?vSg*j`oobb`M|e zv=Se<@sRLS@voP*>oC@Vl4CX~xE`3>*;Bybf3UqfOD}O@&2;wlGlS&>D+!T)J5pJW z)%6-17xVPha|%Q0_8ocKb_GpksUP1PTzkH5f1ucUNmYNYvf+9#p4GrU^~lvV;8>Cw>xk;9)42=7Wf}hu=4#?zq z7V!3_XMJucAPa?vEm?*V8gt`aE^ge9eVxX{sB?m3mJ|%~QZC{)`O0nE*(3Ks{-^xY z0p5g;7<1{sM!A`Q^@{)R*`Gt{#;gGm>yXGjUtq`wF%j74e-uF}le|5sw&yQPm;ve^fAf|E*eA+ za8JFVUiBVp@uv@Tg?UNxTa8Up!cpOC154xTJ;jA|hsI1(;n-A@51{X)Pn1FWG8dYjL5@YpPR5L9_i68JzAjpJKJw z-cI86PK=aW$?h25qticdjI==G)tZS)kXV&hZ0>{~{*q7FW&=dH{I}58@;ZsIZ<1H?oJ60xRruCzbMu$yF zemT|?ws)zk7aI4XkzkvC72yljb#h0Rg2jRa*Xkf(uUb_e6 zX+%?h_rW!+9@bOp#SVS0UPL3om~eCb{MY@(QJjW+Z3qsyCNoQG1;#?QKaC zzWd~mX9{v0n>V||wB-qSTHgT?oFhBec`G4-GCqE#sch{pAeUh97&~pJBuU$y+5@2; z3@rg=#iOpCxi?>j#WfFa?YYu&KXv%y8OnlIY6G6OD9f=R<6>M239O3swJ;Z1W+B^o zl;MtT_UsIvl6Par9V2QUkXyWSDQ{&W34Y{(EqHx)YRim|Q)=6ay0o(c77;dhYk4^1 zUAG%7Pt?`{#Hn!dxV2CzW2z3eBw=`A8}{C<7qd$!Z*=_DKns7@-r44aUbD3V~D9@dk38gO>Pd8m1Vso%h!1211#3&BJvqXOn;3=f9{q|6QiGjDWv-IbQxK)M)aQr^+4(q=?sD2@-j|3BBlwDi#3L(l{n6S zzAEaoU6ypy@l$k;Uy``TKr}`muALew6f4IPnNFLXmliL7@vw&p`F){1V9C=y75g5* zM~Y1YA)v3#iz&4X|9O%Mh^E-@!v+9E4P#SG__%#kSMoa)T3Y3%XX*voPQXRz^obN9 ze5BT+l*a(2jB=RdBTC`^(sFc~X@eZfo2t)HBQsgmdFHmXri`O@5N2=q<%CjB5)sT> zWCr@b=z#>PplOueNfxbKtXu1$QgewbHz{KRgy?AR$HlQZe&(`)QDouQ@hC1)RVI|r zgfATqf6fCV6r0UC2w$5ZtUOxW-LDR%sudyoV_ua+fHXzGrFr`6$Co8eSVjF3vmhRm zdP6{!b6EDK;3LS*AAy8b#$hEPj1gRd6%9M9k)#r^WQK-)LWevYR2xKpPb^rG>?aJ8-g-I(_t`>d_=WSBs}-G=#;P9doS}mJH)kUD zy+Ba{R-GN{X7j!8txO4g&$E;wt=FnhzqBPkY?dpiFxHU4Kv3*XoDMSqA72)Jrrx?_ zIji<_OQH1)eoddM#%W+-TSLkx8smKGU+)c|wNbT8j_pW^Y-U!LIj$%9y9Y94{^8L7 zg)83rz5bpBi0shCi8_Nw+jrYSACl@HzS0C8CsdpWt2zo>+rz>5uqrUZ?EKjal)^t=SblfJtuj=J* z1Nk?ks34LX`ixksMYInn!7fsfncU2OQ%RHqNCS-o@H(NAKS<8sPC^YkzAdMDDCZRL zy8`VK0WCA&#+TUXk}b8a1o%q@GD9gzKwn<~^u3ZF5(~k9O1|YL59`TmXAN-=WP#_A zeE+AWm7N513C*<5bl++`4lskzTeT*TPF|COXGo_;h#BmPo+Ey}P7^>36>^|uwpU?# z66iqg3Hc-Z_PK+>OBNvzh3)NZbONB z%bujGMuCXXqW}Q}B$O;{~p-$v~QECY&A2)`(Tc~gp+UC|@#w^Pwqbq)aQJj-ow=kMbDYlJ( z?KGdP_i+NMiVJ7d$&tvfA@Z7$%3S$oLQ%@Bt5pzgC_pZkMmR@r;bdzTYmniFIs=tX zvY@F7?5MBp(2l|y1Iapbwe!q=PBmNHfaxmqB;TU34F_+c2FsV<#8v6RstMmD`>Z=w zh9X`lD-Q(27yoLg!v*m&ffw4h*A}`Jw&sb#5R7s6?sbQ&Rrb>oBH$Vk3u%o?&rFElZ`j+H``r3}S5q zHnK2tvyG+kNY)^RTWC0dQKMUz?7$A<~y@ghsS=frxFXIE6vSDV= z&-~Jo2y_8otl2B^Sh3JY*~Z&W)*FQ}N^p5?EX9=DpgRK2)6cXaS)9Ii#Sgfyg|vCA zef<^A@>cId`tfl&Ial>7?3442>+TENjhY=dYYwKe$bc>ES;|s>2nN28&FmPdI9M30 zH&9t;K8RoyHV`(_xmPlMb0M$1nKEv4n7|oaBBpjJ6xNhs6GBB>q-HRoTmoP8G2bXG zdOMUk9yLulKH6#8jyDq)1?xnLCb>BSS5Ok%?!@ZycdHs%|})l0SHpGT1v(n9`k?>Xh13E?d=c&j22JT6BXZUj!?ffm-sItqw+;&zBN*C%pey z-^@6m2Vw{$V~W+z(`g4HoNl7(H0hQ*-!S|k0wJStv7}x23)MLm&T6_oJ_jW^Nrl89 zQ3u^Ol;w7b;p&Eosev7f9@-v!oZAoViX%0x>9Z?*qPKtca&O~tt{(qd;$j2Azzdfn z*A~!;F%dVz%)1kASh#{{;ZkmP#J+oT7%;S?E&Cx2rfIrI96P%F@CD+-gsUP+_b}X0US=zY zxabP4RWYB5M*IG<)EhsW+4$Wnba&5)r!JntB(&>3%D)(+!+CVgW0JQPo!R^8V$nzg zU&E;bS7zdlhwq{w6l=-3El=<&M79A6H<*gt=TtWc%iTYZdhgh44oq!Dob$QzS+y_T zd)O{0EKvEC_)|)6!NfLK8(^mtf=rCOx|XW0x|t10RhEJZaQ;ejhn`7{GKab=fv*2oIUGcn|FUJ}+4XnvEkri& zUYcH{#Tz3*B&TBfTwL!-d}o*?D9VoE!Dbr3JzrBbqZoMH6nTH^S|oY7SyN2-!w>`p zeQk#^TCDZtGth1%2|W+kTtl%jr}q() znNfSR8D)9=dsBs}Z0B2Sc_AUFtuLw*lEV19>&ix61Q7$7^|5jG64OneHQT`mPK6b( zp>2z1pIpSqiuZ1qaPl;Vg3Y->_sEU&B%~){#~&D8qqKc|hd9bV>-eyEhd| z;pOK@s3{PqKMa2@Ako|QkV_Z(sM{8bsV@>UvU|@>rdp%1BRT39w&qo|vzVo#Zczb0 zia+v32h5A3bVg%7ysRg2yT~_rc5N&*eZ0N$rb7Yw#a_i>Lf?#CPQHzum)>=2_K`Z* z)uFqIUqKslL@m+KuWOSEdWxhRK)X=dp;VU0y}U{B%AB+*)fU<%55dGFm0LK^hB~D< zF)C6oex!ZF<6A{Oy}~iA&v#r*Otlm3r&r!{eR%PYvJWKG|JB|m2V&7ka_K~&^ZP>- zx$^f7g#Sp6|E)Q}1qD4nIT^YW$R;bnF}K25JtEaGe#K=jE50QIP1&q^Yoj_0om{RW zw_1IK*m{X4*@h4|I}yY27${BaWSf#dC+4vBBiOO(AqYizpt`Y*yAh>F=Qt|1A!~MN z1Jt0PH>gbVZ#(A>?^7+i@Akg0DI2uzPREVrop# z;0CCGiQNP(9+ys8f0^b+c2?$uk3d7qH@hMCvkMWQ-Ypzhx*ZYpQgw{2zi)Y|l-;6} zm0!eEd(Eb`H^;ijbbDj5A#At)9BRzYbm@ALNcOpy6ZyObpg7P>&z$AJj9|+drx2=EfL=J-#Mp3#;9Fg7=%1*>tNy!m9<)87Hzs zpmRj}ikn57B8^rLX8Z4HwxYB5*oEELGAws?$G+wdRATKhxu#4$574&Uha{UVk-rQ^ zv>c8HD2aBB1Pd$$tL@%q3zbb8z2j!du#^YQ9GonWWfsI-;->t5nO_?}zRznxDzEEA zSXnHemC&*8c3DM+L{!yF+k&D%l}IiU8+=)aVLS4dE4FuyC*j$jlPe1tW^mie0iYKi z`KuSs#k3ArB+HmDM~O$Js0Ota>C(1iaxSr1d31d(ma+0CQq7luE}YoM09O3^?&17B zy7!yz1&jaB4YB{QXJAWzHcS4+w_VTy#S6)UiGL7mW=Dx)bU7el7gQ!b$$8ur4IX=r z>Q#^6;cmYlxNCsw>l-$?L@c*1{gj<)=SWQw{1178s7!CWHW+@WL?;T*fp{N#sK6(J zTOu6;u*3hM1qX6;AuOuPd;+imhXKDWXbP5qss}s@7U#KGCTJIBao3mhXtb4fcvx=JLGh|%bgUhhyMX(iFCk@`O5e165A1hk$RsR z1_@8C^`&uc8+2jJd3s@h4)4zVQhBSx5+Y&0+*7sQISGMF?gL zqJoUW;}a4hT^GKz&kyC94`!;!-PXz1d#IyWHsPydwhuGwQ>aSw5wx;%6{15nJugTI z^Bh#;ag28OIU5{mmpW91^=G{?=vK8JH3}!}T(#r3^2sYA?9E#v?4rWwURidIp=}r5 zDUZ@UCrn9pyN)af7)T}O@f`|}z-RT{B8`q0ie{y3kV_4bic z%Ui6l95q-;d+iN{g_+TmC*ulLyP*hGRF6(z4rr&}_Sqj-41iFTQq2_fT{N}vc*iTs z#TIYNnp4n=F<5kMUVAR)oU)Op5tU4{@h#kDVGXAleQHUwA#tZ;c~It$CGreHqP`B4;^$ zPTz$yECl=4^{nGea7LQB6}bJ4dp>iFF?<{GfVVpYETFKn|C~^kWh*OR9BVFaB{oREzfrg2OLW8|4f4lL& zs~D+2H0ILo*I0C+?$)P0=t*wBakKwB#e+h!AeA@9x)-=AEXH^*-AXZ8a_F9|!kE5z#1D_aW={sZ&9`>*-> zZ)6dW==E_-fgsg&0zBibntU?vK0^RVo^(5;K=kQ%j-?*(JDBT4*&Se{4x`aa#O=vH z-s{{iruWcdK#|?m70Mt5uhq)L-Cz3kp3@<1tIuDR5Or}qX|FJ5VntCzxwAUFuvPWe zpqoK|B#3Xa3I8(@Oan`Q0aQaX%1!D?@`GPQD1*{=4a1Y&GVKNyXB|-Kj%M4TgHL>@ zz>ei?Kb}#}Qw*uECs68i^kl0rat-*(12t5mFp5bKiID%eQ{@iKdpmyj6a=Elq{M(V5UC!R zicKt_G4fGRw2RCv44A=r)X{RhD)qFqt$8%{Hs>Pp82t)dP@3?zwRyNhu3h8_SeC<` zGQo-gg-;p8pWf3cG`y-5%Y!5etm=JsW)?@lW|XumP)WB>6*#eqWwZU%6N2PRtKmtrHDe5lFd#t@7w|4%fpNT{7o}{9{yX^F*U@skEh+?Np zkpxJ8KU%^L=j9l2djA6%rL4x40z|^hoTrcMdV+nBkkLm!G0~%z(5dx>w~n&u(?)_o zF8pr&IZ=2z2b}YN;-|=W-MfczH*(Y8gpik|zkOtrS*eQ6VlMW<6cvz$4N_#>v`eU1 z*QwLi)1*N1Wb{JX)6FnPbcoS$HPx6K`deT7=k|@?0^4;3qQLfBf396*vH9i|K`34b^{Q}pYM_Xrp^RX3~SGz4n*HMT^OMt>B7^y z=fP_7{6jBm%`SJiA8HY_S$@&6zd*rX2&2Q0@~+_;2o;U6cPpW1o8JF|A%DRt|E3oB zOCSBtVFmD-?B8_aJ+RF*COkwK^kAyeJ+yviB829UI;C(=GnqAcduIF5A^jTElsrqb zt^4>zz24LPEgX@}do4Z|1b^#WMY%EpcHtJm_t4mOR-|t&E=41`Q*hZcF6rq==gipB zIH6Zl^P}+e2e8MLID*6L`ikc0jrn{l)`m**wrI0lTuj_F_P=pRGT)upvlm_O5AQ&# zB+eigisEp~)p#Ed`&ITT}+KoEGj4Qf5hs;+`wH_xy z5LxzZ*qvFb2@&q~{_&Eq$h7}fJT9oM)c40Jr*C!+QOmWf8BQ}OOtA2Dlct)4Kasbc z`KG$M2jBa-ztJfu;t*kpGU1!t|3Q(}vg7%cN6%9aN%E;%}U;>k<#?bwR8pYC-^s&*4RYUU-^SG*cH!p#H-i>Z6@;w$wV?OVzk zDcZtzk(QJDZdE%&MX|lRJu6M`GyX+V;Gp zU3pbg#Do4ErMJ)Cay{R{X4NFpQfiHEs}Qw622yvaS^f3)1 z`V|x%At7^ zo^Wg%oA_?GI>e?fdcWEoEbPRFOIEhz{H#~}^bMZ#W>`DI5VoYp`)Z-6-Fmbjw|=)> zpGjQ88(;2Z-A(7=iN7!EK9@mgJov#h6L>Ih(mvw5;xMysvPH$hOy;}4GDMb>FcdLF zkk97BA%}WmyXO-L1VhF`eWTCgPTh>SYJ!d$v)IFc{U{@7Z1O<+VJ( zHbgUhPui_Yjlvjjh;4P^F*OaEa?Nj+ad!+K_Dw6Z=f56Hmwwco#>Q-Zy%>G-6VhnV zdJsI@V+Qj3+2|sEI9{ele`g`JepL)P?m)3MSkYF{eHo0wCV~nXSXRKhuuqlnCe;gf z3)`i3;G!U%(s488x^p|5z+Qj2j&1wQYB6*m@?1^uw_pS}S&xTyD)?hG3@id*_Q7^J zNh0eI6?m&(YNOqppjJ~zu3%b)KV`z%;XeNJ&K9n>LEX4^ZLMTlriiN}ui>PZT>9Dr z8+pSHlclCzHTN;*UJDARb*cSUl;1AKmpkiV&{u$hFx;?7L#PW4Q)(zSB6Z)&!?v5QYQeQAD*j-7a;8Y| z%vNXUj+Q)pMFiWXBBJek)TVw4;*AddGEzX#Lg9muM;F9PqHK?PZ`4f665}f{K+nBu zY<&UL#JhBNMldd9Y}<2dJ4>W(g~@<}f9z?z?bd)-Qml`+M=FbkG4s_B#MP=BHfUM7 z#q?c3oV1Um9&APWG2AbKp-en77;3jHJa$1u+-X?1adKd1o@~1r@l%)ID_+^ew{Ex6 z+Pq0VpwwJLTx3ez#k1YIsxFlZIaNDuviWc*RIioq3yltNUe62a?wy zeJiiQn$^s=MWSIdgn;KRyq3x~rTSy~6QJXN=ZcBF?U_{H+bQskgXqEKr~bRM_yZZY z%M;koUslXHu%uR8S?HoTrurGSfi7L?{rOk}#pSU6URqHCGQ8~=zfaCsa=8+Jjk4rH zk9$XPomU75#-Bf5{B2!3CaF733)m)lmaWC|&ZL3u`o;A81FG>X$rV};!dg)r2D}5~ zSTW0HP>zN93`Ck;wxe(Udb?A(OincWWHK(vR32Ha4d~xadRU>MJzsx28mr zBe(0vg7haNy;ju@v>5lMXt4f8J_TAhr*C1mX6~_bg-^O+h7}P`xMX)I6c9Zgm6UtZ z2WM6KXh==Kw$VTH-dkUP_Sq1Bse=`%yMGwPwm;Fk_^Io6vHUFHT9RuA;ya6_gsBjI tw_t=0_<|&q0)#VQ$^hj{HC#QAI%R*-b*Iaa_&3f-6l7Ilh0+gR{C^9StgQe5 diff --git a/ProgramScreenshots/SettingsSiteXvideosAdditional.png b/ProgramScreenshots/SettingsSiteXvideosAdditional.png index d226d4099aa08d4e38173a1da0f5bede53592b26..29c4854a27b6b56df63cdc25d15465909bb22877 100644 GIT binary patch literal 6527 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 literal 7059 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 B{eS=f diff --git a/ProgramScreenshots/SettingsTwitterUser.png b/ProgramScreenshots/SettingsTwitterUser.png new file mode 100644 index 0000000000000000000000000000000000000000..d47197fcd6e871e6091c7054a0cf174b48c0e99e GIT binary patch literal 7121 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 XyVxg4QrF2R2b~!VZd7A%EB3ztx}kRJ literal 3704 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 U&{C^B`z-=Y3@r>QK>v#VH~$1N>Hq)$ diff --git a/SCrawler/API/Base/Declarations.vb b/SCrawler/API/Base/Declarations.vb index b1be790..714cbad 100644 --- a/SCrawler/API/Base/Declarations.vb +++ b/SCrawler/API/Base/Declarations.vb @@ -9,5 +9,8 @@ Namespace API.Base Friend Module Declarations Friend ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly) + Friend ReadOnly TitleHtmlConverter As Func(Of String, String) = + Function(Input) SymbolsConverter.HTML.Decode(SymbolsConverter.Convert(Input, EDP.ReturnValue), EDP.ReturnValue). + StringRemoveWinForbiddenSymbols().StringTrim() End Module End Namespace \ No newline at end of file diff --git a/SCrawler/API/Base/Structures.vb b/SCrawler/API/Base/Structures.vb index 29fa892..df56a67 100644 --- a/SCrawler/API/Base/Structures.vb +++ b/SCrawler/API/Base/Structures.vb @@ -187,7 +187,7 @@ Namespace API.Base Post = New UserPost With { .ID = e.Attribute(Name_MediaPostID).Value, - .[Date] = AConvert(Of Date)(e.Attribute(Name_MediaPostDate).Value, ParsersDataDateProvider, Nothing) + .[Date] = AConvert(Of Date)(e.Attribute(Name_MediaPostDate).Value, DateTimeDefaultProvider, Nothing) } End Sub Public Shared Widening Operator CType(ByVal _URL As String) As UserMedia @@ -225,7 +225,7 @@ Namespace API.Base New EAttribute(Name_MediaFile, File.File), New EAttribute(Name_SpecialFolder, SpecialFolder), New EAttribute(Name_MediaPostID, Post.ID), - New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, ParsersDataDateProvider, String.Empty)) + New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, DateTimeDefaultProvider, String.Empty)) } ) End Function diff --git a/SCrawler/API/Base/UserDataBase.vb b/SCrawler/API/Base/UserDataBase.vb index cc1b5a4..da557d4 100644 --- a/SCrawler/API/Base/UserDataBase.vb +++ b/SCrawler/API/Base/UserDataBase.vb @@ -6,17 +6,18 @@ ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY +Imports System.IO +Imports System.Net +Imports System.Threading +Imports System.Runtime.CompilerServices +Imports SCrawler.Plugin +Imports SCrawler.Plugin.Hosts Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.XML.Objects Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Forms.Toolbars Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools.Web.Clients -Imports System.IO -Imports System.Net -Imports System.Threading -Imports SCrawler.Plugin -Imports SCrawler.Plugin.Hosts Imports UStates = SCrawler.API.Base.UserMedia.States Imports UTypes = SCrawler.API.Base.UserMedia.Types Namespace API.Base @@ -108,6 +109,7 @@ Namespace API.Base Private Const Name_UserExists As String = "UserExists" Private Const Name_UserSuspended As String = "UserSuspended" Private Const Name_FriendlyName As String = "FriendlyName" + Private Const Name_UserSiteName As String = "UserSiteName" Private Const Name_UserID As String = "UserID" Private Const Name_Description As String = "Description" Private Const Name_ParseUserMediaOnly As String = "ParseUserMediaOnly" @@ -141,17 +143,30 @@ Namespace API.Base End Get End Property Friend Property Progress As MyProgress - Friend ReadOnly Property Self As IUserData Implements IUserData.Self - Get - Return Me - End Get - End Property #End Region #Region "User name, ID, exist, suspend" Friend User As UserInfo Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts - Friend Overridable Property UserExists As Boolean = True Implements IUserData.Exists, IPluginContentProvider.UserExists - Friend Overridable Property UserSuspended As Boolean = False Implements IUserData.Suspended, IPluginContentProvider.UserSuspended + Private _UserExists As Boolean = True + Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists + Get + Return _UserExists + End Get + Set(ByVal _UserExists As Boolean) + If Not Me._UserExists = _UserExists Then EnvirChanged(_UserExists) + Me._UserExists = _UserExists + End Set + End Property + Private _UserSuspended As Boolean = False + Friend Overridable Property UserSuspended As Boolean Implements IUserData.Suspended, IPluginContentProvider.UserSuspended + Get + Return _UserSuspended + End Get + Set(ByVal _UserSuspended As Boolean) + If Not Me._UserSuspended = _UserSuspended Then EnvirChanged(_UserSuspended) + Me._UserSuspended = _UserSuspended + End Set + End Property Friend Overridable Property Name As String Implements IContentProvider.Name, IPluginContentProvider.Name Get Return User.Name @@ -163,7 +178,46 @@ Namespace API.Base End Set End Property Friend Overridable Property ID As String = String.Empty Implements IContentProvider.ID, IPluginContentProvider.ID - Friend Overridable Property FriendlyName As String = String.Empty Implements IContentProvider.FriendlyName + Protected _FriendlyName As String = String.Empty + Friend Overridable Property FriendlyName As String Implements IContentProvider.FriendlyName + Get + If Settings.UserSiteNameAsFriendly Then + Return _FriendlyName.IfNullOrEmpty(UserSiteName) + Else + Return _FriendlyName + End If + End Get + Set(ByVal n As String) + _FriendlyName = n + End Set + End Property + Friend ReadOnly Property FriendlyNameOrig As String + Get + Return _FriendlyName + End Get + End Property + Friend ReadOnly Property FriendlyNameIsSiteName As Boolean + Get + If Settings.UserSiteNameAsFriendly Then + Return Not FriendlyName.IsEmptyString And Not _FriendlyName = UserSiteName And FriendlyName = UserSiteName + Else + Return False + End If + End Get + End Property + Private _UserSiteName As String = String.Empty + Friend Property UserSiteName As String + Get + Return _UserSiteName + End Get + Set(ByVal _UserSiteName As String) + If Not Me._UserSiteName = _UserSiteName Then EnvirChanged(_UserSiteName) + Me._UserSiteName = _UserSiteName + End Set + End Property + Protected Sub UserSiteNameUpdate(ByVal NewName As String) + If Not NewName.IsEmptyString And (UserSiteName.IsEmptyString Or Settings.UserSiteNameUpdateEveryTime) Then UserSiteName = NewName + End Sub Friend ReadOnly Property UserModel As UsageModel Implements IUserData.UserModel Get Return User.UserModel @@ -197,10 +251,6 @@ Namespace API.Base _DescriptionChecked = True End If End Sub - Protected Sub UserDescriptionReset() - _DescriptionChecked = False - _DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime - End Sub #End Region #Region "Favorite, Temporary" Protected _Favorite As Boolean = False @@ -246,7 +296,7 @@ Namespace API.Base Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture Try If f.Exists Then - Using p As New UserImage(f, User.File) : p.Save() : End Using + Using p As New UserImage(f, MyFile) : p.Save() : End Using End If Catch End Try @@ -409,13 +459,18 @@ BlockNullPicture: #Region "Files" Friend Overridable Property MyFile As SFile Implements IUserData.File Get - Return User.File + If IsSavedPosts Then + Return MyFileSettings + Else + Return User.File + End If End Get Set(ByVal f As SFile) User.File = f Settings.UpdateUsersList(User) End Set End Property + Protected MyFileSettings As SFile Protected MyFileData As SFile Protected MyFilePosts As SFile Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists @@ -661,14 +716,16 @@ BlockNullPicture: Private _UserInformationLoaded As Boolean = False Friend Overridable Sub LoadUserInformation() Implements IUserData.LoadUserInformation Try - If MyFile.Exists Then + UpdateDataFiles(, True) + If MyFileSettings.Exists Then FileExists = True - Using x As New XmlFile(MyFile) With {.XmlReadOnly = True} + Using x As New XmlFile(MyFileSettings) With {.XmlReadOnly = True} If User.Name.IsEmptyString Then User.Name = x.Value(Name_UserName) UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True) UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False) ID = x.Value(Name_UserID) - FriendlyName = x.Value(Name_FriendlyName) + _FriendlyName = x.Value(Name_FriendlyName) + UserSiteName = x.Value(Name_UserSiteName) UserDescription = x.Value(Name_Description) ParseUserMediaOnly = x.Value(Name_ParseUserMediaOnly).FromXML(Of Boolean)(False) Temporary = x.Value(Name_Temporary).FromXML(Of Boolean)(False) @@ -705,7 +762,8 @@ BlockNullPicture: End Sub Friend Overridable Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation Try - MyFile.Exists(SFO.Path) + UpdateDataFiles(True) + MyFileSettings.Exists(SFO.Path) Using x As New XmlFile With {.Name = "User"} x.Add(Name_Site, Site) x.Add(Name_Plugin, HOST.Key) @@ -718,7 +776,8 @@ BlockNullPicture: x.Add(Name_UserExists, UserExists.BoolToInteger) x.Add(Name_UserSuspended, UserSuspended.BoolToInteger) x.Add(Name_UserID, ID) - x.Add(Name_FriendlyName, FriendlyName) + x.Add(Name_FriendlyName, _FriendlyName) + x.Add(Name_UserSiteName, UserSiteName) x.Add(Name_Description, UserDescription) x.Add(Name_ParseUserMediaOnly, ParseUserMediaOnly.BoolToInteger) x.Add(Name_Temporary, Temporary.BoolToInteger) @@ -743,7 +802,7 @@ BlockNullPicture: LoadUserInformation_OptionalFields(x, False) - x.Save(MyFile) + x.Save(MyFileSettings) End Using If Not IsSavedPosts Then Settings.UpdateUsersList(User) Catch ex As Exception @@ -756,7 +815,7 @@ BlockNullPicture: #Region "User data" Friend Overridable Overloads Sub LoadContentInformation(Optional ByVal Force As Boolean = False) Try - UpdateDataFiles() + UpdateDataFiles(, True) If Not MyFileData.Exists Or (_DataLoaded And Not Force) Then Exit Sub Using x As New XmlFile(MyFileData, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True} x.LoadData() @@ -771,7 +830,7 @@ BlockNullPicture: End Sub Friend Sub UpdateContentInformation() Try - UpdateDataFiles() + UpdateDataFiles(True, True) If MyFileData.IsEmptyString Then Exit Sub MyFileData.Exists(SFO.Path) Using x As New XmlFile With {.AllowSameNames = True, .Name = "Data"} @@ -847,12 +906,45 @@ BlockNullPicture: #Region "Download functions and options" Protected Responser As Responser Protected UseResponserClient As Boolean = False + Protected _ForceSaveUserData As Boolean = False + Protected _ForceSaveUserInfo As Boolean = False + Private _DownloadInProgress As Boolean = False + Private _EnvirUserExists As Boolean + Private _EnvirUserSuspended As Boolean + Private _EnvirChanged As Boolean = False + Private _PictureExists As Boolean + Private _EnvirInvokeUserUpdated As Boolean = False + Protected Sub EnvirDownloadSet() + UpdateDataFiles(, True) + _DownloadInProgress = True + _DescriptionChecked = False + _DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime + _ForceSaveUserData = False + _ForceSaveUserInfo = False + _EnvirUserExists = UserExists + _EnvirUserSuspended = UserSuspended + _EnvirChanged = False + UserExists = True + UserSuspended = False + DownloadedPictures(False) = 0 + DownloadedVideos(False) = 0 + _PictureExists = Settings.ViewModeIsPicture AndAlso Not GetPicture(Of Image)(False) Is Nothing + _EnvirInvokeUserUpdated = False + End Sub + Private Sub EnvirChanged(ByVal NewValue As Object, Optional ByVal Caller As String = Nothing) + If _DownloadInProgress Then + Select Case Caller + Case NameOf(UserExists) : If Not _EnvirUserExists = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True + Case NameOf(UserSuspended) : If Not _EnvirUserSuspended = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True + Case Else : _EnvirChanged = True + End Select + End If + End Sub Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData Dim Canceled As Boolean = False _ExternalCompatibilityToken = Token Try - UpdateDataFiles() - UserDescriptionReset() + EnvirDownloadSet() If Not Responser Is Nothing Then Responser.Dispose() Responser = New Responser If Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser) @@ -860,14 +952,7 @@ BlockNullPicture: Responser.DecodersError = New ErrorsDescriber(EDP.SendInLog + EDP.ReturnValue) With { .DeclaredMessage = New MMessage($"SymbolsConverter error: [{ToStringForLog()}]", ToStringForLog())} - Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(Of Image)(False) Is Nothing - Dim sEnvir() As Boolean = {UserExists, UserSuspended} - Dim EnvirChanged As Func(Of Boolean) = Function() Not sEnvir(0) = UserExists Or Not sEnvir(1) = UserSuspended Dim _downContent As Func(Of UserMedia, Boolean) = Function(c) c.State = UStates.Downloaded - UserExists = True - UserSuspended = False - DownloadedPictures(False) = 0 - DownloadedVideos(False) = 0 _TempMediaList.Clear() _TempPostsList.Clear() LatestData.Clear() @@ -896,6 +981,7 @@ BlockNullPicture: ReparseVideo(Token) ThrowAny(Token) + If IsSavedPosts Then UpdateDataFiles(True) If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then _ TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None) _ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd) @@ -906,12 +992,12 @@ BlockNullPicture: Dim mcb& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0) _ContentList.ListAddList(_ContentNew.Where(Function(c) _downContent(c) Or MissingFinder(c)), LNC) Dim mca& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0) - If DownloadedTotal(False) > 0 Or EnvirChanged.Invoke Or Not mcb = mca Then + If DownloadedTotal(False) > 0 Or _EnvirChanged Or Not mcb = mca Or _ForceSaveUserData Then If __SaveData Then LastUpdated = Now RunScript() - DownloadedPictures(True) = SFile.GetFiles(User.File.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count - DownloadedVideos(True) = SFile.GetFiles(User.File.CutPath, "*.mp4|*.mkv|*.mov", SearchOption.AllDirectories, EDP.ReturnValue).Count + DownloadedPictures(True) = SFile.GetFiles(MyFile.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count + DownloadedVideos(True) = SFile.GetFiles(MyFile.CutPath, "*.mp4|*.mkv|*.mov", SearchOption.AllDirectories, EDP.ReturnValue).Count If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser) UpdateContentInformation() Else @@ -922,10 +1008,12 @@ BlockNullPicture: End If If Not UserExists Then ReadyForDownload = False UpdateUserInformation() - If _CollectionButtonsExists AndAlso EnvirChanged.Invoke Then UpdateButtonsColor() + If _CollectionButtonsExists AndAlso _EnvirChanged Then UpdateButtonsColor() + ElseIf _ForceSaveUserInfo Then + UpdateUserInformation() End If ThrowIfDisposed() - If UpPic Or EnvirChanged.Invoke Then OnUserUpdated() + If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated() Catch oex As OperationCanceledException When Token.IsCancellationRequested MyMainLOG = $"{ToStringForLog()}: downloading canceled" Canceled = True @@ -938,17 +1026,32 @@ BlockNullPicture: If Not Responser Is Nothing Then Responser.Dispose() : Responser = Nothing If Not Canceled Then _DataParsed = True _ContentNew.Clear() + _DownloadInProgress = False DownloadTopCount = Nothing DownloadDateFrom = Nothing DownloadDateTo = Nothing DownloadMissingOnly = False + _ForceSaveUserData = False + _ForceSaveUserInfo = False End Try End Sub - Protected Sub UpdateDataFiles() + Protected Sub UpdateDataFiles(Optional ByVal ForceSaved As Boolean = False, Optional ByVal ValidateContetnt As Boolean = False) + 'TODELETE: saved posts name compatibility 2023.2.5.0 + Dim __validateSaved As Func(Of Boolean) = Function() MyFileData.Exists Or MyFilePosts.Exists If Not User.File.IsEmptyString Then - MyFileData = User.File + MyFileSettings = Nothing + If IsSavedPosts Then + Dim u As UserInfo = User + u.Name = "SavedPosts" + u.UpdateUserFile() + Dim mfp As SFile = u.File + mfp.Name &= "_Posts" + If (ValidateContetnt AndAlso mfp.Exists) Or (Not ValidateContetnt AndAlso u.File.Exists) Or ForceSaved Then MyFileSettings = u.File + End If + If MyFileSettings.IsEmptyString Then MyFileSettings = User.File + MyFileData = MyFileSettings MyFileData.Name &= "_Data" - MyFilePosts = User.File + MyFilePosts = MyFileSettings MyFilePosts.Name &= "_Posts" MyFilePosts.Extension = "txt" Else @@ -1098,7 +1201,6 @@ BlockNullPicture: Return v End If Else - 'URGENT: UserDataBase.ProcessException [Throw ex] If ThrowEx Then Throw ex Else Return EXCEPTION_OPERATION_CANCELED End If Return 0 @@ -1293,7 +1395,7 @@ BlockNullPicture: Else pOffset = 1 End If - fSource = User.File.CutPath(pOffset).Path.CSFileP + fSource = MyFile.CutPath(pOffset).Path.CSFileP Dim OptPath$ = String.Empty If IncludedInCollection Then @@ -1501,7 +1603,6 @@ BlockNullPicture: Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile) As Boolean Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Sub OpenFolder() - ReadOnly Property Self As IUserData Property DownloadTopCount As Integer? Property DownloadDateFrom As Date? Property DownloadDateTo As Date? diff --git a/SCrawler/API/Instagram/SiteSettings.vb b/SCrawler/API/Instagram/SiteSettings.vb index 2ddcd00..78046d0 100644 --- a/SCrawler/API/Instagram/SiteSettings.vb +++ b/SCrawler/API/Instagram/SiteSettings.vb @@ -86,10 +86,10 @@ Namespace API.Instagram Friend ReadOnly Property CSRF_TOKEN As PropertyValue Friend Property IG_APP_ID As PropertyValue - + Friend Property IG_WWW_CLAIM As PropertyValue Friend Overrides Function BaseAuthExists() As Boolean - Return Responser.CookiesExists And ACheck(IG_APP_ID.Value) And ACheck(IG_WWW_CLAIM.Value) And ACheck(CSRF_TOKEN.Value) + Return Responser.CookiesExists And ACheck(IG_APP_ID.Value) And ACheck(CSRF_TOKEN.Value) End Function Private Const Header_IG_APP_ID As String = "x-ig-app-id" Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim" @@ -219,7 +219,7 @@ Namespace API.Instagram HashTagged = New PropertyValue(String.Empty, GetType(String)) CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(CSRF_TOKEN), v)) IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_APP_ID), v)) - IG_WWW_CLAIM = New PropertyValue(www_claim, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v)) + IG_WWW_CLAIM = New PropertyValue(www_claim.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v)) DownloadTimeline = New PropertyValue(True) DownloadStories = New PropertyValue(True) @@ -291,6 +291,7 @@ Namespace API.Instagram Private _NextTagged As Boolean = True Friend Overrides Sub DownloadStarted(ByVal What As Download) ActiveJobs += 1 + If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(IG_WWW_CLAIM.Value) Then IG_WWW_CLAIM.Value = "0" End Sub Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download) With DirectCast(User, UserData) diff --git a/SCrawler/API/Instagram/UserData.vb b/SCrawler/API/Instagram/UserData.vb index 4f49608..3eb9bf6 100644 --- a/SCrawler/API/Instagram/UserData.vb +++ b/SCrawler/API/Instagram/UserData.vb @@ -281,7 +281,7 @@ Namespace API.Instagram Case Else : WaitNotificationMode = WNM.SkipTemp End Select End If - If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until { .GetWaitDate().ToString(ParsersDataDateProvider)}" + If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until { .GetWaitDate().ToString(DateTimeDefaultProvider)}" ProgressTempSet = True Return False Else @@ -452,6 +452,7 @@ Namespace API.Instagram HasNextPage = .Value("more_available").FromXML(Of Boolean)(False) EndCursor = .Value("next_max_id") If If(.Item("items")?.Count, 0) > 0 Then + UserSiteNameUpdate(.ItemF({"items", 0, "user", "full_name"}).XmlIfNothingValue) If Not DefaultParser(.Item("items"), Section, Token) Then Throw New ExitException Else HasNextPage = False @@ -742,18 +743,40 @@ Namespace API.Instagram #End Region #Region "GetUserId" Private Sub GetUserId() + Dim __idFound As Boolean = False Try Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/users/web_profile_info/?username={Name}",, EDP.ThrowException) If Not r.IsEmptyString Then - Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing - ID = j({"data", "user"}, "id").XmlIfNothingValue + Using j As EContainer = JsonDocument.Parse(r) + If Not j Is Nothing AndAlso j.Contains({"data", "user"}) Then + With j({"data", "user"}) + ID = .Value("id") + __idFound = True + UserSiteNameUpdate(.Value("full_name")) + Dim descr$ = .Value("biography") + If If(.Item("bio_links")?.Count, 0) > 0 Then descr.StringAppend(.Item("bio_links").Select(Function(bl) bl.Value("url")).ListToString(vbNewLine), vbNewLine) + Dim eUrl$ = .Value("external_url") + If Not eUrl.IsEmptyString AndAlso (descr.IsEmptyString OrElse Not descr.Contains(eUrl)) Then descr.StringAppendLine(eUrl) + UserDescriptionUpdate(descr) + Dim f As New SFile With {.Path = MyFile.CutPath.Path, .Name = "ProfilePicture", .Extension = "jpg"} + If Not f.Exists Then + Dim profilePicture$ = .Value("profile_pic_url_hd") + If profilePicture.IsEmptyString OrElse Not GetWebFile(profilePicture, f, EDP.ReturnValue) Then + profilePicture = .Value("profile_pic_url") + If Not profilePicture.IsEmptyString Then GetWebFile(profilePicture, f, EDP.ReturnValue) + End If + End If + End With + End If End Using End If Catch ex As Exception - If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then - Throw ex - Else - LogError(ex, "get Instagram user id") + If Not __idFound Then + If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then + Throw ex + Else + LogError(ex, "get Instagram user id") + End If End If End Try End Sub diff --git a/SCrawler/API/PathPlugin/Declarations.vb b/SCrawler/API/PathPlugin/Declarations.vb new file mode 100644 index 0000000..c58e5b0 --- /dev/null +++ b/SCrawler/API/PathPlugin/Declarations.vb @@ -0,0 +1,14 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Namespace API.PathPlugin + Friend Module Declarations + Friend Const PluginKey As String = "AndyProgram_PathPlugin" + Friend Const PluginName As String = "Path" + End Module +End Namespace \ No newline at end of file diff --git a/SCrawler/API/PathPlugin/SiteSettings.vb b/SCrawler/API/PathPlugin/SiteSettings.vb new file mode 100644 index 0000000..ad6c15d --- /dev/null +++ b/SCrawler/API/PathPlugin/SiteSettings.vb @@ -0,0 +1,49 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Imports SCrawler.API.Base +Imports SCrawler.Plugin +Imports SCrawler.Plugin.Attributes +Namespace API.PathPlugin + + Friend Class SiteSettings : Inherits SiteSettingsBase + Friend Overrides ReadOnly Property Icon As Icon + Get + Return PersonalUtilities.Tools.ImageRenderer.GetIcon(PersonalUtilities.My.Resources.FolderOpenPic_Orange_16, EDP.ReturnValue) + End Get + End Property + Friend Overrides ReadOnly Property Image As Image + Get + Return PersonalUtilities.My.Resources.FolderOpenPic_Orange_16 + End Get + End Property + Friend Sub New() + MyBase.New(PluginName) + End Sub + Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider + Return New UserData + End Function + Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions + Dim f As SFile = UserURL + If Not f.IsEmptyString AndAlso f.PathNoSeparator = UserURL.StringTrimEnd("\") AndAlso (f.Location = SFOLocation.Local Or f.Location = SFOLocation.Network) Then + Return New ExchangeOptions(Site, f) + Else + Return Nothing + End If + End Function + Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean + Return False + End Function + Friend Overrides Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions + Return Nothing + End Function + Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String + Return String.Empty + End Function + End Class +End Namespace \ No newline at end of file diff --git a/SCrawler/API/PathPlugin/UserData.vb b/SCrawler/API/PathPlugin/UserData.vb new file mode 100644 index 0000000..f222cc5 --- /dev/null +++ b/SCrawler/API/PathPlugin/UserData.vb @@ -0,0 +1,45 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Imports SCrawler.API.Base +Namespace API.PathPlugin + Friend Class UserData : Inherits UserDataBase + Private Const DOWNLOAD_ERROR As String = "The path plugin only provides user paths." + Friend Overrides Property UserExists As Boolean + Get + Return FileExists + End Get + Set(ByVal e As Boolean) + MyBase.UserExists = e + End Set + End Property + Friend Overrides Property UserSuspended As Boolean + Get + Return False + End Get + Set(ByVal s As Boolean) + MyBase.UserSuspended = s + End Set + End Property + Friend Overrides Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing) + OpenFolder() + End Sub + Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XML.XmlFile, ByVal Loading As Boolean) + End Sub + Protected Overrides Sub DownloadDataF(ByVal Token As Threading.CancellationToken) + Throw New InvalidOperationException(DOWNLOAD_ERROR) + End Sub + Protected Overrides Sub DownloadContent(ByVal Token As Threading.CancellationToken) + Throw New InvalidOperationException(DOWNLOAD_ERROR) + End Sub + Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False, + Optional ByVal EObj As Object = Nothing) As Integer + Throw New InvalidOperationException(DOWNLOAD_ERROR) + End Function + End Class +End Namespace \ No newline at end of file diff --git a/SCrawler/API/PornHub/Declarations.vb b/SCrawler/API/PornHub/Declarations.vb index cf5897b..c046642 100644 --- a/SCrawler/API/PornHub/Declarations.vb +++ b/SCrawler/API/PornHub/Declarations.vb @@ -11,7 +11,6 @@ Namespace API.PornHub Friend Module Declarations #Region "Converters" Private ReadOnly UnicodeHexConverter As Func(Of String, String) = Function(Input) SymbolsConverter.UnicodeHex.Decode(Input, EDP.ReturnValue) - Friend ReadOnly HtmlConverter As Func(Of String, String) = Function(Input) SymbolsConverter.HTML.Decode(Input, EDP.ReturnValue) #End Region #Region "Declarations video" Friend ReadOnly RegexVideo_FlashVarsBlock As RParams = RParams.DM("(?<=flashvars_\['[nN]ext[vV]ideo'\];[\r\n]*?)(.+?)(?=;flashvars_\d+?)", 0, EDP.ReturnValue) diff --git a/SCrawler/API/PornHub/UserData.vb b/SCrawler/API/PornHub/UserData.vb index eace7f2..8c1e52f 100644 --- a/SCrawler/API/PornHub/UserData.vb +++ b/SCrawler/API/PornHub/UserData.vb @@ -59,7 +59,7 @@ Namespace API.PornHub URL = ParamsArray(0) ID = RegexReplace(URL, RegexVideo_Video_VideoKey) URL = String.Format(UrlPattern, URL.TrimStart("/")) - Title = HtmlConverter(ParamsArray(1)).StringRemoveWinForbiddenSymbols.StringTrim + Title = TitleHtmlConverter(ParamsArray(1)) End If Return Me End Function @@ -99,7 +99,6 @@ Namespace API.PornHub #Region "Person" Friend Property PersonType As String Friend Property NameTrue As String - Private _FriendlyName As String = String.Empty Friend Overrides Property FriendlyName As String Get If _FriendlyName.IsEmptyString Then Return NameTrue Else Return _FriendlyName @@ -315,7 +314,7 @@ Namespace API.PornHub If l3.ListExists(3) Then m.URL = l3(2) m.File = m.URL - n = HtmlConverter(l3(1)).StringRemoveWinForbiddenSymbols.StringTrim + n = TitleHtmlConverter(l3(1)) If MySettings.DownloadGifsAsMp4.Value Then m.File.Extension = "mp4" If Not n.IsEmptyString Then m.File.Name = n End If @@ -416,7 +415,7 @@ Namespace API.PornHub If albumName.IsEmptyString Then albumName = block.AlbumID.Split("/").LastOrDefault.StringTrim Else - albumName = HtmlConverter(albumName).StringRemoveWinForbiddenSymbols.StringTrim + albumName = TitleHtmlConverter(albumName) End If page = 1 Do While DownloadUserPhotos_PornHub(page, block.AlbumID, albumName, Token) : page += 1 : Loop diff --git a/SCrawler/API/Reddit/SiteSettings.vb b/SCrawler/API/Reddit/SiteSettings.vb index e16387c..df6aaf2 100644 --- a/SCrawler/API/Reddit/SiteSettings.vb +++ b/SCrawler/API/Reddit/SiteSettings.vb @@ -32,8 +32,9 @@ Namespace API.Reddit Friend Sub New() MyBase.New(RedditSite, "reddit.com") With Responser - If .Decoders.Count = 0 OrElse Not .Decoders.Contains(SymbolsConverter.Converters.Unicode) Then _ - .Decoders.Add(SymbolsConverter.Converters.Unicode) : .SaveSettings() + Dim d% = .Decoders.Count + .Decoders.ListAddList({SymbolsConverter.Converters.Unicode, SymbolsConverter.Converters.HTML}, LAP.NotContainsOnly) + If d <> .Decoders.Count Then .SaveSettings() End With SavedPostsUserName = New PropertyValue(String.Empty, GetType(String)) UseM3U8 = New PropertyValue(True) diff --git a/SCrawler/API/Reddit/UserData.vb b/SCrawler/API/Reddit/UserData.vb index f83ed61..71917d2 100644 --- a/SCrawler/API/Reddit/UserData.vb +++ b/SCrawler/API/Reddit/UserData.vb @@ -132,9 +132,9 @@ Namespace API.Reddit #End Region #Region "Download Overrides" Friend Overrides Sub DownloadData(ByVal Token As CancellationToken) - UserDescriptionReset() _CrossPosts.Clear() If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo Is Nothing) Then + EnvirDownloadSet() If Not Responser Is Nothing Then Responser.Dispose() Responser = New Responser Responser.Copy(MySiteSettings.Responser) @@ -165,12 +165,15 @@ Namespace API.Reddit End With End If If DownloadTopCount.HasValue Then DownloadLimitCount = DownloadTopCount + Else + GetUserInfo() End If If SaveToCache AndAlso Not Responser.Decoders.Contains(SymbolsConverter.Converters.HTML) Then _ Responser.Decoders.Add(SymbolsConverter.Converters.HTML) DownloadDataChannel(String.Empty, Token) If ChannelInfo Is Nothing Then _TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC) Else + GetUserInfo() DownloadDataUser(String.Empty, Token) End If End Sub @@ -205,7 +208,8 @@ Namespace API.Reddit If Not r.IsEmptyString Then Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing If w.Count > 0 Then - If UserDescriptionNeedToUpdate() Then UserDescriptionUpdate(w.ItemF({"subredditAboutInfo", 0, "publicDescription"}).XmlIfNothingValue) + 'TODELETE: moved to 'GetUserInfo' 2023.2.5.0 + 'If UserDescriptionNeedToUpdate() Then UserDescriptionUpdate(w.ItemF({"subredditAboutInfo", 0, "publicDescription"}).XmlIfNothingValue) n = w.GetNode(JsonNodesJson) If Not n Is Nothing AndAlso n.Count > 0 Then For Each nn In n @@ -416,6 +420,37 @@ Namespace API.Reddit ProcessException(ex, Token, $"channel data downloading error [{URL}]") End Try End Sub + Private Sub GetUserInfo() + Try + If Not IsSavedPosts And ChannelInfo Is Nothing Then + Dim r$ = Responser.GetResponse($"https://reddit.com/{IIf(IsChannel, "r", "user")}/{Name}/about.json",, EDP.ReturnValue) + If Not r.IsEmptyString Then + Using j As EContainer = JsonDocument.Parse(r) + If Not j Is Nothing AndAlso j.Contains({"data", "subreddit"}) Then + With j({"data", "subreddit"}) + UserSiteNameUpdate(.Value("title")) + UserDescriptionUpdate(.Value("public_description")) + Dim dir As SFile = MyFile.CutPath + Dim __getFile As Action(Of String) = Sub(ByVal img As String) + If Not img.IsEmptyString Then + Dim f As SFile = UrlToFile(img) + If Not f.Name.IsEmptyString Then + If f.Extension.IsEmptyString Then f.Extension = "jpg" + f.Path = dir.Path + If Not f.Exists Then GetWebFile(img, f, EDP.ReturnValue) + End If + End If + End Sub + __getFile.Invoke(.Value("icon_img")) + __getFile.Invoke(.Value("banner_img")) + End With + End If + End Using + End If + End If + Catch ex As Exception + End Try + End Sub #End Region #Region "Download Base Functions" Private Function CreateImgurMedia(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String, diff --git a/SCrawler/API/Twitter/EditorExchangeOptions.vb b/SCrawler/API/Twitter/EditorExchangeOptions.vb index dddbf05..346a41f 100644 --- a/SCrawler/API/Twitter/EditorExchangeOptions.vb +++ b/SCrawler/API/Twitter/EditorExchangeOptions.vb @@ -11,17 +11,22 @@ Namespace API.Twitter Friend Property GifsDownload As Boolean Friend Property GifsSpecialFolder As String Friend Property GifsPrefix As String + Friend Property UseMD5Comparison As Boolean = False + Friend Property RemoveExistingDuplicates As Boolean = False Friend Sub New() End Sub Friend Sub New(ByVal s As SiteSettings) GifsDownload = s.GifsDownload.Value GifsSpecialFolder = s.GifsSpecialFolder.Value GifsPrefix = s.GifsPrefix.Value + UseMD5Comparison = s.UseMD5Comparison.Value End Sub Friend Sub New(ByVal u As UserData) GifsDownload = u.GifsDownload GifsSpecialFolder = u.GifsSpecialFolder GifsPrefix = u.GifsPrefix + UseMD5Comparison = u.UseMD5Comparison + RemoveExistingDuplicates = u.RemoveExistingDuplicates End Sub End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Twitter/OptionsForm.Designer.vb b/SCrawler/API/Twitter/OptionsForm.Designer.vb index 3330cfa..1b2dd82 100644 --- a/SCrawler/API/Twitter/OptionsForm.Designer.vb +++ b/SCrawler/API/Twitter/OptionsForm.Designer.vb @@ -22,16 +22,21 @@ Namespace API.Twitter Private components As System.ComponentModel.IContainer Private Sub InitializeComponent() + Me.components = New System.ComponentModel.Container() Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel - Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(OptionsForm)) - Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim TT_MAIN As System.Windows.Forms.ToolTip Me.CH_DOWN_GIFS = New System.Windows.Forms.CheckBox() Me.TXT_GIF_FOLDER = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_GIF_PREFIX = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.CH_USE_MD5 = New System.Windows.Forms.CheckBox() + Me.CH_REMOVE_EXISTING_DUP = New System.Windows.Forms.CheckBox() CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() TP_MAIN = New System.Windows.Forms.TableLayoutPanel() + TT_MAIN = New System.Windows.Forms.ToolTip(Me.components) CONTAINER_MAIN.ContentPanel.SuspendLayout() CONTAINER_MAIN.SuspendLayout() TP_MAIN.SuspendLayout() @@ -45,13 +50,13 @@ Namespace API.Twitter 'CONTAINER_MAIN.ContentPanel ' CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(304, 84) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(304, 161) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) CONTAINER_MAIN.Name = "CONTAINER_MAIN" CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(304, 109) + CONTAINER_MAIN.Size = New System.Drawing.Size(304, 161) CONTAINER_MAIN.TabIndex = 0 CONTAINER_MAIN.TopToolStripPanelVisible = False ' @@ -60,19 +65,22 @@ Namespace API.Twitter TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] TP_MAIN.ColumnCount = 1 TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_MAIN.Controls.Add(Me.CH_DOWN_GIFS, 0, 0) TP_MAIN.Controls.Add(Me.TXT_GIF_FOLDER, 0, 1) TP_MAIN.Controls.Add(Me.TXT_GIF_PREFIX, 0, 2) + TP_MAIN.Controls.Add(Me.CH_USE_MD5, 0, 3) + TP_MAIN.Controls.Add(Me.CH_REMOVE_EXISTING_DUP, 0, 4) TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill TP_MAIN.Location = New System.Drawing.Point(0, 0) TP_MAIN.Name = "TP_MAIN" - TP_MAIN.RowCount = 4 + TP_MAIN.RowCount = 6 TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) + TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.Size = New System.Drawing.Size(304, 84) + TP_MAIN.Size = New System.Drawing.Size(304, 161) TP_MAIN.TabIndex = 0 ' 'CH_DOWN_GIFS @@ -89,10 +97,10 @@ Namespace API.Twitter ' 'TXT_GIF_FOLDER ' - ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image) - ActionButton1.Name = "Clear" - ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_GIF_FOLDER.Buttons.Add(ActionButton1) + ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image) + ActionButton3.Name = "Clear" + ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_GIF_FOLDER.Buttons.Add(ActionButton3) Me.TXT_GIF_FOLDER.CaptionText = "GIFs special folder" Me.TXT_GIF_FOLDER.CaptionToolTipText = "Put the GIFs in a special folder" Me.TXT_GIF_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill @@ -103,10 +111,10 @@ Namespace API.Twitter ' 'TXT_GIF_PREFIX ' - ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image) - ActionButton2.Name = "Clear" - ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_GIF_PREFIX.Buttons.Add(ActionButton2) + ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image) + ActionButton4.Name = "Clear" + ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_GIF_PREFIX.Buttons.Add(ActionButton4) Me.TXT_GIF_PREFIX.CaptionText = "GIF prefix" Me.TXT_GIF_PREFIX.CaptionToolTipText = "This prefix will be added to the beginning of the filename" Me.TXT_GIF_PREFIX.Dock = System.Windows.Forms.DockStyle.Fill @@ -115,18 +123,45 @@ Namespace API.Twitter Me.TXT_GIF_PREFIX.Size = New System.Drawing.Size(296, 22) Me.TXT_GIF_PREFIX.TabIndex = 2 ' + 'CH_USE_MD5 + ' + Me.CH_USE_MD5.AutoSize = True + Me.CH_USE_MD5.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_USE_MD5.Location = New System.Drawing.Point(4, 88) + Me.CH_USE_MD5.Name = "CH_USE_MD5" + Me.CH_USE_MD5.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_USE_MD5.Size = New System.Drawing.Size(296, 19) + Me.CH_USE_MD5.TabIndex = 3 + Me.CH_USE_MD5.Text = "Use MD5 comparison" + TT_MAIN.SetToolTip(Me.CH_USE_MD5, "Each image will be checked for existence using MD5") + Me.CH_USE_MD5.UseVisualStyleBackColor = True + ' + 'CH_REMOVE_EXISTING_DUP + ' + Me.CH_REMOVE_EXISTING_DUP.AutoSize = True + Me.CH_REMOVE_EXISTING_DUP.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_REMOVE_EXISTING_DUP.Location = New System.Drawing.Point(4, 114) + Me.CH_REMOVE_EXISTING_DUP.Name = "CH_REMOVE_EXISTING_DUP" + Me.CH_REMOVE_EXISTING_DUP.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_REMOVE_EXISTING_DUP.Size = New System.Drawing.Size(296, 19) + Me.CH_REMOVE_EXISTING_DUP.TabIndex = 4 + Me.CH_REMOVE_EXISTING_DUP.Text = "Remove existing duplicates" + TT_MAIN.SetToolTip(Me.CH_REMOVE_EXISTING_DUP, "Existing files will be checked for duplicates and duplicates removed." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Works only" & + " on the first activation 'Use MD5 comparison'.") + Me.CH_REMOVE_EXISTING_DUP.UseVisualStyleBackColor = True + ' 'OptionsForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(304, 109) + Me.ClientSize = New System.Drawing.Size(304, 161) Me.Controls.Add(CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.Icon = Global.SCrawler.My.Resources.SiteResources.TwitterIcon_32 Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(320, 148) + Me.MaximumSize = New System.Drawing.Size(320, 200) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(320, 148) + Me.MinimumSize = New System.Drawing.Size(320, 200) Me.Name = "OptionsForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -144,5 +179,7 @@ Namespace API.Twitter Private WithEvents CH_DOWN_GIFS As CheckBox Private WithEvents TXT_GIF_FOLDER As PersonalUtilities.Forms.Controls.TextBoxExtended Private WithEvents TXT_GIF_PREFIX As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents CH_USE_MD5 As CheckBox + Private WithEvents CH_REMOVE_EXISTING_DUP As CheckBox End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Twitter/OptionsForm.resx b/SCrawler/API/Twitter/OptionsForm.resx index 27f385b..129abb5 100644 --- a/SCrawler/API/Twitter/OptionsForm.resx +++ b/SCrawler/API/Twitter/OptionsForm.resx @@ -124,7 +124,7 @@ False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -132,7 +132,7 @@ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -140,4 +140,16 @@ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC + + False + + + 17, 17 + + + False + + + 17, 17 + \ No newline at end of file diff --git a/SCrawler/API/Twitter/OptionsForm.vb b/SCrawler/API/Twitter/OptionsForm.vb index 970e6d5..8cac46e 100644 --- a/SCrawler/API/Twitter/OptionsForm.vb +++ b/SCrawler/API/Twitter/OptionsForm.vb @@ -30,6 +30,8 @@ Namespace API.Twitter TXT_GIF_FOLDER.Tag = NameOf(SiteSettings.GifsSpecialFolder) TXT_GIF_PREFIX.Text = .GifsPrefix TXT_GIF_PREFIX.Tag = NameOf(SiteSettings.GifsPrefix) + CH_USE_MD5.Checked = .UseMD5Comparison + CH_REMOVE_EXISTING_DUP.Checked = .RemoveExistingDuplicates Try Dim p As PropertyOption @@ -59,6 +61,8 @@ Namespace API.Twitter .GifsDownload = CH_DOWN_GIFS.Checked .GifsSpecialFolder = TXT_GIF_FOLDER.Text .GifsPrefix = TXT_GIF_PREFIX.Text + .UseMD5Comparison = CH_USE_MD5.Checked + .RemoveExistingDuplicates = CH_REMOVE_EXISTING_DUP.Checked End With MyDefs.CloseForm() End Sub diff --git a/SCrawler/API/Twitter/SiteSettings.vb b/SCrawler/API/Twitter/SiteSettings.vb index 004574a..c5d2043 100644 --- a/SCrawler/API/Twitter/SiteSettings.vb +++ b/SCrawler/API/Twitter/SiteSettings.vb @@ -69,6 +69,8 @@ Namespace API.Twitter Throw New NotImplementedException("[GetFormat] is not available in the context of [TimersChecker]") End Function End Class + + Friend ReadOnly Property UseMD5Comparison As PropertyValue #End Region Friend Overrides ReadOnly Property Responser As Responser #End Region @@ -115,6 +117,7 @@ Namespace API.Twitter GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String)) GifsPrefix = New PropertyValue("GIF_") GifStringChecker = New GifStringProvider + UseMD5Comparison = New PropertyValue(False) UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1) UrlPatternUser = "https://twitter.com/{0}" diff --git a/SCrawler/API/Twitter/UserData.vb b/SCrawler/API/Twitter/UserData.vb index 392ae7a..0557d44 100644 --- a/SCrawler/API/Twitter/UserData.vb +++ b/SCrawler/API/Twitter/UserData.vb @@ -7,13 +7,16 @@ ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY Imports System.Net +Imports System.Drawing Imports System.Threading Imports SCrawler.API.Base Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Tools.Web.Clients Imports PersonalUtilities.Tools.Web.Documents.JSON +Imports PersonalUtilities.Tools.ImageRenderer Imports UStates = SCrawler.API.Base.UserMedia.States +Imports UTypes = SCrawler.API.Base.UserMedia.Types Namespace API.Twitter Friend Class UserData : Inherits UserDataBase Private Const SinglePostUrl As String = "https://api.twitter.com/1.1/statuses/show.json?id={0}&tweet_mode=extended" @@ -21,12 +24,18 @@ Namespace API.Twitter Private Const Name_GifsDownload As String = "GifsDownload" Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder" Private Const Name_GifsPrefix As String = "GifsPrefix" + Private Const Name_UseMD5Comparison As String = "UseMD5Comparison" + Private Const Name_RemoveExistingDuplicates As String = "RemoveExistingDuplicates" + Private Const Name_StartMD5Checked As String = "StartMD5Checked" #End Region #Region "Declarations" Friend Property GifsDownload As Boolean Friend Property GifsSpecialFolder As String Friend Property GifsPrefix As String Private ReadOnly _DataNames As List(Of String) + Friend Property UseMD5Comparison As Boolean = False + Private StartMD5Checked As Boolean = False + Friend Property RemoveExistingDuplicates As Boolean = False #End Region #Region "Exchange options" Friend Overrides Function ExchangeOptionsGet() As Object @@ -38,6 +47,8 @@ Namespace API.Twitter GifsDownload = .GifsDownload GifsSpecialFolder = .GifsSpecialFolder GifsPrefix = .GifsPrefix + UseMD5Comparison = .UseMD5Comparison + RemoveExistingDuplicates = .RemoveExistingDuplicates End With End If End Sub @@ -55,10 +66,16 @@ Namespace API.Twitter Else GifsPrefix = Container.Value(Name_GifsPrefix) End If + UseMD5Comparison = Container.Value(Name_UseMD5Comparison).FromXML(Of Boolean)(False) + RemoveExistingDuplicates = Container.Value(Name_RemoveExistingDuplicates).FromXML(Of Boolean)(False) + StartMD5Checked = Container.Value(Name_StartMD5Checked).FromXML(Of Boolean)(False) Else Container.Add(Name_GifsDownload, GifsDownload.BoolToInteger) Container.Add(Name_GifsSpecialFolder, GifsSpecialFolder) Container.Add(Name_GifsPrefix, GifsPrefix) + Container.Add(Name_UseMD5Comparison, UseMD5Comparison.BoolToInteger) + Container.Add(Name_RemoveExistingDuplicates, RemoveExistingDuplicates.BoolToInteger) + Container.Add(Name_StartMD5Checked, StartMD5Checked.BoolToInteger) End If End Sub #End Region @@ -70,6 +87,7 @@ Namespace API.Twitter Else If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly) DownloadData(String.Empty, Token) + If UseMD5Comparison Then ValidateMD5(Token) End If End Sub Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken) @@ -100,6 +118,30 @@ Namespace API.Twitter If Not r.IsEmptyString Then Using w As EContainer = JsonDocument.Parse(r) If w.ListExists Then + + If Not IsSavedPosts And POST.IsEmptyString And Not w.ItemF({0, "user"}) Is Nothing Then + With w.ItemF({0, "user"}) + If .Value("screen_name").StringToLower = Name Then + UserSiteNameUpdate(.Value("name")) + UserDescriptionUpdate(.Value("description")) + Dim __getImage As Action(Of String) = Sub(ByVal img As String) + If Not img.IsEmptyString Then + Dim __imgFile As SFile = UrlFile(img, True) + If Not __imgFile.Name.IsEmptyString Then + If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg" + __imgFile.Path = MyFile.CutPath.Path + If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None) + End If + End If + End Sub + Dim icon$ = .Value("profile_image_url_https") + If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty) + __getImage.Invoke(.Value("profile_banner_url")) + __getImage.Invoke(icon) + End If + End With + End If + For Each nn In If(IsSavedPosts, w({"globalObjects", "tweets"}).XmlIfNothing, w) ThrowAny(Token) If nn.Count > 0 Then @@ -114,9 +156,6 @@ Namespace API.Twitter End If End If - If Not IsSavedPosts AndAlso UserDescriptionNeedToUpdate() AndAlso nn.Value({"user"}, "screen_name") = Name Then _ - UserDescriptionUpdate(nn.Value({"user"}, "description")) - 'Date Pattern: 'Sat Jan 01 01:10:15 +0000 2000 If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty @@ -174,7 +213,7 @@ Namespace API.Twitter If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then _DataNames.Add(dName) _TempMediaList.ListAddValue(MediaFromData(m("media_url").Value, - PostID, PostDate, GetPictureOption(m), State), LNC) + PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC) End If End If Next @@ -190,7 +229,7 @@ Namespace API.Twitter Dim f$ = UrlFile(URL) If Not f.IsEmptyString AndAlso Not _DataNames.Contains(f) Then _DataNames.Add(f) - _TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate,, State), LNC) + _TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate,, State, UTypes.Video), LNC) End If Return True End If @@ -218,7 +257,7 @@ Namespace API.Twitter ff = UrlFile(url) If Not ff.IsEmptyString Then If GifsDownload And Not _DataNames.Contains(ff) Then - m = MediaFromData(url, PostID, PostDate,, State) + m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video) f = m.File If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*" @@ -298,6 +337,131 @@ Namespace API.Twitter End Try End Sub #End Region +#Region "MD5 support" + Private Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR" + Private Sub ValidateMD5(ByVal Token As CancellationToken) + Try + Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString + If UseMD5Comparison And _TempMediaList.Exists(missingMD5) Then + Dim i% + Dim data As UserMedia = Nothing + Dim hashList As New Dictionary(Of String, SFile) + Dim f As SFile + Dim ErrMD5 As New ErrorsDescriber(EDP.ReturnValue) + Dim __getMD5 As Func(Of UserMedia, Boolean, String) = + Function(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String + Try + Dim ImgFormat As Imaging.ImageFormat = Nothing + Dim hash$ = String.Empty + Dim __isGif As Boolean = False + If __data.Type = UTypes.GIF Then + ImgFormat = Imaging.ImageFormat.Gif + __isGif = True + ElseIf Not __data.File.IsEmptyString Then + ImgFormat = GetImageFormat(__data.File) + End If + If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg + If IsUrl Then + hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5)) + Else + hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5)) + End If + If hash.IsEmptyString And Not __isGif Then + If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg + If IsUrl Then + hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5)) + Else + hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5)) + End If + End If + Return hash + Catch + Return String.Empty + End Try + End Function + If Not StartMD5Checked Then + StartMD5Checked = True + If _ContentList.Exists(missingMD5) Then + Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing + Dim eIndx% + Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File + If RemoveExistingDuplicates Then + RemoveExistingDuplicates = False + _ForceSaveUserInfo = True + If existingFiles.Count > 0 Then + Dim h$ + For i = existingFiles.Count - 1 To 0 Step -1 + h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False) + If Not h.IsEmptyString Then + If hashList.ContainsKey(h) Then + MyMainLOG = $"[{ToStringForLog()}]: Removed image [{existingFiles(i).File}] (duplicate of [{hashList(h).File}])" + existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5) + existingFiles.RemoveAt(i) + Else + hashList.Add(h, existingFiles(i)) + End If + End If + Next + End If + End If + For i = 0 To _ContentList.Count - 1 + data = _ContentList(i) + If (data.Type = UTypes.GIF Or data.Type = UTypes.Picture) Then + If data.MD5.IsEmptyString Then + ThrowAny(Token) + eIndx = existingFiles.FindIndex(eFinder) + If eIndx >= 0 Then + data.MD5 = __getMD5(New UserMedia With {.File = existingFiles(eIndx)}, False) + If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True + End If + End If + existingFiles.RemoveAll(eFinder) + End If + Next + If existingFiles.Count > 0 Then + For i = 0 To existingFiles.Count - 1 + f = existingFiles(i) + data = New UserMedia(f.File) With { + .State = UStates.Downloaded, + .Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture), + .File = f + } + ThrowAny(Token) + data.MD5 = __getMD5(data, False) + If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True + Next + existingFiles.Clear() + End If + End If + End If + + If _ContentList.Count > 0 Then + With _ContentList.Select(Function(d) d.MD5) + If .ListExists Then .ToList.ForEach(Sub(md5value) If Not hashList.ContainsKey(md5value) Then hashList.Add(md5value, New SFile)) + End With + End If + + For i = _TempMediaList.Count - 1 To 0 Step -1 + data = _TempMediaList(i) + If missingMD5(data) Then + ThrowAny(Token) + data.MD5 = __getMD5(data, True) + If Not data.MD5.IsEmptyString Then + If hashList.ContainsKey(data.MD5) Then + _TempMediaList.RemoveAt(i) + Else + hashList.Add(data.MD5, New SFile) + _TempMediaList(i) = data + End If + End If + End If + Next + End If + Catch ex As Exception + ProcessException(ex, Token, "ValidateMD5",, VALIDATE_MD5_ERROR) + End Try + End Sub +#End Region #Region "Get video static" Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Responser) As IEnumerable(Of UserMedia) Try @@ -310,7 +474,7 @@ Namespace API.Twitter Using j As EContainer = JsonDocument.Parse(r) If j.ListExists Then Dim u$ = GetVideoNodeURL(j) - If Not u.IsEmptyString Then Return {MediaFromData(u, PostID, String.Empty)} + If Not u.IsEmptyString Then Return {MediaFromData(u, PostID, String.Empty,,, UTypes.Video)} End If End Using End If @@ -359,10 +523,17 @@ Namespace API.Twitter End Function #End Region #Region "UrlFile" - Private Function UrlFile(ByVal URL As String) As String + Private Function UrlFile(ByVal URL As String, Optional ByVal GetWithoutExtension As Boolean = False) As String Try - Dim f As SFile = CStr(RegexReplace(LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern)), FilesPattern)) - If Not f.IsEmptyString Then Return f.File Else Return String.Empty + If Not URL.IsEmptyString Then + Dim f As SFile = CStr(RegexReplace(LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern)), FilesPattern)) + If f.IsEmptyString And GetWithoutExtension Then + URL = LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern)) + If Not URL.IsEmptyString Then f = New SFile With {.Name = URL.Split("/").LastOrDefault} + End If + If Not f.IsEmptyString Then Return f.File + End If + Return String.Empty Catch ex As Exception Return String.Empty End Try @@ -371,9 +542,10 @@ Namespace API.Twitter #Region "Create media" Private Shared Function MediaFromData(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String, Optional ByVal _PictureOption As String = Nothing, - Optional ByVal State As UStates = UStates.Unknown) As UserMedia + Optional ByVal State As UStates = UStates.Unknown, + Optional ByVal Type As UTypes = UTypes.Undefined) As UserMedia _URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern)) - Dim m As New UserMedia(_URL) With {.PictureOption = _PictureOption, .Post = New UserPost With {.ID = PostID}} + Dim m As New UserMedia(_URL) With {.PictureOption = _PictureOption, .Post = New UserPost With {.ID = PostID}, .Type = Type} If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern)) If Not m.PictureOption.IsEmptyString And Not m.File.IsEmptyString And Not m.URL.IsEmptyString Then m.URL = $"{m.URL.Replace($".{m.File.Extension}", String.Empty)}?format={m.File.Extension}&name={m.PictureOption}" @@ -391,20 +563,25 @@ Namespace API.Twitter #Region "Exception" Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False, Optional ByVal EObj As Object = Nothing) As Integer - With Responser - If .StatusCode = HttpStatusCode.NotFound Then - UserExists = False - ElseIf .StatusCode = HttpStatusCode.Unauthorized Then - UserSuspended = True - ElseIf .StatusCode = HttpStatusCode.BadRequest Then - MyMainLOG = "Twitter has invalid credentials" - ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then - MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})" - Else - If Not FromPE Then LogError(ex, Message) : HasError = True - Return 0 - End If - End With + If AEquals(EObj, VALIDATE_MD5_ERROR) Then + If Not FromPE Then LogError(ex, Message) + Return 0 + Else + With Responser + If .StatusCode = HttpStatusCode.NotFound Then + UserExists = False + ElseIf .StatusCode = HttpStatusCode.Unauthorized Then + UserSuspended = True + ElseIf .StatusCode = HttpStatusCode.BadRequest Then + MyMainLOG = "Twitter has invalid credentials" + ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then + MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})" + Else + If Not FromPE Then LogError(ex, Message) : HasError = True + Return 0 + End If + End With + End If Return 1 End Function #End Region diff --git a/SCrawler/API/UserDataBind.vb b/SCrawler/API/UserDataBind.vb index 8e88ef4..adcb318 100644 --- a/SCrawler/API/UserDataBind.vb +++ b/SCrawler/API/UserDataBind.vb @@ -370,7 +370,7 @@ Namespace API If Not e.Exists Then e = New ErrorsDescriber(EDP.SendInLog) If Count > 0 Then Collections.ForEach(Sub(c) c.OpenSite(e)) End Sub - Private ReadOnly RealUser As Predicate(Of IUserData) = Function(u) u.UserModel = UsageModel.Default + Private ReadOnly RealUser As Predicate(Of IUserData) = Function(u) u.UserModel = UsageModel.Default And Not u.HOST.Key = PathPlugin.PluginKey Friend Overrides Sub OpenFolder() Try If Count > 0 Then diff --git a/SCrawler/API/XVIDEOS/Declarations.vb b/SCrawler/API/XVIDEOS/Declarations.vb index dcbdc58..4043f31 100644 --- a/SCrawler/API/XVIDEOS/Declarations.vb +++ b/SCrawler/API/XVIDEOS/Declarations.vb @@ -6,17 +6,17 @@ ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY +Imports SCrawler.API.Base Imports PersonalUtilities.Functions.RegularExpressions Namespace API.XVIDEOS Friend Module Declarations Friend Const XvideosSiteKey As String = "AndyProgram_XVIDEOS" - Private ReadOnly HtmlConverter As Func(Of String, String) = Function(Input) SymbolsConverter.HTML.Decode(Input, EDP.ReturnValue) Friend ReadOnly Regex_M3U8 As RParams = RParams.DM("http.+?.m3u8.*?(?=')", 0) - Friend ReadOnly Regex_VideoTitle As RParams = RParams.DMS("html5player.setVideoTitle\('(.+)(?='\);)", 1, EDP.ReturnValue, HtmlConverter) + Friend ReadOnly Regex_VideoTitle As RParams = RParams.DMS("html5player.setVideoTitle\('(.+)(?='\);)", 1, EDP.ReturnValue, TitleHtmlConverter) Friend ReadOnly Regex_VideoID As RParams = RParams.DMS(".*?www.xvideos.com/(video\d+).*", 1) Friend ReadOnly Regex_M3U8_Reparse As RParams = RParams.DM("NAME=""(\d+).*?""[\r\n]*?(.+)(?=(|[\r\n]+?))", 0, RegexReturn.List) Friend ReadOnly Regex_M3U8_Appender As RParams = RParams.DM("(.+)(?=/.+?\.m3u8.*?)", 0) Friend ReadOnly Regex_SavedVideosPlaylist As RParams = RParams.DM("
0 Then - Dim uName$, fStr$ - Dim uErr As New ErrorsDescriber(EDP.ReturnValue) - For i% = 0 To Domains.Count - 1 - fStr = String.Format(UserRegexDefault, Domains(i)) - uName = RegexReplace(UserURL, RParams.DMS(fStr, 1, uErr)) - If Not uName.IsEmptyString Then Return New ExchangeOptions(Site, uName) - Next + If Not UserURL.IsEmptyString AndAlso Domains.Count > 0 AndAlso Domains.Exists(Function(d) UserURL.ToLower.Contains(d.ToLower)) Then + Dim data As List(Of String) = RegexReplace(UserURL, UserRegex) + If data.ListExists(3) AndAlso Not data(2).IsEmptyString Then Return New ExchangeOptions(Site, data(2), data(1) = ChannelOption) End If Return Nothing End Function diff --git a/SCrawler/API/Xhamster/UserData.vb b/SCrawler/API/Xhamster/UserData.vb index fb3c5ff..f79fae2 100644 --- a/SCrawler/API/Xhamster/UserData.vb +++ b/SCrawler/API/Xhamster/UserData.vb @@ -38,7 +38,7 @@ Namespace API.Xhamster Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken) _TempPhotoData.Clear() If DownloadVideos Then DownloadData(1, True, Token) - If DownloadImages Then + If Not IsChannel And DownloadImages Then DownloadData(1, False, Token) ReparsePhoto(Token) End If @@ -50,11 +50,16 @@ Namespace API.Xhamster Dim Type As UTypes = IIf(IsVideo, UTypes.VideoPre, UTypes.Picture) Dim mPages$ = IIf(IsVideo, "maxVideoPages", "maxPhotoPages") Dim listNode$() + Dim skipped As Boolean = False + Dim cBefore% = _TempMediaList.Count Dim m As UserMedia If IsSavedPosts Then URL = $"https://xhamster.com/my/favorites/{IIf(IsVideo, "videos", "photos-and-galleries")}{IIf(Page = 1, String.Empty, $"/{Page}")}" listNode = If(IsVideo, {"favoriteVideoListComponent", "models"}, {"favoritesGalleriesAndPhotosCollection"}) + ElseIf IsChannel Then + URL = $"https://xhamster.com/channels/{Name}/newest{IIf(Page = 1, String.Empty, $"/{Page}")}" + listNode = {"trendingVideoListComponent", "models"} Else URL = $"https://xhamster.com/users/{Name}/{IIf(IsVideo, "videos", "photos")}{IIf(Page = 1, String.Empty, $"/{Page}")}" listNode = {If(IsVideo, "userVideoCollection", "userGalleriesCollection")} @@ -80,7 +85,7 @@ Namespace API.Xhamster If m.Post.Date.HasValue Then Select Case CheckDatesLimit(m.Post.Date.Value, Nothing) - Case DateResult.Skip : Continue For + Case DateResult.Skip : skipped = True : Continue For Case DateResult.Exit : Exit Sub End Select End If @@ -108,7 +113,7 @@ Namespace API.Xhamster End Using End If - If MaxPage > 0 AndAlso Page < MaxPage Then DownloadData(Page + 1, IsVideo, Token) + If (Not _TempMediaList.Count = cBefore Or skipped) And (IsChannel Or (MaxPage > 0 And Page < MaxPage)) Then DownloadData(Page + 1, IsVideo, Token) Catch ex As Exception ProcessException(ex, Token, $"data downloading error [{URL}]") End Try @@ -286,7 +291,7 @@ Namespace API.Xhamster .ID = j.Value("id"), .Date = AConvert(Of Date)(j.Value("created"), DateProvider, Nothing) }, - .PictureOption = j.Value("title").StringRemoveWinForbiddenSymbols, + .PictureOption = TitleHtmlConverter(j.Value("title")), .Object = New ExchObj } If PostDate.HasValue Then m.Post.Date = PostDate @@ -309,7 +314,7 @@ Namespace API.Xhamster End If If Not m.URL.IsEmptyString Then If m.Post.ID.IsEmptyString Then m.Post.ID = m.URL.Split("/").LastOrDefault - If m.PictureOption.IsEmptyString Then m.PictureOption = j.Value("titleLocalized").StringRemoveWinForbiddenSymbols + If m.PictureOption.IsEmptyString Then m.PictureOption = TitleHtmlConverter(j.Value("titleLocalized")) If m.PictureOption.IsEmptyString Then m.PictureOption = m.Post.ID If setSpecialFolder Then m.SpecialFolder = m.PictureOption @@ -334,7 +339,7 @@ Namespace API.Xhamster Return If(Responser.Status = Net.WebExceptionStatus.ConnectionClosed, 1, 0) End Function #End Region -#Region "Idisposable support" +#Region "IDisposable support" Protected Overrides Sub Dispose(ByVal disposing As Boolean) If Not disposedValue And disposing Then _TempPhotoData.Clear() MyBase.Dispose(disposing) diff --git a/SCrawler/Download/Feed/DownloadFeedForm.vb b/SCrawler/Download/Feed/DownloadFeedForm.vb index 7689cdd..e519346 100644 --- a/SCrawler/Download/Feed/DownloadFeedForm.vb +++ b/SCrawler/Download/Feed/DownloadFeedForm.vb @@ -25,6 +25,8 @@ Namespace DownloadObjects Private FeedEndless As Boolean = False Private ReadOnly FileNotExist As New FPredicate(Of UserMediaD)(Function(d) Not d.Data.File.Exists) Private BttRefreshToolTipText As String = "Refresh data list" + Private CenterImage As Boolean = False + Private NumberOfVisibleImages As Integer = 1 #End Region #Region "Initializer" Friend Sub New() @@ -81,6 +83,25 @@ Namespace DownloadObjects DataRows = .FeedDataRows DataColumns = .FeedDataColumns FeedEndless = .FeedEndless + If .FeedCenterImage.Use Then + CenterImage = True + NumberOfVisibleImages = .FeedCenterImage + Else + CenterImage = False + NumberOfVisibleImages = 1 + End If + + If .FeedBackColor.Exists Then + BackColor = .FeedBackColor + Else + BackColor = SystemColors.Window + End If + If .FeedForeColor.Exists Then + ForeColor = .FeedForeColor + Else + ForeColor = SystemColors.WindowText + End If + Dim fsd As Boolean = .FeedStoreSessionsData ControlInvoke(ToolbarTOP, MENU_LOAD_SESSION, Sub() MENU_LOAD_SESSION.Visible = fsd @@ -107,7 +128,7 @@ Namespace DownloadObjects MyRange.HandlersSuspended = True MyRange.Limit = c MyRange.HandlersSuspended = False - If Not MyDefs.Initializing And rangeChanged Then RefillList() + If Not MyDefs.Initializing Then RefillList(False) End With End Sub #End Region @@ -376,9 +397,10 @@ Namespace DownloadObjects If d2.Count > 0 Then d.InsertRange(0, d2) : d2.Clear() End If Dim w% = GetWidth() + Dim h% = GetHeight() Dim p As New TPCELL(DataRows, DataColumns) Dim fmList As New List(Of FeedMedia) - d.ForEach(Sub(de) fmList.Add(New FeedMedia(de, w, AddressOf FeedMedia_MediaDeleted))) + d.ForEach(Sub(de) fmList.Add(New FeedMedia(de, w, h, AddressOf FeedMedia_MediaDeleted))) If fmList.Count > 0 Then fmList.ListDisposeRemoveAll(Function(fm) fm Is Nothing OrElse fm.HasError) If fmList.Count > 0 Then For i = 0 To fmList.Count - 1 @@ -420,6 +442,13 @@ Namespace DownloadObjects Private Function GetWidth() As Integer Return (TP_DATA.Width - PaddingE.GetOf({Me, TP_DATA}).Horizontal(2)) / DataColumns End Function + Private Function GetHeight() As Integer + If CenterImage And DataColumns = 1 Then + Return (TP_DATA.Height - PaddingE.GetOf({Me, TP_DATA}).Vertical(2)) / IIf(NumberOfVisibleImages > 0, NumberOfVisibleImages, 1) + Else + Return -1 + End If + End Function Private Sub DownloadFeedForm_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd ResizeGrid() End Sub @@ -431,10 +460,11 @@ Namespace DownloadObjects With TP_DATA If .Controls.Count > 0 Then Dim w% = GetWidth() + Dim h% = GetHeight() Dim p As TableLayoutPanelCellPosition Dim rh As New Dictionary(Of Integer, List(Of Integer)) For Each cnt As FeedMedia In .Controls - cnt.Width = w + cnt.RerenderObject(w, h) p = .GetCellPosition(cnt) If Not rh.ContainsKey(p.Row) Then rh.Add(p.Row, New List(Of Integer)) rh(p.Row).Add(cnt.Height) diff --git a/SCrawler/Download/Feed/FeedMedia.vb b/SCrawler/Download/Feed/FeedMedia.vb index b684649..d9b79e3 100644 --- a/SCrawler/Download/Feed/FeedMedia.vb +++ b/SCrawler/Download/Feed/FeedMedia.vb @@ -29,19 +29,19 @@ Namespace DownloadObjects End Property Friend ReadOnly Property HasError As Boolean Friend ReadOnly File As SFile - Public Shadows Property Width As Integer + Public Shadows Property Width(Optional ByVal UpdateImage As Boolean = True) As Integer Get Return MyBase.Width End Get Set(ByVal w As Integer) If Size.Width <> w Then - Dim s As New Size(w, If(MyImage Is Nothing, VideoHeight, MyImage.FitToWidthF(w).Height)) + Dim s As New Size(w, If(MyImage Is Nothing, VideoHeight, If(UpdateImage, MyImage.FitToWidthF(w).Height, MyPicture.Height))) Dim objSize As Size = s - objSize.Height += (TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2)) + objSize.Height += ObjectsPaddingHeight MinimumSize = objSize MyBase.MaximumSize = objSize Size = objSize - If Not MyImage Is Nothing Then + If UpdateImage AndAlso Not MyImage Is Nothing Then With MyPicture .MinimumSize = Nothing .MaximumSize = Nothing @@ -53,6 +53,11 @@ Namespace DownloadObjects End If End Set End Property + Private ReadOnly Property ObjectsPaddingHeight + Get + Return TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2) + End Get + End Property Private ReadOnly UserKey As String Private ReadOnly Post As UserMedia Friend ReadOnly Property Checked As Boolean @@ -61,12 +66,56 @@ Namespace DownloadObjects End Get End Property Friend ReadOnly Property Information As String + Private Function GetImageResize(ByVal Width As Integer, ByVal Height As Integer) As Size + If Height > 0 Then + Dim h% = Height = ObjectsPaddingHeight + If h <= 0 Then h = Height + Dim s As Size = MyImage.FitToHeightF(h) + s = MyImage.FitToWidthF(s, Width, False) + If s.Height > MyImage.Height Then s = MyImage.Size + Return s + Else + Return MyImage.FitToWidthF(Width) + End If + End Function + Friend Sub RerenderObject(ByVal Width As Integer, ByVal Height As Integer) + If Not MyImage Is Nothing Then + Dim s As Size + If Height > 0 Then + s = GetImageResize(Width, Height) + With MyPicture + .MinimumSize = Nothing + .MaximumSize = Nothing + .Size = s + .MinimumSize = s + .MaximumSize = s + .Anchor = AnchorStyles.Top + End With + Me.Width(False) = Width + Else + Me.Width = Width + MyPicture.Anchor = AnchorStyles.Left + AnchorStyles.Top + End If + Else + Me.Width = Width + End If + End Sub + Private Sub ApplyColors() + If Settings.FeedBackColor.Exists Then + BackColor = Settings.FeedBackColor + LBL_INFO.BackColor = Settings.FeedBackColor + End If + If Settings.FeedForeColor.Exists Then + ForeColor = Settings.FeedForeColor + LBL_INFO.ForeColor = Settings.FeedForeColor + End If + End Sub #End Region #Region "Initializers" Public Sub New() InitializeComponent() End Sub - Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Handler As MediaDeletedEventHandler) + Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Height As Integer, ByVal Handler As MediaDeletedEventHandler) Try InitializeComponent() File = Media.Data.File @@ -92,14 +141,15 @@ Namespace DownloadObjects Select Case Media.Data.Type Case UserMedia.Types.Picture, UserMedia.Types.GIF MyImage = New ImageRenderer(File) - s = MyImage.FitToWidthF(Width) + Dim a As AnchorStyles = AnchorStyles.Top + If(Height > 0, 0, AnchorStyles.Left) + s = GetImageResize(Width, Height) h = s.Height MyPicture = New PictureBox With { .SizeMode = PictureBoxSizeMode.Zoom, .Image = MyImage, .InitialImage = .Image, .Dock = DockStyle.None, - .Anchor = AnchorStyles.Left + AnchorStyles.Top, + .Anchor = a, .Size = s, .MinimumSize = s, .MaximumSize = s, @@ -141,11 +191,11 @@ Namespace DownloadObjects If Settings.FeedAddDateToCaption Then info &= $" ({Media.Date.ToStringDate(ADateTime.Formats.BaseDateTime)})" LBL_INFO.Text = info - s = New Size(Width, h + TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2)) + s = New Size(Width, h + ObjectsPaddingHeight) Size = s MinimumSize = s MaximumSize = s - + ApplyColors() If Not Handler Is Nothing Then AddHandler Me.MediaDeleted, Handler Else Throw New ArgumentNullException With {.HelpLink = 1} diff --git a/SCrawler/Download/Groups/DownloadGroup.vb b/SCrawler/Download/Groups/DownloadGroup.vb index 5dafc8f..0d91b36 100644 --- a/SCrawler/Download/Groups/DownloadGroup.vb +++ b/SCrawler/Download/Groups/DownloadGroup.vb @@ -90,18 +90,7 @@ Namespace DownloadObjects.Groups End Sub Friend Sub New(ByVal e As EContainer) Me.New - If e.Attributes.Contains(New EAttribute(Name_Name)) Then - 'TODELETE: 2022.10.18.0 - NeedToSave = True - Name = e.Attribute(Name_Name) - Temporary = e.Attribute(Name_Temporary).Value.FromXML(Of Integer)(CInt(CheckState.Indeterminate)) - Favorite = e.Attribute(Name_Favorite).Value.FromXML(Of Integer)(CInt(CheckState.Indeterminate)) - ReadyForDownload = e.Attribute(Name_ReadyForDownload).Value.FromXML(Of Boolean)(True) - ReadyForDownloadIgnore = e.Attribute(Name_ReadyForDownloadIgnore).Value.FromXML(Of Boolean)(False) - If Not e.Value.IsEmptyString Then Labels.ListAddList(e.Value.Split("|"), LAP.NotContainsOnly) - Else - Import(e) - End If + Import(e) End Sub #End Region #Region "ToString" diff --git a/SCrawler/Download/TDownloader.vb b/SCrawler/Download/TDownloader.vb index b33fe3e..02a74d2 100644 --- a/SCrawler/Download/TDownloader.vb +++ b/SCrawler/Download/TDownloader.vb @@ -51,7 +51,7 @@ Namespace DownloadObjects If Not u.Name.IsEmptyString And Not u.Site.IsEmptyString Then User = Settings.GetUser(u) End If Data = New UserMedia(e(Name_Media), User) - [Date] = AConvert(Of Date)(e.Value(Name_Date), ParsersDataDateProvider, Now) + [Date] = AConvert(Of Date)(e.Value(Name_Date), DateTimeDefaultProvider, Now) Session = e.Value(Name_Session).FromXML(Of Integer)(0) Dim f As SFile = e.Value(Name_File) If f.Exists Then Data.File = f @@ -78,7 +78,7 @@ Namespace DownloadObjects Friend Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer Return ListAddValue(New EContainer(Name_Data, String.Empty) From { Data.ToEContainer, - New EContainer(Name_Date, AConvert(Of String)([Date], ParsersDataDateProvider, String.Empty)), + New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)), New EContainer(Name_Session, Session), New EContainer(Name_File, Data.File)}, If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing), LAP.IgnoreICopier) diff --git a/SCrawler/Editors/ColorPicker.Designer.vb b/SCrawler/Editors/ColorPicker.Designer.vb new file mode 100644 index 0000000..500569b --- /dev/null +++ b/SCrawler/Editors/ColorPicker.Designer.vb @@ -0,0 +1,141 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Namespace Editors + + Partial Public Class ColorPicker : Inherits System.Windows.Forms.UserControl + + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + Private components As System.ComponentModel.IContainer + + Private Sub InitializeComponent() + Me.components = New System.ComponentModel.Container() + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ColorPicker)) + Dim TT_MAIN As System.Windows.Forms.ToolTip + Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel() + Me.LBL_CAPTION = New System.Windows.Forms.Label() + Me.LBL_COLORS = New System.Windows.Forms.Label() + Me.BTT_COLORS_FORE = New System.Windows.Forms.Button() + Me.BTT_COLORS_BACK = New System.Windows.Forms.Button() + Me.BTT_COLORS_CLEAR = New System.Windows.Forms.Button() + TT_MAIN = New System.Windows.Forms.ToolTip(Me.components) + Me.TP_MAIN.SuspendLayout() + Me.SuspendLayout() + ' + 'TP_MAIN + ' + Me.TP_MAIN.ColumnCount = 5 + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 105.0!)) + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!)) + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!)) + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!)) + Me.TP_MAIN.Controls.Add(Me.LBL_CAPTION, 0, 0) + Me.TP_MAIN.Controls.Add(Me.LBL_COLORS, 1, 0) + Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_FORE, 2, 0) + Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_BACK, 3, 0) + Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_CLEAR, 4, 0) + Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill + Me.TP_MAIN.Location = New System.Drawing.Point(0, 0) + Me.TP_MAIN.Margin = New System.Windows.Forms.Padding(0) + Me.TP_MAIN.Name = "TP_MAIN" + Me.TP_MAIN.RowCount = 1 + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) + Me.TP_MAIN.Size = New System.Drawing.Size(340, 28) + Me.TP_MAIN.TabIndex = 3 + ' + 'LBL_CAPTION + ' + Me.LBL_CAPTION.AutoSize = True + Me.LBL_CAPTION.Dock = System.Windows.Forms.DockStyle.Fill + Me.LBL_CAPTION.Location = New System.Drawing.Point(3, 0) + Me.LBL_CAPTION.Name = "LBL_CAPTION" + Me.LBL_CAPTION.Size = New System.Drawing.Size(99, 28) + Me.LBL_CAPTION.TabIndex = 0 + Me.LBL_CAPTION.TextAlign = System.Drawing.ContentAlignment.MiddleRight + ' + 'LBL_COLORS + ' + Me.LBL_COLORS.AutoSize = True + Me.LBL_COLORS.Dock = System.Windows.Forms.DockStyle.Fill + Me.LBL_COLORS.Location = New System.Drawing.Point(108, 3) + Me.LBL_COLORS.Margin = New System.Windows.Forms.Padding(3) + Me.LBL_COLORS.Name = "LBL_COLORS" + Me.LBL_COLORS.Size = New System.Drawing.Size(163, 22) + Me.LBL_COLORS.TabIndex = 1 + Me.LBL_COLORS.Text = "Here's what it looks like." + Me.LBL_COLORS.TextAlign = System.Drawing.ContentAlignment.MiddleCenter + ' + 'BTT_COLORS_FORE + ' + Me.BTT_COLORS_FORE.Dock = System.Windows.Forms.DockStyle.Fill + Me.BTT_COLORS_FORE.Location = New System.Drawing.Point(276, 2) + Me.BTT_COLORS_FORE.Margin = New System.Windows.Forms.Padding(2) + Me.BTT_COLORS_FORE.Name = "BTT_COLORS_FORE" + Me.BTT_COLORS_FORE.Size = New System.Drawing.Size(18, 24) + Me.BTT_COLORS_FORE.TabIndex = 2 + Me.BTT_COLORS_FORE.Tag = "F" + Me.BTT_COLORS_FORE.Text = "F" + TT_MAIN.SetToolTip(Me.BTT_COLORS_FORE, "Font color") + Me.BTT_COLORS_FORE.UseVisualStyleBackColor = True + ' + 'BTT_COLORS_BACK + ' + Me.BTT_COLORS_BACK.Dock = System.Windows.Forms.DockStyle.Fill + Me.BTT_COLORS_BACK.Location = New System.Drawing.Point(298, 2) + Me.BTT_COLORS_BACK.Margin = New System.Windows.Forms.Padding(2) + Me.BTT_COLORS_BACK.Name = "BTT_COLORS_BACK" + Me.BTT_COLORS_BACK.Size = New System.Drawing.Size(18, 24) + Me.BTT_COLORS_BACK.TabIndex = 3 + Me.BTT_COLORS_BACK.Tag = "C" + Me.BTT_COLORS_BACK.Text = "C" + TT_MAIN.SetToolTip(Me.BTT_COLORS_BACK, "Back color") + Me.BTT_COLORS_BACK.UseVisualStyleBackColor = True + ' + 'BTT_COLORS_CLEAR + ' + Me.BTT_COLORS_CLEAR.BackgroundImage = CType(resources.GetObject("BTT_COLORS_CLEAR.BackgroundImage"), System.Drawing.Image) + Me.BTT_COLORS_CLEAR.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom + Me.BTT_COLORS_CLEAR.Dock = System.Windows.Forms.DockStyle.Fill + Me.BTT_COLORS_CLEAR.Location = New System.Drawing.Point(320, 2) + Me.BTT_COLORS_CLEAR.Margin = New System.Windows.Forms.Padding(2) + Me.BTT_COLORS_CLEAR.Name = "BTT_COLORS_CLEAR" + Me.BTT_COLORS_CLEAR.Size = New System.Drawing.Size(18, 24) + Me.BTT_COLORS_CLEAR.TabIndex = 4 + Me.BTT_COLORS_CLEAR.Tag = "D" + TT_MAIN.SetToolTip(Me.BTT_COLORS_CLEAR, "Reset") + Me.BTT_COLORS_CLEAR.UseVisualStyleBackColor = True + ' + 'ColorPicker + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.Controls.Add(Me.TP_MAIN) + Me.Name = "ColorPicker" + Me.Size = New System.Drawing.Size(340, 28) + Me.TP_MAIN.ResumeLayout(False) + Me.TP_MAIN.PerformLayout() + Me.ResumeLayout(False) + + End Sub + Private WithEvents LBL_COLORS As Label + Private WithEvents BTT_COLORS_FORE As Button + Private WithEvents BTT_COLORS_BACK As Button + Private WithEvents BTT_COLORS_CLEAR As Button + Private WithEvents TP_MAIN As TableLayoutPanel + Private WithEvents LBL_CAPTION As Label + End Class +End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/ColorPicker.resx b/SCrawler/Editors/ColorPicker.resx new file mode 100644 index 0000000..c6fe36e --- /dev/null +++ b/SCrawler/Editors/ColorPicker.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go + tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX + AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SCrawler/Editors/ColorPicker.vb b/SCrawler/Editors/ColorPicker.vb new file mode 100644 index 0000000..6d1226f --- /dev/null +++ b/SCrawler/Editors/ColorPicker.vb @@ -0,0 +1,113 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Imports System.ComponentModel +Imports PersonalUtilities.Forms +Imports PersonalUtilities.Functions.XML.Objects +Namespace Editors + Public Class ColorPicker : Implements IChangeDetectorCompatible + Private Event DataChanged As EventHandler Implements IChangeDetectorCompatible.DataChanged + Public Sub New() + InitializeComponent() + End Sub +#Region "Appearance" + + Public Property CaptionWidth As Integer + Get + Return TP_MAIN.ColumnStyles(0).Width + End Get + Set(ByVal w As Integer) + TP_MAIN.ColumnStyles(0).Width = w + End Set + End Property + Private ReadOnly ButtonsMarginDefault As New Padding(2) + + Public Property ButtonsMargin As Padding + Get + Return BTT_COLORS_CLEAR.Margin + End Get + Set(ByVal m As Padding) + BTT_COLORS_BACK.Margin = m + BTT_COLORS_FORE.Margin = m + BTT_COLORS_CLEAR.Margin = m + End Set + End Property + Private Function ShouldSerializeButtonsMargin() As Boolean + Return Not ButtonsMargin.Equals(ButtonsMarginDefault) + End Function + Private Sub ResetButtonsMargin() + ButtonsMargin = ButtonsMarginDefault + End Sub + + Public Property CaptionText As String + Get + Return LBL_CAPTION.Text + End Get + Set(ByVal t As String) + LBL_CAPTION.Text = t + End Set + End Property +#End Region +#Region "Colors" + Private BackColorDefault As Color = DefaultBackColor + Private _BackColorImpl As Color? = Nothing + Private Property BackColorImpl As Color? + Get + Return _BackColorImpl + End Get + Set(ByVal c As Color?) + _BackColorImpl = c + If _BackColorImpl.HasValue Then LBL_COLORS.BackColor = _BackColorImpl.Value Else LBL_COLORS.BackColor = BackColorDefault + End Set + End Property + Private ForeColorDefault As Color = DefaultForeColor + Private _ForeColorImpl As Color? = Nothing + Private Property ForeColorImpl As Color? + Get + Return _ForeColorImpl + End Get + Set(ByVal c As Color?) + _ForeColorImpl = c + If _ForeColorImpl.HasValue Then LBL_COLORS.ForeColor = _ForeColorImpl.Value Else LBL_COLORS.ForeColor = ForeColorDefault + End Set + End Property +#End Region +#Region "Get, Set" + Friend Sub ColorsSet(ByVal b As XMLValue(Of Color), ByVal f As XMLValue(Of Color), ByVal bDefault As Color, ByVal fDefault As Color) + BackColorDefault = bDefault + If b.Exists Then + BackColorImpl = b.Value + Else + BackColorImpl = Nothing + End If + ForeColorDefault = fDefault + If f.Exists Then + ForeColorImpl = f.Value + Else + ForeColorImpl = Nothing + End If + End Sub + Friend Sub ColorsGet(ByRef b As XMLValue(Of Color), ByRef f As XMLValue(Of Color)) + If BackColorImpl.HasValue Then b.Value = BackColorImpl.Value Else b.ValueF = Nothing + If ForeColorImpl.HasValue Then f.Value = ForeColorImpl.Value Else f.ValueF = Nothing + End Sub +#End Region +#Region "Buttons handlers" + Private Sub COLOR_BUTTONS_Click(ByVal Sender As Button, ByVal e As EventArgs) Handles BTT_COLORS_BACK.Click, + BTT_COLORS_FORE.Click, + BTT_COLORS_CLEAR.Click + Select Case CStr(Sender.Tag) + Case "F" : ForeColorImpl = AFontColor.SelectNewColor(ForeColorImpl, EDP.ReturnValue) + Case "C" : BackColorImpl = AFontColor.SelectNewColor(BackColorImpl, EDP.ReturnValue) + Case "D" : BackColorImpl = Nothing : ForeColorImpl = Nothing + End Select + RaiseEvent DataChanged(Me, Nothing) + End Sub +#End Region + End Class +End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/GlobalSettingsForm.Designer.vb b/SCrawler/Editors/GlobalSettingsForm.Designer.vb index 84cf9e9..0ead2f7 100644 --- a/SCrawler/Editors/GlobalSettingsForm.Designer.vb +++ b/SCrawler/Editors/GlobalSettingsForm.Designer.vb @@ -24,16 +24,18 @@ Namespace Editors Private Sub InitializeComponent() Me.components = New System.ComponentModel.Container() Dim TP_BASIS As System.Windows.Forms.TableLayoutPanel - Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(GlobalSettingsForm)) - Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_IMAGES As System.Windows.Forms.TableLayoutPanel - Dim ActionButton15 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton16 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton17 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton18 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton19 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton20 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel Dim LBL_DATE_POS As System.Windows.Forms.Label @@ -46,14 +48,14 @@ Namespace Editors Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel Dim TAB_BEHAVIOR As System.Windows.Forms.TabPage Dim TP_BEHAVIOR As System.Windows.Forms.TableLayoutPanel - Dim ActionButton21 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton22 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton11 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton12 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_OPEN_INFO As System.Windows.Forms.TableLayoutPanel Dim TP_OPEN_PROGRESS As System.Windows.Forms.TableLayoutPanel Dim TAB_DOWN As System.Windows.Forms.TabPage Dim TP_DOWNLOADING As System.Windows.Forms.TableLayoutPanel - Dim ActionButton23 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton24 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_MISSING_DATA As System.Windows.Forms.TableLayoutPanel Dim TAB_FEED As System.Windows.Forms.TabPage Dim TP_FEED As System.Windows.Forms.TableLayoutPanel @@ -71,6 +73,8 @@ Namespace Editors Me.CH_SHOW_GROUPS = New System.Windows.Forms.CheckBox() Me.CH_USERS_GROUPING = New System.Windows.Forms.CheckBox() Me.TXT_USER_AGENT = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.TXT_USER_LIST_IMAGE = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.COLORS_USERLIST = New SCrawler.Editors.ColorPicker() Me.OPT_FILE_NAME_REPLACE = New System.Windows.Forms.RadioButton() Me.OPT_FILE_NAME_ADD_DATE = New System.Windows.Forms.RadioButton() Me.CH_FILE_NAME_CHANGE = New System.Windows.Forms.CheckBox() @@ -99,6 +103,7 @@ Namespace Editors Me.CH_NOTIFY_CHANNELS = New System.Windows.Forms.CheckBox() Me.CH_NOTIFY_SAVED_POSTS = New System.Windows.Forms.CheckBox() Me.CH_DOWN_REPARSE_MISSING = New System.Windows.Forms.CheckBox() + Me.CH_NAME_SITE_FRIENDLY = New System.Windows.Forms.CheckBox() Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox() @@ -112,11 +117,14 @@ Namespace Editors Me.CH_DOWN_OPEN_PROGRESS = New System.Windows.Forms.CheckBox() Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.CH_UNAME_UP = New System.Windows.Forms.CheckBox() Me.TXT_FEED_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_FEED_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.CH_FEED_ENDLESS = New System.Windows.Forms.CheckBox() Me.CH_FEED_ADD_SESSION = New System.Windows.Forms.CheckBox() Me.CH_FEED_ADD_DATE = New System.Windows.Forms.CheckBox() + Me.TXT_FEED_CENTER_IMAGE = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.COLORS_FEED = New SCrawler.Editors.ColorPicker() Me.TAB_MAIN = New System.Windows.Forms.TabControl() Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() TP_BASIS = New System.Windows.Forms.TableLayoutPanel() @@ -153,6 +161,7 @@ Namespace Editors CType(Me.TXT_MAX_JOBS_CHANNELS, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).BeginInit() TP_FILE_NAME.SuspendLayout() TP_FILE_PATTERNS.SuspendLayout() TP_CHANNELS_IMGS.SuspendLayout() @@ -180,6 +189,7 @@ Namespace Editors TP_FEED_IMG_COUNT.SuspendLayout() CType(Me.TXT_FEED_ROWS, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_FEED_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.TXT_FEED_CENTER_IMAGE, System.ComponentModel.ISupportInitialize).BeginInit() TAB_NOTIFY.SuspendLayout() TP_NOTIFY_MAIN.SuspendLayout() Me.TAB_MAIN.SuspendLayout() @@ -199,13 +209,15 @@ Namespace Editors TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_CHANNELS, 0, 4) TP_BASIS.Controls.Add(Me.CH_CHECK_VER_START, 0, 5) TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 7) - TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 8) - TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 9) + TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 10) + TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 11) TP_BASIS.Controls.Add(Me.TXT_USER_AGENT, 0, 6) + TP_BASIS.Controls.Add(Me.TXT_USER_LIST_IMAGE, 0, 8) + TP_BASIS.Controls.Add(Me.COLORS_USERLIST, 0, 9) TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill TP_BASIS.Location = New System.Drawing.Point(3, 3) TP_BASIS.Name = "TP_BASIS" - TP_BASIS.RowCount = 11 + TP_BASIS.RowCount = 13 TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) @@ -214,20 +226,23 @@ Namespace Editors TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_BASIS.Size = New System.Drawing.Size(570, 279) + TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) + TP_BASIS.Size = New System.Drawing.Size(570, 337) TP_BASIS.TabIndex = 0 ' 'TXT_GLOBAL_PATH ' - ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image) - ActionButton13.Name = "Open" - ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image) - ActionButton14.Name = "Clear" - Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton13) - Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton14) + ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image) + ActionButton1.Name = "Open" + ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image) + ActionButton2.Name = "Clear" + Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton1) + Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton2) Me.TXT_GLOBAL_PATH.CaptionText = "Data Path" Me.TXT_GLOBAL_PATH.CaptionToolTipEnabled = True Me.TXT_GLOBAL_PATH.CaptionToolTipText = "Root path for storing users' data" @@ -288,9 +303,9 @@ Namespace Editors ' 'TXT_COLLECTIONS_PATH ' - ActionButton15.BackgroundImage = CType(resources.GetObject("ActionButton15.BackgroundImage"), System.Drawing.Image) - ActionButton15.Name = "Clear" - Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton15) + ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image) + ActionButton3.Name = "Clear" + Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton3) Me.TXT_COLLECTIONS_PATH.CaptionText = "Collections folder" Me.TXT_COLLECTIONS_PATH.CaptionToolTipEnabled = True Me.TXT_COLLECTIONS_PATH.CaptionToolTipText = "Set collections folder name (name only)" @@ -302,10 +317,10 @@ Namespace Editors ' 'TXT_MAX_JOBS_USERS ' - ActionButton16.BackgroundImage = CType(resources.GetObject("ActionButton16.BackgroundImage"), System.Drawing.Image) - ActionButton16.Name = "Refresh" - ActionButton16.ToolTipText = "Set to default" - Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton16) + ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image) + ActionButton4.Name = "Refresh" + ActionButton4.ToolTipText = "Set to default" + Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton4) Me.TXT_MAX_JOBS_USERS.CaptionSizeType = System.Windows.Forms.SizeType.Percent Me.TXT_MAX_JOBS_USERS.CaptionText = "Maximum downloading tasks of users" Me.TXT_MAX_JOBS_USERS.CaptionWidth = 50.0R @@ -321,10 +336,10 @@ Namespace Editors ' 'TXT_MAX_JOBS_CHANNELS ' - ActionButton17.BackgroundImage = CType(resources.GetObject("ActionButton17.BackgroundImage"), System.Drawing.Image) - ActionButton17.Name = "Refresh" - ActionButton17.ToolTipText = "Set to default" - Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton17) + ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image) + ActionButton5.Name = "Refresh" + ActionButton5.ToolTipText = "Set to default" + Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton5) Me.TXT_MAX_JOBS_CHANNELS.CaptionSizeType = System.Windows.Forms.SizeType.Percent Me.TXT_MAX_JOBS_CHANNELS.CaptionText = "Maximum downloading tasks of channels" Me.TXT_MAX_JOBS_CHANNELS.CaptionWidth = 50.0R @@ -351,9 +366,9 @@ Namespace Editors ' 'TXT_IMGUR_CLIENT_ID ' - ActionButton18.BackgroundImage = CType(resources.GetObject("ActionButton18.BackgroundImage"), System.Drawing.Image) - ActionButton18.Name = "Clear" - Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton18) + ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image) + ActionButton6.Name = "Clear" + Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton6) Me.TXT_IMGUR_CLIENT_ID.CaptionText = "Imgur Client ID" Me.TXT_IMGUR_CLIENT_ID.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 204) @@ -365,10 +380,10 @@ Namespace Editors ' Me.CH_SHOW_GROUPS.AutoSize = True Me.CH_SHOW_GROUPS.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_SHOW_GROUPS.Location = New System.Drawing.Point(4, 233) + Me.CH_SHOW_GROUPS.Location = New System.Drawing.Point(4, 288) Me.CH_SHOW_GROUPS.Name = "CH_SHOW_GROUPS" Me.CH_SHOW_GROUPS.Size = New System.Drawing.Size(562, 19) - Me.CH_SHOW_GROUPS.TabIndex = 8 + Me.CH_SHOW_GROUPS.TabIndex = 10 Me.CH_SHOW_GROUPS.Text = "Show groups" TT_MAIN.SetToolTip(Me.CH_SHOW_GROUPS, "Grouping users by site") Me.CH_SHOW_GROUPS.UseVisualStyleBackColor = True @@ -377,24 +392,24 @@ Namespace Editors ' Me.CH_USERS_GROUPING.AutoSize = True Me.CH_USERS_GROUPING.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_USERS_GROUPING.Location = New System.Drawing.Point(4, 259) + Me.CH_USERS_GROUPING.Location = New System.Drawing.Point(4, 314) Me.CH_USERS_GROUPING.Name = "CH_USERS_GROUPING" Me.CH_USERS_GROUPING.Size = New System.Drawing.Size(562, 19) - Me.CH_USERS_GROUPING.TabIndex = 9 + Me.CH_USERS_GROUPING.TabIndex = 11 Me.CH_USERS_GROUPING.Text = "Use user grouping" TT_MAIN.SetToolTip(Me.CH_USERS_GROUPING, "Group users by groups and/or labels") Me.CH_USERS_GROUPING.UseVisualStyleBackColor = True ' 'TXT_USER_AGENT ' - ActionButton19.BackgroundImage = CType(resources.GetObject("ActionButton19.BackgroundImage"), System.Drawing.Image) - ActionButton19.Name = "Refresh" - ActionButton19.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh - ActionButton20.BackgroundImage = CType(resources.GetObject("ActionButton20.BackgroundImage"), System.Drawing.Image) - ActionButton20.Name = "Clear" - ActionButton20.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_USER_AGENT.Buttons.Add(ActionButton19) - Me.TXT_USER_AGENT.Buttons.Add(ActionButton20) + ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image) + ActionButton7.Name = "Refresh" + ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh + ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image) + ActionButton8.Name = "Clear" + ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_USER_AGENT.Buttons.Add(ActionButton7) + Me.TXT_USER_AGENT.Buttons.Add(ActionButton8) Me.TXT_USER_AGENT.CaptionText = "UserAgent" Me.TXT_USER_AGENT.CaptionToolTipEnabled = True Me.TXT_USER_AGENT.CaptionToolTipText = "Default user agent to use in requests" @@ -404,6 +419,38 @@ Namespace Editors Me.TXT_USER_AGENT.Size = New System.Drawing.Size(562, 22) Me.TXT_USER_AGENT.TabIndex = 6 ' + 'TXT_USER_LIST_IMAGE + ' + ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image) + ActionButton9.Name = "Open" + ActionButton9.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image) + ActionButton10.Name = "Clear" + ActionButton10.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton9) + Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton10) + Me.TXT_USER_LIST_IMAGE.CaptionText = "Userlist image" + Me.TXT_USER_LIST_IMAGE.CaptionToolTipEnabled = True + Me.TXT_USER_LIST_IMAGE.CaptionToolTipText = "Background image for user list" + Me.TXT_USER_LIST_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill + Me.TXT_USER_LIST_IMAGE.Location = New System.Drawing.Point(4, 233) + Me.TXT_USER_LIST_IMAGE.Name = "TXT_USER_LIST_IMAGE" + Me.TXT_USER_LIST_IMAGE.Size = New System.Drawing.Size(562, 22) + Me.TXT_USER_LIST_IMAGE.TabIndex = 8 + ' + 'COLORS_USERLIST + ' + Me.COLORS_USERLIST.ButtonsMargin = New System.Windows.Forms.Padding(1, 2, 1, 2) + Me.COLORS_USERLIST.CaptionText = "Userlist colors" + Me.COLORS_USERLIST.CaptionWidth = 103 + Me.COLORS_USERLIST.Dock = System.Windows.Forms.DockStyle.Fill + Me.COLORS_USERLIST.Location = New System.Drawing.Point(1, 259) + Me.COLORS_USERLIST.Margin = New System.Windows.Forms.Padding(0) + Me.COLORS_USERLIST.Name = "COLORS_USERLIST" + Me.COLORS_USERLIST.Padding = New System.Windows.Forms.Padding(0, 0, 2, 0) + Me.COLORS_USERLIST.Size = New System.Drawing.Size(568, 25) + Me.COLORS_USERLIST.TabIndex = 9 + ' 'TP_FILE_NAME ' TP_FILE_NAME.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] @@ -415,13 +462,13 @@ Namespace Editors TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0) TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0) TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill - TP_FILE_NAME.Location = New System.Drawing.Point(1, 27) + TP_FILE_NAME.Location = New System.Drawing.Point(1, 53) TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0) TP_FILE_NAME.Name = "TP_FILE_NAME" TP_FILE_NAME.RowCount = 1 TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_NAME.Size = New System.Drawing.Size(574, 30) - TP_FILE_NAME.TabIndex = 1 + TP_FILE_NAME.TabIndex = 2 ' 'OPT_FILE_NAME_REPLACE ' @@ -473,14 +520,14 @@ Namespace Editors TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0) TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0) TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill - TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 58) + TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 84) TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0) TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS" TP_FILE_PATTERNS.RowCount = 1 TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!)) TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30) - TP_FILE_PATTERNS.TabIndex = 2 + TP_FILE_PATTERNS.TabIndex = 3 ' 'CH_FILE_DATE ' @@ -701,10 +748,10 @@ Namespace Editors ' Me.CH_FEED_STORE_SESSION_DATA.AutoSize = True Me.CH_FEED_STORE_SESSION_DATA.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_STORE_SESSION_DATA.Location = New System.Drawing.Point(4, 111) + Me.CH_FEED_STORE_SESSION_DATA.Location = New System.Drawing.Point(4, 166) Me.CH_FEED_STORE_SESSION_DATA.Name = "CH_FEED_STORE_SESSION_DATA" Me.CH_FEED_STORE_SESSION_DATA.Size = New System.Drawing.Size(568, 19) - Me.CH_FEED_STORE_SESSION_DATA.TabIndex = 4 + Me.CH_FEED_STORE_SESSION_DATA.TabIndex = 6 Me.CH_FEED_STORE_SESSION_DATA.Text = "Store session data" TT_MAIN.SetToolTip(Me.CH_FEED_STORE_SESSION_DATA, "If checked, session data will be stored in an xml file.") Me.CH_FEED_STORE_SESSION_DATA.UseVisualStyleBackColor = True @@ -787,15 +834,27 @@ Namespace Editors ' Me.CH_DOWN_REPARSE_MISSING.AutoSize = True Me.CH_DOWN_REPARSE_MISSING.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 176) + Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 202) Me.CH_DOWN_REPARSE_MISSING.Name = "CH_DOWN_REPARSE_MISSING" Me.CH_DOWN_REPARSE_MISSING.Size = New System.Drawing.Size(568, 19) - Me.CH_DOWN_REPARSE_MISSING.TabIndex = 6 + Me.CH_DOWN_REPARSE_MISSING.TabIndex = 7 Me.CH_DOWN_REPARSE_MISSING.Text = "Trying to download missing posts using regular download" TT_MAIN.SetToolTip(Me.CH_DOWN_REPARSE_MISSING, "If missing posts exist, the missing posts will attempt to be downloaded via user " & "download") Me.CH_DOWN_REPARSE_MISSING.UseVisualStyleBackColor = True ' + 'CH_NAME_SITE_FRIENDLY + ' + Me.CH_NAME_SITE_FRIENDLY.AutoSize = True + Me.CH_NAME_SITE_FRIENDLY.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_NAME_SITE_FRIENDLY.Location = New System.Drawing.Point(4, 134) + Me.CH_NAME_SITE_FRIENDLY.Name = "CH_NAME_SITE_FRIENDLY" + Me.CH_NAME_SITE_FRIENDLY.Size = New System.Drawing.Size(562, 19) + Me.CH_NAME_SITE_FRIENDLY.TabIndex = 5 + Me.CH_NAME_SITE_FRIENDLY.Text = "Use the site name as a friendly name" + TT_MAIN.SetToolTip(Me.CH_NAME_SITE_FRIENDLY, "Use the user's site name as a friendly name") + Me.CH_NAME_SITE_FRIENDLY.UseVisualStyleBackColor = True + ' 'TP_CHANNELS_IMGS ' TP_CHANNELS_IMGS.ColumnCount = 2 @@ -847,7 +906,7 @@ Namespace Editors TAB_BASIS.Location = New System.Drawing.Point(4, 22) TAB_BASIS.Name = "TAB_BASIS" TAB_BASIS.Padding = New System.Windows.Forms.Padding(3) - TAB_BASIS.Size = New System.Drawing.Size(576, 285) + TAB_BASIS.Size = New System.Drawing.Size(576, 343) TAB_BASIS.TabIndex = 0 TAB_BASIS.Text = "Basis" ' @@ -857,7 +916,7 @@ Namespace Editors TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22) TAB_DEFAULTS.Name = "TAB_DEFAULTS" TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3) - TAB_DEFAULTS.Size = New System.Drawing.Size(576, 338) + TAB_DEFAULTS.Size = New System.Drawing.Size(576, 486) TAB_DEFAULTS.TabIndex = 1 TAB_DEFAULTS.Text = "Defaults" ' @@ -871,17 +930,19 @@ Namespace Editors TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES, 0, 2) TP_DEFS.Controls.Add(Me.CH_DEF_TEMP, 0, 1) TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES_NATIVE, 0, 4) + TP_DEFS.Controls.Add(Me.CH_NAME_SITE_FRIENDLY, 0, 5) TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill TP_DEFS.Location = New System.Drawing.Point(3, 3) TP_DEFS.Name = "TP_DEFS" - TP_DEFS.RowCount = 6 + TP_DEFS.RowCount = 7 + TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DEFS.Size = New System.Drawing.Size(570, 332) + TP_DEFS.Size = New System.Drawing.Size(570, 480) TP_DEFS.TabIndex = 0 ' 'CH_DOWN_IMAGES_NATIVE @@ -901,7 +962,7 @@ Namespace Editors TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22) TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS" TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3) - TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 338) + TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 486) TAB_DEFS_CHANNELS.TabIndex = 4 TAB_DEFS_CHANNELS.Text = "Channels" ' @@ -925,7 +986,7 @@ Namespace Editors TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_CHANNELS.Size = New System.Drawing.Size(570, 332) + TP_CHANNELS.Size = New System.Drawing.Size(570, 480) TP_CHANNELS.TabIndex = 0 ' 'TXT_CHANNEL_USER_POST_LIMIT @@ -953,7 +1014,7 @@ Namespace Editors TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR) TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22) TAB_BEHAVIOR.Name = "TAB_BEHAVIOR" - TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 338) + TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 486) TAB_BEHAVIOR.TabIndex = 5 TAB_BEHAVIOR.Text = "Behavior" ' @@ -984,17 +1045,17 @@ Namespace Editors TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_BEHAVIOR.Size = New System.Drawing.Size(576, 338) + TP_BEHAVIOR.Size = New System.Drawing.Size(576, 486) TP_BEHAVIOR.TabIndex = 0 ' 'TXT_FOLDER_CMD ' Me.TXT_FOLDER_CMD.AutoShowClearButton = True - ActionButton21.BackgroundImage = CType(resources.GetObject("ActionButton21.BackgroundImage"), System.Drawing.Image) - ActionButton21.Enabled = False - ActionButton21.Name = "Clear" - ActionButton21.Visible = False - Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton21) + ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image) + ActionButton11.Enabled = False + ActionButton11.Name = "Clear" + ActionButton11.Visible = False + Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton11) Me.TXT_FOLDER_CMD.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_FOLDER_CMD.CaptionText = "Folder cmd" Me.TXT_FOLDER_CMD.CaptionToolTipEnabled = True @@ -1033,11 +1094,11 @@ Namespace Editors 'TXT_CLOSE_SCRIPT ' Me.TXT_CLOSE_SCRIPT.AutoShowClearButton = True - ActionButton22.BackgroundImage = CType(resources.GetObject("ActionButton22.BackgroundImage"), System.Drawing.Image) - ActionButton22.Enabled = False - ActionButton22.Name = "Clear" - ActionButton22.Visible = False - Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton22) + ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image) + ActionButton12.Enabled = False + ActionButton12.Name = "Clear" + ActionButton12.Visible = False + Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton12) Me.TXT_CLOSE_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_CLOSE_SCRIPT.CaptionText = "Close cmd" Me.TXT_CLOSE_SCRIPT.CaptionToolTipEnabled = True @@ -1125,7 +1186,7 @@ Namespace Editors TAB_DOWN.Controls.Add(TP_DOWNLOADING) TAB_DOWN.Location = New System.Drawing.Point(4, 22) TAB_DOWN.Name = "TAB_DOWN" - TAB_DOWN.Size = New System.Drawing.Size(576, 338) + TAB_DOWN.Size = New System.Drawing.Size(576, 486) TAB_DOWN.TabIndex = 6 TAB_DOWN.Text = "Downloading" ' @@ -1134,17 +1195,19 @@ Namespace Editors TP_DOWNLOADING.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] TP_DOWNLOADING.ColumnCount = 1 TP_DOWNLOADING.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 1) - TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 2) - TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 3) + TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 2) + TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 3) + TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 4) TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0) - TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 4) - TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 5) - TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 6) + TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 5) + TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 6) + TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 7) + TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1) TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0) TP_DOWNLOADING.Name = "TP_DOWNLOADING" - TP_DOWNLOADING.RowCount = 8 + TP_DOWNLOADING.RowCount = 9 + TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!)) @@ -1153,17 +1216,17 @@ Namespace Editors TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DOWNLOADING.Size = New System.Drawing.Size(576, 338) - TP_DOWNLOADING.TabIndex = 0 + TP_DOWNLOADING.Size = New System.Drawing.Size(576, 486) + TP_DOWNLOADING.TabIndex = 1 ' 'TXT_SCRIPT ' - ActionButton23.BackgroundImage = CType(resources.GetObject("ActionButton23.BackgroundImage"), System.Drawing.Image) - ActionButton23.Name = "Open" - ActionButton24.BackgroundImage = CType(resources.GetObject("ActionButton24.BackgroundImage"), System.Drawing.Image) - ActionButton24.Name = "Clear" - Me.TXT_SCRIPT.Buttons.Add(ActionButton23) - Me.TXT_SCRIPT.Buttons.Add(ActionButton24) + ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image) + ActionButton13.Name = "Open" + ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image) + ActionButton14.Name = "Clear" + Me.TXT_SCRIPT.Buttons.Add(ActionButton13) + Me.TXT_SCRIPT.Buttons.Add(ActionButton14) Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_SCRIPT.CaptionText = "Script" Me.TXT_SCRIPT.CaptionToolTipEnabled = True @@ -1171,12 +1234,12 @@ Namespace Editors "sing the script option." Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 92) + Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 118) Me.TXT_SCRIPT.Name = "TXT_SCRIPT" Me.TXT_SCRIPT.PlaceholderEnabled = True Me.TXT_SCRIPT.PlaceholderText = "Enter script path here..." Me.TXT_SCRIPT.Size = New System.Drawing.Size(568, 22) - Me.TXT_SCRIPT.TabIndex = 3 + Me.TXT_SCRIPT.TabIndex = 4 ' 'TXT_DOWN_COMPLETE_SCRIPT ' @@ -1186,12 +1249,12 @@ Namespace Editors Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipText = "This command will be executed after all downloads are completed" Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionWidth = 120.0R Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 121) + Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 147) Me.TXT_DOWN_COMPLETE_SCRIPT.Name = "TXT_DOWN_COMPLETE_SCRIPT" Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderText = "Enter command here..." Me.TXT_DOWN_COMPLETE_SCRIPT.Size = New System.Drawing.Size(568, 22) - Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 4 + Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 5 ' 'TP_MISSING_DATA ' @@ -1202,21 +1265,32 @@ Namespace Editors TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_TO_LOG, 0, 0) TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_ERROS_TO_LOG, 1, 0) TP_MISSING_DATA.Dock = System.Windows.Forms.DockStyle.Fill - TP_MISSING_DATA.Location = New System.Drawing.Point(1, 147) + TP_MISSING_DATA.Location = New System.Drawing.Point(1, 173) TP_MISSING_DATA.Margin = New System.Windows.Forms.Padding(0) TP_MISSING_DATA.Name = "TP_MISSING_DATA" TP_MISSING_DATA.RowCount = 1 TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24.0!)) TP_MISSING_DATA.Size = New System.Drawing.Size(574, 25) - TP_MISSING_DATA.TabIndex = 5 + TP_MISSING_DATA.TabIndex = 6 + ' + 'CH_UNAME_UP + ' + Me.CH_UNAME_UP.AutoSize = True + Me.CH_UNAME_UP.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_UNAME_UP.Location = New System.Drawing.Point(4, 30) + Me.CH_UNAME_UP.Name = "CH_UNAME_UP" + Me.CH_UNAME_UP.Size = New System.Drawing.Size(568, 19) + Me.CH_UNAME_UP.TabIndex = 7 + Me.CH_UNAME_UP.Text = "Update user site name every time" + Me.CH_UNAME_UP.UseVisualStyleBackColor = True ' 'TAB_FEED ' TAB_FEED.Controls.Add(TP_FEED) TAB_FEED.Location = New System.Drawing.Point(4, 22) TAB_FEED.Name = "TAB_FEED" - TAB_FEED.Size = New System.Drawing.Size(576, 338) + TAB_FEED.Size = New System.Drawing.Size(576, 486) TAB_FEED.TabIndex = 7 TAB_FEED.Text = "Feed" ' @@ -1226,21 +1300,26 @@ Namespace Editors TP_FEED.ColumnCount = 1 TP_FEED.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FEED.Controls.Add(TP_FEED_IMG_COUNT, 0, 0) - TP_FEED.Controls.Add(Me.CH_FEED_ENDLESS, 0, 1) - TP_FEED.Controls.Add(Me.CH_FEED_ADD_SESSION, 0, 2) - TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 3) - TP_FEED.Controls.Add(Me.CH_FEED_STORE_SESSION_DATA, 0, 4) + TP_FEED.Controls.Add(Me.CH_FEED_ENDLESS, 0, 3) + TP_FEED.Controls.Add(Me.CH_FEED_ADD_SESSION, 0, 4) + TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 5) + TP_FEED.Controls.Add(Me.CH_FEED_STORE_SESSION_DATA, 0, 6) + TP_FEED.Controls.Add(Me.TXT_FEED_CENTER_IMAGE, 0, 1) + TP_FEED.Controls.Add(Me.COLORS_FEED, 0, 2) TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill TP_FEED.Location = New System.Drawing.Point(0, 0) TP_FEED.Name = "TP_FEED" - TP_FEED.RowCount = 6 + TP_FEED.RowCount = 8 + TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) + TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_FEED.Size = New System.Drawing.Size(576, 338) + TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) + TP_FEED.Size = New System.Drawing.Size(576, 486) TP_FEED.TabIndex = 0 ' 'TP_FEED_IMG_COUNT @@ -1296,10 +1375,10 @@ Namespace Editors ' Me.CH_FEED_ENDLESS.AutoSize = True Me.CH_FEED_ENDLESS.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_ENDLESS.Location = New System.Drawing.Point(4, 33) + Me.CH_FEED_ENDLESS.Location = New System.Drawing.Point(4, 88) Me.CH_FEED_ENDLESS.Name = "CH_FEED_ENDLESS" Me.CH_FEED_ENDLESS.Size = New System.Drawing.Size(568, 19) - Me.CH_FEED_ENDLESS.TabIndex = 1 + Me.CH_FEED_ENDLESS.TabIndex = 3 Me.CH_FEED_ENDLESS.Text = "Endless feed" Me.CH_FEED_ENDLESS.UseVisualStyleBackColor = True ' @@ -1307,10 +1386,10 @@ Namespace Editors ' Me.CH_FEED_ADD_SESSION.AutoSize = True Me.CH_FEED_ADD_SESSION.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_ADD_SESSION.Location = New System.Drawing.Point(4, 59) + Me.CH_FEED_ADD_SESSION.Location = New System.Drawing.Point(4, 114) Me.CH_FEED_ADD_SESSION.Name = "CH_FEED_ADD_SESSION" Me.CH_FEED_ADD_SESSION.Size = New System.Drawing.Size(568, 19) - Me.CH_FEED_ADD_SESSION.TabIndex = 2 + Me.CH_FEED_ADD_SESSION.TabIndex = 4 Me.CH_FEED_ADD_SESSION.Text = "Add the session number to the post title" Me.CH_FEED_ADD_SESSION.UseVisualStyleBackColor = True ' @@ -1318,19 +1397,51 @@ Namespace Editors ' Me.CH_FEED_ADD_DATE.AutoSize = True Me.CH_FEED_ADD_DATE.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 85) + Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 140) Me.CH_FEED_ADD_DATE.Name = "CH_FEED_ADD_DATE" Me.CH_FEED_ADD_DATE.Size = New System.Drawing.Size(568, 19) - Me.CH_FEED_ADD_DATE.TabIndex = 3 + Me.CH_FEED_ADD_DATE.TabIndex = 5 Me.CH_FEED_ADD_DATE.Text = "Add the date to the post title" Me.CH_FEED_ADD_DATE.UseVisualStyleBackColor = True ' + 'TXT_FEED_CENTER_IMAGE + ' + Me.TXT_FEED_CENTER_IMAGE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox + Me.TXT_FEED_CENTER_IMAGE.CaptionSizeType = System.Windows.Forms.SizeType.Percent + Me.TXT_FEED_CENTER_IMAGE.CaptionText = "Center images in grid (number of visible images)" + Me.TXT_FEED_CENTER_IMAGE.CaptionToolTipEnabled = True + Me.TXT_FEED_CENTER_IMAGE.CaptionToolTipText = "Don't fit images to the grid, but center them and set the number of visible image" & + "s." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Only works when the number of columns is 1." + Me.TXT_FEED_CENTER_IMAGE.CaptionWidth = 50.0R + Me.TXT_FEED_CENTER_IMAGE.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown + Me.TXT_FEED_CENTER_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill + Me.TXT_FEED_CENTER_IMAGE.Location = New System.Drawing.Point(4, 33) + Me.TXT_FEED_CENTER_IMAGE.Margin = New System.Windows.Forms.Padding(3, 3, 2, 3) + Me.TXT_FEED_CENTER_IMAGE.Name = "TXT_FEED_CENTER_IMAGE" + Me.TXT_FEED_CENTER_IMAGE.NumberMaximum = New Decimal(New Integer() {50, 0, 0, 0}) + Me.TXT_FEED_CENTER_IMAGE.NumberMinimum = New Decimal(New Integer() {1, 0, 0, 0}) + Me.TXT_FEED_CENTER_IMAGE.Size = New System.Drawing.Size(569, 22) + Me.TXT_FEED_CENTER_IMAGE.TabIndex = 1 + Me.TXT_FEED_CENTER_IMAGE.Text = "1" + Me.TXT_FEED_CENTER_IMAGE.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center + ' + 'COLORS_FEED + ' + Me.COLORS_FEED.ButtonsMargin = New System.Windows.Forms.Padding(1, 2, 1, 2) + Me.COLORS_FEED.CaptionText = "Feed colors" + Me.COLORS_FEED.Dock = System.Windows.Forms.DockStyle.Fill + Me.COLORS_FEED.Location = New System.Drawing.Point(1, 59) + Me.COLORS_FEED.Margin = New System.Windows.Forms.Padding(0) + Me.COLORS_FEED.Name = "COLORS_FEED" + Me.COLORS_FEED.Size = New System.Drawing.Size(574, 25) + Me.COLORS_FEED.TabIndex = 2 + ' 'TAB_NOTIFY ' TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN) TAB_NOTIFY.Location = New System.Drawing.Point(4, 22) TAB_NOTIFY.Name = "TAB_NOTIFY" - TAB_NOTIFY.Size = New System.Drawing.Size(576, 338) + TAB_NOTIFY.Size = New System.Drawing.Size(576, 486) TAB_NOTIFY.TabIndex = 8 TAB_NOTIFY.Text = "Notifications" ' @@ -1357,7 +1468,7 @@ Namespace Editors TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 338) + TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 486) TP_NOTIFY_MAIN.TabIndex = 0 ' 'TAB_MAIN @@ -1373,7 +1484,7 @@ Namespace Editors Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0) Me.TAB_MAIN.Name = "TAB_MAIN" Me.TAB_MAIN.SelectedIndex = 0 - Me.TAB_MAIN.Size = New System.Drawing.Size(584, 311) + Me.TAB_MAIN.Size = New System.Drawing.Size(584, 369) Me.TAB_MAIN.TabIndex = 1 ' 'CONTAINER_MAIN @@ -1382,13 +1493,13 @@ Namespace Editors 'CONTAINER_MAIN.ContentPanel ' Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN) - Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 311) + Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 369) Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN" Me.CONTAINER_MAIN.RightToolStripPanelVisible = False - Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 336) + Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 394) Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TopToolStripPanelVisible = False ' @@ -1396,15 +1507,15 @@ Namespace Editors ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(584, 336) + Me.ClientSize = New System.Drawing.Size(584, 394) Me.Controls.Add(Me.CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.Icon = Global.SCrawler.My.Resources.Resources.SettingsIcon_48 Me.KeyPreview = True Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(600, 375) + Me.MaximumSize = New System.Drawing.Size(600, 433) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(600, 375) + Me.MinimumSize = New System.Drawing.Size(600, 433) Me.Name = "GlobalSettingsForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -1420,6 +1531,7 @@ Namespace Editors CType(Me.TXT_MAX_JOBS_CHANNELS, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).EndInit() TP_FILE_NAME.ResumeLayout(False) TP_FILE_NAME.PerformLayout() TP_FILE_PATTERNS.ResumeLayout(False) @@ -1457,6 +1569,7 @@ Namespace Editors TP_FEED_IMG_COUNT.ResumeLayout(False) CType(Me.TXT_FEED_ROWS, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_FEED_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.TXT_FEED_CENTER_IMAGE, System.ComponentModel.ISupportInitialize).EndInit() TAB_NOTIFY.ResumeLayout(False) TP_NOTIFY_MAIN.ResumeLayout(False) TP_NOTIFY_MAIN.PerformLayout() @@ -1526,5 +1639,11 @@ Namespace Editors Private WithEvents CH_NOTIFY_CHANNELS As CheckBox Private WithEvents CH_DOWN_REPARSE_MISSING As CheckBox Private WithEvents TXT_USER_AGENT As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents TXT_USER_LIST_IMAGE As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents TXT_FEED_CENTER_IMAGE As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents CH_NAME_SITE_FRIENDLY As CheckBox + Private WithEvents CH_UNAME_UP As CheckBox + Private WithEvents COLORS_USERLIST As ColorPicker + Private WithEvents COLORS_FEED As ColorPicker End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/GlobalSettingsForm.resx b/SCrawler/Editors/GlobalSettingsForm.resx index 99f7914..2220944 100644 --- a/SCrawler/Editors/GlobalSettingsForm.resx +++ b/SCrawler/Editors/GlobalSettingsForm.resx @@ -121,7 +121,7 @@ False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -132,7 +132,7 @@ cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -143,7 +143,7 @@ False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -151,7 +151,7 @@ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -167,7 +167,7 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -183,7 +183,7 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -197,7 +197,7 @@ 17, 17 - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -213,7 +213,26 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go + tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX + AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP + WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP + aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+ + 5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8 + vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB + cMaRN0UdBBkAAAAASUVORK5CYII= + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -230,15 +249,6 @@ False - - False - - - False - - - 17, 17 - This is a global setting for newly added users only. This parameter specifies how the video will be stored in the users' download path. @@ -266,34 +276,19 @@ You can find more detailed information about the missing posts in the form that False - - False - False False - - False - False False - - False - - - False - - - False - - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -301,7 +296,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -321,13 +316,7 @@ You can find more detailed information about the missing posts in the form that False - - False - - - False - - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -338,7 +327,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -355,12 +344,6 @@ You can find more detailed information about the missing posts in the form that False - - False - - - False - False @@ -370,7 +353,4 @@ You can find more detailed information about the missing posts in the form that False - - False - \ No newline at end of file diff --git a/SCrawler/Editors/GlobalSettingsForm.vb b/SCrawler/Editors/GlobalSettingsForm.vb index 52edccf..861a762 100644 --- a/SCrawler/Editors/GlobalSettingsForm.vb +++ b/SCrawler/Editors/GlobalSettingsForm.vb @@ -33,6 +33,8 @@ Namespace Editors CH_CHECK_VER_START.Checked = .CheckUpdatesAtStart TXT_USER_AGENT.Text = .UserAgent TXT_IMGUR_CLIENT_ID.Text = .ImgurClientID + TXT_USER_LIST_IMAGE.Text = .UserListImage.Value + COLORS_USERLIST.ColorsSet(.UserListBackColor, .UserListForeColor, SystemColors.Window, SystemColors.WindowText) CH_SHOW_GROUPS.Checked = .ShowGroups CH_USERS_GROUPING.Checked = .UseGrouping 'Behavior @@ -61,8 +63,10 @@ Namespace Editors CH_DOWN_IMAGES.Checked = .DefaultDownloadImages CH_DOWN_VIDEOS.Checked = .DefaultDownloadVideos CH_DOWN_IMAGES_NATIVE.Checked = .DownloadNativeImageFormat + CH_NAME_SITE_FRIENDLY.Checked = .UserSiteNameAsFriendly 'Downloading CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime + CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime TXT_SCRIPT.Checked = .ScriptData.Attribute TXT_SCRIPT.Text = .ScriptData.Value TXT_DOWN_COMPLETE_SCRIPT.Text = .DownloadsCompleteCommand @@ -90,6 +94,10 @@ Namespace Editors 'Feed TXT_FEED_ROWS.Value = .FeedDataRows.Value TXT_FEED_COLUMNS.Value = .FeedDataColumns.Value + TXT_FEED_CENTER_IMAGE.Checked = .FeedCenterImage.Use + TXT_FEED_CENTER_IMAGE.Value = .FeedCenterImage.Value + TXT_FEED_CENTER_IMAGE.Enabled = .FeedDataColumns = 1 + COLORS_FEED.ColorsSet(.FeedBackColor, .FeedForeColor, SystemColors.Window, SystemColors.WindowText) CH_FEED_ENDLESS.Checked = .FeedEndless CH_FEED_ADD_SESSION.Checked = .FeedAddSessionToCaption CH_FEED_ADD_DATE.Checked = .FeedAddDateToCaption @@ -151,6 +159,8 @@ Namespace Editors .UserAgent.Value = TXT_USER_AGENT.Text DefaultUserAgent = TXT_USER_AGENT.Text .ImgurClientID.Value = TXT_IMGUR_CLIENT_ID.Text + .UserListImage.Value = TXT_USER_LIST_IMAGE.Text + COLORS_USERLIST.ColorsGet(.UserListBackColor, .UserListForeColor) .ShowGroups.Value = CH_SHOW_GROUPS.Checked .UseGrouping.Value = CH_USERS_GROUPING.Checked 'Behavior @@ -179,8 +189,10 @@ Namespace Editors .DefaultDownloadImages.Value = CH_DOWN_IMAGES.Checked .DefaultDownloadVideos.Value = CH_DOWN_VIDEOS.Checked .DownloadNativeImageFormat.Value = CH_DOWN_IMAGES_NATIVE.Checked + .UserSiteNameAsFriendly.Value = CH_NAME_SITE_FRIENDLY.Checked 'Downloading .UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked + .UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked .ScriptData.Value = TXT_SCRIPT.Text .ScriptData.Attribute.Value = TXT_SCRIPT.Checked .DownloadsCompleteCommand.Value = TXT_DOWN_COMPLETE_SCRIPT.Text @@ -202,6 +214,8 @@ Namespace Editors 'Channels .ChannelsImagesRows.Value = CInt(TXT_CHANNELS_ROWS.Value) .ChannelsImagesColumns.Value = CInt(TXT_CHANNELS_COLUMNS.Value) + .FeedCenterImage.Use = TXT_FEED_CENTER_IMAGE.Checked + .FeedCenterImage.Value = TXT_FEED_CENTER_IMAGE.Value .FromChannelDownloadTop.Value = CInt(TXT_CHANNEL_USER_POST_LIMIT.Value) .FromChannelDownloadTopUse.Value = TXT_CHANNEL_USER_POST_LIMIT.Checked .FromChannelCopyImageToUser.Value = CH_COPY_CHANNEL_USER_IMAGE.Checked @@ -210,12 +224,15 @@ Namespace Editors 'Feed .FeedDataRows.Value = CInt(TXT_FEED_ROWS.Value) .FeedDataColumns.Value = CInt(TXT_FEED_COLUMNS.Value) + COLORS_FEED.ColorsGet(.FeedBackColor, .FeedForeColor) .FeedEndless.Value = CH_FEED_ENDLESS.Checked .FeedAddSessionToCaption.Value = CH_FEED_ADD_SESSION.Checked .FeedAddDateToCaption.Value = CH_FEED_ADD_DATE.Checked .FeedStoreSessionsData.Value = CH_FEED_STORE_SESSION_DATA.Checked FeedParametersChanged = .FeedDataRows.ChangesDetected Or .FeedDataColumns.ChangesDetected Or - .FeedEndless.ChangesDetected Or .FeedStoreSessionsData.ChangesDetected + .FeedEndless.ChangesDetected Or .FeedStoreSessionsData.ChangesDetected Or + .FeedBackColor.ChangesDetected Or .FeedForeColor.ChangesDetected Or + .FeedCenterImage.ChangesDetected .EndUpdate() End With @@ -264,5 +281,14 @@ Namespace Editors CH_NOTIFY_CHANNELS.Enabled = b CH_NOTIFY_SAVED_POSTS.Enabled = b End Sub + Private Sub TXT_USER_LIST_IMAGE_ActionOnButtonClick(ByVal Sender As ActionButton, e As ActionButtonEventArgs) Handles TXT_USER_LIST_IMAGE.ActionOnButtonClick + If Sender.DefaultButton = ADB.Open Then + Dim f As SFile = SFile.SelectFiles(TXT_USER_LIST_IMAGE.Text, False, "Select a new image for the user list:", "Pictures|*.jpg;*.jpeg;*.png").FirstOrDefault + If Not f.IsEmptyString Then TXT_USER_LIST_IMAGE.Text = f + End If + End Sub + Private Sub TXT_FEED_COLUMNS_ActionOnValueChanged(sender As Object, e As EventArgs) Handles TXT_FEED_COLUMNS.ActionOnValueChanged + TXT_FEED_CENTER_IMAGE.Enabled = TXT_FEED_COLUMNS.Value = 1 + End Sub End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/UserCreatorForm.vb b/SCrawler/Editors/UserCreatorForm.vb index ae0d63a..e224e5d 100644 --- a/SCrawler/Editors/UserCreatorForm.vb +++ b/SCrawler/Editors/UserCreatorForm.vb @@ -80,6 +80,8 @@ Namespace Editors Return TXT_SCRIPT.Text End Get End Property + Private FriendlyNameIsSiteName As Boolean = False + Private FriendlyNameChanged As Boolean = False #End Region #Region "Exchange, Path, Labels" Friend Property MyExchangeOptions As Object = Nothing @@ -248,7 +250,18 @@ Namespace Editors TXT_SPEC_FOLDER.Buttons.Clear() TXT_SPEC_FOLDER.Buttons.UpdateButtonsPositions() With UserInstance + If .HOST.Key = PathPlugin.PluginKey Then TXT_SPEC_FOLDER.Enabled = False TXT_USER_FRIENDLY.Text = .FriendlyName + FriendlyNameIsSiteName = DirectCast(.Self, UserDataBase).FriendlyNameIsSiteName + If FriendlyNameIsSiteName Then + With TXT_USER_FRIENDLY + .ControlChangeColor(True, False) + .Buttons.AddRange({New ActionButton With {.Text = "F", .ToolTipText = "Name set by you"}, + New ActionButton With {.Text = "S", .ToolTipText = "Name from site"}, + New ActionButton(ADB.Clear)}) + .ClearTextByButtonClear = False + End With + End If CH_FAV.Checked = .Favorite CH_TEMP.Checked = .Temporary CH_PARSE_USER_MEDIA.Checked = .ParseUserMediaOnly @@ -275,6 +288,7 @@ Namespace Editors .MyFieldsChecker.EndLoaderOperations() .EndLoaderOperations() End With + FriendlyNameChanged = False Catch ex As Exception MyDef.InvokeLoaderError(ex) End Try @@ -336,7 +350,19 @@ Namespace Editors If Not UserInstance Is Nothing Then With DirectCast(UserInstance, UserDataBase) .User = User - .FriendlyName = TXT_USER_FRIENDLY.Text + Dim setFriendly As Boolean = True + If FriendlyNameIsSiteName Then + If Not FriendlyNameChanged Then + setFriendly = False + Else + setFriendly = MsgBoxE({"Are you sure you want to set the site name as the friendly name?" & vbCr & + $"Friendly name: { .FriendlyNameOrig}" & vbCr & + $"Site name: { .UserSiteName}" & vbCr & + $"Your choice: {TXT_USER_FRIENDLY.Text}", "Friendly name change"}, vbExclamation,,, + {"Confirm", New Messaging.MsgBoxButton("Decline", "Friendly name will not be changed")}) = 0 + End If + End If + If setFriendly Then .FriendlyName = TXT_USER_FRIENDLY.Text .Favorite = CH_FAV.Checked .Temporary = CH_TEMP.Checked .ReadyForDownload = CH_READY_FOR_DOWN.Checked @@ -346,7 +372,7 @@ Namespace Editors If Not MyExchangeOptions Is Nothing Then .ExchangeOptionsSet(MyExchangeOptions) Dim l As New ListAddParams(LAP.NotContainsOnly + LAP.ClearBeforeAdd) If .IsCollection Then - With DirectCast(UserInstance, API.UserDataBind) + With DirectCast(UserInstance, UserDataBind) If .Count > 0 Then .Collections.ForEach(Sub(c) c.Labels.ListAddList(UserLabels, l)) End With Else @@ -387,6 +413,10 @@ CloseForm: If Not s.UserName.IsEmptyString Then Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = s.HostKey) If i >= 0 Then + If s.HostKey = PathPlugin.PluginKey Then + TXT_SPEC_FOLDER.Text = s.UserName + s.UserName = s.UserName.CSFileP.Segments.LastOrDefault + End If CMB_SITE.SelectedIndex = i CH_IS_CHANNEL.Checked = s.IsChannel TXT_USER.Text = s.UserName @@ -408,6 +438,30 @@ CloseForm: Private Sub TXT_USER_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_USER.ActionOnButtonClick If UserIsCollection AndAlso Sender.DefaultButton = ADB.Refresh Then TXT_USER.Text = UserInstance.CollectionName End Sub + Private Sub TXT_USER_FRIENDLY_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_USER_FRIENDLY.ActionOnTextChanged + If Not MyDef.Initializing Then FriendlyNameChanged = True + End Sub + Private Sub TXT_USER_FRIENDLY_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_USER_FRIENDLY.ActionOnButtonClick + If Sender.DefaultButton = ADB.Clear Then + TXT_USER_FRIENDLY.Clear() + FriendlyNameIsSiteName = False + FriendlyNameChanged = False + TXT_USER_FRIENDLY.ControlChangeColor(SystemColors.Window, SystemColors.WindowText) + Else + Select Case Sender.Text + Case "F" + TXT_USER_FRIENDLY.Text = DirectCast(UserInstance, UserDataBase).FriendlyNameOrig + FriendlyNameIsSiteName = False + FriendlyNameChanged = False + TXT_USER_FRIENDLY.ControlChangeColor(SystemColors.Window, SystemColors.WindowText) + Case "S" + TXT_USER_FRIENDLY.Text = DirectCast(UserInstance, UserDataBase).UserSiteName + FriendlyNameIsSiteName = True + FriendlyNameChanged = False + TXT_USER_FRIENDLY.ControlChangeColor(True, False) + End Select + End If + End Sub Private Sub CMB_SITE_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_SITE.ActionSelectedItemChanged CH_IS_CHANNEL.Checked = False MyExchangeOptions = Nothing diff --git a/SCrawler/ListImagesLoader.vb b/SCrawler/ListImagesLoader.vb index 53a5cef..cef565a 100644 --- a/SCrawler/ListImagesLoader.vb +++ b/SCrawler/ListImagesLoader.vb @@ -139,6 +139,8 @@ Friend Class ListImagesLoader End If End With MyList.EndUpdate() + Else + UpdateInProgress = False End If Else MsgBoxE({"User list update aborted. Click the 'Refresh' button to refresh the user list.", "Update user list"}, vbExclamation) @@ -195,9 +197,9 @@ Friend Class ListImagesLoader ElseIf CheckUserCollection(User) Then .BackColor = Color.LightSkyBlue .ForeColor = Color.MidnightBlue - ElseIf Not IsInit Then - .BackColor = SystemColors.Window - .ForeColor = SystemColors.WindowText + Else 'If Not IsInit Then + .BackColor = Settings.UserListBackColorF + .ForeColor = Settings.UserListForeColorF End If End With Return LVI diff --git a/SCrawler/MainFrame.vb b/SCrawler/MainFrame.vb index bca82a2..3580c5e 100644 --- a/SCrawler/MainFrame.vb +++ b/SCrawler/MainFrame.vb @@ -10,6 +10,7 @@ Imports System.Threading Imports System.ComponentModel Imports PersonalUtilities.Forms Imports PersonalUtilities.Functions.Messaging +Imports PersonalUtilities.Tools Imports SCrawler.API Imports SCrawler.API.Base Imports SCrawler.Editors @@ -36,7 +37,8 @@ Public Class MainFrame With Settings.Plugins If .Count > 0 Then For i% = 0 To .Count - 1 - MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, .Item(i).Settings.GetSettingsButton) + If Not .Item(i).Key = PathPlugin.PluginKey Then _ + MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, .Item(i).Settings.GetSettingsButton) Next End If End With @@ -88,6 +90,7 @@ Public Class MainFrame LIST_PROFILES.ShowGroups = .UseGrouping ApplyViewPattern(.ViewMode.Value) AddHandler .Labels.NewLabelAdded, AddressOf UpdateLabelsGroups + UpdateImageColor() UserListLoader = New ListImagesLoader(LIST_PROFILES) RefillList() UpdateLabelsGroups() @@ -116,6 +119,7 @@ Public Class MainFrame Await .Automation.Start(True) End With UpdatePauseButtonsVisibility() + MainFrameObj.UpdateLogButton() GoTo EndFunction FormClosingInvoker: Close() @@ -190,6 +194,25 @@ CloseResume: If Not _DisableClosingScript And Not _VideoDownloadingMode Then ExecuteCommand(Settings.ClosingCommand) If Not MyMainLOG.IsEmptyString Then SaveLogToFile() End Sub + Private Sub MainFrame_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd + If Not _UFinit Then UpdateImageColor() + End Sub + Private Sub UpdateImageColor() + Try + If Settings.UserListImage.Value.Exists Then + Using ir As New ImageRenderer(Settings.UserListImage) : LIST_PROFILES.BackgroundImage = ir.FitToWidth(LIST_PROFILES.Width) : End Using + Else + LIST_PROFILES.BackgroundImage = Nothing + End If + With Settings + If Not .UserListBackColorF = LIST_PROFILES.BackColor Or Not .UserListForeColorF = LIST_PROFILES.ForeColor Then + LIST_PROFILES.BackColor = .UserListBackColorF + LIST_PROFILES.ForeColor = .UserListForeColorF + End If + End With + Catch ex As Exception + End Try + End Sub Private Sub MainFrame_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown Dim b As Boolean = True Select Case e.KeyCode @@ -272,6 +295,7 @@ CloseResume: LIST_PROFILES.ShowGroups = .UseGrouping If f.FeedParametersChanged And Not MyFeed Is Nothing Then MyFeed.UpdateSettings() UpdateSilentButtons() + UpdateImageColor() End If End Using End With @@ -339,8 +363,11 @@ CloseResume: .ScriptUse = f.ScriptUse .ScriptData = f.ScriptData If Not f.MyExchangeOptions Is Nothing Then DirectCast(.Self, UserDataBase).ExchangeOptionsSet(f.MyExchangeOptions) - Settings.Labels.Add(LabelsKeeper.NoParsedUser) - .Self.Labels.ListAddList(f.UserLabels.ListAddValue(LabelsKeeper.NoParsedUser), LAP.ClearBeforeAdd, LAP.NotContainsOnly) + If Not .HOST.Key = PathPlugin.PluginKey Then + Settings.Labels.Add(LabelsKeeper.NoParsedUser) + f.UserLabels.ListAddValue(LabelsKeeper.NoParsedUser) + End If + .Self.Labels.ListAddList(f.UserLabels, LAP.ClearBeforeAdd, LAP.NotContainsOnly) .UpdateUserInformation() End If End With @@ -882,6 +909,23 @@ CloseResume: Else __ModelAskForDecision = True End If + + If (users.Count = 1 AndAlso Not users(0).IsCollection AndAlso users(0).HOST.Key = PathPlugin.PluginKey) OrElse + (users.Count = 2 AndAlso users.All(Function(u) u.IsCollection OrElse u.HOST.Key = PathPlugin.PluginKey)) Then + __modelUser = UsageModel.Virtual + If Added Then + __modelCollection = UsageModel.Virtual + Else + i = users.FindIndex(_col_user) + If i >= 0 Then + __modelCollection = users(i).CollectionModel + Else + __modelCollection = UsageModel.Virtual + End If + End If + __ModelAskForDecision = False + End If + If __ModelAskForDecision Then Select Case MsgBoxE({"How do you want to add users to the collection?", MsgTitle}, vbQuestion,,, { @@ -909,7 +953,7 @@ CloseResume: For Each user As UserDataBase In users If Not user.IsCollection Then Try - user.User.UserModel = __modelUser + user.User.UserModel = IIf(user.HOST.Key = PathPlugin.PluginKey, UsageModel.Virtual, __modelUser) user.User.CollectionModel = __modelCollection userCollection.Add(user) RemoveUserFromList(user) @@ -1006,10 +1050,10 @@ CloseResume: Exit Sub End If CurrDir = CurrDir.CutPath(IIf(.DataMerging, 3, 2)) - colName = CurrDir.PathFolders.LastOrDefault - Dim vu As IEnumerable(Of IUserData) = .Where(Function(vuu) vuu.UserModel = UsageModel.Virtual) + colName = CurrDir.Segments.LastOrDefault + Dim vu As IEnumerable(Of IUserData) = .Where(Function(vuu) vuu.UserModel = UsageModel.Virtual Or vuu.HOST.Key = PathPlugin.PluginKey) If vu.ListExists Then - If MsgBoxE({"This collection contains virtual users." & vbCr & + If MsgBoxE({"This collection contains virtual users and/or paths." & vbCr & "If you continue, the virtual user paths will not be changed." & vbCr & "The following users have been added to the collection in virtual mode:" & vbCr & vu.ListToStringE(vbCr, GetUserListProvider(False)), MsgTitle}, @@ -1017,17 +1061,29 @@ CloseResume: End If End If End With + ElseIf .HOST.Key = PathPlugin.PluginKey Then + MsgBoxE({"This is the path (not user). The paths cannot be changed.", MsgTitle}, vbCritical) + Exit Sub Else CurrDir = .Self.File.CutPath(1) End If Dim NewDest As SFile = SFile.SelectPath(CurrDir, $"Select a new destination for {IIf(_IsCollection, "collection", "user")} [{ .Self}]") + Dim NewDest2 As SFile If Not NewDest.IsEmptyString Then NewDest = $"{NewDest.PathWithSeparator}{colName}\" - If MsgBoxE({$"You are changing the user's [{ .Self}] destination" & vbCr & - $"Current destination: {CurrDir.PathNoSeparator}" & vbCr & - $"New destination: {NewDest.PathNoSeparator}", - MsgTitle}, MsgBoxStyle.Exclamation,,, {"Confirm", "Cancel"}) = 0 Then + NewDest2 = $"{NewDest.PathWithSeparator}{CurrDir.Segments.LastOrDefault().StringAppend("\", String.Empty)}" + Dim choice% = MsgBoxE(New MMessage($"You are changing the user's [{ .Self}] destination" & vbCr & + $"Current destination: {CurrDir.PathNoSeparator}" & vbCr & + $"New destination [1]: {NewDest.PathNoSeparator}" & vbCr & + $"New destination [2]: {NewDest2.PathWithSeparator}", + MsgTitle, + {New MsgBoxButton("Confirm [1] (Enter)", "Move the data to the destination [1]."), + New MsgBoxButton("Confirm [2]", "Move the data to the destination [2].") With {.KeyCode = Keys.D2}, + "Cancel"}, + MsgBoxStyle.Exclamation) With {.AppendKeyCode = False}) + If choice < 2 Then + If choice = 1 Then NewDest = NewDest2 If Not NewDest.IsEmptyString AndAlso (Not NewDest.Exists(SFO.Path, False) OrElse ( diff --git a/SCrawler/MainMod.vb b/SCrawler/MainMod.vb index 40b2587..9502652 100644 --- a/SCrawler/MainMod.vb +++ b/SCrawler/MainMod.vb @@ -104,7 +104,7 @@ Friend Module MainMod Friend UserListLoader As ListImagesLoader Friend MyProgressForm As ActiveDownloadingProgress Friend MainFrameObj As MainFrameObjects - Friend ReadOnly ParsersDataDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime) + Friend ReadOnly DateTimeDefaultProvider As New ADateTime(ADateTime.Formats.BaseDateTime) Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan} Friend ReadOnly UserExistsPredicate As New FPredicate(Of IUserData)(Function(u) u.Exists) Friend ReadOnly LogConnector As New LogHost diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb index 4a27b16..9ecdba6 100644 --- a/SCrawler/My Project/AssemblyInfo.vb +++ b/SCrawler/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb b/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb index f6f08d5..ea05cb6 100644 --- a/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb @@ -83,7 +83,8 @@ Namespace Plugin.Hosts New PluginHost(New API.LPSG.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), New PluginHost(New API.PornHub.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), New PluginHost(New API.Xhamster.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.XVIDEOS.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids)} + New PluginHost(New API.XVIDEOS.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(New API.PathPlugin.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids)} End Function Friend Shared Function GetPluginsHosts(ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj index f0fe311..73a7be6 100644 --- a/SCrawler/SCrawler.vbproj +++ b/SCrawler/SCrawler.vbproj @@ -175,6 +175,9 @@ + + + @@ -270,6 +273,12 @@ Form + + ColorPicker.vb + + + UserControl + @@ -465,6 +474,9 @@ CollectionEditorForm.vb + + ColorPicker.vb + GlobalSettingsForm.vb diff --git a/SCrawler/SettingsCLS.vb b/SCrawler/SettingsCLS.vb index 3244e2c..cd3e7a9 100644 --- a/SCrawler/SettingsCLS.vb +++ b/SCrawler/SettingsCLS.vb @@ -116,6 +116,8 @@ Friend Class SettingsCLS : Implements IDisposable ChangeReadyForDownOnTempChange = New XMLValue(Of Boolean)("ChangeReadyForDownOnTempChange", True, MyXML, n) DownloadNativeImageFormat = New XMLValue(Of Boolean)("DownloadNativeImageFormat", True, MyXML, n) ReparseMissingInTheRoutine = New XMLValue(Of Boolean)("ReparseMissingInTheRoutine", False, MyXML, n) + UserSiteNameAsFriendly = New XMLValue(Of Boolean)("UserSiteNameAsFriendly", False, MyXML, n) + UserSiteNameUpdateEveryTime = New XMLValue(Of Boolean)("UserSiteNameUpdateEveryTime", False, MyXML, n) Plugins.AddRange(PluginHost.GetMyHosts(MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)) Dim tmpPluginList As IEnumerable(Of PluginHost) = PluginHost.GetPluginsHosts(MyXML, GlobalPath.Value, DefaultTemporary, @@ -126,6 +128,11 @@ Friend Class SettingsCLS : Implements IDisposable FastProfilesLoading = New XMLValue(Of Boolean)("FastProfilesLoading", True, MyXML) MaxLargeImageHeight = New XMLValue(Of Integer)("MaxLargeImageHeight", 150, MyXML) MaxSmallImageHeight = New XMLValue(Of Integer)("MaxSmallImageHeight", 15, MyXML) + UserListBackColor = New XMLValue(Of Color) + UserListBackColor.SetExtended("UserListBackColor",, MyXML) + UserListForeColor = New XMLValue(Of Color) + UserListForeColor.SetExtended("UserListForeColor",, MyXML) + UserListImage = New XMLValue(Of SFile)("UserListImage",, MyXML) DownloadOpenInfo = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenInfo", "OpenAgain", False, False, MyXML) DownloadOpenProgress = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenProgress", "OpenAgain", False, False, MyXML) DownloadsCompleteCommand = New XMLValueAttribute(Of String, Boolean)("DownloadsCompleteCommand", "Use",,, MyXML) @@ -169,10 +176,15 @@ Friend Class SettingsCLS : Implements IDisposable n = {"Feed"} FeedDataColumns = New XMLValue(Of Integer)("DataColumns", 1, MyXML, n) FeedDataRows = New XMLValue(Of Integer)("DataRows", 10, MyXML, n) + FeedCenterImage = New XMLValueUse(Of Integer)("FeedCenterImage", 1,, MyXML, n) FeedEndless = New XMLValue(Of Boolean)("Endless", True, MyXML, n) FeedAddDateToCaption = New XMLValue(Of Boolean)("AddDateToCaption", True, MyXML, n) FeedAddSessionToCaption = New XMLValue(Of Boolean)("AddSessionToCaption", False, MyXML, n) FeedStoreSessionsData = New XMLValue(Of Boolean)("StoreSessionsData", True, MyXML, n) + FeedBackColor = New XMLValue(Of Color) + FeedBackColor.SetExtended("FeedColorBack",, MyXML, n) + FeedForeColor = New XMLValue(Of Color) + FeedForeColor.SetExtended("FeedColorFore",, MyXML, n) n = {"Users"} FromChannelDownloadTop = New XMLValue(Of Integer)("FromChannelDownloadTop", 10, MyXML, n) @@ -197,7 +209,6 @@ Friend Class SettingsCLS : Implements IDisposable n = {"Notifications"} ShowNotifications = New XMLValue(Of Boolean)("ShowNotifications", True, MyXML, n) - ShowNotifications.ReplaceByValue("ShowNotifications") 'TODELETE: 2022.9.24.0 ShowNotificationsDownProfiles = New XMLValue(Of Boolean)("Profiles", True, MyXML, n) ShowNotificationsDownAutoDownloader = New XMLValue(Of Boolean)("AutoDownloader", True, MyXML, n) ShowNotificationsDownChannels = New XMLValue(Of Boolean)("Channels", True, MyXML, n) @@ -247,63 +258,148 @@ Friend Class SettingsCLS : Implements IDisposable #Region "USERS" Friend Sub LoadUsers() Try - Users.Clear() + Users.ListClearDispose + UsersList.Clear() If UsersSettingsFile.Exists Then Using x As New XmlFile(UsersSettingsFile, Protector.Modes.All, False) With {.AllowSameNames = True} x.LoadData() - If x.Count > 0 Then x.ForEach(Sub(xx) UsersList.Add(xx)) + UsersList.ListAddList(x, LAP.IgnoreICopier) End Using - UsersCompatibilityCheck() - Dim PNC As Func(Of UserInfo, Boolean) = Function(u) Not u.IncludedInCollection And Not u.Protected - Dim NeedUpdate As Boolean = False - If UsersList.Count > 0 Then - Dim cUsers As List(Of UserInfo) = UsersList.Where(Function(u) u.IncludedInCollection And Not u.Protected).ToList - If cUsers.ListExists Then - Dim d As New Dictionary(Of String, List(Of UserInfo)) - cUsers = cUsers.ListForEachCopy(Of List(Of UserInfo))(Function(ByVal f As UserInfo, ByVal f_indx As Integer) As UserInfo - Dim m% = IIf(f.Merged Or f.IsVirtual, 1, 2) - If Not f.Protected AndAlso SFile.GetPath(f.File.CutPath(m - 1).Path).Exists(SFO.Path, False) Then - If Not d.ContainsKey(f.CollectionName) Then - d.Add(f.CollectionName, New List(Of UserInfo) From {f}) - Else - d(f.CollectionName).Add(f) - End If - Return f - Else - If Not f.Protected Then NeedUpdate = True : UsersList.Remove(f) - Return Nothing - End If - End Function, True) - Dim v% - If d.Count > 0 Then - For Each kv As KeyValuePair(Of String, List(Of UserInfo)) In d - Users.Add(New UserDataBind(kv.Key)) - MainFrameObj.CollectionHandler(DirectCast(Users(Users.Count - 1), UserDataBind)) - For v = 0 To kv.Value.Count - 1 : DirectCast(Users(Users.Count - 1), UserDataBind).Add(kv.Value(v), False) : Next - Next - d.Clear() - End If - End If - If UsersList.LongCount(PNC) > 0 Then UsersList.Where(PNC).ToList.ForEach(Sub(u) Users.Add(UserDataBase.GetInstance(u, False))) + Dim NeedUpdate As Boolean = False + Dim i%, indx%, c% + Dim UsersListInitialCount% = UsersList.Count + Dim iUser As UserInfo + Dim userFileExists As Boolean + Dim __plugins As List(Of KeyValuePair(Of String, String)) + + If UsersList.Count > 0 Then + __plugins = Plugins.Select(Function(p) New KeyValuePair(Of String, String)(p.Key, p.Name)).ToList + For i% = UsersList.Count - 1 To 0 Step -1 + iUser = UsersList(i) + With iUser + 'Check plugins + If .Plugin.IsEmptyString Then + If .Site.IsEmptyString Then + MyMainLOG = $"The corresponding plugin was not found for the user [{ .Name}]. The user was removed from SCrawler." + Else + indx = __plugins.FindIndex(Function(p) p.Value.ToLower = .Site.ToLower) + If indx >= 0 Then + .Plugin = __plugins(indx).Key + .Site = __plugins(indx).Value + NeedUpdate = True + Else + .Protected = True + MyMainLOG = $"The corresponding plugin was not found for the user [{ .Name}]." + End If + End If + Else + If Not __plugins.Exists(Function(p) p.Key.ToLower = .Plugin.ToLower) Then + .Protected = True + MyMainLOG = $"The corresponding plugin was not found for the user [{ .Plugin}:{ .Site}: { .Name}]." + End If + End If + + 'Check paths + c = IIf((Not .IncludedInCollection Or (.Merged Or .IsVirtual)) And Not .Plugin = PathPlugin.PluginKey, 1, 2) + userFileExists = SFile.GetPath(.File.CutPath(c - 1).Path).Exists(SFO.Path, False) + If Not .IsProtected Then + If userFileExists Then + If .LastSeen.HasValue Then .LastSeen = Nothing : NeedUpdate = True + Else + .LastSeen = Now + MyMainLOG = $"The user [{ .Site}: { .Name}] was not found. " & + $"It will be removed from SCrawler on { .LastSeen.Value.ToStringDate(DateTimeDefaultProvider)}." + NeedUpdate = True + End If + ElseIf userFileExists Then + If .Protected Then + If Not .LastSeen.HasValue Then .LastSeen = Now : NeedUpdate = True + MyMainLOG = $"The corresponding plugin was not found for the user [{ .Site}: { .Name}]. " & + $"It will be removed from SCrawler on { .LastSeen.Value.ToStringDate(DateTimeDefaultProvider)}." + Else + If .LastSeen.HasValue Then .LastSeen = Nothing : NeedUpdate = True + End If + ElseIf If(.LastSeen, Now).AddDays(30) < Now Then + UsersList.RemoveAt(i) + MyMainLOG = $"The user [{ .Site}: { .Name}] was not found and was removed from SCrawler." + NeedUpdate = True + Continue For + End If + End With + UsersList(i) = iUser + Next + + If UsersList.Count > 0 Then + With UsersList + 'Create collections + Dim d As New Dictionary(Of String, List(Of UserInfo)) + .Where(Function(u) u.IncludedInCollection And Not u.IsProtected).ListIfNothing. + ListForEachCopy(Of List(Of UserInfo))(Function(ByVal u As UserInfo, ByVal ii As Integer) As UserInfo + If Not d.ContainsKey(u.CollectionName) Then + d.Add(u.CollectionName, New List(Of UserInfo) From {u}) + Else + d(u.CollectionName).Add(u) + End If + Return u + End Function, True, EDP.ThrowException) + If d.Count > 0 Then + For Each kv As KeyValuePair(Of String, List(Of UserInfo)) In d + Users.Add(New UserDataBind(kv.Key)) + With DirectCast(Users.Last, UserDataBind) + MainFrameObj.CollectionHandler(.Self) + For i = 0 To kv.Value.Count - 1 : .Self.Add(kv.Value(i), False) : Next + End With + Next + d.Clear() + End If + + 'Create users + .Where(Function(u) Not u.IncludedInCollection And Not u.IsProtected). + ListIfNothing.ListForEach(Sub(u, ii) Users.Add(UserDataBase.GetInstance(u, False))) + End With + End If End If + If Users.Count > 0 Then + 'Load user data Dim t As New List(Of Task) For Each user As IUserData In Users : t.Add(Task.Run(AddressOf user.LoadUserInformation)) : Next Task.WaitAll(t.ToArray) t.Clear() - Dim du As List(Of UserInfo) = (From u As IUserData In Users - Where Not u.IsCollection AndAlso Not u.FileExists AndAlso Not DirectCast(u, UserDataBase).User.Protected - Select DirectCast(u, UserDataBase).User).ToList - If du.ListExists Then du.ForEach(Sub(u) UsersList.Remove(u)) : du.Clear() - Users.ListDisposeRemoveAll(Function(ByVal u As IUserData) As Boolean - If Not DirectCast(u, UserDataBase).User.Protected Then + + 'Users final check + Dim findWrongUser As Func(Of UserInfo, Boolean) = Function(ByVal u As UserInfo) As Boolean + Dim uIndex% = UsersList.IndexOf(u) + If uIndex >= 0 Then + Dim uu As UserInfo = UsersList(indx) + If Not uu.LastSeen.HasValue Then + uu.LastSeen = Now + NeedUpdate = True + UsersList(indx) = uu + MyMainLOG = $"The user [{uu.Site}: {uu.Name}] was not found. " & + $"It will be removed from SCrawler on {uu.LastSeen.Value.ToStringDate(DateTimeDefaultProvider)}." + End If + End If + Return uIndex >= 0 + End Function + Users.ListDisposeRemoveAll(Function(ByVal u As UserDataBase) As Boolean + If Not u.User.IsProtected Then If u.IsCollection Then With DirectCast(u, UserDataBind) If .Count > 0 Then + Dim __del As Boolean For i% = .Count - 1 To 0 Step -1 + __del = False If Not .Item(i).FileExists Then - .Item(i).Delete() + With DirectCast(.Item(i), UserDataBase).User + If Not findWrongUser(.Self) Then + __del = True + MyMainLOG = $"The user [{ .Site}: { .Name}] was not found and was removed from SCrawler." + End If + End With + If __del Then .Item(i).Delete() + .Item(i).Dispose() .Collections.RemoveAt(i) End If Next @@ -311,14 +407,22 @@ Friend Class SettingsCLS : Implements IDisposable Return Not .FileExists End With Else - Return Not u.FileExists + If Not u.FileExists Then + If Not findWrongUser(u.User) Then MyMainLOG = $"The user [{u.User.Site}: {u.User.Name}] was not found." + Return True + Else + Return False + End If End If Else Return False End If End Function) End If - If NeedUpdate Then UpdateUsersList() + + If NeedUpdate Or Not UsersList.Count = UsersListInitialCount Then + If UsersList.Count = 0 Then UsersSettingsFile.Delete() Else UpdateUsersList() + End If End If If Users.Count > 0 Then Labels.AddRange(Users.SelectMany(Function(u) u.Labels), False) @@ -327,51 +431,6 @@ Friend Class SettingsCLS : Implements IDisposable Catch ex As Exception End Try End Sub - Private Sub UsersCompatibilityCheck() - With UsersList - Dim user As UserInfo - Dim uKeysList As List(Of String) = Nothing - If Plugins.Count > 0 Then uKeysList = Plugins.Select(Function(p) p.Key).ListIfNothing - If uKeysList Is Nothing Then uKeysList = New List(Of String) - Dim i% - If .Count > 0 AndAlso (uKeysList.Count = 0 OrElse - .Exists(Function(u) u.Site.Length = 1 Or u.Plugin.IsEmptyString Or Not uKeysList.Contains(u.Plugin))) Then - Dim indx% - Dim c As Boolean = False - For i = 0 To .Count - 1 - user = .Item(i) - With user - If .Site.Length = 1 Then - Select Case .Site - Case "1" : .Site = Reddit.RedditSite : c = True - Case "2" : .Site = Twitter.TwitterSite : c = True - Case "3" : .Site = Instagram.InstagramSite : c = True - Case "4" : .Site = RedGifs.RedGifsSite : c = True - End Select - End If - If Not .Site.IsEmptyString Then - If .Plugin.IsEmptyString Then - indx = Plugins.FindIndex(Function(p) p.Settings.Name.ToLower = .Site.ToLower) - If indx >= 0 Then .Plugin = Plugins(indx).Settings.Key : c = True Else .Protected = True - Else - indx = Plugins.FindIndex(Function(p) p.Key = .Plugin) - If indx < 0 Then .Protected = True - End If - End If - .UpdateUserFile() - End With - .Item(i) = user - Next - If c Then UpdateUsersList() - Else - For i = 0 To .Count - 1 - user = .Item(i) - user.UpdateUserFile() - .Item(i) = user - Next - End If - End With - End Sub Private _UserListUpdateRequired As Boolean = False Friend ReadOnly Property UserListUpdateRequired As Boolean Get @@ -546,6 +605,8 @@ Friend Class SettingsCLS : Implements IDisposable Friend ReadOnly Property ChangeReadyForDownOnTempChange As XMLValue(Of Boolean) Friend ReadOnly Property DownloadNativeImageFormat As XMLValue(Of Boolean) Friend ReadOnly Property ReparseMissingInTheRoutine As XMLValue(Of Boolean) + Friend ReadOnly Property UserSiteNameAsFriendly As XMLValue(Of Boolean) + Friend ReadOnly Property UserSiteNameUpdateEveryTime As XMLValue(Of Boolean) #End Region #Region "User data" Friend ReadOnly Property FromChannelDownloadTop As XMLValue(Of Integer) @@ -563,6 +624,19 @@ Friend Class SettingsCLS : Implements IDisposable Friend ReadOnly Property FastProfilesLoading As XMLValue(Of Boolean) Friend ReadOnly Property MaxLargeImageHeight As XMLValue(Of Integer) Friend ReadOnly Property MaxSmallImageHeight As XMLValue(Of Integer) + Friend ReadOnly Property UserListBackColor As XMLValue(Of Color) + Friend ReadOnly Property UserListBackColorF As Color + Get + Return If(UserListBackColor.Exists, UserListBackColor.Value, SystemColors.Window) + End Get + End Property + Friend ReadOnly Property UserListForeColor As XMLValue(Of Color) + Friend ReadOnly Property UserListForeColorF As Color + Get + Return If(UserListForeColor.Exists, UserListForeColor.Value, SystemColors.WindowText) + End Get + End Property + Friend ReadOnly Property UserListImage As XMLValue(Of SFile) Friend ReadOnly Property DownloadOpenInfo As XMLValueAttribute(Of Boolean, Boolean) Friend ReadOnly Property DownloadOpenProgress As XMLValueAttribute(Of Boolean, Boolean) Friend ReadOnly Property DownloadsCompleteCommand As XMLValueAttribute(Of String, Boolean) @@ -622,10 +696,13 @@ Friend Class SettingsCLS : Implements IDisposable #Region "Feed properties" Friend ReadOnly Property FeedDataColumns As XMLValue(Of Integer) Friend ReadOnly Property FeedDataRows As XMLValue(Of Integer) + Friend ReadOnly Property FeedCenterImage As XMLValueUse(Of Integer) Friend ReadOnly Property FeedEndless As XMLValue(Of Boolean) Friend ReadOnly Property FeedAddDateToCaption As XMLValue(Of Boolean) Friend ReadOnly Property FeedAddSessionToCaption As XMLValue(Of Boolean) Friend ReadOnly Property FeedStoreSessionsData As XMLValue(Of Boolean) + Friend ReadOnly Property FeedBackColor As XMLValue(Of Color) + Friend ReadOnly Property FeedForeColor As XMLValue(Of Color) #End Region #Region "New version properties" Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean) diff --git a/SCrawler/UserInfo.vb b/SCrawler/UserInfo.vb index ece6c05..392aa3f 100644 --- a/SCrawler/UserInfo.vb +++ b/SCrawler/UserInfo.vb @@ -25,6 +25,7 @@ Partial Friend Module MainMod Friend Const Name_IsChannel As String = "IsChannel" Friend Const Name_SpecialPath As String = "SpecialPath" Friend Const Name_SpecialCollectionPath As String = "SpecialCollectionPath" + Private Const Name_LastSeen As String = "LastSeen" #End Region #Region "Declarations" Friend Name As String @@ -49,6 +50,12 @@ Partial Friend Module MainMod Friend CollectionModel As UsageModel Friend IsChannel As Boolean Friend [Protected] As Boolean + Friend ReadOnly Property IsProtected As Boolean + Get + Return [Protected] Or (LastSeen.HasValue AndAlso LastSeen.Value.AddDays(30) < Now) + End Get + End Property + Friend LastSeen As Date? Friend ReadOnly Property DownloadOption As DownOptions Get If IsChannel Then @@ -77,6 +84,8 @@ Partial Friend Module MainMod SpecialPath = SFile.GetPath(x.Attribute(Name_SpecialPath).Value) SpecialCollectionPath = SFile.GetPath(x.Attribute(Name_SpecialCollectionPath).Value) IsChannel = x.Attribute(Name_IsChannel).Value.FromXML(Of Boolean)(False) + If Not x.Attribute(Name_LastSeen).Value.IsEmptyString Then LastSeen = AConvert(Of Date)(x.Attribute(Name_LastSeen).Value, DateTimeDefaultProvider, Nothing) + UpdateUserFile() End Sub Friend Sub New(ByVal c As Reddit.Channel) Name = c.Name @@ -145,7 +154,8 @@ Partial Friend Module MainMod New EAttribute(Name_Merged, Merged.BoolToInteger), New EAttribute(Name_IsChannel, IsChannel.BoolToInteger), New EAttribute(Name_SpecialPath, SpecialPath.PathWithSeparator), - New EAttribute(Name_SpecialCollectionPath, SpecialCollectionPath.PathWithSeparator)}) + New EAttribute(Name_SpecialCollectionPath, SpecialCollectionPath.PathWithSeparator), + New EAttribute(Name_LastSeen, AConvert(Of String)(LastSeen, DateTimeDefaultProvider, String.Empty))}) End Function #End Region #Region "IComparable Support" @@ -159,7 +169,8 @@ Partial Friend Module MainMod #End Region #Region "IEquatable Support" Friend Overloads Function Equals(ByVal Other As UserInfo) As Boolean Implements IEquatable(Of UserInfo).Equals - Return Site.StringToLower = Other.Site.StringToLower And Name.StringToLower = Other.Name.StringToLower + Return Site.StringToLower = Other.Site.StringToLower And Name.StringToLower = Other.Name.StringToLower And + (Not Plugin = PathPlugin.PluginKey Or SpecialPath = Other.SpecialPath) End Function Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean Return Equals(DirectCast(Obj, UserInfo))