From ac6a9e021cb3ac0c6d2bb20cbe078e5c34ac5cc3 Mon Sep 17 00:00:00 2001 From: Camille Appert Date: Fri, 13 Mar 2015 19:00:15 +0100 Subject: [PATCH] KeePass-2.20.1 --- Build/KeePassLibSD_Distrib/KeePassLibSD.dll | Bin 311296 -> 311808 bytes Build/KeePassLib_Distrib/KeePassLib.dll | Bin 216576 -> 217088 bytes Docs/Chm/help/base/cmdline.html | 4 +- Docs/History.txt | 22 + Ext/DeprecatedSources/AppConfigEx.cs | 632 ------- Ext/DeprecatedSources/AppPolicy.txt | 147 -- Ext/DeprecatedSources/EntryTemplates.cs | 226 --- .../EntryTemplates_DefaultText.xml | 1499 ----------------- .../ImportCsvForm_120218.Designer.cs | 262 --- Ext/DeprecatedSources/ImportCsvForm_120218.cs | 277 --- .../ImportCsvForm_120218.resx | 120 -- Ext/DeprecatedSources/Kdb4File.Read.Dom.cs | 680 -------- Ext/DeprecatedSources/KeePassCsv1x_120221.cs | 187 -- Ext/DeprecatedSources/MainForm_110830.txt | 66 - .../PasswordListPrintDocument_110101.cs | 165 -- .../PopularPasswords_100725.cs | 369 ---- .../ProtectedString_111029.cs | 436 ----- Ext/DeprecatedSources/ShInstUtil/Program.cs | 114 -- .../ShInstUtil/Properties/AssemblyInfo.cs | 42 - .../Properties/Resources.Designer.cs | 63 - .../ShInstUtil/Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 26 - .../ShInstUtil/Properties/Settings.settings | 7 - .../ShInstUtil/ShInstUtil.csproj | 75 - .../ShInstUtil/ShInstUtil.pfx | Bin 1756 -> 0 bytes Ext/DeprecatedSources/UpdateCheck_111216.cs | 205 --- Ext/DeprecatedSources/XorredBuffer_111029.cs | 196 --- Ext/KeePass.exe.config | 4 +- Ext/KeePass.iss | 8 +- Ext/KeePassMsi/KeePassMsi.vdproj | 12 +- KeePass/Native/NativeMethods.Unix.cs | 6 + KeePass/Plugins/PlgxCache.cs | 2 +- KeePass/Plugins/PlgxPlugin.cs | 2 +- KeePass/Program.cs | 2 +- KeePass/Properties/AssemblyInfo.cs | 4 +- .../Nuvola_Derived/B16x16_DeleteEntry.png | Bin 629 -> 641 bytes .../Nuvola_Derived/B16x16_EditCopyLink.png | Bin 658 -> 809 bytes .../B16x16_FileSave_Disabled.png | Bin 498 -> 669 bytes .../Nuvola_Derived/B16x16_File_Close.png | Bin 654 -> 731 bytes .../Nuvola_Derived/B16x16_File_SaveAll.png | Bin 440 -> 555 bytes .../B16x16_File_SaveAll_Disabled.png | Bin 440 -> 528 bytes .../Nuvola_Derived/B16x16_Key_New.png | Bin 670 -> 768 bytes .../B16x16_Window_2Horz1Vert.png | Bin 543 -> 837 bytes .../Nuvola_Derived/B16x16_Window_3Horz.png | Bin 511 -> 805 bytes KeePass/UI/OpenWithMenu.cs | 13 +- KeePass/Util/AppLocator.cs | 139 +- KeePass/Util/GlobalMutexPool.cs | 3 +- KeePass/Util/IpcBroadcast.Fsw.cs | 5 +- KeePass/Util/IpcUtilEx.cs | 2 +- KeePass/Util/SessionLockNotifier.cs | 4 +- KeePass/Util/ShellUtil.cs | 16 +- KeePass/Util/TempFilesPool.cs | 2 +- KeePass/Util/WinUtil.cs | 2 +- KeePassLib/Native/NativeMethods.cs | 25 + KeePassLib/Properties/AssemblyInfo.cs | 4 +- KeePassLib/PwDefs.cs | 6 +- KeePassLib/Utility/AppLogEx.cs | 2 +- KeePassLib/Utility/GfxUtil.cs | 16 +- KeePassLib/Utility/UrlUtil.cs | 19 +- KeePassLibSD/Properties/AssemblyInfo.cs | 2 +- ShInstUtil/ShInstUtil.rc | 8 +- .../TrlUtil/Properties/AssemblyInfo.cs | 4 +- 62 files changed, 218 insertions(+), 6031 deletions(-) delete mode 100644 Ext/DeprecatedSources/AppConfigEx.cs delete mode 100644 Ext/DeprecatedSources/AppPolicy.txt delete mode 100644 Ext/DeprecatedSources/EntryTemplates.cs delete mode 100644 Ext/DeprecatedSources/EntryTemplates_DefaultText.xml delete mode 100644 Ext/DeprecatedSources/ImportCsvForm_120218.Designer.cs delete mode 100644 Ext/DeprecatedSources/ImportCsvForm_120218.cs delete mode 100644 Ext/DeprecatedSources/ImportCsvForm_120218.resx delete mode 100644 Ext/DeprecatedSources/Kdb4File.Read.Dom.cs delete mode 100644 Ext/DeprecatedSources/KeePassCsv1x_120221.cs delete mode 100644 Ext/DeprecatedSources/MainForm_110830.txt delete mode 100644 Ext/DeprecatedSources/PasswordListPrintDocument_110101.cs delete mode 100644 Ext/DeprecatedSources/PopularPasswords_100725.cs delete mode 100644 Ext/DeprecatedSources/ProtectedString_111029.cs delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Program.cs delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Properties/AssemblyInfo.cs delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Properties/Resources.Designer.cs delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Properties/Resources.resx delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Properties/Settings.Designer.cs delete mode 100644 Ext/DeprecatedSources/ShInstUtil/Properties/Settings.settings delete mode 100644 Ext/DeprecatedSources/ShInstUtil/ShInstUtil.csproj delete mode 100644 Ext/DeprecatedSources/ShInstUtil/ShInstUtil.pfx delete mode 100644 Ext/DeprecatedSources/UpdateCheck_111216.cs delete mode 100644 Ext/DeprecatedSources/XorredBuffer_111029.cs diff --git a/Build/KeePassLibSD_Distrib/KeePassLibSD.dll b/Build/KeePassLibSD_Distrib/KeePassLibSD.dll index b4eb0bdad3e6501beaca985fd04ed7f74e82107d..b4a7e2734ad79a859be4da04cb24b67094428370 100644 GIT binary patch delta 59508 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 Av;Y7A delta 59179 zcmb4s2Y3`!7xvuQo!QN1Q#PCI5>hsVBrKav=)EIFiuB&Q6wSacJ%kM+NH4B%0YOC( zMMRMR0i}t+2Pz1P3W|sg^;3!kL`C@Db7!&%>i0kYpXcGsea|`f+;hv^K1=bV&f;R{ ziUpak#B}N=8Gn}~xk@y%O41&)B&j;{;>Rmr%9q>auKXk?cFD(PsVlKBnWgKdl~od> z70C{01wWOqeBJC1_h;2?UzZ|!2Kalzi&!puJ-nM$V+X<)S!U89Xwu*P_$Nz>WWHaP z%;6-tNvM%|$iTOEo;&$g-5KM)>n69zYcOnI(!{ivzIv&_%b)#H?QB)&$d`GffbcR8oFn?0DF2sTKW% zDybO~lO%0J$^DiAW_G^hx#-RekL&i`GK&ts5Z9jF3SW!c%{qrS$A9T~1(vn$h$R=! zmL#*bFud0BL(Bn1Qk_=WVRcxv{o$1fZ+9WXR&6b4!^KpT)}lwD?k#8MPSY(|yavdE)=627PC?*HH+jdP+4!WCnr3M|Z}?Q@YRn(LS^25B>S!0iSCA3A!+b~eg`Z35#d?HqrF3P1@cpUvSl#gKRM)`z z$cJ|hwB*2IlQhvN%7);&y)y;7q@3NjT>1NQZqo|NQRaw^=HY9pNuib$15{CAcbMG(bepSxxM%-zn8=jk%5E?+RP(-b+MEn~> z+*yL#zMMORxO#a^DCZ6<*A16*N0jTHDCdqMZjrG2z2K&bw`2^lb^k4D#ECxPn(0Yt z{UYYQkBNvq%QeP^N2I@BDIOYSMODipO*Cn*nP4wI+}ZPtd`Agi^`Jjc!fJ+>rIpmk z=*yZVqxy|ZkF!b>%~}dE$S<>&hM<;-=IyGLAP3e8G4b>&H*22oTUD|w4scY>S#q^X zKxVtc!?VV)p5fzJnV>&pJ4Pro@gq3HpRG{=G?R>hk0Ez zbpn6oo??NLcm45l+*-6-o9tbKhh6sak{|M?npnN?h}vG(AiNl~QFte4lkjJt&BAIO zFKZF5Q74bJ3J8+fOLjNh!dPs0SmQhvTe7UNOJ?aM&o@0Fv&!L7E%I4vINTzSrH9{a@dxWsvae-* zh6?|s)#8M)!qn5k)H9&k>m@5%$H-0>%FQMhhKaSxOl>ARyuHn{7&CgdMM~i+?VREG zcJWL`sA~9j+r)6ccJbj1{F~k`kzFfU+U_kGqfPe?Z$-;@l@eF)Pfe(wpZk3Zda8dR z3x_)n=+4%L*AK{MYfBCfcrt;8zM&82GHZD8!wcDglB9x;QBjkrR#dk(J3Mw;ddKrX zGi7&C4JMgYtq`bkjp)F~@zTVg5SjAeau$S11$FGQsx5>@5n&<7t{@1Xo>qx141YhZ zZb-ybJvMDNwEg3CyXmm|s-w)Vsx5*nC-**8TZ{mj4n6D^cO9SAQ>n!|3^{sYG5RCN zc*s%SU-4RaUtt)XFl;VGELAH4tz2WLPtEAvOOmqnbO-3^I+3p>kUJHJ;vVX6<1nYx zZh_=W-kg5G%)TrsF6zrr2j^zr2K_M91k_R7mfb4pTYTCQuMap5*w6>ck_HRbuqwn= zz579Zs>$q)#>d^`40ICXP-%R4Y-(%uP=-`s`06W+Ud5UA^g7VO=UJ}C|0DWV7Q_x%6Go7M}gJVz&aQ6V*^&Si7 zz19iR8LzcN<29=nGITd=M46B_~o7b*jFXWu5`vOg|l`yV4sEu?M`Rk zg$s8d25nxtlzmq6Zt1%+yI8XJ^$f;755NA#8TMs($-egNi||>ZC8_&Y#Ia-HZSS_N z@per#DJPo5OxdJa@ro7wE((umwwT=ozJ!VwQ!ATx*AlLBvNGP6rYCQ)YvFpQHo(dU zr~06G_Py5`#W(G}D$EgH`(7Tq8UD|E)15R4GiEAwZyjoQSHnF{`yeek{g{U)I}WpU zADOl@$>vmKZ!8*av?UJ{&8U*9XZow?Es8$=HazR&nDC@?otXEz{pVztzZRT6Dx5B~ zV%D5C)E^yaT=KyuT^O4gzW!xqNt+A17`q()QfgN4V$b4cXW4Y( zgK)PWcS5XOsm9KP^RCnff7F#(;Cyk#k8teO1JF5nbqP2FuH{2#;k7Q{pSw1cNhJ-h z?_=nrZv2$bGE1_4Zq8Wi@W@}@kLyyqtRl>L(Sd@JHoqQGS#e3!pB|R7gQmg@Q9`q4 zBDa30c*wHJ9NbZI-|aglcP=U}+F~k-!7{>PE{dhc9o4_8A8YDbNHg@Rs0h1N3&V!H zmer&!UiA{I>c|2&_yl;`DiD*laMeZDJbw`)xSUX;n1MO5(nPHgVt=MdXSua)RAZzD z2Jgt&Yiv>JZA>`LERWw&m@l*yvZ6S6;V>7{Lzv2w-97_XWNTB%0kYT+T^?qRJYR>D23FtMDWdw8pemv|406D#Q+)>>k@?qNMiEcZRE4aBN+4{IZ_lJ8-$ z=Xf;>%WAV2B7f&}TUj2S26pGCSA@y=aTQ@o9kc2lh6rWMg?zb%Wmc!E(5F&0ldO5M zG}X?hdBhI9E_Q2lt}{w!*5IF5SYr#R%i7aC#mdrs&yyF;WR0FCMSDZMVJ7be6nkEd zIWNT`i|Qf$kyiFmVolMQf=@$Ul!<(yCDq~&M6on>gHMQJRoLp%rBSSfiES!9X=fu8 zcA&Io0<$vKgEw-r{&<9)Y$&twU!1Ino#vAgnZ_>iFA`ZYyT$)ZWNq2crLB_K6^t9D zHQelFIrJa678A8>T*lqIl2j`?5MQTkpfhQE&`Abq)ODIo+7lUS;+(b3B3w>XIpv#JmGhP{H%13sTu<=(G8lboP zvvve&`U*@C#`C8$*$~#S^iC#w+svAmo~Xv|Q<7$t$1xY}LL}qzM+aa^Y^+(6<5B^Qe5* zAikn*x?JetEAyGFbWA=w%UBiOq$az@s+8u|Vjjk-mUgPmutktn+M+IV$n2@o?)6#U ziXC2Ulj!j1p?7%vtp;oX+sQjOWP8~tt~O$sYz(j7h@E1|{8l4Yhoy0UV^%x%F>3Z| z;1u%Z3w+HVYRo=p5?PUq??>}87}Y#z?b?H=2B$SQ$6?jRA{e7aX|ya6l>${jXX(r) zY_!aB_@!oSAR2em=BzQA^R(uyN@B};Wz{97FgEmy`%7PL&U!F5kKb* zSk4e=`c&;Jv`^pc4M@uOlBmQ;ZBgexk#}g#QdxZInAU6^WAiy{gDm^`qBbmqhpjCO ztD7jv^QF(VWg}R%Ly`1Nno6&AeBev40)k%;smvs^cJ6P_wzG8pS$p;*JH}_+&z7)m zT6=|`GFrRgqt=f=dZ31zFHyNykWV{%cToCu!qg;Ykuc>)O$agkgu`qO+Z?*Nr${&H+E1Z0<|rS=@6W2)}8^LpLc{SGl1(YI7= zYMvVWkuU4c{HZh(jES-u6I8Nk)so3Oi?<8^s5{FHU4cQ`>$!@jRl5cn6Xj2c(yk*E zFgL<${1ZZX)Fg)ezhZ<=kJvby^y(0tZ`I*buW#egVCRlR6z? zFbP{8y1~gh%Vi4`Mb@js!4uYh0IHL&h?jb>r+tYwxi%Ailz+_ zk@L!98=P{6$dVCJH^*D{Vwv7@4I@gqU-vNhqF$^XTJND=7;%0tt=yYo4fqE?(g*L# zA3UlrYlla-zHBoa%m?>lZXVl@rIdwRMZ!zi@BF|0*sZF6BIjBPmX#KH);RPF-inL~ zg29ymtQWh@2Ml1<*?9iw09F-`7xl-x16VgUm8T74ISJEHxMd^R02E5_Jnub_bxWba z2AzH3MC!~69}=_x)D`@l9~y|!aW?;CAgjz~@*4wLwS-Afx8=qK$B3uJ6zs|K2eC@5 zJ8wUT)l?tXEf)=9J*>;25-od|^N$CyG0DG@q-;*#4I-1)1Jqm0`wV8DkgYMqV)ktI zE9Pb6a+%9!_!}Qcg)mT)G!jvVGj(T|jZ^zo?iY>sRb&C1mtL{d?bkora&JbF3|?5T z7%eSJhofQJbrV*X_7{p6fd4v}B_yqYrkr3>y%aF}t!8VK_7_hX!s@bO-fakTqi)9z zVa@u@BSn)Ze&kp$1${$gQ&Pduao+hlKVzgG^x=JS)>I{Q-_jMlS}y8cgtr6TNcCY9 zbLIZgW!ZuM{I4M_ofY!bq0H}JM#j9fq#h6BM#z&fVi?Riv4x9`S_$RhkSlwa@k>Kl zCSN_2bzmaA5RdW0Si`akd2tv^RfkXsp6725W7%cl8^hR(EXGfHroj-!rPyHt!C2W&D`PyB^i$}1m|GUPa5v(D5 zg#SK*^=1<9I+Eov#*0R>8cC0rCx|}a8K4wR=5LN<$tsR2Y?_H*8p%@Qc0|;udwH8b zJsRV?e-s;J-Hd$LOy13W#VD3&-3Vkic{lQxN3pT7!UDFmZ8;80;4;q~&HR-7Xx8fA z3|6i23}X9blTUWLysOBrY7+AlFPZhFU@lS{WhLe!R95__(JYB==9V$65pvgR4Bo5F zeBc&`6du82W;Fu zmQ57d_dd^;j%AfVzlMD;ZHR4)t8B7=PHIJQPc{ils* zO+z`bBMJ-khgAJoftdn6FjF)IIL{~R(9oHNyyhi>SNGrIwY)bT!N14rSk9yLtdyV& z?-2J+U>T_84infy$1zOIY-;&rzYqUv0t;m9M0JW6-Af@~57{)%yG!TMOTLRwd5HOH zjX?^*_w}x67Tz2`-rGH-RX9_;N06XLx*Mt!9e9RR&-2p{v7mZEgiAX-jQ+EiZdH38 zlQ5AMW*BQCVfFno-d6B*7p(q%(AgQm#yZ3)C+QyI!FLs~>{!DxtwqS=?+UP5+Qn@e zs}T|+T|YNgcIgrIhn~DidzGB{|62-8x8_;p!bhke9>&ao)ETaup@P{gPTafvjqDBpY(Kh&hgDfqfqFHJR-rYQTGOKz|gt8{mbu!y* z%V}2DsKXgMI`NKESZnqMUpj>?V|#e&RMzNzk(MVlWW47ikO%1_N{EU|Bt(VT_E@DGZ53f6yboo&c-v6*SDxKOuhFTt{Z z3^hqIp3WZQUG+!7H0Dat*XjB){BKQ(KRpdoZh8xx*!nH+B}PP2`j>Vllct_;SH*`_ zdkTIe<;Nng6cTS;Zn9O|Pwru;jMq69jRU8effOxD;_o{Zw|Q6WS2++0eD|2C8PSTxTp z#MHpfyA`r57Q?3$vWyNmh!iIRVuhS1yL=8Mh+{}mXW9=Gur$1dVcDW(!cpudIxL<+ zb(%UABEU5isb`lv9?`fk%OElN0f&15ww9wl*SA_yQ;-O zOiAjYr8qujPMhkmxwLplOxi3QC-|)no7r0xTV38;{OT-Ry>Rf#MXZYLZTJ?gdWyVn z^R`8pdB{9a#C)n5F|`E#Y!Q2ey~nd>vnExxQyo;Hkw(Fwo=#iNq8ib+dE)b%-2L-hGrcm#tJyKH2*NZ~GV< z#;)+qkFnK`6)np08Ebaciw>;e4=iA{n2U!N;4OCZrxvihP$f87`~uRLO~ma@2G%Nr zh>#$G?Jy*E^_PuH4E~Cwv=k_a2$cdmA@tHZ-Til2a^MijQla|~S>?bblHJOOHFvUD zU1Xm&V~5g<-6-4N5=jY2Ev1PrS1^rFU&zub-RnYXzzeCHq}w1>btyl+ka@>-gCx)k zM9ju8!wU=}&Zvr<0^$TJa?&xw2+XR;$t2FA3LKZ$fem*uxSFD`?Q04US%n(7pjW7@h4z^ znF8KF=pAc~^0&!a7D-;Shm4CRDC9rJ% z-BRrJkRuUwym9JRN5<8Vgr46<3BIQaw#2*n9YfkDVV@o<0 zS+uFH8mhk2httMP*vHPJqH4MP8d7!oNk!lM)oCz~H(0@j$5~sI)fug=68H-%Sk0=b zV5SHEgpuMG>FpyTYx!hDgiTsL|6>J9NvaMOhEKCs1S|=v!{V*MeJk0R%J~t)vdz;f zI=5q>9XJWhTa&-ElHHGG_b)5iE>CAL_2C6mcs0=HUO0sBc^u~f0shV7tO@JPtAv>o zi>-QLmXY-cRDA)8?+e69-gvy_{ul%t2zcZ00{8;U_>3^is!DG`r1`Ev1o2)N9Fre+ zMppAfVQeEhc&8`WtMTi}rko*}C24#;HL#i6R-tp-&TFhfGu^}cuR?!*h|gbzeVOC@ zrBy7||MwWefO~v@-Nqm{_I6RZ*u}R6w)3A?vF2E#)LMLM6U-HKv)h`1h-k@@ekm%$rDCYO?6@Z0hW-s2P_x%)4^d#qtCs(HMs| zaV)q$;-7Jrjajd04Iba|>T59BWBj2t$cmY-T*GR!hWyAH^vLl%do2saSG4P`BTM|R zwJe3dx0ZEKfo!mwzK(UqYdT>aJCh)aaUq@A8B594yvvhp8mr5XJ;^5c{jJ4X9`Sq! zXstRjp}d({0u3RJX8}?&1;+Ei>zT(n3&7|+gn)Jemak`3EsqOR3g5dPx%z?syq?vL zt_Qyck2J^Luk)Uv}z3yz!c^h|7rtkT~UUKnIXGg+TEZQX`_arvsIW`lC{rVhx80QZoHnI9C z&qfM|`h$HDBztG_l1(ftTAZP*M((|wH-8@W_SYun%s(Dc{6{pnDZAaY<&8My5sTOq zzVCUqhds-uY{sH;I_H~N8@tFA7F6a$@2t{qH?snnE#Q5&;Eri+K6?u$tDo>!wy;LE z{4ncwyS4Xmp5=(Tqt?Mzym4s{s4k%$=*MFmQH5C;Pc=WU^b%_onoZuwg;f47F9BQ* z+eb5V#bN|hY_AKB#bN|-H&b!o3K~Tfp*bRiYhK>sNazs}(i20P*))bfR)Oa&A|QJg z@=so3scE>UrfLPK)aYCvdMXVe8!pqN(9pA})VY;TN$T-eUdEBqkNnijEIY1#Sq5zm z9A7rz@;26tHRdh1vFw~CXj9H8Os1o}O%aTV(w1W1S9=L%6Qwl+CkK+|rHi-WBr0(~ zvTL_CI)JgoY|)lN2geLIU%>%NWB&N7?3pr!ow~wevb3MK+s;<9X8hcCR+QcluF%=M zpN>+^MS1j)i*o64M{UG|udxDmV?(Egu7mN1bn^K_udzxzeh0hH)dGHDEHP;<5peep zw!%Ye&ByIv8KL_Sjz+n(!4r?Rc-&V>mZV@igzSRGm@H<+8Wn5yqVvqfNh(%m?ICq4 zCL@LsU&AeA3?0D^^swj;tJ@icX?RCs#W(yKIZcT7b|PeR*p{^B))JO%?@ZW{o0s75 zKEU%zSVl}2aNN%5+$gZR@&P3*MOR9IQUa9b+^duTrB_O@_M>=M6k-OiQ4nc$!=rIL zCjS>>6XNfJH0ZCZSpM zK}=<+j}{HLo9}xfaE$QNZHvhqC~!KZ3Q7Ap_`M&C+Icuhn4* zO_lfD%`)>Tb(=Xss*t)yuN4maFt@<$>K*}qZZ}(&Ppus1SY$aLN=6Wku#Drv0&^)+ zG@*{$^P#28HLx#~^`gM5h6`ngW);|h>5ulW(#NPjRLZ1;yr*csqQ@0d5tpAX#iXER z>5rvskjw_~4zFXh9>@z`XDzA?LbCoO#a$=E3R7mSgt~x%VCKeEWbm`EvuY`W!AIYd zg2n9+3gT#nLq9?F4&|;lFitn+%icgY){MXM23wo32o;34zIFnR>d^_S+A!XKA8Q&t z9C7Wr=~$$X;Lq&CL}esDu#eSAS_*x)e(U@&3J13m9l_>Y-OoJvw)@J)aa=8_iw;H` z1tYGSlvUg&X;I!`0-@&ivzmTN#;N3HBq-hyl%j0)l1DL7uG%=(A&;W8(GWmBlE1p2 zb*@e^V&IrbM2J=`8r6kAMxNar+S+>L75#w;>RAUcJS{Elb%5CzTfv7O#QMJ(KX?%H z$!7e|gKRj?y$2rx`iZYSgexQS_~(bPqyH06eiKK0^Gb)j$yza-{6BLTGp5G;gTrim zwFi+pF40nov2tNO>P5A&;N>RhEmg3zQGC=}tWmrFM`c8>{jO1_S5c;QsZ3j;v}k)O zIF5hy7B)x5bH@>u5!bq`5ThOH9rZrm@(8O@PZXjxw|atAl!=qB--}|T8SW;H7UKFi1Wr!u-3V zEK6K##9)IVDCrn$dCz@+KKvNww-57YjZLB&?M3ffcQGf!65lb z9Q~A^HpYZ}GFVF^18XxtAe+g5JI?Co{xf1+B%&pvizs>D@!Q8)DxZ9UxrP^lVN*qNzDG<;$U0_r z-pI?Ndm=WOuu>#Xv4JBsrTz|jjU##{tq7KIG0UROCX;$R?A!4lPOwI~6&0ymqH_~5 zR#2|WH37hz$-BPI^2>jg{&lH*V@-$5rtr!BnXU6x`c zACY`X-d&Z=%=I{OENs9ofTo zoI;m!jDLNK4NF^q7)7{fXT~-9+w|~eL+zq1M|OKXeE55;cZW$4`zB4n_>B8ag|1WcQ-(%x(=s*56%ZnDtr0K~#dzvl8654+T=Wh=;0U2nKBlCKKTfUmuV%ep^41@+Mm>*^Me+tuniRSm zG&AM079*?O*;yL??3)-KZdEYjs(q6GB5%(g>&ZVY^h$tSapt538wFCUUkJw|OOf-p%Zk=sN%*apG{FEIV=G zh@J)b^3w=J=_*c4GN8&o{Fv2tPlj>D` zC*?aFR?z6cnD%9_g(Fscor9&W5wPZ_!a{Ag&{s(xmkM4I`h3ngmeyE5_w?k|v{^lg zwNfZKS3tgBnrK~utDR*RgDJ;R8N+Hy5`CpG9bz0mpF79;gd83IRW<&Qt~v)|-Qy^H zcmwl^Fn{!4<9J#Q_2)th?_{rzWwETD+W$L3#!!CXGfS(ly;q*{^t%ySCSGxe4fn&_MI=!UyZ0zH5iHb=8x&_~1s5Hd8PUOX z81IbVElgwo%QYT3xTK2{Q9D?hdrx6638m-iLP_%DpWuwMKEnFFa?yYtQF=SB(2($r z1ih$e^SgyE0bSQxQJ2^Hlx<)S@b^AtU7Mf7>jUqmb&cc=$sQymP8VrI@UsZQu%_Uf zL)l!U(j&N(54wPJon?I51?EX_h~Pe_NGCor=YFCTZDa6N=+`bfco)9rb3=O zRxXS-a0+3}gfNux8K1G#Si13(3ny(*(Ax3mKEskJil6z6zvDBZ&2j2~LD)rJO4l%Ft4^mAv307RHbBB^Q~udPGsb zv#%{jKFS7I+%l#MeqsW@g}3^gxs&v9QqQ=%i1I0Wzvoe(v(!|47OQ%1Qh|yoXt#ev z)<54faukV-2qvvI8kr5pK&5CWvPlh=+uBX5hl(=}QRX>L%EV_C>zyalKQ~4>9nUW zib7oeq!tlvan-J;w+IVbMBW$7o%%R6;p{>aDitR|MfA*#4upj(eApMvW!1~xo4{v( z!78Qvi@vW+{k1RHpb$es`o%R0;dc;BqQwq9X+Pf zYvRKmT&Mb)iV1FzGg!m~<;W$~0xnj+m^M74C6~;x|>OBjXC9 z!LLw9Cat`V^qX^L+(k0+r@mp8L{;a;gG~h>u0>PnnzR=I^YEroi6<3^%S~j__8OnX_4>Li8yhe6V9z zitbT~YO)yBWJN%~D=sPt8;qh#wqIr`Lq$=z^pesarpRqBJ*2nGWMg<2x4GyI%B9;} z6o{lvm$`(5@~>a!GIQUztR>DZCwzXWszGL}ywnU0cb=7k%p1>>TrBZ|v#|ug zwAId^`HqdqtkRQaU(+yO{KxzvR`JtY&$GT~8BQ^R(OZ*_S(V3*%5B8^LZJJS+m-JB z+xgt@SpB-gFV&h_FNzWD~B4csIUhbA>Cq6Ap95`3ucp4OiCvmw8id z$h|S;uxMd)r+(~D)0DuXJ;5*jmwEp08p%H}U$U1TU8Bq<%51; zRYKEHD!TOVOG>dWPQgw8N?6o&M}`t@W=&*?mU{k7v(`#fPF^LskS0yK(5y8DR~sor zjow9BVE?C|v8lZVd%4LKq!vsYUxj1(q#R%2Szyjo-d)~CGst7us-5AT;~;C9(;v06nTke>~%V2R&| z55Iy<_eOlf6&y2L_`xeIDMu79y*Hl9}{j#{@p(8q0H$ z#9b#FN9q-15Al81aLw{l{_QoElR1M-i|MB&Ta59Z`0@QT3radNeXenxHA@kRBp8;o z@i6R7ri@_sj6Zgr)l$#HEq@aK;yNxz=1$U6)W-5pud|G5HKD1kg3Gzh4Z%1v@FAkm zp@i(ciV*H+Wd6iDuqOPWpICNtH#BlP>qq*PDBMyHyC_^&_ELIzjwpYuLlJq#j*Re{ zHZQ$N{Jo!WT5z66{meS4;vKQ_0Y9^Pe_tAG_?eBb)B+~aN*Z97L#P_9rW)`53rh?s zWo#N{$7wXKfzwQnGpQ_fog-W*(--pxFZ?mg(%`5m6g|Qc!xph}E9eo^NC%2B<-G-% z{NOLFXa5h7_X}2k<0yY+qvaTGXgF3ySDy`w*x42HD)DKdQR?N@hT|VH5|x*P5Va`3 zodSHquk3}mU6D57OP6sMw8{iVH`#c#7TG(`C*EXf9kSqk*(PGd6Fn}y zV~`pkB8Yh$27dyjaVp$-`&~zD3xACl`KO>IYbOXtV$G^LUHS`hg`kkG_nk;hRU38F%+8}f$E^*NqYf*1?_=fe*=Xy4m!b0BvvJmVF-H4e>FoXNb z{O3Pd)i@tnv14GPm(uIwS%2c|%=3J}pG<4j1TsJ7@AP!%yFmuG5T9 z?fYYAxrVBb=+w7cFwe2wX6wzh5uFdejkDgbZ?lf7r?04&x__ZxX}}BqVsr7m$IpMU z`i>4zlnXI>;@d`=y>;M??y%<7-vYZR6WVt%H zNQxd_j(4=E8bZ0L_-Q8s_el9COs?kIA2FP0LqxLb^3LLJS#AbLddqUpO67)yShw!> zuH}bhc{UD?TbShZY)e1PqO4*+NZ%Fmu0x73QC=5%hrC*5zdy>mh(BVId)O#rzD#^G zS->xv){!l9^(fNY(+znpmBPPlVL*IQzX9!q~Iux4o8M# ziV&pRe;6VosyHULY7bE-NVjvQB7g^G*|>9T;lo?7Tz=XrXR)XG4Xd1S|1)I#U%tez zg#t9TA%tnnL^hJD{>uw>|0dL)<%6T-><-UC#qC2+Tpu?O3WvdalSUWAg0;|AOqwpn z3`dc0^Hdr^?zh3s0XtpD><~%O8a&9~iIS@(k-qhg+P3U+0fBbhWRu&}*#uDz&4}qB zx+RQ_f-zYnsXY%Fz5}spn-QREt}o!Jy~t96@vC0O3#O%YZ8h({-GFeD4K9+qN^gLD;LOl7T40@=$w6C zJxQ3<@5=htnRFSS5iQ456KRP{v_6w~EosC{poIH)Unc*z5qX7giM6pZ~k!&x~k_%VML>TSLjU!HqL2l95IlRui~Y`@hqdCDU~Kr7lI*N%amIskp$l(-v=%6TQzxh0Dd$RFWP~8#{NUcv{7eRA_rB=+^eqBk%zE@j8MQtM?5&V$4ypwv`uT$vK|(kQse- zvKtc3L~{Spl_+GNpQ<|SFOKYAY`*>gRZi|yzC&4T*}cvQCB%zhC3qW9sM96ZE( zWXpGx>1P`0BEwx6P+gh@Q1uOvy)k@zj+`RjZpmnM zks4h>jzX_2^H}xjpSY38D{7;0VY82Moh#oQBEJdq*(yb3= z^s!dZ$uXd(w-tiuK#;Ox+%cjECSeMLq^ou;Hb={C{F~|t-qj~pZ}v4lq^LSulDefb zX#qA}s`i{57+3IM5ZRQ@eaECn2ZGnTr!=UIEX9LYwSDgnZSZ^ucn#m>lk3E^!yxoF z8Wj!nCrWSlr^yq@c_!R5S#l&y3L_#>QvFAorTDFO#XJ4i8w}M{XeF1k^lv1LZg0>2Y z#{fZtf-Vzui=c-~De^~xel0lhd;TgN$g=ie&q=DYhZ5)@=;%G7fbIFZ;esPmq%KQ>EnZCs#V|C+QOf6lMn~+ziwubvf`|j!PN>s!CJAam$b3 zdc7(=b%3h1V(z!#A3{<6Squ86O zDEB*dvU1zK$9j@zCrPhZj*7U<8aK)tdTNJD7Tjb&(LB}5< zY3Y&U@$VUBpd2Ne+A-4k`WV84q@Rva0^a{naSi?t<$Ii<3j|#Os!BbNlfUmAr*cX< zu_fNbs7P(nu(zp6_Iih;hu?X6s46+$B|FvMrF=Io4b_l`T0?D=jcD-SMK@P5z?ixU zbTc{$qyJD-H(Y_jM}+nyrU3O6C|;o9rU44hgQY5V{0NaW+Vr51RTHvtK+nKtT_C(+ zrhvj&ywqOE9x?@mW-oiP=}~Et>G2SRm`vI?z|165SeXOW=|GAUG|+teX_?R}p}EZd z9E*}Bo3;u^*V)PKnLy;|RwQx1JkzvIB>0B?gk6#5oAwKI8Sw}mREm+pP5Wy|;W5*3 zCA1Nq+G9}DfbR&^%0MK1PZ;&bB(Vk3BGWm68pZ5@Y?0|xAlxsCNj53ca?>{=-hdc# zG;I1FNRmbaMM^CKrIDw5JD1NfD|doK!Xib zOUND+DAn9rph*IG%$)>!6sVq5#oU!pNaBEAmT4Yj*@z;23C`e$Va+21+Gn7V=$GTA z_k^R_=1~HDEl`emjL`f;Xy%y5TIN907DrjiF&AJLCtgYes%xrdo+409fqdp73sps^ zZ5$Q8-#ib$u^KOR7O1^>p+JKL>T7;kpvgdK(jfDz0xgcCiWzDy5$Gv_hMD&PNzzs% z5hV>b9};M%K%)(GOrQw{`XnUaOabGi{{o?T5kgt~7Dvr%oB3@~Y!-}Liu9KGW04Dc ze38k^-Z6hEa*-NOP4ATXTj5N0`~zq~r_Dc$*rf{a|F|txssV&elAZ!hk!6%Pb6n4ikmM$yLA!!oYKr*SCQcocEHlbXlp+H`N z@|DH{JuFZyrKvzq3sgsGF3>lG5~O-cD*^RFtgo~w9oe_)S5# zxkyvjIUCVr(hh9JGHGu}JWdGu?ZhcY0%YhW>r-5L(oFnLLC&PTv1Obq^)|uu-~iFw zjzmX_@B~mMB?SLSVA96A`|x&G4!#Lm6+a5cq$a`d!Jk$4gIFegC}`UtWusd#l!P1% z50cCbo+3F2RqP zLi|coI=Nj^+LUjSTv9G5lR8bIvg`|KSvH<>7I^v;+iMhr@R&G-z*IpC1uYhIfuJh{ zT?1N0TF{2*S9w{iinP1;0ypTCRD?g8aulVNK6Nb|o!=$NZ?SjRn2fn zx2NrmttB;^PIT<_qpX&+3*k`D;*~RQvYy2+&iEkKAsv`O<#BpOb_|m)&e)Z~r0X*d z!FM+E0Ze@zGcThUy)zGjUw7sa&^9wqfcBh8vB)hZjh#ttV){%9KO(}9i|`8~d|+lO z`0vkbj|ucS;)J9hW>Vqb6*Q?Zgak4Q$y{wgn-@~@y##$oaEe5DNg*ZktO&m@!e7S&G3ztCL+Ut-Tny!BWHE;nGq*E5>Nby5hs`4& zAD!1blSzx_QI0px>)>=q+vW`b=ZATtL6^@DfjS=}6RD3Kjnr%P$C9h|DQ*Z_R@3bs zO9!W?phE>6C+IXm7lrV^;IW_?sA~bW*t7-YY4rt^n|ccN6gJ$Fb?MCf_5)n z1RYgczn}ndzgkSOUKmaeU0Y1_)?zcd$=V%=Z(c%n+)L(U>FzQqV+rwR21C@^^Ow+T z(?BS7S%OSS1D7lTov>sjXpvA|x`Z5ByM#*U`6a8te@*ZYEqM~*vrsR~amS^HvicPF z04?KeZh91){!57-NjwUDJ*z90z8OM}*FnIf=awqjOnP-G`QCU4`P)fQJvTYaDB;@6 z$m>bVC?C_7kwbbeb-H{R#abiihGk?YVfnbK$lh`)37ykoIq~zCQ%^GlG}Nbf8dxY& z(4NIl2)aRVHZM;FfBW*w34MwW2+q5LekACZf?gB!4?%4!$WD@=X)7pJLlM4D(C&f` z6?CkiL877JIRY#a^l3qx4kkmdAY5NMv4Yz9#T@cFdnM(5fS`{H`hlQ{j}yP0poM~N z7xWuJtA|NCFuc}-<}AX81+DhPgZMr&H2MkDoV0sYl1Y``67&N>zY_E+D3hXAcc7*u zUcXAKiPL%YIz-M&eAQc4$J19IL1#Qm&=6=D|FPBIqa>CI$_3ph=p(hhPk>HH^z&Eh zo$~f6US}fu!fK*h1$|Y}eS)44^t7NK3wlw|9|ZkX(A$DOrV3hD z(Ds6M5p>j=n;|Go5MaKbO9g#O(ANY#Cg@2)KNs`|LD^bLAV$z^LH&Z(5wxSA;{^>0 z8Wwb$pzjEJ9u)2W79I}iE@=1S8S9A75p=1bs|DRC=oUeD2)ZA%mbA0``$@H=cLS z>t+a4X%qOWv{i6Qh4c_bkd8h1KKhK)g7e9fUEO9e-kYVC>#1S30qs*fWIbi+`ua<# z+?WmY?xbwEg(O>Tu=$u2+~5UW0lun+^od65Qz2iU;;Mqy1TAa5SL!_qexs)zMTBNg zk)f`F1_hlX_&e{>-wplypWY4q-cOT$NYFQ)Cg+X`{yD+9^7L_^6PGPtzlmQOseYhE zO(*;Cz(G*w!L(XVw)G%|Zyj8Wu>H^nu}+q8h&XS)N#T;iH|sjte+2#g@Sh0ByhU`@ zTcoq%EwZpl&=21_R?o@QBkzD#7BpYb)`Ipq5+cFCV`^h0d2D?XCp#!;o#SMv^ms;d zCu??sTzvRMK?^7Q{v9&+*ER8-Ke*NGl{JvBy^-hO>vo+^2^Qjg-_ND%D6C?R@(N#B$*o$V(+ZGn#N#5bU%^MERK zD%l02dW2xfl$NUWh@k)E6u(Vg>wJTj#I{zY-`^%W{+%hMTL#I!qu7GdyQAd?T836u z>YL4CVwJQ4T4&9-HZ1tb9;;*vbUA8UR*l$LB~O=CvLxJqtW^ZP=ZaIh2{cD)Rq&oG zUU^ZVl~SjIpBxV5M+5Z*!hacnT~Z`%o;jUkO{a$7cw&AQ9d&enaNbXF;q_pbj3g)7uX=XscQxiu6C@)VTv|74e;7iX@z7lA@^{-IDpK>+j2LmQ(*MVG9h2Pd{+MlvlNjFe^$h=Ai z1GR;$y3*Z1y&$Wu%o1phb);4^-KRWiAWf?ev{ctbSumEXydw~mMW}Lmu5wz3!tY#V zJ${jtazTFQD=nv&`<<^$6llJ6bDuxu8p?D79qe-*=m`UnYc-Yi1|rvLDtio6jCi$_ zLk0@>xo!r$z|X&kv(V@nBHO~n`bu&H*;sw0p^l{gY9Fu$$_N7;NMt~d=*aqZ{V{R_ zWr-pCP3xK7KshAP9BFq!|MZ5+uLhdZ?f&#eN}HK_FiWRGgl0-j{CXE&73u7tVd>44UJ>+QdJDxpOP4jB$XF{S%Rn6`DnOkL)Mw)1*wzYu zbx&C7Gtq|sJ7DIlkPe4HwT-gI5RLLVKktey)O?S(f>i zbiXplKt-8jzdzmAT-!OXYN28Zk>#U3wXtlJscPPEHvcf=Npsvb#1J#CRl7YrgdOW?K(r=C)aUNs?lqU?d z8fc($(LkFf?Tj6yd|{whC%qCoSozvOdnT<(AF52Bt6Mn%G+a4HD1_ucLBx@Y_fcK= zJ&cZ0rq9z63p|xRS~+K+*ueRO2bEd#by*6~SY=@Zy%;-A*>0e`z|PnS$^`>8faXKW zqmSwF+5tVR)LcL)gxm+##1$y#1l0TGiIEO&PGC!VIa(ZeEj^%^7gEIeDE#lDgUT2k zSvNG1Op}$#I+A$chJCWK$w0@OC~S(d*Fa~QjFG1*$8;33J{u@apQ@bFq4m|kexQ#9 znj`JQ*7Y<6KMN*W$qAt8N}_?z2EK}&q4))wFI@`kN|>qaTqazTKIy<%q2hmBk9P%{ zg~|$nj!B6P;@K>vTUeKcOu={-QeGDDnA9_eu}73&SLoSr2A|-w;X@;fa&U#6Ul+)`7t(3L~&nGNZ20f{x zy}>9Ce&$^K9g8^~Jjqr>(C5LQ>=C3~3x?u6zX$Qne@4f`ggWd!}#@x0PmN2pPSy`a1(&>ZRT8|a2WXALAz`O>jN8T*VL@tT9N zUCKNiiHg~!JR^{viCs#!jY1PL8#IRrG)HPM#m06ky`Iypw3^b#gPT#lO=YS#?0b|R zI+COYgFSndB?cNYWwhrFUNq3}SwGqL zE87jUWy%c5LVFB&WXd+je&vvXKAZ9Z+piqg5pofNs(&*jxZ2ue>QkP>N*x0&?b6SA zSZQpa4P6ESwKmYWsarg6DWeQDbLt+TB`*jo(t@ey6W&rXLNDrY72pwNje#~!J?uHE z{A!>*Q%`t~E6;4vHBU@^-}8=g?j;>vnEHw5q_O}X&QM4G=*zOAKL+X{L;G%DV3D=Y<7YC<#Gk#Pge3U@w)U+FMSCn`IeLAgn##N=Jf&M$~@$_rTqY>0J z<0qx=4n3ZI`uT)klr;uQo8BhlS7lU*F7pH3P+kTS<6o!g9WrhzZE)v=66^=zZ%Vfa z>XLCwIc=aIjQ*iy?b0>p0R5@VGSKqry)teq#|^Y``hbkTl$yJB&4bg2W!zDY80g*U z<1-|+W+`Me{+)*zranp#=qn&uy=|at(}Ni%b>|*kb{jHPjo+)I*csz9Eb49pd1m}K z&8nU^P>mToV{Ph>25K}Tlo73_zOKh>KjUgrjGFZZA&h^$XPi%nRVNC#S{gfJeny;n zJc5>I#H$VWk*fY~JJihr&9@GlRqA%AuNbIc)~#rVdelI(W<8papq@0)%2|>rLH*D` z>jnBuM`WOu2x4I~%c0BUZaP(sn4vRiFu!0JWUfw~%~WzkReN@`yN^+Lo- z>PQ2PMZ9Enf`R5DUa~sbKu;BIb5vGm8E9{jDXFqL&p>C3W~8R5OAT}}R1^YSZNTqf zG*x}dK!3q#s``R~5@!D;rK$MoDNz>HXMYu&rtUFNOUTmILk8*(S-N_{K!MpOnMXZi zpn0>myFKb>23j*a^i@WN`i%i!oc%q}RRisrosw8Zy=kD+vtMvmQSTb)yV=(>GF8g~ z-I>2;-vmlGP(tXhjH+smfwDu^Dpl2d1Jw&jrmAXv19b|SLx3#|I6QQcWvT5AG%d8< zouv*j&{D{<)iDNo9z(7rkPqOOjF$481-tMlherBKvi0D(lG0-B!^Ql)2w552AoU7h6(EehD z<*IiLbf)+($*)=t>ZSH|@mK$+w=V&!s%qO_dpK)>A_5-50SBfMnGQ3^ERz(bmT8hX zfH+*_-(vn^@ZGxL{S8 z16|^1LXBYOGRL~a(=&>?Y}w8 zCq6S5y7Z(=&Ipz?bH7VpdJkD9={NJ7OB&tsg-Dk^GudSz9ehr(*)wmt45o$)oMn@W zQA8O^XK2hcbClyydP8F$&iu_~7~OIauYcKO-^@QUbGW9fEe1y=iK z4{{w#YkI|&#Ev+Lj?&nB2@An@N@FXsIrIKO6u&up1+XM! zMmSFT4M0a}&I|ON|xfjF5BaHyS&V^N8fo z>l!7-LUH|r!_{T6{LGFNm@>SN0v?ac(t6`+~J`Gu$ua|+j5#}W|?j) z=m*HMt#))L%1XLJV~4t{z&_E~DX3Z@J*=_o$c}65w>fn-h4kNdaD)<*pF(<3bC!1* zAs5o$H0Gs$L<*_n&$v%k&2n?y3aKYDev-_SSJ71ABY(WM&}|i6tFd;uC*(EsdyTp0 z7PzgY@CGF8QZ{kVUG27xdi9&b_KM=*Y za=a*Sq2U_yaQqfnvc`Jm?swZtdunWO?m=K9HI|+`LjI6W)Yyz%o%A7H3k*l71-V4o zMnBS=e92@R{X}DY$z&TX6O63Rt#I2;H~mLcban3MZXeMiGn1s9^gE4xn9JG5ha$2V z*>;Wb^_!jaN6w6}hevY1aN9+v|1Lr+^q1Ur)9=jenp+W#eAM8pxA}yQF|*rl#dMjO z)w}Jdm&}Z~m(b3CG^E?>P)4U|?6cf@n{rx&3`VHwlS*w5)7F2A(CL%*IvkpXMq|N)6vt!q2aWONqbmBR#(E6e>{Lx#6L|F+cK0Ie z?r~ZqBQuhpbM{hh*#U{}SLyrB1pD{gME7envbkX2%#dx%-dmqhkl^3@$=qjr@uo>G`eEoZ*A^Sq8A0$x0j^5 z^oWyS8S@6Y-=(KCHhbO(_j@#aN;A9V z-iqBYvwC+&*4o&vA=AAMPRvy>D}I@2&AMo8a2{v9G&Vl(PxsdBRgGoj!Oa>Qtg#x?42?YpzBVkY9eh`mk9*m9c}{KF7U9IJMO${z%$iB< z*k@Y8GkHXDW?yJ*?3fXv?A+XZA=i!q>~3*)z_(giKPO$CjW4w4D_!C|JuTsYkD0~IL%)C4d ztOz4{`_|h8up`Kf*Cier$WED^k`&0!BjY|VkHCg(T5O&ld0H> zx;3w8S7wcj?{6|Ne=~D)i)4|=Dv6O77{v-T$_tEQk)1>X^8%yTLXGhPqgjQHnl9zrM(9>}p=GmG_zV~Yf{dT~K-k8W%QvP$xa5en?ac4(9r-;I5v zFl3nOMw9 zVhPByt(1IYolO!;)u=wd9@tQg`Q{TPnT^$0LcR)YipIu)uREKrF(df8v)LNk489bW zr?FD-rLY2x-2mV7Y_-Pz$cL4X=hW)X$ z>Ur?>Vl6Z_Y;juW-po;BZ!I1Stb@i1A>B*tS&i+4bT2VKja>!b%Pdr5x+SXevXRAV zG;qn-&V5*SjioM`1gy8lCNHV8d4=`YSniT~V3Uv)Sgl?1ug-nhF5$zj*O%FQV6{nP z&~)&1Kz3bvFX87-eVMoBd$_dJwl6cT78DcqV><-1YEkgHLqE1xV|?whA1l>Zmjcd? zn$s=r+>c$+eEj)X8oOimNm3e6IU6PEn+zSY z!8VP3q_NO3rM9oJ;~E<|q|AN*tJheSzSMRgd-XZd*ZUM4=sbvBLdJ7B+Ia{gokd%W zEI8Tf4K_e9++FyzRc9k6v}(B`&2uRG7di{9+*S+(_MTuQbj485VQi(D-E$nlc4{nn z#Td_#?7W#x_8h}>@S9Bh#7kT8ljAt%VrChh<5_oPVntyh>*a~pKXF!0WL4;FU{+pO zZ>VXQ(?s@;V0clT#I|cJWTj4;#Kw7xJ&a!|N$IS+k6^u5&i71b8#VR@u&Hc}pYV-e zNt6sW9T>mQAX8SBIApN%n)BV2CeOFodU)ZS??ukaRi4w?C1m+z(aQCn?=m}o?#n03 zfW623k?~=6v!{`b5)3Oki>=Yv*HF<}tV(0GP|+-=20$)w{Ui5Q?)J=LdQO2Ug_4xb zsx%flm9sGT-68I?EgT_dvq>83Sh(Lan`MOvUl(9GY(^+&nIx#N%ySOQ3`ZYS?MCxl zw!qAC+RtU%kr^xTy8S*=yNZN!V0O8HosSgkWvI*o);XH90y4I+(sKc;(%6*3&pa2h zUNORF1YbV;RAY0&w}{=zd7yDXc?E7 zQ<6kwyw{!sW}~tAwRJXom|kQ3*46{_(%9Iw-*hQrff}2>c7$BSVgM)lya{ z7*Q(IY)je7ibmf-20z)sOC*`qakdB9lB0qxs7|vz#H^|tBg>ebVB{P`ma%;r`_TxY z<*Wvm=J|LjNr%~4!HE8Nob6$jcCs;>BkT>qNCfzfFuMzlz6#b_Fp_&b&9;K+FE;v) zGH1ca9!PhTEz?-dabp^Mj%&AAH^<_Su@Y?+T{#hFdyF}2tLUyL(rl|3yzy>s;cC`K zFftAzt67-FW&1& z#1?IPv_%fisJH_v#2a<4z@l0xI-=LfKzg8U1XM^aph`@D@XiP#*JW}5P$5TA;Wk_^ z(f$JMqfPSp7W9UEu3{udS!wKHTVlMa|^qpc7ZRD{k^{!67X6}($x&JA-gLh+4~rTu?Y0Oaq1 zMfw9OBmxlr1m3I|AD2?m-5+rP;&8+<7WQPcrvSpSM_XVvD)RvqvJz0$3KP1>S)}DC zll45(NVdR6BErEF!wWu$9|Ou{FWO~j*Pwk7@hv!!Wb%WBeb>U~M_tjvIp@5wY1nhklcB3u|ej1iTyi95U6|5Y*HHwGt4C*`Jz%}$I-m7GC5hJ-5Mi)S% zL@Yx^V$t=U41GM3du2>3GJ4#56TKq0Mq9z+Rm)V*lboLYs+4O`WVRah@)FSkHV7KD7LW(!S%^SSK14JfG-DfaC zqgNq9xsLizhz}9z2fT#@K7)2U#10m=i1Y?UCSj;^+bD=a5>V=e?!IUbK(x$AWH$-* zw-GHHU)ZxjZG8@i0>CQX%0%xEzt6Lz76z1hO%!>2?<%pTN_ z;#m2qMU0q3@EGX-mWhQ!BshWzjv;b_h0MT)drQMrP*4UM*f_a&+pvkPO20Tn!yDmenS zj+`;VhLS6Q45vgAc`{VO=|jV8PRucycE(!BK_>Np5^1y*^2bvZl{DKTBB5`KWFoY| z;Q(%#w8bDd#4e}=0>bR}FOmgg7yzM%QeR~{w zr&{0)uod{IfT`uTaFH+Ij93oY;_!;vJ#k7xO|LXLBSqwsx{4DN9dU}}E&ikzZj{6b zWyJoo2CK*W$>S&cKT(=y-Bhuhmx*gmLl4J6?s18aqI^mQ-4w?QKDU#|Y@F`!tQ+>m z@?`iYx+qe#uDC{R-hvnTk8tk=HcX~@F~a@?y_VQG8InjTcx6%v2-AH)m7E3Ckt=`= zH)l7|=GRwQ>%+q4BN|Lv#lZFp2K@;r6YH%!u|1$nS^+Ag9V%{Sl!=%G`lAwz$h$jy zM8ZN5J;U<6?22BC)67Wz`FZxgKViB<@iOUyl^B3%9EF=V(UAeDkW4_89Lsxc}%3UWNE$q!_o8FupG; zjq%X`8_Cn`K~E%jTFl?)@V8#$e^dNuto1akM5C<`ezK`#ChEBuvjk8f>rfGu<_NdJ zs8oK)XCtQp6?m1NAC5{y;|&bD1*nkwC~;fXY~40)^ZQ+xtbh%p0%Awhz0nRrJM;-# zf!E}De5%`{p+2|8Qr3`~53Qy6ugM1K2Pf0ECabm~DkTi;74U zXtrS)3bTFzm3|mM_z7Df6H(ziDHHJW{%rMAj5}bF)&Mnue3A_ z!+SAC49S-IAH?G%cN9fE!>u~6h1WuH-KKWbhj4@u z`XlbJw3}xAf2(MV)|QzzUS{Cw4^&7dT!G;kM@eT?`~Vda4XBb{fbh{sz=olW$0&ry zs2HQe82Ypr<5PnenQD>UdzhV2vcQ&!xYjMew10KQTO)EXqfCTy2yHZ7Ni-@iBMv}iB--HR{r|7r zV!+`jlL?qW*rGjzB8H>CLNQED!?a?U5{g*x;DbH%f4+fb7o5e4e!%YuMemi!EUa(C z?Go3UDk4=L7Q;~{tDmqRzrz&q{2YPt-!kj*aM@@W)&D0Ko`xH@r{8ow?iH0VVl5tf zm}{o%hv8rO$# z^@uy*UlaYQ$~A4ZiN_1u^8Tb=kKL|VD%i$GG6{onFr$@E zMVV}{(6^w?6H7!Krk!Yud)vKDY|A{w6A8YW1-JbeX>4@M~<$yxfCZvHy2`OyUW|nAin$1w&N`K`bE5ZZT&2ZhmuF34 z#Fa+eY()GR5boE}u0X6o`~p!FdV?0l#z*qiw_Y^AxLSM#pBjIjX$pO@nb%2y?1!Rwf?g9nY zb^ulMO60GyZrqKA$@o4@D|WIRY>5awj1+J2}#9@eI5yb+9xP?wfMO2R8zQMPJQL%jN zX?ZuD1zs5+7{kJ=+2;40(ElI%BMSW6u*a`jqF_;sSRWC8MK;f(68zdP)&SrcHR>Xj zsL)zewwY1JM{Wu!D#G!f2g&5HMRu0WF6=7s%H$lza9h$=My{YO{-CWEY=u00LJ@zH zCSh9m(VD$HEzd{TM!5K5f<{Rwuy%{O*aPuba$>(N8@XvkEfrBY5#Mp#L_ zd6t)8sA!1_w4Y22vpifa;A3dRzFM};Kd}G1^?%DO#2q}Jddq~b?JMLoR?G74U)Du-aA^iq;d{(H(^QP?4G04& z+CTN?y1=ohh{wzvW%xw~?tQ%X;QU8SEXCv2rnXQfV|Kz8Q&wTWi@N1uvb3|nE0ei^ z@Hd4RDQ?+>z5Ej#|1A?VwZ-k&CQN(?(K4n26q$UEdefx_5h-+jS%=4a7%7lH)`9*n zdhcH$4{C^MYByCxK2OsX_(e=>nBG_uN79^hCauW;(yn;ypK?1%YOyp&NtX0WPby9k zRbI7n=$IngI+_0s|7d(IcQn3mTq{qX=*E+I#U!K!C)T<>PSuO1{xk!qW z)tCEw~aJV-wUunKfshODbE?B_D}Y%CW-q;$dbYw%Iw1d>uutc z5&MY}rwoKI+g6kG{SW0hg@5HXPRRs2T;cC3$0_UgzvbN< z&a2Lb+vmMUeOlsQ1j$quecI1wG~voi^SBpuk`8YIyJ+~%(a=3@aDh~I&H zp9>`VzybRUq{jgrq4 z&A!AZ6_q}y^g(3+R(crf;~=ASc?v4iQOQDlAFJ{{=o!9CP+21J9Xl<348?C%plwW! ziqgJ+iO&Q1{DEaHPfOn)D6>B;Jvd+|RpTB!kXw~3^F6J&maGEwLQF1M4|W>ZyQN_z zTfxpK+38!YWR?{B7D8bIyf;E&w|zHCqfGN4`yu!DFY8bXjVVdBWMzq})RGSoOA)_8 zluLX1)xn2WUh@l*_&29U6aEJJXu^+l9lW_llse*4I?RtBV@awb{9|!-VAtE!k*+3d zRq-_TD3w~|ORtnJhKvT4f}5n5@?=?v1%Q&evGlTEy0R(qy59qNUumiB139CFcMy*r z6CEGO<)sh&B=tmTk*%bjFTLRKK>oh;4~VSNtA+>ikEP8FyjALLs+HeL?NE6J(4&XD zA)H`WvR9K1CK&A1Dt&?>gLLg$2celIy$o&C{s)J&{GOD%kAwvG_rGayQAZujFnFp9 z4{kSvtNa`bSGOG8W7v-8&vra=)o|9qi&9ds{w(OcRkmaI+%DA~)Pc>vJG32-ZV@!N zu1;SBEgq~>BBbX`>98>#I@C-`A(e;V>%)Y9LMMg%`_Kgc6tc)?s()`X#9QaUPlS4# z(Q0_vr~aeWD8OnGS5^jgIARoFH5|H1z#e5I;AHHFI0$hR;+uf!Dz*z*Qg+2Z9d_Xc z#IJk4tPVCi${xZGmF+M4+#v&kBq;^=a2?u%e$>~?j|VJQH$|QdxCAlj@;de1 zabE|lQ`5`8X8GnoK2RPpEnrH!Q0v2I1IwjWhc5;0R}boq&ihrj!&hKg ziog2)J0`q`NBMUw?spQcPnUm(Lw%Vktvn-rG9f39d{oL1;}l|s`?Ja z@Ian__~W1yvfjrDPLlik`?TcvgK3qO;^d#<>num>Q-Yl_3wKQHj)|SI0B4!M*On_y z?KM1@<2chbD<$w%mm?X5(`xvUfu0ZKm?LoJkc1+EtG1KfjG0`kKk&u6!B*HAHk+c)=HHTBr#h+av8n_Vj~+(>(~nFG<^%o-uwgL20-JrM(}GK|*-Nn5 zOR(8Xu-PlH*(>mPm*C;6(UA9^8cbCq-#xZ9ss<0=1KGRkWK;@CuDSxa9!6kKh_8ho zpdVJXy5j?=v~%mTm_xqwc9pRX8Y8=^&gLu@nJ+D>s*C6i4d&dM*ViK&nzQP@eYtcQ z@dw1)fEna2q{<+2_42m;be%SrfQixj0iTa92TbWyO`NMQ!nx+rqi6I3 z*|qwWXnt|KWWP?jRyJ%P1UU{F6MdRb5^VbGIPy!`spxdYx0=ROD^+@z7<(n8IyB}I zv`vod_t+j&U_T`3eME0;r&RDh4EYhg?s&=i5xVN-7K+o5UdK1M-jiQFUZ+PBN(;7MyI!K;b_RHVm^EhLs+M1q_2prz8zPWgHf^ zguItfryrp3Q+*s3JV4Z-iyx-&5f$<@z1dQ+H}cvIQ@pFV#D^4~ zQITt{9PJ<_xXAphsgI69daB6}-b}oMP)k*%)t0sWLtCa#RF()BKiq_|W za#Ek#${&Wf&q4VqyLBSJWYt4%uRzX{+F`*ysaA#yVMQX(^n|Iooswwety+k!YE4$3 zNKSemcQjubm2s$hzO?B?UBqr_=ZUQ_T|9B3vU`T^JTzf7%*;2~ZdCY1n-3P2gg?)>LrHoN-^Od(cgQf*BZwVt-_-OMhzIg{WIk>K$sZ|hu)g6Xb@o;PwWyC7l@R0cO}PcT_dX$2p# zY?dCB3)^|HJpx;*!{^&-ww+or&l$B)*wx!QKC=05^k%tzz3xa9>n@p{#o zdUjMC#8UrF7G=j!LL;wZC;R z-`)2TN5fYGaKB*7>$w%TcM_|$ZLOwThjag(L{Dv-qHRax7TQJIZq@W!jazrs(!rLu zQwnTn8F_;=2od~vl&6fw?Y~oUVaqF2t!-G7iFTc)a$U0}BFI1?~s7?584-WEa=}s z7lJMa-3}tb*6;&)`r!7#zQIAky@LA%PY#|DJUciqcvbL@;Jv{If=>m18T?i7&EUG= z2f;MNKO{UPIiy#}z>v(4MIp;WPK8_xu?_VNeKB-K=-SZI(CX0Bp?5-U!a9aUhQ)^s z3wtMQW|%3g$QX7d%pp8DyifS>@VCR~gs%@T4L=wDb@-?^3y6)=w zX;=FQuZTer=@G_=oQQc5izC)Wltk1-{5#@C#BULQMzoHMj*O3dEpl39c4U5}DROn> z_Q;~hLy@N=Z$!#b)=`d8ZKFJ+f}$d$x<#c$O^%uswJ2(L)E804ucPiok!auOpy;&d ziP6)eXGSlI-W(Vs?_M^{Cki~c6MHu|^d7BTu5&zPu~fiZ8!yd9Ghvmj=5 zOrZ0wn3FO0V|-$J$IghIA6pxn95*O#WZc}i(zyF^q+921;oW+68`EuGw=3Q5c54;i zI^HurF1~mCl=z(ZW$_#0cN*jO#~+Tr5dSdVD#1R%CBY}*<%B5-GZGdjtV`IDus5MR z;Y`B$gsTa^Bs@$|60H+EBqk@mm^d|Yed5l+>tWEqqv3=5WNj;Kkx_{BV zuDg=bCdDHqFeM{pPRa)-||-Egk&o;HiuC~FqC7oxoZ z?LBB8pT$cVI#O*9pZr4Qmszc$M4d5v^8)>ib-YP2u<>+J7K6&*NTbxiPTm;l;D~N{=m(x5gcQ@5S*ND9`0>0y`*= zdt>r=7Ta1@Ll+PQ@6Y4KAI@v$0lz(u*}XQ9=P(wr+k77X{#c&2_k3RUcTKkqu-hJ zeR^?QG^y{J55XI;W*6Y*HC+D~anV|y=ZdwDK;N;J>!oWIcm#KR?MJc|c?9R69r=UU z^FQX{r=%4rpejhFVvhhNvAHopXOd--s9O%$OSclRk8YI=KTioLlUH?X!0rzylQi8r zz=66ApbP?($za_FU=IP5$s4-OU=KwcuG?`yJh0!0EbTz;|`~0YB0m0Q^{23d!~W%H)vl5a0=2IbeWt?g)8BOGfZW$z0DPeP3KSpu zHQ3&WzVutL{pe*t1HB4ff5bp~4U_=HAo>I7!GJOep|xO#B8JmjpoAfIrME$kK#Zby zK#!z%j3C9(Iv~-2@Drr;F4(b%-Do{1@ra4^H_#IhljsA`lMz$sL(sb;K2INk{sN#( zQt6*y_dx7PB}FDL0!pMeRlx3r_!8AA@aHryQwEM#s5LnHAoiurLFtFspSA$~Rm3#f z67<&qWio);gZ(<8(s3X{e5#OLrpbSMEPTPP!3{WB?X*;k-a5R!pv^_|p z0pahhXh%T!-2qU>Q#Y{3Ax@wkpiD$er_X^t2@rm&m3o3b8F2~q0(&X-0bE1<0E?+V z;654%k^2GR14c9$u!M#JmeO!Q<3Sn$n?p1Tu#Cn49;b1T-~?g~jR)m3nh44{nhf@r zi05ev*ca#vfEQ^Gz^`aez)Q3@;MeqJz;Ea)fIrZFkoE@RP1+xnT0n{XNM8f{mJv6% z>FYp#qJzM32T&&AYzSaiHWV;|4F`;5Bf%TZMuQy%D3Mq;7VH?r1U4S*L^csHiKPRk zvNr*Hv#EeDv$p{IunfRg*gJrI*}ITKKW2Ov$UtTU9K|vLr?6RoMm8HTm*qgvTtIlA ziRFU*KH_{f50pGW_?=vq2lfKQe6|3TMTkpSKIn@9;nOW_G1yBHO>8MB%K+goL7B-2 zWCb$;7P93atwdbKR)Vq`aV=W~`WnP_Yz^q^5jV1Rpl<+_$R@S{><##jVYZ=J4ea(yayj87GOf)seGgOiOst z;n*{#m*bTvW1UxkcZByS?`A#@KJ9#ReKz^*@j35v%}3|k!q?F^#5cybkMCsPS-uy2 zuliOPelvvl$M~B9HU{huxEJs+;Mc%E0_O%T3i1l>8XOlK9nv>sTF8NrUqW=DA)%3> z8KK+5q;TtS*Kp5pW4Kks@QASyL!w4Ut&eIQ{bEetm^(2mLt;0_?u`8;_E7Ax*w16X zi(L`-LEN4=r*0j)rNzGyKRP}=K0m%b(ILqvDKe>R%951Al>I4}Qoc7OCMdIQFupQqP#h8c=ZX8@$SQJ(Pk3c7uORyuVCf0z#U#bix)xYWbbY5zo}hvddu?12dk z{BfzaZ2?=_;_X=4Vot10i-K7ApsQ(JlHy)`BuP0u-t>Br(zkr$Lv=wB)f-& zhR1j7=5O!;2=WOE3JdfJ3-S;32~CPiitpwh5*C+eD2|lWZxt!f3Fm|VMl zsd@bz z_`!O0+cQ4oqZTjp;(;*vAtT_w`#F`k?^nr7FDJbG(ulsLn+|-KI=}t1i{J2irJL#0 zezlK75kxfn`<&aI@?D-$%Fd~#exIuSOtvNJd(GE$7e&Li*i-^L+rj{~_9tN^n1mDm n;^z*k6Q9sb8xE_TeSiNFKR!F(=XvItXJ)6*>@j~+^!zQ+ zcQ4L-t!&x=$@)7b@kVaukfa{6Bq=6y)WlVfh1 zWXS`({CZhRGk)qOhxB2rscS+v#Lob~hrW~rSugz=)|BgzraKJ)zeTSg`< zn(VoUKRRsd+K}_39@Sq&FLMsc)w)Tb7jO++DmRbLvBxBc6OvdvVRk z^z=kq)T)7Px=#6(b*z{jHK(H0$j(b{J+XbvJ9l`eznZu9!qZX78$LY72I@z77j~nb zAQ!ru+9V}IVv?j4R1c8*+p_KlL-R|L%U=+~wFhfaVY0$C5`wAkw|8v01!1)aiY`TU zqZCc)|6|nFj?##T`m8J|p#awecpku|gdB>$qB%_FaP3K$581gI57RkZjTI@7Zbb_y zXe~*ry%{?>5U6NHSdx4NvNRPX4u`xvmnYOSlpqXIa{7NA~~61y_@xQ0k7HXn5(aU{__z^M!W?bhOh@=X1i6WYf~B zABug2^`m#?&_bXk%cxd4DsO>Qtz!poHX}IH#~3Vp0SmziP`eds!4U}DR!?95k2lOd z)z$bSc1j-+KRy06ksz70lKosi89$w!)cg6e(q=%I(@<6ms1&8t0-JO_Tu4SSSJ?HH zzBIN^-|k!9b}7`{!XpoNq-SW*Qz~yJleI`B;7E@%W#pPE)58ftR-kWA7=cpwBjGRq zN!Zd-KvYzTnxgnjkM=ibpI3MGbM|i@mj|Z8K2eGeKr}Sr0`hb)cBi=w#0kw?M3NPW(bgLBJBoBHE?#?>yp?b<6 z*RkKKQ;wBuO&rlrrTBZjQzsi)Cwq^$s4qx#SsnKSVg7DVzvYopC;Uk7n3|~HnCgyv zR>%B=?DQ0NoVMDOza(xa;;LPQELbP|o@8AGw|^b?2jX@U+-Y^(pNMM~!m2th`$a#M znmFvgb;2L&gufBDyD$_RRqN32#5LW_t>b<}Tr<&Y>bT$O{nAp|pZb)vcat7~Mom!+ zQKadzR>BeI0ew(|Ey?xE=^Y__6T*Ocw;tWF8GEX_Rl^~y^aZ?qE4z2urRg^9MPiVH zHfR8&lYUp^x8JK z6>Xm$mGd@>s(wEwj>qLgY+xkh+qqh34-}1N=k=S5RQ9931@veAP0$Pa&!E5R zsm0CMMZIfr4*Nr&UaYcj^?N|i>8})zNA|Ou=Yb9u^bSF*iB^Bn{1q1e5}f377S?r6 z`>LO5`6y#s^)V&6Y-{z(5_AYVs~>8!m$NS$>=?G zSQh`MFr^DqYe2Qi>bpBebKkR6e0q~lu1Sn&RtN-k| zNM_sh+xvb3I;!7Wm@kC-Hvt{kf4PHt@$`-uh0pZQcVj^Dj|j2Hs=JJc^T2^YH(Ua} zW>QqG+v|hQ|>~aAxzN?Ay9VnId-9p7HgAjc6F$}wW2#4rhikRrVob#UXNW_IXOKe4_=Tveng3avNl35 zm^qjY*B8w^B22ktq*-T7fvFp3wPDxk56{XUJkm^y9J6bq0D{f=976sn+GxQ4Pk_%M zZ?!Rc&g={}wz~K11jSCJ$hC3$#JP8}@%s6><<&hZTQwGJyEZ{zwB;^#z3$(78|bR7 zKUn;6`knW8Ou7|OHO!Bdd8n+moFYC4b=Rg%(m%UD7?}*`w40zI3#z3f7-Bg}V5kc{ zf>4|Sm7*gikhL3ua#9Ppgt1MUOA|p;YbyAjU<&HrG=$J#Orye{O>uvk3dv27*~d^!5)Xxyek9lGBSqRSUiw6bfM~gRSu(m5 zObEpvHBSAB4$bDkN~js1gRaA-%_Wd#fl7ctag2rL>3=@aF(v|DHn&*w^`1LgIBL2D zebJ5_l;zGHe$WFunzAbW#~rz>s=DEm&oc~oA3xPK@9jp?^om4kWL(xBLyugE_KZeF zw27FyhtEJo-2xSDtKMg4DthusJB!)v`lg+kY=ORSXIplM{^!o?JT@ewZi8;mgsGH!ex)lCI zJJeYSJJqEype`e_9Hinrnx3oTE{J?Kug$cx0)lL>O__sE%BES!Srbs^46Dah=Afgh zRZ`}RXjThV%B0t(4WSY%fK6W%SAD25ZhJ1)UE6ive_mv_SHJV0jZwT|rd~D1uix>) zQI@F>-ZO-S^e6VTWJC1Rdva0b<6o@6`e4zE!`RB|Q!l1)&s{KAc>|K-6?f~(OD|o? z`0(X3`m-;`U%{;Y@a0Svzp5r4`j1KE>1y4z|1Xygc62bosjbnyuinMl>04h-W^1co zcr}V;%tGmD>!2_XRnQjli3i8~XU7&dH`ztiKg^0xlto9+C4AXA?aHB{RI8-YTHto747A8eexn`-t} z@U;6uWQ|lY!?O8(Q6=A_c}Im(9auUqJD64c0BQAw-0wqlQVe&Arg{v1C{s3B0qwyW zH8Auq4i0Az>7|ESH>7ksD1ZO`x7QYmM%~p4sRSMdS9WTB^)-j?V%zkr!^`5fkvSef zx95`aO4e8JJG_>$_4?qq^FbHBT>`rI?T$&0Ko9RKKR!x*6v5~kecgW~lRc)lK5`v9 zqOUuW6S)bVR{nwV@Y?3kL%5!c6f9hyt=VBpWYSx!K7iu?DdN|t4kXs4D_Dbw_16`w za$;SMT)`VkyuYtt4JVd_yw)Xo9kJLItWm_`SFpwqOTL0NfmpUHSZt!c?`T%9evpLv zG<4NuVH|KEuVHJBL6X4`U8?OeRMf3;)Rp3vjoZFMbGis)buv=FKjF2CFF2{zz!qER9ajViE`siyb&@MMiVNyvZw;3hUkzy8C)mX?pS zUj1-tjh2~CyN@PX@)(jo{?XVg<;llx#ZpK=*3@Jx!A8`#Rlk0$JImTdr0gHkKN7wO)9djOXAvF2-6 zac+_kXHnhsM8uG_7b*V#knPpyf0~fCw>H&!sYC~pPzm?xPkkD|3i-gN?NSe4twx^F z2CBMLPyZ~1y{xzSET_?_S}nh51%BFGK&M{u3bcJn#eRL^XRmgD6(E%6jSdX;MSJaD zk2hL-4J@zQ8$EmK2%kIXB5pu?otTQ(6(6I$K~b7{V-O{VSl$@zfPVL>M(j;}*QtrI z2O(~3&I_fE>OsBf=S|olz3=BG8HXX6mLv9kv!L*Vx$oyC#$f53ma)@_@$ z%M)!2$LXWK7%}uMN;q1Mm(;fr(vE=00X_%w9h-V5YLg3+t8|W%P7o{Wa(29@sm%hwke*N<=8)U>a#z=ac)Q50C7kLj09&PXs z(>~D~o=!~;LCK}0XU)Te&<3L?NZ)R+IH?ajodZLar<3a$O8$34&z$}io5@?hO2Ovs zp07$1Pr-;))*h^HFypalpX)Ja3L+#?HzF&1RufEXL+$aJz5vf>Lnrnn1)?zcVi(5L zs*x)3ih7!)_IP`pG&m1(Dp8*!-XSueeg!1#Lqf&tbH+RCNg|XqL{!*5SG=p9$dXXW z``q#Fe@f0kvivZd7Sq|9M7{=BI}36J;~TQ#iT9XRzO5BUxF#Ze2Tra%T!6w4MunT> zaYgiVSBOil7Jq+*xZTxaOz7(w?^q{RH$)-(Xwxr!-OyDAzSE!VSAWpYe%(3#M>A3% zaN*GaJoI^IQ*B()e%9YP>%$cC7k$RrM1AKs361Qb3U1f_8AId&lArX#Z+x;{#7t!W zMLa^k>VKV0PW@l893oa?i=W}g@{g`4}=^b@3^njq=ui8_#c^kf}KIr?cGNIm*l9Y{NRstzy9P~( z?+K=1$Ko%9+|(D~YzJFs>Kr_@ZFtF$UDl_6*RctuA)ApYn8*E?1=m`S4i;c2_)Gub zyL@(8k2=?X(%(>`&5H!=PGHcPfQn$QiD}rHU5iW`vQ5LDpfv{7saiq}yN7fvhXW%n z;V4VmEw*Ds;=k*A&LyRq841>AM0*YX`wKlvc)9+=xfHnM`u@5WoXpI_LdC{4nZla| z$YnV^*DZoteHF3Tl=Y3@x9+#P&R<*QW-=g~3;X*hJcl@;Tx=K+GzD9PfT*?Ne+(vS zR{WXg^AvG{*HF=<6mYP7Brn9agV(0o^=>}|dk8ayj!Wbm0mNb%RhHwPw8EMuKNEKuf;Dr z<6o;u4=Zm<3oGx7zpP==)hjM|7>m(2{I?@}UH|02O-k2`N-K0INR`$ZinU@9Cs%N= z7gVbg7$#dlFa5PRCKj%n3{3oD^?AQG#1ik`Ut0x{Gt_Tt1o3b|7F4Zc`UI1x8l(UH zYakB^2z`4l3O!LsiK;bxKF2SZL=mOzw^m(HVpb9VaiBr z2vflVs#o9pn?D)v-&J%VkV6||E{3{=KWdXt>)-!|y$RiZ@pBffe{*p}y$y;~n8XGJ zJ?d{zO!&Q&-L2pMd;1hBy;kn>7&Jm9q{DA|UMrea)Z6IG;W6XHiTq)Q*r6J`Klm!hh(FOYbGr9?VS{3NJ*Am-Qbm z1>)!|PRuVLP@LL-bpKy7GQ?`g6-a5Gd2ay5unz*&t9?>^$OD} zVG1V5lG?-A&e-koqAEL3T~E@T11O~$9XQMMkOMwPuyedaO);i%mce=$E9sGHJjvNe zmS#lDEFX_jnPqtzK-;>W5j4K%EFFRsGHVq{gCLZsXaQ_N;@!{8!n;?r3_7uymkKxj zZ46ojC2N;fWC~*tO7~yJAj+bwrIU<0XPkgb`_Vaz1vjb_#EooP2E4w6lS1i?P?vR>fyS zm-}&+_dNV}VSLzZjCHUcUa==@UWvfggi_Jec;3OLL{v)Jp=juJT@Eb=6kEITPA!N~ zcn`9wg%HYhB;XbNj2t+%TwpB^Bq?8TF?Ffo=7Wp(xfUF+UBgzJYvy^(HfUSdG}xBc z7@TRcy1K$oIx)bBBa5-%3G2d+BUtEl)H8w&Xw%47wGra%xzXSj7-yaA7&~md>|)6g zv9FDdI67k~!b1t4pllS2pvch-IHrWZsN)K^OzyXJ+zS*mxwa+Vyf zz#S`r6}1(lIk*bZ3no#9scvg>;!<*oB8Y0coQMljsX25LY6R?}`@>Brcla>M(rPsG zV8cfDCyc`$mLK^9*~;O5MWcXe*j!MztrtBHo?RUsUitGm&%tVnI@!RmBE@X89G$Az zu{G@!!46)UaO0nLdQx_IdY;xA0k>T#fJN@N3vaA01J`5zF9vGk8~dYKmY;TtMeZjf z78Yw}vc_N0tY3T^Dm*?9wavAh&Q#Pk#>f~Jh`t_i;6o<)-Oi|rVSd#t72$vlC*bA_ zqJnH+R}v`yKE^(1_aJSoq4R}lt(08CH7PMAq};#t&zGRugi_MzDgG(NHoyDRSngN* z84Y4tessNerP_>Pv8)+uZ!Cyqg|VY*6Q^mwY~uwlYh;{`W!IGsq52@J^l&S=vOQN( zLQ(cyF5~jtKrlVBctktQx4#$;`)p1N7?p9Xe+(6iX5dX`d+p)X#_>27Vr>n(mld%N zMjJ27kELw-++KHhJ^av?7`J#?^MCWHasO+OWQYc@cZ|YDXhC9)n4qF*2SdPo_M!u10k3*Y2jqAv$z77n$*EosbQW!{_p2 zr>PsZlH41jonbH9iP@3nI>W2Ud+Jp~$#yY0^A`r}W+*UB4Cq0--Kjlkd=}3N*#m~x z$9!HfA$S)ZZYTd@L)a3(WW&*t2qoG`tQK@7;xdv&^XQvDR#}@q~}v*k}im zOcmSIE*^fS7PxsB$IK)#S|_kzWC#k_;m@~c;7B79WDb=W(N3k<#huAkn{wI-C0U3& zYuZ|oS+Uh}6i?0uZgm(|i%id#MYW8Rc=~m}HlWkZKA*s~75B7ku* zfi;Pkl{)>p^jxcc3(tjltqg^L#&7`YS1=A@!}1Eo;j1-{Ud2dnm#$j&)7z&vs|n6c zmyxV-Um}~6PmNU^h89KR6d}sWJ`Hi{ZA2&HQ@o152$%f)m`#6T^z^fk@s*$XB69c` zl1tUP!rff-+yaVfY0d|86TtfdDi#m@GN$pEeuvLr8IR!A@h;Z!YU24t7r>;T*?p9H z)k`>j2szX))FOgrXO6D@W2BR7SJdNpW{ZU!IuC{sL6Qfq0rX|rm!5=&nQn}xval&M+(bA z`8=A!GOnMB7eIAL3|!RPc%v%j5D!&HtE7Ov$Gd&Y<9^9(8K|x3tF^)p#*0u2wh|3rLxiN8e?TD>sl@}onEIHv&rQg z*-t@ZYeRO_K{Wtfe5G+~Ivc|x#_@Ev&byMVB$AaFo4 zMngeFNDA+QP^G0s;A&ZNcrVGu{F^K#{3*$n=D}JZdBrHqd72#k2_C2uk&&wsNey3y zGJGCuJkp3YNV?L6v~ad6O%IUtB&2<>lr{+WgA{Rb1m{Xg5h-~b{*1rz@;5mG8JETL zsstN`XPYL+8Qn8k1I09HOvz-~k^+eRG(N@b8Nit#^v&3sD{V;h_>jb4QJgMbS`eE{$&*?R zr5`3wFe|vZG0RUIk5ZydmS&1w7JZP}q(gjBe{!B5f5kO$-j72Lt6@e;41C{!gtaJ}1V2LYnE6vc#Wh+*%zIp1 zn_MHIz!j1yBnco61u%^=#x`X>-r6wkYs&m=sxc~?HElzsbiX$$3EL3UpoU;_*wak# zQoy^(Nv2ITUTDgiS;gZ_ z!uVzukF%zDoOH9%EFNb~@i=RW$BE);sIqQ@X24cXCYRN4O`xJCFta8wt0pj;0@NgI zVxWh25_RL7@ruljQ1<7$!>aMD%9?noCSu_xC!3Wr+|D?!vIb=vs4Mls!c@erSq0Wv zpfiOsydu*cjR)nmD8`mJh+_liW}|;ImfG`Xc!M^RZ!I!oY|0>x5z0(XtoWuQiBlMh zthp~OB(+-*3k69FRFhWRYE(C4V zWI>$^Htrp{a8FaZW9+= zuy)39XA5YZjNA}QQ)t4EWnljhOUxBvI&032mla%C4h-91GiTbg-Ax72k_tk0qK_MI ztO~I~WmK|QHtdB1)|FXoq=pY%36EY0-@g)`Hk#$K=4t=1WDiu}#x-_I!WWENb1`GS zfOt9Ky~dVY=6BprZ#FFD7<+SB!y?)R5`#f)e~nsy1xLp5i8)+|9iuWMCXaPBFW*E3 zJJDS+V{{&CkQG6O{6)#!?hqTAPFdXGtVqRV$lQ{RQXez6GnM5S_vT~uU1S^tm$fm@V<+`r;-nU^6pGWT06q9(V>n=g)yP}6 z{igJSaUQ&dq@pAxut5w6s4}aKRRvfntTvv+!z(l$_M66d9Ox4K>UQH~0qf7^8@YuT z2|61?3gO98V}2n^VO7S)Le>Z9Y#}SbQln83Yr<|fy3=F0F|CN@B-56H3rViH9NP%!l?PmO1%o-vW ziOpGWg;r1MQe$Fs*2lBDo>gOSbC&I^1S6z{Fdc)TS`>wdmACtS!=HCl&? zk08@Sq9u#{I(!qEs-&8|rrRF21#4Es9&_8yh;7B1I>i1^l$vd{Z^eQQs07mE)H_ga z+9Vhi6H#xJ*S;Z1d(c?aie1}8Y@uP3F};6mh8|h+3maUEMe8M=T4|rV(Ns8?qOqVDNBp4pid<$F;e3M zbFrbdW22bcc)J~IqR>}Rm9ve}?Xmc8Qp#Ggn~m#AQTH9jZKW*rAEvTAS6F(dlnsTY zoc5@GyNo{V*)+s|zCCN1nt<{$t1%5-d9{eE(T2MN%W{jeUHS?XCn#+?u)MrBwL1TZ z0UvoFV0{!?7bn%&*@2CNs|g+1vpgYayxkE?f4A{NM^@%>AW{x(J13~IyE}AZuQImH zuytYG@aWxzjpL~{qfuv;Y#ivqqS^b#hh4C9*2hrFSnI-la4Qf9Xc(~+uk*6<0c=@c zL;`(CXfCE8(O%~qe7=a!pp5BdtW(5Ge)2g~@_v;7_Mano_@eAqK*2GG;Mna}01YV0 ztEll5RfG~m$c_y%Uu`H+gv`W{W*pK~Q|j^5I0ETv8Xnnbk(Hv#U_8|gd#B~ySnpbiPe?YCWH9^4P`b197Nct4 zk=I^v4@^{2e1tbrm|}QwIrA9Y5XFTHY?qafjp5x{MmAla#z9yL4#Mt5(Bq)PDD$4R zLtBCxn+?f*#+L4^LH1HWpA))Hbs2&|#%0jp6UfvJ&RQ5s#zwUNCW>iW5jhn{V{%$x0Dxc~5+UzRh^LCu_l$7~l3} zTWZvwHr4-Qs&DQk)KByh>bBnaeto%7(3@4VXUz!f4ZnrLmL7 zkUngXe&pTi z)&cmUWJ|$P*9_t+73=9?Hy@6G&xyT~dx#ZRf_pPke4M($7}A$z`Zf~N8_bROs+%b2 z@p_C?eOY3O-Rsis1t)<0UniuS5zak`Z+g6!{TQ0?O%Hmo6JB@jRHr74#KTCuy2<#s zFUyFoiy4oDJEb2|B397p#qNu+3m5J)@X=XngtF(02`0$im?q-pBKDBM(zb%&W!;a5 zzu=2nX_OGuQ+L!;chspzX%CR$SZ}OVLPghzAQfssH*aiUn91+pD)iIMA991Z)|)WV zP^(z;{R(6?s7^&eZ=BGdb?HX2UGp9SbtiaYO>5C58&TG{aV6fA4L9>H``c5|c}3kp z?W4`JP#!kWV!*Mh+l+hrvtm)vXbTMzrB-sfKMTc>?_GvstIL7=Wb2HE16UxE1UuM9 zqFtnGketG>iKaaa#VA2JuJ;6R%`{ku3uW8D7O8vim4NxlmfwXLM#zaP*pEOMv`3i% z3^ZV6cwqSt9fPm2$H5g^%N->S4N=zPI=dH_q#qa3vWvSL;^u~_Q;%W#WJ7t!i^4TyXzPvngD@;TW^5gV zJ;?3G>w{Q_rjH}Hp~R>_afSogv}q?Px$R&EW9u`F&|uc6(Q|Oap*;a9I>l7%jqacz zKJ+6eu~vH0xM?uEnSE-U8H^hPpBYLyyC=Q@Y7M%dB3x*ijL|^Ro-%fpvv%&Ci0cV9 z#3Fc?aj_glTW#R0$l}Bd=m%)buu0gVWC4+@p1}6QxC`Im2$)ji|P8>{+a2o{z$g2(eP}WB{77fQ_ zI5ujiaBS{SjL8|s<3m}Mm)=ESSiAA4p>k-56UEwo7#rF;meQeZ*P%Xli8$f+y2U#} zN9Xc-)W%3u3;^hrj-a@_9`R70F^&vl-O-f?hO>-oe6T`WxA+9SIW%fV8-&GhV-D&- zG$=SKf;2PRjqcHj#3(M^jtTm_Zt}wGCg&CpXQ9-dNPIp9Guu2OVjAy@4i?8pVfmWvs{UXGXAMtTaRscpTBe(KvR4 zlj1ux>r*Aj{4KhmD$yt@YOcRUbHLhB7U3mEa3q`3^jY%Q>>Y4DCj&3ku002yRc}p} z_O!8QBx~L6|D`gb7ag|h53W*3@l=1lMEo=;$r1w4acr7^Q*uGh;#+_CFpw4hR_2483+7V{*BMIy~c>KEEw4TZ&LMD zrS)qNV#f129_eZ0oZ1@{NE$cPsU4tD0)^hBP#lF0QpiK0L&lGY?mG;III?+*0(1-f zZ6j|y3$Px6%XUYIM&=K9M2Lk^(C>9JD%lI@qQ$r>lnqxWpVXmGxl-uXz~fz z>JwL$kvNJ|vnU2Gk>m2ul<{mhW<#%yXN?u~Y%XlooF9)P;yfc`0^1tNM`?QG^o&-v zbZo@PH$^-AQxv;X{S2yh=TNuooHi_u$+;ikN*H|ye2Pqb4nkLezreGSICWp~3i+2{ zEuV(*gU<7=;?&qUO*W(sbRyRabu^jk=vUz3l2dIA555xO>KSn9y6|QHO*Ec=4XB+3 zf#@3}ay@IA{m*!GEy|2%uhaeHde&;}x0Hq=(#W}8UQQ;lDB4ilt(wWp+IP@1r|nph zO4tq&2ZoQ=>dD$UXyE%U+*u-%W;{jv&ZwBkS_kVZQgOI(#g7S>>NLRy?;GQzi7YQ7 zGED_LrN|xLOUaxS!7%lRa8$50|hLnCN`z! zwuRc-{e`V8hj9==Wr_h%_&+i*%nF$~p+d754zmPpx$W#qU|62z60#{Yv2GIv0z>~- ze5dw<@!2Gnm{hM$tei|2!L7nJJd;_H-7LnRjo@S!bP#YjwF}0m$t)!528Il(l3o|a zHBc`;q%JycmA=R^P9Y1ZB*ZDDc@X}et4c=J{tFZ41d~g+b0y){qPT4IX04{x2tEGj zpwHoafZ9hCT`oLp#7tqC2_Idhh%KaFjj|~$qm;%^arGsf?!rD&9W1;OcDWKh8AZy* z)+sEhT#cu6U3}kw>!;Mhm*b&TLKU6TC8Nhp*p&RsSbG!8=y{nE{+CY{ zeyA;F(>Sh+{!OaldPDtB7AR#|lVs!aO)RS?K9t41Ui2A_Fprpn!3r{(B~@ghAY{!H zqY*_(v+(Y-@a`+lQ2$RSB=+2zChDlT-MCR>jT1@Vaas8qD(0LL;H>e0#>zV5`&(Bw zou^a(-3`XFsUnFaHGGJRSuOS4`2JR0L5;#w`wYE@oJZHjNTe9ern5X|H-=7UYQzDB zwDIX3M!&mB3B*b&VW6aO2s;r@8lOCR3}i_bP9B{`A{VKpj}D9*1K_YuraohXd@!rl76m% z6miawj7Z{ZxLkZ*lALSYAI3RzEfb$kSf9vQ$Er9YmQ@2U8^6Hfk!95jD^GAF@L3@NR?6#IEv#M!T8V(phW_o5>3E0`Mi8E`x;8FhY$TH75p9CL`V(g&x{# zt4I?0FrJ;s_FVfWOj@UaNlAY31AG`KDzGo-a#!GI+prTB&{FYqh}$Y!8U+Jd1A2sy zAhOmFLAyi6!pjwH!zYg;jW=fD;NeZn8xt&wd#h5#rbx)JSFnT4$b7V;`H=^4;+piy!k-n}vl3o{|0XFv-Y zM{Z_G!$Ob;rz^9*AYqI$lb!)Bm$<`~S@iW6ap@V*a52LbEK_DVDFtxp8PM{Ho2Sg8 z@6d=#&j4;&cf5rqq!mJ_-YfjVHz5o+US^#lJ$!Pp$(Vi%>*p+jMl{x&Um9=R!ZLG< z0X_6oMR>5YYt0QcF=j@ zJmbbWxK*>uI6MbSm1^UsIc$IId$qNRHp#y>_RnR(#$Kw8Gz`($jxTkHsx{1jIp%mP z;cjbVY9&j~Z9{HhE?hI@V0uhQ!}V(#sHuCUX&cUjycPS6U6m|99T&7w84{4gQiN!1 zejYw+Z-9W;e%(AaF|{T|%NnkI<7*0GxV2F=5BCZ?)N&M!!rF6)E^c#~KT>4sLQwQp zz#Mkys*l-tOrx^a5#rjP1FDPQ4*!=*1}~VVuf&%{67^NnY#RB5sqQ~@I~n;A)~vMP zIZ0|f4_9&Uybe{j@wGFlytdq8!GOS*X7 zNpRYaA)TFLNa`D_Ikrjbr=S5z%1vKSQ=}y`i2ufI6h1EKML{n`zKuYCKG6a}`wKcr z(5i@dY!Y<0phxGEiPM7qEI95eirltJt-68ruc9PJRXv@mNb>~UR7DBz5_Gqqhe2J^ zS5>!zw!J;)c9+x-RFQ7Goita2x}?pwlXTnd5qdlaph)rp5;R!wq01$8T0or21qVTw z3c6O%&4NBE=qG}H2kMd>caR;wpe+TRbw~LfinQkrO7hb?-oC>n{dfmyrY?+H=#sKQ zQD)a@5r|tZq=M}$=nV@g!ZblYUP!rgEFv0Mq&ecH#}`#3jF&p!No6qXPSPAB=tM!+ z3%cvhP^S?>Ctg~!xFR85dInUHjx0Xth><>7yuhPK(Mu@q4WKC43OroW9ZSmL<62O^ zG^o{y6u~(EFB>>Elc3 zmHmWpyi~j_Wtm?Zx2)T;cxf)e@zQER9|Tn*((}tG_n!({xSYaoEGLJ4Tdr2QBy|PR z`#}}yl@*lCTY`QsXv|8gE9y#0vI;asdTk{+_W`IPUEB4$l`&HGT?;%hQrTU(cg096 zMR-E$0*_yM^)AX%)ndfbk%n&6>07&dW-k2 zI_dbxdJ*5PB6mMqt+!XC@j6+U0vaRjNT*~r=qFNQq$hML_QOIduhATSDRm7cpA`|0 z0zq2|S}N!u&=_g-8Zt3Ya2^))2q+q-F!7h*IM$LOub?S{W(k@vXbV9*3EEfC5uo2$ zu1{YZp(1@@?Y(Oi>5sLV<2$M0I!W3ln^mmEI(mOY*HI;!Am{=?mw_tMtLv!nTlOIf zw;7c0wFVV?xAmg%1wFdHxz~n<^Jo9RA{lA$n^d9lFAN&YV zBu=vF1f%75g_(y9iWnomFVIIM*__d$S)rkXuUwm z@(DuCr85Gi$)5^g5>DluQbYNa8Bw4N`AdP!+&7ZX>~6Y}b&rnp?At0;QHDFuOXc&+ z%7&+w&tKk;X!l-3SBvll&_e0;erjT&^d2aae(6`4dd>X1`|kmLtpCfYUg?GYo$$k$ z7yFOETeJ;0kNKQwbBgm1*vW20w7~$PjRjQ&&5ak27J`-v+ST}bBM$w>517vzNec#a zV|E({e#Hs_XllAV$$hBJCUN)3jPi~ABsFt2oKcWCYI077)LsJf|dwc zCg?SSUMJ{OL2ni`B4TY2;fDmR7W8F74+{DLXrz4pmjavnoRD#Gn^=`opJ^{vCq8G?iRGB={!<=jW;YvwZBr!t;`k zy}tCZ93MLvSw@d}%U1?{Z1wUs4Sek3<;1byMd3T{&dKw!Nvnvn-#FS5k&O>P{p*Rd zXZ_8seC&yP$lS?$E?{h4HG4i+q#=ulj$PCNB|3FcPE$pCe>Roz=d-DdznQ(ZK#>wx zQ#fsPgdW)fTsMcp1tQ!^(Ds6M6?A~0<$_KWbm3|T^mA{1Bu$Z)t=^ePiS+>I-0b@i zzBv1WTan^#CjPR@&B-MF0-U6IL>tX}FiGf)1<2SiskI^%ZwP~$N?G%|HK+;qnWwZ- zq!EIe()yg=H;~gN-=q)Bt8R-m&_<#=Z&BLpKEH*HQMh~Y?g87_9j?f$bP+&WB^}7# z89#$1V82L`7CDxtBzeLt%|a*B(}0RCbRzqW_zKq6LT9s&0u3^ebRqkA{7iPhLSJNj z33N%ID(Q=iZ{ugNHFt>=lA>KhaCW{cBH-(eXPU-(Ze}l9=oNupve4TC9k7trB*u3$ zJ7S?vniBfZLT8)C1DzCT5t0b_Zec&vqK3ZP7{l0#3__Oet7HjxM+jC)e>KeZRk7EE z@OA0GO^4uK!U+rgDbTeTh9&8B$)o1`7P8?M@~ZK^JJ|#arK+ubi`iL$s-z4x*0YS2 zV1%Z41!@Q1GW(`KQos{Lt=BwDZn5+`&>S@kb zv!6`ls8U-4U9`{>0{v~Fj|5UM>?5Azl0eZGN^eH-5-ikJpj05Fzs{ivm}v<&2-M6% zuLx9Np>G6gWucTDGTPokeFW-ip$dWeSm<7XuC>q+frb-`AbBN7X2x2=Qh_E}C@c_t z_DhaFD9~&ReJoI=g?u5ha)*Vw2(-*XVS!d#=w5;D5h$|G@uGlREa8^|ZL?5ZE*X7F zpjAnM>^InIwjXn+nl`eU9TMn_vwh0==+*3fQ-v@0;x6rQzKA`ay$|#KWJjiaeP>Vtz&`b-JL-r7xYoY0o zJ;WAT$S6$mJj_;D=!wEe8sLK#d~RZyQO~qgOo@B3D=$7JhzNeUt zE)zlXmf~N0J6RVKIqobT9>0qXu#h+XqA#+GRhm%bqMFSS$gJzt>~4Y9Njr)?3Ds;a zex8Kt^Zw%agr}MJRTCX6PD=O>3tH$*al?dX*fkcqP@I*pn=Q8xZ=RFzEc?+yam@=7 zo{O*q+$JZZ4V$-2c%JpJP^fvkgcsN*3$)(8E!hZI& zg;Ld#39qr#H%wW9dVRthtiVFUn@>x4lP$N~Fee>b*@3HB%vLWm}wm_iI*^cJh65eBL z1vXW`3@REgoYyM)w`)uk#k)ZTj^VbqSU?&8sk}fqr=lhU_4w4y?NV&hEY=+8h zU?Cb*kFf^@qTGL!@G)z4n36X~$`h=_LNrpIV4EyNBjpM9fQ4wJ{FFUzAsQ(^WB#|q z_-77|U$AT55_xirY?0*oiVd^Sv=(VV<1DlSvNLRog&u_L46CrvVaUE_b1ZZMvai`4 z7PDeNHHX z`qM&1ko~~qx6N|u0@)ADVzhJtE>kGdA&O_MkwKSEcBZ zA?z3SzJO<#U!cu()m!v2D!6v;&i0Vuz@lW=wKxTS>F~|EPtBOcBBf-B|?~e(tl5Q_)p7<9VX`v-0 zZ4&=xa|NoB)|DJ`F+SnAh$!6$#Q7e97D?MmIwi_{%qPN%7&jGui$IGUC*Y{U=UeFK zk~E+t7AlNy-7nG3S6Q%8Ylhpo8%zYhuT6CD116FRT8~V0^FF(O*u$JGGT{Uzb;h~P zGlVDdsTO*n&BDY)zCa*zi1zbk7NQ~A&+oTT%XUeg0DsIv9owY=y=a&yw+HEp(#P?{CH5x6rxLRDTJ# zeMOp8((k3&{j;U*PY-pZ$T*D(Ttw>-~Ls#~;mjueaafAIMMFqGy1b z|76NOZr{OuEmwaQC?b8^exJXbpEaR$q5Yfwp}gQ1Q}yrmANxn}r!5rQ;dB2;KH-8X zOYV^58O>+bqVN2p`KuOc(%~onSpN8bP0bRZ34HOdChFGVqW=cI#zK*99avy8ANrdq z9NOVb+*BU1&{!lfl|N~rc^zVbKC{pUf#NQj@pgA`2d4757J9iuATW)ewb0=XjRQCF zr+zmzKk6_mdOH8eLSIEXG!M++U(~=3Hh%^8|6!`0?~vr4%^TICc7a>?Pz(Lm!RML7 zpS4g_$3~vHe9fOCo~V|Ue3L+D*w&6y0+swpQ-%q`nYajlu2wS=N{sMJCX}A;IFeWK zwwHt%F$b#RJp?jmJym?TKs4*A3{>%{rY0smi-8tfXhQm3f!q0m7CPE-U0?xE_{+@F z(Targg^c_MJ1G#u#}$=2#b+UNuFi= zw1wt%N(1`SLMtI#j@wQQ@fJDOK(?HxSm+_hR`5&X$X4j@E9z1i6d_=FIiVefZNO4`H^2((T* z-?>TBy|@)Xu9>;t%sUFSPU2m1lJ4UP3dvSUX6%4oZ56 zcQG}^`syJ*z>-DsCqVYBC0o~J3eW)Y3#XWAbjkNT%;yoJPI!Bl8A;ptqn2<&`h~bh z`2h<(*(J&I7$52;XVyu_y39*@j1RZapH1Ij+xbijorG*VH)_#>q{sO_fy@j(!Cw}L zYC>${6Z{>4A_P|_?ck>cq;0I#Nl)=X*k?uVr3c*o5_j>(E!3!N2;0Sv2~;KJ3gn0( zO>+{ni^o}rCNaBsQw!0YqMGLmWX>t7d5I~Dh)KoMyrZQ`lZvN#Pk}J)%6=&MKl~aC zoz313G|56rj|oZ7@aY!v^-$f<@H;J((PLNgZhn`Aa(g@r^st56^f;XOEZ3RNN3k~dXDES5cmxU(wcn3&{6=mqS z4YEBv#zHG0+rt9_opFwdU>5TtPq!dVjb6k*1#1>5&3^Xs0t?aXXD@GUA(}PqGCVr9<@ap(CY3#|qEf$y=(asdRJiQjZkm8gbjZDpLT@IvpQ^J9}M-i;)*MG6ziQ z*p8xx5tMc!oTm5C%+`NrP~WsR|UE*hqd*pepIh-m!_9@+E;*N#FOLme5%4 zm`w?;l70uuk_TDH*=Jfp6M2t7>!j`_&eUvKZE9-zAyeg}s)?HPai-$ZEdJ(8#;2l1>JsUU?QsCWbf6-7%W zmj^^pP*G%y;(^rEG|RHcv{K(nNh>u?P0P%*c(c-?lA`>dd1lnz>HXgCzrKs>x_R#V zdFHTY&CHs$_S&``M}1|!;%#bU2iv*=0)L{s3Qx8_JkLa zUWnqMqBoDb-=r@L9pm|zOY`TgwjW2$O?RIcimRg%aZXs zoz?UU$sQlBGp?pLB`Y3&qw{LodM|Q#j=Gw*3kIj6BSel(;>FkLzZ&juG}FnFX=%~x z?ag$mq~oGD0h=w^L#a{5b+lG8pVa=qJo{iaBr3JN%R2h1WPO3v)6l-cH#GH#{d!s@ z*~HYL#*H+#pYY92%`k4EuyYBo45`#o#~7ccod*e8pE}XFmAXo{GqupTo%WDyf9g!* z4jLfYk<_`yT{Kd%_fr=dchf}4E~i!)pQD2%`zCdj@p-yaGLlwj+(!@JXWAy?%QSYd zDBeD;y~}HKzht3l-Q5n-+GOGD1HRX(%Migvqz!g^gRYZoM%r`6!}Q5Vgl|dO7Q27Z zuOwTY_KNW>+CN438qN!E45dE@)EVwms+j5uTbfY#n;myM^W({SM%IHJ9ac82Cj znhx|sdRVe?BR)5trG``yS~B7*<2hO)+3FGB8b6}?G~wGk;*RkGEs<;wm<7l z>As^|Bx{Fs-_c!?IgWHO+@kv=^BHLb_WDRo9DV%ALg(A`ZRvb`WHGS!B`Y3zqx1Ll zBgv{pRy%%AuSm9I^A8F_KBkhnW zAELC6bO7ogosOAyjz7_dB@4`S0OldtfXoc_XBr^c$jl|qKhqe=reqeo-=Rs8&C7fO z*kH+)XFli9Mu$tbHS-DQHkt_x*MtW%=ez$xbEWfCW*M+2CA*%v-2GR&K(afTb-*el z(`R)u{7P3z)-}r!SiNMCSs7|OZIo`8F`M$b#vJ$v%K|cd2!jXwuKK3Y`h-B-x#;Vqh+k*^SCj71m8M?@>#f z6&8a`E7$iLRp_j;B;ju_{Y$dXosGawBCFFslHF77z&@00Z1#MY4(zgsbkX>|iVX|R=8d=z zZ^mrcsvK-mGAnzZyA9Ki7VJX5*W3;4vSgKx@3?njg=2(oPWF55o!MuS@lS#s*;kS+ z$iCq2$etW0A{S(T?(WQPjpuA3snD{!8(i4ViGps({?6T%HB1)l+3a?AH+C~mumix{ z+3*6vnt_?vWy#J1>&|*l5xyJQR$V>Vog&WQZLFN`U47Wise-xY4CxxoQl^PW{~Rr^ zYd9mtg7(k3;2zChogvuBoOxYiSw#tF<-`|m`QzCI$qI6AI>xi!vxM)doQkdqjLa5n zdCsb?iR?3EHDqJXhOWI>?Gqx;7jrrpdb4%N%1Lw1F0E^CHhd0u!W~b}3tjuL(s?4A z-*Rqr?#IrS3f5^fXE&e1NO9A_*nH0F^i^ZO>)MZbA}iO|kA2Re9~%p-8;q?F$NmDo zIg;H3)}Pg4q_|Dh2C!CY6jHtj?_wIvJ{O_b5eKtd zl4&8`!8fu@6j+qY*?!69<^}+JU$PWaB(PieS)3`Er7RKYQcMF(L)Z(FRp$;fJ;Jn$ zlCH^p%#^~M%0*~>ZnkMCTPoSq$jPSRY^P)sOhu+t)-2i6xz&zo?1E&wb7z`Hu-c^} zmzQ$qnjT|C6@nefU1Z8&RmkedJGoV+k?fQv>8ad$QzmPdEOz`ByDXMn$rIL*!Q(gd z7{zu-mNkAWu;a)?b7!-&$jbE-$GaG^*=5OQk2eDQL9$ijI~j7=uaZ48-VqpEhG)B6 z|2{ZJGs7~hss1WBM>A*1I!x$f7{lBpGfi*=<}KL}@Qr1`l8pu5SQaB$Irwr}l4NG^ z<+8z&9RS}rHhh`9{+$5lIF>1$--2^I%ax2wbOcr)na9LVh6!wjWKrOoz~)Jo1HOrD zv1BFSo5-pp+W@{vtX8r;;G4uY0>kUyI}@MnF_~?b&WjUY0Jc}M-yvZhdqpz)NshqY zlx)DHPKJDTOtQ(~%V(z~TRZ7sj{!%NJ&Fvjf2;F2ee8b1FClb>4CQY$O=sGDUxqTBtwtus?{u~e86UpC_L$CI zl}roS=02TutH#Q}hbCuir?a7w@yBt+tUxdgK0^7u^9%;RFou%}f8n$#}jOeWFO^qb$F7ol@E@04s$_PM_TjzJm#=hCHpNe)MGB|y^2TH5q-X& z$2|6|WSV1ss7EQgCTX|)7>}pe_mYJIo6ks%NH{n@(L-b1B+CNd0+ub=$cF3cO zT|in+<`ul-v4Ztq%R|fI)5^!}S2CA6tT%bK;FQNIHr6cI>jmdMYFN8uX9_;`Sj~p7 zyO-{|#~OBAFzkqHS-W8PY;Y}O^%$w|HN~hI)-pFqQ>VBX>X?UQqo){w#Yq-11U}_t zeI=U%J~PXd%si#D=Q@@v+0H2s0V|N~-6`&#^=yV@m!^0Cn}-a?kG-~@RR|}!3B|8x zMvB z>|??7lL}o78#VU1q_YZ*hK;OEven?+#9)6dek$~v!MBOI2!`2gX0i9#@0~ZZ<;ZR* zeZBj7HnP_x(?XIxpJwlhNWEIr$?!BgBbi;1BQWifqz@O3^xVp>NfuT#8rV(A1{b*) zwy{>pvWtwsIyQ)^O)r}0xt+lq##qsXMOhBpSvSG3qTAU3!NiBGEFBqd{1;ufvkT#p z_Vu0y*%WUSO`2kw?fDF=maIDWDbF43Rmq+f{}*R)wX+B_P<3guK;_FC5!h@Fmf+Tmv5tV zSyOGhm;E5tv@W(9ESsNa?Q)5GyMC7K^X%qWQTw~~)wVCNu@jJCHv3qfU}VtxS+@IF zXI$@=lkD}?wl6Zzf(MZ=u|UB{8AQIsUbOJ-XRk@$?)BO%+x;w0tVXejm)Uf|h`OQL z_GMNm)~4utg_X#aYT$-hwy&^Tk_~{!Cf1?!LGiCLC&9={hy9q(tcl2i8_rJV*pf1C$vQY52MlpkP?5?xdPv=LOlWPN6^jy zq$C%WfaT`g=+u&GQdBDr!e)n9GxK@c?K ze++#P`On$?=a?j{+z>!UGDKM#{8Ndj^(Y}(C7G3Y}L+?d$FT9NOr;P4-d!Se3_Q0lCJo`f`Zyu@1Im;ijOTfef04aGCkdcw7 zTb|LesBnahUeM<8D&c7<7;xqv$I6re&D0;)vh$zvGC=rG2LXd*~tDvEzlfI=SF z_X-n=Wsw`P7)zz`Pl|%Y!#9udL_CjPX=^|zc@d=}fGYWe8@=!U$xDe)EYI|RKFWV? z3F!a#nt}&e<9X8m;XGZ%;#&}ZLR4n(h81X!_CtuS7Pg4=0YxPds6VhNNkZk38PNY> zUuYy5h?W_N?53b@*#rKwJqzRKB9;QGWHBHmYf$0CRl)g2A&sCw|KEcSPJ~U#E2tbr ztn~dFa@PL0bSRc@7nBtI~cAZN8AAEiV1+bf_h0PC!k_=SD z^flJPD_+7^3*{Ip9{|Ea^u7(Z8K{Uz$P`Gge zREhJSY)U*)xxjC@?z#C93!9SO=oVRzMmrBsC1Mm5pgk9LK7S}UizsA0jt((rEXEjN zTk6%AssZsI`~O}{EH1BNDZx>Ny&rfxy@ZM1w7~z||KG*PGl&mzQ^=(!as4ACAW*=k z7<2zV{{l}^v${yN5pnd3KJ7fS5r@&uMW zoG&gE`G`f>-5>^LK#c5*_y{VGqy3+~q9<`wNe;#fyJ8Nkf2fp1NBbuf9dI%x79CJ1 zVi`FD^`{WUrCHegVT?k=n$fbKiHU3JT)h9S!(@$!dl2{k1;y=>c;Y3zZ$gYpU~$%s zKXl~9{At174duV;e^9gsYkQu>$GCbIcz^wa8S#bJS94+5kz0U#w`jQ4CY=Cv#CaZ1 zdp{oRuBeDA`hg7-8Y=03MvZVuCD|5^T(o&&*aHfWG7lB8teE;2+cHye8_L(a3K97{ z@T#QLq7-qWH4#(+4wbA#_d2wn7B-&0ZKym4NXg59j2r>fk@o==@)@8?uA}{p1%8jV zD2CfAJS*Xs-4x43EPv>D@42N~%Ci#>4a5@L78G%tL5W!Bxco)&K*b*r?u%g!$Yi8g zeEwDcW1hJF|7)h=rYQomjsa9iq6PAcii%4QcuWC0BdLHol7lg#pNkv>P6k~i#ekH| z!I%Z`Q=lqYUJCOcJZwd2JqB$-dp}~2VjgtB!aitW|2O*U7%%$7VGH|RuqpWn5Pr|? z%HKM;uEH_hxbIcS&tSvDSyYs#9-J&&wE5|~_n^i3zE_-3nEz1`C{D47D;nMossst1 zdxiL7sK5}k-?@hQaRfGVj$dn4j@#Jz~3;FrOsg5U?9_kTjr=UIRp3R^C+$Vo)7hnROjAA4_I>yVZ z(2G&$UWQ(Hm<6^KSp;bPhsa8dj%eiZy8d9iN#T_2OE}}h+7fG z!u3V84 zBM=i2`y=v2$GzvoqFS0|?f!3Vu}a|A5tZ;;FiM7CB`jAM-)gw7%|eGrFbV8?w-93a zAO@S5%f!QqzuH16!hD1+W=~;1iModP$Ah$xmV&L4YCuZrQ5P3qVK<;69xm=edk>;` zvciNP+zJ^xoO! zUGnd2%NTC=ycZ-Ke|G=TD>9Wa=4*<2OsO^RR@D)(t^QqAb+dkB;TAiEo;7!;YL}j^ z3mxGuM8633H&GoIt+$&)OpA;LdunSl&1()ByJ$Ax^hHm3xuWfgwjW)$sKQ)KRcGy; zMb%zy>PL%?*oP6mbrSYawSzA4|?T;atxH07P}Z0k~bEQQrgtM-seC$3AQVI)Atj|XDdWj(tX)Ow%E0) zpDjM;RfC1~A#pvk9QqLcPG%)l%I3ojjaS)i2n{Ry35pz2*6y{B@|SSxX=Rzwu#41{ z4Rzjy@w_S-N-o`5mZP?k7s|StbD8Q6`|oQ^b#@!IB*WXDl$v-ueY9wXcOTs4u8k&| zR+^vZ0osyzj_vSunn+WnvV2J=Lndq}lcAi3BfD(A0s)$T`OlDw@3#lFEVuJ!g?cv_T4ml_Rzls7>bQ5G#ta%{%xwy7(Y zYAL?SY~#{#j>+s9#G^}7K{*HZ5#`F#kzltj9qrq!v@f0HTMEUm_AP_rcLMU}EX9nP z39UE}US7pgCB<~qr&NJ6<;~B@LHkPDwW5RDRcP`IlZWLCFiiODm&yzX=urvVDv`*_PJn|DGXeduDwXUfx1MSZE3Mq-SHmWlw)xewOOY@5 zH8O39i=kPW=9T5ptUOcsieH<$ukw%|Z-S%X<%his-hI68cYyH&-pA}sU;8C1-$2gE zO4{QO-|;)bIxbWEIS#Yq=#2JQyUQf);W&TZDg*tSS)%Ef(#$G{%y&7>5|+*MuViV< z%Kcl|J{UbM?8#--{*|<1nZfBaTf1zg`JlDx?swe3O5yvkRY4<1nyM7r<(u8B6#g=3 z750o;>>0JnaXV&#y|5uk~oakZl-}tnk*{27xhp)kC|z9EPXvF67on zXIpi`rjO34ird}L_N|%_&_~y|YDz$|F0HCKV2|=zRVTw9=vDI^_do}TH0?)aKPr{% zeAVHARNeKecLMgKw@v-N%EgeW;~gMVr>}Md+pXFN7+-xdAXE2fD z)OoD14Lk&uIOi#xQ5%@7%UY4;kgO{LY$nTAycAfkt6%YYU>NqTM&jHt1Asb2Z-CsR~-(J?R~N)z`wWpWH}swCQ1Uw@RfrB^Ev7k ztV{`N)|pqP1zlAdS7w2oXgclMtlPJ8EX3es2C0;er*#Kc&I)S9;?H8$FJskP35*P% z%W$UsY*csp%gX1>$zUX3hFOnq!8QjD{Id5Ph0lP+3UA*zh;2HbRcC_u!CnX|RsvSt z=v=Ju{ilkR=v7$`bCgiuYS<=n)RLdg&)cYO&WBd$gF9I9Gu)`GTa^&prcRCQXTD;i zc5y%M{{_wrUtr^Yfpxoyb-M|*a_p#jX+gg2Fo4enw_^xX`J~BIKGND1d((0McID~Z z&F=Ned#gGb>XmDVy#4DH-v0H9TJv*Iy~6jNt5R7P5zG3_-3|!8JbxH8e{iEg&I;uVzuT3+lsnJ4= zDj&cGmGAMv6po%MKW0yLZ_VY9Kxto!bPkQgV+ce&5|1Q7<+DY9h?!=apdQH`9h#u> zV{23I)Z~XUg}>m<;P~TA&E(W-EhItZbA5`cWkK;Nn8iLgSBFD+)1D9Ar`%lK+S#78 zuD${p@#!D|i|1J{G8t6F7Y?aR>6R_qJ z)aB;82DOXE=kXGi_n{I9I_guXa-|TJLR8vxpY)p=&aV?Q!`pPBYo>;ms(gYdRrv&w z4ExV+c28FNAU@xR+aDk%uYm!iq#?o}0Gp42GE7^BX-idj$1T#-re>{a?abTh!|-IQ zxoa+lm%+hs{cPVK9PP>CHNS-?D||1RWQFe`ldLRXV-t~S#WT&c;+gX6W9NuuW!suA zfG@6bkI1*;6JWm8!8L<}imkXe-|E9P@G7;{WyCKLe_W$=GVm+82P7L*3lqQ9^xDA@ zyR25#4vko7wXZfE@GvNqXjh_Lk1@H**R_QaRd~{?u+PCJhdRB1!KkWsOi=mQ zYEv6~TSYZsbsMm{4Om^R0qeUB>$?r>+ko|LP#x-uObuA;2CQ|18d#SbwFi>Tj@pl% zXg|hhTF2FGjmos{TbH9YDnskuh&m$HbXe(J>oy0aV=nv*^u?%RYkpGr!V=!jwl>#Y ziJGHX^HDR$nqS6>t)HoLG4QpUE}AdC_)=?sozbumGBO$}b-&g*L{~C9b9GG9DN8I?GO&vLpYEQVSBuVZSWSh z!69tYlM?x4aS~IVRQ2mzV@_flw?V28!`swO>k?x6==|3W1B}+zO$lg(!XA(5piWrl zZ?uOjTAj~gMvcncb#Fv9D&^~33}><6M#T)uK8SC1K7h!NwKV3c^6k3u&R3OI#9t6e z{do9Q1FL#iHxhfqfcn)jVPs(ax|n8Y?@cimt>czz*LqyEzHPeJgEwG;T^N~Fzb)pf z_1rZRjed0QnnGh3o4aPFu_xeMV;{hU#%3~iO@)yc{I8fcb!B~X3~%1|!ERmZV%Vo7 z)qEP$hn?;FMNBd-QhDSLj&16Ode`Wy)_mE@N8FHDzTg_w8~#l&ZI4yxGxY~!FGC}D zF@1pzn+};~D20dyZ16zvI)~mwFT-p2O_;@w*sG4(QJ+@z@cKwot9pDrTv{k!i8IPq zC*Jl#itS|X| zl%T*~WLXZ1eg$A9`v&w%Mj9?Br0Tjfe3sBb@6nLu&_N&6a0Bclw3E>ug?1ibzHUat zzZ3FxWev9yYIG|b>>TrTX4H2e?nUK2#A_P7+71&$>&RrGZn^tGj z6jMN?sSw*OoAL|d1dt+4*^sP@sT4yeV7pC#b8*(($q8;HcmqzLoz|TVoq?bTh+=T1Ms48>2sc9SF6yEdKZ<)?pT6Kw9}r$4fZ z??pQ(_Drw+*usafsSaUHla+DN?n!>iX-Jl^d=jAt?stDcaj3Ndp{;w3EDg`>7p)fv-wqL)zdx5 z_c9i98H+iK=k6??)3fyHrZ#7Fp0(Dkn;j{%$p@Tnvl_6(<}~1wHV)nGNU2Q@-~yZd z-8+&pn=iqxu(<_TW%DcGDjP!&J5p=o4!F+d6DvE?fch32Pf)hmgaGcei3HqZGXU@f zoAMrd(ygPrtsM#MnB$=*{X70>{=r@K(@J^=lda?_zzA|MDVVGwQ^1ZVC&2DUMg|9y zM@TE!BhWjF=)pT4^_htCNCYU$Nlx#r>ep7!`zO;!tbZZ-bOYcny45-{U>DtOJv^Wp z^{qM{^O^3F`U^?6f*6hDTkW;Jgb^-Jka?OsX>eq?e;}Ojdo7DbEJWaDB zuX2kcw_DKe;Kc0?PF(ksh`FPkk66iL%o|Ox5a+ID6R$)I;HQZlx^eUagbJaZk64Mg z3-xBi7F7JYVqk19t=- z3A_^cW#A8i?Sb||U4ps>1qVe1GLLLc84;de_D&*;q9U*%| zz6$w0#5XiKbZTg0=<(3&q5ls3DfIWyu3?E`sbSN@o(S6z_EOkuVW+~r4eJ^{Jp9S< z_2E0ho5F8|(}>`RtcY0=4G}LzoQSv^Q4~2da&hF!$i~Q*B45`cO;M3i*-^`*8lrYZ zJsz+*E}@o?g)#0!b7iH^P8d&Tw2>9wNQ zC%ta=>W~zX^k~w!q@tu}lN{g?bOAgUCnU}YpYy^G6gk5$#=s9W5w*$BL!GD7ydV9| zo{+KL@)hcu8^CC**!A46oN8F^Q_0C zJsa(Ev^S3C#T*;-_``(kN9FC&gB%IDfcVX5Ug`GHZ$ftZF$*D|DXwpWZ5(p~u+;S< zz<@El;KVUJav0)xRA!CQxKuWV7hi{tXVHFp3~!HfV|XzQu2&$7N*8{VUyR{+8x!ls z@=Uk8@Jc(3O$2>FZU++~Lvwj04)x=ewx7(sT_^L%P{bs}RK)R&1hdh{Auz9P&(%Eto!%>1nhbGZvjQaZqMU|i4*#D!8aa+{8aD*Af56X zV23F@RdfnR@7NYY2AsJeoJ16cc@omQFa~f>Ay=9Z%|$%B%|&IPzgWceqeaWW{-CJb zK~K!kw>pz`fGWHNLc#WDjOdA9)6f3uCsx`xTB)dHDqRjZjaCEBpeq4q(i*@Lx(09| zT?@E~ngJJ6cnm|z=mx+gbR*zWx>4{~PfpJrBy)h~LnQ zpnpp*!Y>PwTl5k*z5`Uq_w*C6ZzKLduYl4DsFEM)Rj_|TyhGt*CGs<%LVlsw!EQtR zm3|3IJ0N`Lg|-0xPQM1cOTPh~Fpetw4ip8EvfJ>>f`q|8g;=p4z@bC*VLyWH%YFt7 zXKmnpl>G{J3gS@q8z{p7RWh921v?dS1XEO%q#>p=s>1KbA!aZg=#K*`B$HW#JrXes ze(D-N+Z_e};N2e95!^Y5W0)-{qY=llPN3%^j%W6uj{{W5MCJ(g1jI?q8I;M0`K$}* zd58tf74#{9Dk)@cfHRmo;7n!$EMeUNwb{%Af>tpvAS(eCvYPpTU4yuW`GHc4SjPfD zUyHbf1%ciOsFJ5y2-sTzRkDqRfxR7Z2a5pZ8N{6|3iMroDtU>;fW043B`<5NCy-YF zRrpcic(4xvs^oQ+2=*I*FoakV*oOgO2(dnZM_E5Lj66xiIWw) zazNezoI>*8C+DY=TY%^5TIy7@4RIiDqz4IrYZJ}>$l^ts{losX5Tw{MJZrSB%+1O8w8>jJt4JR8sy@Iyd&V9&tC zLCb>jgNuV-34S~HWN_b*tdON4ABGr0O`)lw8KLV#Z-ga<4+79=$?(P3d)~7fJF=3P`F?YBcYTR!8;8+d#-ob@(MhzEMAm zhM}eEV-)h8dORM+m%1uRA-C1(88E)oCjoy@*#i8?9WJ!b_J*-Ro;DAPQJ+xWH@_L9 z)_4TzFX{O^5Fzq^1pE)wcZ>_vyT*m2y zlKi5H{qtuu?OvjeQaXa3KCx)}@Z6HTCf!oiH^wufZ@<0+`bYN<8W`CxGAJ@SYCuqI z?7*m?etkpxghxikMuqi{YD#@Wy~~uIO{xD<=di@d6HCSno;D+Y?zE{TxrJ#HXHF}e zRgyn#D&daDC(bCzAO8n=#Ke*ZK~2raRBJ_Pc6V1sVsLz`}Kdp8(KXgiUghc+Q)b7e8bIK`oyAosm{*-!)P6`S$ zZ#k~I)tyltAV0@5>Qr6Rg7fO3?gra%5=_ELC}3Dq|2FuQ*si9Lq(2!%#*j4f7#T{^ zNiunq3;^CAthAcMQ_nR`*HP7Samdl@VZS1W9EU}pG@TBoFX@^p zVrf5HCCq$s0PPw0cK@Q`aLyrP0z-h1of9e9If#<95&cIvggIMZjd-Zf-scl*Kfdd* z-W)lQ4tI#0BzH-K=%L*1R@40<+ItdhY8ps0l)6E5f!S^_UC=?)7wX+)9?Y+NVNFRx o=w$eB-th>Hw+-WsL!wC({6(6-dxW~GW22kwQ|Na}O{n$%1BJ1_BLDyZ delta 53390 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 diff --git a/Docs/Chm/help/base/cmdline.html b/Docs/Chm/help/base/cmdline.html index 1c16d89..fa5e78a 100644 --- a/Docs/Chm/help/base/cmdline.html +++ b/Docs/Chm/help/base/cmdline.html @@ -64,8 +64,8 @@ security reasons (the operating system allows reading the command line options of other applications).

-

When passing the -pw-stdin option, KeePass ≥ 1.24 and ≥ 2.20 -read the password from the StdIn stream.

+

When passing the -pw-stdin option, KeePass +reads the password from the StdIn stream.

Key file. For supplying the key file location, the -keyfile: switch diff --git a/Docs/History.txt b/Docs/History.txt index 56e5a9d..61575d6 100644 --- a/Docs/History.txt +++ b/Docs/History.txt @@ -1,3 +1,25 @@ +2012-10-04: 2.20.1 +- Improved support for images with DPI resolutions different + from the DPI resolution of the display device +- {GOOGLECHROME} placeholder: updated detection code to also + support the latest versions of Chrome +- The option to lock on remote control mode changes now + additionally watches for remote connects and disconnects +- Improved Windows registry accesses +- Improved behavior when the user deletes the system temporary + directory +- On Unix-like systems, KeePass now stores most of its + temporary files in a private temporary directory (preferably + in $XDG_RUNTIME_DIR) +- Added detection support for the following web browsers on + Unix-like systems: Rekonq, Midori and Dooble +- KeePass does not try to set the WM_CLASS property on Mac OS X + systems anymore +- Modified some icons to work around unsupported PNG + transparency keys in Mono +- Various code optimizations +- Minor other improvements + 2012-09-08: 2.20 - Header data in KDBX files is now authenticated (to prevent silent data corruption attacks; thanks to P. Gasti and K. B. diff --git a/Ext/DeprecatedSources/AppConfigEx.cs b/Ext/DeprecatedSources/AppConfigEx.cs deleted file mode 100644 index 7d29452..0000000 --- a/Ext/DeprecatedSources/AppConfigEx.cs +++ /dev/null @@ -1,632 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2009 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if KeePassLibSD -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Xml; -using System.Reflection; -using System.Diagnostics; - -using KeePassLib; - -#if KeePassLibSD -using KeePassLibSD; -#endif - -namespace KeePassLib.Utility -{ - ///

- /// Implements a cascading configuration class (singleton). Application settings - /// are first tried to be loaded from the global configuration file. If the - /// requested configuration key isn't found, it is loaded from the user - /// configuration file (stored in the user directory). - /// - public static class AppConfigEx - { - private static SortedDictionary m_cfgCurrent = - new SortedDictionary(); - - private static bool m_bModified = false; - - private static string m_strGlobalConfigFile = null; - private static string m_strUserConfigFile = null; - private static string m_strCreateDir = null; - - private static string m_strBaseName = null; - - private const string RootElementName = "Configuration"; - private const string ConfigItemElement = "Item"; - private const string ConfigItemName = "Name"; - private const string ConfigItemValue = "Value"; - - private const string ValTrue = "True"; - private const string ValFalse = "False"; - - /// - /// Get/set the base name for the configuration. If this property is - /// null, the class constructs names based on the current - /// assembly and the product name. - /// - public static string BaseName - { - get { return m_strBaseName; } - - set - { - m_strBaseName = value; - - m_strGlobalConfigFile = null; // Invalidate paths - m_strUserConfigFile = null; - m_strCreateDir = null; - } - } - - /// - /// Load configuration. This method will load configuration information - /// from several different files (global configuration file in application - /// directory, configuration file in user directory, etc.) and mix them - /// into one in-memory configuration pool. - /// Base name for the configuration files and - /// directories. For example, this could be "KeePass". - /// - public static void Load() - { - GetConfigPaths(); - - SortedDictionary dictGlobal; - LoadFile(m_strGlobalConfigFile, out dictGlobal); - Debug.Assert(dictGlobal != null); - - SortedDictionary dictUser; - LoadFile(m_strUserConfigFile, out dictUser); - Debug.Assert(dictUser != null); - - // Combine global and user options. Global options override user options. - m_cfgCurrent = dictGlobal; - foreach(KeyValuePair kvp in dictUser) - { - if(!m_cfgCurrent.ContainsKey(kvp.Key)) - m_cfgCurrent[kvp.Key] = kvp.Value; - } - - m_bModified = false; - } - - private static void GetConfigPaths() - { - if(m_strGlobalConfigFile == null) - { - Assembly asm = Assembly.GetExecutingAssembly(); - Debug.Assert(asm != null); if(asm == null) return; - -#if !KeePassLibSD - string strFile = null; - - try { strFile = asm.Location; } - catch(Exception) { } - - if((strFile == null) || (strFile.Length == 0)) - strFile = UrlUtil.FileUrlToPath(asm.GetName().CodeBase); -#else - string strFile = UrlUtil.FileUrlToPath(asm.GetName().CodeBase); -#endif - Debug.Assert(strFile != null); if(strFile == null) return; - - if((m_strBaseName == null) || (m_strBaseName.Length == 0)) - { - // Remove assembly extension - if(strFile.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) - strFile = strFile.Substring(0, strFile.Length - 4); - else if(strFile.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) - strFile = strFile.Substring(0, strFile.Length - 4); - } - else // Base name != null - { - strFile = UrlUtil.GetFileDirectory(strFile, true) + m_strBaseName; - } - - m_strGlobalConfigFile = strFile + ".config.xml"; - } - - if(m_strUserConfigFile == null) - { - string strBaseDirName = PwDefs.ShortProductName; - if((m_strBaseName != null) && (m_strBaseName.Length > 0)) - strBaseDirName = m_strBaseName; - - string strUserDir; - try - { - strUserDir = Environment.GetFolderPath( - Environment.SpecialFolder.ApplicationData); - } - catch(Exception) - { - strUserDir = UrlUtil.GetFileDirectory(UrlUtil.FileUrlToPath( - Assembly.GetExecutingAssembly().GetName().CodeBase), true); - } - - if((!strUserDir.EndsWith(new string(Path.DirectorySeparatorChar, 1))) && - (!strUserDir.EndsWith("\\")) && (!strUserDir.EndsWith("/"))) - { - strUserDir += new string(Path.DirectorySeparatorChar, 1); - } - - m_strCreateDir = strUserDir + strBaseDirName; - m_strUserConfigFile = m_strCreateDir + Path.DirectorySeparatorChar + - strBaseDirName + ".config.xml"; - } - } - - private static void EnsureAppDataDirAvailable() - { - Debug.Assert(m_strCreateDir != null); - if(m_strCreateDir == null) return; - - if(!Directory.Exists(m_strCreateDir)) - { - try { Directory.CreateDirectory(m_strCreateDir); } - catch(Exception) { Debug.Assert(false); } - } - } - - private static bool LoadFile(string strFile, out SortedDictionary vConfig) - { - XmlDocument doc = new XmlDocument(); - XmlNode xmlField; - string strValue; - - vConfig = new SortedDictionary(); - - try { doc.Load(strFile); } - catch(Exception) { return false; } - - XmlElement el = doc.DocumentElement; - if(el == null) return false; - if(el.Name != RootElementName) return false; - if(el.ChildNodes.Count <= 0) return true; - - foreach(XmlNode xmlChild in el.ChildNodes) - { - Debug.Assert(xmlChild != null); if(xmlChild == null) continue; - - xmlField = xmlChild.Attributes.GetNamedItem(ConfigItemName); - if(xmlField == null) continue; - - strValue = xmlChild.InnerText; - if(strValue != null) vConfig[xmlField.Value] = strValue; - else vConfig[xmlField.Value] = string.Empty; - } - - return true; - } - - /// - /// Save the current configuration to files. File cascading is - /// handled by this function. This function first tries to write - /// to the global configuration file, if this fails it tries the - /// configuration file in the user's application directory. - /// - /// Returns true, if the configuration was saved - /// successfully, false otherwise. - public static bool Save() - { - if(m_bModified == false) return true; - - GetConfigPaths(); - - if(SaveFile(m_strGlobalConfigFile)) return true; - - EnsureAppDataDirAvailable(); - if(SaveFile(m_strUserConfigFile)) return true; - - return false; - } - - private static bool SaveFile(string strFile) - { - if(strFile == null) return false; - - XmlTextWriter xtw; - try { xtw = new XmlTextWriter(strFile, Encoding.UTF8); } - catch(Exception) { return false; } - Debug.Assert(xtw != null); if(xtw == null) return false; - - xtw.WriteStartDocument(); - xtw.WriteWhitespace("\r\n"); - xtw.WriteStartElement(RootElementName); - xtw.WriteWhitespace("\r\n"); - - Debug.Assert(m_cfgCurrent != null); - foreach(KeyValuePair kvp in m_cfgCurrent) - { - xtw.WriteWhitespace("\t"); - xtw.WriteStartElement(ConfigItemElement); - xtw.WriteAttributeString(ConfigItemName, kvp.Key); - - // xtw.WriteAttributeString(ConfigItemValue, kvp.Value); - xtw.WriteString(kvp.Value); - - xtw.WriteEndElement(); - xtw.WriteWhitespace("\r\n"); - } - - xtw.WriteEndElement(); - xtw.WriteWhitespace("\r\n"); - xtw.WriteEndDocument(); - xtw.Close(); - - return true; - } - - /// - /// Get the status of the global configuration file. - /// - /// Returns true if you can write to the - /// global configuration file. - public static bool HasWriteAccessToGlobal() - { - GetConfigPaths(); - - StreamWriter sw = null; - try { sw = File.AppendText(m_strGlobalConfigFile); } - catch(Exception) { } - - if(sw != null) - { - sw.Close(); - return true; - } - - return false; - } - - /// - /// Get a configuration string. - /// - /// Name of the configuration item. - /// Configuration item value. Returns an empty string ("") if - /// the named item could not be found. - /// Thrown if - /// is null. - public static string GetValue(string strField) - { - Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException(); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) return str; - - return string.Empty; - } - - /// - /// Get a configuration string. - /// - /// Name of the configuration item. - /// Default string to return if the named item - /// doesn't exist. May be null. - /// Configuration item value. Returns - /// if the configuration item doesn't exist. - public static string GetValue(string strField, string strDefault) - { - Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException(); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) return str; - - return strDefault; - } - - /// - /// Get a configuration string. - /// - /// Key/value pair. Key = field name, value = default - /// value to return if the key isn't found. - /// Configuration item value or the default value. - public static string GetValue(KeyValuePair kvp) - { - string str; - if(m_cfgCurrent.TryGetValue(kvp.Key, out str)) return str; - - return kvp.Value; - } - - /// - /// Set a configuration item's value. The item is created if it doesn't - /// exist yet. It is overwritten if it exists already. - /// - /// Name of the configuration entry. - /// Value of the configuration entry. - /// Thrown if one of - /// the parameters is null. - public static void SetValue(string strField, string strValue) - { - Debug.Assert(strField != null); // Exception will be thrown by GetValue - Debug.Assert(strValue != null); if(strValue == null) throw new ArgumentNullException(); - - string strExisting = GetValue(strField, null); - - if(strExisting == null) // Key doesn't exist yet - { - m_cfgCurrent[strField] = strValue; - m_bModified = true; - } - else // strExisting != null, i.e. key exists already - { - if(!strValue.Equals(strExisting)) - { - m_cfgCurrent[strField] = strValue; - m_bModified = true; - } - } - } - - public static void SetValue(KeyValuePair kvpField, string strValue) - { - SetValue(kvpField.Key, strValue); - } - - /// - /// Get a boolean value from the current configuration. - /// - /// Name of the field to get. - /// Default value that is returned - /// if the specified field doesn't exist. - /// Returns boolean value. - public static bool GetBool(string strField, bool bDefaultIfNotFound) - { - Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException(); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) - { - if(str.Equals(ValTrue)) return true; - if(str.Equals(ValFalse)) return false; - } - - return bDefaultIfNotFound; - } - - public static bool GetBool(KeyValuePair kvp) - { - Debug.Assert((kvp.Value == ValTrue) || (kvp.Value == ValFalse)); - - string str; - if(m_cfgCurrent.TryGetValue(kvp.Key, out str)) - { - if(str.Equals(ValTrue)) return true; - if(str.Equals(ValFalse)) return false; - } - - return (kvp.Value == ValTrue); - } - - /// - /// Set a configuration item's value. - /// - /// Name of the item. - /// Value of the item. - public static void SetValue(string strField, bool bValue) - { - SetValue(strField, bValue ? ValTrue : ValFalse); - } - - public static void SetValue(KeyValuePair kvpField, bool bValue) - { - SetValue(kvpField.Key, bValue); - } - - /// - /// Get an integer value from the current configuration. - /// - /// Name of the configuration item. - /// Default value that is returned if - /// the specified item cannot be found. - /// An integer. - /// Thrown if - /// is null. - public static int GetInt(string strField, int nDefaultIfNotFound) - { - Debug.Assert(strField != null); - if(strField == null) throw new ArgumentNullException("strField"); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) - { - int nValue; - if(StrUtil.TryParseInt(str, out nValue)) return nValue; - } - - return nDefaultIfNotFound; - } - - public static int GetInt(KeyValuePair kvp) - { - int nValue; - string str; - if(m_cfgCurrent.TryGetValue(kvp.Key, out str)) - { - if(StrUtil.TryParseInt(str, out nValue)) return nValue; - else { Debug.Assert(false); } - } - - if(StrUtil.TryParseInt(kvp.Value, out nValue)) return nValue; - else { Debug.Assert(false); } - - return 0; - } - - /// - /// Get an unsigned integer value from the current configuration. - /// - /// Name of the configuration item. - /// Default value that is returned if - /// the specified item cannot be found. - /// An unsigned integer. - /// Thrown if - /// is null. - public static uint GetUInt(string strField, uint uDefaultIfNotFound) - { - Debug.Assert(strField != null); - if(strField == null) throw new ArgumentNullException("strField"); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) - { - uint uValue; - if(StrUtil.TryParseUInt(str, out uValue)) return uValue; - } - - return uDefaultIfNotFound; - } - - public static uint GetUInt(KeyValuePair kvp) - { - uint uValue; - string str; - if(m_cfgCurrent.TryGetValue(kvp.Key, out str)) - { - if(StrUtil.TryParseUInt(str, out uValue)) return uValue; - else { Debug.Assert(false); } - } - - if(StrUtil.TryParseUInt(kvp.Value, out uValue)) return uValue; - else { Debug.Assert(false); } - - return 0; - } - - /// - /// Get an unsigned long integer value from the current configuration. - /// - /// Name of the configuration item. - /// Default value that is returned if - /// the specified item cannot be found. - /// An unsigned long integer. - /// Thrown if - /// is null. - public static ulong GetULong(string strField, ulong uDefaultIfNotFound) - { - Debug.Assert(strField != null); - if(strField == null) throw new ArgumentNullException("strField"); - - string str; - if(m_cfgCurrent.TryGetValue(strField, out str)) - { - ulong uValue; - if(StrUtil.TryParseULong(str, out uValue)) return uValue; - } - - return uDefaultIfNotFound; - } - - public static ulong GetULong(KeyValuePair kvp) - { - ulong uValue; - string str; - if(m_cfgCurrent.TryGetValue(kvp.Key, out str)) - { - if(StrUtil.TryParseULong(str, out uValue)) return uValue; - else { Debug.Assert(false); } - } - - if(StrUtil.TryParseULong(kvp.Value, out uValue)) return uValue; - else { Debug.Assert(false); } - - return 0; - } - - /// - /// Set a configuration item's value. - /// - /// Name of the configuration item. - /// Value of the configuration item. - public static void SetValue(string strField, int nValue) - { - SetValue(strField, nValue.ToString()); - } - - public static void SetValue(KeyValuePair kvpField, int nValue) - { - SetValue(kvpField.Key, nValue.ToString()); - } - - /// - /// Set a configuration item's value. - /// - /// Name of the configuration item. - /// Value of the configuration item. - public static void SetValue(string strField, uint uValue) - { - SetValue(strField, uValue.ToString()); - } - - public static void SetValue(KeyValuePair kvpField, uint uValue) - { - SetValue(kvpField.Key, uValue.ToString()); - } - - /// - /// Set a configuration item's value. - /// - /// Name of the configuration item. - /// Value of the configuration item. - public static void SetValue(string strField, ulong uValue) - { - SetValue(strField, uValue.ToString()); - } - - public static void SetValue(KeyValuePair kvpField, ulong uValue) - { - SetValue(kvpField.Key, uValue.ToString()); - } - - /// - /// Remove all fields indexed by a prefix and consecutive numbers. - /// All fields starting with the prefix will be removed. Index - /// is zero-based. - /// - /// Field prefix. - /// First index. - public static void RemoveIndexedItems(string strFieldPrefix, uint uStartIndex) - { - uint uPos = uStartIndex; - string strField; - - while(true) - { - strField = strFieldPrefix + uPos.ToString(); - - if(GetValue(strField, null) != null) - { - m_cfgCurrent.Remove(strField); - Debug.Assert(GetValue(strField, null) == null); - - ++uPos; - } - else break; - } - } - } -} - -#endif // KeePassLibSD diff --git a/Ext/DeprecatedSources/AppPolicy.txt b/Ext/DeprecatedSources/AppPolicy.txt deleted file mode 100644 index db4c3cc..0000000 --- a/Ext/DeprecatedSources/AppPolicy.txt +++ /dev/null @@ -1,147 +0,0 @@ - /// - /// Application policy settings - /// - public static class AppPolicy - { - private static bool[] m_vCurPolicyFlags = new bool[(int)AppPolicyFlag.Count]; - private static bool[] m_vNewPolicyFlags = new bool[(int)AppPolicyFlag.Count]; - - private static string PolicyToString(AppPolicyFlag flag) - { - string str = KPRes.Feature + @": "; - - switch(flag) - { - case AppPolicyFlag.Plugins: - str += KPRes.Plugins; - break; - case AppPolicyFlag.Export: - str += KPRes.Export; - break; - case AppPolicyFlag.Import: - str += KPRes.Import; - break; - case AppPolicyFlag.Print: - str += KPRes.Print; - break; - case AppPolicyFlag.SaveDatabase: - str += KPRes.SaveDatabase; - break; - case AppPolicyFlag.AutoType: - str += KPRes.AutoType; - break; - case AppPolicyFlag.CopyToClipboard: - str += KPRes.Clipboard; - break; - case AppPolicyFlag.DragDrop: - str += KPRes.DragDrop; - break; - case AppPolicyFlag.ChangeMasterKey: - str += KPRes.ChangeMasterKey; - break; - case AppPolicyFlag.EditTriggers: - str += KPRes.TriggersEdit; - break; - case AppPolicyFlag.UnhidePasswords: - str += KPRes.UnhidePasswords; - break; - default: - Debug.Assert(false); - str += KPRes.Unknown + "."; - break; - } - - str += MessageService.NewLine + KPRes.Description + @": "; - - switch(flag) - { - case AppPolicyFlag.Plugins: - str += KPRes.PolicyPluginsDesc; - break; - case AppPolicyFlag.Export: - str += KPRes.PolicyExportDesc; - break; - case AppPolicyFlag.Import: - str += KPRes.PolicyImportDesc; - break; - case AppPolicyFlag.Print: - str += KPRes.PolicyPrintDesc; - break; - case AppPolicyFlag.SaveDatabase: - str += KPRes.PolicySaveDatabaseDesc; - break; - case AppPolicyFlag.AutoType: - str += KPRes.PolicyAutoTypeDesc; - break; - case AppPolicyFlag.CopyToClipboard: - str += KPRes.PolicyClipboardDesc; - break; - case AppPolicyFlag.DragDrop: - str += KPRes.PolicyDragDropDesc; - break; - case AppPolicyFlag.ChangeMasterKey: - str += KPRes.PolicyChangeMasterKey; - break; - case AppPolicyFlag.EditTriggers: - str += KPRes.PolicyTriggersEditDesc; - break; - case AppPolicyFlag.UnhidePasswords: - str += KPRes.UnhidePasswordsDesc; - break; - default: - Debug.Assert(false); - str += KPRes.Unknown + "."; - break; - } - - return str; - } - - public static string RequiredPolicyMessage(AppPolicyFlag flag) - { - string str = KPRes.PolicyDisallowed + MessageService.NewParagraph; - str += KPRes.PolicyRequiredFlag + ":" + MessageService.NewLine; - str += PolicyToString(flag); - - return str; - } - - public static void CurrentAllowAll(bool bAllow) - { - for(int i = 0; i < (int)AppPolicyFlag.Count; ++i) - m_vCurPolicyFlags[i] = m_vNewPolicyFlags[i] = bAllow; - } - - public static void CurrentAllow(AppPolicyFlag flag, bool bAllow) - { - m_vCurPolicyFlags[(int)flag] = m_vNewPolicyFlags[(int)flag] = bAllow; - } - - public static void NewAllow(AppPolicyFlag flag, bool bAllow) - { - m_vNewPolicyFlags[(int)flag] = bAllow; - } - - public static bool NewIsAllowed(AppPolicyFlag flag) - { - return m_vNewPolicyFlags[(int)flag]; - } - - public static bool IsAllowed(AppPolicyFlag flag) - { - return m_vCurPolicyFlags[(int)flag]; - } - - public static bool Try(AppPolicyFlag flag) - { - bool bAllowed = m_vCurPolicyFlags[(int)flag]; - - if(bAllowed == false) - { - string strMsg = RequiredPolicyMessage(flag); - MessageService.ShowWarning(strMsg); - } - - return bAllowed; - } - } diff --git a/Ext/DeprecatedSources/EntryTemplates.cs b/Ext/DeprecatedSources/EntryTemplates.cs deleted file mode 100644 index 1a2dc3a..0000000 --- a/Ext/DeprecatedSources/EntryTemplates.cs +++ /dev/null @@ -1,226 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2009 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Drawing; -using System.Windows.Forms; -using System.Diagnostics; - -using KeePass.Forms; -using KeePass.Resources; - -using KeePassLib; -using KeePassLib.Security; - -namespace KeePass.Util -{ - internal sealed class EntryTemplateItem - { - private bool m_bProtected = false; - private string m_strItemName = string.Empty; - - public bool Protected - { - get { return m_bProtected; } - } - - public string Name - { - get { return m_strItemName; } - } - - public EntryTemplateItem(string strItemName, bool bProtected) - { - if(strItemName == null) throw new ArgumentNullException("strItemName"); - m_strItemName = strItemName; - m_bProtected = bProtected; - } - } - - internal sealed class EntryTemplate - { - private string m_strName = string.Empty; - private Image m_imgSmallIcon = null; - private EntryTemplateItem[] m_pItems = null; - - public string Name - { - get { return m_strName; } - } - - public Image SmallIcon - { - get { return m_imgSmallIcon; } - } - - public EntryTemplateItem[] Items - { - get { return m_pItems; } - } - - public EntryTemplate(string strName, Image imgSmallIcon, EntryTemplateItem[] pEntries) - { - if(strName == null) throw new ArgumentNullException("strName"); - if(pEntries == null) throw new ArgumentNullException("pEntries"); - - m_strName = strName; - m_imgSmallIcon = imgSmallIcon; - m_pItems = pEntries; - } - } - - public static class EntryTemplates - { - private static List m_vTemplates = new List(); - - private static ToolStripSplitButton m_btnItemsHost = null; - private static List m_vToolStripItems = new List(); - - public static void Init(ToolStripSplitButton btnHost) - { - if(btnHost == null) throw new ArgumentNullException("btnHost"); - m_btnItemsHost = btnHost; - - ToolStripSeparator tsSep = new ToolStripSeparator(); - m_btnItemsHost.DropDownItems.Add(tsSep); - m_vToolStripItems.Add(tsSep); - - EntryTemplates.AddItem(BankAccount); - EntryTemplates.AddItem(PersonalContact); - } - - private static void AddItem(EntryTemplate et) - { - m_vTemplates.Add(et); - - ToolStripMenuItem tsmi = new ToolStripMenuItem(et.Name); - tsmi.Click += OnEntryTemplatesExecute; - m_btnItemsHost.DropDownItems.Add(tsmi); - - if(et.SmallIcon != null) tsmi.Image = et.SmallIcon; - else tsmi.Image = KeePass.Properties.Resources.B16x16_KGPG_Key1; - - m_vToolStripItems.Add(tsmi); - } - - public static void Clear() - { - m_vTemplates.Clear(); - - foreach(ToolStripItem tsmi in m_vToolStripItems) - { - tsmi.Click -= OnEntryTemplatesExecute; - m_btnItemsHost.DropDownItems.Remove(tsmi); - } - - m_vToolStripItems.Clear(); - } - - private static void OnEntryTemplatesExecute(object sender, EventArgs e) - { - ToolStripMenuItem tsmi = sender as ToolStripMenuItem; - if(tsmi == null) { Debug.Assert(false); return; } - - string strName = tsmi.Text; - foreach(EntryTemplate et in m_vTemplates) - { - if(et.Name == strName) - { - CreateEntry(et); - break; - } - } - } - - private static void CreateEntry(EntryTemplate et) - { - if(Program.MainForm.ActiveDatabase.IsOpen == false) - { - Debug.Assert(false); - return; - } - - PwGroup pgContainer = Program.MainForm.GetSelectedGroup(); - if(pgContainer == null) - pgContainer = Program.MainForm.ActiveDatabase.RootGroup; - - PwEntry pe = new PwEntry(true, true); - - // pe.Strings.Set(PwDefs.TitleField, new ProtectedString( - // Program.MainForm.Database.MemoryProtection.ProtectTitle, - // et.Name)); - - foreach(EntryTemplateItem eti in et.Items) - pe.Strings.Set(eti.Name, new ProtectedString(eti.Protected, string.Empty)); - - PwEntryForm pef = new PwEntryForm(); - pef.InitEx(pe, PwEditMode.AddNewEntry, Program.MainForm.ActiveDatabase, - Program.MainForm.ClientIcons, true); - - if(pef.ShowDialog() == DialogResult.OK) - { - pgContainer.AddEntry(pe, true); - - // Program.MainForm.UpdateEntryList(null, true); - // Program.MainForm.UpdateUIState(true); - Program.MainForm.UpdateUI(false, null, false, null, true, null, true); - } - else Program.MainForm.UpdateUI(false, null, false, null, false, null, false); - } - - private static readonly EntryTemplate BankAccount = new EntryTemplate( - KPRes.BankAccount, null, new EntryTemplateItem[]{ - new EntryTemplateItem(KPRes.TAccountNumber, false), - new EntryTemplateItem(KPRes.TAccountType, false), - new EntryTemplateItem(KPRes.BranchCode, false), - new EntryTemplateItem(KPRes.RoutingCode, false), - new EntryTemplateItem(KPRes.SortCode, false), - new EntryTemplateItem(KPRes.Iban, false), - new EntryTemplateItem(KPRes.SwiftCode, false), - new EntryTemplateItem(KPRes.BranchTel, false), - new EntryTemplateItem(KPRes.TAccountInfoTel, false), - new EntryTemplateItem(KPRes.BranchHours, false), - new EntryTemplateItem(KPRes.TAccountNames, false), - new EntryTemplateItem(KPRes.MinBalance, false), - new EntryTemplateItem(KPRes.TransfersOf, false), - new EntryTemplateItem(KPRes.Frequency, false) - }); - - private static readonly EntryTemplate PersonalContact = new EntryTemplate( - KPRes.Contact, null, new EntryTemplateItem[]{ - new EntryTemplateItem(KPRes.JobTitle, false), - new EntryTemplateItem(KPRes.Department, false), - new EntryTemplateItem(KPRes.Company, false), - new EntryTemplateItem(KPRes.WorkTel, false), - new EntryTemplateItem(KPRes.EMail, false), - new EntryTemplateItem(KPRes.HomeTel, false), - new EntryTemplateItem(KPRes.MobileTel, false), - new EntryTemplateItem(KPRes.Pager, false), - new EntryTemplateItem(KPRes.CarTel, false), - new EntryTemplateItem(KPRes.WorkFax, false), - new EntryTemplateItem(KPRes.HomeFax, false), - new EntryTemplateItem(KPRes.WebPage, false), - new EntryTemplateItem(KPRes.Assistant, false), - new EntryTemplateItem(KPRes.AssistantTel, false), - new EntryTemplateItem(KPRes.HomeAddress, false) - }); - } -} diff --git a/Ext/DeprecatedSources/EntryTemplates_DefaultText.xml b/Ext/DeprecatedSources/EntryTemplates_DefaultText.xml deleted file mode 100644 index 611a0c6..0000000 --- a/Ext/DeprecatedSources/EntryTemplates_DefaultText.xml +++ /dev/null @@ -1,1499 +0,0 @@ - - - - - Action - - - Add custom toolbar button - - - Add Entry - - - Add Entry... - - - Create a new password entry. - - - Add Entry String Field - - - Create a new string field for the current entry. - - - Advanced - - - After Opening a Database - - - All Entries - - - All Files - - - All Supported Files - - - Application - - - Application exit - - - Application startup - - - Arguments - - - Do you want to continue? - - - Assistant - - - AssistantTel - - - The following file has already been attached to the current entry: - - - Failed to attach file: - - - Attach Files To Entry - - - Attachments - - - Save Attached File As - - - Save attached files to: - - - Do you wish to rename the new file or overwrite the existing attached file? - - - Click [Yes] to rename the new file. - - - Click [No] to overwrite the existing attached file. - - - Click [Cancel] to skip this file. - - - Author - - - Automatically create new - - - Automatically generated passwords for new entries - - - Remember and automatically open last used database on startup - - - Automatically save when closing/locking the database - - - Show expired entries (if any) - - - Show entries that will expire soon (if any) - - - Auto-Type - - - Auto-Type Entry Selection - - - Multiple entries have been found for the currently active window. Please select the entry, which you want to auto-type into the active window. - - - Multiple entries exist for the current window. - - - Auto-type obfuscation may not work with all windows. - - - Prepend special initialization sequence for Internet Explorer windows - - - The specified auto-type sequence is invalid. - - - The following auto-type placeholder or special key code is unknown/unsupported: - - - Available Languages - - - Bank Account - - - Bits - - - Branch Code - - - Branch Hours - - - Branch Tel. - - - Browser - - - < &Back - - - &Finish - - - &Next > - - - Cancel - - - Cannot move entries because they aren't stored in the same group. - - - Car Tel. - - - You are changing the composite master key for the currently-open database. - - - Check for update at KeePass startup - - - You have the latest version. - - - New KeePass version available! - - - &Clear List - - - Clipboard - - - Clipboard will be cleared in [PARAM] seconds - - - Clear clipboard when closing KeePass - - - Data copied to clipboard. - - - Protect clipboard using 'Clipboard Viewer Ignore' format - - - &Close - - - Close button [X] minimizes main window instead of terminating the application - - - Company - - - Comparison - - - Components - - - Condition - - - Changes to the configuration/policy will affect you and all users of this KeePass installation. - - - Changes to the configuration/policy will only affect you. Policy flags that are enforced by the administrator are reset after restarting KeePass. - - - Failed to save the configuration. - - - Configure Auto-Type - - - Configure auto-type behaviour for this entry. - - - Configure Auto-Type Item - - - Associate a window title with a keystroke sequence. - - - Configure Keystroke Sequence - - - Define a default keystroke sequence. - - - Create New Password Database - Step 2 - - - Contact - - - Contains - - - Copied entry data to clipboard - - - Copy - - - Copy All - - - Copy - - - Copy Password to Clipboard - - - Copy &Password - - - Copy &TAN - - - Copy User Name to Clipboard - - - Create Composite Master Key - - - Create New Password Database - - - Creation Time - - - Remember user name and password - - - Do not remember user name and password - - - Remember user name only - - - CSV / Text File - - - Current Style - - - Custom - - - Custom Fields - - - Customizable HTML File - - - Custom toolbar button clicked - - - Cut - - - Data - - - Database - - - Enter a short description of the database or leave it empty. - - - Database Maintenance - - - Here you can maintain the currently opened database. - - - The current database file has been modified - - - Enter a name for the database or leave it empty. - - - Database Settings - - - Here you can configure various database settings. - - - Default - - - Delete - - - Delete Entries - - - Delete Entry - - - Are you sure you want to permanently delete the selected entries? - - - Are you sure you want to permanently delete the selected entry? - - - Delete Group - - - Deleting a group will also delete all entries and subgroups in that group. - - - Are you sure you want to permanently delete the selected group? - - - Department - - - Description - - - Details - - - Discard changes - - - Please see the documentation for more details. - - - Drag&Drop - - - The string field name you specified already exists. String field names must be unique for each entry. - - - Edit Entry - - - You're editing an existing password entry. - - - Edit Group - - - Edit properties of the currently selected group. - - - Edit Entry String Field - - - Edit one of the entry's string fields. - - - eMail - - - Empty - - - Encoding - - - Default ANSI (System) - - - Selected encoding is invalid. The file cannot be interpreted using the selected encoding. - - - Ends with - - - Enter Master Key - - - Generate additional random bits. - - - Entropy Collection - - - Entry - - - Entry List - - - Environment variable - - - Equals - - - Error Code - - - Errors - - - Event - - - Execute command line / URL - - - Exit instead of locking the workspace after the specified time - - - Expired Entries - - - Expiry Time - - - Export - - - Export data to an external file. - - - Export File/Data - - - Export To HTML - - - Export entries to a HTML file. - - - Exporting... - - - Export to: - - - Fatal Error - - - Feature - - - Field Name - - - The entered name exists already and cannot be used. - - - The entered name is invalid and cannot be used. - - - Please enter a field name. - - - The selected field, which identifies the source entry, contains illegal characters (like '{', '}', newline characters, ...). - - - Multiple entries match the specified identifying field. - - - To avoid ambiguity, entries can be identified by their UUIDs, which are unique. - - - Field Value - - - File - - - The file on disk/server has changed since it was loaded. Probably someone else has edited and saved the database. - - - Save the current database to the file. Changes made by the other user will be lost. - - - Load the file on disk/server and merge it with the current database in memory. - - - File exists - - - The following file exists already: - - - Failed to create the file association. Make sure you have write access to the file associations list. - - - Successfully associated KDBX files with KeePass! KDBX files will now be opened by KeePass when you double-click on them. - - - KeePass Password Database - - - The specified file is currently locked by the following user: - - - KeePass will open the file, but note that you might overwrite changes each other when saving. - - - This file path contains a semicolon (;) and therefore cannot be processed. Replace the semicolon and repeat the procedure. - - - The specified file could not be found. - - - File/URL - - - Files - - - Save database changes before closing the file? - - - Save database changes before exiting KeePass? - - - Save database changes before locking the workspace? - - - Abort the current operation. - - - The file will not be closed. - - - KeePass will not be closed. - - - The KeePass workspace will not be locked. - - - Discard all changes made to the database and close the file. - - - Discard all changes made to the database and exit KeePass. - - - Discard all changes made to the database and lock the KeePass workspace. - - - Save all changes made to the database and close the file. - - - Save all changes made to the database and exit KeePass. - - - Save all changes made to the database and lock the KeePass workspace. - - - The new file's content does not match the data that KeePass has written, i.e. writing to the file has failed and it might be corrupted now. - - - Please try saving again, and if that fails, save the database to a different location. - - - Filter - - - Focus entry list after a successful quick search (toolbar) - - - This file format doesn't support database descriptions. - - - This file format doesn't support database names. - - - This file format doesn't support root groups. All entries in the root group are moved to the first subgroup. - - - To export to this file format, the root group must have at least one subgroup. - - - This file format only supports one attachment per entry. Only the first attachment is saved, the others are ignored. - - - Frequency - - - General - - - Generated Passwords Count - - - Enter number of passwords to generate. - - - Please enter the number of passwords to generate: - - - Generated Passwords Samples - - - Generate a password - - - Generic CSV Importer - - - Remove selected profile - - - Remove the currently selected profile. - - - Save as Profile - - - Save current settings as a profile. - - - Please enter a name for the new password generator profile, or select an existing profile name to overwrite it: - - - Derive from previous password - - - Group - - - The selected group cannot store any entries. - - - This option is disabled, because local help is not installed. - - - Help Source Selection - - - Choose between local help and online help center. - - - Hide field using asterisks - - - Home Address - - - Homebanking - - - Home Fax - - - Do you want to visit the KeePass homepage now? - - - Home Tel. - - - IBAN - - - ID - - - Ignore - - - This file uses a file format feature that is not supported. - - - Image Viewer - - - Import - - - Import Behavior - - - Select an import method. - - - Import failed. - - - Import an external file. - - - Files to be imported: - - - Import File/Data - - - The import process has finished! - - - Importing... - - - It is indispensable that you read the documentation about this import method before continuing. - - - Have you understood how the import process works and want to start it now? - - - Internet - - - Invalid file structure! - - - Invalid Key - - - The specified URL is invalid. - - - The specified user name / password combination is invalid. - - - Job Title - - - The KeePassLibC library is required to open and save KDB files created by KeePass 1.x. - - - KeePass KDBX Files - - - KeePassLibC (1.x File Support) - - - KeePassLibC could not be found. - - - Alt - - - Control - - - Key Modifiers - - - Shift - - - Create a new key file - - - The specified key file could not be found or its format is unknown. - - - Key Files - - - Select key file manually - - - Use an existing file as key file - - - Keystroke Sequence - - - The selected language has been activated. KeePass must be restarted in order to load the language. - - - Last Access Time - - - Last Modification Time - - - Limit to single instance - - - Locked - - - &Lock Workspace - - - Un&lock Workspace - - - Lock workspace when minimizing main window - - - Lock workspace when locking Windows, switching user or sleeping - - - Main Window - - - Composite master key has been changed! - - - Save the database now in order to get the new key applied. - - - The master password must be at least {PARAM} characters long! - - - The estimated quality of the master password must be at least {PARAM} bits! - - - Menus - - - Merging data... - - - Min. Balance - - - Minimize main window after copying data to the clipboard - - - Minimize main window after locking the workspace - - - Minimize main window after opening a database - - - Minimize to tray instead of taskbar - - - Mobile Tel. - - - Name - - - Use native library for faster key transformations - - - Navigation - - - Network - - - Never expires - - - NewDatabase.kdbx - - - New Group - - - New state - - - No - - - The operating system didn't KeePass grant read access to the specified file. - - - (None) - - - None - - - Not - - - Notes - - - Not installed - - - The selected file isn't a valid XSL stylesheet. - - - The object with the specified name could not be found. - - - Off - - - of - - - On - - - Open Database File - - - Open database file - - - Opened database file - - - Opening password database... - - - Optimize for screen reader (only enable if you're using a screen reader) - - - Options - - - Here you can configure the global KeePass program options. - - - Other Placeholders - - - Overwrite - - - Overwrite the existing file? - - - Pager - - - Detailed descriptions of all parameters can be found in the help manual. - - - Password - - - Password Managers - - - Password Generation Options - - - Here you can define properties of generated passwords. - - - Enter the password: - - - Password and repeated password aren't identical! - - - Paste - - - Perform global auto-type - - - Pick Characters - - - Select the requested character positions. - - - Pick an icon. - - - Plugin - - - The following plugin cannot be loaded: - - - Plugins - - - Here you can configure all loaded KeePass plugins. - - - Allow auto-typing entries to other windows. - - - Allow copying entry information to clipboard (main window only). - - - This operation is disallowed by the application policy. Ask your administrator to allow this operation. - - - Allow sending information to other windows using drag&drop. - - - Allow exporting entries to (non-encrypted) file formats. - - - Allow importing entries from external files. - - - Allow loading plugins to extend KeePass functionality. - - - Allow printing password entry lists. - - - The following policy flag is required - - - Allow saving databases to disk/URL. - - - Print - - - Print password entries. - - - Quick Search - - - Exclude expired entries in quick searches (toolbar) - - - Ready. - - - Recycle Bin - - - Remember password hiding setting in 'Edit Entry' window - - - Do you wish to restart KeePass now? - - - Routing Code - - - Sample Entry - - - Save - - - Do you want to save the changes before closing? - - - KeePass - Save Before Close/Lock? - - - Save Database - - - Saved database file - - - Saving database... - - - Saving database file - - - Search... - - - Search the password database for entries. - - - Search Results - - - entries found. - - - Automatically search key files on removable media - - - Type to search the database - - - in - - - Find - - - Select All - - - Select Color - - - Please select a different group. - - - selected - - - Select a file. - - - Select an icon - - - Select Language - - - Here you can select a different user interface language. - - - One or more of the KeePass self-tests failed. - - - Show All Entries - - - Show Expired Entries - - - Show full path in title bar (instead of file name only) - - - Show grid lines in password entry list - - - Show in - - - Show tray icon only if main window has been sent to tray - - - Expired Entries and Entries That Will Expire Soon - - - Sort Code - - - Special Keys - - - Select one of the standard expire times - - - Standard Fields - - - Start and Exit - - - Start minimized and locked - - - Starts with - - - Success. - - - SWIFT Code - - - Synchronization failed. - - - Synchronize - - - Synchronizing... - - - Make sure that the two databases use the same composite master key. This is required for synchronization. - - - Synchronization completed successfully. - - - System - - - System Code Page - - - Account Info Tel. - - - Account names - - - Account Number - - - Account Type - - - TAN Wizard - - - With this TAN wizard you can easily add TAN entries. - - - Target Window - - - Text Viewer - - - Time span - - - Title - - - Toggle - - - Show/hide password using asterisks - - - New... - - - Open... - - - Save All - - - Too many files have been selected. Select smaller groups and repeat the current procedure a few times. - - - Transfers Of - - - Compute the number of rounds that lead to a delay of 1 second on this computer. - - - The trigger action type is unknown. - - - Add Trigger - - - Create a new workflow automation. - - - The trigger condition type is unknown. - - - Edit Trigger - - - Modify an existing workflow automation. - - - The trigger event type is unknown. - - - Trigger execution failed - - - Trigger name - - - Triggers - - - Automate workflows using the trigger system. - - - Change trigger on/off state - - - A newer KeePass version or a plugin might be required for this type. - - - Undo - - - Unknown - - - An unknown error occurred. - - - Unknown file version! - - - Update checking failed. - - - URL - - - Open a database stored on a server. - - - Open From URL - - - URL Override - - - Save current database on a server. - - - Save To URL - - - User Name - - - Enter the user name: - - - UUID - - - Value - - - Version - - - View Entry - - - You're viewing a password entry. - - - Wait - - - Warnings - - - Web Browser - - - Web Page - - - Web Site Login - - - Web Sites - - - Windows - - - Work Fax - - - Workspace Locked - - - Work Tel. - - - Transform using XSL Stylesheet - - - XSL Stylesheets - - - Select XSL Transformation File - - - XSL Stylesheets for KDB4 XML - - - Yes - - - - - - Failed to initialize encryption/decryption stream! - - - AES/Rijndael (256-Bit Key) - - - An extended error report has been copied to the clipboard. Please send it to the KeePass developers. - - - Fatal Error - - - A fatal error has occurred! - - - The file is corrupted. - - - The file header is corrupted! Some header data was declared but is not present. - - - Failed to load the specified file! - - - A newer KeePass version is required to open this file. - - - The target file might be in a corrupted state. Please try saving again, and if that fails, save the database to a different location. - - - Failed to save the current database to the specified location! - - - The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted. - - - The file is encrypted using an unknown encryption algorithm! - - - The file is compressed using an unknown compression algorithm! - - - The file version is unsupported. - - - Failed to create the final encryption/decryption key! - - - The .NET framework/runtime, under which KeePass is currently running, does not support this operation. - - - The composite key is invalid! - - - Make sure the composite key is correct and try again. - - - Found invalid data while decoding. - - - In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format. - - - The length of the master key seed is invalid! - - - The selected file appears to be an old format - - - Unknown header ID! - - - The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored. - - - diff --git a/Ext/DeprecatedSources/ImportCsvForm_120218.Designer.cs b/Ext/DeprecatedSources/ImportCsvForm_120218.Designer.cs deleted file mode 100644 index a83ebbb..0000000 --- a/Ext/DeprecatedSources/ImportCsvForm_120218.Designer.cs +++ /dev/null @@ -1,262 +0,0 @@ -namespace KeePass.Forms -{ - partial class ImportCsvForm - { - /// - /// Erforderliche Designervariable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Verwendete Ressourcen bereinigen. - /// - /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. - protected override void Dispose(bool disposing) - { - if(disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Vom Windows Form-Designer generierter Code - - /// - /// Erforderliche Methode für die Designerunterstützung. - /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. - /// - private void InitializeComponent() - { - this.m_btnOK = new System.Windows.Forms.Button(); - this.m_btnCancel = new System.Windows.Forms.Button(); - this.m_lblFileEncoding = new System.Windows.Forms.Label(); - this.m_cmbEncoding = new System.Windows.Forms.ComboBox(); - this.m_lvPreview = new KeePass.UI.CustomListViewEx(); - this.m_tbSourcePreview = new System.Windows.Forms.TextBox(); - this.m_lblSourcePreview = new System.Windows.Forms.Label(); - this.m_lvHeaderOrder = new KeePass.UI.CustomListViewEx(); - this.m_lblOrder = new System.Windows.Forms.Label(); - this.m_lblOrderHint = new System.Windows.Forms.Label(); - this.m_lblPreview = new System.Windows.Forms.Label(); - this.m_lblDelimiter = new System.Windows.Forms.Label(); - this.m_tbSepChar = new System.Windows.Forms.TextBox(); - this.m_cbDoubleQuoteToSingle = new System.Windows.Forms.CheckBox(); - this.m_pbRender = new System.Windows.Forms.ProgressBar(); - this.m_btnPreviewRefresh = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // m_btnOK - // - this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.m_btnOK.Location = new System.Drawing.Point(702, 450); - this.m_btnOK.Name = "m_btnOK"; - this.m_btnOK.Size = new System.Drawing.Size(75, 23); - this.m_btnOK.TabIndex = 0; - this.m_btnOK.Text = "&Import"; - this.m_btnOK.UseVisualStyleBackColor = true; - this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); - // - // m_btnCancel - // - this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.m_btnCancel.Location = new System.Drawing.Point(702, 479); - this.m_btnCancel.Name = "m_btnCancel"; - this.m_btnCancel.Size = new System.Drawing.Size(75, 23); - this.m_btnCancel.TabIndex = 1; - this.m_btnCancel.Text = "&Cancel"; - this.m_btnCancel.UseVisualStyleBackColor = true; - this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); - // - // m_lblFileEncoding - // - this.m_lblFileEncoding.AutoSize = true; - this.m_lblFileEncoding.Location = new System.Drawing.Point(9, 15); - this.m_lblFileEncoding.Name = "m_lblFileEncoding"; - this.m_lblFileEncoding.Size = new System.Drawing.Size(73, 13); - this.m_lblFileEncoding.TabIndex = 2; - this.m_lblFileEncoding.Text = "File encoding:"; - // - // m_cmbEncoding - // - this.m_cmbEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.m_cmbEncoding.FormattingEnabled = true; - this.m_cmbEncoding.Location = new System.Drawing.Point(105, 12); - this.m_cmbEncoding.Name = "m_cmbEncoding"; - this.m_cmbEncoding.Size = new System.Drawing.Size(228, 21); - this.m_cmbEncoding.TabIndex = 3; - this.m_cmbEncoding.SelectedIndexChanged += new System.EventHandler(this.OnCmbEncodingSelectedIndexChanged); - // - // m_lvPreview - // - this.m_lvPreview.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.m_lvPreview.Location = new System.Drawing.Point(12, 262); - this.m_lvPreview.Name = "m_lvPreview"; - this.m_lvPreview.ShowItemToolTips = true; - this.m_lvPreview.Size = new System.Drawing.Size(684, 240); - this.m_lvPreview.TabIndex = 14; - this.m_lvPreview.UseCompatibleStateImageBehavior = false; - this.m_lvPreview.View = System.Windows.Forms.View.Details; - // - // m_tbSourcePreview - // - this.m_tbSourcePreview.AcceptsReturn = true; - this.m_tbSourcePreview.Location = new System.Drawing.Point(105, 39); - this.m_tbSourcePreview.Multiline = true; - this.m_tbSourcePreview.Name = "m_tbSourcePreview"; - this.m_tbSourcePreview.ReadOnly = true; - this.m_tbSourcePreview.Size = new System.Drawing.Size(672, 90); - this.m_tbSourcePreview.TabIndex = 5; - // - // m_lblSourcePreview - // - this.m_lblSourcePreview.AutoSize = true; - this.m_lblSourcePreview.Location = new System.Drawing.Point(9, 42); - this.m_lblSourcePreview.Name = "m_lblSourcePreview"; - this.m_lblSourcePreview.Size = new System.Drawing.Size(68, 13); - this.m_lblSourcePreview.TabIndex = 4; - this.m_lblSourcePreview.Text = "Source data:"; - // - // m_lvHeaderOrder - // - this.m_lvHeaderOrder.AllowColumnReorder = true; - this.m_lvHeaderOrder.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.m_lvHeaderOrder.Location = new System.Drawing.Point(105, 135); - this.m_lvHeaderOrder.Name = "m_lvHeaderOrder"; - this.m_lvHeaderOrder.Size = new System.Drawing.Size(672, 53); - this.m_lvHeaderOrder.TabIndex = 7; - this.m_lvHeaderOrder.UseCompatibleStateImageBehavior = false; - this.m_lvHeaderOrder.View = System.Windows.Forms.View.Details; - // - // m_lblOrder - // - this.m_lblOrder.AutoSize = true; - this.m_lblOrder.Location = new System.Drawing.Point(9, 141); - this.m_lblOrder.Name = "m_lblOrder"; - this.m_lblOrder.Size = new System.Drawing.Size(90, 13); - this.m_lblOrder.TabIndex = 6; - this.m_lblOrder.Text = "Define field order:"; - // - // m_lblOrderHint - // - this.m_lblOrderHint.AutoSize = true; - this.m_lblOrderHint.Location = new System.Drawing.Point(102, 191); - this.m_lblOrderHint.Name = "m_lblOrderHint"; - this.m_lblOrderHint.Size = new System.Drawing.Size(499, 13); - this.m_lblOrderHint.TabIndex = 8; - this.m_lblOrderHint.Text = "Drag&&drop the columns to define the order of the fields in the CSV file. \"(Ignor" + - "e)\" columns will be ignored."; - // - // m_lblPreview - // - this.m_lblPreview.AutoSize = true; - this.m_lblPreview.Location = new System.Drawing.Point(9, 246); - this.m_lblPreview.Name = "m_lblPreview"; - this.m_lblPreview.Size = new System.Drawing.Size(125, 13); - this.m_lblPreview.TabIndex = 12; - this.m_lblPreview.Text = "Imported entries preview:"; - // - // m_lblDelimiter - // - this.m_lblDelimiter.AutoSize = true; - this.m_lblDelimiter.Location = new System.Drawing.Point(9, 216); - this.m_lblDelimiter.Name = "m_lblDelimiter"; - this.m_lblDelimiter.Size = new System.Drawing.Size(73, 13); - this.m_lblDelimiter.TabIndex = 9; - this.m_lblDelimiter.Text = "Field delimiter:"; - // - // m_tbSepChar - // - this.m_tbSepChar.Location = new System.Drawing.Point(105, 213); - this.m_tbSepChar.Name = "m_tbSepChar"; - this.m_tbSepChar.Size = new System.Drawing.Size(35, 20); - this.m_tbSepChar.TabIndex = 10; - this.m_tbSepChar.TextChanged += new System.EventHandler(this.OnDelimiterTextChanged); - // - // m_cbDoubleQuoteToSingle - // - this.m_cbDoubleQuoteToSingle.AutoSize = true; - this.m_cbDoubleQuoteToSingle.Location = new System.Drawing.Point(165, 215); - this.m_cbDoubleQuoteToSingle.Name = "m_cbDoubleQuoteToSingle"; - this.m_cbDoubleQuoteToSingle.Size = new System.Drawing.Size(238, 17); - this.m_cbDoubleQuoteToSingle.TabIndex = 11; - this.m_cbDoubleQuoteToSingle.Text = "Replace double quote (\"\") by single quote (\")"; - this.m_cbDoubleQuoteToSingle.UseVisualStyleBackColor = true; - this.m_cbDoubleQuoteToSingle.CheckedChanged += new System.EventHandler(this.OnDoubleQuoteCheckedChanged); - // - // m_pbRender - // - this.m_pbRender.Location = new System.Drawing.Point(142, 246); - this.m_pbRender.Name = "m_pbRender"; - this.m_pbRender.Size = new System.Drawing.Size(554, 13); - this.m_pbRender.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - this.m_pbRender.TabIndex = 13; - // - // m_btnPreviewRefresh - // - this.m_btnPreviewRefresh.Location = new System.Drawing.Point(702, 262); - this.m_btnPreviewRefresh.Name = "m_btnPreviewRefresh"; - this.m_btnPreviewRefresh.Size = new System.Drawing.Size(75, 23); - this.m_btnPreviewRefresh.TabIndex = 15; - this.m_btnPreviewRefresh.Text = "&Refresh"; - this.m_btnPreviewRefresh.UseVisualStyleBackColor = true; - this.m_btnPreviewRefresh.Click += new System.EventHandler(this.OnBtnPreviewRefresh); - // - // ImportCsvForm - // - this.AcceptButton = this.m_btnOK; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.m_btnCancel; - this.ClientSize = new System.Drawing.Size(789, 514); - this.Controls.Add(this.m_btnPreviewRefresh); - this.Controls.Add(this.m_pbRender); - this.Controls.Add(this.m_cbDoubleQuoteToSingle); - this.Controls.Add(this.m_tbSepChar); - this.Controls.Add(this.m_lblDelimiter); - this.Controls.Add(this.m_lblPreview); - this.Controls.Add(this.m_lblOrderHint); - this.Controls.Add(this.m_lblOrder); - this.Controls.Add(this.m_lvHeaderOrder); - this.Controls.Add(this.m_lblSourcePreview); - this.Controls.Add(this.m_tbSourcePreview); - this.Controls.Add(this.m_lvPreview); - this.Controls.Add(this.m_cmbEncoding); - this.Controls.Add(this.m_lblFileEncoding); - this.Controls.Add(this.m_btnCancel); - this.Controls.Add(this.m_btnOK); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "ImportCsvForm"; - this.ShowInTaskbar = false; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Generic CSV Importer"; - this.Load += new System.EventHandler(this.OnFormLoad); - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button m_btnOK; - private System.Windows.Forms.Button m_btnCancel; - private System.Windows.Forms.Label m_lblFileEncoding; - private System.Windows.Forms.ComboBox m_cmbEncoding; - private KeePass.UI.CustomListViewEx m_lvPreview; - private System.Windows.Forms.TextBox m_tbSourcePreview; - private System.Windows.Forms.Label m_lblSourcePreview; - private KeePass.UI.CustomListViewEx m_lvHeaderOrder; - private System.Windows.Forms.Label m_lblOrder; - private System.Windows.Forms.Label m_lblOrderHint; - private System.Windows.Forms.Label m_lblPreview; - private System.Windows.Forms.Label m_lblDelimiter; - private System.Windows.Forms.TextBox m_tbSepChar; - private System.Windows.Forms.CheckBox m_cbDoubleQuoteToSingle; - private System.Windows.Forms.ProgressBar m_pbRender; - private System.Windows.Forms.Button m_btnPreviewRefresh; - } -} \ No newline at end of file diff --git a/Ext/DeprecatedSources/ImportCsvForm_120218.cs b/Ext/DeprecatedSources/ImportCsvForm_120218.cs deleted file mode 100644 index 3b9916f..0000000 --- a/Ext/DeprecatedSources/ImportCsvForm_120218.cs +++ /dev/null @@ -1,277 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2012 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using System.Diagnostics; -using System.IO; - -using KeePass.DataExchange; -using KeePass.UI; -using KeePass.Resources; - -using KeePassLib; -using KeePassLib.Security; - -namespace KeePass.Forms -{ - public partial class ImportCsvForm : Form - { - private PwDatabase m_pwDatabase = null; - private byte[] m_pbInData = null; - private bool m_bBlockChangedEvent = false; - - private string m_strSource = string.Empty; - - private const string StrEncAscii = "ASCII"; - private const string StrEncUtf7 = "UTF-7"; - private const string StrEncUtf8 = "UTF-8"; - private const string StrEncUtf32 = "UTF-32"; - private const string StrEncUnicode = "Unicode"; - private const string StrEncBigUnicode = "Big Endian Unicode"; - - public void InitEx(PwDatabase pwStorage, byte[] pbInData) - { - m_pwDatabase = pwStorage; - m_pbInData = pbInData; - } - - public ImportCsvForm() - { - InitializeComponent(); - Program.Translation.ApplyTo(this); - } - - private void OnFormLoad(object sender, EventArgs e) - { - Debug.Assert(m_pwDatabase != null); if(m_pwDatabase == null) throw new InvalidOperationException(); - Debug.Assert(m_pbInData != null); if(m_pbInData == null) throw new InvalidOperationException(); - - GlobalWindowManager.AddWindow(this); - - this.Icon = Properties.Resources.KeePass; - - m_bBlockChangedEvent = true; - - AddFieldColumn(m_lvHeaderOrder, KPRes.Title, -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.UserName, -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Password, -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Url, -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Notes, -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Custom + " 1", -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Custom + " 2", -1); - AddFieldColumn(m_lvHeaderOrder, KPRes.Custom + " 3", -1); - AddFieldColumn(m_lvHeaderOrder, "(" + KPRes.Ignore + ")", -1); - AddFieldColumn(m_lvHeaderOrder, "(" + KPRes.Ignore + ")", -1); - AddFieldColumn(m_lvHeaderOrder, "(" + KPRes.Ignore + ")", -1); - - foreach(ColumnHeader chHdr in m_lvHeaderOrder.Columns) - chHdr.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize); - - const int nPrevColSize = 120; - AddFieldColumn(m_lvPreview, KPRes.Title, nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.UserName, nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Password, nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Url, nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Notes, nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Custom + " 1", nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Custom + " 2", nPrevColSize); - AddFieldColumn(m_lvPreview, KPRes.Custom + " 3", nPrevColSize); - - m_cmbEncoding.Items.Add(KPRes.EncodingAnsi); - m_cmbEncoding.Items.Add(StrEncAscii); - m_cmbEncoding.Items.Add(StrEncUtf7); - m_cmbEncoding.Items.Add(StrEncUtf8); - m_cmbEncoding.Items.Add(StrEncUtf32); - m_cmbEncoding.Items.Add(StrEncUnicode); - m_cmbEncoding.Items.Add(StrEncBigUnicode); - - m_cmbEncoding.SelectedIndex = 0; - m_tbSepChar.Text = ","; - m_cbDoubleQuoteToSingle.Checked = true; - - m_bBlockChangedEvent = false; - - UpdateStringSource(); - UpdatePreview(); - } - - private static void AddFieldColumn(ListView lv, string strText, int nSize) - { - ColumnHeader hdr = lv.Columns.Add(strText); - - if(nSize >= 0) hdr.Width = nSize; - } - - private void OnBtnOK(object sender, EventArgs e) - { - OnBtnPreviewRefresh(sender, e); - Application.DoEvents(); - - int nItem = 0; - foreach(ListViewItem lvi in m_lvPreview.Items) - { - m_pbRender.Value = (100 * nItem) / m_lvPreview.Items.Count; - ++nItem; - - PwEntry pe = new PwEntry(true, true); - m_pwDatabase.RootGroup.AddEntry(pe, true); - - pe.Strings.Set(PwDefs.TitleField, new ProtectedString( - m_pwDatabase.MemoryProtection.ProtectTitle, lvi.Text)); - pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( - m_pwDatabase.MemoryProtection.ProtectUserName, lvi.SubItems[1].Text)); - pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( - m_pwDatabase.MemoryProtection.ProtectPassword, lvi.SubItems[2].Text)); - pe.Strings.Set(PwDefs.UrlField, new ProtectedString( - m_pwDatabase.MemoryProtection.ProtectUrl, lvi.SubItems[3].Text)); - pe.Strings.Set(PwDefs.NotesField, new ProtectedString( - m_pwDatabase.MemoryProtection.ProtectNotes, lvi.SubItems[4].Text)); - - string strCustom = lvi.SubItems[5].Text; - if(strCustom.Length > 0) - pe.Strings.Set(KPRes.Custom + " 1", new ProtectedString(false, strCustom)); - - strCustom = lvi.SubItems[6].Text; - if(strCustom.Length > 0) - pe.Strings.Set(KPRes.Custom + " 2", new ProtectedString(false, strCustom)); - - strCustom = lvi.SubItems[7].Text; - if(strCustom.Length > 0) - pe.Strings.Set(KPRes.Custom + " 3", new ProtectedString(false, strCustom)); - } - - m_pbRender.Value = 100; - } - - private void OnBtnCancel(object sender, EventArgs e) - { - } - - private void UpdateStringSource() - { - string strEncoding = (m_cmbEncoding.Items[m_cmbEncoding.SelectedIndex] as string); - - Encoding enc = Encoding.Default; - if(strEncoding == StrEncAscii) enc = Encoding.ASCII; - else if(strEncoding == StrEncUtf7) enc = Encoding.UTF7; - else if(strEncoding == StrEncUtf8) enc = Encoding.UTF8; - else if(strEncoding == StrEncUtf32) enc = Encoding.UTF32; - else if(strEncoding == StrEncUnicode) enc = Encoding.Unicode; - else if(strEncoding == StrEncBigUnicode) enc = Encoding.BigEndianUnicode; - else { Debug.Assert(strEncoding == KPRes.EncodingAnsi); } - - try - { - MemoryStream ms = new MemoryStream(m_pbInData, false); - StreamReader sr = new StreamReader(ms, enc); - m_strSource = sr.ReadToEnd(); - sr.Close(); - ms.Close(); - } - catch(Exception) { m_strSource = KPRes.EncodingFail; } - - m_tbSourcePreview.Text = string.Empty; - m_tbSourcePreview.Text = m_strSource; - } - - private void UpdatePreview() - { - m_lvPreview.Items.Clear(); - // m_lvPreview.BeginUpdate(); - - string strDelimiter = m_tbSepChar.Text; - if(strDelimiter.Length == 0) return; - - char[] vPartTrimChars = new char[] { '\"' }; - int nLine = 0; - string[] vLines = m_strSource.Split(new char[] { '\r', '\n' }); - foreach(string strLine in vLines) - { - m_pbRender.Value = (100 * nLine) / vLines.Length; - ++nLine; - - if((strLine == null) || (strLine.Length == 0)) continue; - - List vParts = ImportUtil.SplitCsvLine(strLine, strDelimiter); - - for(int i = 0; i < vParts.Count; ++i) - vParts[i] = vParts[i].Trim(vPartTrimChars); - - ListViewItem lvi = new ListViewItem(string.Empty); - - lvi.Text = SafeListIndex(vParts, m_lvHeaderOrder.Columns[0].DisplayIndex); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[1].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[2].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[3].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[4].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[5].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[6].DisplayIndex)); - lvi.SubItems.Add(SafeListIndex(vParts, m_lvHeaderOrder.Columns[7].DisplayIndex)); - - m_lvPreview.Items.Add(lvi); - } - - m_pbRender.Value = 100; - // m_lvPreview.EndUpdate(); - } - - private static string SafeListIndex(List vList, int nIndex) - { - if(nIndex >= vList.Count) return string.Empty; - return vList[nIndex]; - } - - private void OnCmbEncodingSelectedIndexChanged(object sender, EventArgs e) - { - if(m_bBlockChangedEvent) return; - - UpdateStringSource(); - UpdatePreview(); - } - - private void OnDelimiterTextChanged(object sender, EventArgs e) - { - if(m_bBlockChangedEvent) return; - - UpdatePreview(); - } - - private void OnDoubleQuoteCheckedChanged(object sender, EventArgs e) - { - if(m_bBlockChangedEvent) return; - - UpdatePreview(); - } - - private void OnBtnPreviewRefresh(object sender, EventArgs e) - { - UpdatePreview(); - } - - private void OnFormClosed(object sender, FormClosedEventArgs e) - { - GlobalWindowManager.RemoveWindow(this); - } - } -} \ No newline at end of file diff --git a/Ext/DeprecatedSources/ImportCsvForm_120218.resx b/Ext/DeprecatedSources/ImportCsvForm_120218.resx deleted file mode 100644 index ff31a6d..0000000 --- a/Ext/DeprecatedSources/ImportCsvForm_120218.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Ext/DeprecatedSources/Kdb4File.Read.Dom.cs b/Ext/DeprecatedSources/Kdb4File.Read.Dom.cs deleted file mode 100644 index 24b4cca..0000000 --- a/Ext/DeprecatedSources/Kdb4File.Read.Dom.cs +++ /dev/null @@ -1,680 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2010 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Security; -using System.Security.Cryptography; -using System.Drawing; -using System.Xml; -using System.IO; -using System.Diagnostics; - -using KeePassLib; -using KeePassLib.Collections; -using KeePassLib.Cryptography; -using KeePassLib.Cryptography.Cipher; -using KeePassLib.Interfaces; -using KeePassLib.Security; -using KeePassLib.Utility; - -namespace KeePassLib.Serialization -{ - public sealed partial class Kdb4File - { - /* - private void ReadXmlDom(Stream readerStream) - { - XmlDocument doc = new XmlDocument(); - doc.Load(readerStream); - - XmlElement el = doc.DocumentElement; - ReadDocument(el); - } - - private void ReadDocument(XmlNode xmlRootNode) - { - Debug.Assert(xmlRootNode != null); - if(xmlRootNode == null) throw new ArgumentNullException("xmlRootNode"); - if(xmlRootNode.Name != ElemDocNode) throw new XmlException("xmlRootNode"); - - foreach(XmlNode xmlChild in xmlRootNode.ChildNodes) - { - string strNodeName = xmlChild.Name; - - if(strNodeName == ElemMeta) ReadMeta(xmlChild); - else if(strNodeName == ElemRoot) ReadRoot(xmlChild); - else ReadUnknown(xmlChild); - } - } - */ - - private void ReadUnknown(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - // if(m_slLogger != null) - // m_slLogger.SetText("Unknown field: " + xmlNode.Name, LogStatusType.Warning); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - ReadUnknown(xmlChild); - } - - private XorredBuffer ProcessNode(XmlNode xmlNode) - { - Debug.Assert(xmlNode != null); - if(xmlNode == null) throw new ArgumentNullException("xmlNode"); - - XmlAttributeCollection xac = xmlNode.Attributes; - if(xac == null) return null; - - XmlNode xmlProtected = xac.GetNamedItem(AttrProtected); - if(xmlProtected != null) - { - if(xmlProtected.Value == ValTrue) - { - string strInner = xmlNode.InnerText; - - byte[] pbEncrypted; - if(strInner.Length > 0) - pbEncrypted = Convert.FromBase64String(strInner); - else pbEncrypted = new byte[0]; - - byte[] pbPad = m_randomStream.GetRandomBytes((uint)pbEncrypted.Length); - - return new XorredBuffer(pbEncrypted, pbPad); - } - } - - return null; - } - - /* - private void ReadMeta(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemGenerator) { } // Ignore - else if(strName == ElemDbName) - m_pwDatabase.Name = ReadString(xmlChild); - else if(strName == ElemDbNameChanged) - m_pwDatabase.NameChanged = ReadTime(xmlChild); - else if(strName == ElemDbDesc) - m_pwDatabase.Description = ReadString(xmlChild); - else if(strName == ElemDbDescChanged) - m_pwDatabase.DescriptionChanged = ReadTime(xmlChild); - else if(strName == ElemDbDefaultUser) - m_pwDatabase.DefaultUserName = ReadString(xmlChild); - else if(strName == ElemDbDefaultUserChanged) - m_pwDatabase.DefaultUserNameChanged = ReadTime(xmlChild); - else if(strName == ElemDbMntncHistoryDays) - m_pwDatabase.MaintenanceHistoryDays = ReadUInt(xmlChild, 365); - else if(strName == ElemDbKeyChanged) - m_pwDatabase.MasterKeyChanged = ReadTime(xmlChild); - else if(strName == ElemDbKeyChangeRec) - m_pwDatabase.MasterKeyChangeRec = ReadLong(xmlChild, -1); - else if(strName == ElemDbKeyChangeForce) - m_pwDatabase.MasterKeyChangeForce = ReadLong(xmlChild, -1); - else if(strName == ElemMemoryProt) - ReadMemoryProtection(xmlChild); - else if(strName == ElemCustomIcons) - ReadCustomIcons(xmlChild); - else if(strName == ElemRecycleBinEnabled) - m_pwDatabase.RecycleBinEnabled = ReadBool(xmlChild, true); - else if(strName == ElemRecycleBinUuid) - m_pwDatabase.RecycleBinUuid = ReadUuid(xmlChild); - else if(strName == ElemRecycleBinChanged) - m_pwDatabase.RecycleBinChanged = ReadTime(xmlChild); - else if(strName == ElemEntryTemplatesGroup) - m_pwDatabase.EntryTemplatesGroup = ReadUuid(xmlChild); - else if(strName == ElemEntryTemplatesGroupChanged) - m_pwDatabase.EntryTemplatesGroupChanged = ReadTime(xmlChild); - else if(strName == ElemLastSelectedGroup) - m_pwDatabase.LastSelectedGroup = ReadUuid(xmlChild); - else if(strName == ElemLastTopVisibleGroup) - m_pwDatabase.LastTopVisibleGroup = ReadUuid(xmlChild); - else if(strName == ElemCustomData) - ReadStringDictEx(xmlChild, m_pwDatabase.CustomData); - else ReadUnknown(xmlChild); - } - } - - private void ReadMemoryProtection(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemProtTitle) - m_pwDatabase.MemoryProtection.ProtectTitle = ReadBool(xmlChild, false); - else if(strName == ElemProtUserName) - m_pwDatabase.MemoryProtection.ProtectUserName = ReadBool(xmlChild, false); - else if(strName == ElemProtPassword) - m_pwDatabase.MemoryProtection.ProtectPassword = ReadBool(xmlChild, true); - else if(strName == ElemProtUrl) - m_pwDatabase.MemoryProtection.ProtectUrl = ReadBool(xmlChild, false); - else if(strName == ElemProtNotes) - m_pwDatabase.MemoryProtection.ProtectNotes = ReadBool(xmlChild, false); - // else if(strName == ElemProtAutoHide) - // m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = ReadBool(xmlChild, true); - else ReadUnknown(xmlChild); - } - } - - private void ReadCustomIcons(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemCustomIconItem) - ReadCustomIcon(xmlChild); - else ReadUnknown(xmlChild); - } - } - - private void ReadCustomIcon(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - PwUuid uuid = PwUuid.Zero; - byte[] pbImageData = null; - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemCustomIconItemID) - uuid = ReadUuid(xmlChild); - else if(strName == ElemCustomIconItemData) - { - string str = ReadString(xmlChild); - - if((str != null) && (str.Length > 0)) - pbImageData = Convert.FromBase64String(str); - else { Debug.Assert(false); } - } - else ReadUnknown(xmlChild); - } - - if((uuid != PwUuid.Zero) && (pbImageData != null)) - m_pwDatabase.CustomIcons.Add(new PwCustomIcon(uuid, pbImageData)); - else { Debug.Assert(false); } - } - - private void ReadRoot(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - bool bFoundDataGroup = false; - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemGroup) - { - if(!bFoundDataGroup) - { - m_pwDatabase.RootGroup = ReadGroup(xmlChild); - bFoundDataGroup = true; - } - else { Debug.Assert(false); ReadUnknown(xmlChild); } - } - else if(strName == ElemDeletedObjects) - { - ReadDeletedObjects(xmlChild, m_pwDatabase.DeletedObjects); - } - else ReadUnknown(xmlChild); - } - - Debug.Assert(m_pwDatabase.RootGroup != null); - Debug.Assert(m_pwDatabase.RootGroup.ParentGroup == null); - } - - private PwGroup ReadGroup(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - PwGroup pgStorage = new PwGroup(false, false); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemUuid) pgStorage.Uuid = ReadUuid(xmlChild); - else if(strName == ElemName) pgStorage.Name = ReadString(xmlChild); - else if(strName == ElemNotes) pgStorage.Notes = ReadString(xmlChild); - else if(strName == ElemIcon) pgStorage.IconID = (PwIcon)ReadUInt(xmlChild, (uint)PwIcon.Key); - else if(strName == ElemCustomIconID) pgStorage.CustomIconUuid = ReadUuid(xmlChild); - else if(strName == ElemTimes) ReadTimes(xmlChild, pgStorage); - else if(strName == ElemIsExpanded) - pgStorage.IsExpanded = ReadBool(xmlChild, true); - else if(strName == ElemGroupDefaultAutoTypeSeq) - pgStorage.DefaultAutoTypeSequence = ReadString(xmlChild); - else if(strName == ElemEnableAutoType) - pgStorage.EnableAutoType = StrUtil.StringToBoolEx(ReadString(xmlChild)); - else if(strName == ElemEnableSearching) - pgStorage.EnableSearching = StrUtil.StringToBoolEx(ReadString(xmlChild)); - else if(strName == ElemLastTopVisibleEntry) - pgStorage.LastTopVisibleEntry = ReadUuid(xmlChild); - else if(strName == ElemGroup) - { - PwGroup pgSub = ReadGroup(xmlChild); - pgSub.ParentGroup = pgStorage; - pgStorage.Groups.Add(pgSub); - } - else if(strName == ElemEntry) - { - PwEntry pe = ReadEntry(xmlChild); - pgStorage.AddEntry(pe, true); - } - else ReadUnknown(xmlChild); - } - - // Create new UUID if absent - if(PwUuid.Zero.EqualsValue(pgStorage.Uuid)) - pgStorage.Uuid = new PwUuid(true); // No assert (import) - - return pgStorage; - } - */ - - private PwEntry ReadEntry(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - PwEntry pe = new PwEntry(false, false); - - Debug.Assert(Color.Empty.ToArgb() == 0); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - string strName = xmlChild.Name; - - if(strName == ElemUuid) pe.Uuid = ReadUuid(xmlChild); - else if(strName == ElemIcon) - pe.IconId = (PwIcon)ReadUInt(xmlChild, (uint)PwIcon.Key); - else if(strName == ElemCustomIconID) - pe.CustomIconUuid = ReadUuid(xmlChild); - else if(strName == ElemFgColor) - { - string strColor = ReadString(xmlChild); - if((strColor != null) && (strColor.Length > 0)) - pe.ForegroundColor = ColorTranslator.FromHtml(strColor); - } - else if(strName == ElemBgColor) - { - string strColor = ReadString(xmlChild); - if((strColor != null) && (strColor.Length > 0)) - pe.BackgroundColor = ColorTranslator.FromHtml(strColor); - } - else if(strName == ElemOverrideUrl) - pe.OverrideUrl = ReadString(xmlChild); - else if(strName == ElemTags) - pe.Tags = StrUtil.StringToTags(ReadString(xmlChild)); - else if(strName == ElemTimes) ReadTimes(xmlChild, pe); - else if(strName == ElemString) ReadProtectedStringEx(xmlChild, pe.Strings); - else if(strName == ElemBinary) ReadProtectedBinaryEx(xmlChild, pe.Binaries); - else if(strName == ElemAutoType) ReadAutoType(xmlChild, pe.AutoType); - else if(strName == ElemHistory) ReadHistory(xmlChild, pe.History); - else ReadUnknown(xmlChild); - } - - // Create new UUID if absent - if(PwUuid.Zero.EqualsValue(pe.Uuid)) - pe.Uuid = new PwUuid(true); // No assert (import) - - return pe; - } - - private void ReadTimes(XmlNode xmlNode, ITimeLogger times) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode) - { - string strName = xmlChild.Name; - - if(strName == ElemLastModTime) - times.LastModificationTime = ReadTime(xmlChild); - else if(strName == ElemCreationTime) - times.CreationTime = ReadTime(xmlChild); - else if(strName == ElemLastAccessTime) - times.LastAccessTime = ReadTime(xmlChild); - else if(strName == ElemExpiryTime) - times.ExpiryTime = ReadTime(xmlChild); - else if(strName == ElemExpires) - times.Expires = ReadBool(xmlChild, false); - else if(strName == ElemUsageCount) - times.UsageCount = ReadULong(xmlChild, 0); - else if(strName == ElemLocationChanged) - times.LocationChanged = ReadTime(xmlChild); - else - ReadUnknown(xmlChild); - } - } - - private string ReadString(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - return xmlNode.InnerText; - } - - private bool ReadBool(XmlNode xmlNode, bool bDefault) - { - ProcessNode(xmlNode); - - string str = xmlNode.InnerText; - if(str == ValTrue) return true; - else if(str == ValFalse) return false; - - Debug.Assert(false); - return bDefault; - } - - private PwUuid ReadUuid(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - if(string.IsNullOrEmpty(xmlNode.InnerText)) return PwUuid.Zero; - return new PwUuid(Convert.FromBase64String(xmlNode.InnerText)); - } - - private uint ReadUInt(XmlNode xmlNode, uint uDefault) - { - ProcessNode(xmlNode); - - uint u; - if(StrUtil.TryParseUInt(xmlNode.InnerText, out u)) return u; - - Debug.Assert(false); - return uDefault; - } - - /* private long ReadLong(XmlNode xmlNode, long nDefault) - { - ProcessNode(xmlNode); - - long n; - if(StrUtil.TryParseLong(xmlNode.InnerText, out n)) return n; - - Debug.Assert(false); - return nDefault; - } */ - - private ulong ReadULong(XmlNode xmlNode, ulong uDefault) - { - ProcessNode(xmlNode); - - ulong u; - if(StrUtil.TryParseULong(xmlNode.InnerText, out u)) return u; - - Debug.Assert(false); - return uDefault; - } - - private DateTime ReadTime(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - DateTime dt; - if(TimeUtil.TryDeserializeUtc(xmlNode.InnerText, out dt)) return dt; - - Debug.Assert(false); - return m_dtNow; - } - - private void ReadProtectedStringEx(XmlNode xmlNode, ProtectedStringDictionary dictStorage) - { - ProcessNode(xmlNode); - - string strKey = string.Empty; - XorredBuffer xbValue = null; - string strValue = null; - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemKey) - { - ProcessNode(xmlChild); - strKey = xmlChild.InnerText; - } - else if(xmlChild.Name == ElemValue) - { - xbValue = ProcessNode(xmlChild); - - // If contents aren't protected: read as plain-text string - if(xbValue == null) strValue = xmlChild.InnerText; - } - else ReadUnknown(xmlChild); - } - - if(xbValue != null) - { - Debug.Assert(strValue == null); - dictStorage.Set(strKey, new ProtectedString(true, xbValue)); - } - else - { - Debug.Assert(strValue != null); - dictStorage.Set(strKey, new ProtectedString(false, strValue)); - } - -#if DEBUG - if(m_format == Kdb4Format.Default) - { - if(strKey == PwDefs.TitleField) - { - Debug.Assert(m_pwDatabase.MemoryProtection.ProtectTitle == - dictStorage.Get(strKey).IsProtected); - } - else if(strKey == PwDefs.UserNameField) - { - Debug.Assert(m_pwDatabase.MemoryProtection.ProtectUserName == - dictStorage.Get(strKey).IsProtected); - } - else if(strKey == PwDefs.PasswordField) - { - Debug.Assert(m_pwDatabase.MemoryProtection.ProtectPassword == - dictStorage.Get(strKey).IsProtected); - } - else if(strKey == PwDefs.UrlField) - { - Debug.Assert(m_pwDatabase.MemoryProtection.ProtectUrl == - dictStorage.Get(strKey).IsProtected); - } - else if(strKey == PwDefs.NotesField) - { - Debug.Assert(m_pwDatabase.MemoryProtection.ProtectNotes == - dictStorage.Get(strKey).IsProtected); - } - } -#endif - } - - private void ReadProtectedBinaryEx(XmlNode xmlNode, ProtectedBinaryDictionary dictStorage) - { - ProcessNode(xmlNode); - - string strKey = string.Empty; - XorredBuffer xbValue = null; - byte[] pbValue = null; - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemKey) - { - ProcessNode(xmlChild); - strKey = xmlChild.InnerText; - } - else if(xmlChild.Name == ElemValue) - { - xbValue = ProcessNode(xmlChild); - - if(xbValue == null) - { - string strInner = xmlChild.InnerText; - - if(strInner.Length > 0) - pbValue = Convert.FromBase64String(strInner); - else pbValue = new byte[0]; - } - } - else ReadUnknown(xmlChild); - } - - if(xbValue != null) - { - Debug.Assert(pbValue == null); - dictStorage.Set(strKey, new ProtectedBinary(true, xbValue)); - } - else - { - Debug.Assert(pbValue != null); - dictStorage.Set(strKey, new ProtectedBinary(false, pbValue)); - } - } - - private void ReadAutoType(XmlNode xmlNode, AutoTypeConfig atConfig) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemAutoTypeEnabled) - atConfig.Enabled = ReadBool(xmlChild, true); - else if(xmlChild.Name == ElemAutoTypeObfuscation) - atConfig.ObfuscationOptions = - (AutoTypeObfuscationOptions)ReadUInt(xmlChild, 0); - else if(xmlChild.Name == ElemAutoTypeDefaultSeq) - atConfig.DefaultSequence = ReadString(xmlChild); - else if(xmlChild.Name == ElemAutoTypeItem) - ReadAutoTypeItem(xmlChild, atConfig); - else ReadUnknown(xmlChild); - } - } - - private void ReadAutoTypeItem(XmlNode xmlNode, AutoTypeConfig atStorage) - { - ProcessNode(xmlNode); - - string strWindow = string.Empty, strKeySeq = string.Empty; - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemWindow) - strWindow = ReadString(xmlChild); - else if(xmlChild.Name == ElemKeystrokeSequence) - strKeySeq = ReadString(xmlChild); - else ReadUnknown(xmlChild); - } - - atStorage.Set(strWindow, strKeySeq); - } - - /* - private void ReadDeletedObjects(XmlNode xmlNode, PwObjectList list) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemDeletedObject) - list.Add(ReadDeletedObject(xmlChild)); - else ReadUnknown(xmlChild); - } - } - - private PwDeletedObject ReadDeletedObject(XmlNode xmlNode) - { - ProcessNode(xmlNode); - - PwDeletedObject pdo = new PwDeletedObject(); - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemUuid) - pdo.Uuid = ReadUuid(xmlChild); - else if(xmlChild.Name == ElemDeletionTime) - pdo.DeletionTime = ReadTime(xmlChild); - else ReadUnknown(xmlChild); - } - - return pdo; - } - */ - - private void ReadHistory(XmlNode xmlNode, PwObjectList plStorage) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemEntry) - { - plStorage.Add(ReadEntry(xmlChild)); - } - else ReadUnknown(xmlChild); - } - } - - /* - private void ReadStringDictEx(XmlNode xmlNode, StringDictionaryEx sdStorage) - { - ProcessNode(xmlNode); - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemStringDictExItem) - ReadStringDictExItem(xmlChild, sdStorage); - else ReadUnknown(xmlChild); - } - } - - private void ReadStringDictExItem(XmlNode xmlNode, StringDictionaryEx sdStorage) - { - ProcessNode(xmlNode); - - string strName = null, strValue = null; - - foreach(XmlNode xmlChild in xmlNode.ChildNodes) - { - if(xmlChild.Name == ElemKey) - strName = ReadString(xmlChild); - else if(xmlChild.Name == ElemValue) - strValue = ReadString(xmlChild); - else ReadUnknown(xmlChild); - } - - if((strName != null) && (strValue != null)) - m_pwDatabase.CustomData.Set(strName, strValue); - else { Debug.Assert(false); } - } - */ - } -} diff --git a/Ext/DeprecatedSources/KeePassCsv1x_120221.cs b/Ext/DeprecatedSources/KeePassCsv1x_120221.cs deleted file mode 100644 index 1cbde91..0000000 --- a/Ext/DeprecatedSources/KeePassCsv1x_120221.cs +++ /dev/null @@ -1,187 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2012 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; -using System.Drawing; -using System.IO; - -using KeePassLib; -using KeePassLib.Delegates; -using KeePassLib.Interfaces; -using KeePassLib.Security; -using KeePassLib.Utility; - -namespace KeePass.DataExchange.Formats -{ - internal sealed class KeePassCsv1x : FileFormatProvider - { - public override bool SupportsImport { get { return true; } } - public override bool SupportsExport { get { return true; } } - - public override string FormatName { get { return "KeePass CSV (1.x)"; } } - public override string DefaultExtension { get { return "csv"; } } - public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } - - public override bool ImportAppendsToRootGroupOnly { get { return true; } } - - public override Image SmallIcon - { - get { return KeePass.Properties.Resources.B16x16_KeePass; } - } - - public override void Import(PwDatabase pwStorage, Stream sInput, - IStatusLogger slLogger) - { - StreamReader sr = new StreamReader(sInput, Encoding.UTF8); - string strFileContents = sr.ReadToEnd(); - sr.Close(); - - CharStream csSource = new CharStream(strFileContents); - - while(true) - { - if(ReadEntry(pwStorage, csSource) == false) - break; - } - } - - private static bool ReadEntry(PwDatabase pwStorage, CharStream csSource) - { - PwEntry pe = new PwEntry(true, true); - - string strTitle = ReadCsvField(csSource); - if(strTitle == null) return false; // No entry available - - string strUser = ReadCsvField(csSource); - if(strUser == null) throw new InvalidDataException(); - - string strPassword = ReadCsvField(csSource); - if(strPassword == null) throw new InvalidDataException(); - - string strUrl = ReadCsvField(csSource); - if(strUrl == null) throw new InvalidDataException(); - - string strNotes = ReadCsvField(csSource); - if(strNotes == null) throw new InvalidDataException(); - - if((strTitle == "Account") && (strUser == "Login Name") && - (strPassword == "Password") && (strUrl == "Web Site") && - (strNotes == "Comments")) - { - return true; // Ignore header entry - } - - pe.Strings.Set(PwDefs.TitleField, new ProtectedString( - pwStorage.MemoryProtection.ProtectTitle, strTitle)); - pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( - pwStorage.MemoryProtection.ProtectUserName, strUser)); - pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( - pwStorage.MemoryProtection.ProtectPassword, strPassword)); - pe.Strings.Set(PwDefs.UrlField, new ProtectedString( - pwStorage.MemoryProtection.ProtectUrl, strUrl)); - pe.Strings.Set(PwDefs.NotesField, new ProtectedString( - pwStorage.MemoryProtection.ProtectNotes, strNotes)); - - pwStorage.RootGroup.AddEntry(pe, true); - return true; - } - - private static string ReadCsvField(CharStream csSource) - { - StringBuilder sb = new StringBuilder(); - bool bInField = false; - - while(true) - { - char ch = csSource.ReadChar(); - if(ch == char.MinValue) - return null; - - if((ch == '\"') && !bInField) - bInField = true; - else if((ch == '\"') && bInField) - break; - else if(ch == '\\') - { - char chSub = csSource.ReadChar(); - if(chSub == char.MinValue) - throw new InvalidDataException(); - - sb.Append(chSub); - } - else if(bInField) - sb.Append(ch); - } - - return sb.ToString(); - } - - public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, - IStatusLogger slLogger) - { - PwGroup pg = (pwExportInfo.DataGroup ?? ((pwExportInfo.ContextDatabase != - null) ? pwExportInfo.ContextDatabase.RootGroup : null)); - - StreamWriter sw = new StreamWriter(sOutput, new UTF8Encoding(false)); - sw.Write("\"Account\",\"Login Name\",\"Password\",\"Web Site\",\"Comments\"\r\n"); - - EntryHandler eh = delegate(PwEntry pe) - { - WriteCsvEntry(sw, pe); - return true; - }; - - if(pg != null) pg.TraverseTree(TraversalMethod.PreOrder, null, eh); - - sw.Close(); - return true; - } - - private static void WriteCsvEntry(StreamWriter sw, PwEntry pe) - { - if(sw == null) { Debug.Assert(false); return; } - if(pe == null) { Debug.Assert(false); return; } - - const string strSep = "\",\""; - - sw.Write("\""); - WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.TitleField), strSep); - WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UserNameField), strSep); - WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.PasswordField), strSep); - WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UrlField), strSep); - WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.NotesField), "\"\r\n"); - } - - private static void WriteCsvString(StreamWriter sw, string strText, - string strAppend) - { - string str = strText; - - str = str.Replace("\\", "\\\\"); - str = str.Replace("\"", "\\\""); - - sw.Write(str); - - if((strAppend != null) && (strAppend.Length > 0)) sw.Write(strAppend); - } - } -} diff --git a/Ext/DeprecatedSources/MainForm_110830.txt b/Ext/DeprecatedSources/MainForm_110830.txt deleted file mode 100644 index 7221fdf..0000000 --- a/Ext/DeprecatedSources/MainForm_110830.txt +++ /dev/null @@ -1,66 +0,0 @@ - /* public void RefreshEntriesList() - { - int nItemCount = m_lvEntries.Items.Count; - if(nItemCount <= 0) return; - - PwEntry peTop = GetTopEntry(); - PwEntry peFocused = GetSelectedEntry(false); - int iScrollY = NativeMethods.GetScrollPosY(m_lvEntries.Handle); - - UpdateImageLists(); // Important - - PwEntry[] vSelected = GetSelectedEntries(); - if(vSelected == null) vSelected = new PwEntry[0]; - - PwEntry[] vList = new PwEntry[nItemCount]; - for(int iEnum = 0; iEnum < nItemCount; ++iEnum) - vList[iEnum] = (PwEntry)m_lvEntries.Items[iEnum].Tag; - - m_lvEntries.BeginUpdate(); - m_lvEntries.Items.Clear(); - m_lvEntries.Groups.Clear(); - m_lvgLastEntryGroup = null; - - int nTopIndex = -1; - ListViewItem lviFocused = null; - - m_dtCachedNow = DateTime.Now; - ListViewStateEx lvseCachedState = new ListViewStateEx(m_lvEntries); - - for(int iAdd = 0; iAdd < nItemCount; ++iAdd) - { - PwEntry pe = vList[iAdd]; - - ListViewItem lvi = SetListEntry(pe, null); - - if(pe == peTop) nTopIndex = iAdd; - if(pe == peFocused) lviFocused = lvi; - - if(Array.IndexOf(vSelected, pe) >= 0) lvi.Selected = true; - } - - Debug.Assert(lvseCachedState.CompareTo(m_lvEntries)); - - UIUtil.SetAlternatingBgColors(m_lvEntries, m_clrAlternateItemBgColor, - Program.Config.MainWindow.EntryListAlternatingBgColors); - - Debug.Assert(m_bEntryGrouping == m_lvEntries.ShowGroups); - if(m_lvEntries.ShowGroups) - { - // Test nTopIndex to ensure we're not scrolling an unrelated list - if((nTopIndex >= 0) && (iScrollY > 0)) - NativeMethods.Scroll(m_lvEntries, 0, iScrollY); - } - else - { - if(nTopIndex >= 0) - { - m_lvEntries.EnsureVisible(m_lvEntries.Items.Count - 1); - m_lvEntries.EnsureVisible(nTopIndex); - } - } - - if(lviFocused != null) m_lvEntries.FocusedItem = lviFocused; - - m_lvEntries.EndUpdate(); - } */ diff --git a/Ext/DeprecatedSources/PasswordListPrintDocument_110101.cs b/Ext/DeprecatedSources/PasswordListPrintDocument_110101.cs deleted file mode 100644 index fe1b7c4..0000000 --- a/Ext/DeprecatedSources/PasswordListPrintDocument_110101.cs +++ /dev/null @@ -1,165 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2011 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* -using System; -using System.Collections.Generic; -using System.Text; -using System.Drawing; -using System.Drawing.Printing; -using System.Windows.Forms; -using System.Diagnostics; - -using KeePassLib; -using KeePassLib.Delegates; -using KeePassLib.Security; - -namespace KeePass.UI -{ - internal sealed class PasswordListLine - { - public PwIcon IconID = PwIcon.None; - public PwUuid CustomIcon = null; - public List TextFields = new List(); - } - - public sealed class PasswordListPrintDocument : PrintDocument - { - private PwGroup m_pgDataSource = null; - - private Font m_fontNormal = null; - private Font m_fontPassword = null; - - private List m_vLines = new List(); - private int m_nCurrentLine = 0; - - public PasswordListPrintDocument(PwGroup pgDataSource) - { - Debug.Assert(pgDataSource != null); - if(pgDataSource == null) throw new ArgumentNullException("pgDataSource"); - - m_pgDataSource = pgDataSource; - } - - private void DisposePrinterFont(ref Font f) - { - if(f != null) - { - f.Dispose(); - f = null; - } - } - - protected override void OnBeginPrint(PrintEventArgs e) - { - base.OnBeginPrint(e); - - RenderDocument(e); - - m_fontNormal = new Font(FontFamily.GenericSansSerif, 10.0f); - m_fontPassword = new Font(FontFamily.GenericMonospace, 10.0f); - } - - protected override void OnEndPrint(PrintEventArgs e) - { - base.OnEndPrint(e); - - DisposePrinterFont(ref m_fontNormal); - DisposePrinterFont(ref m_fontPassword); - } - - protected override void OnPrintPage(PrintPageEventArgs e) - { - base.OnPrintPage(e); - - Graphics g = e.Graphics; - - float fLeft = e.MarginBounds.Left; - float fRight = e.MarginBounds.Right; - float fTop = e.MarginBounds.Top; - float fBottom = e.MarginBounds.Bottom; - float fWidth = fRight - fLeft; - - string strTestText = @"WJygpqQIL|°"; - float fNormalHeight = TextRenderer.MeasureText(g, strTestText, - m_fontNormal).Height; - float fPasswordHeight = TextRenderer.MeasureText(g, strTestText, - m_fontPassword).Height; - - float fLineHeight = Math.Max(fNormalHeight, fPasswordHeight); - - float fCurrentY = fTop; - - while(true) - { - if((fCurrentY + fLineHeight) >= fBottom) - break; - - PasswordListLine pll = m_vLines[m_nCurrentLine]; - int nTextCount = pll.TextFields.Count; - - for(int iField = 0; iField < nTextCount; ++iField) - { - PointF ptText = new PointF((fWidth * iField) / nTextCount, - fCurrentY); - - g.DrawString(pll.TextFields[iField], m_fontNormal, - Brushes.Black, ptText); - } - - fCurrentY += fLineHeight; - - ++m_nCurrentLine; - if(m_nCurrentLine == m_vLines.Count) break; - } - - e.HasMorePages = (m_nCurrentLine != m_vLines.Count); - } - - private void RenderDocument(PrintEventArgs e) - { - m_vLines.Clear(); - m_nCurrentLine = 0; - - GroupHandler gh = delegate(PwGroup pg) - { - return true; - }; - - EntryHandler eh = delegate(PwEntry pe) - { - PasswordListLine pll = new PasswordListLine(); - - pll.IconID = pe.IconID; - pll.CustomIcon = pe.CustomIconUuid; - pll.TextFields.Add(pe.Strings.ReadSafe(PwDefs.TitleField)); - pll.TextFields.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); - pll.TextFields.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); - pll.TextFields.Add(pe.Strings.ReadSafe(PwDefs.UrlField)); - pll.TextFields.Add(pe.Strings.ReadSafe(PwDefs.NotesField)); - - m_vLines.Add(pll); - return true; - }; - - m_pgDataSource.TraverseTree(TraversalMethod.PreOrder, gh, eh); - } - } -} -*/ diff --git a/Ext/DeprecatedSources/PopularPasswords_100725.cs b/Ext/DeprecatedSources/PopularPasswords_100725.cs deleted file mode 100644 index ed8cf57..0000000 --- a/Ext/DeprecatedSources/PopularPasswords_100725.cs +++ /dev/null @@ -1,369 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2010 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Security.Cryptography; -using System.Globalization; -using System.Diagnostics; - -using KeePassLib.Utility; - -namespace KeePassLib.Cryptography -{ - /// - /// Bloom filter-based popular password checking. - /// - public static class PopularPasswords - { - private const int PpcTableSize = 4096 * 8; // Bits, multiple of 64 - - // Bits set: 15719 of 32768 - // Hash functions: 16 - // Phi (bits unset ratio) estimation: 0.520486428116307 - // Exact Phi: 0.520294189453125 - // False positives ratio: 7.86320618801785E-06 - private static readonly ulong[] PpcTable = { - 0xE4489A3404344788UL, 0x86B25DB476F58AB7UL, 0xB581FAA53EA2342AUL, - 0x70B2C54E1E6762D0UL, 0x1AEEB1A9DF75C01BUL, 0xEE2B0C368A1FE6DAUL, - 0x02DC8D0E5CD9FC17UL, 0x6A449E23057C6560UL, 0x889E159F16E9681DUL, - 0x2686144C0927486FUL, 0x6C4AF58039D4E4D0UL, 0xC5AB193CD0077707UL, - 0x32399D528F7E1F07UL, 0xD6396059B4C04626UL, 0x0E0AF217323143B5UL, - 0x5BD81DA44A6EC64BUL, 0xC2B7AF8E93C4D482UL, 0x92E221F8F7D6F708UL, - 0x91E9933F20E90825UL, 0x5D0AD3B4F81061E3UL, 0x06101FFA010464E7UL, - 0xB10F259524E1BEAAUL, 0x81191B0D13812121UL, 0x2CBEF0BAE5896DA0UL, - 0x4187F900F4B164F8UL, 0x6362BB64B8507748UL, 0x3A622549FE71D89DUL, - 0x052819709952C6CFUL, 0x58EBFBDEACA4D82EUL, 0x2AA0001D0A33CCA0UL, - 0x19EF6C2C114DDC21UL, 0x937F5B504AE709F0UL, 0xD0CD4487EA84F479UL, - 0x169CA49DB21A1338UL, 0x307EF1001D232212UL, 0xB1A42ECB6F61051EUL, - 0x98E28AD44EA4D8F0UL, 0x65820520E5FC0830UL, 0xC231BE1D6054AAD5UL, - 0x3E61CEADDA6AD3A9UL, 0xCE1AA54066469E83UL, 0x3DE3666FB5653C57UL, - 0x39D894D5C6310CA5UL, 0x39CB8A2D5A49CB02UL, 0xDEC88143040007E7UL, - 0x371BFD3E22C20F6DUL, 0x93E1697B64CD8C89UL, 0x67CB5B14CC3ED9EDUL, - 0x6D10DA90332239D6UL, 0x6673DD254CD82162UL, 0x24089D15A893BB0FUL, - 0xEA4D11D96C16A203UL, 0xF70176A0E28539A8UL, 0x0DE6B18BA8966C86UL, - 0x856FC8659A6E9D7FUL, 0x7B726A5A2A6DE203UL, 0x0CFBC2911CB2CE63UL, - 0x6363D417490A0256UL, 0x541A26883DF51A45UL, 0xB37BE5AF83DA3AD1UL, - 0xE7B834E9000CA060UL, 0x841B2F8473222666UL, 0xE16CCFE7029B7E5EUL, - 0x3C08D6AABC226AC9UL, 0x0887968C7690498FUL, 0x3B12659FAC807598UL, - 0xD886F0364EC34407UL, 0x1B31A94B51E024F5UL, 0xC492A4F451800A11UL, - 0x6D89165B69494B89UL, 0x5B183AFD7A22D9B5UL, 0xCDFF381022100872UL, - 0xD29D38A72690562BUL, 0xEFBEE452E0B08682UL, 0x79D755AD7BC57506UL, - 0x38C5372ED560B720UL, 0xB42B16AA623D0378UL, 0x5166ECA60CC145F7UL, - 0x415C4A83F53FA99EUL, 0x3CA25AC6937A92F2UL, 0xDDEE63E44F2B5C9CUL, - 0x580EE47F5FC58ABAUL, 0x7AA9763C6E7BBBD5UL, 0x80420F1F81FBF086UL, - 0xC882A993C8A6AAA0UL, 0x2AE686154F8B3C1AUL, 0x30FE1DA4CA7C74EDUL, - 0x6062AD6F3A825452UL, 0xC53E126449486920UL, 0x9C02CADB149D340CUL, - 0x640F66F165EB961DUL, 0xAC20B871E28D20D6UL, 0x208E878696510DE9UL, - 0x0E9526E74040EE6CUL, 0x39AF5257605AF29EUL, 0x9E0B4A4F372E14ACUL, - 0x74143CD2D734F14DUL, 0x426496359E685811UL, 0x7B63BF2DB9B343C6UL, - 0xB3B40017B49BC96BUL, 0x4BE5B132E6AD8F35UL, 0x0CBDF68541C060F2UL, - 0x5D822A6CF8548376UL, 0xADC77581F25106E4UL, 0x4E91EC63FE2E5847UL, - 0x95167F55FC249D81UL, 0xD4D8F7E04A9F1845UL, 0xD4B55F3F350F10DEUL, - 0x310E105A026E91F8UL, 0xA1DF7398366C1398UL, 0x19D187ADC6C2C26DUL, - 0x1A20235761A2ED08UL, 0xA0B65B813345E3FCUL, 0x208EDBEA6828239FUL, - 0x6745B0810E0DC190UL, 0xDB09F52112896186UL, 0xAAFD7E27B0760AC0UL, - 0x7081DDCC1AEF30F3UL, 0x12744B39E6A8A1E8UL, 0x59A0166D773C5BE4UL, - 0x25426A44E348A784UL, 0x2F117FAF2464B3EFUL, 0x07DE883BA546C9F0UL, - 0x81260E8469A42391UL, 0x7528100996040644UL, 0xB20E1E42F1601FAEUL, - 0x68C9A1A96C5D7002UL, 0x3AE9934E86D51BADUL, 0xCF095403DAC63ED5UL, - 0xAB6F755ECB8064C8UL, 0x8480C7D61D55829FUL, 0x1E7A383A70CBFA6FUL, - 0x2ED63359316544BAUL, 0x4ACCC761760FC489UL, 0x9B668054F469AE2DUL, - 0xCA231AB3FE49327BUL, 0x9164054162F1567BUL, 0x0E276E3BC1FA10AEUL, - 0xB47E34300405D7EFUL, 0xA50FD0B6BF67C75FUL, 0x62BCA28A13A5C2B9UL, - 0x9884F6008C2AE25BUL, 0x80F0D9722D30215CUL, 0xF702F1093AA6AD69UL, - 0x11ECD08A62B902ACUL, 0x32EADD0519A8F117UL, 0x784E07D4E2026220UL, - 0x3803CAC2CDDC9FCDUL, 0x9F55A4559CF9FBCAUL, 0xB64A7C5991550497UL, - 0x632DEF7CE48765A1UL, 0xB7EEC58454987009UL, 0xB798651B5C588074UL, - 0xCF177657608C684FUL, 0x09B886763311529FUL, 0x13279B25F38E9078UL, - 0x4494804869BB8200UL, 0xF3316EF9A5693494UL, 0x6E0DA3E544E21ED9UL, - 0x087F84F0538BD741UL, 0xBC877CCA688983C5UL, 0xF733E7057A2661B4UL, - 0xB503AD77C9E83B23UL, 0x8FB6B2560FCAE443UL, 0xC10E770A2389C1F4UL, - 0x4BBEE81101789902UL, 0xCF28D640F2C4EE03UL, 0xB5FA56647A0D246EUL, - 0xE0E13635CC3A003CUL, 0xAF321B876375B0E0UL, 0x5CC1F60F2CEC1947UL, - 0x6D79F85C6C3E2178UL, 0x8C5105F188F59F48UL, 0xF026E4771132D495UL, - 0x68806C37457C8A11UL, 0xAC4FCFE08FF935E9UL, 0x02C9ED0DE36DEAD0UL, - 0x736E789114C176C0UL, 0x018484BB3F90C627UL, 0xADE11EBC06679C81UL, - 0xDC12310CF4646120UL, 0x565939720A871E91UL, 0x5129FA305D5F80D8UL, - 0x2F1978C44B222F66UL, 0xB2019E9C3C9223A3UL, 0xC26E8310561ABA8BUL, - 0x4C3268947F138A08UL, 0x1B10F12838C2F672UL, 0x3DD765F24A8EAD63UL, - 0xAC255685D091756CUL, 0x1EE8F33DAB66696EUL, 0xDCC69A9317A640E4UL, - 0xB3E10F8B1451577BUL, 0x9C989C1D83694926UL, 0x76C223945AE55AC5UL, - 0x3A5B5A5BA089C4F4UL, 0x5FF9863504F6D63AUL, 0x2BA33660EBC2D7B2UL, - 0xA90E90345E800C21UL, 0xE5C1C600199418DFUL, 0xB05541ED4A60E891UL, - 0xA79B38C035129539UL, 0x101AE63623F00D19UL, 0x86AEF221B04AE1E6UL, - 0x2D5FB8BDF5DD4537UL, 0xCF57F9D3F420CD52UL, 0x41FAB56E1CBEDE7DUL, - 0x4E31A70953DE2053UL, 0xB697E044F555FB02UL, 0x9E32B905F6B54765UL, - 0x0EE565A5E3C49262UL, 0x0E2BEB43000C0363UL, 0xBABF2096A749073FUL, - 0xDE0C27F78E1B89D9UL, 0x14878D174A34D220UL, 0x49189778D3782CF7UL, - 0xC4E37E8E0AFBE8FFUL, 0x0553DB16D17599F3UL, 0xE5324CCC7E3DFAF6UL, - 0x1002D714B914D3E3UL, 0x2C8C0DF862CF9D90UL, 0x552817B44DFF5733UL, - 0xD343B93EE79DA789UL, 0x5B70BB23756C998AUL, 0xB4E79BF903F1B28EUL, - 0xFEC69776A1728BC1UL, 0x3B3481B27815701CUL, 0x8028717CB8AB7835UL, - 0x15C681958C8DAE00UL, 0x44D5CEAEF0A1563CUL, 0x6BB90C05209F1A8EUL, - 0x1323A9FA431DC10DUL, 0x50C7BFFE3DB35371UL, 0x613D8488D33B6D4FUL, - 0x6C300351CF14A712UL, 0xD451A406E06F92D2UL, 0x9D48DC26ABA018B3UL, - 0x1F4573A97CA5FDBAUL, 0x6E65AE090F50F2FBUL, 0x1EBA1E084584BFB3UL, - 0x58BC501FBF7AC020UL, 0x0CF6120722B5D600UL, 0x4ABC91E6DC5000EEUL, - 0x9CBD9C3911614606UL, 0x0BDC8E1A1650977FUL, 0x90383FB6559BCB49UL, - 0x42B98DA163D4411DUL, 0x1C4582B0DBE9F911UL, 0x372C888720E79B05UL, - 0x906560A343786D02UL, 0x9E233DF7175BD4FEUL, 0x4EB66BA91A9C41BFUL, - 0x41FDB3460AC6F231UL, 0x79DB680FA3BA9330UL, 0x5A541224CD43333DUL, - 0x9F3E5B722C0AEEE1UL, 0xA91711FDED89836EUL, 0x80E21258E3E49714UL, - 0x7819026EF352AD7FUL, 0xC293097A18EBEB58UL, 0xCDD60C0948E07C98UL, - 0x444C2170AC4C972AUL, 0xB714CA937966E535UL, 0x6F11F3358AFA71BCUL, - 0xA84E8A3E6892C978UL, 0xE6308B5D0DB90822UL, 0x46E0A95E998B2B86UL, - 0x6A5C6F56AEA55DDBUL, 0x1DB0599111046F3EUL, 0x55D6DB893B553280UL, - 0x62C8F9D71B387563UL, 0x3389047820C4085CUL, 0xA744C6E6B040304BUL, - 0xFD5D213F3F48497DUL, 0xCC5B2117B6532683UL, 0xDC1C19721683F83DUL, - 0x1CB8405C21EB9AADUL, 0x8DB81937DF5C01B6UL, 0x99C6DF745BB3FAEBUL, - 0x450BEAA37F336CEDUL, 0xF0154CEB08FB4623UL, 0xA00293117E29034BUL, - 0xA66DD9AC091740E8UL, 0xB4E7455E47738348UL, 0x9BF6AB384A17588BUL, - 0x355EA7E660615307UL, 0x29973430E7BD32C1UL, 0xFCF99196BA1453FEUL, - 0x561E4A9749A31000UL, 0x996E40ACB907907CUL, 0x8C068A537891D817UL, - 0xDB42112F997B7851UL, 0xFA785497B0DBA777UL, 0x28AEF904C18EE0E3UL, - 0x8A70C563CE4B4567UL, 0x56A968C07D246D99UL, 0xFD327FAD0450EF8DUL, - 0x00C7DA2B6C9F79F5UL, 0xCF6280916EBF0129UL, 0xAC978A54BDD2071DUL, - 0x2D41D3E0C76E3F32UL, 0x63425615DB3281B4UL, 0x481BB08F50D69823UL, - 0x5F80EE74AC0BE2BDUL, 0x0D3AC9CC76A2D632UL, 0xEDB7C0E219D80DFAUL, - 0xCD2FA275D82EB2B6UL, 0x41898B02F28A159DUL, 0x1BD46018489C80B8UL, - 0x3AE0AECD4BB1127DUL, 0xA0FF48E7432058DFUL, 0xD1CC9C721482F42CUL, - 0x7B0FB481B5F19E03UL, 0xA221FDB32FC9174BUL, 0x1FE31F128748AD5CUL, - 0xA9C80E0BB849C784UL, 0x9725ED5C207DEAB2UL, 0x8EEC7C5310933D31UL, - 0xDE590C192A0B27B4UL, 0xE51CE519B6437021UL, 0x6E1057997FB1DEAEUL, - 0xC57DF8FEB45EE6A4UL, 0xDE24D5C87D4555E2UL, 0xF00FC5511FE008C1UL, - 0xC664EFBB36A481EDUL, 0x58688CC427EC4CC7UL, 0x254829013B0E76AEUL, - 0xECD1857ED61869A5UL, 0x64CE789BDE508F7DUL, 0xF295CAAA594ECC58UL, - 0x8F5B58B79C94EBE0UL, 0xA39BF312E6C61A6CUL, 0x0D00969829C5502BUL, - 0xB8C13C1FC5CB718DUL, 0x3224118DA915B5EFUL, 0x10EC24C2121DD4D7UL, - 0x1FB788E5D8E03357UL, 0x5E9F86D0099CE632UL, 0x673ED65F677821B0UL, - 0x312A41E1B51549F9UL, 0x00DF25E45DAD76E2UL, 0x5A1561911C876B19UL, - 0x1A58EF968CC11787UL, 0x029599EB8BD8719AUL, 0xEA27B36FFF5930F7UL, - 0x04060010169D7A62UL, 0x5630B4458FBA3A71UL, 0xB9CB8F84D66A93F8UL, - 0x3428A1C10490B5BAUL, 0x7E5857F34A1482F7UL, 0xCC62980D2ADAC41DUL, - 0x903EC89CC55BD0CEUL, 0xFE9EC99089004024UL, 0xECD3E226F9BE420CUL, - 0x17475B3D71CCA656UL, 0x5CCBD2176CA8DE01UL, 0xB13675D62856894CUL, - 0x744032E639C3F11FUL, 0x0E349612CEAF382AUL, 0x41E516CDA67BB4DCUL, - 0x343CB2990641694AUL, 0xEF1EE7E82B7E65CAUL, 0x32D3BD01D421A7CBUL, - 0xD7FC605717AF512CUL, 0x62D776335ACAA6A6UL, 0xFDA7C7EFBEFFB24DUL, - 0x1DA4421BE204563FUL, 0x7AC5071D7D6439ECUL, 0xB04907D74291F402UL, - 0x1622EAB93909C0BEUL, 0x0104D4A240D85592UL, 0x902DAC0ADEE44311UL, - 0xC1A9DFE403C0DA20UL, 0xF625780DB1B3F871UL, 0x75AB40C313DF9E55UL, - 0xDFAE2CD087187B45UL, 0x417D7807D2171F9FUL, 0xCD1D1A444D86DF78UL, - 0x87DE186A752CDB73UL, 0xEDEBA23523A0DC64UL, 0x10AA6B0C35F6B110UL, - 0x38C31C863D4F4ED5UL, 0x7A4665420070B621UL, 0x4F2B5963CE4F5F6CUL, - 0x1960F7AD866513A3UL, 0x3A7C924A978F8251UL, 0x56B8481940FDF39AUL, - 0x11643EEFEEE1ACA6UL, 0xED127C507EF6C54CUL, 0xB5EBD3BFA89E9F67UL, - 0x21879F26D4BE4A14UL, 0x8D6154A8A2027EA6UL, 0x1C69E882730B93C8UL, - 0x8D7B11D1DD98B5F2UL, 0x76A7FAA7A888B1FBUL, 0x90A971E4C8F7AE28UL, - 0x56A4D02DF123F5EAUL, 0x44A05664A7F03956UL, 0x309C6C63418B2616UL, - 0x108CA042607E272AUL, 0x4AB8F3508ADDA60CUL, 0xA7FBBAF0BB17714BUL, - 0x3CC8A384E2D96A84UL, 0x391E782A19AD5190UL, 0x23065DCE40659703UL, - 0xC530D54413A3791EUL, 0x803E3C294BE1C26EUL, 0x61ABAAC14D74EC54UL, - 0xA4F72A046456894DUL, 0x242893DB0DB83BB0UL, 0xD34E3160ADCB5CAFUL, - 0x70DC7C26C140E652UL, 0xC61E965117931ED2UL, 0x6E292C67D1F4C3A7UL, - 0xCBF4C4668630AD09UL, 0x89E71E5660F60C09UL, 0xB94E78B3D69CF448UL, - 0x34F7E505129E67E8UL, 0x2B5692EB2F9ADB1FUL, 0x18B33EB5C6218B92UL, - 0x69B0107420A2245FUL, 0x882D9A53746BB452UL, 0xD672B7869EA7CFD9UL, - 0x19A7272D0738C53FUL, 0x1322E47C89337EB2UL, 0x812E69C0245E50D7UL, - 0xF187AA4541ABDDD3UL, 0x8FEAA798A615B748UL, 0x667E3C139D8B56C8UL, - 0xAEC9BF9F45CA5D44UL, 0xFBB9142069E57883UL, 0x094C75FB9845661DUL, - 0x23A6C5F02F3A6C55UL, 0x9A16DA92770C6ECCUL, 0xF748C20B24D1DC6FUL, - 0x7ACB623BBD295332UL, 0xEAEF79479E38A94CUL, 0x704D58570E2E5332UL, - 0x036F52F5A9684E7CUL, 0xEC738490914BA27EUL, 0xF9278559E81D901EUL, - 0x49821AAC204B64C2UL, 0x990985242F9C9A31UL, 0x06A3649A1BA11E75UL, - 0xE4A1A9808B319814UL, 0x18A4498A7BBA0060UL, 0x75ED340849D3CCA3UL, - 0x82225D786972A9E0UL, 0x8EADE60B8E678CD5UL, 0xC99BB41C1726AABDUL, - 0x2AB9C9C8FAC6DC30UL, 0x0441780010493500UL, 0xDDDDE54767F517ADUL, - 0x56DB8BCC493B8490UL, 0xD1A6739A09D42053UL, 0x617912F0246C3648UL, - 0x6ADF565B9B17101DUL, 0x0CA0C0BEC98D33BBUL, 0xC920D715A451BC53UL, - 0xA10E436864547E8FUL, 0x8A2686E7564305BAUL, 0xF5454820A996BC1FUL, - 0xC9216226D09DDC39UL, 0x68A0E58CAE5C7DB9UL, 0x7F5252D3EA712008UL, - 0x5BC5B55C5F4A9803UL, 0xAFC544F4F2E4002EUL, 0x6C42C429889A7D5CUL, - 0x2F4F73AA425DEFA6UL, 0x2E6AFD00A266DEF0UL, 0x49CACCAAE1B2C278UL, - 0xB62663F96D79781DUL, 0x87E5E67912BAD6F9UL, 0x93BF4AB146F447CFUL, - 0xC942B3D03448F513UL, 0x50B6C04EC1C35605UL, 0x010B453F9ACBF9DDUL, - 0x84CB000D0AA3E002UL, 0xB0AFA8BD656B2A9AUL, 0x736BC06ADC0DBADFUL, - 0x18C9AE72A4F7F14DUL, 0x8B20226817FED9F7UL, 0x488201718D3F25AAUL, - 0xB436031BF234430AUL, 0x301B579C25A81F6CUL, 0x94AD1143EF48395BUL, - 0xD18DAC91770DE980UL, 0xB8B8E0C504956DE5UL, 0xDDC58A6B8AF36BD0UL, - 0x70288138236C8C2EUL, 0x12566E4A4C2B5769UL, 0x323D3516D4611368UL, - 0xC8A045E9E3E20B1FUL, 0x1B69C6DCD29AAE04UL, 0x24DA7006D030D431UL, - 0x468A8E0A5523AF97UL, 0x075CABD7CAC6346DUL, 0x6AA5CE224365EB50UL, - 0x888443448F8FC9F1UL, 0x4D04602CAD6D5208UL, 0x84FC44D5FE8D928EUL, - 0x703E412307FC7C32UL, 0xAFBAEAA0E3D8BBAAUL, 0x7C32F528AA001332UL, - 0x86BB81913BB879C7UL, 0x99853897C46219ABUL, 0xA213ED45FD500DD2UL, - 0xD591D1A722685833UL, 0x33305B089DCD5298UL, 0x52D2E2138D12701CUL, - 0x99B931133F6A60CDUL, 0x2633C5A928D65828UL - }; - - public static bool IsPopularPassword(char[] vPassword) - { - Debug.Assert(PpcTable.Length == (PpcTableSize / 64)); - - if(vPassword == null) throw new ArgumentNullException("vPassword"); - if(vPassword.Length == 0) return false; - - foreach(char ch in vPassword) - { - if(!IsPopularChar(ch)) return false; - } - - UTF8Encoding utf8 = new UTF8Encoding(false); - byte[] pbUtf8 = utf8.GetBytes(vPassword); - - int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize); - Array.Clear(pbUtf8, 0, pbUtf8.Length); - - foreach(int iIndex in vIndices) - { - if(!GetTableBit(PpcTable, iIndex)) return false; - } - - return true; - } - - private static bool IsPopularChar(char ch) - { - return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || - ((ch >= '0') && (ch <= '9')) || (ch == '_') || (ch == '!')); - } - - private static int[] GetTableIndices(byte[] pbPasswordUtf8, int nTableSize) - { - Debug.Assert((nTableSize >= 2) && (nTableSize <= 0x10000)); - Debug.Assert((nTableSize % 64) == 0); - - SHA512Managed sha = new SHA512Managed(); - byte[] pbHash = sha.ComputeHash(pbPasswordUtf8); - - int[] vIndices = new int[pbHash.Length / 4]; // 4 by experiment - for(int i = 0; i < vIndices.Length; ++i) - vIndices[i] = ((((int)pbHash[i * 2] << 8) | - (int)pbHash[i * 2 + 1]) % nTableSize); - - return vIndices; - } - - private static bool GetTableBit(ulong[] vTable, int iBit) - { - return ((vTable[iBit >> 6] & (1UL << (iBit & 0x3F))) != 0UL); - } - -#if (DEBUG && !KeePassLibSD) - private static bool SetTableBit(ulong[] vTable, int iBit) - { - if(GetTableBit(vTable, iBit)) return false; - - vTable[iBit >> 6] = (vTable[iBit >> 6] | (1UL << (iBit & 0x3F))); - return true; - } - - public static void MakeList() - { - string strData = File.ReadAllText("MostPopularPasswords.txt", Encoding.UTF8); - strData += " "; - CharStream cs = new CharStream(strData); - - List vPasswords = new List(); - StringBuilder sbPassword = new StringBuilder(); - while(true) - { - char ch = cs.ReadChar(); - if(ch == char.MinValue) break; - - if(char.IsWhiteSpace(ch)) - { - string strPassword = sbPassword.ToString(); - strPassword = strPassword.ToLower(); - - if(strPassword.Length > 3) - { - if(vPasswords.IndexOf(strPassword) < 0) - vPasswords.Add(strPassword); - } - - sbPassword = new StringBuilder(); - } - else - { - Debug.Assert(!char.IsControl(ch) && !char.IsHighSurrogate(ch) && - !char.IsLowSurrogate(ch) && !char.IsSurrogate(ch)); - Debug.Assert(IsPopularChar(ch)); - sbPassword.Append(ch); - } - } - - ulong[] vTable = new ulong[PpcTableSize / 64]; - Array.Clear(vTable, 0, vTable.Length); - - long lBitsInTable = 0; - UTF8Encoding utf8 = new UTF8Encoding(false); - foreach(string strPassword in vPasswords) - { - byte[] pbUtf8 = utf8.GetBytes(strPassword); - int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize); - - foreach(int i in vIndices) - { - if(SetTableBit(vTable, i)) ++lBitsInTable; - } - } - - StringBuilder sb = new StringBuilder(); - sb.Append("\t\t\t"); - for(int i = 0; i < vTable.Length; ++i) - { - if(i > 0) - { - if((i % 3) == 0) - { - sb.AppendLine(","); - sb.Append("\t\t\t"); - } - else sb.Append(", "); - } - - sb.Append("0x"); - sb.Append(vTable[i].ToString("X16")); - sb.Append("UL"); - } - - sb.AppendLine(); - sb.AppendLine(); - sb.AppendLine("Bits set: " + lBitsInTable.ToString() + " of " + - PpcTableSize.ToString()); - int cHashFn = GetTableIndices(utf8.GetBytes("Dummy"), PpcTableSize).Length; - sb.AppendLine("Hash functions: " + cHashFn.ToString()); - double dblPhi = Math.Pow(1.0 - ((double)cHashFn / PpcTableSize), - (double)vPasswords.Count); - sb.AppendLine("Phi (bits unset ratio) estimation: " + - dblPhi.ToString(CultureInfo.InvariantCulture)); - dblPhi = ((double)(PpcTableSize - lBitsInTable) / (double)PpcTableSize); - sb.AppendLine("Exact Phi: " + dblPhi.ToString(CultureInfo.InvariantCulture)); - sb.AppendLine("False positives ratio: " + Math.Pow(1.0 - dblPhi, - (double)cHashFn).ToString(CultureInfo.InvariantCulture)); - - File.WriteAllText("Table.txt", sb.ToString()); - } -#endif - } -} diff --git a/Ext/DeprecatedSources/ProtectedString_111029.cs b/Ext/DeprecatedSources/ProtectedString_111029.cs deleted file mode 100644 index e37fd06..0000000 --- a/Ext/DeprecatedSources/ProtectedString_111029.cs +++ /dev/null @@ -1,436 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2011 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Security; -using System.Text; -using System.Diagnostics; -using System.Runtime.InteropServices; - -using KeePassLib.Cryptography; -using KeePassLib.Utility; - -#if KeePassLibSD -using KeePassLibSD; -#endif - -namespace KeePassLib.Security -{ - /// - /// Represents an in-memory encrypted string. - /// -#if (DEBUG && !KeePassLibSD) - [DebuggerDisplay(@"{ReadString()}")] -#endif - public sealed class ProtectedString - { - // SecureString objects are supported only on Windows 2000 SP3 and - // higher. On all other systems (98 / ME) we use a standard string - // object instead of the secure one. This of course decreases the - // security of the class, but at least allows the application - // to run on older systems, too. - private SecureString m_secString = null; // Created in constructor - private string m_strAlternativeSecString = string.Empty; - - private string m_strPlainText = string.Empty; // Never null - private bool m_bIsProtected = false; // See default constructor - - private XorredBuffer m_xbEncrypted = null; // UTF-8 representation - - /// - /// A flag specifying whether the ProtectedString object has turned on - /// in-memory protection or not. - /// - public bool IsProtected - { - get { return m_bIsProtected; } - } - - /// - /// A value specifying whether the ProtectedString object is currently - /// in-memory protected or not. This flag can be different than - /// IsProtected: if a XorredBuffer is used, the IsProtected - /// flag represents the memory protection flag, but not the actual protection. - /// In this case use IsViewable, which returns true if a - /// XorredBuffer is currently in use. - /// - public bool IsViewable - { - get { return (!m_bIsProtected && (m_xbEncrypted == null)); } - } - - public bool IsEmpty - { - get - { - if(m_xbEncrypted != null) return (m_xbEncrypted.Length == 0); - - if(m_bIsProtected) - { - if(m_secString != null) return (m_secString.Length == 0); - else return (m_strAlternativeSecString.Length == 0); - } - - return (m_strPlainText.Length == 0); - } - } - - public int Length - { - get - { - if(m_xbEncrypted != null) - { - byte[] pb = m_xbEncrypted.ReadPlainText(); - - string str = StrUtil.Utf8.GetString(pb, 0, pb.Length); - SetString(str); // Clear the XorredBuffer object - - // No need to erase the pb buffer, the plain text is - // now readable in memory anyway (in str). - - return ((str != null) ? str.Length : 0); - } - - if(m_bIsProtected) - { - if(m_secString != null) return m_secString.Length; - else return m_strAlternativeSecString.Length; - } - - return m_strPlainText.Length; // Unprotected string - } - } - - /// - /// Construct a new protected string object. Protection is - /// disabled by default! You need to call the - /// EnableProtection member function in order to - /// enable the protection, if you wish the string to be protected. - /// - public ProtectedString() - { - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - } - - /// - /// Construct a new in-memory encrypted string object. - /// - /// If this parameter is true, - /// the string will be protected in-memory (encrypted). If it - /// is false, the string will be stored as plain-text. - public ProtectedString(bool bEnableProtection) - { - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - - m_bIsProtected = bEnableProtection; - } - - /// - /// Construct a new protected string. The string is initialized - /// to the value supplied in the parameters. - /// - /// If this parameter is true, - /// the string will be protected in-memory (encrypted). If it - /// is false, the string will be stored as plain-text. - /// The initial string value. This - /// parameter won't be modified. - public ProtectedString(bool bEnableProtection, string strValue) - { - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - - m_bIsProtected = bEnableProtection; - SetString(strValue); - } - - /// - /// Construct a new protected string. The string is initialized - /// to the value supplied in the parameters (UTF-8 encoded string). - /// - /// If this parameter is true, - /// the string will be protected in-memory (encrypted). If it - /// is false, the string will be stored as plain-text. - /// The initial string value, encoded as - /// UTF-8 byte array. This parameter won't be modified. - public ProtectedString(bool bEnableProtection, byte[] vUtf8Value) - { - if(vUtf8Value == null) throw new ArgumentNullException("vUtf8Value"); - - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - - m_bIsProtected = bEnableProtection; - SetString(StrUtil.Utf8.GetString(vUtf8Value, 0, vUtf8Value.Length)); - } - - /// - /// Construct a new protected string. The string is initialized - /// to the value passed in the pbTemplate protected string. - /// - /// The initial string value. This - /// parameter won't be modified. Must not be null. - /// Thrown if the input - /// parameter is null. - public ProtectedString(ProtectedString psTemplate) - { - Debug.Assert(psTemplate != null); - if(psTemplate == null) throw new ArgumentNullException("psTemplate"); - - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - - m_bIsProtected = psTemplate.m_bIsProtected; - SetString(psTemplate.ReadString()); - } - - /// - /// Construct a new protected string. The string is initialized - /// to the value passed in the XorredBuffer object. - /// - /// Enable protection or not. - /// XorredBuffer object containing the - /// string in UTF-8 representation. The UTF-8 string must not - /// be null-terminated. - /// Thrown if the input - /// parameter is null. - public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected) - { - Debug.Assert(xbProtected != null); - if(xbProtected == null) throw new ArgumentNullException("xbProtected"); - - try { m_secString = new SecureString(); } - catch(NotSupportedException) { } // Windows 98 / ME - - m_bIsProtected = bEnableProtection; - m_xbEncrypted = xbProtected; - } - - /// - /// Clear the string. Doesn't change the protection level. - /// - public void Clear() - { - if(m_secString != null) m_secString.Clear(); - else m_strAlternativeSecString = string.Empty; - - m_strPlainText = string.Empty; - - m_xbEncrypted = null; - } - - /// - /// Change the protection level (protect or don't protect). Note: you - /// only need to call this function if you really want to change the - /// protection. If you specified the protection flag in the constructor, - /// and don't want to change it, you don't need to call this function. - /// - /// If true, the string will be protected - /// (encrypted in-memory). Otherwise the string will be stored in - /// plain-text in the process memory. - public void EnableProtection(bool bProtect) - { - if(m_xbEncrypted != null) - { - m_bIsProtected = bProtect; - return; - } - - if(m_bIsProtected && !bProtect) // Unprotect - { - string strPlainText = ReadString(); - - Clear(); - - m_strPlainText = strPlainText; - m_bIsProtected = false; - } - else if(!m_bIsProtected && bProtect) // Protect - { - m_bIsProtected = true; - - SetString(m_strPlainText); - } - } - - /// - /// Assign a new string value to the object. - /// - /// New string. The string must not contain - /// a null terminator. - /// Thrown if the input - /// parameter is null. - /// Thrown if the new string - /// contains a null terminator. - public void SetString(string strNewValue) - { - Clear(); - - Debug.Assert(strNewValue != null); if(strNewValue == null) throw new ArgumentNullException("strNewValue"); - - // String must not contain any null character - Debug.Assert(strNewValue.IndexOf((char)0) < 0); - - if(m_bIsProtected) - { - if(m_secString != null) - { - char ch; - for(int i = 0; i < strNewValue.Length; ++i) - { - ch = strNewValue[i]; - if(ch == 0) throw new ArgumentException(); - - m_secString.AppendChar(ch); - } - } - else m_strAlternativeSecString = strNewValue; - } - else // Currently not protected - { - m_strPlainText = strNewValue; - } - } - - /// - /// Convert the protected string to a normal string object. - /// Be careful with this function, the returned string object - /// isn't protected any more and stored in plain-text in the - /// process memory. - /// - /// Plain-text string. Is never null. - public string ReadString() - { - if(m_xbEncrypted != null) - { - byte[] pb = m_xbEncrypted.ReadPlainText(); - - string str = StrUtil.Utf8.GetString(pb, 0, pb.Length); - SetString(str); // Clear the XorredBuffer object - - // No need to erase the pb buffer, the plain text is - // now readable in memory anyway (in str). - - return (str ?? string.Empty); - } - - if(m_bIsProtected) - { - if(m_secString != null) - { -#if !KeePassLibSD - IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString); - string str = Marshal.PtrToStringUni(p); - Marshal.ZeroFreeGlobalAllocUnicode(p); -#else - string str = m_secString.ReadAsString(); -#endif - return (str ?? string.Empty); - } - else return m_strAlternativeSecString; - } - - return m_strPlainText; // Unprotected string - } - - /// - /// Read out the string and return a byte array that contains the - /// string encoded using UTF-8. The returned string is not protected - /// anymore! - /// - /// Plain-text UTF-8 byte array. - public byte[] ReadUtf8() - { - if(m_xbEncrypted != null) - { - byte[] pb = m_xbEncrypted.ReadPlainText(); - - // Clear XorredBuffer - SetString(StrUtil.Utf8.GetString(pb, 0, pb.Length)); - - return pb; - } - - if(m_bIsProtected) - { - if(m_secString != null) - { -#if !KeePassLibSD - Debug.Assert(sizeof(char) == 2); - char[] vChars = new char[m_secString.Length]; - - IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString); - for(int i = 0; i < vChars.Length; ++i) - vChars[i] = (char)Marshal.ReadInt16(p, i * 2); - Marshal.ZeroFreeGlobalAllocUnicode(p); - - byte[] pb = StrUtil.Utf8.GetBytes(vChars, 0, vChars.Length); - Array.Clear(vChars, 0, vChars.Length); -#else - byte[] pb = StrUtil.Utf8.GetBytes(m_secString.ReadAsString()); -#endif - return pb; - } - else return StrUtil.Utf8.GetBytes(m_strAlternativeSecString); - } - - return StrUtil.Utf8.GetBytes(m_strPlainText); // Unprotected string - } - - /// - /// Read the protected string and return it protected with a sequence - /// of bytes generated by a random stream. The object's data will be - /// invisible in process memory only if the object has been initialized - /// using a XorredBuffer. If no XorredBuffer has been used - /// or the string has been read once already (in plain-text), the - /// operation won't be secure and the protected string will be visible - /// in process memory. - /// - /// Random number source. - /// Protected string. - /// Thrown if the input - /// parameter is null. - public byte[] ReadXorredString(CryptoRandomStream crsRandomSource) - { - Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource"); - - if(m_xbEncrypted != null) - { - uint uLen = m_xbEncrypted.Length; - byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); - return m_xbEncrypted.ChangeKey(randomPad); - } - else // Not using XorredBuffer - { - byte[] pbData = ReadUtf8(); - uint uLen = (uint)pbData.Length; - - byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); - Debug.Assert(randomPad.Length == uLen); - - for(uint i = 0; i < uLen; ++i) - pbData[i] ^= randomPad[i]; - - return pbData; - } - } - } -} diff --git a/Ext/DeprecatedSources/ShInstUtil/Program.cs b/Ext/DeprecatedSources/ShInstUtil/Program.cs deleted file mode 100644 index ba84f37..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Program.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2009 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Windows.Forms; -using System.IO; -using System.Reflection; -using System.Diagnostics; - -using Microsoft.Win32; - -namespace ShInstUtil -{ - public static class Program - { - [STAThread] - public static void Main(string[] args) - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - - if((args == null) || (args.Length == 0)) return; - - string strCmd = args[0]; - if(string.IsNullOrEmpty(strCmd)) return; - strCmd = strCmd.ToLower(); - strCmd = strCmd.Trim(new char[]{ '\r', '\n', ' ', '\t', '-', '/', - '\"', '\'' }); - - if(strCmd == "ngen_install") - { - UpdateNativeImage(false); - UpdateNativeImage(true); - } - else if(strCmd == "ngen_uninstall") - UpdateNativeImage(false); - } - - private static string FindNGenPath() - { - RegistryKey kSoftware = Registry.LocalMachine.OpenSubKey("SOFTWARE"); - RegistryKey kMicrosoft = kSoftware.OpenSubKey("Microsoft"); - RegistryKey kNet = kMicrosoft.OpenSubKey(".NETFramework"); - - string strPath = (kNet.GetValue("InstallRoot") as string); - - kNet.Close(); - kMicrosoft.Close(); - kSoftware.Close(); - - if(string.IsNullOrEmpty(strPath)) return null; - - DirectoryInfo di = new DirectoryInfo(strPath); - FileInfo[] vNGens = di.GetFiles("ngen.exe", SearchOption.AllDirectories); - if((vNGens == null) || (vNGens.Length == 0)) return null; - - strPath = null; - DateTime dt = DateTime.MinValue.AddYears(1); - foreach(FileInfo fi in vNGens) - { - if(fi.CreationTime >= dt) - { - strPath = fi.FullName; - dt = fi.CreationTime; - } - } - - return strPath; - } - - private static void UpdateNativeImage(bool bInstall) - { - try - { - string strNGen = FindNGenPath(); - if(string.IsNullOrEmpty(strNGen)) return; - - string strMe = Assembly.GetExecutingAssembly().Location; - string strBasePath = Path.GetDirectoryName(strMe).Trim(new char[]{ - '\r', '\n', ' ', '\t', '\"', '\'' }); - string strToReg = strBasePath + Path.DirectorySeparatorChar + "KeePass.exe"; - - string strPreCmd = (bInstall ? string.Empty : "un"); - - ProcessStartInfo psi = new ProcessStartInfo(); - psi.Arguments = strPreCmd + "install \"" + strToReg + "\""; - psi.CreateNoWindow = true; - psi.FileName = strNGen; - psi.WindowStyle = ProcessWindowStyle.Hidden; - - Process p = Process.Start(psi); - p.WaitForExit(16000); - } - catch(Exception) { } - } - } -} diff --git a/Ext/DeprecatedSources/ShInstUtil/Properties/AssemblyInfo.cs b/Ext/DeprecatedSources/ShInstUtil/Properties/AssemblyInfo.cs deleted file mode 100644 index 0a72271..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2009 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General assembly properties -[assembly: AssemblyTitle("ShInstUtil - KeePass Installation Utility")] -[assembly: AssemblyDescription("Installation Utility")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Dominik Reichl")] -[assembly: AssemblyProduct("ShInstUtil - KeePass Installation Utility")] -[assembly: AssemblyCopyright("Copyright © 2007-2009 Dominik Reichl")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// COM settings -[assembly: ComVisible(false)] - -// Assembly GUID -[assembly: Guid("7e0eb6e8-4f13-4b04-aad9-2acf8417a776")] - -// Assembly version information -[assembly: AssemblyVersion("2.0.8.*")] -[assembly: AssemblyFileVersion("2.0.8.0")] diff --git a/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.Designer.cs b/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.Designer.cs deleted file mode 100644 index 128a6da..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.1433 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ShInstUtil.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ShInstUtil.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.resx b/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.resx deleted file mode 100644 index ffecec8..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.Designer.cs b/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.Designer.cs deleted file mode 100644 index 82e5aad..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.1433 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ShInstUtil.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.settings b/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.settings deleted file mode 100644 index abf36c5..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Ext/DeprecatedSources/ShInstUtil/ShInstUtil.csproj b/Ext/DeprecatedSources/ShInstUtil/ShInstUtil.csproj deleted file mode 100644 index c2a3539..0000000 --- a/Ext/DeprecatedSources/ShInstUtil/ShInstUtil.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - Debug - AnyCPU - 8.0.50727 - 2.0 - {D6240ED0-5AE4-4F6D-B1F1-C691630B4D3F} - WinExe - Properties - ShInstUtil - ShInstUtil - true - ShInstUtil.pfx - - - 2.0 - - - - - true - full - false - ..\Build\ShInstUtil\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\Build\ShInstUtil\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - True - Settings.settings - True - - - - - \ No newline at end of file diff --git a/Ext/DeprecatedSources/ShInstUtil/ShInstUtil.pfx b/Ext/DeprecatedSources/ShInstUtil/ShInstUtil.pfx deleted file mode 100644 index 19b0155f5b910f8d44dddd6910a2524028c1638e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1756 zcmY*Yc~sL^7XD>13!sMxCsBnV1IaGSK2 zO+?uuNkz5!+lLi2x9S{e{&g%H|8 z5JH;>MhK1n)8OMf;HYa3?q6GTq@GYHau_azUT(IyfktIji=M?;oa|T3?s|N<`(T~( zy*;KwIU{=?`Gu5M#P17Eg^FamMrV#D+zu$BrGNJ;uSXrCzUI?p?q~S4k3;fV&lAu6 z0kQa|XNKUh==tS+=4{D>MDO*dal2D4Lwin z&k)Mn193B#Nq@^yyBznHjZ*QGxm2u8LzBv2MUxvlS)9Jwk>~E98vn7|#O9d&nI5PK zH==7}zgZ46+D`f-BphG#2TwPBs^Bv@Dukxz3s6f2Suu2%jBW*P<1WtV@ z`>nJ{=c~$lHlp^YUZmQwxF}}glHIcuasQl^imon8a!GiFvU~3D!*avXGog`(%h0Nb zh81Mm2xh@GAgp*kAWk(f`Ev%}u~%fn^)c$}Vm*&)yf-I4pdP~Wa-uXL=5vZ^b4yap|#qFQpW#^Uth^ zZN9r6uI1@9_h1+58*knI{_75Wf z;&6o;Hu>JXD0rOGW#YU@TIk=NX{0rSJWKOkE(b9kPJ3CqYNCUnC58p zcB=B~qFqpN@7SiS*^oUII-~b+%&VGmVJPF&DgnPKwmadnRPCJ`z{Q;^n`gom>+F9! z#opU`twR(%CFuOI=4d@40uF}&06+-&lhh@88#94SzzrY(48Q@P10;Y9R$CAe0S_>2 zK}-TwD%jD%N&qNdR63|Tf;s~XN5Bbi2ZI1)6T%Q^JOToT2q_o{(bw1;I0D1~kw7w# z0HlC<65s+jz#lw6GpB(l5HY|$9Y_SZ1P~_!Y_O01GKB+tzue=2hy$Del0heS{qcJw z0yL)-r0Ss%04!C1Dv-a}74g}w|FOlsZNn@?ezt3l5Sqq44;x=wf>bCV9|i4U>>5>s z!$!JR-utCHu*wq~q2ZDYf7CY}=Z|R*=&=fdE$v76Tb;x!zs!&@%( z8ge=4jMA)jQ-YO-+tTz6ey%rNxl?9Z%CniZqO2ijbrq={U%j?KJu90Z|B%&Y5}$iC zSRU^wYmiNcIg1}qUwX_2&arOnUpI56i3|%7t)siojcX=b9zf&nMy>pEqjobAo7Ev_3)6P~`4X5l;SX*ZXrE1>2D|hOLum^SaS83^O z-Fp-C@@=r;#@n0()2gCOdPJwv(enk51!JxIp31har^S&p{vHouK1zMx_ z@{%PfMV;$PiDvJZY1Ca0a6y`LLz|uu-Ew^9^&flfK65A~b(O>^K5}K)?cs}9mf39& z{*w*%-vP(gbcRDaWB*6YE;6?@#@nL1lz43j!{h7)b= zsjjF*OM`zc(v~|yo>a(Dw2rfA(@-iS$f0@TTn#kI=m z8#Z-uhAI=iB;@z2q1r23h*wR)WXFrgk*ut5rJIpM^SEytM!3Wpf-}K{fJAJ=?|?xK z;JW# - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Net; -using System.Net.Cache; -using System.Windows.Forms; -using System.Xml; -using System.Diagnostics; -using System.Threading; - -// using KeePass.Native; -using KeePass.Resources; - -using KeePassLib; -using KeePassLib.Resources; -using KeePassLib.Serialization; -using KeePassLib.Utility; - -namespace KeePass.Util -{ - /* public static class UpdateCheck - { - private const string ElemRoot = "KeePass"; - - private const string ElemVersionU = "Version32"; - private const string ElemVersionStr = "VersionDisplayString"; - - private static volatile string m_strVersionURL = string.Empty; - private static volatile ToolStripStatusLabel m_tsResultsViewer = null; - - public static void StartAsync(string strVersionUrl, ToolStripStatusLabel tsResultsViewer) - { - m_strVersionURL = strVersionUrl; - m_tsResultsViewer = tsResultsViewer; - - // Local, but thread will continue to run anyway - Thread th = new Thread(new ThreadStart(UpdateCheck.OnStartCheck)); - th.Start(); - } - - private static void OnStartCheck() - { - // NativeProgressDialog dlg = null; - // if(m_tsResultsViewer == null) - // { - // dlg = new NativeProgressDialog(); - // dlg.StartLogging(KPRes.Wait + "...", false); - // } - - try - { - IOWebClient webClient = new IOWebClient(); - IOConnection.ConfigureWebClient(webClient); - - Uri uri = new Uri(m_strVersionURL); - - webClient.DownloadDataCompleted += - new DownloadDataCompletedEventHandler(OnDownloadCompleted); - - webClient.DownloadDataAsync(uri); - } - // catch(NotImplementedException) - // { - // ReportStatusEx(KLRes.FrameworkNotImplExcp, true); - // } - catch(Exception) { } - - // if(dlg != null) dlg.EndLogging(); - } - - private static void OnDownloadCompleted(object sender, DownloadDataCompletedEventArgs e) - { - string strXmlFile = NetUtil.GZipUtf8ResultToString(e); - - if(strXmlFile == null) - { - if(e.Error != null) - { - if(m_tsResultsViewer == null) - MessageService.ShowWarning(KPRes.UpdateCheckingFailed, e.Error); - else if(e.Error.Message != null) - UpdateCheck.SetTsStatus(KPRes.UpdateCheckingFailed + " " + - e.Error.Message); - } - else ReportStatusEx(KPRes.UpdateCheckingFailed, true); - - return; - } - - XmlDocument xmlDoc = new XmlDocument(); - - try { xmlDoc.LoadXml(strXmlFile); } - catch(Exception) - { - StructureFail(); - return; - } - - XmlElement xmlRoot = xmlDoc.DocumentElement; - if(xmlRoot == null) { StructureFail(); return; } - if(xmlRoot.Name != ElemRoot) { StructureFail(); return; } - - uint uVersion = 0; - - foreach(XmlNode xmlChild in xmlRoot.ChildNodes) - { - if(xmlChild.Name == ElemVersionU) - uint.TryParse(xmlChild.InnerText, out uVersion); - else if(xmlChild.Name == ElemVersionStr) - { - // strVersion = xmlChild.InnerText; - } - } - - if(uVersion > PwDefs.Version32) - { - if(m_tsResultsViewer == null) - { - if(MessageService.AskYesNo(KPRes.ChkForUpdNewVersion + - MessageService.NewParagraph + KPRes.WebsiteVisitQuestion)) - { - WinUtil.OpenUrl(PwDefs.HomepageUrl, null); - } - } - else UpdateCheck.SetTsStatus(KPRes.ChkForUpdNewVersion); - } - else if(uVersion == PwDefs.Version32) - ReportStatusEx(KPRes.ChkForUpdGotLatest, false); - else - ReportStatusEx(KPRes.UnknownFileVersion, true); - } - - private static void ReportStatusEx(string strText, bool bIsWarning) - { - ReportStatusEx(strText, strText, bIsWarning); - } - - private static void ReportStatusEx(string strLongText, string strShortText, - bool bIsWarning) - { - if(m_tsResultsViewer == null) - { - if(bIsWarning) MessageService.ShowWarning(strLongText); - else MessageService.ShowInfo(strLongText); - } - else UpdateCheck.SetTsStatus(strShortText); - } - - private static void StructureFail() - { - Debug.Assert(false); - - if(m_tsResultsViewer == null) - MessageService.ShowWarning(KPRes.InvalidFileStructure); - else - UpdateCheck.SetTsStatus(KPRes.ChkForUpdGotLatest + " " + - KPRes.InvalidFileStructure); - } - - private static void SetTsStatus(string strText) - { - if(strText == null) { Debug.Assert(false); return; } - if(m_tsResultsViewer == null) { Debug.Assert(false); return; } - - try - { - ToolStrip pParent = m_tsResultsViewer.Owner; - if((pParent != null) && pParent.InvokeRequired) - { - pParent.Invoke(new Priv_CfuSsd(UpdateCheck.SetTsStatusDirect), - new object[] { strText }); - } - else UpdateCheck.SetTsStatusDirect(strText); - } - catch(Exception) { Debug.Assert(false); } - } - - public delegate void Priv_CfuSsd(string strText); - - private static void SetTsStatusDirect(string strText) - { - try { m_tsResultsViewer.Text = strText; } - catch(Exception) { Debug.Assert(false); } - } - } */ -} diff --git a/Ext/DeprecatedSources/XorredBuffer_111029.cs b/Ext/DeprecatedSources/XorredBuffer_111029.cs deleted file mode 100644 index 3b16d96..0000000 --- a/Ext/DeprecatedSources/XorredBuffer_111029.cs +++ /dev/null @@ -1,196 +0,0 @@ -/* - KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2011 Dominik Reichl - - 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 2 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; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -using System; -using System.Diagnostics; - -namespace KeePassLib.Security -{ - /// - /// Represents an object that is encrypted using a XOR pad until - /// it is read. The key XOR pad can be changed without revealing the - /// protected data in process memory. - /// - public sealed class XorredBuffer - { - private byte[] m_pbData = new byte[0]; // Never null - private byte[] m_pbXorPad = new byte[0]; // Never null - - /// - /// Length of the protected data in bytes. - /// - public uint Length - { - get { return (uint)m_pbData.Length; } - } - - /// - /// Construct a new XOR-protected object using a protected byte array - /// and a XOR pad that decrypts the protected data. The - /// byte array must have the same size - /// as the byte array. - /// - /// Protected data (XOR pad applied). - /// XOR pad that is used to decrypt the - /// parameter. - /// Thrown if one of the input - /// parameters is null. - /// Thrown if the byte arrays are - /// of different size. - public XorredBuffer(byte[] pbProtectedData, byte[] pbXorPad) - { - Debug.Assert(pbProtectedData != null); if(pbProtectedData == null) throw new ArgumentNullException("pbProtectedData"); - Debug.Assert(pbXorPad != null); if(pbXorPad == null) throw new ArgumentNullException("pbXorPad"); - - Debug.Assert(pbProtectedData.Length == pbXorPad.Length); - if(pbProtectedData.Length != pbXorPad.Length) throw new ArgumentException(); - - m_pbData = pbProtectedData; - m_pbXorPad = pbXorPad; - } - - private void Decrypt() - { - Debug.Assert((m_pbData.Length == m_pbXorPad.Length) || (m_pbXorPad.Length == 0)); - - if(m_pbData.Length == m_pbXorPad.Length) - { - for(int i = 0; i < m_pbData.Length; ++i) - m_pbData[i] ^= m_pbXorPad[i]; - - m_pbXorPad = new byte[0]; - } - } - - /// - /// Decrypt the buffer. The XorredBuffer protection is useless - /// after you used this method. The object cannot be re-encrypted. - /// - /// Unprotected plain-text byte array. - public byte[] ReadPlainText() - { - Decrypt(); - return m_pbData; - } - - /// - /// Change the protection key for this XorredBuffer object. - /// The data will first be decrypted using the old key and then - /// re-encrypted using the new key. This operation doesn't reveal - /// the plain-text in the process memory. - /// - /// New protection pad. Must contain exactly - /// the same number of bytes as the length of the currently protected data. - /// Use the Length property of the XorredBuffer to query - /// the data length and pass a correct number of bytes to ChangeKey. - /// New protected data (encrypted using the new XOR pad). - /// Thrown if the input - /// parameter is null. - /// Thrown if the input - /// byte array doesn't have the correct size. - public byte[] ChangeKey(byte[] pbNewXorPad) - { - Debug.Assert(pbNewXorPad != null); if(pbNewXorPad == null) throw new ArgumentNullException("pbNewXorPad"); - - Debug.Assert(pbNewXorPad.Length == m_pbData.Length); - if(pbNewXorPad.Length != m_pbData.Length) throw new ArgumentException(); - - if(m_pbXorPad.Length == m_pbData.Length) // Data is protected - { - for(int i = 0; i < m_pbData.Length; ++i) - m_pbData[i] ^= (byte)(m_pbXorPad[i] ^ pbNewXorPad[i]); - } - else // Data is unprotected - { - for(int i = 0; i < m_pbData.Length; ++i) - m_pbData[i] ^= pbNewXorPad[i]; - } - - m_pbXorPad = pbNewXorPad; - return m_pbData; - } - - public bool EqualsValue(XorredBuffer xb) - { - if(xb == null) { Debug.Assert(false); throw new ArgumentNullException("xb"); } - - if(xb.m_pbData.Length != m_pbData.Length) return false; - - bool bDecThis = (m_pbData.Length == m_pbXorPad.Length); - bool bDecOther = (xb.m_pbData.Length == xb.m_pbXorPad.Length); - for(int i = 0; i < m_pbData.Length; ++i) - { - byte bt1 = m_pbData[i]; - if(bDecThis) bt1 ^= m_pbXorPad[i]; - - byte bt2 = xb.m_pbData[i]; - if(bDecOther) bt2 ^= xb.m_pbXorPad[i]; - - if(bt1 != bt2) return false; - } - - return true; - } - - public bool EqualsValue(byte[] pb) - { - if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } - - if(pb.Length != m_pbData.Length) return false; - - if(m_pbData.Length == m_pbXorPad.Length) - { - for(int i = 0; i < m_pbData.Length; ++i) - { - if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false; - } - return true; - } - - for(int i = 0; i < m_pbData.Length; ++i) - { - if(m_pbData[i] != pb[i]) return false; - } - return true; - } - - /// - /// XOR all bytes in a data buffer with a pad. Both byte arrays must - /// be of the same size. - /// - /// Data to be protected. - /// XOR pad. - /// Thrown if one of the - /// parameters is null. - /// Thrown if the length of - /// the data array and the pad aren't equal. - [Obsolete("Use MemUtil.XorArray instead.")] - public static void XorArrays(byte[] pbData, byte[] pbPad) - { - Debug.Assert(pbData != null); if(pbData == null) throw new ArgumentNullException("pbData"); - Debug.Assert(pbPad != null); if(pbPad == null) throw new ArgumentNullException("pbPad"); - - Debug.Assert(pbData.Length == pbPad.Length); - if(pbData.Length != pbPad.Length) throw new ArgumentException(); - - for(int i = 0; i < pbData.Length; ++i) - pbData[i] ^= pbPad[i]; - } - } -} diff --git a/Ext/KeePass.exe.config b/Ext/KeePass.exe.config index 5f6aca9..f9efb5a 100644 --- a/Ext/KeePass.exe.config +++ b/Ext/KeePass.exe.config @@ -10,8 +10,8 @@ - + diff --git a/Ext/KeePass.iss b/Ext/KeePass.iss index 63fc529..ea6fc95 100644 --- a/Ext/KeePass.iss +++ b/Ext/KeePass.iss @@ -8,10 +8,10 @@ #define MyAppNameEx "KeePass Password Safe 2" #define MyAppPublisher "Dominik Reichl" -#define KeeVersionStr "2.20" -#define KeeVersionStrWithMinor "2.20" -#define KeeVersionStrWithMinorPath "2.20" -#define KeeVersionWin "2.20.0.0" +#define KeeVersionStr "2.20.1" +#define KeeVersionStrWithMinor "2.20.1" +#define KeeVersionStrWithMinorPath "2.20.1" +#define KeeVersionWin "2.20.1.0" #define MyAppURL "http://keepass.info/" #define MyAppExeName "KeePass.exe" diff --git a/Ext/KeePassMsi/KeePassMsi.vdproj b/Ext/KeePassMsi/KeePassMsi.vdproj index 54e1cdb..7df4aa7 100644 --- a/Ext/KeePassMsi/KeePassMsi.vdproj +++ b/Ext/KeePassMsi/KeePassMsi.vdproj @@ -382,7 +382,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:KeePass, Version=2.20.0.18622, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:KeePass, Version=2.20.1.16631, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { "_838987B3C51D42C3C7B9BDA1339A5500" @@ -413,7 +413,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:KeePass.XmlSerializers, Version=2.20.0.18622, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:KeePass.XmlSerializers, Version=2.20.1.16631, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { "_8C05ADB649434D7892E36709EBDED4CC" @@ -564,7 +564,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:KeePass, Version=2.20.0.18622, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:KeePass, Version=2.20.1.16631, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { "_C4F8814F844C43EE8C9F5B662182B11A" @@ -712,14 +712,14 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:KeePass" - "ProductCode" = "8:{F6B49374-09A3-4B84-BA45-1CA2CD1C793F}" - "PackageCode" = "8:{72EA3387-C9B6-433D-B670-E84AEC1CF35C}" + "ProductCode" = "8:{798C312A-7893-46A2-A269-D3176F13D060}" + "PackageCode" = "8:{F4690AAC-FA26-488E-A4EE-5FAFE81E56DA}" "UpgradeCode" = "8:{F2F19898-4F86-4940-9BFA-426574CE03E1}" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:TRUE" - "ProductVersion" = "8:2.20.0" + "ProductVersion" = "8:2.20.1" "Manufacturer" = "8:Dominik Reichl" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:http://keepass.info/" diff --git a/KeePass/Native/NativeMethods.Unix.cs b/KeePass/Native/NativeMethods.Unix.cs index 8544892..11a0c6e 100644 --- a/KeePass/Native/NativeMethods.Unix.cs +++ b/KeePass/Native/NativeMethods.Unix.cs @@ -175,6 +175,12 @@ internal static void SetWmClass(Form f, string strName, string strClass) { if(f == null) { Debug.Assert(false); return; } + // The following crashes under Mac OS X (SIGSEGV in native code, + // not just an exception), thus skip it when we're on Mac OS X + // https://sourceforge.net/projects/keepass/forums/forum/329221/topic/5860588 + if(KeeNativeLib.NativeLib.GetPlatformID() == PlatformID.MacOSX) + return; + try { Type tXplatUIX11 = GetXplatUIX11Type(true); diff --git a/KeePass/Plugins/PlgxCache.cs b/KeePass/Plugins/PlgxCache.cs index fa6acf2..c554ef9 100644 --- a/KeePass/Plugins/PlgxCache.cs +++ b/KeePass/Plugins/PlgxCache.cs @@ -114,7 +114,7 @@ public static string GetCacheRoot() // if(di.DriveType == DriveType.Network) // { // strDataDir = UrlUtil.EnsureTerminatingSeparator( - // Path.GetTempPath(), false); + // UrlUtil.GetTempPath(), false); // strDataDir = strDataDir.Substring(0, strDataDir.Length - 1); // } // } diff --git a/KeePass/Plugins/PlgxPlugin.cs b/KeePass/Plugins/PlgxPlugin.cs index 6345912..578bfc5 100644 --- a/KeePass/Plugins/PlgxPlugin.cs +++ b/KeePass/Plugins/PlgxPlugin.cs @@ -266,7 +266,7 @@ public static void CreateInfoFile(string strPlgxPath) private static string CreateTempDirectory() { - string strTmpRoot = Path.GetTempPath(); + string strTmpRoot = UrlUtil.GetTempPath(); strTmpRoot = UrlUtil.EnsureTerminatingSeparator(strTmpRoot, false); strTmpRoot += (new PwUuid(true)).ToHexString(); diff --git a/KeePass/Program.cs b/KeePass/Program.cs index a41b7a9..4c573c1 100644 --- a/KeePass/Program.cs +++ b/KeePass/Program.cs @@ -284,7 +284,7 @@ public static void Main(string[] args) try { string strFileOut = UrlUtil.EnsureTerminatingSeparator( - Path.GetTempPath(), false) + "KeePass_UrlOverride.tmp"; + UrlUtil.GetTempPath(), false) + "KeePass_UrlOverride.tmp"; string strContent = ("[KeePass]\r\nKeeURLOverride=" + Program.Config.Integration.UrlOverride + "\r\n"); File.WriteAllText(strFileOut, strContent); diff --git a/KeePass/Properties/AssemblyInfo.cs b/KeePass/Properties/AssemblyInfo.cs index 03f753b..9712ee7 100644 --- a/KeePass/Properties/AssemblyInfo.cs +++ b/KeePass/Properties/AssemblyInfo.cs @@ -38,5 +38,5 @@ [assembly: Guid("02020c52-c0da-47c0-9f3f-a6fe76cee400")] // Assembly version information -[assembly: AssemblyVersion("2.20.0.*")] -[assembly: AssemblyFileVersion("2.20.0.0")] +[assembly: AssemblyVersion("2.20.1.*")] +[assembly: AssemblyFileVersion("2.20.1.0")] diff --git a/KeePass/Resources/Nuvola_Derived/B16x16_DeleteEntry.png b/KeePass/Resources/Nuvola_Derived/B16x16_DeleteEntry.png index cf9dea078cb0f0fdb62ce9e12398dd721706623b..8cff343f1768177be5e684e58ca11b4e78edb5ad 100644 GIT binary patch delta 627 zcmV-(0*w9j1c3#R8Gi-<001BJ|6u?C0!T?jK~#9!m6KUW)BzC2f8(y@g^3ywQjmr% z9khXx4`HuCMMd11m{ELYI+vdmS)_wHMsf*c=KGfWRb+LH%4?AMSGDT8|HhL_1gnraRP_+a06p^Y07bPx(p~(rlmwl#{;5!3yj;J?^Kal_c N002ovPDHLkV1oD}EF%B_ delta 615 zcmV-t0+{`Q1@#1w8Gix*005AYXf^-<00wkYPE!E?00030iNG(A0006iNkl#F130`l`H%70P}lx7!V>VSL47{e_8L$IXy zL&FUMF$8*c<>bLb4#7GO0Oa5}baWV{aY`#nQgLl{ef{$Ecve{TZ;m?E(PYr8%IBDQ zuwrn;kT7Q2?^Vgd-I7<*2b&~!6&b_tKa3B02cFzXeF^07QfmdHI}aq*h_IvjE`qiqUtmRt)KLAHhEwyX-wtWBq002ovPDHLkV1nW_ BC_DfF diff --git a/KeePass/Resources/Nuvola_Derived/B16x16_EditCopyLink.png b/KeePass/Resources/Nuvola_Derived/B16x16_EditCopyLink.png index 731f6115cac994d77a4b7a7cf50fb8a028a3d5b1..fff50009c89ee67fad7ef07ae635ba7250494863 100644 GIT binary patch delta 797 zcmV+&1LFLW1*ry*8Gi-<001BJ|6u?C00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQ zF)%Rna-jeK0+>leK~y+TZBy?{T45CS582243w;mvA%qpvHGgZ$0wcmN#vE+b`j87r zkVeaNrA$l0B*cCS5(IPD25yto+7wBfrh>Xmon~s?XYYNjyjxv3_q^PD&U2sVoagdR z?%n70y|H1~vWwR=K4aMIxfQQW9*i#TVq}rLw|s$EX#?BKV{eN2kGQ#*%hvhUiMe?) zZu`aoFf;*Dsecq!R#srM*oGMo1%*O^{r!DfJHGt21u(L(OCLre z5ll}{BbiL%?CcD+S`Cdx0~Z$;G*3)SU}I_Tn5`%t$$XLPN&h|-w(UpjtYV9o%OaD zTmytcA*`;hqF5}_hG;a3U@(Y-g9G?{K6H0?V{>y8r)19Jy8z5)GcuVBZ4Lwi(CKuL zN~Lf(9PoHN=;-Lc_VzY%4dCfr0F#rGC=?0^hr>{-)!_5_&}cLe2m~+~3}|m}huiH& zruLr%#edZr$HvBx%jMv7I?>hDh4uAyr2c@eP9zect*s4SuNTR4pohy~Xs+o4rBaD_ zJPxf^i^0J`q)WhY5%_fqBoYa1Y;4dEB&vXDhBL&Tw{FxK2J8%2jVyp%E~m{$1>lfu zH1ZqxnPr-hzr>SS&Kkw b1s3=VxpVq!9a_^$00000NkvXXu0mjfwFzMp delta 644 zcmV-~0(`_-ga1Oog9X8ZC#5|r zSG02a_aQLELCkB^NpaU7>IDeL92_cBc^E}RZ5U1b$r1!xX!x#q;1VN!tuq;a{(prPEJmi zmX=0FMuH%aQli8E|*tVS7%==FD!goUtd>BWipwB{sFq<+P2+px390SbGh8(=gZpQ?wGr^wRLuO zHaR&N63Fy{A8nQpO-xKwDir`yN=--!nqUUU^H0Yb1cZh->tzr^G((!7pWol#&t|hX zH#g?jH+^G}YRG|p#FROrKU^nHhX=WHFIOxU_xASc_4>ud1rf;fYycR}vQF}6I4}Tr zGCV)~WMgCW^z?LkdfFa@FffD!sbyIaU>NTKsaGw%{U{iLSe$6WqxT;?1CIb>AcP=- eX7F!61BKsy1~Z{_Fm|2*0000Vp7=M-c!bngFXo#o;T!}9P zLEIYR8&N@A=)$P@788?`IR*DRndLN;#qGAfI(51=05n%uS1_B+u-oktH#awG*lafZ z9agIqCX)$Tt@ckTG#dU~UteP|7~pg|aTDL)-#DMo`1tsc%x?zQZnr}&my?Dnz~OM9 z)oNk0*~lLWI)5Av*lxG7x8LvOo3Q0_iF7&*i^XyQP-8F|)k;9e;}Nsj z4242LMpP9j0CwVHCq)G%6T;v*0r`CXH{ka6RuoXCvJ?;4m4#G5g$jU8RRshzn@!b3 z1@iUvh0o7VRSiM&`CLX|jS6r&op^nH#c()8zu!l%*MCE|+eN$G7Vz8Kn*>$XYBgjs z8PIqY;C8!Ftyaa|L?R&(kH_)+{EVlkC&XegJU%`m5C}--+1=gU1>o^`P%fA8^70}o z7K;TYlL^M-vBY#b6@^Bl5y4f{q`_d2IeGt7LTIPcK{y;nBodJ^yk74Gz}fgbDXm_w%iGUpv(lA@ zax9vcOeO{J@bCb?-+uwz-`|S|G>=YGK0C6Q!JDB6l}bgLPzh_)5p+78$l@mF<0#54 qFf*djsGQM6cGv6m7XV5B8$UiTHe|hme?kBN00{s|MNUMnLSTZhharUk delta 483 zcmV<90UZ9F1@Z%s8Gix*005AYXf^-<00wkYPE!E?00030iNG(A0004}Nkl5o%C>EdF$pgKAdN&s_!UIt zoMVh3qW8Yn>vcMve}ELJ$2m_WBBnht#@~`e>b-ITq~9qg!0Ur}6|dQeIwB^XM3k1l z0gN%{Tvb)^Gk-z|udZ|M4G==qb$z*9thLF5M4gDd_jO(8d9IWaLcBF3HzXnyWj8I z?N&-z6ouAWN?F(Sa5zk-cmp`+Aq4Ne)_O9TFvf1Tn_RV42w{xr_xq2>qix&wr4dmn zmAqT6Rz&ntkBCK4R8^(5PQD8OI2;b$Zr2!dJRX%&-g_cS1d^N2=hJ(CI-LLj2?+it Z{sMsv7lCWjXNmv-002ovPDHLkV1iwr+V%hd diff --git a/KeePass/Resources/Nuvola_Derived/B16x16_File_Close.png b/KeePass/Resources/Nuvola_Derived/B16x16_File_Close.png index 20394a6c444abea8c744a4202303ecba08ce0d59..4818ef44cd470598a75e0b82d913735fc4bd759c 100644 GIT binary patch delta 718 zcmV;<0x|uL1=|IX8Gi-<001BJ|6u?C00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQ zF)%Rna-jeK0!m3lK~y+TrIXuBlW`cw{bQ<&NN*&eA|($w*MD5o>85!ooaD?cu!9## zw6MS=LUD;%(@>UeOjf?Ob-+XzUcQI$ z3V25NblSyuu7934c4rbO4p78TDh@;NAw-s7{hQpE!5;$eG;|K~syZ z5HVR`b^-c*{Jzo)-TiQ9R*n9})yc2RJ(5{B>*w6u-kqBaP-<4wUW`K5b=0eOfbSRG zs+ca1_U_ssA5XUP;)s*b0h0<*GnmmG3;t|9_x2Sg z0E&^LdkZ832Wzcj=2%e5u`{D9K`C#(R3N^9d}|}9w{Uf<7CqhtWfOBYb2mpXB{cHb zdQ{p}Cd(`k6M;Ov7-yAdEBzU}lEyk|lvf)Z3`b?|5mC8Bt(BUq#IOog=+7>~y(L}X z)u~5$^Ff(2lt`p3X;qf$wvuunPxtr3^e@Ny4|*#{)lcZ)C;$Ke07*qoM6N<$f|+$e A!vFvP delta 640 zcmV-`0)PG61&#%f8Gix*005AYXf^-<00wkYPE!E?00030iNG(A0006*Nkl95zL`5NXh4VyJ-eISUw_WYy@wcJ!2hV~&>XvW zKby@FVnRe!Rh>?U|8?-s1+wQ*7#NDh7CDZyp7+7g6Yz5j67kH^*Kqig*L(8Rlg9^u z!oW~Gp19c43oHvQr{T*o2m&Y?Wb>**=jJ9oo`&Y9!~2n9v2SgC{lKRUQ6$kQG&Dg; zDyDg>l~q;U?|;8CJw4tG005@l+#KfvhXW*uJPd%D?5wO7)4bhL%RK6{*4t%S_Il6E zT)$ZXcs?UZ2!92}+gA<|EL3tIcAY4ZSFpq^2e}tN=3zgYL+UdDpPb=41`cBK`V2HZF<$k%n_W#h@dNvYS)^&YtZC#cHhA{yc#iH>3)d(W+eA?%0h1G-A zSPJyd&o9)~HCimyh&rOK>xLwiG8vxZS}wf_9q!VuX4^YbsSQLx)G4JNPh(W9100006%xCklz&ny7iy(2Z1S#*#EcSg zEmugQyllc|NYCue_81%X*b5&=bMb6rZKr;ni_`DZ=X`(XXaLP$Ri{73FzsYy&c)EI zi$RMMlc-_K6?(Isiq<31hUU-apM#c34>z(xIt{T8czzSR0*MqH-pXhV?!tiPaf$0t zoRk2(#v%Lyfqw`@VsPM!P&44m2Na_nio(7tO7(y@A5e_;t?!*J`x7;T{(L|&+PZm# z#-#+6#$X0es&>0srp%nCqW>3As&?-}nDWt2w0*yTQne>H9??#HQQr5MxkB@VggYz- zEmkrqW-Uf0i=@?QtF?`Dm(-g4RO!z%fR+glc3*-(EPsXnC5iV*;XbIKPCHjy{c<%; z;=%N6r|I5Q=vr6kT#eJQ5=WhOu67onVN625{*L1!z=bn}*^)8H75>-o70nP3TbBp3}@&@Z&+N|!M3!E)w(BY fm)x}f`xf@!jxHplmyr)100000NkvXXu0mjfLkjW# delta 425 zcmV;a0apI21h@l`8Gix*005AYXf^-<00wkYPE!E?00030iNG(A00009a7bBm000XU z000XU0RWnu7ytkPSV=@dRCwBr&OJ_BK@>pYb7#ge;MjUd1j!xHnFV+W*#JW6=&}MT zHb8^e09{%dDCsCE5CTPtC{npdg7`7Sf7tV8=29RT%tOehKY!9EiZa>y=2>HR2HqJoX-cXfi4Yiif+Gb} znX60;V@X3fIB30=?C&%a_8IS{k#u^4-Y|%miQxmu_L1?W&pzdVn?^Fz?q8CX6~Ij+ zsW0fy2T3CUH-C*Jt0mKyga8gf#5haYp&&Uyc_ZnzZ)<~?-`~Qb6J+4!sv9(EiZRcL zF};y&eP0Ej4!Ed#_{;iU9wI(!jP!@^NXEISbpMYw8XaqGwPJ#@yH8Q_GAKliC+9&- zT>I+0*ZP7hN?r!6JbIlib&N58{@NHct7S#WtKs@C4)h9X>b^0oZor)vzY+XvSl`J;c;v1?fYv2dFpR8Gb`&0L>3^@55jSrN;_ZtMoVE@%X9LT6_th`w8_nRGZM~ zK)&?C_V)fFV1LXW6*NS_=o*Ss$B1}*6)Rt?Vz;Y{fH7N9PDDYQUawEL+oRd~pjzwj zTa{iicvRko@|MeY@WKw1E2 zJUkS+zb_CD>jJ%GclT&kFrBtBTasjCIVd)q5{sP+OeYf2@p_MOIs;fNwh3UI_PW`| zFLw+~r@e0W959>qy4iEUdedI@)0zI0{j100000NkvXXu0mjf D)otCZ delta 425 zcmV;a0apHy1h@l`8Gix*005AYXf^-<00wkYPE!E?00030iNG(A00009a7bBm000XU z000XU0RWnu7ytkPSV=@dRCwBr(7i4MVHC#k=e+N+Uos;^<6|Rn4Jy3~(cuob4;oQ& z4T44@(Mz_|FOe*X#B8(JuNX4#JLf3Ku)B(R+LM3s%OQngaDV%Ihx2puTre&bO;t%q zq~HH&G#-zR4;Uk>Ru|XSSHg+#)5CkPMZuyOHP6p30sIrFii!|G0`Z6wIEGgWf?y!X zB;?r`!xqKwqk~sK4G|3lndJ23LPX>EQ$(Cs@5QBXE*TCo34n)(D30GnR76C?IbSMO zhztN8l>pT3_J0=^rmW?1xd`Cu>N*If0RmvE)y4IV)vfIFW_EdbDM?(dc4KYj?d@e}cQgA9=al>na!Ce)JR*|cAgAOv==EOnNV0taudNa{ TA&~j>00000NkvXXu0mjfhFH3f diff --git a/KeePass/Resources/Nuvola_Derived/B16x16_Key_New.png b/KeePass/Resources/Nuvola_Derived/B16x16_Key_New.png index de21b88b86fe7b942683926ad3a4573252351572..fb4f54e8d9737b831f80ac7669a6e556d1eec727 100644 GIT binary patch delta 755 zcmVYU8Onx~xR)X8K{e|?*1388lJ@Vzg* z&yWA}J?|^*RR#!a$u@3gytx5w^a=X16gaF_W{v$geQTQQ(&A{oC#5+xfx)6cI^(41 zlP}X7=ZCG&z<-*6w%jZ_UdYg;2V=_fr#Ib~pJj(ICWYa!SXKvU3t!UoFoC+*^H^J> zz?O((>>@uN_+U(tF#7!VAAnX>#mA&`6yFM?Dl-F9ceg9|_v|QinITNIL;?!ttydV% z@n$67gQ2^}76GIE{Z!vL2xf_R=nhjoDSXbj%G+m|=zlBAX-o*gQYqt?M#8lE6k~Z} zg!@T2CdLr#v$H6p&!U#^CpYv0GlpOn1adHxhKoNhhV~pOs)$P%v(L~F5kRZL7gMS) z7O@GTBqjuV(@wr+?&6(12>YmqXg(s!IdUSkMTM>?&iZ;D`MJK%y;H6l3qp@FSHA_i zH^Sg%n12#reiL@9CkvB@DGWc(_`rbc@Q_A@#kAP}k_79-1jUj5I2t!VyJ+qbWfrh? z3s|+=m^ON$O7^26|Md#vGQhc*5&JB@8HDbsX#OgyL)5US5rH|q8w+N43>7|<%C9kQ zGOe88?{PXc8k8}CluEs+xbDf9csC|%1m^1n>}-A8vGsUS9e+CsRd3>;PR9pD z8p<$tXc1Uw*~r4s9`v~f`1IuQ`rd+b!mip{%3?#Qk?w{zXT+_%k)2*YU@2yYTFraO l4$7tbD3QzlAMmed{~M#2H+EaRt^EK1002ovPDHLkV1gBpVORhF delta 657 zcmV;C0&e|)2A&0w8Gix*005AYXf^-<00wkYPE!CP0I>i}Zc*ZC00070NkluI3=9k>^rxKb_j9jNV-QjNeDCwQEv>KEP4s1*Kb%-8`RvF04@X)5 zzF}o%`T8POI)5vN@z;+Z+pB`OneIM$qZeB9n@ic4fkFE2`r{vO@UcsLe0=7smeITC z=U6#ZUkQI_;Ei6zZ1DYocjV#EU;h03Ew15og_-*a0|SeYrs(aL2FjXFybS;Ue!s*k z>n&!H#;W3Ja;t*n$J;xMf4&&H|1#v>&A{=U;osxm-+w={{N;MSYmZL-Drd31NBF9^ zR5Xpw(R-P>|1z*JFbFgJc+c?n2mgP5nIj8@1eLO)c$XpvAoB{V zt9^;fw@kgt^!28QC|;~y%sPOvsuX0=AfS1seSRc47wX0hrr z%lytGC8QN|^?yB_egG#L;Yb}M*TB9?ND=GZX4p{-;e`;C52`%yzYLr8uws`PX-8ra zu{k!vFIb7XXeA;`ko}3UOe;Q#t*FvF3AykI%{eQ9V`Ny-2sUKeSR7W0q>e76_<@Zt z_OJAPM{&6MU{#2VyF&Z3k0?$zisS1zc7em`LVw@Rf`0%b(v}zl<*jyp4TpG`c%Xoe zPTTm^sK>+b@CZXgZm}D}_@tltYT;m0bTMU5CJQLS&7S02yzS^27Z@CL<8lqs-|qtV z03{Ed%u}0?{9}xm9xIa^j0q$hEaFXva4$u^UVpvo!Q&ahDe4|e?(KCj16$N)*Qeb{Tf$2H%Lf~deJ2wnZxvqc2wfq)x z^X`+MS4--pHoSwXkydIe*qzyiE~|mVS@ooyuYW_AVL^AMn$+~W96EJ}l;b9nkCu?6 zGq69Ukb_CNgeO%oC&+@dJhlo$^F#@w;-0E)T1lJ)gjjh4ZIMM5W z34P6Hyh9q0RwXvEH}4B)jXj(+*f^%|{wq|Oz08PgLGl${Sfs6IcGNv)MOv5{VPSf> zg)(WO7G`a)XKH9IUZPenjhF)kYQff8rUcfrFv`p~Ro4#rgxMBj00000NkvXXu0mjf Dn$Lqz delta 529 zcmV+s0`C3A2A>3w8Gix*005AYXf^-<00wkYPE!E?00030iNG(A0005hNkl6(!0)iqj z68x8hnB8QP-JLndVnNV|;4tODnRCw11mSoCqNT4g}#uj8|}^ zs=Havo}0OF`^MU5cwiVfaCo3mW2cAxAqI|-V;DFXp*n(%$8%+8R}1r7-R*;%K?0T- z{II$)Jw4TIRS^_Wgf_63oBMs1onG9U#iiNfHh$4^uiL+W@9CZEm(R?cfC7L4W_q$b zy8E2PEw!4Bsehx*U$zqJda^ayt~-+rF$YDms#Mpcr4mZyZ#htqWl{i!qaaDLGATq@ zaZA*n$toqmAdz$@NhXnGN`*)~)P!=TL@|OSBj^zk2BopW;d-*Da7M^o5%ff7g5?s( zOYgSg$M>K_frJF$^~%?mZ`KvTAR{UaUu_+erQ)!)FMqw=Z@mO5Bod5vyINdY=O`3T z4>=pr|A^B015yANkvXXu0mjf2=(}+ diff --git a/KeePass/Resources/Nuvola_Derived/B16x16_Window_3Horz.png b/KeePass/Resources/Nuvola_Derived/B16x16_Window_3Horz.png index d46201a6958a731a7c94fb6d2bb4430178250860..cd9e3bcba7e8e96f0fb91cc0ffb187bf2ba41798 100644 GIT binary patch delta 793 zcmV+!1Lpky1EmI#8Gi-<001BJ|6u?C00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQ zF)%Rna-jeK0+dNaK~y+TrIA}mlVKc(-;25kqJj<*QFP};M}I3KiI9q#&S}dd6*)<2 zW+Zdt%EkRgLaU}h!V@=Z0fe$+*0hYr`P4DTXfg=@#FpT z@bd8czP~{H-zzi;=gBY>q2H>Y%T!3nP}q>Bur5_0POq?9W>vDn3Y|iXR$+0x!UBy# zwB`znV$ULS3xCX9>wuH>aQrD8ehm9-VDAGsAm<%c*kXp1a!4u#O$o$ZfemG_bek2i zC9i_)A~z}L9Hd`xu({B|;=DI#PPK<-H7ZLy<3J~~w$M%V<~s=O_HxYiZoc}4=$Gko zc*)7RO4GaU(5yyfzJVbI{DYJ|_c1rYg4md4!uH08`hN__3wir)(Aw_)CmSCAF8MH) z#sG7)vcdZ8W~v&;1zy==_x_uFYIThX!dW0N2;aYP>!qLB+Db%RmW9gK-iXV&2Pze#)PDiAuB~VhvVV z=PyA)C4V1V`XX8xM_F&Lmv8+ZN}u%01`iM`4K~aTk%C=Eth{gTi4dr)yW4}$)yMT( z53`c05z7qsFxCGN1cSdqtK50iM$-r9m>`^WboAkIIw`JkF*C`ISd#q^(`bWWFo;*K zap$r7ynX*=yg?XiYjfi2>Y}*1kD1Aj5eu_xFn>KA`QtxjelQg9V?1`3=8s)tf^g>Q z>}0T~owAx9W^H1&xNzjdNco{2JAnfO{JB-Sx6-O6uj XL=p`u<5)#Q00000NkvXXu0mjfZZvoq delta 496 zcmV+_F8pr z8fch{ybb(H^>h+>F!DzSxP5R*fbnSl{Mnl)_wV$2?IzH0fB&KgUw>RaeHYn8x9Xy| zQv*nXs?F2} z*pd*@T(#<>WBq*ApPNh<{%N*%_+Bo2_}*k1LUWe*^0Sy1rQCe@vX7nd#7J=>hzL|w mn#{wTpnw2@0Fz#64SxfV!zm4UA)j0T0000 0)) + string strPath = (kCommand.GetValue(string.Empty) as string); + if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } - else strPath = null; + else { Debug.Assert(false); } kCommand.Close(); - kOpen.Close(); - kShell.Close(); - kHtml.Close(); return strPath; } - // HKEY_CLASSES_ROOT\\ChromeHTML\\shell\\open\\command private static string FindChrome() { if(NativeLib.IsUnix()) @@ -229,60 +218,80 @@ private static string FindChrome() return FindAppUnix("chromium-browser"); } + string strPath = FindChromeNew(); + if(string.IsNullOrEmpty(strPath)) + strPath = FindChromeOld(); + return strPath; + } + + // HKEY_CLASSES_ROOT\\ChromeHTML[.ID]\\shell\\open\\command + private static string FindChromeNew() + { RegistryKey kHtml = Registry.ClassesRoot.OpenSubKey("ChromeHTML", false); - RegistryKey kShell = kHtml.OpenSubKey("shell", false); - RegistryKey kOpen = kShell.OpenSubKey("open", false); - RegistryKey kCommand = kOpen.OpenSubKey("command", false); - string strPath = (kCommand.GetValue(string.Empty) as string); + if(kHtml == null) // New versions append an ID + { + string[] vKeys = Registry.ClassesRoot.GetSubKeyNames(); + foreach(string strEnum in vKeys) + { + if(strEnum.StartsWith("ChromeHTML.", StrUtil.CaseIgnoreCmp)) + { + kHtml = Registry.ClassesRoot.OpenSubKey(strEnum, false); + break; + } + } + + if(kHtml == null) return null; + } + + RegistryKey kCommand = kHtml.OpenSubKey("shell\\open\\command", false); + if(kCommand == null) + { + Debug.Assert(false); + kHtml.Close(); + return null; + } + string strPath = (kCommand.GetValue(string.Empty) as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } - else strPath = null; + else { Debug.Assert(false); } kCommand.Close(); - kOpen.Close(); - kShell.Close(); kHtml.Close(); - return (strPath ?? FindChromeOld()); + return strPath; } // HKEY_CLASSES_ROOT\\Applications\\chrome.exe\\shell\\open\\command private static string FindChromeOld() { - RegistryKey kApps = Registry.ClassesRoot.OpenSubKey("Applications", false); - RegistryKey kExe = kApps.OpenSubKey("chrome.exe", false); - RegistryKey kShell = kExe.OpenSubKey("shell", false); - RegistryKey kOpen = kShell.OpenSubKey("open", false); - RegistryKey kCommand = kOpen.OpenSubKey("command", false); - string strPath = (kCommand.GetValue(string.Empty) as string); + RegistryKey kCommand = Registry.ClassesRoot.OpenSubKey( + "Applications\\chrome.exe\\shell\\open\\command", false); + if(kCommand == null) return null; + string strPath = (kCommand.GetValue(string.Empty) as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } - else strPath = null; + else { Debug.Assert(false); } kCommand.Close(); - kOpen.Close(); - kShell.Close(); - kExe.Close(); - kApps.Close(); return strPath; } // HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Computer, Inc.\\Safari\\BrowserExe private static string FindSafari() { - RegistryKey kSoftware = Registry.LocalMachine.OpenSubKey("SOFTWARE", false); - RegistryKey kApple = kSoftware.OpenSubKey("Apple Computer, Inc.", false); - RegistryKey kSafari = kApple.OpenSubKey("Safari", false); - string strPath = (kSafari.GetValue("BrowserExe") as string); + RegistryKey kSafari = Registry.LocalMachine.OpenSubKey( + "SOFTWARE\\Apple Computer, Inc.\\Safari", false); + if(kSafari == null) return null; - if(strPath != null) + string strPath = (kSafari.GetValue("BrowserExe") as string); + if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); @@ -290,8 +299,6 @@ private static string FindSafari() else { Debug.Assert(false); } kSafari.Close(); - kApple.Close(); - kSoftware.Close(); return strPath; } diff --git a/KeePass/Util/GlobalMutexPool.cs b/KeePass/Util/GlobalMutexPool.cs index 43964a8..8bf1813 100644 --- a/KeePass/Util/GlobalMutexPool.cs +++ b/KeePass/Util/GlobalMutexPool.cs @@ -201,7 +201,8 @@ public static void Refresh() private static string GetMutexPath(string strName) { - string strDir = UrlUtil.EnsureTerminatingSeparator(Path.GetTempPath(), false); + string strDir = UrlUtil.EnsureTerminatingSeparator( + UrlUtil.GetTempPath(), false); return (strDir + IpcUtilEx.IpcMsgFilePreID + IpcBroadcast.GetUserID() + "-Mutex-" + strName + ".tmp"); } diff --git a/KeePass/Util/IpcBroadcast.Fsw.cs b/KeePass/Util/IpcBroadcast.Fsw.cs index 6aed17b..f7ba4e4 100644 --- a/KeePass/Util/IpcBroadcast.Fsw.cs +++ b/KeePass/Util/IpcBroadcast.Fsw.cs @@ -49,7 +49,8 @@ private static void FswEnsurePaths() { if(m_strMsgFilePath != null) return; - string strDir = UrlUtil.EnsureTerminatingSeparator(Path.GetTempPath(), false); + string strDir = UrlUtil.EnsureTerminatingSeparator( + UrlUtil.GetTempPath(), false); m_strMsgFileName = IpcUtilEx.IpcMsgFilePreID + GetUserID() + IpcUtilEx.IpcMsgFilePostID; m_strMsgFilePath = strDir + m_strMsgFileName; @@ -109,7 +110,7 @@ private static void FswStartServer() { FswEnsurePaths(); - m_fsw = new FileSystemWatcher(Path.GetTempPath(), m_strMsgFileName); + m_fsw = new FileSystemWatcher(UrlUtil.GetTempPath(), m_strMsgFileName); m_fsw.IncludeSubdirectories = false; m_fsw.NotifyFilter = (NotifyFilters.CreationTime | NotifyFilters.LastWrite); diff --git a/KeePass/Util/IpcUtilEx.cs b/KeePass/Util/IpcUtilEx.cs index 247a111..3953c5a 100644 --- a/KeePass/Util/IpcUtilEx.cs +++ b/KeePass/Util/IpcUtilEx.cs @@ -115,7 +115,7 @@ private static string GetIpcFilePath(int nId) { try { - string str = Path.GetTempPath(); + string str = UrlUtil.GetTempPath(); str = UrlUtil.EnsureTerminatingSeparator(str, false); return (str + IpcMsgFilePreID + nId.ToString() + ".tmp"); diff --git a/KeePass/Util/SessionLockNotifier.cs b/KeePass/Util/SessionLockNotifier.cs index 276b3ef..b66f7ac 100644 --- a/KeePass/Util/SessionLockNotifier.cs +++ b/KeePass/Util/SessionLockNotifier.cs @@ -114,7 +114,9 @@ private void OnSessionSwitch(object sender, SessionSwitchEventArgs e) r = SessionLockReason.Lock; else if(e.Reason == SessionSwitchReason.SessionLogoff) r = SessionLockReason.Ending; - else if(e.Reason == SessionSwitchReason.SessionRemoteControl) + else if((e.Reason == SessionSwitchReason.SessionRemoteControl) || + (e.Reason == SessionSwitchReason.RemoteConnect) || + (e.Reason == SessionSwitchReason.RemoteDisconnect)) r = SessionLockReason.RemoteControlChange; if(r != SessionLockReason.Unknown) diff --git a/KeePass/Util/ShellUtil.cs b/KeePass/Util/ShellUtil.cs index 6f6674a..17dac7c 100644 --- a/KeePass/Util/ShellUtil.cs +++ b/KeePass/Util/ShellUtil.cs @@ -46,8 +46,8 @@ public static class ShellUtil try { kClassesRoot.CreateSubKey("." + strFileExt); } catch(Exception) { } RegistryKey kFileExt = kClassesRoot.OpenSubKey("." + strFileExt, true); - kFileExt.SetValue(string.Empty, strExtId, RegistryValueKind.String); + kFileExt.Close(); try { kClassesRoot.CreateSubKey(strExtId); } catch(Exception) { } @@ -58,11 +58,11 @@ public static class ShellUtil try { kExtInfo.CreateSubKey("DefaultIcon"); } catch(Exception) { } RegistryKey kIcon = kExtInfo.OpenSubKey("DefaultIcon", true); - if(strAppPath.IndexOfAny(new char[]{ ' ', '\t' }) < 0) kIcon.SetValue(string.Empty, strAppPath + ",0", RegistryValueKind.String); else kIcon.SetValue(string.Empty, "\"" + strAppPath + "\",0", RegistryValueKind.String); + kIcon.Close(); try { kExtInfo.CreateSubKey("shell"); } catch(Exception) { } @@ -77,8 +77,12 @@ public static class ShellUtil try { kShellOpen.CreateSubKey("command"); } catch(Exception) { } RegistryKey kShellCommand = kShellOpen.OpenSubKey("command", true); - kShellCommand.SetValue(string.Empty, "\"" + strAppPath + "\" \"%1\"", RegistryValueKind.String); + kShellCommand.Close(); + + kShellOpen.Close(); + kShell.Close(); + kExtInfo.Close(); ShChangeNotify(); @@ -128,6 +132,7 @@ private static void ShChangeNotify() { RegistryKey kRun = Registry.CurrentUser.OpenSubKey(AutoRunKey, true); kRun.DeleteValue(strAppName); + kRun.Close(); } } catch(Exception) { Debug.Assert(false); } @@ -138,8 +143,8 @@ public static bool GetStartWithWindows(string strAppName) try { string strNotFound = Guid.NewGuid().ToString(); - string strResult = Registry.GetValue("HKEY_CURRENT_USER\\" + AutoRunKey, - strAppName, strNotFound) as string; + string strResult = (Registry.GetValue("HKEY_CURRENT_USER\\" + AutoRunKey, + strAppName, strNotFound) as string); if((strResult != null) && (strResult != strNotFound) && (strResult.Length > 0)) @@ -171,6 +176,7 @@ public static bool GetStartWithWindows(string strAppName) { RegistryKey kRun = Registry.LocalMachine.OpenSubKey(PreLoadKey, true); kRun.DeleteValue(strAppName); + kRun.Close(); } } catch(Exception) { Debug.Assert(false); } diff --git a/KeePass/Util/TempFilesPool.cs b/KeePass/Util/TempFilesPool.cs index 9cc9e5b..97784bc 100644 --- a/KeePass/Util/TempFilesPool.cs +++ b/KeePass/Util/TempFilesPool.cs @@ -76,7 +76,7 @@ public void AddDirectory(string strTempDir, bool bDeleteRecursive) public string GetTempFileName() { - return this.GetTempFileName(true); + return GetTempFileName(true); } public string GetTempFileName(bool bCreateEmptyFile) diff --git a/KeePass/Util/WinUtil.cs b/KeePass/Util/WinUtil.cs index d068296..8e944e8 100644 --- a/KeePass/Util/WinUtil.cs +++ b/KeePass/Util/WinUtil.cs @@ -379,7 +379,7 @@ private static string FreeDriveIfCurrent(char chDriveLetter) char chCur = char.ToUpper(strCur[0]); if(chPar != chCur) return string.Empty; - string strTemp = Path.GetTempPath(); + string strTemp = UrlUtil.GetTempPath(); WinUtil.SetWorkingDirectory(strTemp); return strCur; diff --git a/KeePassLib/Native/NativeMethods.cs b/KeePassLib/Native/NativeMethods.cs index 87170bd..41bbd2e 100644 --- a/KeePassLib/Native/NativeMethods.cs +++ b/KeePassLib/Native/NativeMethods.cs @@ -21,6 +21,10 @@ using System.Text; using System.Security; using System.Runtime.InteropServices; +using System.IO; +using System.Diagnostics; + +using KeePassLib.Utility; namespace KeePassLib.Native { @@ -148,6 +152,27 @@ internal static int StrCmpNaturally(string x, string y) return x.CompareTo(y); #else return StrCmpLogicalW(x, y); +#endif + } + + internal static string GetUserRuntimeDir() + { +#if !KeePassLibSD + string strRtDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); + if(string.IsNullOrEmpty(strRtDir)) + strRtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + if(string.IsNullOrEmpty(strRtDir)) + { + Debug.Assert(false); + return Path.GetTempPath(); // Not UrlUtil (otherwise cyclic) + } + + strRtDir = UrlUtil.EnsureTerminatingSeparator(strRtDir, false); + strRtDir += PwDefs.ShortProductName; + + return strRtDir; +#else + return Path.GetTempPath(); #endif } } diff --git a/KeePassLib/Properties/AssemblyInfo.cs b/KeePassLib/Properties/AssemblyInfo.cs index 2fe2c41..a506eb0 100644 --- a/KeePassLib/Properties/AssemblyInfo.cs +++ b/KeePassLib/Properties/AssemblyInfo.cs @@ -38,5 +38,5 @@ [assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")] // Assembly version information -[assembly: AssemblyVersion("2.20.0.*")] -[assembly: AssemblyFileVersion("2.20.0.0")] +[assembly: AssemblyVersion("2.20.1.*")] +[assembly: AssemblyFileVersion("2.20.1.0")] diff --git a/KeePassLib/PwDefs.cs b/KeePassLib/PwDefs.cs index d165d4b..3766103 100644 --- a/KeePassLib/PwDefs.cs +++ b/KeePassLib/PwDefs.cs @@ -54,18 +54,18 @@ public static class PwDefs /// e.g. 2.19 = 0x02130000. /// It is highly recommended to use FileVersion64 instead. /// - public const uint Version32 = 0x02140000; + public const uint Version32 = 0x02140100; /// /// Version, encoded as 64-bit unsigned integer /// (component-wise, 16 bits per component). /// - public const ulong FileVersion64 = 0x0002001400000000UL; + public const ulong FileVersion64 = 0x0002001400010000UL; /// /// Version, encoded as string. /// - public const string VersionString = "2.20"; + public const string VersionString = "2.20.1"; public const string Copyright = @"Copyright © 2003-2012 Dominik Reichl"; diff --git a/KeePassLib/Utility/AppLogEx.cs b/KeePassLib/Utility/AppLogEx.cs index c4d3afa..b1353e5 100644 --- a/KeePassLib/Utility/AppLogEx.cs +++ b/KeePassLib/Utility/AppLogEx.cs @@ -51,7 +51,7 @@ public static void Open(string strPrefix) string strDirSep = string.Empty; strDirSep += Path.DirectorySeparatorChar; - string strTemp = Path.GetTempPath(); + string strTemp = UrlUtil.GetTempPath(); if(!strTemp.EndsWith(strDirSep)) strTemp += strDirSep; diff --git a/KeePassLib/Utility/GfxUtil.cs b/KeePassLib/Utility/GfxUtil.cs index 5edf5c1..2b48740 100644 --- a/KeePassLib/Utility/GfxUtil.cs +++ b/KeePassLib/Utility/GfxUtil.cs @@ -54,20 +54,28 @@ private static Image LoadImagePriv(Stream s) { #if !KeePassLibSD imgSrc = Image.FromStream(s); - Image img = new Bitmap(imgSrc.Width, imgSrc.Height, + Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height, PixelFormat.Format32bppArgb); + + try + { + bmp.SetResolution(imgSrc.HorizontalResolution, + imgSrc.VerticalResolution); + Debug.Assert(bmp.Size == imgSrc.Size); + } + catch(Exception) { Debug.Assert(false); } #else imgSrc = new Bitmap(s); - Image img = new Bitmap(imgSrc.Width, imgSrc.Height); + Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height); #endif - using(Graphics g = Graphics.FromImage(img)) + using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.DrawImage(imgSrc, 0, 0); } - return img; + return bmp; } finally { if(imgSrc != null) imgSrc.Dispose(); } } diff --git a/KeePassLib/Utility/UrlUtil.cs b/KeePassLib/Utility/UrlUtil.cs index 5d01cfd..178c081 100644 --- a/KeePassLib/Utility/UrlUtil.cs +++ b/KeePassLib/Utility/UrlUtil.cs @@ -20,9 +20,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using System.Diagnostics; using KeePassLib.Native; @@ -588,5 +588,22 @@ public static bool AssemblyEquals(string strExt, string strShort) return false; } + + public static string GetTempPath() + { + string strDir; + if(NativeLib.IsUnix()) + strDir = NativeMethods.GetUserRuntimeDir(); + else strDir = Path.GetTempPath(); + + try + { + if(Directory.Exists(strDir) == false) + Directory.CreateDirectory(strDir); + } + catch(Exception) { Debug.Assert(false); } + + return strDir; + } } } diff --git a/KeePassLibSD/Properties/AssemblyInfo.cs b/KeePassLibSD/Properties/AssemblyInfo.cs index 5cd83ff..47ffb10 100644 --- a/KeePassLibSD/Properties/AssemblyInfo.cs +++ b/KeePassLibSD/Properties/AssemblyInfo.cs @@ -38,4 +38,4 @@ [assembly: Guid("1d3c6f10-e10b-47be-a2f1-af2562d7d470")] // Assembly version information -[assembly: AssemblyVersion("2.20.0.*")] +[assembly: AssemblyVersion("2.20.1.*")] diff --git a/ShInstUtil/ShInstUtil.rc b/ShInstUtil/ShInstUtil.rc index 31cfe29..97955d5 100644 --- a/ShInstUtil/ShInstUtil.rc +++ b/ShInstUtil/ShInstUtil.rc @@ -65,8 +65,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,20,0,0 - PRODUCTVERSION 2,20,0,0 + FILEVERSION 2,20,1,0 + PRODUCTVERSION 2,20,1,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -83,12 +83,12 @@ BEGIN BEGIN VALUE "CompanyName", "Dominik Reichl" VALUE "FileDescription", "ShInstUtil - KeePass Helper Utility" - VALUE "FileVersion", "2, 20, 0, 0" + VALUE "FileVersion", "2, 20, 1, 0" VALUE "InternalName", "ShInstUtil" VALUE "LegalCopyright", "Copyright (c) 2007-2012 Dominik Reichl" VALUE "OriginalFilename", "ShInstUtil.exe" VALUE "ProductName", "ShInstUtil - KeePass Helper Utility" - VALUE "ProductVersion", "2, 20, 0, 0" + VALUE "ProductVersion", "2, 20, 1, 0" END END BLOCK "VarFileInfo" diff --git a/Translation/TrlUtil/Properties/AssemblyInfo.cs b/Translation/TrlUtil/Properties/AssemblyInfo.cs index e45e4fa..51a3108 100644 --- a/Translation/TrlUtil/Properties/AssemblyInfo.cs +++ b/Translation/TrlUtil/Properties/AssemblyInfo.cs @@ -38,5 +38,5 @@ [assembly: Guid("39aa6f93-a1c9-497f-bad2-cc42a61d5710")] // Assembly version information -[assembly: AssemblyVersion("2.20.0.*")] -[assembly: AssemblyFileVersion("2.20.0.0")] +[assembly: AssemblyVersion("2.20.1.*")] +[assembly: AssemblyFileVersion("2.20.1.0")]