From 679fff5e63ade1c044907fb00333d51489e45307 Mon Sep 17 00:00:00 2001 From: Alexis Delhaie Date: Sun, 25 Oct 2020 21:50:45 +0100 Subject: [PATCH] Add params and headers --- javafx.bootstrap/javafx.bootstrap/icon.ico | Bin 0 -> 115416 bytes .../javafx.bootstrap/javafx.bootstrap.rc | 2 +- javafx.bootstrap/javafx.bootstrap/main.cpp | 2 +- src/main/java/META-INF/MANIFEST.MF | 3 + .../alexisdelhaie/endpoint/Application.java | 3 +- .../alexisdelhaie/endpoint/MainWindow.form | 91 +++++---- .../alexisdelhaie/endpoint/MainWindow.java | 135 ++++++++++++-- .../endpoint/builder/TabBuilder.java | 114 +++++------- .../endpoint/configuration/AboutDialog.form | 63 +++++++ .../endpoint/configuration/AboutDialog.java | 37 ++++ .../configuration/ConfigurationDialog.form | 175 ++++++++++++++++++ .../configuration/ConfigurationDialog.java | 64 +++++++ .../ConfigurationProperties.java | 7 + .../endpoint/http/HttpClient.java | 8 +- .../alexisdelhaie/endpoint/utils/Tools.java | 14 ++ .../adapter/CustomDeleteMouseAdapter.java | 34 ++++ .../utils/adapter/CustomNewMouseAdapter.java | 36 ++++ .../adapter/DeleteParamMouseAdapter.java | 26 +++ .../utils/adapter/NewParamMouseAdapter.java | 26 +++ src/main/resources/icon.png | Bin 0 -> 22975 bytes 20 files changed, 720 insertions(+), 120 deletions(-) create mode 100644 javafx.bootstrap/javafx.bootstrap/icon.ico create mode 100644 src/main/java/META-INF/MANIFEST.MF create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java create mode 100644 src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java create mode 100644 src/main/resources/icon.png diff --git a/javafx.bootstrap/javafx.bootstrap/icon.ico b/javafx.bootstrap/javafx.bootstrap/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2c0ff3c33d76341d89462b683eb625a4ef1d789f GIT binary patch literal 115416 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

hV(4J+*rdNuW6L)h@?%MZgBO zRfJvrEOF*$NA6iPcG>p7#pfnCQ=}(>M#QU~EYD+$H8;I>EYg0}wYn0$v`t)~&;Oc7 zT>mm2-rB_q3l4g1R}37TE$-}lf;}ZT|B(zCli?i=^6KHA=pGmGNRha@MNAQlv9*pH zqzj8_iE+dk+wnqwEvpJT#PbL-IKl(B1qmMFc}X4TMVWXk-k?H$tZjd_T+=3nIz#-0 zaisSwEUEy0enmoinvn21kk1C#e0>rQ5V`Q;Ti^WehOQarv4x{zD(Hyh7f#qnlm^F=r|`3pyIT>T|Kz{6tvb zmnAW_GR3&CJr+*&L=8hV6@|<&Xad12bao@XB(!US0Xynj5lJWbJ(vWKb#Yb6eR+xD zt$bb$Z`*Osc-71~XZdyfm!#3n=@K~pIO7S~QODQ~i2FLE;`jn*A=hu#M%&DJhF1wW zNNBnXt&WUqYm~z>waZYmT`ubcvHVPt4R{9UDIaKjnh(#(a(wr=e!3%wKeulQippHc zXfeYxC@AA*+2~WQTw>%>TvPKmQN(-rvSiPE+MZ0Ol6T|d0}`udY8~4%Q1jj%vM#ds zpFiKQy+h2Ri8JzaY;rNbRmwbevMN23y?|IU_JiRU&!@}S{=`(id(3otP6nuk80{(h zRxLr@c|1)6kQs<}Fr+RNndRQWMo_UxB-$Sh49m^lw?3%8O5YBGW1T>-5Al00k&BRi zLGck}K4G8(M`~$p>@p3K7U21ailo3Y*~*Yv*!gNyH2n*&?k%&n8+EesfV2deLYVS% zsY$uE_hXxiq~m!thos~U%xU;=+$FNOP!V6Vyutu0kKA%}I${IE$}&C1!Wm&eoeF+Q zj>x*QM_D@?jU|M&a#@lYej+q)NQy9^;^LVtZFy)lb1n=ykn4-}HCX3~<2&L;mc>wY zqK;kc8cinyk_6~^?VZY5Y~r*Se@mZ6907`vi%leTE&1D}&qNxgt^LYhb2P|O+4LVV z73k2hoC68mQIff8eFaM{4kwW9)uv%m8B?f2{Oc@liK;h`XV1OeB3q*j=5r@Kz*CuK z+*jQR1Vs`FxGCK}&rjk&h9i(|KPVOBuBH!s)B6$gB=~r;GVC}_&_|H8~e);7R zHc146WJyi9tWazrIP*b0;Zdl^jPY~6977IcDn%;XS6w3bEt*Lz(l-N~{1om9?>!ut zcPHcO?_5dMF)^Z`Q1gSuNZwON^o5tbI`qqXMj*l_(|8LqtK*a>UnoOg9LY6?}Yoyx-}O5%I8r@?w2{8MQ%nx z+U7o$3V(z;fM`PmLk?JE$#d2D2YK^4S=FrOLkQ%qAeO?bie$-c%rtWOTj|peEk?cu zElP#mS{GZ2o+$Waqc4gbm0S_sd~F)fAeacGK^1Z*4V&%F|EffDr-g@ zQJCIXl1uK!2cNF-0$HEgYEG)9tSZq0KPDR&&!Pwi&F1Cq->xt%Sbidi=g6C^o!L&? zwm7W)OiK=OpgR;N92YJ6rm7*={t*MOkDZLy9mqL;(ETb`4*$ccPT z*%GOWm&7v}B}M~qhSZ)ZWLCg=KihB@kg+MeImu`ts@O|(R_rymqr=*7TISYpEj{E24e?dEZ!%yDpFC*-Rb~) z+eu(R+~632ab4#HHvAdJjg^;eQZdSNaX6>|#g)QnHvbjvDZ$M7n60ZszF!8}oG->J z@OeBI+p$pEtB{tMbbB8yg#ldzyW~HY!Lg6{fYzv9yS~RLC~9oir!*E0#Ap)@nFkbM z1#q|N7oIL};=7leuiywgKOe&rD&& z?t{Gt9bztjB)sfvS;iT}ls0$eb?O74x_J958A}39|7Z5cyQa?!=&Rn@m$BU^Ltx+T z*vq{ixPG2E2@N^|El13gA}&Q|sP|Fiumy?3R`=5=Ki+=!>g|(AfyK?26A<3M89pw4 z{^!BP^v-w&_$6sX%Q;}64%q5xLVEiUk3~v)5%`VxlAqWjXK{|B*VP!7FQuQ^V}+R@ z7~};&;}BHGc@NLs7uAtOS?`ar1FaCmEWL?B{=fhkZm_P*kTyHIyzU+F&}p-FCOih` z49f_v7KG_pQ{LOmGGzHjg|b&#R0EG;=G}2^U??5k=(K1wM|gY#j#S4wV=rY=Bsu&G zu>nEmm4t{-OLv>nUS1I3HOR~_9=dE0FDm32pWN%cKr%nZ!OBvtL1LSg1667>y1Q0D1f zV)i{7$#+ykJ~xvRlZ%bZK#Ly^9^sgK%8V&4;Oq~MJqc|4yeR{@c3`i#E%~SbE&xm+ z==77Zku~#93WNcfSDG|=o2KNWxCJ78qit46DlwR^3ym;L!ign>;(1FxwM3VV)14dg zxzKj&HjB$M(lT|VqHT&Jv+;*fhp%!Fbj2;oYa$iQR|pJ99HHC{>xBu&w$?0{BZgJJ zYNfQT&)n{?m}QK)0KVQtIFNcl^TD3(Eg1$qcvZc2S^D9qD~Iu&o5L%S9>bMW*{E^} zg7;?!>t(cX^h?fA74TNPQ`;ZS*{WWsj%F8PG`Ts6J$zE_XU~uF`Di+o$p2wDO1aB- z9_#vJe9CPP39Xl_3LDk;d>zOpxgZBmQ2hh@o$M^A0W;q$va6Pn-5^L_$K zpi}jHXv#&mk{4oD^~hABdvaj)@TKnF?VwV*+dCvO&aWP3x#^dXQ5D3E$2{3k)l;z= zE5OaO|G?{MKnT3bs)wE&LaWxWGgL`i^yJFOh8%)<7*#*-!k9^eZ8!b8!&s=rt?0Lw zR-bgP#@ss|&i#h~%i|c9dd5 zy0c*Y)1MTsse)cYk;``yfw7J*)k}U;aSZb8$$25P`xuawpwts+onnp}8X(N- zjyJ}2wX2%4|xxM9TE{^)hh>=*_WXl(A zOC|VpBadN$v27E}k{49hJ{_K4!rPW>7VD6kjMKd_96PbD5$ZZh-QudQbH=$axX$dl z;H+nR?TssiJ$1J~TXcHLYo5VK2OeG~t*_U2`}(XD%-Gx+!A@MC`oW(1>nwYAneaN} zmj@qo%}Ym>*##rJ64pA{Zpz8#)FqwSssVe<&j<4?tz}Ox*?*~~G~4Q7TbM|;T;;GM z!=!RvS^WwjzM3I%KyWA4O)r{c!NEs#@klSOTJOqjAOSs9ieK7tY*p<( zpQ%Sp%C)2|YS>WvLD zV`Q}ONtEovzPpv-XB6c5^s=K+%FE}dhuW?44-LNN7nfRGv8J6ld(&v}RxHw~KIN!+ zAiK88AiKJtIKTUT2F7Z(Y^M&y^GYPwlnVaoZEgiXDTA@R{UNVrgV*r@xc%cWTg~DH zlS1x@3)_~~TlQl~XDWo0(pOmsVr@v9qIQqrt#BN^1Gpg@qC3_`*&3%#8s^%l!(ZT{oNkL zV&|SQ-f)S7eTW<4$(BGmv2W?)Z1!j8x=1Bin${g&Zl<4#EFWfSe&AKJ(F_rqN_s`d zf5skJRrG!*aB10OfsfyKJjI;}dR;d!Ki%jN;S$$?SZ~EJL0eMR;j%6ZLDf!U;HY6o z{x)4FTdQ$0YOmk&^Q(9jW}$;yM9`y(I}1uh!kIVLEspog*tSPK+CpjkiQJaTb%cyz zDyi{OjN1$PUxiEsV?PB73<+nxi_l|mPZM&VI6-RU)&Pwb9OVOGaOvW}q1NT9;?+TKhJsnGg% zA5Cq6L%GLRBR%^n2AZ&k%+H|ML)xk59C`U>Ng0zy=;#fanZG1pQR2=H~IB}|P92nqhM^*}Dbj~t<>4!{R zLtZ`T-#@r{sjk)GS9bgCCf*@$cA|E~vh9N}_MtSkX@KFOE&ys~QBoC54i{nC$NPZVl z#M^akgJvqCzo`<P2wHf zpr`7CP53q~@Iv#MuuFG*$C3y}t&B9rHt)pX1coA8_tzkTt?kx+_HTAe)!Cf=)K%o9 zFO?zd?hhPjBPx%DU#zj6R&`UBIJ5r>v#!=LzSL9(b>?aNE$^>fu;jYnCFB$mRSo#3X{ z^LqDBgLx+1a-yWS(IzmTLC(opGnb)kZ;z5mUfYwf5n3&;>~mAokKTE3Nk_lO9E||# z0DAX$MwZqUJDD#j5)CyTJS(W7Z}#1@EgIyx+K*T2!~Ve=Z((m_{J5ndRGQjc4uY_f z!3oRk4G`XWsMO#oA2alDLb+!7O1lg>+10PLi|S%on0XBE4vR`xbXjMRcBW_3VZiFX z(nCtAgXT|MJ9WjawxI_!LV1ltl?3jGY8elh2sE=ZmeG%=?8|j3`E{v)Ik7F`FI#hm zc#?*Ad@yCV?rX}rj+)8$S_{~gMe>S^%W@-dwej>N6=UcnEWdB zB+p3Q3TWz@fVGshim)kR8IqWE?p4NWRKz@cYH?ljyEd@Ed?aA@_Q3fW()q4<+zG-n z?Y?mZhNG6jLxB6dl%H=sIvjdzXk=Q3d|I+omZ?D=u!r2}F%z53qydU1FpI2&GHE$T z9wCE8j|~a~WU=Ml`ThHIsT6Qqqzah6H*w1QnARb8n5}cui;Drf=#c&-Unq zHoSKHBx%IMXVGH#Qk3_iIE%|evyFMN7vV0)i@n+SfgV0iqjRiMisBe4HJmg^VTNUH)Ua)VyL9}r&fg?1PaJa*;%ZDZ*jNV}f z?sxvt`+YfRlob8TV2fgn5}V39+@GrQYfU8r=Mq)vqCJ&z{nj6+s!R85-QLIZFd=i~ z8JcfD#2c-adCgPX+1`!3C$)U9HH1)0wA-WkdAR3n6=F;>ku zW>J^yNZ4CH`V-(f=lk+5-u<9YhTuj__>^uD`;fyEu4bU^LW^z=&M|IONOP|+a;dEQ zR#d{w#GD?v_ZMTl9v$_BFX&@ui60df4=!1KY`X2hgC1=RikGBrT+?IbKvkS{dY32x z>q^p)5jd-z#3LRS1@t~Q?kdvpSTGYL_!fRhXV@Ao)i5w;336UbKH7}^cz=36!a{9d zk++prVAt1Hmo;KXl2c8*UW5G8o2wncv+v*AJTj{2Tu<3t(ohIuv23<4HXYL6AT>A9 zK#Q6Hbw&qEL`7G=O%AQ>*cB1_fp}oHDA`o~lbH*~z%`1|{w~p%rTloD^ws`xYMnd4 zLMDPv%fq_T-E34$tgOLJ^4qpYN}H^_ECOvon7pMItZ+`ZGeihz!S-PSPHp?`dh5_K zX$+ z<`YHDqyX07iaW;#@4^Y8l7YO6!`WS8EV(zoJ8&|nE_*BOWN6rKx9p2qJPfe&|0;WC3{}bzozzv)&&l(7Ec)5~iuk&bYUov0fg7G%UCVg0(up^rQo0RWtl+YtHNg zSMd9XZ{h?u(jG7e)t9{4BY8x-lHdMp7UtDn{*sq3*~46)N*BJlwPT;WYp17Rb3sS; zY4SM}d;?Hc{cdTYPp?Q+*gCZ>=XBy!=*QMR+TKAuQJZUH+05Wun6(iNfyI{{g=pLJ zRS$c~k_LUYX^z<0f<#Q7sx^#S*Vfc+0uhN+opl@DUZ)jmCRdN;IA2`7w z=1L9D5`S3fXEl1)mT1Q|*r@T=K|8U_MyP%jIxnz<-Z_wpSd~SS-Q^@edzizq$Eoqs zSCNgVtd$lO3OR_W6&+ZGo8XuXiz=RtAL)1JwF_#Ef~Y!PV2W1LxG#|8^9h$O)%ntF z^Yt@N(Y7lkltA_7-J$|8x0>h7kOpR*& z&^i449qRNVE8Ysxg&z+Lr$|B!G;Lcm&ScQ7ZOXILuieGEP{`}kJHX(+uEMa9|EfPS z`WQQj!_*W$EKO5USxy!b_E8S?;MRvB=}(pjo@Su0l4rfEVKHF-%;b8)iKef?hW9Q1 zM-Zm8H`r7uxG;7r1ni#45gK9Q#WmsX5-)6?=dLf0;`n0G3RN%a6@rmVPMA3+`c~y@ zmmwWu`BJv?P2DdcuY-)7!kMQ7`-8EzwC41& zBM-guz*qHN)HBxZG(1H;;ubpTA8~}=DQ=kGztCeS;tKBD0h-4o9X! zIAux4znGqQ{7D(p$xBqtB^DCbbN&9~8Fp^R^A^h*G8S@9DN~!bfYSAzZ)IydsA`5Vi_o@TL~cC} zm3};_`{3}L&?mvEl%ssp?M=9&##B)w?x>+o8Vp%(T3K4CFTAf3d25fl-c9+@Y%BBy zFIPAe-gsjpyFcH5>;CpGGo6%T$O(3}1=iRknohGMu~(G}?)w}(zfG(^8Dlr4TYry{ z`vIML*e24zwNN;wsGJ+wFU6Ebq&{c|xVs4>*WPf{HuklmF|2XNekvaDh}$g($_)*Z zfSz6A{b6s@Rbbwx&-LU;>*gZ{aIx`BTaaWVnvcfh5XjTRfpv#^u7V~+sAw2e^ax}xLLVAVfH$bbR@7P=-a$82<>pni6rq#}eWlAUy zGS9M|=cy=Tn&>`0y@7A;+rQb-V8t*{T=Yv?CrEfN<+5GR-*~5cwCon6Pa+A0K&uO=x$_&yQ z=)OYE=6z^zaAt-_8q&CwOnn*$5D@4^0$t~qd9ki!fkKK?isigwP6eoh6Z_U34T~$=eG;=e65;CZwx@r zb3S7w(B3O>CQmi6$b!)_X0Ib|tLY%6dWqDw#;B&eGfzH``1hTJKdTHJx-7Cqyzl3b zb0qE}+_K8HGM2zYaPh!y^)cGE;OhbX`*BA0cpOX$X4zErxQd+%$IQZz?*^r=b=WcX z?&*%wK|ye|G*do5LgzF3ETubhkIZOCk&JbAq- z8-Le|$N=OdHUvk(yh85b4zJB6lMTJ(1ogM2Hy+OOu2x5%%>38i0 z^nRsSe$a4!J9Xn4YB23ZRIwrk{@N5cU!eD^f{rff-5~Eisub&h3+u4OV{EdToRqH= z3ZM%-sM|WmH1e7@+y=&+QjJg+u0&ogYokq|SYMX_rEKY3UzkkmyLbNWQt9+SbzuK; z<(*OT_xDFS;lUTnvXAf_EM-Q}h`Uqy4V+llu(VoKBVPH*juvbb!AXv>@r?s(GP$0B z#GRtLVtp7TNe=KlHZY@`ggx%2ED2!#i*XK1F6be{NFW-FH=?Q=K2wZkl~mm^;hwfw z#xEes(Zj%-hNH}kfdW?u)apHqYVI*6B}|(1d=d<0fuH=~W0oc~bNlm%3hInSc8d6O z8Uyp|4muwJM;Qnok3tB=0jet_fnaP zNzimtCVTV*+z@Hfqq2N-OV&UDJuxL*aJJ5o{YvaJcefR%%o`IDI566qJ-~X8hVx`K zn^M5tVoxdxvE6>@M(9ggzx#Zik07h*=m53p! zW3u@tPI)d;r$BCHmff`wC&F`9So+aAUHhY4(*;_U#g>p>VFO;=k54`pj!s_k4rf-K zV+4uU-JY41=fVQMtEs8rEBY?Fggpp_Mr=iv?54oi&B$b^4y*-;7Nm-FZnk)*Stt@!O@jg77Z@V;CyRa0WT z%14Lgaf2!iiH~&iJVR^%_)@{>{_w)|IzK5hsLDg8b3%DkVsNuolK7)kiE#^lM3F=9 z08>E1Za=R{{5wIEd}?tDmw5>;Fj7pZVU%nhu!1q(%tv&EV1+2 zmewxd$+JaX*$;AJT&5Mx|I(b$ph%v z;XPaanqmc#{E2m!1e_lJ;CN@x^n?3Fuvew)p0gd?4XCv}&daH$VO4r-%a7vLRonZ$ zczh155S8d6EdwS*>w<&^F3XqAH5IYho=@$>wP;UC9IKN{dj1$>|Ml(y?IWIAk;@fr zjtFYRgoCaKUSEy)p<`;Y0xJK}8GUTic>)xtQpBCeAQ0g1B1l1h`e(|M0{Ixz^<5@IyKGl8)$88S?@*vTiS@80y_ z*RmJS6w+~z&sDqkwbXa9Y!S~X<;+M45w0CPGtVyMqwT%#vQQq^nblG7re`bg$=Wjw zgBS{z!@hhvwBcgohMoJn-d+|XczfOx-4-d52f{J&St_CCy&^8ddypg8=<_Y%C_WRH zcdT&|8C{7Hwf-}DR5|wvLZ!iXVJ@C;_!8HMpH}Ho5b>2!?%ywZ5A2#yx@JOp;95#! z>{EeSQ2J=Gcc#7p++8ElJ~m49rIzv85nlHZYU#mpj-d9cqq9vcHMmK1us*v3{M4;w zhd98RMosdDfLo@*ygek0ZG7XUWgnq(o&D@_FDDv@ zJH64uKgQlY94RTq3Jj=0Wh=Glb|s~0zVdM;O~shUiEeuj8jUYVmr2J6>YOF45T8ym033SOvQRjiBQEADD`>1{X_jwJ*PJ{l#^!I z!%`PsFDNK`%cgNaNhziozkt*YMJ`EJ_T8HedBOyOKcMnu+aM`Pypa#gdiEUCUa8#v z+Ur&Vbk1&%O;QnYv6|{btGg1eitAZNt$mFPQ6NQ3oQ#7~H$F1XXlU2M95jU>AQIS(LCBF=(m1Bfa++Jt=;|6QEEFY& zvS&PDMjOuiwJ`!aHb66cZd_;aR~*M$zLY+T_N!&_aBZNQ?v33@{21iw-;4~Tq9-F! z#xI||e{P$-e=4TFT(I6Nc!kl&1eq*#D0lp(Z&z_Y=L#4UTHWRdKSH<;5#?wZnBP*b z1eVaPTp~F;enY^EYefX~b>u>daSSlQ1`o+c70$;|Q?+apu+vFU3~s50GLy?NTaPC(l=#Neph@*{UnmBCM za3+-RdQUDz##KHw2ln!OA#Y#0F*!e4#R+|e!xmHr7fRL$_r7^Q#{hhtb&{nAQiMla zNT>ZKn#jFx07N>n7kjyi2TBSl#Z_}`BUpz7*5A=O*0rMn_Sk?nseD1*7A?$;w3G*U z$AkTp)A@lz_t?re1C^PsOF@!x7(twcDHO0MTBT?JtWU&w&{fd+l{#0zBh0RuAY=-$ z+$UKIu;hYbLQxk`ZxiEZ*fDk*S2X91uCBz^C=@`VARH)%<_dAv7;V|Qiusc#q=6kd zi2m@^qqe~w$sUIf0p@SAB#WRCB5Vl!>rpEg;u-y7a8Qc%3Jl=m#00jD!CqjES#i2A z>GTnvrBi^_G4?ukcJZObv8^AC-|1ZhR)#u*)z1!~z8zN-%J7-7hFHvgkkNjfG=s>G z7waXdb8PkuiA=XwqTwEK@NJ@zgj=m>ga#aAbnnKosh@z~)l(RA<|thh4?;Xs7U=U9 zJzQtxA|Ul4pRthcT(X~G?0s{S`kPULrruq#wW*U%BWVZ2c0CldWvNoO?6v|3kM)sL zx@P3r44R^l7~uNPzP;kUQG-k)eZbpRXTCGiTNlZmgmVk-K4eUe2^E)}AeE+dU7*>@ zhnsB80*+#G<=R`R5|aH-qxQ46>JJMzpF81$m?l}C!ZSeB;IX+@B{YIzl~Et>_-u{W zYUSqHB?`|QAY0(V&mt+2#ICTEU?7p3D6a0~ks%$CuNck7+(mXE3i62qn1mEgwn_Dx-{nfwi(V;G{j)ZBl?#kHmkgL> z)UhsN=4$tssk(}R70Kq(OVBb^VA!bD7Gz`OdK>5mv=!_NP}a=EFW(V%m)CnuN(#pT zyp9nCM#&qu#w($*It4qH8Ly-2X(ew@c$U7Vn$R8&g(C5QgQ!t=#j;7PBr|{|TD+ZH zs}^s%#HONCD%K81WFwryfX$i+APz`?7r=Kx*nQKnuuPURbM`1b%;@fL>(XTYI4z$iw|S#hbH$oM5XLhU5`+RP>?Ku?ab*;Ph>TOu&hJ>6&k@kqFYbsBP|xyupl~4 zQZ7DsAqd#L$i+OvCx{zBDrNw5Z=&84eyp0gtcwc3U0X+fh!lMrC(nfs97I0Drv)9M zrb#~ZCMn{?zmg+m(0ld+#2O?NY~KCe<`q8y3pj^_*3eSuEdKek$HW^~nD+d|zX94T z!4<*gC-6DzLzeP-@x8u(X4E513gB?E%VHW7U*9p`$96r2N?_}#LL@u%AE9ti1}Im{fKOYDiVy~ExgFN*L8*GGvf&K1NLWdaW-1&Zs(0sPs*hh zCpQ?6YLK#mx_ptWc@P)y9De!+u)+Ft2lfvSED$*X=$pR3@&8SOvB7}= zqDI@`@&LLF=nC2vSMmqp0nhO+1L6Th4G7q;{(q1EZFc~37Xksqjj@5~1FVAqkphAbmjGfd0=m{zD7{U`-B43s3~0 zcYyW)&X`{d4ZQag_fs4A%iMv#K`{XH@4^S#U+c^s+WyQtKoMwr0xdw~{~@>Izy2~X zcdwLb_&X3{0Omgv(FEFo2(Ser&VToP z`fvI^fHy866F|*?(0|7Ll>e{%{r7V}^?$&}|7xuNxv&5D{3oCPOY8wVAi|&>Pjwaz zs2PwkAe{duHh<)A0az0Nas@OC=!e+;qp$zi{wDX|^7&uK`QO9+H17Y%`^WZoa{m+i zQ~uvY479{EXeVMjaZ}-Q>`hUjXf6e_T_TOya#EBGh;!L^( z$OX{<*LeZptq$nZU*!IKa{NCvo&)0hKNahLjPXCVKlk@vb0<0F{xgvQ&&fUky761_ z@W1&zfHw`G!oSY_Um5FvJ(l}Ja{Tu={~O$Y@cHlTzi~fh|ASn}F()qMg@CC4o010*PxoW{PsRFQ_v!zxas0n3$A6FWfWQB3?x*YlQJiWOkin1l>A$T7 zc#{Ci`hojz;HPq_U|0e{oy(OyT6~t{Ga*!5B~n0`%mmKC$4}ExKf_#6(HdM z=Kl9Q0Oq2Arhj1nTR#6=HCv!w^Jn$?e`GxOKc3^i^Zyp-|D5}&@BhI4drJkhRMRJJ zR3iTk7634}2DJZYasHdX|9_R^zq9`q>rdl7!1*`XV*vJmsP_S#{uA#1l@EY9Fc*iN z{Cm0o{_)(uImf%xV9;@D7<9e|2GbCW!F1+eFhg}1%xE(P(_f82x4p!mYa=n}EPKq! zBbgt3_{Vtvi&+1=xu3HCnP`$v+-d$-%{c${#QJ|}jz6v6{mwl9L(TSw znw=jTz}pjp8EM2|jt($?*W>F32HjPNK|iy?oOqu94WIv(<9{COzx(?)pZ_^`48Z-n z&Q+YapZi}iu>>%u0CYMx_shQh|Av}vgcJtTQ;fkJAN^g(|Kh=Wn;3Lc66OTP_nr4& zV*d+&|2cQy`MK|+?L6_IrT9-y1^{zfK!d+v{~P1E|G1hhj2DCHF8YfY|LH#*?qSgN zF_;r?CcqB9_3ys>{I9sX{pjzf?T_4n)`Rv(4W4+=(f%je0Koh_pg+ye{s#BopW}be zJk5`DGe5S!GtU2_Ru9x_PV@S~?mvzAcb#Bu27^x0`dN(sk^kT14)CY@rehDfiDS?6 z=l_#z0N_pyXavyrwHSXR$N#f6+h451_y=>mCoKlkSNXfJ{Ywu*pJ3265kL6%U-EbN zpZxtN?x*|#?muee*pvQ0qFx9vCkFKK8~gtaIsSBB_TB{yW?}eWiuLb38M?O&$OjC+ zjPt+Xerf~XectmI>;W5~Kh?)$FZ#3plW_oGe!AYW7FcijPprlGH;?B6xiP^1i~oCZ z{UOJrhw1?vVEn-b{*>eY#Qm2(|08z{z#S07scHfJkBtoh?oUs1`mgopb-UkMd-dh{(*^+U;(!i*m`)^+|>HJyJ7^k4b#+AQYSpX0Z3JYWOg{rxAO|Hk|~duGhB z&o|8+`>>Gx(KY~Z&pT!R$L08ca6I?R^_D+di$RLPOm+U18~>m4Cv;=NcYptRtpAqd zzsLF0c>go@KXCufp9N@H^8QHvK%6)I?O6XGJTIGW_MZdzZ(YgJKIS+?hI{5 zr~j|LD*?BnxY7?Xt`Q6pNX$66ixL&%f=dv0VH~qKlF^J=X5vJJxDX8}B0LsBKnN~~ zBF0@o$s|!+5DX8EqT-UcVgmXAqXME5Q6KkqSIvKF>#E-SF7G{N?C(3TZ{K(C?K=He zopb8cIj4ZXw(COUeOM~)ggt1_^`M&jhJgDVfqib=+d=HruTO4Q*yd`?=l|f|h<&WF zuH?Ou_4atjYdPi#_kf1)Ij5E~0Jsm3Ig_=T$JbiNi`aTK=7Shp_SCJp9(jBFkblql z0saPe8v8c(Le?w%74}%S_J;4Jsedi{0C3+5^hPviGLQeJ4dZMPd%-un*WRGb)gJN< zV?GDGH5I}g_+uV%`QC4oFW-BsYWo0i9}>mBjpuVRm&WM$*f?9n;%v6ZXB&Va#&Xtp zCz&6NcZoZ&2kxMKh=x>yKXC5^TIb>)#y)J{>GfEBu4G--^4U5$RN>hAK-SCLiXhIG z{r-y07Jh2Df8BQ^{+A`{cnf=scZ0jZ9{BfMS02%`;LoZe=9_;ZI^wwcsb_9c(-wG zZJWMuE)CXrn`@6x%SOa*Op^W?#A2}L?ydbj)GxB<@0Yk|>v*N>&3MS4TIT}=#8 z`%30fh2t=SIymXRJ29WD40oM7M{#vU4n}jj$;Vo_Q>?X(y@Mh56u9&9r~`;zPsM-mcKavPIBb_XJ}sAqV(M}oV$4sL<2ZKAXW%a4 zF{Gc~pL$}=^niEEk73hkc^_-j2je}^@xgd^aaZ^si1UH_C-nhf-zf3VDd(MBnk1iX zAm^zDmg}ppPRFY}=}cQ@Oam_tMfsAY4kynJYwK}y1?G4WlME!Vb5vGwCe*|j~a&|Ss$#;iF!Deuimxk zPA6j8C1n?O4)^L~uZ-W0JwG>hACP08d^a)vn|!vN z*6|kZB<~gWV{jgGFi{D#weADJy|=-BGt=>ryh+GqwqPpfm_zBqzw>NM&gaUdac%mz z@t${GcEVB618a3tlFy~jczNncDK@=5pUb7=<8W8_AA<8Cy)FEIq-xe%e!DDLpW?H1 zY&*+mn_BOzLLE=JvMOKJM{Nzhc6sy}Z(Pg0aj^Mot>aDXo%Yk)zIym=mH&ofd9n`w zp(~@>(yk1hwiX1@-E)aLOi`Ld|zz@EN? zr>*(2S0BcD8tgP7@AX`c&IRoH7#&YJd+r*I6MH4+aj@Um-~N=?1sLj#3BQf7^DxdU zmi3N~SD0)3#h6#vAByv#SDEpDey6z-|9a^70`s}pdAw8qD9Dr6V;*(Z_{Z-iK3n@A z?2pq5&EwN-yCB{&-@2@K?Ww3U6kQ`^YnJo!m3?Uo|ncQwlu)M z^V;}0+Y}vN;ks<4^Es{K$!_=WhdxD}#YzwV;j!8For62&)QFslY+0}4ui|`n@W-=v zUKY(}h)?vUoCu5yjQP0no{Br^d1uTM?uz=XA^d^+79d~kPm*I@7JfX(zDt_NSLU-# zn$HQ}&BVT#&n>AGcISI+(KX1k1E$8dS7W{&xLfl%TGwMMo`H|=+Y0+UvOaMhpMT5; zxC8$_M1E=9;lO^!t{VGR@!3|O^p@y$$K&0 z)mh-K@!uP`_m0_@rcHddM#q~qSrvmbz7O~BI*(IsJX`q!FI={bE*tULhR1u7uRd*E7ISF-PRNL+8##OHImp@1;-7oocS%ma`8e#33EZ0joju`j zE^Kv!J$&>!ww~e%CLYPX+y6_*c((HSTz8@QtC-i-OUIA1Wxa(vjs5XQ5)t+if5)b8 zJ)dnb=4-qz3%{Iy^AB_3ko!Y4me($e(#8*R|3vtM9{Q|Ylec|$+GiJ*^QrSWOV8W5 z(`yTRiMxgWPJQyt=j`~K%6;{+j&W=~+nTS>`LoUnKkjyS&5);1n(*xyUws(+#Cd!r zxC8&AhzR@M68{QieI@fbBk%1opFhqvE%wUx+xhdaZg+UcHOPPF?)>w3>ANeUiZb9U@iU39#N!-DrELy!3$a&0y)7Ne5bE441mtI*4> z-ANegQVXAqSevbjtOw>8`_MJOUDHm$ehb9i`7-uy^V9K(zB~BVH@Cw>&4<8Wul@94 z{|)AKiSs#O(_8Xh$@(bnz`w5#+Je>qfc@Iy@zv?;vhjAk9`7m!CvLn~yB@FdWxY8U zZ*K4lzgBtr>6OgmEzGG8I66Kw=KB)%eA88Z#rluLzuVGie6`Z^arRwhdle{oZ_9c+ z4g;@^thaT%9dDU`UDjW6SKH!``UB;=26J!WwcKB}i1Sa@Ee8WK4abbUL?seG^_O@N0hI>TE+v8p1PS_Kf_;2hrxecf! z_nb_~rE&Co1+u;lIzD!N4sjJ6^0Q43+&`Gd>A8H;e6EH%K5@(oyfyAPA5#KtL$<#@ z{ENl@vWToghjxp*CKk9Wdd)6;s)htJ57ZcNOR zZbv%a#9di+ul$#O-{#m;13bi^$#`3P%(sb-*LYj!)9?CE-5wh6=mXA}PxIYn z=y>U~g-$0s&zZ|9tc`w`c+0VFVShaEKR!|RYg+)=?+)_gWqtMQvPnK$iGMJUm$to% zvDP^><}7n2z3JcM+}l)B46FIE@{MN%_~*vGkk7Ul_F~Kn+zERhw5!HB?F{T66Zp55 z&z9_a6IXBL&sjR&9`hm&ANh<7b-LTjLF>&z*E_gdu^36~vUQX726w`qC|CV=>KCYq zF)%(BgKRoYt&=Ys!JYCZkqcjsn)}uCC9&S;V6S9-+v5)GPaula{7aGnz^?28~^G#Qu&+F#9DUM?HibW4`D--i&t(cldO@-(X+858tsLce{Gc-hBhI8klCr;M5v-3;Xyn z5ByIedIR(&dn{M_8n_P#u-EG|ImUa=`J5T=R1byfR&0|ao+>}bK+%v9-pmk)7!FM>3CHK$GhhOPI(jU{qPWHk|Vxa z%7>!<`r(5U!~P^k!FRVQ@ZZ6v!+LBP zW7|Xg6V*2KpFpj~zdl)2o#r}2n)~O)T#syOA@6IAd+zz1lJQ#R8{7%|O`s!dg>TmH z;K6OrKmBMC|NIk)Zy9m7o9VdD>I9UNTbh2F#9r9)8vg>aKGvqsgL}M=2iAJb>+^Y8 znAQ6Kcy3<@72n`2>w&kY|D#4{Y1U7Gy~do*1#qVrtXS+T)A5$9*SO={e`c+*&HH^vKQFdUleze_k^`g zIc2@{*_v@5qvJL1bY2GPR!>Ze{`UWcKESY#RO#j)sc~NvdmHmS<6YTyp?Q3Qj<>O2 z0qp;&C_b(6`OUcxi1^*>zFW+`i!$st>gPx#6Zyd3oM=cg$zv-fBAD z#(rMQ)B#_v7hd)FUGxE(8@Ag%z}|a9&h4uj^Eqw1;yPYoKLF3lb6 z$67q|_VydVpY%bi73gA!A1$MnuBdy^zGXe({sHKR?G3YfvZkE3R{86}z%T2NIqR@d_fBy2PA>%QJN8MxxcN+JZ*eBTaiEDEO ze6~^ljjiL?0`rSNHHpvPEP)R-8o2)(D5D=R&OTVl{TF`^`97L&`t<-{UT{sm^?kNV z=8G}E4ww%EZ69L)i%azcOh52FM)sSJz0$oUck}Y^uHdEXzpwDtYx32u(X^V5Uk%KM ze1UuZZjM;nZ4qyG7U&5Ot1b?sO>{g1-itwJfxeLQ`Js<|64>tx8V_30u5|nq5r+}7 z>HA}ScEEU0&j=%5yiwH?0QL=_!$IR=+bsoAE!!IA%T_d>^VQlMFz|<@K&QdKGa2+8Vl6*+V{f#5pL3li-@5GQ!1-CwWYB4#o$|N%i%-_`2>|;oLHmKu z0F8tHXEtalVl6)aF{>sZ!lK=mZpyCg*-JkG;D3X!3g0|!5jFu^MOXX z?qL4!(PcwJKmEqX^18FWZj#sLmh!TpLH%Fcjouq2-)PbQ?;)?%&owltA8gY9S3lUO zuT_imrMiJ?9lhI+e$f1ULqiX`Hb1X!&>VbUJd>v2THLTPxE41IF2xNEH}w7}i zDC^o`4-AK|o89(x4qb1Zb=}n9936{ZH#%Q$=uq!#_ja4#RlT22`1hOKM^qT!X7~GB z7rc)2*Kq&M>i^;YhsRU+Iy@f3*WvLTxo)%>hCFDpuVds#v;BX_8;3zij{b5 zac*v?^pUwi5ApRt!uONch9h;UAG!KD^9a??nHK7=t4E+(Lq8%~AefauDOeaKUyHx^ zfc0;@W%NBcDUJa(f;u$pioZCHX=vC99%`c2Joq_VcHrl3xf?(COQ(P?VCQ~mJUe%* z8SK2RZeizbO@!CmjAw(kxquDY_7u==pbo9s##-KspVP4cJRb-e26_a%e+a%g5%`vL z9?s`&t!Nt#-a*?c+K#iq+kMCeZ~q8r82iPS4+Pb+iFNrc@cnhraPYhg#043?74NBh zga5&TcbvDE^ouWZ@DAEx89TqzaM0K4()cQV6g=++x(U=0=G$QI@J+afFi+;2v-5WV zbyC#1gok2TtpXkD`l>7_3 zTnB0sKMi<31GLugP5r$hzNx=Q`g$zig7*u*LcD{zfOg{kMLVtaFY5a5H32lokAUY+ zpu6MwP8;Kve9Pb01>O>Kn{V)b5%Jzt(vYume@M5xvEO}FH8Hc;2jBaE-Y~o?yv-OV z*=}Td%orb(DBFU*e(A29O&h@3tv}`Lj-PWj<8b1yq{ZXUyteMG{&(vE&J^-*gMa|OiQR4_3?Y0Jvoc}R~-ecfxE<9 z^G&>Swb%6r*z@+NN_b5A4tPEhv{CY|^>|ue*LplvpUE+P*Lj?Ovd*&UGG3w{2Yco& z?q9x_CQ{C{2T^ZSjB-X-5SF^Qid?}O)~L7!^bX8O9L&$KQpFvfu&Upgm)*_3~; zN4&`7V>IT9Z`$M7>}&if_Pjf~2(RJK!fxvceq(GmZMRi8#v!}-Yx7f>%lR+VDfX{E zPGfHE=}h~%ialLF^oI7RXuT4AcLFUlcnjHP%Qua=?&~>Zo3LRp{b{-(CxbaYhPr(| z>eiY4EhXRJzlYlAY}aMj_oQ&0bnrbJ^OPL6de#`%HVoM=plh+0ZIX=3!EW3~*t7S7 ze`^n4vA>(z+fD5Cv-`c_zMXcBIm(%0p5l!0n7&>}k4xK4$oM!Ws(BAG(Vv1ERRQMQ z+2=;?b#O)+&-#Dhy9;Oy=BAb|ue`52HY>(zy$<&D?P?!Ky^kOE^s@K(7{1pU)cek? zBL@5By1<4>;=3}Nl`WWBFZMa#@IElN_c2rZTbR8qXy56*uhTfkox%6+pi(e5E1=JU z`B|dP%HMjne*EK?J@hZLuZPRGs`1^kR36cD_c-3^J@9>Vz`K&`6^wEJf;d|pI`1EA z^YM@PU-qY4IGaBu-{;k*{9FGE{9`|x;d=>^b?sGc^I(7R*t$yazjOnA9`eD&&&|^3 zr3tor*Iav;v%kN_{p-Ig^%?pzdnY4w)_OwzeHSafmb0$mZTRMDZ-&<#{s(W@OY)vDKXYW8x6Y>echUm2lLX#1H>2*a@rc>Vqao|x5YQ zxZ(R^nv1LX_!awdw&YGR?_qy`1v(10nQg1n7?<-Dg}1idq#nmUB}%66!@b!AY`=<9)OQ-0P0W8Ct=aQI-jfBV_6 zP2Y3c%$}U7Y;~)zn?2Uae$h6JuvsPVdOseFZ}#S5^Ly+s^R!IoW{;&{j8i|Cd`rwV z-{AdFBJke%{F;t&jrrJvIeYmb)6Vb<1PP_}g!FwN~ap>#QgY|^4e>qN{S+XtgH;TSa zJ{bSzAIkoTdV6^e_U>!=&Y9@*!5BAoo2|!nJ^G19bN2jwoWu83o_wsW&w{>=y~P5& zWBJCOzK0Wm_b#*2Y*yu0mva4L;vGKL7`_AllalMO+x#gfaR2_HoIQ6hr`+YVTFUI5 zKXZTHSnk0;RED0Ex(xOk>F$YrA@?rCc$&vK)nrx&LtZS&_2?K6^>x(nR(NZ^)t<&j z5bv|1Ybn}xOV?+T=fGAMdR)kL$Tje9WV+U8@Ym)#h{uf|NXi&T9&CQ4&n(QHF)n$R zcx%4Zo~}oN_pZ~UdOWaMlg4;}cZ}_3_Se?-i_~XA7vy>X`9H+q_b8!$xzcAbV_fue z$@i7^zV%{1)9J9&$Hm#|0pDg#!HjX~YmDJLLy!BY&r^@XUwU5*-;i$tbMPGHTkr1% z-n*S&`54!8l$gFQ>^4`Av*p#5Ok(f934g$=oMXQd=YapSeCy8=#yIU&uJ$X(KBjVC zGqX26c<+8{n$22xj1%9M&1&Z3kmVfny=o5ccO&E&2S3EGw_qCgUth@ChBch6eGB8D zZw%&ozwYo}eqx^w@cy+ugT8LrtiRIhNYu}Z_jTK5C4J`2{9!e$i|>|E#}YPcY+o;5 zd#c>CGSb&$`Q|F`au4XTEkGNLt!~!OlK8gzdS06q*!yJvS95H{o}AKVML$o{X9<1X z+0)777;iwn*%mYh#G2uJYu(VDpXHdBX4i9pk#M2fWMNLgW8{ zKKo`Z#(0_RRoiAI-xK<3q4oWQCsjs$vt)giI>y6%b5S>G(s9QB1-q>Q^jhF^t89!L zn^oKDn3MZY-;uyk{li)CM^Lxuhp_(|p@!_!@5x{Ef=@ly_cg?}>*x zGc3W^U-WtS@b8qy19M}$h4&#g`YfrhbL32dkSijtj`4AuKLiYIp&jyMSw4xYD;s!To0DbZ~A}xld{)R zcuyVUn(veJegn&p_gpysjh+Jr{tGy)W-#ZU(Nf6$nUQx z{!#Y>usjHq5R_cI2SWQ)$hv20erEG6YS+fqywKxZV{Z7S+BKhos)~PYt!F@UTZy|} z+Yh#Cq-JkezG=QqU)MEzHiGw>#6O3gL2dU$gWt}3@;BfUwQiichGeG`S(ppkEsVFt zcTlqk^=A9mH2&Rs1|$#iE$n0r4YqzYFJWK!Vtj-D=or_S<2>LEP+jsLtY^>@tmO~N z3O@(LKzUEyF8Qc_jN80Zed&tiyyh+M87yrDqTsyz;{khec;u(Q9(!&^_%7Jjof@12 zsODy?kZ}r8xCb*AjBwd+gVI)3j3x_VpOq7L0M~>m|^2pf<^W3q1!+_W83M zdoZvyf8##lbjlBoll!Y`e`5smB-utXE~3Zneop%*+yrX#{73s4&}+!1ufuK~4*O-9 z@v|oKooTa%_X}DEo`-|lUH)t2IZPDw+i~;tZE80%F;i&=76Z@&`%XH=p580Xd)Oo2DJ<55>p59HPn?+Wgv9@n0~km9X(X_ z23=R9bF+B6VQYPEY7mF6^U<+UU8{44@LB%5_5OzMAG$W}Zjw#v*euUm>vNcY{anJ& zOFu_dTq1bRP4t6!?&1eg1Va2Ea1lQQoHTA!S3>}d4~kk5_&^V!u5hQxQE$*sL8eZ` zp7p5{fjq(vps#{XMt;@Bpy|l9xgWVU4hn;i#EF|i^p)J}jeBX&I|FJE}xdx4gV{$kf)Fnv6(uY~$I;<(wIi#T8PQgqD@ zYfx<2BF>OsA!22Q==d;`bG{t$6MN-tul+f+88rpATum}X$`#5x4CfxkEy=02G=#Ll$;Jn^zQ&htWPxvAmysoYidi|7(|X ze{^pVUrsUBLF~dmuRvURuD*meZv|?SZMUDf-N#eqA!k>>74VNWZrgHRvA37X_((hN zMaG&mVI4MeOk-@07IMYzD-n4Z>fMb&O09!#~>YuWtgxYO#Gp&3MQ!gjbK@2%}Ne5f`BKHx$ zAo9+zcX-;t{&+o}H=eo9QPHsxGFM>%@=^>7X!pJ#kJ)u#Y&kCaIP_<-&R2PL&{c?g zj2w`oVocI_RP_Kv-dIWu3awwp$Fqp_eGmD9`)USYk2jh;!MJv-yvT50k@3}bE+5;M?{WOmNy$G^w6>VoxU)fPm zkPAV%A9ntStMeJvZK30n54b;Ph?IjmPBbhJulhFfLH;2>Z~rC#|J0MXjGNN!w(|94 z9?y%2@9zNnsynFc*jeIv%eDvY4*GZ`u3PJT%F#i8WmsqRkZYj(ipMOFQ5p1qd-UZ_7*pfStTY-FM z(m!!I2Vr@LKEjqi9k4*p{0Cw#qL7rGt9>(_-D_2J4 zMTr~$EmIH^>P_nB=1Ms2-V0+><;9@=-n4%)In+LCeyChtv>R<#IbWf6>v&@+S3#45xT8kjh=N+ij0cT2E(xc__$T(z$9nPtD2QG5Jbp z`;PY|_i^N_=)R)+xX3?*ZAdwIzxk=i7Ye`+y@Czr-}!SX$4$JKk}0-aA)E8zt9W_J ziK?$qAGh*voE$SJR+rj7&zS=`HLP^bXehTx=g5*>1sUSs^9$5PxRtY2f9Bi^Exka- zvlUB3?iu9^nOIE3t9ZzvM=S$kYdTiPVnfbBl@8Qo<9;nRmLavh&6Hj?_ zecZp}oN$v0T{F}(D`9OQl9Q*OxfSP%cy6@4+w}N8zH=xqC!aj@n`RViFXFM-NAEb_ z5qUS^zJmB5oo`~|(68!?ws-$kM2?$hzKbQtd!)!il7&(pvVyf#yhSr)juhfcyg3(h zA8WAe?dN!T){jE5#T09)VoZaW;!7}J9$?GEV9u%99@hCn9+FKPW7kf=eBH|9a~^8K zMH%~F27N{3ZpO4*=l4*&pvZ6GD$ip8{1e@g<52c=UW@MIMt4#UHs!17oHg0*h+T^~ zNdLjH39U?c8~&3L;ulQbMtmPftfLj@7{maTv6e<{?|^6iV$@c#W7X}LWu-U6`NPmN zMPqZ>yKlHM#pKw;^%W~_ORoLBfHg2N4}-1JXzW@$KhpFSJ$DOqzO6gSRw4aU^q}}P zH-6q~w|M4uU$NtlL=29wpUH;CJbz!r$a^NQ)3iILkK1}v*jV3$9zysC;s6RAl-oA* zKa5O?je`#Qii#~T@iQLQ+|2w1ZErvyUl7E&t3Dpl`Qf@Luxp`z*_yu=YC3(GY-AC? zjTmkz55s+&`b#M8DTw=7fb~Lp^yYw#b&{K3M>+CVOuiGFt?Y5inI@Z|f`j5vqw+A) z$MM`_V>q1oJ28Q_cffqPNz3u%xtnaeH~lo&Eh{Q$Iov~UKQCoURv$O9R!)4`BCO9w z{3pZ%p7()hcZ)kV)f`C22VdETlda236~@RSPN;PAS&-vOmdEvR`c_1p5(2b{Cf!Kpw{&Q+S9k}n&AQVm;=ncyr=J!@tTQ!occ>lY?F*-TaLC@w0>mqKz*sO zf}*{6MXrIi5xbit#*$ZCt+;`*M5bc~|n%4W~=FlGyIlKJKBtkAqGC#p>0n8y)il&_UQ+v|lgC z!?B>3V2hXBxN=*Lhx+)G{)n;c{}N~{+T05ibBES@i{=q%dpFp$Cxb4AZ8#k=<$lmZ z(47xqeBKXvI308`+I%vo8>lAFT80ZjRw6*DAA*r6-l#L3nbnn z*n4!{uc1MNCG}`%kYP%}xtadIbwfiFojV5SM!H7J!)JQCHIGKRSxh^c=zXib&2$Yu z!u)Bz^>fhAML#F=+?v#L)X!BvXAz#)&_HooyMm4ZnK-Q-E05DctOxB;voB~6*1%_C zO?DyHWM9Dg;0st|TZnb4nON%?g!PhrvF3og*5<%{w*d{peP2cVfEDv#uLILss=ZFr z=~eiy2f+utO*O5+eFutI3l&o&*U$BR)jF<-BU1O)>*ZLhkTq?)tcDMCV9_?XLQ>W1&>^hu22Z9%JpxQfVlLY!8xZYVHMxL4fU z?D6Z=dXM(|?6Vs4VKX-IoCihL=xM!Jj3;$pQ6pN#5}@u`_+TrZ5w+wv>imTdT8E-F zcj-egYrlgC2i%wFWp|xgt@Da;jJ3Pacw!HX4sL-pIsd*(ls_8vhyTzR{7=22+*j#y zQESek#_awti~A4WzGp~w1?%~G-HrCGG4*k=7C!R~@yntnEb1mYK0?%=2**+Q^RIT- zjDz*Ro{-gpgLT#bW5cspcT#KFdaVpT3;*uHYTd)~zia;+%#c%3A?D1>V8ld*Wl3z_>jL-XvZcyv2nrBsK zP_I9Y>$4E+e9y~g?P4tA?X2}N|HdD1wrD!1H9OlU%9;@ucIUagjQfduV|~%P<;R?A zC$rZc3)UOWnjO|i#TpE)c^&aQ^waZlf1D7;daXtH{cVgPLr_~Ha=`D(OYqf(@|`{M z2a4LM`o36;Ab-AGXT!a}x=^lD1#5!AT8WAk3*yAY^Y-r=6uG_g2IZNn+F=Z9wPM|j z>Q~z92x85qFYf)dS$dtu#0EMsYDQ+_-qO!b{_(WK$9SjOOXVBS;2!2dVl76m0qD9M za=m31bmU-5KVeMS&pKG2Fg{y~WeBaSh1=qxwy}k=e%8{T?D_`><5~AKYb4GZgO=6A zvyqwHgRILss0N3HvE|3cx`Fmf$~j?A$SztZc-h2|kPLC+qb!+8>tLbUxZ$?2b*SrR zo;9t@h5Vsr?ti?Hza)d<-yamjB3NrFwr?EcCr>>-4|8?1<{+N6?Gw~~5|PU#^pCjz zWqWQ5o>v=;g$%L$!{m>rai4KeZAZ-WqCQ~aS^KP|-*+|UfZNi&^#P0r8rh{|Tu=j; zYUt&SSuG>BO89Ucj5W{BT;H)jbQ`>D|Mfoa*8k+*Z-)#2Z0`LZ@LW996OnZ<^x8=H zzH+XPxo)ieMQy;(kU#0ojK>`LxBuD#>37tA4)<9LKbZ16J_CPgqW!7burqFe;;(rQ z_z|h*3*9g1*V3P>e24134t%jU#fp4V%(pe^{cq=AdsjcA{}(#|qwB-ZFp4t0$eqv(&je8uTnvqH9}qQ2!YS7wzSD^B zG~qXz)$h@7(>>s-7zKX@_Vwz>d*bKdmJq%Q4R+33HcKu;Ew1 zj&6c2I|?@4F8ImV1K-;M-y4bVwaB?1%`Y+Eq4@@E9Y%KFg_ z;CtBTOV7nA-XC-SF$W>9ZYjD74y?m5*nPf?o0tuKZhiyb8;Q2!e(HNPf5zN`BL_Ns zPz^+3-(I%INV-4fNV|Yq#5_gJjXKE~Yio}vngi(=cbWrGED3Z<3)by+!S_ZA9%=3> z_Cv*7ifsF*-eAMV6+k+|Fh9R#-=mXLPqYfB}x!7Wg2NW@NG#{boM0Kri|8MT! z@Nc@Uh!5?}X^p_g97)C*BHnGx!He;|l_DOD<}oynpg6nxeZu?<6DG|C%Xdk5ctWhJL6?}6E9)?TIx`eGo-^#XaR}-TpoMqDCkI`lc~0E`0y6p zi2K3b5c(c=0O^1!CyD+;eF&e2Q-?no{vKTm{po&>L9W$r2NHNN&k_ML(X^U`}%-=zDMcqUyMRq7ek({LR(kiev9$FQTSeD{C?aSzFzoG R8zG5^vJU+@`VM{fe*xH8mgoQg literal 0 HcmV?d00001 diff --git a/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc b/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc index 222a172..6ad1bf4 100644 --- a/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc +++ b/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc @@ -52,7 +52,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_ICON2 ICON "C:\\Users\\robof\\Downloads\\icon.ico" +IDI_ICON2 ICON ".\\icon.ico" #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/javafx.bootstrap/javafx.bootstrap/main.cpp b/javafx.bootstrap/javafx.bootstrap/main.cpp index 72aa108..5365560 100644 --- a/javafx.bootstrap/javafx.bootstrap/main.cpp +++ b/javafx.bootstrap/javafx.bootstrap/main.cpp @@ -13,7 +13,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe --module-path \".\\lib\" --add-modules javafx.controls,javafx.fxml -jar .\\app\\EndPoint.jar")); + LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe -cp .\\app\\EndPoint.jar ovh.alexisdelhaie.endpoint.Application")); if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CloseHandle(&pi.hProcess); diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000..c0393eb --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: ovh.alexisdelhaie.endpoint.Application + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/Application.java b/src/main/java/ovh/alexisdelhaie/endpoint/Application.java index a241036..0f65b7b 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/Application.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/Application.java @@ -5,10 +5,11 @@ import ovh.alexisdelhaie.endpoint.utils.Tools; import javax.swing.*; import java.awt.*; +import java.io.IOException; public class Application { - public static void main(String[] args) throws UnsupportedLookAndFeelException { + public static void main(String[] args) throws UnsupportedLookAndFeelException, IOException { UIManager.setLookAndFeel(new FlatIntelliJLaf()); MainWindow dialog = new MainWindow(); dialog.pack(); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form index ef73f21..83b9eb6 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form @@ -1,6 +1,6 @@

- + @@ -10,7 +10,9 @@ - + + + @@ -24,7 +26,7 @@ - + @@ -32,7 +34,7 @@ - + @@ -40,7 +42,7 @@ - + @@ -50,51 +52,76 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java index 2fc1ecc..354d1f1 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java @@ -1,6 +1,7 @@ package ovh.alexisdelhaie.endpoint; import ovh.alexisdelhaie.endpoint.builder.TabBuilder; +import ovh.alexisdelhaie.endpoint.configuration.ConfigurationDialog; import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties; import ovh.alexisdelhaie.endpoint.http.HttpClient; import ovh.alexisdelhaie.endpoint.http.Request; @@ -8,9 +9,8 @@ import ovh.alexisdelhaie.endpoint.http.RequestBuilder; import ovh.alexisdelhaie.endpoint.http.Response; import ovh.alexisdelhaie.endpoint.utils.MessageDialog; +import javax.imageio.ImageIO; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; @@ -22,9 +22,28 @@ import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; public class MainWindow extends JFrame { + private enum StatusColor { + INFORMATION("#53baf5"), + SUCCESS("#7ccf16"), + REDIRECTION("#b153f5"), + ERROR_CLIENT("#f5ca53"), + ERROR_SERVER("#f55353"); + + private final String hex; + + StatusColor(String s) { + hex = s; + } + + public String getHex() { + return hex; + } + } + // Constants public final static int WIDTH = 1280; public final static int HEIGHT = 720; @@ -36,27 +55,45 @@ public class MainWindow extends JFrame { private JTabbedPane tabbedPane1; private JButton newTabButton; private JProgressBar progressBar1; + private JLabel statusLabel; + private JButton settingsButton; private final ConfigurationProperties props; private final HashMap urls; - public MainWindow() { + private final ConcurrentHashMap controlState; + private final ConcurrentHashMap responses; + + public MainWindow() throws IOException { props = new ConfigurationProperties(); + controlState = new ConcurrentHashMap<>(); + responses = new ConcurrentHashMap<>(); urls = new HashMap<>(); + setIconImage(ImageIO.read(MainWindow.class.getResource("/icon.png"))); setContentPane(contentPane); setMinimumSize(new Dimension(WIDTH, HEIGHT)); setSize(WIDTH, HEIGHT); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - TabBuilder.create(tabbedPane1, "New request", urls); + TabBuilder.create(tabbedPane1, "New request", urls, urlField); Component tab = tabbedPane1.getSelectedComponent(); urls.put(tab.hashCode(), ""); + enableControl(true, tab.hashCode()); + settingsButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + ConfigurationDialog.showDialog(props); + } + }); newTabButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); - TabBuilder.create(tabbedPane1, "New request", urls); + TabBuilder.create(tabbedPane1, "New request", urls, urlField); Component tab = tabbedPane1.getSelectedComponent(); urls.put(tab.hashCode(), ""); + enableControl(true, tab.hashCode()); + showStatus(tab.hashCode()); } }); sendButton.addMouseListener(new MouseAdapter() { @@ -70,11 +107,12 @@ public class MainWindow extends JFrame { } } }); - tabbedPane1.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent e) { - if (tabbedPane1.getSelectedIndex() != -1) { - urlField.setText(urls.get(tabbedPane1.getSelectedComponent().hashCode())); - } + tabbedPane1.addChangeListener(e -> { + if (tabbedPane1.getSelectedIndex() != -1) { + int hashCode = tabbedPane1.getSelectedComponent().hashCode(); + urlField.setText(urls.get(hashCode)); + enableControl(controlState.get(hashCode), hashCode); + showStatus(tab.hashCode()); } }); urlField.getDocument().addDocumentListener(new DocumentListener() { @@ -100,32 +138,44 @@ public class MainWindow extends JFrame { Optional possibleTab = getSelectedTab(); if (possibleTab.isPresent()) { JSplitPane tab = possibleTab.get(); + int tabHashCode = tab.hashCode(); + statusLabel.setVisible(false); + enableControl(false, tabHashCode); int i = tabbedPane1.indexOfComponent(tab); - JTextArea bodyField = TabBuilder.getResponseArea(i); - progressBar1.setVisible(true); + JTextArea responseBody = TabBuilder.getResponseArea(i); + responseBody.setForeground(Color.black); + responseBody.setText(""); + JTextArea bodyField = TabBuilder.getBody(i); new Thread(() -> { try { String url = urlField.getText(); HttpClient h = new HttpClient(props); Request r = new RequestBuilder(url) + .setCustomHeaders(TabBuilder.getHeaders(i)) .build(); Optional possibleRes = Optional.empty(); switch ((String) Objects.requireNonNull(methodBox.getSelectedItem())) { case "GET" -> possibleRes = h.get(r); - case "POST" -> possibleRes = h.post(r, ""); - case "PUT" -> possibleRes = h.put(r, ""); + case "POST" -> possibleRes = h.post(r, bodyField.getText()); + case "PUT" -> possibleRes = h.put(r, bodyField.getText()); case "DELETE" -> possibleRes = h.delete(r); case "HEAD" -> possibleRes = h.head(r); } if (possibleRes.isPresent()) { Response res = possibleRes.get(); - - bodyField.setText(res.getBody()); + responses.put(tabHashCode, res); + responseBody.setText(res.getBody()); } } catch (KeyManagementException | IOException | NoSuchAlgorithmException e) { - bodyField.setText(e.getMessage()); + responseBody.setForeground(Color.red); + responseBody.setText(e.getMessage()); + if (responses.containsKey(tabHashCode)) { + responses.remove(tabHashCode); + showStatus(tabHashCode); + } } finally { - progressBar1.setVisible(false); + enableControl(true, tabHashCode); + showStatus(tabHashCode); } }).start(); } else { @@ -133,6 +183,55 @@ public class MainWindow extends JFrame { } } + private void enableControl(Boolean state, int hashCode) { + if (Objects.nonNull(state)) { + controlState.put(hashCode, state); + if (tabbedPane1.getSelectedComponent().hashCode() == hashCode) { + sendButton.setEnabled(state); + urlField.setEnabled(state); + methodBox.setEnabled(state); + progressBar1.setIndeterminate(!state); + } + } + } + + private void showStatus(int hashCode) { + if (controlState.get(hashCode) && responses.containsKey(hashCode) && + tabbedPane1.getSelectedComponent().hashCode() == hashCode) { + statusLabel.setForeground(Color.BLACK); + Response res = responses.get(hashCode); + final StringBuilder sb = new StringBuilder(); + if (res.getStatusCode() != -1) { + sb.append(res.getStatusCode()) + .append(" ") + .append(res.getStatus()) + .append(" (in ") + .append(res.getTime()) + .append(" ms)"); + if (res.getStatusCode() >= 100 && res.getStatusCode() < 200) { + statusLabel.setForeground(Color.decode(StatusColor.INFORMATION.getHex())); + } else if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) { + statusLabel.setForeground(Color.decode(StatusColor.SUCCESS.getHex())); + } else if (res.getStatusCode() >= 300 && res.getStatusCode() < 400) { + statusLabel.setForeground(Color.decode(StatusColor.REDIRECTION.getHex())); + } else if (res.getStatusCode() >= 400 && res.getStatusCode() < 500) { + statusLabel.setForeground(Color.decode(StatusColor.ERROR_CLIENT.getHex())); + } else if (res.getStatusCode() >= 500) { + statusLabel.setForeground(Color.decode(StatusColor.ERROR_SERVER.getHex())); + } + } else { + sb.append("in ") + .append(res.getTime()) + .append(" ms"); + } + + statusLabel.setText(sb.toString()); + statusLabel.setVisible(true); + } else { + statusLabel.setVisible(false); + } + } + private Optional getSelectedTab() { Component c = tabbedPane1.getSelectedComponent(); if (c instanceof JSplitPane) { diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java index d30fa97..881a393 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java @@ -1,30 +1,24 @@ package ovh.alexisdelhaie.endpoint.builder; -import ovh.alexisdelhaie.endpoint.utils.InsertToTableDialog; -import ovh.alexisdelhaie.endpoint.utils.KeyValuePair; +import ovh.alexisdelhaie.endpoint.utils.Tools; +import ovh.alexisdelhaie.endpoint.utils.adapter.CustomDeleteMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.CustomNewMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.DeleteParamMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.NewParamMouseAdapter; import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; -import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import java.util.HashMap; -import java.util.Map; -import java.util.Optional; public class TabBuilder { - private static HashMap indexes = new HashMap<>(); + private static final HashMap indexes = new HashMap<>(); - public static void create(JTabbedPane tab, String label, HashMap urls) { - Component c = tab.add("", buildMainPanel()); + public static void create(JTabbedPane tab, String label, HashMap urls, JTextField urlField) { + Component c = tab.add("", buildMainPanel(urlField)); int index = tab.indexOfComponent(c); updateIndexes(index); tab.setTabComponentAt(index, buildTabPanel(tab, c, label, urls)); @@ -33,7 +27,13 @@ public class TabBuilder { private static void updateIndexes(int index) { indexes.put("main[" + index + "].responseTextArea", indexes.get("main[waiting].responseTextArea")); + indexes.put("main[" + index + "].body", indexes.get("main[waiting].body")); + indexes.put("main[" + index + "].params", indexes.get("main[waiting].params")); + indexes.put("main[" + index + "].headers", indexes.get("main[waiting].headers")); indexes.remove("main[waiting].responseTextArea"); + indexes.remove("main[waiting].body"); + indexes.remove("main[waiting].params"); + indexes.remove("main[waiting].headers"); } private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, HashMap urls) { @@ -68,7 +68,7 @@ public class TabBuilder { return b; } - private static JSplitPane buildMainPanel() { + private static JSplitPane buildMainPanel(JTextField urlField) { JTextArea t = new JTextArea(); t.setBackground(Color.WHITE); t.setEditable(false); @@ -76,73 +76,57 @@ public class TabBuilder { indexes.put("main[waiting].responseTextArea", t); return new JSplitPane( JSplitPane.VERTICAL_SPLIT, - buildParametersTabbedPane(), + buildParametersTabbedPane(urlField), sp ); } - private static JTabbedPane buildParametersTabbedPane() { + private static JTabbedPane buildParametersTabbedPane(JTextField urlField) { JTabbedPane p = new JTabbedPane(); - p.add("Params", buildParamsTab()); + p.add("Params", buildParamsTab(true, urlField)); p.add("Authorization", new JPanel()); - p.add("Headers", buildParamsTab()); - p.add("Body", new JTextArea()); + p.add("Headers", buildParamsTab(false, null)); + JTextArea body = new JTextArea(); + indexes.put("main[waiting].body", body); + p.add("Body", body); return p; } - private static JTable buildTable() { - JTable t = new JTable(); - TableColumn keyCol = new TableColumn(); - keyCol.setHeaderValue("Keys"); - TableColumn valCol = new TableColumn(); - valCol.setHeaderValue("Values"); - t.addColumn(keyCol); - t.addColumn(valCol); - return t; - } - public static JTextArea getResponseArea(int index) { return (JTextArea) indexes.get("main[" + index + "].responseTextArea"); } - private static JPanel buildParamsTab() { + public static JTextArea getBody(int index) { + return (JTextArea) indexes.get("main[" + index + "].body"); + } + + public static HashMap getParams(int index) { + JTable t = (JTable) indexes.get("main[" + index + "].params"); + return Tools.tableToHashMap(t); + } + + public static HashMap getHeaders(int index) { + JTable t = (JTable) indexes.get("main[" + index + "].headers"); + return Tools.tableToHashMap(t); + } + + private static JPanel buildParamsTab(boolean isParam, JTextField urlField) { String[] headers = {"Keys", "Values"}; - Object[][] datas = {}; - DefaultTableModel model = new DefaultTableModel(datas, headers); + DefaultTableModel model = new DefaultTableModel(new Object[][]{}, headers); JPanel p = new JPanel(); JTable t = new JTable(model); - JButton addButton = new JButton("Add new parameter"); - JButton delButton = new JButton("Delete parameter"); + indexes.put((isParam) ? "main[waiting].params" : "main[waiting].headers", t); + JButton addButton = new JButton("New"); + JButton delButton = new JButton("Remove"); delButton.setEnabled(false); - t.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ - public void valueChanged(ListSelectionEvent event) { - delButton.setEnabled(t.getSelectedRows().length > 0); - } - }); - addButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - Optional result = InsertToTableDialog.showDialog("Enter value"); - if (result.isPresent()) { - DefaultTableModel m = (DefaultTableModel) t.getModel(); - m.addRow(new Object[]{result.get().getKey(), result.get().getValue()}); - } - } - }); - delButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - int n = t.getSelectedRows().length; - if (n > 0) { - DefaultTableModel m = (DefaultTableModel) t.getModel(); - for(int i = 0; i < n; i++) { - m.removeRow(t.getSelectedRow()); - } - } - } - }); + t.getSelectionModel().addListSelectionListener(event -> delButton.setEnabled(t.getSelectedRows().length > 0)); + if (isParam) { + addButton.addMouseListener(new NewParamMouseAdapter(t, urlField)); + delButton.addMouseListener(new DeleteParamMouseAdapter(t, urlField)); + } else { + addButton.addMouseListener(new CustomNewMouseAdapter(t)); + delButton.addMouseListener(new CustomDeleteMouseAdapter(t)); + } p.add(addButton); p.add(delButton); p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form new file mode 100644 index 0000000..4703c1d --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form @@ -0,0 +1,63 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java new file mode 100644 index 0000000..d4dc42f --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java @@ -0,0 +1,37 @@ +package ovh.alexisdelhaie.endpoint.configuration; + +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.*; + +public class AboutDialog extends JDialog { + + public static final int WIDTH = 450; + public static final int HEIGHT = 500; + + public static final String VERSION = "0.1.3"; + + private JPanel contentPane; + private JLabel version; + private JLabel javaVersion; + + private AboutDialog() { + setContentPane(contentPane); + setModal(true); + setTitle("About EndPoint"); + version.setText("Version: " + VERSION + " (NOT FINISHED)"); + javaVersion.setText("Software: Java " + System.getProperty("java.version") + " (GUI: Java Swing)"); + } + + public static void showDialog() { + AboutDialog dialog = new AboutDialog(); + dialog.setModal(true); + dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setResizable(false); + Tools.centerFrame(dialog); + dialog.setVisible(true); + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form new file mode 100644 index 0000000..f45007c --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form @@ -0,0 +1,175 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java new file mode 100644 index 0000000..50ad4c1 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java @@ -0,0 +1,64 @@ +package ovh.alexisdelhaie.endpoint.configuration; + +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.*; + +public class ConfigurationDialog extends JDialog { + + public static final int WIDTH = 450; + public static final int HEIGHT = 700; + + private JPanel contentPane; + private JButton buttonOK; + private JCheckBox allowInvalidSsl; + private JCheckBox allowDowngrade; + private JComboBox httpVersion; + private JSpinner timeout; + private JButton aboutButton; + + private final ConfigurationProperties props; + + private ConfigurationDialog(ConfigurationProperties props) { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + setTitle("Settings"); + this.props = props; + buttonOK.addActionListener(e -> onOK()); + aboutButton.addActionListener(e -> AboutDialog.showDialog()); + allowInvalidSsl.setSelected(this.props.getBooleanProperty("allowInvalidSsl", false)); + allowDowngrade.setSelected(this.props.getBooleanProperty("allowDowngrade", true)); + httpVersion.setSelectedItem(this.props.getStringProperty("httpVersion", "HTTP/1.0")); + timeout.setValue(this.props.getIntegerProperty("timeout", 10000)); + + allowInvalidSsl.addActionListener((e) -> { + this.props.setProperty("allowInvalidSsl", String.valueOf(allowInvalidSsl.isSelected())); + }); + allowDowngrade.addActionListener((e) -> { + this.props.setProperty("allowDowngrade", String.valueOf(allowDowngrade.isSelected())); + }); + httpVersion.addActionListener((e) -> { + this.props.setProperty("httpVersion", (String) httpVersion.getSelectedItem()); + }); + timeout.addChangeListener((e) -> { + this.props.setProperty("timeout", String.valueOf(timeout.getValue())); + }); + + } + + private void onOK() { + dispose(); + } + + public static void showDialog(ConfigurationProperties props) { + ConfigurationDialog dialog = new ConfigurationDialog(props); + dialog.setModal(true); + dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setResizable(false); + Tools.centerFrame(dialog); + dialog.setVisible(true); + } +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java index 052170d..6616350 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java @@ -52,6 +52,13 @@ public class ConfigurationProperties { return defaultB; } + public int getIntegerProperty(String key, int defaultI) { + if (properties.containsKey(key)) { + return Integer.parseInt(properties.get(key)); + } + return defaultI; + } + private void save() { try { mapper.writeValue(new File(filepath), properties); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java index fe0e639..261d5bf 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java @@ -27,12 +27,16 @@ public class HttpClient { private final boolean allowInvalidSsl; private final boolean allowDowngrade; private final String httpVersion; + private final int timeout; + private boolean downgraded; public HttpClient(ConfigurationProperties props) { this.allowInvalidSsl = props.getBooleanProperty("allowInvalidSsl", DEFAULT_ALLOW_INVALID_SSL); this.allowDowngrade = props.getBooleanProperty("allowDowngrade", DEFAULT_ALLOW_DOWNGRADE); this.httpVersion = props.getStringProperty("httpVersion", DEFAULT_HTTP_VERSION); + this.timeout = props.getIntegerProperty("timeout", DEFAULT_TIMEOUT); + this.downgraded = false; } @@ -99,7 +103,7 @@ public class HttpClient { private Socket buildSocket(String host, int port) throws IOException { Socket s = new Socket(host, port); s.setKeepAlive(false); - s.setSoTimeout(DEFAULT_TIMEOUT); + s.setSoTimeout(timeout); return s; } @@ -124,7 +128,7 @@ public class HttpClient { SSLSocket s = (SSLSocket) factory.createSocket(host, port); s.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }); s.setKeepAlive(false); - s.setSoTimeout(DEFAULT_TIMEOUT); + s.setSoTimeout(timeout); if (allowDowngrade) { try { s.startHandshake(); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java index 8a64724..65d51f1 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java @@ -1,6 +1,9 @@ package ovh.alexisdelhaie.endpoint.utils; +import javax.swing.*; +import javax.swing.table.DefaultTableModel; import java.awt.*; +import java.util.HashMap; public class Tools { @@ -18,4 +21,15 @@ public class Tools { frame.setLocation(x, y); } + public static HashMap tableToHashMap(JTable table) { + HashMap result = new HashMap<>(); + DefaultTableModel m = (DefaultTableModel) table.getModel(); + for (int i = 0; i < m.getRowCount(); i++) { + String key = (String) m.getValueAt(i, 0); + String value = (String) m.getValueAt(i, 1); + result.put(key, value); + } + return result; + } + } diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java new file mode 100644 index 0000000..3583dc9 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java @@ -0,0 +1,34 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class CustomDeleteMouseAdapter extends MouseAdapter { + + protected final JTable table; + protected boolean valid = false; + + public CustomDeleteMouseAdapter(JTable table) { + this.table = table; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + updateTable(); + } + + private void updateTable() { + int n = table.getSelectedRows().length; + if (n > 0) { + DefaultTableModel m = (DefaultTableModel) table.getModel(); + for(int i = 0; i < n; i++) { + m.removeRow(table.getSelectedRow()); + } + valid = true; + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java new file mode 100644 index 0000000..f2288ab --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java @@ -0,0 +1,36 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.utils.InsertToTableDialog; +import ovh.alexisdelhaie.endpoint.utils.KeyValuePair; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Optional; + +public class CustomNewMouseAdapter extends MouseAdapter { + + protected final JTable table; + protected boolean valid = false; + + public CustomNewMouseAdapter(JTable table) { + this.table = table; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + updateTable(); + } + + private void updateTable() { + Optional result = InsertToTableDialog.showDialog("Enter value"); + if (result.isPresent()) { + DefaultTableModel m = (DefaultTableModel) table.getModel(); + m.addRow(new Object[]{result.get().getKey(), result.get().getValue()}); + valid = true; + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java new file mode 100644 index 0000000..d7e5080 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java @@ -0,0 +1,26 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.url.URLGenerator; +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.event.MouseEvent; + +public class DeleteParamMouseAdapter extends CustomDeleteMouseAdapter { + + private final JTextField urlField; + + public DeleteParamMouseAdapter(JTable table, JTextField urlField) { + super(table); + this.urlField = urlField; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (super.valid) { + urlField.setText(URLGenerator.processNewUrl(Tools.tableToHashMap(super.table), urlField.getText())); + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java new file mode 100644 index 0000000..e85992a --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java @@ -0,0 +1,26 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.url.URLGenerator; +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.event.MouseEvent; + +public class NewParamMouseAdapter extends CustomNewMouseAdapter { + + private final JTextField urlField; + + public NewParamMouseAdapter(JTable table, JTextField urlField) { + super(table); + this.urlField = urlField; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (super.valid) { + urlField.setText(URLGenerator.processNewUrl(Tools.tableToHashMap(super.table), urlField.getText())); + } + } + +} diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0d216b34187a0c609ba391e94b9a0077e3ca6636 GIT binary patch literal 22975 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 PMt|_(`g`1Ri#qWiStC}J literal 0 HcmV?d00001