From d41c785e80ba5c74dd2d68fd81d5e359b1d255fb Mon Sep 17 00:00:00 2001 From: "LAPTOP-SB56SG4Q\\86185" Date: Tue, 11 Jan 2022 15:24:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=BC=80=E6=BA=90=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=9D=90=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JSD-9268需求确认书.docx | Bin 0 -> 40102 bytes README.md | 5 +- plugin.xml | 21 ++ .../xxxx/xxxx/config/InitializeMonitor.java | 21 ++ .../xxxx/xxxx/config/PluginSimpleConfig.java | 80 ++++++ .../plugin/xxxx/xxxx/filter/SSOFilter.java | 108 ++++++++ .../eco/plugin/xxxx/xxxx/logout/Logout.java | 20 ++ .../plugin/xxxx/xxxx/utils/EncryUtils.java | 179 ++++++++++++ .../eco/plugin/xxxx/xxxx/utils/FRUtils.java | 255 ++++++++++++++++++ .../eco/plugin/xxxx/xxxx/utils/HttpUtils.java | 243 +++++++++++++++++ .../plugin/xxxx/xxxx/utils/ResponseUtils.java | 94 +++++++ .../com/eco/plugin/xxxx/xxxx/utils/Utils.java | 226 ++++++++++++++++ 12 files changed, 1251 insertions(+), 1 deletion(-) create mode 100644 JSD-9268需求确认书.docx create mode 100644 plugin.xml create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/config/InitializeMonitor.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/config/PluginSimpleConfig.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/filter/SSOFilter.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/logout/Logout.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/utils/EncryUtils.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/utils/FRUtils.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/utils/HttpUtils.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/utils/ResponseUtils.java create mode 100644 src/main/java/com/eco/plugin/xxxx/xxxx/utils/Utils.java diff --git a/JSD-9268需求确认书.docx b/JSD-9268需求确认书.docx new file mode 100644 index 0000000000000000000000000000000000000000..432120b09bf34c056d3f7294382313009af7b522 GIT binary patch literal 40102 zcmb5VW0)0rNzKE2`5}O;A@Koq za3!L2n9UiPp&Q9wZ(qHjTGhDcwzZuDiYC9m|B0#41LNS))A|6wM#+$V7Gnr$wK<^Z z$rgc>K2TS>ocpXK>QSkXf=Y`MdAF6V$rt!i3t?umF|CGpWGtJ@!Y0|b2pol)%in4@ z-z1LJ6pefh9ORks*Q5X5JnOSvSAXY^X7(`m`6_O<3QD<#4;)vc!HG_7$}bjo$4&f1 z{vY!P6%IOzo}! ziR~HwykE+e;?TpQy$SI~*b-nYRN4kap6meR-dBeiX(2$xNt7k8{0ukF~GYkirvL^kEP^zuIEEMCJ>Vm$%>gH0b=ZR5!P!FDbyI z+F(Cg47eu%iq|K1H8WxDRg$>|gwm{{w$lXBT_he>6~%FljZ&fFSx3`W-yC{fGEY zxZf>8U!lXI!18${6*-s`Q&J9F>ZcpZQmf;%R2R;j!`X~Xvo{J6r=2Z0k&=WjEMQX2 zHF&e^)>GS?5oCm|!CH*e6H0!w&(+O4iN}i7(H7h;Kv*JaAh>xEif|FH&EnUM(OIIN z<-CUaIj@p0e^Zyr6-`@Hgb_}m8=D%W{rf;aw7qMSzo=U!??%SfGYjVy&09#G0R81$ z$!#@ER0E8|?tBy~UO&mpYLF;iEMqArtyN3KHeveAGz!ofMC<$4V(_4wv-N`~MknqH zoNrT=qZgx^ISTj^@sKzna2;6JebzpWDJUs&DkolO3RMLL5#?reky03de(0Qh_Qw}`Wg zr;VxeKd5i%N;@A)Aod{l`zt&`!r^u5`wc(aOf}h>0nPr_^j>Y$(!KfSq=>A6Sl%rAw^cE(%R^>Vg&<9CwuvDoDip>Zt; zEa`^@p0wRSp;q?s;aO)=pT{q$P7_FvZi)5*>N92cV$AQ|sdoix*>xZ7fF@>mSI5u6 z!ErfmwjgPrLt54l+06mdz#@+hiq0vE9?f8IAD1}Ru?scc$f7YyLy6$XZ;bdzD0^?( zHlb?G*vyKtuf*zPjyX)88{V3iXCN<0pID8eo zck@sx(B&WSWBGN8zv@M^JX3;dg13x-{hRi;2j&bDKe8DZ`0iJ1@M2o4Wae8VgwA;n z|2Z$He`Z-fruOSa`Pkd&B~=ps5&5Tc0-5ObR^GcOLRiwaEJiSNkJ-!iiRGp6;!D}2 zx#adI?8C#pCf<9}wz~hBhrHMMK$Z#S%o@6MYS;K0j*#58$MpWKC`TSMUfBJ5R+_qIx)}mV z()M^{mq!Me{n}>-fWbD^id6FK><*~S@D`?le<4GCjw>hvcLN+d?Lnwc@F;X7zVJt_ z=S>lw#i4N_O~x$b=!HAr`Kt5sabLZxN+U*>mC&BEZ(A1-G3f<3Rem)E6#rKg-?@sd#~(mAR^y8cx{HGfU38tJBA zA;sbyHQqT?eAW$uBmqUftx;^5Pz?G2^<1Obu+Prrx{fn1pRXz7PAR*=1j6TD|JyP7 zxMv;fkc)xELa8lZn=_ir&6MNVGX)~LZxp4n9u(QFKS_gL*CYDYEl1FGDVaJWMAK=M zXe^u8pATHK&|w6MA~QQcT6}Uf$W-Buk=$`Q#{yQwaG=WscNT}X``%vCi6+BXXWpx- zI7ZR3!Tt>AyF=q%gwMq#el;9ub(}@?+`C1B!S#u0DhqRzY?oJG9Fcge+l`&~CVz!* z`pgm|s%h4lH6bBs1hK@ow5kANOEHXu6p}b8F$7Rba)2YWn(`nyF~sqo>k^X(4r*pC z?dg@)X=ipr#P<4Y7O6L^_#|h&@YYE9MPX(oQywk0Kxy!>-)eN>9_oI_J7(WjXLqWY zWp=#sC-B=bl;ezwa+IRu)eJIabMp+E?AC)Ioura?#-ZzkCpGmVl+w3HN-b+yvIoAP z84!8q`Yv);TEP9saw`{_dpOW5eobhQ)k!-!{goL>eIrM712AL+LP|TEAw~Gz$Etwr z5!8S-b6dwVG1=H(c84LAIHQ`#?jmspu1hjBW2%MOv`JvWx^x&HA3DaA20wS9jI-Kj4we^Y2R9|L&F}Z3UncZ9A@xLWr}}J^kRx+$ z`WwT>8fX2<3^n`xZ=l&edX&xeH@i9>a|LH|d4@m)g-|0R7UvTFgs5=26ALE?t?|p` zCrWNn$t8agdZ(B0@rXN7CMw=TQL+0ZDlr5-HsjagB+-g=2ln-bH%!+{iLT*)XpXIb zVU21*iqqaTASFCbVjFjoh5vzi_Tl|V1hqTE0urKeq{TvGksZ@6v{Rl-E#KfF5GhN5 zmzR~5u6xF#)|5(1xuo-TlYTk$SfrRnyNEC;tUw}*(SS?}%ND!f7_aCS(=;kmbW7ty zo(^fV(`;wBgKuz=cos3(R}x{L@y;V%5Yw;VhVt44qilrcRlj#09#j!~v>?*P&2b%^BN7Bb40 zH6D2N+B=SW;zJv%sdTSlr7Vm#boIawsK8c4L?VpkrNi zf7JA%!1KcHod#1t%-aKH1E<>^F2G3ZGbZLLCU4y|JyxVACnPrV;ccsw3w>wcr-SWm zH`VH*N8WtIZG0>=VLgVA_qfz58Qblwf5f*4Vf4140^s0l@2l^ zxA~fX#ILT5<%F;JFZ*pT_*>+!dTmbvmf&0L4T{*l@Ym3iW(=h3#Nlg+wJ%dir{x|U zOrm#@jKT?5gW7ET!4vB${G<5{kEjA@sZA>D){F*=Ity2)>Is*06>Y>Sm@aBG=ukST z)y!+QP|KOmuA!DPeBD9MWd=KeT#pZM13M5OY6#fWD9&V=9&0q%>?rCP(pF>6V{IN4 zfcA>pu@zo6)hl8%K~|?!$nB}3rUhK@OAA+j8xz@6p@nu;Xv`eSf;y4eQ^hlTDhFnd zXF(mxY>N=E-0d2ys{TbgJ_b*UAg2ov0*+@Ql+yG2bip$@%VO@br(mChq}d3G2W37-;GZrW7_9!_Fxhq-1GKW=KzdU_^1`1(aVQy&BjOTX zpMxjXejNnaU4-y+5-Xs+KAx>tT&(OFgy%L?bFRv<#VKqpn>uT&N;<)2l4O`zvP8I% zW=NK$SKTcfb8%**o)CpiiJv6DSLz9O{nm2;I)$ZGeiPtLq9RhB8F@A;W zU;I&eVb74(+~WI6Jx(BRNzLPLXorhAPHab=)?uQz(-yO$gA2g9{Xfib1>Qi+zj%6XdZx1O$-{8MgHE_)a7fKH(u8hpVJYdttO%WQMa zTP$dLy_sfD&lP9Usi5>w&BpwY^F`F;V2AfK>J&78Eokgaj=1=O0B45Yp>TB++1nvm zFO#eqHN5AiqU8Y~YNjhf0;bNw_0Epnv|>>| zSGdbp=Fhf-ZAQ1=s^3F+ukTl9p11zj(Te`hoBTjGtk)lB1x{YBGtUF3P7-(R8Dng# zZmocV?~k%xSKP|t_MZWT)=Gj6g$q zejz>(VNX-2Cr%QvTW{Hc+TjCK2Ls`Pm9@;L%P(1=(Sovh+$`_fd^<|`EM|`zaMQ@a z;JY^uDwK5kH!o5!7X(Ipb+Vu<55F zk`D2j^HdgNcfO1cmP+mFZD9(vl_*)v1#r#lo8MLMm3d3ctE%evk^MjQHRsT6O6uV? z9f`w(t@7%+C*Oj+);(`F=a9a8Mu;@5w)_QYB0F_t`#j=msge`n_f|s5h*dY^eU!r0 zdbadI(}t2Tv38()6QASg{X>2YGtmYcq>L7jjxL#G{C*GUmjrc^qk2i99I)z2R&~e^lvw4`wogR z4*X=~gM)X&k&h7Gf~$3pR8e1EgoR9t7)NXHyp! zOFQ#_z2P@wY&dPOJ^Px!!(%-+$3h?wNXVwZ*;_0$FUlOU%p!nl>Lh`H7yn+>?+s_4 zjE!5A<9>>+aP9@>;QzUArb2gLZwakff%81zg4R7TQ(t1YK6z;Fg2)!#sPHP2Qod+* zuGKzCYvunuIa#b+)&)1Y0uoues+?GvDY(d7c3L|I*R6Ptv2=kQ>#k2Z-!1FbRGZkw z%ZlDqi8+t5RYcqRO6;h)kujQD=Un$J04Y;JXL zTykMI*Vfblf-SR!7gd^5qUx`X)#i~Ny6HO`*;$!=CO7njcXW6?zPd#`s?S(!Zt;8E zbwenq(#fS&N%V^%tPVX0PxuQ=s2j(X-dnLxZgcO###6gzSG=Hxt)tmtU^M| z9Bup#WnJj65N!tZD9)=hc5!R(4tFg;8?tN?qmYI4YtTJAs*E_acu##g0?8GH#rA7y z%d082^KP!xt>$$*uEnWyjGTG390JVVb)%Q?7Tts@r^Rv{0cOg*@58IpQ*PsEaAo&O znb|JP$MY}ZQRa8e%RGgZ`g|pP#3aRo8ImMEd5A#rg^R4W;Jr za(ph}dksBpRTx5SKw(J}eQXTbEaCbazB9Pv5rHbVAMTbdQ^gDSjy6u08*2%vw~(u7 z)#>K%bzjPk!QCOvpA$9n%B#W_1y`HqjxQG)SMJO?s|?*rZ|BS0`QBQ01#rcWJq_Dt zQ1mh+jEE7zR!nhHkUBL~luwA9k)4z^OK=5o?XJ@bb?*jq4Cp-mn6K6-m}F>`Y&@X4 zvukMysV&gE1^_T zXH|iV4MxVF%m$<06*MOOayfm$6ZAjXVH|P5Cwb?(xoXB4k6$1s4>dXbeEr#(i#HvX zQaY3)b&n?Izb-m6@blB-y^OFjc5WqhP$@@*%O{QChanO`lrj0z#DLHwRp28wQ@a#(kt?2 z&^ICsdL&As9~sh3Q&_P+d~wV$SWclE{!)X0-Xut$DLUaaC5-cB*`P6_6fGK5O6*6q zPmkD{P3X?hrNp#>+%aaC{5h0d=59clwse)=qdb7B4$P>lHQrrozg3JWf zj~^1|eFBXEY7+7x+{bttg)bLZsQOA*3Y3-x9p-%^HHA4z;M=^bYlD@$2f%7_-Chf$QdR0^A|OotGflSK5E z2`evSbQg|%a3B)GL1vhl*C3x0c-2e{8S)P$CnFRs(@1=y5xF3E(w))okEihlJxHJ! zFv5(#Ko) zkK7u+iRA2`e)?74O*sA*c9(&9K=59#&0FE4?nVJ#-$#%Gas^p@^K|yXE@l`v5n^2K z!B?0A^K||}gJ^dx+}#56$-AvO%AQrF!-f}VF$`4;Cm26E| zfUyGrjmzkUDOpQ{yO$!I?`*&pw+=r|%V}DkdhS(XKx_&P0GeyHI(`jqFZIW$smfK=N>4D|OO>)eGjqL@lIvqI zszBI@Cw$NGmU-{bKmX}ZXLHqBqk#bc1ph|a|HzI)R@w;TWxfGKsXOSb8mNtXHjevu7qH+MX9I2iPN={RUI%zaZG804+TQsA2 z*D7y}v%WkOxynL{8L|h;6vWXje~JZdD0})5EZ=(nHAH<=7r?DyxxXA{`qvO`K}>Eu zdp~T!^B>Lh6bifB4GlaBE@YXGT}HOwKyXs)i5H?6@S?#8ld%gvx(LpSu3pV@;?&>o z@i$7rz`|A(!$1z8*I_1yF$v|FJg@I`mGAsUnZKb+t0TfsIX6QGT=Q^|1=}tS@lrEO z4oeSE$*i3_G2gu*1qNAo%>-h9WuEcjP2-2V(ad_$@Grd>q}o)6nB9QZF@4xe7i!9j zZ+vCAO5q@gdu?{qfH$`QQ*DSgu=t)agvmn_qd-Q*l__B|RS>jr;flI)#eN3l>uP9o z>Bz~pb-SXYMqBZatA@ELTXhHztD|MJ?B8@;tW^GeB)by(?l zrD`%Vfh5I+w^v-l8{h&?_UJzczM7*_YkMxT8-QeNCWb_`m@*wEjdrrz>V)aHds&#& z<2oy0*MlOv+!U-s8#uCUj?uJ3V#&xs4Zayfh6HOcfZi zx3U0KfuG!2cEFXHo##}p2n<`Hp-)%$^kyX+ak8Lta(t<$9`|*?>Yo&KA*`p$C#x3= zV`emvuRG<42PIPH8pf&Rl>(%)BXIYrLE{V222F7@99B>8+Ql%SJphR;s4eU)#2xMH1!?- z5Kxo|KrDqITqyNd;I6eq(M-x1g$3bnBw(x~}uCKlxu+T6{$-x#B{|p({kW+;`n4 zxgSfHmwJ&vvKjR{<9^9*i4csEsv}2j_}!fxIvY{(t|Df|3W-le)@DUp{gde2q%+LH zeOg*NR_k$2CoHkX(#~WNR}gYB4OWL-Dv=s7V%ZICDrC_sNi2|wY*9?s{mXm_%0@+4 zax{gM(u%EVc!T@IT(sV zl%@dCcT-7-tA2?n9`&!dt1bT^E}Ez^xQg!0$ zv2>hlxJ+JmEB}o?zWG>!&8Rc|i-?4R4^P^3tS(@6qA7Z!Df}})1o$s=amvVeX0}}W z6(Y-uPsKMBc~&C@i#lMiT!VufMs(10n35eY=-v@+r0BctN|MyL9+Vgi)!|Y>3f1eh z7q7(<15mrK#j&^4vA1$xz}swCjF!49R0732avlX{L3vgs3E;mpEzP5Hv4)uEqT@+` zjJn>QFK)tLD5_acH_j3WxlSJE`nu!7cJDU%$)ohvz1C(LHf^pyM!T@+DxRH*Mr~%T z@^8*U9xb~jew@2!Lie>nWT*CNHu3*5PZlN^>o4=v7lA5lJHpEj=rXf&oyrwJ|1wXN zrtWdA5;nqIY1z!v?xu3|`zf~7u>XmW9x9K7o;WxIgUJHbIXmT>8VunVKRXd_)WTA~qdq47v}N zLVy&4Y!O*I$x9g;J)K>KK|0nYbKNr25yP!8yy=b>82Z~#RqjtnOP11&Q{>2xy6Qsqd&lfqCX8cZ(1GM;2ZC zdBWz^8d&oW2G&Be?Jmu|t!`^Q5amkPBqG=(IUFz*gbYSTxk2?baqJC40~$0;y5f9G z4`JChc8_Dd*U|5`>pge|z}A}H&zc$G+b zNq?{Zvy2jsk){}iae%ZFWonp+Kv%`n@ikZd!e@+J0aaEX5^Tb`7BZYS9}F=j(@GC7 zF{5jj^p6~0-?V%G&IMLrkd4EPH>M@8j1jLNEy#(eLYstr;!PjcmM+Nf2Bew(7L7%< zJ)>}DU{t#owsDNsPBkr4DHRs!mN+h@KNGvPG(!Q)&QGe3$AX8BsFv{(%y95h9)jhW4J@sZHE(#+AcY0cca<5@`8g>ScFLWELsA!nV8cC@Ac=P zKNraJRBlwGKqiqHw~hwZ@B?y+@H!8__vibTZ?%$jZ1Svrgv$I-V$dBOR_vfXOIfl; zraQnq!@lM1sz@I;J06@9&A7uJWe$8@^&Lg)p9Rs0kfSZK%;UY!CSHKikQ__sU$eaX zFS9(I9sQXUkh@|zk>qr+wyY?ZOXs*$TT`aHo~_m+(&oy$mcFY)kDfOsMt zMN2f#q=yFsv#Nr$T^Td*oHKdG^=lJ6jyu>%?-xGguNv`8Zt2w>z$O+Jvd0E{nP2(K z>d$X~TGRpHW11I6@RY}a$pP5&0aE%P2#MZ6%U^SB{lCrezZXKuJ92+Z-9~O?eZUt!6mRum5^!$siS`&~}xQR^}{%j->vPLCTVngViY4krFg2r;@{bHb{M? znQXk4!_J>tk3WwsPt{mDI7|l1tcb4yB93gNOh-)}@?r5pJI& z%+Z&*k4cR?>mNYC*Qy7VbKplYZih@XQVw6;u~qLyez=U!=pjaAwBisO@S72gB+-dU z?@ci)YkNBq8Sh`ub^UpP69~6_pAF!_uy{NbfB2clTOJ*Y68?fVU0WW?{6aNg`j};% zw@EI#(ly2%19dbx^tw^5wUtu!kH3`B_lq5@vPF<0p~X{&g7HM|&zhx2%F`!v6qw_| z(eCKv$*}Wuv+hUIZxTs9#oB9olM9C(RBw*X;s_azXv6DY{o&yWEpqyw^>n)%G@1&3 zYw6~|{+G-Bw{=z3w$EZf@yl!a3Haoo)M;p`RLHMPWH}dZt(@L|-p2seyAy2*&iZ=C zgdxGzO>LoHjhuDoJaL%1JkLCMCER-Zc#K5YtEqz`w{EC%sJ$qX|Ye=K$pX z-KYBgwm3D^o|-GljEWtIq+mt6PoPjfghG{vMAE+B{)|`#IO`nbV9+)dWQh@aB_|PE zr=(^DrwNOCdU~2313mRyZH6>d>rDp@F!bJ%nk-dUK$fkT$jiKaFgiDk+<;nh6EhPg z3`^n?##K5lzKBL|-gOLATstbm4iz|(`XZ276{%kSpxcIRxS>@AU%IeV72jOMg>3;_ ziLV448ZyRqIM+esMT(ILyfCFocyY&9{m1OrfbqBst|bK+e3^zv#Ts`(d|lwNZwV)b zoeQ6nQ&Y?0^A{fhf?FmZ69M&jtI?Qvd|drjLs?)I<~chDG`(0w1v}y|v!D79Ab7Ws zO#75$7eH1Vj~K=t#0l}=of2@R^zT@!MZ6FmD8sFw2S|2QSy_=YJjglT(*XfXdfHTr zTTb*@u;V<)D|J$RC?IDv7Q~wgusP19SLy75g}!abcjfM=*MVuUb3?rfKj9>z72Irl z2-RwOrVmI`*nh76a2xX4IT-G!k#CQ18p~L=kIZ(oqZyMDG!zIKg__0)dii&2dF8%5 zM7y{8XwcgC@NeqYVt*8mHjiJveG}Hy1t3}RETqkNfNIX4JauMI^*#k&Ym_aDEvb$1 z{ZNN#{u$H`sIH)XRWN^f2=UtJYiXKZZ&xBtJ(4x#@mM&e>&YHRvGiVtJX z$ld|}PEi_60D!;wiGK%E{w?^g&woW!t~6!svDp#2(NFy~F1r&^0-MGP0HgH0D5AhD0>G{ceoE+YiqGOs)W9&cyDp4vA47ksY3ZNB^ffYv$ zML?b}-Q*T&IudS+$9=jJKJ!L_goM}f)BJfYsjebz;$$s!3avI=v2$l%?^N!r5aiHW zWb|aA2vVzRw({+~tp!w}JLrh9>(-|Kv;=?xO1GRDeqPhCRxi^4PWE?sy=LLMK!vt{ z)z{ze(pBz7(+hU`Stk9ww!?0)*kh#_T}i!d&N-GFeXbSc?CA-yPj2O24m;8hHj-MH zN9xe2s%mt*1) z0i-!z;rG9Lf8p=;MH*HT70klGjC&{$pnetqhl#rORAeE-@g+c_*izZ)2$Ptp$=)MK*n{n&q+L?@r^ z@p@QP4u7$Y1taT{N22M!mh^_H_=T zaN2dN%Ng~?X&M6U;`1{=ydL(Ui5xtL;iwM)|22<0lB3yHV1#LT9k)1!n;j>+i5mi^ zTfafkT)ByBPEa^>)PQRoeQX=06iJkAbXH+*6H;&N_5xXd?!7gAYeQnIK)3nz)<#(?m`QTDm?HGobRwyp7&eM;7615Hm%0gd*mm|7q)WQ8>aSxMe2KK zDeco965GCp*ZGcK*n@f+*K+tSZ^3jQH{Eo#>$7RKBhG+ewrVGRpMBMFJL40JFYyZN zNyt$zp?m?*7TkMuFjU;WfWyPKG|_uS>*EN01EM&V*m2BnoC%KfVwgDF)ICl}krfvb z9+=1umP>6JNhoq-g@Q6j3?QJsmQw-kPb>0}yqx z5QYmXmG#awU0oUJ8yBh)Evo~Vx^~lR0z6ByqAn)RD%OsquV7MIBrqnY$qJZ@ywf8T zBg(3jV{$`BJgv8~)0PU$lo+Q&1&iwM{AuX4tn0Lwz%nzX1eI^fk5*Q!>r8->n?DJ4 zw)cz^`_~cAd7>>q=m&ttA7K3vO~?PzoMfM8Ps_!LRU%?&vxvm<&FWng)1s19#JTEs zAVF8-VI~3f4HhRwhpq_^&b~mVDZ7|T=|gS)ZMzyrp4CHia0)55aJ#po$06)#`i@}T zkX1~Slz{|D*M7y}8VqDtGEIn0&o>&@qKeyeYmgW0(Lsb6W2PI5@|1I1>U~h`x7uOf zD_agT$&$o)6CxbZvcYt*)>hLg7H4>h?u!d?3a2p33Gbp3>N4vVm6>RIb6}{B-tTej z-)59yZkBGZIvwbwt(=P;q0U0{qy&4S-#EH2FtGjkZ184^%D>V~H7uW9macIdA#;VU zXk-TzzTT&6o ztD3@Q%NAOg4)SeKfkLv!-jO!5kn*a^pj|kaD)Pyi=OW-thF{b z?y6o9iL?@I&MML_T{WSqXt&nPHp+p>}+uvqSk`SA6 zGM(j<$pbsfQcs&tp}uXD$aV`HX2L)~1$OnjP5} zb&0OkG&EgBOc@wh7_~)Ez2MwYG=F+7p;XhrtD8V0fp6K`Uot3!ol4hJF(ewZAX7SSc2boL3nYYK2Bf4fbr z0|C&{GU>XWRg;Alxd`d>=c<%Y&}^dR9uUJ%il)>t+S6@5yQn>%dw4o(Sjn|Yx>%$U2+1lYmoG* zail=ZBJ%PXu>py8Q8pu0OPn&vZefoEM#?OtmC?}d*ZatTkZ==G9|zj{0bzIXq6Nx| zg~M;G1v}85KHfh0AtQ<-(p^4iE}GFt_a)cg3W zzMznZp8;ejbpUe&Qj!=-Q6=PHS}wKYZzh^J%^V$Yz)4Fcru6_+)dGsp%uw{(=i8YWgmH0=qA^vWQ1ebOl1WbEj0eN1nM7b5!5pOq{;CsH|881%h4*k zghIzSr!TQI3pr&l{{)2suoARwYCh^**+Yx?DP2CKRBxl*|6n&*8@#u--v8zMd#iWG z@5$k0RNmeHf!qL2M>MaYG(>TE8kKu6@B!i=y7&?8{F5ULID*7zm2=%2W>_>gF;_IV zkZlU@)9odtwi)f(?{jo(r@P1d<6-Ni_hU59etP?R^82dxrRNpUE`7_(`URccy~khM zn!o2^`}&IgneTJ>I%~z9-_QAZJ!UP(o6JWrTMLKDL*pzM5)7juiXgP1oRVGP{T7&J z9_5mNqO2OWgg@W3Zc*qrc;Y1~E?hC>UEtsuSgF?GF!j_v>U6oSZMlJRoiB8GK5xO8 zKqBi$$S>&bHDq6cFIYTiGOTBeNyi`BNAZWvV@ROWJpA(WW^oovw!!p2~nMcc!G!RZ4_h1 ze+N!8daK_u9^L7L747B)$)*A_C<+LW>D!uhc5UsyrY6;Lly z8&tR79d8EpE~yStzs6FBrR*f1l7-J&yTt0O*0Bf_?HRT=-!bbZ>^YC!3ztz;(iqVL z_%#x7^g!{4nkg1X6MSR(6RELaA8@5E&Fg!7b-{kzhg>v9ZtUa^dsVk-6Om0Uokwt2VB`HkLyXB3aPlM zIDtBU3k>lVR1;UGVwHNkDo&73pmK_r-d_z2jl7kZ88A7ZF!X!1rlnoFqBD+_Vy)@T zp3hXus9;H3t@2$-Et^oID;GCp-&Goo$aiWlD$$(7rdH%<{u;Y}wUF8fvoR-GxiXZQ z<3->JOz*~=C>LeIjVMNX3u>l^lI`p~N;}B?)tOdn_GwI(_`o$JRi|;=RAO7I5W|wq z8IFX*^rl2C?;@(M(hnlaXYD$Q;$3~*)LLz5-*9!_EGg%zU2WQtu@CvPq$S((F`;tZ zHVC>>tas4mmk~G0#maPpd|6+!qb;9QV)Q!<277iL=}!=>dpv&n`NOb}7PzhS zmI^IYcuyaMs~ni_5UxlH8B7Ac8o3;}a&9>(Q(`|zWCguBHS25s(CVpHp}y(4=YaP0 z3wdO$f2WwaQNJ76A6WIAV8)}FM!$Mv=!tm?J8vYFbIRtax5U_N+A|DyoAlkK8X45q z)B6#VVSO9PCk1ycx~BsXFDz6NC&5O z6Qrrme*O^1I0})9*+o25igYFmH6HTUf0C67t7VGXlLr@7g>zVtp^#8}m}JE(wC2<= zz;Tv~7txBXx{V5Ej>8d2&vDzVjAa~_r0mm@ExmYJ9#HEKX&1Mt5~O9kbqdnt*ln9# zEY|HsqABg^t{i1jbpGs-OG}y2JP|3oYyYk07ZJx9@o_B(hU}Qo8{Sgu^sGT}XwtS5 zJo9Wc+0eT2EPQiOO-J+c1F;vIz<6 zh#9k=Iz+WZRpz~fqNX5+N_o+yiz>SPs%5gstYKS({Tk{hBDR;m<)k94)28}uA+nxX z1NRS6QWOQWDq~@3D{+sP`FU*2vJ}tZg+vkrSvrMc0^Cimlc#!*xpm{70MS(;PrG4} zhO3K-6;kB95*vORdA|>lW`pf$TcI?Sw5@v571t@`lh&xMa)1M(lE`1ubag>X(rw^Czq?k5dO#ca72Xa;UAXSLwg_zsH zdy=_xqo6MsT~g?Qcu7}LdCl8H6#G9p_DM};y5q3}?E@63P%H^PuRgQ`(huBS}Gge8knVLe%RGts%2>M<+DoG)onJx;7uZm?Sv8@urCNrmoL)US|(+8QwsqnIk% zsZtQ)?1$2272H2Ht;2DQ_SgN5vPLCU?%bGopeH%+Vo@P8+Sz+eavA|S_Z~K#$t(e* z5+>NduQiNX(q0UWG-I0`y93=s@a8oVFYVAwNn; z!ewAtOHtO1WLN>$-*5P7UV%CCwJAwU5j)L?p!0VE!3_)Rux zaI8JH8m>@l>F?(Ny-Oc2q#NNi+jKCnD|%=o@H%(V$I9Z!ON6C+g$$WXzYl>ImFr3S zrlzM1x5h$+L{Xpxre>{q+ut6=OUE$3#IPp3V_CEY`A9<%>WlLTy@K$?@U4J+;tvh( zEDp))IBo~dRjo!Mx*rwc7i{1r2f_lK?&3l5{^-7{2j$YVG9xg3&ck$ST;wL5gH&pL zCEQ$ zK!+WW3A`JZExn(2$79o0!I`(~J|Kg#seI^1>;WwwX(%=oTm~B$(K7bpVvnsa_)xY- zwgWnf&RMdXTiF%mhe8sPwx9`nbOVnJ?33-3Lith?J*agn4ezlAKFRG$Ib1aq2c(d>5%{;2z-d%_KJrVcsGsl(W+f zU_UT7qz-n`YU*S{9=_ZSkwMwdEx?NX>`sAvU|cZ(32yI3`CutI>9)`RG|m|D7Bzp} zuyupiE+COn;i}%-l|y=+2eN!*mt>#tWx)OqjmlrpVxT1|Bz@P>nOJ7eT-lp6z*u z&2uaF2mCdjkITXCckTRHYHe9S6t~xUU#@yB&6z+zU%^?pz$@YQ)e_ieDZo6m2MpLx z`*w;FAn#-Rdy^|^yqH}`fox2wF^$*%VeFlPL6^-`5DGovE2X4N-FHL1%Mp@?k3_hZw7)KKm9k0?EY2mO3H0ay?P zv2jcOTO7vs;(6F@A;7=o^wPP-8fsyUv&=dPDgaaifeWl2Xc4Q_5V^f)wsOs#`~;~N zgkpO9aE=%KmmXqC3%^7#wSos2s+L=sqfG)M0+Yr?jqC?{N+s77a1S~iv7`v1#^OxS z2eN0%ky^9wXexM{Rb5d{_}aD71+wdT2ZQNn>l&+CR)EgqVly4IXIZHe^g=8n(gv2% zdzm5wcg;!zx`~VO$xQx_5J=pb1zd3;q4x`d9?Xbq>da*_%S_hrPJrlu_Cc8#<@7|t zKJVi8Hkc{~qPaAVTdmGGNlgLoVZkHBd@+6tGsi&*2SdkPr8FWYY?)hmu5RSXNt|2V5#WeBeV%=5LjWp%RC|~b zWmozmI5op&IT3U>@Qr7`2&tBfF>3=(6+EjTL?{!3Y6JGz0|l3K@pr3kea1z}a>J5M z7oiFo6=KS}T;_dOgMc+D5Aa!4*VIf{GO&UWz=9|^2I2hW%w@CHjm2DA{75o5$z@qD){M@fNk#+y^XI>r*Lp=#WRWbBV6BYPV#8qQEuz&cG0exd_;||J5PlMQwBIP0 zFM0M8gu~oQp@6+;`bm6kDdlG9&Srj{yJ~Y+s?` z8GzwTO8J^rX!N6_PQWTE0TT%uW&`~)Y{A%4qwp09L;eu1YAri_%v%mFpsxN+p~_#{ zAxe6FLbGuAeiXY|GA8@|eg*2&lB7j4bi)v7R?s+7hfQS#Y zAvr?wrjvVE#WWIS{6(L23Wx0cspG%S4@?*r&>T`kYIpP9^24ZDAEIk{dQ+&tNIDWP zf36iuF$X~w4l)aH9*n9M7WtAYu58$oNTI4U=$P?A{S`;3l#>eH6e!ljP7Vx%$qVyQ zJobx)dM1*TJr#!)C55$=SMXAXLAc9gRG?cggBY6S{i7+jW5k^2lw;esf;x^ipF1oC zJa?mu!0=7v@=N9lW1c}o8gt?;3bzm}tTe4vR09dYRe)b`Y}`BW9mrD#H1#(LII-VU zmDLuvoKXW@7Ad2#{c3#*hd-sF?_tm5uK2kxsqImE{47V~2mK;rBjlhyB71M;N)2cW zOMGN2AamQ!p+G1U6sJiY!$~y%9X8<0U(w0q3yW5+MR$xJ9_&#pO|OR_$wZp2el3Vq zGnFg!`Rri8hboY%r9xi$7_2s}mnk$aJ_IXR=NK*`w85%g!x{_RBWkf=$jk=1ZEj3+ zJcN5JZKwdH^E|>+hx<*IXqjRX17%e$k)PZv(yjBR~XYFQ_kan zFlE_>77pfDPzd~Fn!B{;uScaKvGCqJT%|+06cfs%3=fQQos_zIa+@Y*2Kr}3$_QSI zjc+7aUAL2fq^VA13Eqvg>RkfJOCm;8`w-2xX_S(F_^N;)CoJt@v~cH+Epvl+8+@P4H355<@JAP#MnuI{E~@xvGQUR`P?$yC7WBg#*PR`OE-jt88eGTLd459t<0&;FkW;JQ+qGL?AgI1RhY5grZei9k)>| z@|t#WHVl!;AB{u@5dP_ei6@XI>a`!Im3DR|dvBvZsCS8%IXPz52gjfXJ!o63k-v;K z_OBD@3}AKXK1xuVO*w6z`{+INj2~`eAuHoyUuumd}z zAN?7#LLFB$esV3kYA-OZY+8}Dy$Zd?PK<&QtqgV5TibETn!@k*g6vKu)2SS0 z-^W{+<>3^TzjmwU_WuHu_|y+YO2^c!^D@9ikU7nYEcuI!QLg#dPGfNx*B6r!zcl5I zt`f5zJuVBOn8B)SHK_s1&LxQff?V3L;f;8kL3)oOiLq_s?Kp9C?q3m~j}T*PuA39G zktmMTXm;&5H-olh*c(MhOR3u>-TLnlPn+9zN~zOV-Q7H2jyfdya|MfoJf7H*Qr3Ok z_Qa6jXix3=1A9WzE+?eeJN+^kaMfPjDS#y-d&i7Hra=90CAVbH2Y0zNP(Ur=^@#yB zL{tacqzb`Yd32cT98js(Z}*;1Vy!@12*2}*v4`2YO@K`ip3awtQ9`G!*k}gK)rJrK zeMF8L)x^D}EUg2v3{su#psM@Mop~#<{Dux&o%2D6><*Euu2J>YzzcKDAavZk(Xc5L z)l9;t3z|~MaHTxqEw0@s81f-0MQ1cIA09h{@!9{?IL?hwc6)d4)Aifi${KlICDf z6cFOxI4~upUtz-nR3zv1$r6he5*Ln^G+LZ6QOD02I-JrSPZmL*a}a8L5KGmSS_CD3pNOnuggFoTncBMx+{bG^q~#2%w7yoHs+I) z7c3BslXCAOMGEz&)GEdFuWFyGDom*WD&pCs>>V7h1$y@#4ynx$^BQA^24;*wqm!kT z=*MS+iM{m!cIre_^ugd@iNUO`bDbTeS3Pr8M`#8=CGvy|hT8e5TuRqHgwejz6Zlwb z*Gsicn{PN@dNw|eTsu~Dzei$lY0}(Efw{0&gbY*3KWg*YfIp&}r7of@e@Ka$r?XOW=wgvxt#Hp_6uxXce-A}9AYe3mxC&sbogt!xH|5txb`GU@v)8!niB0XMqtf2&BdBI{z2tyLbupigOXX8>i3 zvFk0&w;((;wrh$kz{)u##HOKBszw_VW@3XVf_IWTH1xc({Svz-qx zbKTkWF|pnD;D6#R&Wb}tWg4ERCK(vXHWl@NH&x0lIDXpKpaxBJZ$tDb7) z13S8@JX(qE%^E4EnW!0|xk!Ky8hmwE^9h%t0F?ZM62vCLNxGK8+LidGH^aR7;$ zhQ*@+B*tX{K{OCR^BBQ;nT7oj(68?yKbQk@(v0a2L2f_|`CVj4rm!p}hcxYillcul zW_v&ImeT;fAfE$`aT^FtP{51VKWzH`rYW67*}I-y7O-+^Mc zEo0fdiRT-ij*k!5=o<#3)5b=xE61$NpM9c}j8|saWm*Q4O3~#e`R9k-O_7 zWd%=L!1J%|&gDWB0apdLr3tq~xcE7w{buwEDNPsML)Z!sSm0TzYFf5Bp58?W<27E) z`$OCWdaR7l`0Q*HMa6-a$@YDb^XXd6oKY-f8V=v+ZvhKb!mVoCA$B`DpK z0scu*bMAT-4tGP9@G?MZctKdm1R+{mDQ!f-i<^ao_;mEr0D8wC%Q|FReyeU|)n^8c zS8UDn1?N4DtBkXmr)8;H{PDGA6^nIe`l$9?OMc=^o3^;{b)A`;rq}SbzrS;EvzgQb zUDT@bA&Z>f7DeObv(#N|Y6q6tfR;TNWyF4SOjS35R>m@+FLmgb>65g{&Ie|KPYOXb z$!vX*{l&R6`M0x0hN7QsgUfhVi&F`cJ^F;=vvP``)-7jr;z5Z{YXDrNc}771UcBwe z+B8LWpu?Q0M*plagKmR!UYvbdT$ndl=wt$`o|F_NkKPlR*>B2Tw!`y)qwLh_tbJk` z9b@!?6b0YA{<^*-?(&vRTsZf7CF>cP<7!h}con&(S0T3` zO*S|;9*qQ1Fue_rRtakE^0M^WHxJXyVv8m>SQbcNU}?UdWSRVr34XmP%(i;P7mPP$ z2UKjSDcN$P%7>Z!O+y_CqzLMA)9pXYpl)UycZKhx|4yiLL?6cxK%3`@2lMp$2CwPm z%No6vrR`6q_UmDn_aWaImeVfY`F=7cnKQc0;#}3#Tv0YdZXpi>aj_-TP zGKiXfK}IQgfg2Ee>~38ISZ)xWMWEr(l(;mG&T?iTovhQr4RH(QpcixZyZD1+zF^Fm z9b0f)ex+UWcS$&$b;yU9c{!vdaNAY<-eDWa`S4TGWL5Rj?ySMWHB{;W znWTpnQUNp!?z+pU-naG$5mc|UF|hZPx>bJJnzXO0>F>Y}Fx)M+)*s8tQ14rvfhE=s zS}HdV1wZB6kYi0O?QYU>pYCbPDuY}=bg_k%E=It?;33A>r`Tck&JLo#CO9(LH-lxi z5P7+huGBQ$sm;|O^QS6$ku>C~1F7J}{%WSTe|&l=xpJ6tnpq;e zQWUAoZH&euwcB0KqUHnlNEsv!CNgn)F&nYqItQRG%0P{s4~d)Kd2mQIlZ*aYMs;(g zH@>(DBErRp!tfX>^|q+nOgE@V&qA-vR@=dCYigK;TKGED#J1m-F%{%;?rp>pWiAE~ z{nbGLhxD>6pea9_v*o4;|BjUV%4uL%};698a>*vkr}>yOD-bMCf|t zTS1U7G?*>8-IrLP3~5*IL=R9Uc}M$T( zgzWAvy*+MXX%|2ei%bV5BbQ<9tmcbi@0h>5vJs^cjJ-Wv2*o-I7t zJc%)Cwo~2oypP>Bde62o9p)&Z&Z+<2k^h9jgTM8T!X|60bl^BK+U_m&99z>{urtMp z$lOTgOcj4*-?ipu`+M_oY7;Y7it(M#gCT0{ogmMP%u4<652g#+7~~UXQ(=sA8D~g= zR*lbkU9A)4<5odq=QT1$`8$1M=Uj)RhMhbVFaJ>$y2jkBx1+HeS@py@e4U7@y%{pj zfScnMTS};-c=Cq>F_g%19e2GMnkv=#=YIV1AKU#H-_5u0_r40NoteL0EFbo7+_mpsSNEn>Iu6tomg-%2>P6YM>dc}`050iU zuL(50CV!SwiPCZ>pwLsBJxdUX1oDWmr*sC%PkPa`xR@zi><+Hhs#snAet-0Z;$|#e zlb0f&56P2@?9kw+Rh0c{ZBdcM`dxq^0TR}MWU-g}L}MUrX$6L7gtDTAt5fvE7_IKa zm3IKHU>79$BBCW9)wPB?Q^Opsj;HrKOi`h@EYmm@7`adLUnx%Eg^P?w0pgsBUCEHdBFWhhilZmpb4b`2x{|EoNWlC}>IJcT;YnS@8KKA}??I z<@~^?Nnrb$&?QndB#zV20EoSrRseh0At84+|AcDKpao#T5J!I`3mPy=+--(HedF8 zF5vhxJkM1&Zi8sHFbxP-8$sU=mqb-NzFVL)Q-$nKt~r%w(D`2du%faf@Z;8oxC!n5l8dbhpOvp$ka5q&7AfQgxZ z>|v~PcT!hW^RsgK!ONE-Fuk(vX^ZpuVM=S^>ALf^@qN|u+}+OmakS$3b8`K#Gim90 z&KJs)plpoLrctmgAX^?fVB-jw}j|8=>Z=fPnsP& zUF;nn>zDsz;dovR!pn|BAm(x5s1=1C7pz1XB`Pd7M-#dJwe`DL+b8!uRVPB8%7-j% zt<#C~snmRZz1O5zd~KedJivffZJ4m?u6f^J)s}tuy175!hj!R*rgyzPUmmkIWVq^g zcfIVwIz1D%)juQTIN~C3c2e@>cM}{i34qN%Rk{s~UU9I)87lXnpDmU+Azi$8x`~%? z^|?-A-(=GJ<3BsVM58J-|6c_1e`5--1P(!(l z>TkZ@zAvYJFS{P5F0Xq0qSea_()zV4l25dn^w`XWn@%;kcw)+r1~cQ7mjX!FO$a>^ z9PH%W;$v(yM^m}K5@E~yyLi6=ckk?cUXE>Du6;|S2jocBV^&OAeXEFDKMzJ)qB?$0 zcfXuXeC+sm-@Z%Jef{=a!bqb%y1vHZBvaa~GXW(`}Ryn%d@P_xCBu|1s{S2|0(5SX~G2V<-{fmrE z*S___^~o2maNYU2-u<%GS3Lfz(OGCVUk);LxxisMazA11!1Z-tdODn^@VI^B1jGG2 zxqPtQZHkv0+KTxpg?OL-!s@u$-txXUq6=VV7f)1LR{1VHoY4#+Hbxj?X&NIDXd?ZC;biNr5N!3*(670B5vMq`1wQ%dfU@DHM^xfr+7tlky8Gws zT6cTH_p4_YasDUAi@oDz>svKvM&|%(-buieM+3y1LMcI5&Oy5Z>F z;514tXBQsfvXTBYzY6;Mzbxqg84dW)S;PPOoz<+Z{s$SrQJ^Z*{GaQ;pwfSY(Esl^ zb0=f#|8fCYvC>cheDEPR{6G3>p4FH_VHKfNr>IINvCh)`rf845$6%Gg19~~jn$+K-%%&P%ut=ZbbGkmE?6TzGZD$9vOD4?7w?qLQtPF5R;y8Wn# zjnSymuC)wt`;#Llg5sN^-r+FyJQt$y15yGL+?wqrfT#77mv>N4Ps$aG2cjQ^WaIGU zIT3*!MRSQx=T|`1Z(clS;qN+C?+4E>nEx*zT9B-U;`NI#dH>3*5PzrUzoHErXKMpv zhhKHoe}cYM%3Bs2bjaPfmpD^-e0T;-*8Qe)6XUm(Ith)Im>GqWRStuK(m z%lc`C)kIUX5gJbP9&h_z?1@FG^1$H;c4C}b7V&w(jvnYE$yBAi&9vzBzpjm^@c+0r zM9eysNMd3Vn96$03&5LD-KuLVYlSU2=8P57B}$da2x}X>jgRYkkBb+%^;TBvFb*cG z{5aVy&6GkU2tzITyHsLBp#yWD=JBLTBDtM`?=|8ShiFe$js5CY}eTmVKlUu z;>$zROF?Y!lR0pl&YP%tkD;q!bo%A3z&V{fCr5$BZg&HDcc#j=O{Ee-)75jrO3awK zMEY%}M8bQenwdh?8?0%f1|6?oEDI#I#^)~Gt&rRo9Nxyf0_qPdvpcVrFB8By3O@Ax znT6x<2FA1~0!^`zsTcSUZHX}ZEd5QFF{Cy-6ofc?NZdo>IfONm1uOfx1XD;$N&*vz z`0KzT<2j#`RT5=Y(^=TRr*<2+Va;XCwn1DW+>U^uQFWoaIZ`#ymm!Tp_HRcqR{R!v z!Du(t8Z(Ugh?*WHlIGtK%97UV$uJX_QfF&nf{P!UgTLE5I3;|2-@YFp($iL-*~l$}P-F};(2KUg>c@E2Rz?7{j|0*_GlX-=+;s!M$;yz%An~P#g6Y9p0jOsHW7hX1ej2G|$4$~_}ab3^u zx=p){v;?8EXRrLy^Kf^4%nbX>HEy?InWIQyen5-1FIpSyUO2iOk3~m~?0#0rMJePMZ1$!O>gMMUU9>4s)+RIVtIpf8^Hr^E~42opcCFkK6Q)EYV#f}`vUtukgHRl zv)rk`CzBf3jNsXFB8d+HlbI<2`Zgp|zgo0cx)bOUYc$Z?%RJ2T0(c(4Pe^T9Q;A_U zig;=g0<6CVA`1^(6w*43z5)$KnIki`g&u}3|MCgl=#{+}UG^m87R`mK|Giqb03vW7 z#{sYygUt?9mQxd$$QazGlKWs^u*3UvJt&*xWEags5~!l#`s(`70QQ67!2|4`$l}BQ z>mtCrWkO={0Sg7h*f&qF>ZjYWx&f6wIYmE>jtfzstMgL zvWyy{QGh1e)#`}*=LgVf4oOiwd@)(QKOFos&wMp^ilK54g5;0Ty>%?Xr1yae793xM z>PaPS#E^Wb#vU*LPlO*j;AiAz+qLRHfk?6n%pZpdt)G}n1n$iF?n2_IFzGd>Z-7lQ z=kWe}^(|t)?Ft%%AbH`GS>@Mi$y2|-7h3!87oit7J((v?Ow$sxZj+enb01sTs!CSG z9;txjb`Y@bY4y@cHr3^I`Sn~*SA3omO@u*Eu>Hb98$oUN!k+SK0@Rf0DE_VQ?sq5m z8&fGSazYZbr?t+ZQ>Ajl=*Wg`-^9{QQcX| zjsqIS$D%OV)=ZlhRg7vPf(gPgAE3?%;e&c-xY!&nY$dI1*1wFDUw zq-9@Y6SxmY;!ck2@8(uS2P)an7CCYX;^tNra?1Yu{l|BXyX~=&t&OX!sjF?a7&D5y zRaDD=wtP)Mssca&yxi{QrCB*0NrElRffdL;bwM3S`TU8NpCrC_sxm4FfW={bo^*nq z`O|1UZ&Luj-lLwVS`+c3yLItnf{K&;GrhBY8^}PQ#HuNM*y$SNrt+eqCicaj)ENkX zTvNr^xW#)qj_;6j1GZR&!`n0(a0r}W#<8f<91TJR`ZfUrGsx&Vl?xNg2cOt^6B+(j z4vuBl>j$;r=2@2ar+M1U_N-w@gSj%$EP8KhMD_O?P!Qf;{>4*%y+R1el#Hfx6{#F$ zO1>y9JMd4R&Y|(5uVcOCkF&v7lPYCTE@?^vHa4~NLwj8m6clD`N%-T_Q*hCg5qD{U zjN9vL8+gLt*xcM*8SpD#;CdWa78aI$2t#rmq)O5~UX!Gsp&$YWongrI^gh`Srg7zS zc+j|&CB93tQB(^hgFIoiOf@|h?@%9^r5@YVuf3ZoyJxvxDTWA<(+Z8;#r5em=je=* zBZkohOY}o^?I&`@)L1@7TO-+`U{!8Ak0tj`fpeJ0CEeoc{A7s4cQJ51+ z*$QIU7qFJDU36>|Ovv51Z@Q(^nd|-XXzJgje@)~FfrTtc_TwN%ja}kJCJ9ueFf^ea zs76vCCC{5k8Ic>=*$GS_sSL!wl;5Ns*0aG@o&AgTLc}nn*871$Tnp=T<&l!!Vwvf` z((3`%hfc_Djq48;$XD(mw>$E_zAo*AKIAl9aJ??s9;#}&9{7w-NBSe5EeA+2Hs@AI zUDFe3+@g{L+M2JN*0{eq@-^5e`f9ZsCB}z1dU>F z?L2GOzQ0wfMvyKatgo{itz6#jrFh<%W5h5I(aFL!~Yu@?PqGVBhqm z{vCXpiC~ne-<|eF;Kpr-@k+`nuLd50*K;A-wZKuri73HNFxgGY^F|iY5<)Jz6WN+@ zpKad2%gUTVm)H4640J|xKu+g2_O!Ch$$bNwuOnmWaH_hR9wrXXkqh@M1vRa#gYL@` z4$^voo{5P}t)`8FoJzE~jQB5x2s?r?`I?!4KTO?g+tW{U=@XAVG*{y=k>1nTqpFyCyz_ZS`ZT%|(3K6QHaAx_<*kfyHdSOGd@(9^nq3vT+zx1dPFsr23= zC4PazlBw*F3tDyFUkBCUbo5~gmdA@yF9)Waa{7tU zj#K-iStODRhv?QA;~e{mD(a-0cy-JBYr(~z>F9WU%9!nwf0aNSVW3pk+>9pG(jL@y zS?eILd|d?3^^Y568UMT!Vd_Uz37<$gz)i;c+mpC?Z7vNFWJi+Mq%h;oSw17qffLAB;97 zTe$7&8mX3S8q7rEFQdAJz%lxOkr3Z13TU;a`Z{q63WHc5OJuPi)nIbvTk?oQ@BMEl zdUvJRn>gAM@1Ilu;e$N?J=MWDl!xH);4+BgwxjDUJ<<#@K}Ahaf59ff-BGqliF-Th0MEy>2=?k{P^Z>2%KAtuXe(!SkQ zMwP^F2TuJSwm8ww%q$}U!Tb+B`txx^{k+@$+K=1Y0|T0osWkLyeIglc?z*-zGrgxc z?m(h$4$VQm3T@iFGZ$mr@vVMsJH>p%p6ruze5vzuX@v-{y>Imnx5%NF`amHg;BZG; zSkG3P`|4m;J?a<#6_4^><626-0gyyd>%n#m35&tECj!IG&^<+i!oL|sE28;9B#s_A z8&h`IGlt0NN}OCaq8=MWNL&YP`@@0*13k?U`|?7z?*tHrx&9_-)Ym1J&nA)9*-tWu zWxweb0~Y8-0KvkrY{7Vl7L<@WZX?7;ccN;{%Yo5i^KptrzG;86dLm4vL6GQz>;U=5 zIu_B&!fks)c?-ZfgFpUQ@2*mt?o^#l4+wSTZRochE;IdM*}?CA%23hT-?lghh#0QAxG&M+m*(;1g8cbu5gJw}0v$bl(Dh5b$S0%7dx}vKB&8c8;-smIB1Mm zw{;bU(L+M$z=FbNDW%32low&1gU3U3p}m3RO40!QC}SjtsKz%h7AXd~tYS3CQ`m+8y_r-4?5nPvQ4Q9ic8%<{qY&JA^oQ@? znHy^FA20a0OxT<72$B+En4xL#!0>{08i1X+yqP_lqmVn_X$WuOWZ{ZV{$3qIG}f)| zq_&Ogyx4khG0hU&C;K{OqP5k-Hrv4^j$#x`eTw6`S$+IAe_eTm(}?fwM5y0l!bA#*Hw?WpRkcVLWmZnov#oBk>uZxueNw)AE< z-zl-KG=xR$Qkgc62?9va=zEBCloPl#H%S*uhARF+Ylm0Iyz(&?!~uv^KvRC6#%>SGC>-FZsJtG%2d~ z&__<=QY1|A_64MRnL>s2DMf#I!cyau)0ZQT9vTG(eF1X2<;&*=3vT~J`%pT$YS zpOz`iW2khlyzCCo$>Cbz4Mt;C6|#UlLoQ-*35rx}^{QuWjYG2``Eulbt}IwU>pO2o z`o>G&RP&|gd&FMF$IZ?s&}n?AW`A*S`ux((#i3>->o<$Q{P%Jm4C==k9+)CDom<|@ z58+1_^a<8LB?}0gH9$^>5BF|o^ugL`x(<8JSo2LGIQ%d5&&Y%SmRUBvOjh-CM$^$a zctQB;v2%|xw+;!uOQH>E0)J38&C#_>xFbF?*WbPeo_^hXT!&8B)S?}|`1%J}vHgFM z+)A})D`T;>XK6xu#W;ycs`fLkOLS`og~MaVVU>|!SH9n>PNE%*-6hPYIS+S=QxO#s z2N5Nj1u>Qsyz&&AR^MPQ$?7a5^7FbnqNrke_x!hra=E3qo}7b|e&uf+*~-XY*QKZQ z4I77ZaOjt*NtLn&aua}aPXk*kLc zHy?XW}sIJhCOI4xG{7c zyCbwC;ElANsyePCRSwH>Ix8i;I4McX6yiN6Ex^L~5N*R*GKgRk1f+dT5HTq;J$HVN z;Fo;$ZrsmpOh3K_K;x~jfu-r}+EKitZ*$)S9TEi3dllwH2^@<2K)ikv_d{U}Qp~&f zP^WTGvb2sy5q2@YkImNLQ)Gz9Yo!BmFHN}Ttz3FYmQlvgE9NB?k5RNbPgYm6WX)st z)Wb_0S4c6(;#IcD$wXZi+#(-6S}_+gM7@rrKckOZWocIF>0taLBl7iZhpfLG zMt%7{uRI4(J-d1(!8JD7gaY>9BKtD8l_L`NplRANw{?aoCbjw|HtO;=5qp?cMR96yuo2rzTb%J2&KaTcibWWgTV(icCo9EFJU?{UN@QjXQkr{NK z-1EJ{9opr5^nF!;Beg{98o=NA$06wN)|oUxz(h@W!p@%^AIYy( z3EY+&nIJCpiH$Ec39$v`masRB@->9b?k*paT@X@bgCP}egpdd%cVcyAB1K_pFo=~| ziY`5hqz&kzp0|Q%_x_q>qsVkNyuWtcVUL6%C$JG0Ls-yWcQx)qlTZ@W7|4|H51H#q z8!g|S2Es~YED7$MNN#NUIv3_oeTS@sM1Q#Z)Q~yDiLdLDc&8SnoS@F_Z+E%)7%y6r zA@Xc*p8m^+jp_Gf3^vIB@6%J@l`5{w;@eO^IIH{dJyjxq+?zv7>EN4vu zo#cS`TIx6YXg$AChfj3!*TqtD(|be`M z>VlHOXkh)5oOLmO%ZMTt`k5nL7B0MIgt|C)4^s#GD7?_WFb5Kbyj67 z@RXF5oMl+QcTf*<*Wh3kA;NptYf&A;pj{FR-%j4yJIeIuipHO2=;QRf`+S)^Y@Z_p ze%D_-ezd7roi^ALp;mjE7lj;tbif}okrht-T`dj92ct*et0ub`ECv0795agEG%e{_ z6U%jVOv1kq+H2HplxB#1(8L)QfmpJwlp?oh4jxR|-K^xjosakk{oQZ^@#dtT+JR!y zfvLuW?zHNHL2Hg~fNBbeMXMjEO%SZoVA4UFOIl!2b#OMa{@w5ogGgPtnofx~477U)3A?E)_4N0@%*>E4iut^3`2viXS(4Oux?G#G;3pbdz;7S!zL8Z618)o&uYNGDlgvm9J%yhBa2Yf+h{M`#z zFpSKU6Mte+mvobp@c9>>{XgkZ!#pHeJRMtC4$9v!@yb1)8JfICyPl!81fvI!275JR z!cO7``tpwH_GiH$k@SoyvTUM)08 z0iXvJcHd1B7}DYB5`(0T!5|uBIt6$lGpQ3udU!v*x{1>eFm{@|+_!6PU3gng@w1M- zc7`ItJ%wq>0YNz#0#Yn971e4(_@Gx&9B{-i6Rsi>x4RfHE51iObZUfLzKGhok!)95 zKXT;q*TRJqQrwe68!NQt!&huM#DYu@5nN$!0_%h;?*}eeeK05tk zkcn}lN(G*G7gW8&}3SfPqy6-^mz+he79>NTmdo&M#X&>&Coco6=G6H+15uAUCyW zMF-bFf8~AG6yzeo=22Wm^P1#ayqE_o3HxU-Q$|VaPGwz;=rovwyiE=#9{XMmJ;NcR z(fE(>Iz+y28d=E4p-6ARx@}HR&6DsQlN=cD5KQePLv#-P@^UUNy*dY-BSsw1XIiS? zs(Lhd8#mkt#OVw1dl?4T%s<7tb(M(`M~n*_aWHeI8{+X8#7I}2?lh3}C3p48e%vQ~ zgTg}*$_8=6hSdR4v&09SKc%G6>z}DLSkfqT_#7~xFVrE80$kP5SMEL?5sOjJ2EHP-Eqv@2cpV3v4gihcQc zPB*O}otbh=i!~(h)SVO?DT%pOgS>Efmm5pL*$FFpM=?yPhUJY%<=dvJhcAzhTRv6Y zGg(ZI??e_u7a2+CLJ}uqAV$}nNzb}6ue_9Q2*&Xe%Aln?Q>KuW>IBgOCs~hQZr#4{ z>vUEJ6W$nKq2_2X`)yLL_(uKGgz&)G_RHfggFG@UU6En0Od9uA2+@V?1^mFM06v8v zEG0@$sf)w%q>-shaNy=*ujBwh9^Jy_MoC;Q6E|k%Wd$WwaUW2Dv5al&$Ot*Bak3ni z%Mg1Sb@o=$XjfE0IL>eRG8mveO7jBtY}tW~!Yc4Mt8VTT!FK$0)CyyR&qv4|h*Lde zmQ=O}9X_)8lEj|xDdd)9!lpTUE?uSw+3w0{68u6_0~#J{ceQ?Iz~=iC&mH8^sUeWk zO%z15ABXeYd1Re);h&9_8B!Sevmlbxh#0enz{l|;2Q^ty4t=5RQbP9pL9maamTIkT z5|WqZ%@IjLx&%6`l>BvEI3DyZb4y3>5pXmIchxWy`0e7icDeZl3mpYyp&L*7+wecx z(w^-%^PkOT1yp3yGt$4=jgEB9%82h&TrX~#6=;cNncI5iUxscjX>70~ocC^|L4Gvq z?0KLQQ?9O!9H6d>yL0BxJu=k14KfA~bfYswT>#T~2XV@!BBd=pn?B!Hx?`Yz{45dm zfRDGiUhQ=i#<^wlIFz7jU&{7epBnhTJ;B@^+AnAiDc3DgPtwuK5%Z2MNSCxdBaq7y zY+xeQagI8dMhT04ghDor_G$AlsSC#yVyF&2@0|pz#X-A-g3_KR@20S1Y_Xa_Rv$NU zJQpAxR;|zCW}>(@cEp;E%xL2jpg@bxFx>?XfYd$;3j*Ixuhvhs2Z;E+4!*&N?<5#Y zb0!!J1CgGaq>JiGbLz>QBu%W?nzuYZ5MH`S$y$Ja_*g&%V%`-#(N5K6agB4gDO`KZ zQR;;LMA?**=2=q9boGi%Xk9tH;3tm*R>n|SwsU9O9EJ0<(zi=4&(S+|C<^SgH->rN z{H080?LqO~(Mh$0<0dRXXB{5m0sAAkdz%3v%(fRM{L^B3vT0NrSq2ufJ=~k^zJGvkgKRGuR%T zINYy|f0SZ=t}nH4pa|ihw{s!tdD!b*d;=QvP}SoFL=M5Eo@Q`nIy!fHt%zA!-~H~R z0j$96=Ue8Hki!s+d72R21uD%dl>@q$ni`BL93{)i2(`p?wb`NquGYL?{Hp27)4P_%9CuMS=YW~i((4&opy zBO%+d6-D+IBI4M4#@C7Lotf4VviFF{d_ITj+3uri}S1%MzgoXWlpSnfnEmaVV@MWKT zUvALiUH=A&>R$5IZ_m)FN;)quzE)K($HkLV+^tT+ zC~toI(yBma{+Pn4=I!^yGYn)V_w9DDW^?-C20rEw)(>y@LFZNyRN*XxDlGvAY1KK9 zqH(Epn*}{@td|4xc-7t+(jVRWp4mh^zo;hOSMegS))1pMsVE7{rt$?C9-l5k7+7QoN`vi9Hf}xQmXP5I0=s)DZ$zar=PWbY zfn_lpLF2?j?6defAe(Uok;aGq(PoIurD6s!m>*v-b%m+q$*t&^eNE2Q=$P(yyKz%9=Ly)7-cF5-bj!!g2T@ z-{<9%=EpSd>w7qGM!G-dX6;|_Ce)cxz8Cn9ZVLzBG(Qz%vT1gIP*9!dS0YaL)R7x0KS=_BAM_JR*+%iQ=)!ZIvVg|^$UOzeb3pNjKZAg8veQ~K! zYgyqo<20rI##B(Byu`;9)eTD?tD!dbjy@dkhXi`j-BTg=W;pm7XRV+HMa#)R<+@iP zKACV|51EvL_gu?V_1?SgbcS9kZ}ZKyVCDKSm}rmD{bZ!C(u77FALyCTRpD>b)IVavt&ZQrUt157S-sIJpRS9Odb8w7qBMihyFQ?{PHlM6HNT|(i(-eczUn+dCxIFECS3Yf&+>tQ%e&+X^`W1fo z&zc7yL;`#?GMbA|o`sw1U%hiRQ*-9o!|NG)I>Q&R#f3NVq9ttQ%br^4CVk57_AihZ zwWy~zN`nk*zMN$tc#stdt+V#jYVUOQO<2%YuO$Ry??Q)YB`M5c4&oQ3R&G^~sReE-1 z!UzZH)xnfjb$H#!JcGu5C~Z~6Alxo)4EAYB9Re?)C^KWxbzjT(MfA7?mUxc}y_Rpd zr(_)9!y!nO@UUxf(yapg&{xvGY9bjstL7k7v_a-Phfxl;FnCB7TpLol#moki1=XN4Z z4EB}fQu3OopQDEcUXP{XS4Nz~({R4? zOb~m-kHY74BJXAua@~)~gpd4Fp}-(#m=Ojq@sGW)k~JNa8LuH3y97@X@PQFURyaG?38?&u8B!`1?Zrg&8nhv-MSMybBEmf38@v;;g= zBU$MSb48UZn!L|LIBUBoC-G+c3uwnO--L=J@1#IJ?<-3>m$we{<}H)Ba`%YnnvL^Q z%#1(M;CphHt>V(eFjFqQ%Uk(j#TE`Z^DWu6DkZI2DPGUPcsS1a*n+)vDQra&Roz;f zh~Tv+uj=dH4vH+3x%4evP!SYZ!<%WNrIup38OZy3U`~C%P`*42q&ci2@V>gC&)WvJ z7EWDg$7|GzJJGCHoqN{t$}A1R)+(O{DXZZ{ZV7J#G2r?sFk7j{Dwm?WY(5yDx@f6U zGG}nNZ?fxyhX4T?uDG<33RYtHo#$QfvH6JSh4ec1owu`Ds1A9FTY)<47p1QuM&}X{ z*a%z&?TGV@%7l{zU9zKd)%qS{&1Xk!C0zV=J#)7Mb;|82nAVjiiaaW@d)FxEu+Kq+ zaGN|mr>|fy#nqKV22{gY&o$(Ab|Iqt+nUz>Gs_3+i-IvJ&z1E4n9hz4isl92TRpvss)N&uEaRf`S5RB+(#mP3t zgiCPkq*J`Qwxptts2Iv7!0jHV50o+yQcz$g=Vs=SJCDHPEP+sCt}qe!r&gV%zi4Om zvw3%U`;Nih_gJ$#)05-$3LLu|lWyasWz7!v&D;BZO-J88e35Zs{8D%TS$F$}0r@T> zdMes?(KQk;gp~D@m26Zbxa9)Y#`>spt(GT9f^Q`^p=A?WI2a6}G&JGA-W-2R>A)$w zZOt{uj2Hxk;3?oULluT=30GbWs4Nnnzh_F}K=^gkB!NrX(I4;In(Rh}XL|7}&Gc}C z4wD8HO3_X>MJYlNvR98Gf5_O0cllfY=o)p4liJSKvW`9FHQ75ivXnd7W{)*5PA@wL z?wiLjax}MbLaX}1WMN_42R<7IijI-D)*tubMfNO=9#O^;Abq-Wc9gl>Tl5Pj%YcpD z_1P3f??=puBSa&6k+&+nJ^g*FON!pCItp68^KxqUaB}u{dlhTDiXX2{q%P<;+5u_O`J%Hg=|go>o7<2rHHTv8gveI zJoAX4@6f(G+P*P}l@yiz@#0x4>mu1j)l!>-FA^1n@0}Sp8lq-`C>;wx?*Lhnv&GCb zR?@ineuR!m7B12~E6RZPKoGxhpT2+Yo$4fDmV_c1$7`k@C)sG-}QbLIn@19;iE)oI4fg8KMPRc_N{A0b@<~u_0ACwxN7NAVlvxLav z|2p8UqyqwURONo$@$WmWkHS-_-Swb}pA=5LLvnLVuWB%h#B>IXUqeOhp}n~2uNNIP zoO!Uz>oUP+92??@AWKT5SIY1Cq2Ssedg051xH7R&U5vaw^ZfZ(?@2qT8g~gui$lDS z$(&WUs^_7d$V%Ti*zGDSPg>HDG7f9fUFvtX{f{U_hNM7xxfM}oa<2%l+*rHxU`&ak zu;%KN@h2L~5-v>(*C`=__0r2zU5J13KA$mk5l~dGW@?D?!X(4j#L8MMPJS!KmJ!P5 znMSzho>Os?U*Wvw8^<{rLn9f7xnl2mQKrtpgY3_r4*k{kr}k22d{;DmYkVya@)s5) zcGbM*^{>I^OoP53(lC&IpbUNEkyFuVuvi-d;g?sXF70I-V%jnWh1{bMnskXS5sJa*zbB+-N!cnGv7 zAHZL#p2x3ege)@tH@2Q4WV@x~Q*MA-%0yp{*(wtAE8c@NUp%M8v$@3D&i?q?^Y1c; zQdx|Ldz?NT=G3~fA1auhx$uV<`YlX(9-d>NHuJYO2A60AIDGWpu+%FZ(l9jWP6vx| z=_&^qfi2!dwjrJ<8oap57Loa~qx0ELK>Xw@+Xz7^A!9d_;0};t%-l7DD&3yL@+L`% z+u3Qpk`C?}k?(Y%XHCnrDBJ{z8BIQ1uVM-`tdkT$pxvJSzfSi^0_gwGbdS_<{?AM| z{wrxlCGaAv0itS1)|9?Hz(D}6#W&J&w>NjXizLmo#H*-H08FAS#qW$Pb_!txig>TG zxF12@m4L|g?~PVa`E=Bo&(_a~XZGiuuOzZ+VFxqJc(t{;PIfHS3b)WU!`|e7biZnG zR%|ZL^?R^Xk55<;BuZWEQYcitl#$k}`q6tLq=@dB{ zvu*Lxa=zPHD+SB9ZSq!n7rA$@Z5uIC+Ra$aN?MBMLFAMxI0`xREx9VbR4yjb2`{}$ zbQ3U|_0IP{^s5-geX@$@u${E>EHaE_(umLyr)m57Xsgj9^~-a!}a1 z_Zi!vD!XT*s#ex?u35imApXEgNDCK7&? z__hon;DvdH0t2Oifc~6;M~wm0kOMyhqECJ5#|BP6#gX~YaYLTxsUg2JA9Sba`4JLx z?6m0*=4d7To3rB~AfZTSpu2x35dVfl_C9XN-{wO9#{E85PsRv6^+2MJhf5vy-_a)% z5%j5}vk_6Y)KARdj}>$S=sZ7^0a3%h2ZJ<#V*UMFK!6qgtNjiQkS`oTfwcByBnEOT znjQeVf*X+7{_cDniOYbAKQI$}d*lXzj?PyP(bWLZPykK#%jGe;9{B4Y^gTPrBcc;J zd=>OigB|Ed1i+D760#k`WdOny3Vy@`MfpGdRRt95el_Gg;<10_OaB%pWF~*ykPwpa z6Dbz@V9~QNB=C5!Vkd#Xxc}&l{PoVGRw(*8i?UP`abgJQNe23m{%1ouk*63!9pC@C zq32Pj7(yM4=!Vb*SWr`YAoR=7-{C=rqjTj@@B@=y@Dt2AbUeD6EDBG@`Un3&Coz6MV&D46*#^lu*3$*l*SNriITa}tQ+RiV!tod=9E0XF*O`vfZ( z9d8HAGj}p~b_O`bPN?k%wUFn|P1lwKw9d=U!0v(c4YcDe zq2~AY + com.eco.plugin.xxxx.xxxx + + yes + 1.0.7 + 10.0 + 2018-07-31 + fr.open + + + com.eco.plugin.xxxx.xxxx + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/config/InitializeMonitor.java b/src/main/java/com/eco/plugin/xxxx/xxxx/config/InitializeMonitor.java new file mode 100644 index 0000000..946a369 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/config/InitializeMonitor.java @@ -0,0 +1,21 @@ +package com.eco.plugin.xxxx.xxxx.config; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +/** + * @author fr.open + * @version 10.0 + * Created by fr.open on 2018-12-04 + */ +public class InitializeMonitor extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + PluginSimpleConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/config/PluginSimpleConfig.java b/src/main/java/com/eco/plugin/xxxx/xxxx/config/PluginSimpleConfig.java new file mode 100644 index 0000000..a32bd69 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/config/PluginSimpleConfig.java @@ -0,0 +1,80 @@ +package com.eco.plugin.xxxx.xxxx.config; + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; + +@Visualization(category = "单点登录配置") +@EnableMetrics +public class PluginSimpleConfig extends DefaultConfiguration { + + private static volatile PluginSimpleConfig config = null; + + @Focus(id="com.eco.plugin.xxxx.xxxx.config", text = "单点登录配置", source = Original.PLUGIN) + public static PluginSimpleConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(PluginSimpleConfig.class); + } + return config; + } + + @Identifier(value = "appName", name = "appName", description = "appName", status = Status.SHOW) + private Conf appName = Holders.simple("xxxx"); + + @Identifier(value = "privatekey", name = "密钥", description = "密钥", status = Status.SHOW) + private Conf privatekey = Holders.simple(""); + + @Identifier(value = "index", name = "帆软首页", description = "帆软首页", status = Status.SHOW) + private Conf index = Holders.simple("http://localhost:8075/webroot/decision"); + + @Identifier(value = "authUrl", name = "统一域用户认证请求地址", description = "统一域用户认证请求地址", status = Status.SHOW) + private Conf authUrl = Holders.simple("http://xxxx"); + + + public String getAppName() { + return appName.get(); + } + + public void setAppName(String url) { + this.appName.set(url); + } + + public String getPrivatekey() { + return privatekey.get(); + } + + public void setPrivatekey(String url) { + this.privatekey.set(url); + } + + public String getAuthUrl() { + return authUrl.get(); + } + + public void setAuthUrl(String url) { + this.authUrl.set(url); + } + + public String getIndex() { + return index.get(); + } + + public void setIndex(String url) { + this.index.set(url); + } + + @Override + public Object clone() throws CloneNotSupportedException { + PluginSimpleConfig cloned = (PluginSimpleConfig) super.clone(); +// cloned.text = (Conf) text.clone(); +// cloned.count = (Conf) count.clone(); +// cloned.price = (Conf) price.clone(); +// cloned.time = (Conf) time.clone(); +// cloned.student = (Conf) student.clone(); + return cloned; + } + +} diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/filter/SSOFilter.java b/src/main/java/com/eco/plugin/xxxx/xxxx/filter/SSOFilter.java new file mode 100644 index 0000000..dfd2424 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/filter/SSOFilter.java @@ -0,0 +1,108 @@ +package com.eco.plugin.xxxx.xxxx.filter; + +import com.eco.plugin.xxxx.xxxx.config.PluginSimpleConfig; +import com.eco.plugin.xxxx.xxxx.utils.EncryUtils; +import com.eco.plugin.xxxx.xxxx.utils.FRUtils; +import com.eco.plugin.xxxx.xxxx.utils.Utils; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.plugin.context.PluginContexts; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.stable.fun.Authorize; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@EnableMetrics +@Authorize(callSignKey = "com.eco.plugin.xxxx.xxxx") +public class SSOFilter extends AbstractGlobalRequestFilterProvider { + @Override + public String filterName() { + return "xxxx Filter"; + } + + @Override + public String[] urlPatterns() { + return new String[]{"/*"}; + } + + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain ){ + + if(PluginContexts.currentContext().isAvailable()){ + //是否放行 + boolean release = isRelease(req); + + if(release){ + release(req,res,chain); + return; + } + + //code + String code = req.getParameter("userInfoGwamcc"); + + PluginSimpleConfig psc = PluginSimpleConfig.getInstance(); + + + if(Utils.isNullStr(code)){ + //跳转认证中心 + redirect(req,res,psc); + return; + } + + FRUtils.FRLogInfo("url:"+FRUtils.getAllUrl(req)); + //获取userInfo + String username = getUsername(code,psc); + + //登录 + FRUtils.login(req,res,username,""); + } + + release(req,res,chain); + } + + private String getUsername(String code, PluginSimpleConfig psc) { + try { + return EncryUtils.getStr(code); + } catch (Exception e) { + FRUtils.FRLogError("解密异常:"+e.getMessage()); + return ""; + } + } + + private boolean isRelease(HttpServletRequest req) { + String url = FRUtils.getAllUrl(req); +// FRUtils.FRLogInfo("requestUrl:"+url); + String reft = req.getParameter("ref_t"); + + boolean isLogin = FRUtils.isLogin(req); + boolean isRemote = url.contains("remote"); + boolean isLoginPage = url.contains("login")||url.contains("decision/file")||url.contains("decision/resource")||url.contains("decision/system")||url.contains("query/ip"); + boolean isMobile = Utils.isMobile(req); + + return isLogin || isRemote || isLoginPage || isMobile; + } + + //跳转认证中心 + private void redirect(HttpServletRequest req,HttpServletResponse res, PluginSimpleConfig psc) { + String url = FRUtils.getAllUrl(req); + String authurl = psc.getAuthUrl()+"?appName="+psc.getAppName()+"&redirectURL="+url; + + try { + res.sendRedirect(authurl); + } catch (IOException e) { + FRUtils.FRLogInfo("跳转认证中心异常:"+e.getMessage()); + } + } + + //放行拦截器 + private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) { + try{ + chain.doFilter(req,res); + }catch (Exception e){ + FRUtils.FRLogInfo("拦截失败"); + } + } +} + diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/logout/Logout.java b/src/main/java/com/eco/plugin/xxxx/xxxx/logout/Logout.java new file mode 100644 index 0000000..5f167d8 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/logout/Logout.java @@ -0,0 +1,20 @@ +package com.eco.plugin.xxxx.xxxx.logout; + +import com.eco.plugin.xxxx.xxxx.config.PluginSimpleConfig; +import com.fr.decision.fun.impl.AbstractLogInOutEventProvider; +import com.fr.decision.webservice.login.LogInOutResultInfo; +import com.fr.decision.webservice.v10.login.LoginService; + +import javax.servlet.http.HttpSession; + +public class Logout extends AbstractLogInOutEventProvider { + + @Override + public String logoutAction(LogInOutResultInfo result) { + HttpSession session = result.getRequest().getSession(true); + LoginService.getInstance().crossDomainLogout(result.getRequest(),result.getResponse(),""); + session.invalidate(); + return PluginSimpleConfig.getInstance().getIndex()+"/login"; + } +} + diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/utils/EncryUtils.java b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/EncryUtils.java new file mode 100644 index 0000000..d90fa22 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/EncryUtils.java @@ -0,0 +1,179 @@ +package com.eco.plugin.xxxx.xxxx.utils; + +import com.eco.plugin.xxxx.xxxx.config.PluginSimpleConfig; +import com.fr.json.JSONObject; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 解密类 + */ +public class EncryUtils { + /*** + * Base64转码 + */ + private static byte[] Base64UrlDecode(String input) throws IOException,Exception { + String output = input; + output = output.replace('-', '+'); // 62nd char of encoding + output = output.replace('_', '/'); // 63rd char of encoding + switch (output.length() % 4) // Pad with trailing '='s + { + case 0: + break; // No pad chars in this case + case 2: + output += "=="; + break; // Two pad chars + case 3: + output += "="; + break; // One pad char + default: + throw new Exception("Illegal base64url string!"); + } + BASE64Decoder decoder = new BASE64Decoder();// Standard base64 decoder + byte[] decodedBytes = decoder.decodeBuffer(output); + return decodedBytes; + } + + /*** + * MD5加码 生成md5码 + */ + public static String string2MD5(String inStr){ + MessageDigest md5 = null; + try{ + md5 = MessageDigest.getInstance("MD5"); + }catch (Exception e){ + System.out.println(e.toString()); + e.printStackTrace(); + return ""; + } + char[] charArray = inStr.toCharArray(); + byte[] byteArray = new byte[charArray.length]; + + for (int i = 0; i < charArray.length; i++) + byteArray[i] = (byte) charArray[i]; + byte[] md5Bytes = md5.digest(byteArray); + StringBuffer hexValue = new StringBuffer(); + for (int i = 0; i < md5Bytes.length; i++){ + int val = ((int) md5Bytes[i]) & 0xff; + if (val < 16) + hexValue.append("0"); + hexValue.append(Integer.toHexString(val)); + } + return hexValue.toString(); + + } + + public static List getStrMD5PrivateKeyNew(String userid) { + List list = new ArrayList(); + String strSourceA = ""; + String strSourceB = ""; + String strSourceC = ""; + //账号 + String accountNo = userid; + //当前时间 + Date nowDate = new Date(); + Date laterDate = new Date(nowDate.getTime() + 60000); + Date earlyDate = new Date(nowDate.getTime() - 60000); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); + String strMinutes = sdf.format(nowDate); + String laterMinutes = sdf.format(laterDate); + String earlyMinutes = sdf.format(earlyDate); + + //获取系统握手密钥的方法,需要自己实现 + + String strMD5PrivateKey = PluginSimpleConfig.getInstance().getPrivatekey(); + //密码与GwamccSSO中分配密码一致 + + strSourceA = accountNo + strMinutes + strMD5PrivateKey; + strSourceA = string2MD5(strSourceA); + strSourceB = accountNo + laterMinutes + strMD5PrivateKey; + strSourceB = string2MD5(strSourceB); + strSourceC = accountNo + earlyMinutes + strMD5PrivateKey; + strSourceC = string2MD5(strSourceC); + list.add(strSourceA.toLowerCase()); + list.add(strSourceB.toLowerCase()); + list.add(strSourceC.toLowerCase()); + return list; + } + + private static byte[] HmacSHA256Signer(byte[] keyBytes, byte[] source) + throws InvalidKeyException { + String HMAC_SHA256_ALG = "HmacSHA256"; + Mac hmac; + SecretKey signingKey = new SecretKeySpec(keyBytes, HMAC_SHA256_ALG); + try { + hmac = Mac.getInstance(HMAC_SHA256_ALG); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException( + "cannot use Hmac256Signer on system without HmacSHA256 alg", + e); + } + hmac.init(signingKey); + return hmac.doFinal(source); + } + + public static String getStr(String token)throws IOException, InvalidKeyException, Exception{ + + String[] parts = token.split("\\."); + String header = parts[0]; + String payload = parts[1]; + + byte[] crypto = Base64UrlDecode(parts[2]); + + String headerJson = new String(Base64UrlDecode(header), "UTF-8"); + String payloadJson = new String(Base64UrlDecode(payload), "UTF-8"); + + // verify + JSONObject headerData = new JSONObject(headerJson); + JSONObject payloadData = new JSONObject(payloadJson); + + String userName = payloadData.getString("userName"); + String challenge = payloadData.getString("challenge"); + + //验证握手信息,必须做校验!!! + List list = new ArrayList(); + list = getStrMD5PrivateKeyNew(userName); + String resultStr = ""; + for(int i=0;i header){ + FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--url:"+url); + + //创建httpClient + CloseableHttpClient httpclient = createHttpClient(cookies); + + HttpGet getMethod = new HttpGet(url); + + if(header != null && header.size() > 0){ + Set keySet = header.keySet(); + + for(String key : keySet){ + getMethod.setHeader(key,header.get(key)); + } + } + + try { + HttpResponse response = httpclient.execute(getMethod); + int status =response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String returnResult = EntityUtils.toString(entity, "utf-8"); + + FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--status:"+status); + FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--returnResult:"+returnResult); + + httpclient.close(); + + if (status == HttpStatus.SC_OK) { + return returnResult; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--exception:"+e.getMessage()); + } + + try { + httpclient.close(); + } catch (Exception e) { + FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage()); + } + + return ""; + } + + /** + * HttpPost请求 + * @param postMethod + * @return + */ + private static String HttpPost(HttpPost postMethod){ + CloseableHttpClient httpclient = createHttpClient(null); + + try { + HttpResponse response = httpclient.execute(postMethod); + int status = response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String returnResult = EntityUtils.toString(entity, "utf-8"); + FineLoggerFactory.getLogger().info("FRLOG:HttpPost:status:"+status); + FineLoggerFactory.getLogger().info("FRLOG:HttpPost:returnResult:"+returnResult); + httpclient.close(); + + if (status == HttpStatus.SC_OK) { + return returnResult; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().info("FRLOG:HttpPost:exception:"+e.getMessage()); + } + + try { + httpclient.close(); + } catch (Exception e) { + FineLoggerFactory.getLogger().info("FRLOG:http关闭异常:"+e.getMessage()); + } + + return ""; + } + + public static String HttpPostXML(String url, String xmlParam){ + FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:url:"+url); + + HttpPost postMethod = new HttpPost(url); + + postMethod.setHeader("Content-type", "text/html"); + HttpEntity entity2 = null; + try { + entity2 = new StringEntity(xmlParam); + } catch (UnsupportedEncodingException e) { + FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:参数异常:"+e.getMessage()); + return ""; + } + + postMethod.setEntity(entity2); + + return HttpPost(postMethod); + } + + public static String HttpPostJson(String url, String param,Map header){ + FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:url:"+url); + + HttpPost postMethod = new HttpPost(url); + + postMethod.setHeader("Content-Type","application/json"); + + if(header != null && header.size() > 0){ + Set keySet = header.keySet(); + + for(String key : keySet){ + postMethod.setHeader(key,header.get(key)); + } + } + + if(!Utils.isNullStr(param)){ + HttpEntity entity2 = null; + try { + entity2 = new StringEntity(param); + } catch (UnsupportedEncodingException e) { + FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:参数异常:"+e.getMessage()); + return ""; + } + + postMethod.setEntity(entity2); + } + + return HttpPost(postMethod); + } + + public static String HttpPostWWWForm(String url, Map header,Map param){ + FineLoggerFactory.getLogger().info("FRLOG:HttpWWWForm:url:"+url); + + HttpPost postMethod = new HttpPost(url); + + if(header != null && header.size() > 0){ + Set keySet = header.keySet(); + + for(String key : keySet){ + postMethod.setHeader(key,header.get(key)); + } + } + + if(param != null && param.size() > 0){ + List params = new ArrayList(param.size()); + + for(Map.Entry map : param.entrySet()){ + params.add(new BasicNameValuePair(map.getKey(), map.getValue())); + } + + try { + postMethod.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); + } catch (UnsupportedEncodingException e) { + FineLoggerFactory.getLogger().info("FRLOG:HttpWWWForm:异常:"+e.getMessage()); + return ""; + } + } + + return HttpPost(postMethod); + } + + private static CloseableHttpClient createHttpClient(Cookie[] cookies){ + + SSLContext sslContext = null; + try { + sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + return true; + } + }).build(); + } catch (Exception e) { + FRUtils.FRLogInfo("exception:"+e.getMessage()); + } + + CloseableHttpClient httpclient = null; + + if(cookies != null && cookies.length > 0){ + CookieStore cookieStore = cookieToCookieStore(cookies); + + httpclient = HttpClients.custom().setSslcontext(sslContext). + setSSLHostnameVerifier(new NoopHostnameVerifier()).setDefaultCookieStore(cookieStore).build(); + } + else{ + httpclient = HttpClients.custom().setSslcontext(sslContext). + setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); + } + + return httpclient; + } + + /** + * cookies转cookieStore + * @param cookies + * @return + */ + public static CookieStore cookieToCookieStore(Cookie[] cookies){ + CookieStore cookieStore = new BasicCookieStore(); + + if(cookies != null && cookies.length>0){ + for(Cookie cookie : cookies){ + BasicClientCookie cookie1 = new BasicClientCookie(cookie.getName(), cookie.getValue()); + cookieStore.addCookie(cookie1); + } + } + + return cookieStore; + } +} diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/utils/ResponseUtils.java b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/ResponseUtils.java new file mode 100644 index 0000000..c89cf29 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/ResponseUtils.java @@ -0,0 +1,94 @@ +package com.eco.plugin.xxxx.xxxx.utils; + +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; + +public class ResponseUtils { + private static final int SUCCESS = 200; + private static final int FAILED = -1; + + public static void successResponse(HttpServletResponse res, String body) { + response(res, body, SUCCESS); + } + + public static void failedResponse(HttpServletResponse res, String body) { + response(res, body, FAILED); + } + + private static void response(HttpServletResponse res, String body, int code) { + JSONObject object = new JSONObject(); + PrintWriter pw; + try { + object.put("code", code); + object.put("data", body); + pw = WebUtils.createPrintWriter(res); + } catch (Exception e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + return; + } + res.setContentType("application/json;charset=utf-8"); + String result = object.toString(); + pw.println(result); + pw.flush(); + pw.close(); + } + + public static void response(HttpServletResponse res,JSONObject json){ + PrintWriter pw; + try { + pw = WebUtils.createPrintWriter(res); + } catch (Exception e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + return; + } + res.setContentType("application/json;charset=utf-8"); + String result = json.toString(); + pw.println(result); + pw.flush(); + pw.close(); + } + + public static void responseXml(HttpServletResponse res,String xml){ + PrintWriter pw; + try { + pw = WebUtils.createPrintWriter(res); + } catch (Exception e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + return; + } + res.setContentType("text/xml;charset=utf-8"); + pw.println(xml); + pw.flush(); + pw.close(); + } + + public static void setCSRFHeader(HttpServletResponse httpServletResponse){ + httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); + httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,HEAD,PUT,PATCH"); + httpServletResponse.setHeader("Access-Control-Max-Age", "36000"); + httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization,authorization"); + } + + public static void responseJsonp(HttpServletRequest req, HttpServletResponse res, JSONObject json){ + PrintWriter pw; + try { + pw = WebUtils.createPrintWriter(res); + } catch (Exception e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + return; + } + res.setContentType("text/javascript;charset=utf-8;charset=utf-8"); + String result = json.toString(); + + String jsonp=req.getParameter("callback"); + + pw.println(jsonp+"("+result+")"); + pw.flush(); + pw.close(); + } +} diff --git a/src/main/java/com/eco/plugin/xxxx/xxxx/utils/Utils.java b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/Utils.java new file mode 100644 index 0000000..bca2b65 --- /dev/null +++ b/src/main/java/com/eco/plugin/xxxx/xxxx/utils/Utils.java @@ -0,0 +1,226 @@ +package com.eco.plugin.xxxx.xxxx.utils; + +import com.fr.base.TemplateUtils; +import com.fr.data.NetworkHelper; +import com.fr.io.utils.ResourceIOUtils; +import com.fr.json.JSONObject; +import com.fr.stable.CodeUtils; +import com.fr.stable.StringUtils; +import com.fr.third.org.apache.commons.codec.digest.DigestUtils; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + + /** + * 判断字符串是否为空 + * @param str + * @return true 空字符串 false 非空字符串 + */ + public static boolean isNullStr(String str){ + return !(str != null && !str.isEmpty() && !"null".equals(str)); + } + + /** + * 判断字符串是否非空 + * @param str + * @return + */ + public static boolean isNotNullStr(String str){ + return !isNullStr(str); + } + + /** + * MD5加密 + * @param str + * @return + */ + public static String getMd5Str(String str) + { + return DigestUtils.md5Hex(str); + } + + /** + * 帆软shaEncode加密 + */ + + public static String shaEncode(String str){ + return CodeUtils.sha256Encode(str); + } + + /** + * 获取uuid + */ + public static String uuid(){ + return UUID.randomUUID().toString(); + } + + /** + * 替换空字符串 + * @param str + * @param replace + * @return + */ + public static String replaceNullStr(String str,String replace){ + if(isNullStr(str)){ + return replace; + } + + return str; + } + + /** + * 获取请求体 + * @param req + * @return + */ + public static JSONObject getRequestBody(HttpServletRequest req){ + StringBuffer sb = new StringBuffer(); + String line = null; + try { + BufferedReader reader = req.getReader(); + while ((line = reader.readLine()) != null) + sb.append(line); + } catch (Exception e) { + FRUtils.FRLogInfo("getRequestBody:exception:"+e.getMessage()); + } + //将空格和换行符替换掉避免使用反序列化工具解析对象时失败 + String jsonString = sb.toString().replaceAll("\\s","").replaceAll("\n",""); + + JSONObject json = new JSONObject(jsonString); + + return json; + } + + /** + * 获取ip + * @return + */ + public static String getIp(HttpServletRequest req){ + String realIp = req.getHeader("X-Real-IP"); + String fw = req.getHeader("X-Forwarded-For"); + if (StringUtils.isNotEmpty(fw) && !"unKnown".equalsIgnoreCase(fw)) { + int var3 = fw.indexOf(","); + return var3 != -1 ? fw.substring(0, var3) : fw; + } else { + fw = realIp; + if (StringUtils.isNotEmpty(realIp) && !"unKnown".equalsIgnoreCase(realIp)) { + return realIp; + } else { + if (StringUtils.isBlank(realIp) || "unknown".equalsIgnoreCase(realIp)) { + fw = req.getHeader("Proxy-Client-IP"); + } + + if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) { + fw = req.getHeader("WL-Proxy-Client-IP"); + } + + if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) { + fw = req.getHeader("HTTP_CLIENT_IP"); + } + + if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) { + fw = req.getHeader("HTTP_X_FORWARDED_FOR"); + } + + if (StringUtils.isBlank(fw) || "unknown".equalsIgnoreCase(fw)) { + fw = req.getRemoteAddr(); + } + + return fw; + } + } + } + + /** + * 根据key获取cookie + * @param req + * @return + */ + public static String getCookieByKey(HttpServletRequest req,String key){ + Cookie[] cookies = req.getCookies(); + String cookie = ""; + + if(cookies == null || cookies.length <=0){ + return ""; + } + + for(int i = 0; i < cookies.length; i++) { + Cookie item = cookies[i]; + if (item.getName().equalsIgnoreCase(key)) { + cookie = item.getValue(); + } + } + + FRUtils.FRLogInfo("cookie:"+cookie); + + return cookie; + } + + /** + * 判断是否是手机端的链接 + * @param req + * @return + */ + public static boolean isMobile(HttpServletRequest req) { + String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"}; + String userAgent = req.getHeader("user-agent"); + if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) { + for(String mobile : mobileArray) { + if(userAgent.toUpperCase().contains(mobile.toUpperCase())) { + return true; + } + } + } + return NetworkHelper.getDevice(req).isMobile(); + } + + /** + * 只编码中文 + * @param url + * @return + */ + public static String encodeCH(String url ){ + Matcher matcher = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(url); + + while(matcher.find()){ + String chn = matcher.group(); + url = url.replaceAll(chn, URLEncoder.encode(chn)); + } + + return url; + } + + /** + * 获取web-inf文件夹下的文件 + * filename /resources/ip4enc.properties + */ + public static InputStream getResourcesFile(String filename){ + return ResourceIOUtils.read(filename); + } + + public static void toErrorPage(HttpServletResponse res,String path,Map parameterMap){ + if(parameterMap == null){ + parameterMap = new HashMap(); + } + + try { + String macPage = TemplateUtils.renderTemplate(path, parameterMap); + WebUtils.printAsString(res, macPage); + }catch (Exception e){ + FRUtils.FRLogError("跳转页面异常"); + } + + } +}