fMN9a%?r4J@eJ|D1s=J*K)59zT0Ke|33-66=Kaj}5xloc^*Lxyf^{%q%qPjI5s
z+8dna+BrJJ6w|FcHkFbrV(44*7?ktEJUeUiINmDR*O&LX`4(=2D^lPd48I}DN
ztbjk==MDT1qqaxSu#F~2GYA9u{Jy1QlhZ`hi}2=HjRZvCUX$7UR?q^#mffL;Yn^~Rk^kRYr{wfnv0+#y(E94CoD^FYPd
z<|p(Yp`_NuC;`|%clxvO67l~2+4TNjWnkldH3@MEQ@ms{L_-vW*{_fxB-J2fN*S0z
zO=xS0z|NLP8~o${;{7MN&eQx%oTucG08Kxv+Z-;X7a;^Yhcu0-Nz+
zvZ6W(6gZ>}s|=7QsN=>9Uu!1xu(oQJ^QJGP$y+{l3{%wS{ItqIF)kMqR*o|Szjj6g
z9yAf3Sy34k(IYhTiC3^QQ{?iQ+O@vC$n4QkcT4urCp5{TYq$IE)s6662?hhq310>L
z5^O%Ui;77eDCA7qW`=wBG1M5QQ4_n2wg5f$GZ41NLO3fIaQp415X{MJiVQGIGp7+D
zlhpeXo?6oO?vp6c&m6(o=10#GmJ5fCNV#ux=8Z_V2#HXyHvvnfvwb`u5D#9vS$kj6
zV8kJ?@7p(ED*i40c_m<*=_RLw8>06T@N@WeQ4`*70Or+QvqGAHMbE_BA8)W8&yZ!T
zk;2W7L0pk|n`^iEY1
z+?qW*F_sUwQhQbceX<}XdFUu!1}aNFR+MpFuzxUUizVW8<}E;UQX0g#W$rP*hEW@H
zz~Kl6H9<_ZLX%EW)>^+q1TITuz>Kkax3~0NNDHNj?;{dvy@S9#
zO>v5UEKpJ9XX73(fr>CHETU
zpb*)YA@C;BW_lJGnjr9kbb)(-*E=DIX~3zy7J+RuE)4r4Aa{@1wYUhnyhnReMIiz8yr9G&t-B=;!?sQfl5h`{6S}43?q4#?Iwq!X-^t#%T1IB+Ub#7Q#??r1|Rpa_q}aE<5+R
z_K|4rGe-(jWTXd)Vt!tP?8*v3@W1m6n~K=5!~|35Uc`D6El0s>|M-?61fBy&y|ncK
zD2mHl*Eaz-(+ThXF*i8GwBoRO39%k&cR&~1Z7q=O;N|Igcy_X^r_>=$_j!KiKJyno
z@hb$!J_byK(QTi%$Em0tg6}Ob(8k*i(87$lpW8qd&(rI;QC*8=-P72-`*@T;iE}
zL+{zBXQ!)657f_gOazy%x~h`(IYegg6k`mhec}apUXcPh8UcH5z6O`VbV6Xu4%Nc<
z5Ni*p(;i!W6O}SM?&*m=^EH;8<<*3Lq0?ktKN`kJyU{=Rf0t0nK_IuXh;QTOWCx(zy@JNbNKw{rTY=4=u?lli_srn9k3>vZv~
z^B_m>jTi}kXBF2buRIJjSd*pN1zI{_GZU-JSI^*ZB&k0fKbA?P6(Dv%}f`b^*_1?
z%~&9)hG;-@i(k%ZYf%+YDU;aqoiLGAz@lB3M|3$Pqav}9Kj2*R;QNPM%;gL(1>kVyOFCVmBnj}7>
zP8Na2e(~tGQoM$kS@s-D97xkvGgho47ogSn7zK-(3-VKcDNtxv|8~LTIc|
z_dkxJ)=ASN;yMud+xG)7MGfCI5}8`1_9;n-!#Z<9+~_S}AH4GJ?f)t9`iu&Q;iIXr
zjV#K4`!5mL*9R+VoZ@dlV;NY}Bc0o6oXil{4`PF&)|UWC4ZqvI50S|wcRd1(lQ|_2
znwUZmloI+ex#y)mLY1d1aD;}c#wFqL277sV`RP?bIxH}p{n3SqKvg;MkBB$B;zaIq
zGP5odOxt=TAX0Mf&0Hw}b!o{l%0%d7ZV`wv4DFAlpt|`agqJs{_Yp>
z{y$1NL|pN71l<0X6Y0zO&{vaxjj}&rOAMoFqE^=b71&_K5ckcvbdP1js#kv%rWIcA*02$xG1II;tGYgv&y{A^SAx;ZX>e=pz
z09!)VC5(c8u-(agJCsU~-T?iS8taWAAfR%Yj0ys)%8$;g%%ay72-|Pi|EZx)G4ew*
zj>#7Pe*2lR9ZQSRW2X@LP7^mB))>`usQSu9^NzNg=xPC;7&n#}dVF#La
zsN&sTEx1}h;sSrTS{|hnZJ@3J-uemHjc{Rc6?SD82EL8AAgDDjKKz*EL3Jtf^bHPT
z3^xCiip;%tKvax0-f-Ove1YCVN~w|sVFJ1$REc8Gu)Pt#-c8e7f{jg1PWGfVJgsto
z#%9Je1-%Mr-gVtR>O|T%FldM+?&^+(Bs)!k7_6hV_I0$ErzWe#sDeodi2ALKh5u6x
z&+-+}LEwp)tCQ2WslkemE@L`Wi9IrW1|ezw9$~_;nMtgmAiv`8A>K-h((@noU0b~?
z#;x)%5thvfdi01}GJH~B*dehV(g!(s2~rN~4i`{nq2nz;!+r7wR#3V+67XWa4ekKU
z%~0R@(cr@H1n0*W;4||_n+6ghV^%K27Hhjl$8JN
zL5fP0&f0T!(2W#1)#5UFIX`6m5*gAg(dUl^8BRaH!=6QS9IG6A9ZVPOMr^DQ
zc^%YWSRSLu4Zriv%PRg$kkcs=mD2P{c7j-;#$=_@
z-a~Pjd(Dqj9}FE8yuQFprzT8e?4uZS+T3Ixm!Q~jnkN*bIo3ekk(~gf7Di#KFJ6V&
zdwl$^N3W)l-%|;M)I-y)6+%5bf&m&Br8%=8B6Xrah+Kf`&6*8mc4!KH*bSWL)ghkE
zr8=s1IG-(RZq3YwR_pryvcGI`Y_LrevA#8&+O;S(x_M??EX2gjYE`2xeDT(u2Ft8x
z#=|;PXZ#cdn`?dDaMOn6foSnbYGSK3^BhC(9bP7f?fpd1E
z^8a2CJ$W{Nc5oQ^Uvm3(?h`nrdPcmPqQ2ng)ZX1^bzjjJISIT`yGS-v$k~p1IIDu|
z8Fj%;!YEeM?aCc6QU_c%Y|%yF4Z#!pW0H-f_trvaU>{H54|;PNYY7bb&&(OSK;56L
zF3QxwjHtB8vfk>j-=-bUygI+^m&uO{c1*q@xhKAfd3%n?mEY>cl27P*4G{pcz8=An
z2_IY^GA6O1gmD%}rMxPvRhiY?G6StX)>TDH@Q}eKKb7(iS=mRb=1~ur^>8DN)EJFw3N9rKEz-L9?KK{sT<9lCzMhINln40ZQd=+qjM@6(zq|SPbAsDZ(Yh3pkn)<{ULN}FEW>X8%
zTAm@yY6&!mz{&wi#+S+~?tb>xh)~aj?3-sIBenB$PebhQ||9hD*7#)Xg
z%!KA#QZ$m7cP^3b480TqBv!$L4?0x05vsxJ5blI#C}BRpF7GYOP@SDLx-K?Fk~uO`
zteRf(foJ6=Hs`M~b3mYbTSq-(H?4skN6m_hfk#Z2(@JD-f5O7H0yjSuT^|#}ymz5v
zZS^2&bKt`~W}>KI-f8me@ch->PfX@9CvN1XcUyr>Siwit07(o@Lll*|fNz85E6aqE
zQl^)PfH|~dZC-_)9dE
ztd16qF&6HahWh=gUbOt5-9i7RktM2*vJmh@IV5C>m?E))FBB{+Mt&{=U3Imt)h$S7
z8e+6j6wKZ#21_h}84H99(%4^q<6Y5P_}moy9TRsJJ|u0O%%_CS5|PeME|;-ljfqhs
zn|Y*}fwar+G|*6eJFA!*DS5DW5TCFgrYowI=4_Uh2iCaU#KJxOdA=4xcigHN)njrs
z6qVlzlN~fb=JTjBEU~r>I86E$SGfBBYWntgCg1;m=Q+fL$Y~=(Lh{bpoRXv*DwIP`
zIfsZaF~>^fFo$wxIp;WMIgO=;N+V|zlVgr^p40Zd`}`h1e|p@z?Vjs;y`HD*HLXo1
zz^O`wBX~~Qyum;_7X~CKa92qb7`+IS-SG5o+Ur+fE#!KwZv0lIPbSBu@f@5@+doAa
z4S^5%TKw84m6qOaw!`{Jd+L(CQ@?nQF6lGtT)}mx+FB156Qi$u^H9K)v_5OQ-z=YH
z&kShBTaRmeRWH=52D#1_vggs^^l{Q5K=yV?9w2u}x2!=i)p`X#pGr8k|@hhv9x6qIECf!37H
zBH?#L9;S>MK8k6fL7sflDUCetutRSy_t>EcyJ(5A1CTxFa3(kc%W|Z_$arEc_H}G}
z>rjw%VDp-$mgmGBs-&DcTA*l+h*@l~RJjqoq*wZo7w)GzTQ2*0Qi(jn1_`P&tNT@A
z6fhu@xt1ESafDQP*oo3fyl{9*$vRQQGKh?At}-SYQMIadHmRDQbPlQsD9*8^snd||
zPo33$&;WodcEyQ}XOk0+^n?+DWauWsMBI2TFkE{_I|dysnpuDF2H
z1i;<9slqsb>OZJ{p$&JGrR?%2e8;vleivuG#^PM;F@907(c>EM4+iYFxcSsNpdAaQ
z78!KQ!4*#El44>(5n^9oLTd#gGb+79UHcIsZ%x@h+Z%lUashx=%_b+_sY>j5m-4JB
zk)#O_n#jB=rcPNd2H0Ct+d7WXst%&Qz0xr#DGP`kmPb{#7XtOpxA1Xt;D5gF*K{RtM2|woF|zHlYtg5Go>mm?_FuToU1ZahJt=Y@ItS#ULib
zMH{S9Y}N2n@Wb6-n|2M@Y$m`YnqWiK)iN3;*2GCAL=&Q(3owZ%yu~PgBbRH<49E^
zVY=jw{dm3;TONU``vRQuLI`q`31b`!EP^!)=;OWsT8J7isdE_*B*&!z2K2#W`JKrMV9Y__
z$3J$>8p%_08?MYPohRFZ=9Yeoj6ZNYN?xPv)OwITS(@-;S+7r==`5TtY(k^&?Kem6
zb~_cf38ig-q8Tanc}Ry@;GpXM+G>4|Wf4Ulbr&eK
z{R&0^m~tKys@qgkk1TNc+{sMn(axQ1%F`9!1_0x9-m@YvU3NIP&wAORWkZ2a_QE$+
zR&G=7`)9jU`g4F49DfNQn?8>Oa0ekN%3>ipfL}At1O`t_A?T#7>!m1Ym3
zaKyO#dxL5MRakm0gr-!Vfvm!*t}#!k6>az;u>9N>aS@&30o?FP!SJ<(2U4Ma|G{Y2
zEmq~vEqZEopM{Kk#?O!*($JE*U^eI*>1v%Fz`W6!H70ZeZYU(LaG!oL3D!XAM
zjbrR!hwPuRIH6D;Rsw3_OdrnOZBR^9p99aFP7C+Miq%aOUYxr4#$yKI-$MwFC*6Jz
zm^%ENe$|ipfSP@gl9T6R5&>9z(@h?9*`&JyB5t!i8~OtMXJh2F5R{F(noUZuMYpVKg^SHl@U$gI5Z`JReft`W}gE#Yfl7_2vOC
z$9Wo3Bi=~mXB5eGaCd(Y$eJ1gyLFd;#&C
z{D#Tw5op_lyz#lVnfGDcwXf#5?ueOf5{Ip{H5kezCv+CLP;i07nZ=J&B@D)lrM#z=
zg6@#%Ml_uP@bIvX0cUjId2mgYKjHETHVvWA?+{)VSV8~P+UqJ8Y
z1HA_ja(*1I$b`~eX0*iv$0eX;>qNSPp-qoc{(^32xP@ARUjiyHSq{^tFc}m|et#sW
zDJA&9Yw(>e*``i|y=VH{7$o}O^hqJ?=08twG$!{O$tBv%eIj!0Yy}UKldqEx@+#t$
zuee^azjw5P=u{HA|H*J!
zeC*mVN*$mDO?ohoFh9Tqo@<|k*~R9Tl$JWn#;kvY2}|aatW}yKX!)cXb0Ow`5xhjc
zenDpfU9NU6(>^1a!k1k27T;NLb@&&b30AJYcp%`~`4rT8L+ZT>$C)S6$X^
za|b{Gb>@5O>d@K}vO3y(woUByvi037OwlMjEL002Ljf{G8f$za&n~@WhwyXuiL&}+
zJ&0*#m?zC~X}p-WzE2(q
zRe{0b!k}ETnYtEJA%~u>sL^9)hrir#u;yJr9w;?%PI^|6%BtO05T(U9UTW8HUmUt3hs05
zCrR0IcE16cH>AMX*#GtBzpPlEMWBvE&KJrE*-y9wC^=fEm*>es`?mxnH
zbFj#qd;y_1kYLIc4G7Q{<5kE?lnK9#92hGevThkV>$Oa%Q02xw%TQve`HQlMA9{IA<1
zWe;r%*BxZ!C;{mhcFoA|531(^u(5qc6hN*(;Gg^LzVG`XpY^q>PVo}LQ7En7k{1X|
z06{Otf2pb_14c0pf_7F+ZaG7fk(&uwAYL9gCp8C3IG}b@5agZG@EuP&Xm`a0If<8v&S<_Q<6(`xm1kOy<qAPk<+530jrr4^6YskoWl3g
zIoxq@inWgH{jSJ>(H|_A)fEHfun4PNcC9A)@^uu!`Y%f(^4CTTU(8?MKyYofue0LP
zALnMw{}SYZr&m7EV7G?=lj6+okfT80J2>LMunzjSc-*TuLc#z@+pi)C_q)=5h3UO$
z>+V`=A07A{c)d55Kuoj(LKR6sf~dz@skI3;pE#BQGZ`*$awU(C@3u8_X_~a70-5!U
z>k5ID>QY6Dz_;IsLbUE(x^poq1mxhH(<=*
z>+*o4jzlyWQy$~hbeC#J^R-rKL$rK
zp)P01II{(7A$Z#ME-}xTy=7qs+8GQ13DO8jVT$+z0U+poa#yVOo^5X{k>frC)bMif
zFoa!iKu;PIKKTzlpNaaWwhBGZl-l%iIi>2{i44=
z+cN+NzJv-%)&e74w4wKuJq+tS+|;0VeV+
znl@cXDrE%1G=s~gqZbR<^MFDLX$O!G8{pKDNH{XA;=zr#QX?c`UGQhtYuuxi3y*E$
zUa@PZ#27+PFwx_I12W=9b2fD>ibjkU=e!TebDIl#rS1tduIL%S*v7-mf0{V=HmA9c
z#WOJFPuLgx&q(2dom1#>!B-lss!clVttgP@=yZ^8au_BWH4T_o&9X6qsm1|?<_v?*
z;xWF7T7XyV*jAGLBEu!{Z-e+AF|Crr!1w6e`PG!^^bAi#bC+@o0baBTL=Qqblt
zpqmSs9L1R4wqpkGh3^3qOk$?arN(D|`K)*w7c=EFSOW%BXFygut?|eKtqhB_>fsO}bV
zg{6`{SPYHx(x$N14$94oE6E9Enwcww=ieFk_3&8Z^-Ne6zF16D$S^~mY&W$0N18c_
zDI0zT+#^2TEH8_x$*Rk|DO$==4HK-Ic6xI_V-f4}RWr-cg}T
zmhbJW|0vh|KyRb2vc0ol%)2M;m9ziBd;jMRysR(;`kC}!WM{jtqCCqd#>LST!CaeL
zI=l6Mw>QtRzXa3g3Bq}9v8yOvU$qhpGwltfAJ@LvcM_sl^{Hq@%4me@ue)*+FA0g
zIQ*oN!5og49Kui^_h>7!*AJ3mJu>1G1psVY5;e
z_9kU6L-}W>t(ERbk&cgJbsBR(s7pf6%Ii``F#Q^eLr)^eDKJv{twXv9<6`6O3>Wvf
zSJv%L7Ii|6mwex5Y6_zg4%ghfV^t#~_UqFdJ*;H(^9%4j8UFZU
z3z>EPJTvUJ?u^quFHX=va3IhfI_p|K4U8zsnVZAK@rV$UF?9GN!{kA4x&T1Qv&A
z6X#Wu$vG2Q4eOD<$6=T0u0#bNvj{iLgO=w>c^#@vtbrlZSc
z?6+>O(_-a~cr@+izQay+rGx64JaAynXBVb?%I?+Plj@5yRkXaiPV133`n4A31xIK?
zO->$?-)2R|rrbiQkW9M{HXn64Oq$>7tVg~gR#>IL`hR>yxhykhY?JNz%2G#+>Kl_i1j4LOHyGWh9&oQi)XvJSl8I5
z3o~i`=KZ5hd7-c6XY%~qSvFTm!S4+iBPGm(kLgWZb~$qyH$zW@rOQ9W`7)qS*BfSf
zyp%6ZfuOqfY63ss#PZOge1S6;meSK+Y4&8vCed><+V`~B$T!7KpW$4R8$B(g1pjs)
zN0|Z~+Bupogf3k2D#8UB`6P|*wv93;oq8AY*EOj~Buh^KbcPpu_DnOM*2-+b%(#uxOXSpqz{;?5oL#!1C24fx?HF+=R5vyqnrG#hNi;dx-|*Tj*PfVkJ7$-0TVZ`F~oxZ$A*L}bBqs1Q9|!($8{!TO;`g^pF%
z9~zEAQi60V7)H5I+}r=?(K%XLUsi*VU|r;^AC68G5_rp*E+f}2`TarUtP+Xtr-6u^
z#za;lxEe*1#@!v>j@DgLY`?reHxn7ljb&D5MtIN7B!qrd9tc7}J5R~^jI$@7uyhJt
zJwK%~KWQMi{4bD3`h>)v+o+_vXBIgO{>@15@Q$!ilI5gyGJnYUA?oPKLjEzCoX=?b
z;sM>LS|Uh^ek@Cu;Rk7qm#h}sVP>Tn38e$Setzf3$5%KrmfJ@|i
zpKxu~>PQIV_x!**#{{{3-V$YbKDalzzGL4#+*Uii(N~BW-f2MDpAYrUrf{v6&?&Hy
zyPbJUaRv1Ar()9EHwD8g>$E7ji!rfk+4CEYgX401NfKh7{oGmn54B@J53kahMb?@^
zsX-Pjgn&7X;1g;`p$ad{r_4Up;p87)wHC=^PL_9LB9}S_|7?S=ZT1o83h5L)Kk)Jz
zt>QvMOG3c*$;tyVT^+5d@9R6(O(Ug0`pCd$T@KC;e^Lp1toy#khJ`$WJ(_V}WdIh`
zDP6;&2G%)aM(&dxZ(4(smFo*o=1aNo#Z8JXaAIKTbQTfrm5-ujIyww890e^{?aF*%
zuun1A5z@4)!NiO`V;-y>dWPG@RvIvdx)sX{(Q)|IGd{^lYE)rH==NjL$M)m}Hs9bY
z`d^jhPPXh<4R{gzVQR1LED|z_RE=<5?&_C2$Lr4*J|LhPzO_E`LifS+y%S5lSVCn0
z$!V52m^;&K)}7)q==Xtl&50q;FWrC_qZK9!rzc#>D!Ru=qr4YgW}+x^RLQJL-cA{|
z4I!*r#RkjxktFtBR65#$V2`{n&|DFU#(g$
zIwVONWjVY)Ac+HyweF%E_H7R5mBnCw*&4ETy=y2IRqMfBXftS(GHD-I+@6|nmRxOd
zkKd$S4tT);TODIAiv+!na)l06CB5inv*4hthG;4*G(eOcmiZ#|GSpteT81vKIAtV|
z3?PH-1C9aI$AWy5LOE=%q!CBlR^-wnXpRZb2L150Pr!b5SnGaH&Ou43#2Ct@HBg#h
zWdX`g
zzJBNm9O;`0TkUGQ2Xu9hyJt}GG`>J`lzLE~wvGVj3vSYm+=$)+Z5N5u~
z^Y-7s-$>~TA@f<4B$Lq;r17-?1i8FmYeG|K@;Mm=7D8ueD_a8h%~8};)p^S`8cpBs
zP-m7~DW8SHA8&@M7=$N#(EYa-}X#L;U*_#ZlkX){aRt_Sw-afZE@CmsaA
zWQ8D+Gd$YyGc@W!aBf!Kx`~8-{+)|%ZcD%Fe`>7eS*>OcG24P6nEA7s*2*c$H{5Vw
z9k5A?UwO1>Zski+S&Rr`q%oIZ`&y*6^rc
zsSUCjjN}~N>F4AOK9BEd@}Q~B@B_`|Q6i`_0elPin^|v?xB9+warniO*j+3KBMsj1
zpY)1*4c-ZAbyU(o*HEs!H4ER4La`>9srYD6_M>oUj_m{h^qtSnSRrCh8$zM?`=-A~
zE*Yoj;q&gEGpQhL2%L~ybk0z2r<+@hv|H)CaEb4$9^%`o)&lQ0J-!&&jU?Xvp<2Wi8l57uR)b|^=`!0@7167
z6C`G35+MG8pD*#z(6v^V^6^@t!f3U^iX}Xub5-8~&XaTTl?(R|UH{iVa_evMkb|Q2
z8H3G1X38S$SDD6@q}DRoNu2XrPNcF>V>-AtOgDTEA1V?p7vA4=Tulrk03$VAb{07|
zsRPm|D#3b5d%fU0CggiyF4EysN&P|G*t2Q!*9y!g^`7-uPy{fxtquDFU15(oAa+=8
zwk)=8D7-?xANv**65)$jf3~!IX6!F@n>McLyLKZ{?2P#|w^htbTe&aAwuT2URJW(y
z@0D2O|JNc+W@yc5?|*i_-*8QJbEY7f^XzcN#)`k)h~1F)8C^WD>BL>Laa~ggy|4^=
zf8hbDL8Kl{odJckJ`H3oyXu_cXAd7zJwD>R$@m{jqNHzP>F@ZvKW(jDbFvQwat=I&
zxUuxObpOe7?`kpL={;mZZNQ^rWfB6fe5z)W8ZP92%22wPs{J*OO?y@(f~s~-0^k3}
z%C__mRO#8-`gsF>q4qW30}8m4N}?}_`ZLi`(|>)-U#aG
z;nqD;h{3kA*{1v*FS(6jbbFpPviC^mv;bDK7HSgk18w{pRP}Js4{R2Fk$lpk>_OX|
ze3Gg<6B^>@iB-)|?k5LvoKCFI&M&`z>f5SmGoz6auX0e@(f1S4@wGd&Kk%q9wt}c(0<4G{XbxX(txB
zyN&W_s)g{tS{(gSMy(-8m*)0mJS;1=$Y?B2d#RnQI+v^dT|Hk|$mjH??Sz?d8C09z
z;ftV|URGV1YRE5#z?Ib18#zbbrQpQDpUU$YYCiR)^!vLmOCCS$H=7NRtyb~lwDiRt
zTzeI081%NSG}w%sH=TWvJe)n}JQLyYXXIReXKeMS(6<6%Z=>15>YMg6nDeAJ!>Inp
zt@EJOygx>N+>VQ|?X^z>vCXQVo*rx{=S{=fXV9FXZEIOU<_x9YrlBmsJ)ZXx3&v1LcCY$-ZHpMmxJe5#}iBI6*^qZRqHVu4YnI3Ql
zr1aNuVWb$da%)DO{N*FwwCnzg4W{+A`}mlzznf{f>6~x)vL+~y9)C{Q(~!8^-?9Fq
zstbW1pUQG~W?K1VzKoyL!cVift?dQP)YGC8_A$?^eapaIRI063
z*Q(%(5mrw>w|2utetVv(U`DR+tz+2BMMVEd9p-I^Hf#?|s`F7w4#}RW_@T@SAu3;6
zT}z1T9GQISYu+{RuJ2TbN=GNR+Ms*(A4TSRt4Wp9sv!FP<%1IGIkH}%{6!Av5x#dy
z$4IySie7BVnII2M7ECL-PjOv5E~24U-Ha+{GtU=BUVadD;HP_gD=hJet2b
zF)q9OVo}=DsP@5)mla<7851;FhPAL>x_`U~3){u$29#q)_yZI#Z@~I9s#pg%)=*J3Z
z&(9azg*<5>sf~jYkQ8Rul*>>K)sTg5smR=2oZ{L$abco*o)=Hf)^{zJ&TpBT
zfogbrH(#sqiKVsR1Da#-L5g%RyC&$`W0uAk0hN!EQ)kEq-%^K;C+ilirm9T3R+ge^
z-2~=P6N!NX%i<%wRiWT5FR$;akN=djkhJrpn=od;ajX)p5uG;pNI=1X3*l5`+#K6=
zZA*`I9(ZnNK>h6^i*??kQ-o3CfhwWhrT`J1)%;5H)S
z+L)(@G#eQ|$UuYCP7;1-xY?7=A-$+;Gl)5y%15$Q
zhNWIJd#XCf9}>y@C>eA5P%Uxk5B)smzZL|qths0JZF7fTMGry)8CNmd-#1?s$-B*!
zX)ZY|$$u(KI=5;rKR!8#eR?}VHd%yy;-p$ed&+7Mp_^6VL>N^S9SY$7jV5e=Q_%EazgXLD`~1NLOuqA#&Rcnsf5&
zG33j5zliJ{LK`k}o0`Sjv!Ztm+Y0942;3ZQlypcGcRr)uZaq%F4?l*Ih#SLV#Q`-(UNC=R&*+vELNko|CFWz?g{WmsdTfafoTVJK)PF()82HhyUOSo=J
zM!M&zKB41}^Wne4jQHA=oZlY}Dte$UQ2Bu~@Mfxj9O^?vnS|?*D#>jBr<7shh1Z|O
znYNjAZ&q6UNGw($$qUR<4I@>Dpy8*3dNz-;Cf*g7p2T&=$G^ShK4zhao$#41xoWc5
z)Q_vnPX~{-T)m;gR`hqP*3~+%C)u!N;%W5Q7w1ahrpw{hVlxWuFeC=qy=DA&Z&hto
z1zG9zy>14sfD%rWiLCA~mDVzvhpQWEiIt@?GNgq1U+;40mX7e-pC({IITzaJZsV(&
zBJ_1MLb})Cc`%(FB)?P}g4+6?*+qcxd9hbYtdDTAo3%`jGyZUA=E{!qR%HE|8LRk`
zRJm^w15ayqE;8mU;$JR=4{|JRrEcthHv;vIsRR>Se}g-T%Q{5ACXSHUBX+{-7ozH5
zQ>-GU;`FSDbMvGBe4cIVJl=iQ>2v+nQjckF5!a{bn1?jjftV4}O}lu$Pw?mO5Nd7_
zHL>sX7P*ViJvSdIda?|95VS>);bF0U_;Vq5nZ8F&Ml&hi=ZyWz#t!Gp7X$DH8P4y%
zu;hdD>yE_P0bgsD-LzQ9;@I}zowL>iT9HFTMFjmDy{5POAN0GPxIkQu7Cpn=ZGU?G
zQJZubr=ciR)p5LjghS~@@S{!WJ;!4=3)Eei=tHHzX`J7!Z56JtO)uwm@J2MNkMXXbO>-7QeW6tCzI#}thZ2va+9fV7
z@9VwlLDJi#A5!$DsC5rfp^59fs~#GJH&1uOX6D?XImmVO$zaNht)?iRH7}$G^aH}i
zXVbs&uK$Bf-8yg8vGpH>;4y#cgOiVwZ?q))kh|#>zD7vw+2z;tOJszO2PqxG5NU@To1nkLbCczCIDyQfWqRd#^Po?@7Up2S78RMNDLUER?c8DpO7L!hzTEcln^~nb+?R+^PJY>t`8Lr^4ia%UZwe>Zk
zx?-v1$<35{FCU(gIPL~F}_hIqB}!~`uM(rA3dfSAn(3lWL?))6Rc)%FJS
zS5kF`hBkk18+Fbedhb5=;sUk&d7vZ7jcjJDQV)CJ$w&4TGv^#orqrjl4TrPMhexcg)^_xjGZJnY^#>{Na
zc8k{vA)lzLKV)@Ilf5)n!i=OMm-3A#-u>DYa~{9K?Aahd-jv^vs9N&S^dH_cNebpooQvxCrWJ^x_7-;r$kCkmbd`+YTzZxihTxt-Cux>46^1`V@oqnDE!HeLN6k9)uj-Gay`R
zo0LZOme={zC=BXDYp7|QH=5>z5iB#e!28k39S!Re-s7Vm*K=PXwarf!G@r?qnQuzF
z^s>PYB2jF6gT~T`psklJJSV9R5@&Xup77sNkjifM-=J+POU7;f)>614;o;AFe*HwV
zkK1Cmm`jdva`bEcrzaBGL8yNJ`nrdc^63B0_X}z|gbgCFEBe8=z8geDPVWa3Quj+b
zkqL0Z*YHe+XS>bR4?QxtIPWV+qL1y3CXzxA>R1bmN$r`a>DpB5^8K*H^ugEWNNCx!
zE#F7D>C5W)I%WFATT?FXdR}LOQD*5X*5cYhb#B<;8?EBtwXw16yj`#%NFy#n-Yb7)
zPzqA$q8D?-BmmuHIh|>~b;OqPE}pp|JN))VQE&OwbRn%j`rv1DRBHt5lY@Lvs8;FU
zy1i>09ZN3QOFpGN130yvLhotM%x%ftAIU*PQcH9A%5Gs>;6T&wU2%8aiC3oh=a4RK
zJ?zrkMEMPp(S?SHL5%VTIrYyx4*R0Mj^4z`y;<;BvU)iYs)rf`aVjPiX|Iige*8}T
zPo_^emt?eNcJgVzF-Fx-=?zwZes?QjbHIAs^vGy8S9gf(6Zz9kii)$27g(#EP3l0<
zysjK`Yo%AOIyx<-Hf^(YzT4N1-e>WR0;xMqeR3m+z&Jq}*2Y2Jk2n4hZ23{@BTBq1
z1`S_(oI9Y~`7`%k7+KBjb#2LQbRgZTXTwAMpmkFvHo%+iDA_fldA-u72jzna|L(BH
zn39jsRiHV89&Y~K4C|^E9dNsPsE1($3K-k&1v-T^bX{hPf+#D!Dg&sO&mMxf*VPEO}Z?EO~3
zFvFYr|9jYD#`(mX68~lHFjRhU^C=NRL-|;Q2GLqKG8$1Xg~&!qHddbB$B@`n>s7U|
z=mlvf9gY3W{lax~Ej)SrJxOPKT&kECF6pRf{V*Lj9CylSe;eNYiLpOwJ4a~8$s43f4$>y35+>`KHR^n_2DGqSTt}+n6!GL^q8n&LrXr<
z-sRqg20@jIdykKtCr`dFE7xuFDOtd7}R6tB2ogDuldfuApWMp3+oJ3=kjKp<*M|M
zwJgI+3tz09+FC3(@1}?545baeIoVPU;Msd*T7{#zcoLSIJ9iXh={Lw@4o6GxW--XvIHv}~_J|F%(ar|i*b?pV)SHo0
zfp&GX@&379EWRV+^vwJ;qwjj`O+H(QMYOxI6`xMC~~
zc4YmNp?sRm!DPoP)=H{6ZRyFsY`WIQP_7ZDw)+#St4jQ1?Jy#balIXQJXgBgsPI=G
z&!#iw-cOD>M${X9y@3_IjGgK>Av2%PtyJORj;~9oqG%t
g7XR;CU+KsUSxb`z3Z3sC{QHHGf$8 void
-}
-// Add and Edit
-const AddToolModal: FC = ({
- onHide,
-}) => {
- const { t } = useTranslation()
- const { locale } = useContext(I18n)
- const [currentType, setCurrentType] = useState('builtin')
- const [currentCategory, setCurrentCategory] = useState('')
- const [keywords, setKeywords] = useState('')
- const handleKeywordsChange = (value: string) => {
- setKeywords(value)
- }
- const isMatchingKeywords = (text: string, keywords: string) => {
- return text.toLowerCase().includes(keywords.toLowerCase())
- }
- const [toolList, setToolList] = useState([])
- const [listLoading, setListLoading] = useState(true)
- const getAllTools = async () => {
- setListLoading(true)
- const buildInTools = await fetchAllBuiltInTools()
- if (basePath) {
- buildInTools.forEach((item) => {
- if (typeof item.icon == 'string' && !item.icon.includes(basePath))
- item.icon = `${basePath}${item.icon}`
- })
- }
- const customTools = await fetchAllCustomTools()
- const workflowTools = await fetchAllWorkflowTools()
- const mergedToolList = [
- ...buildInTools,
- ...customTools,
- ...workflowTools.filter((toolWithProvider) => {
- return !toolWithProvider.tools.some((tool) => {
- return !!tool.parameters.find(item => item.name === '__image')
- })
- }),
- ]
- setToolList(mergedToolList)
- setListLoading(false)
- }
- const filteredList = useMemo(() => {
- return toolList.filter((toolWithProvider) => {
- if (currentType === 'all')
- return true
- else
- return toolWithProvider.type === currentType
- }).filter((toolWithProvider) => {
- if (!currentCategory)
- return true
- else
- return toolWithProvider.labels.includes(currentCategory)
- }).filter((toolWithProvider) => {
- return (
- isMatchingKeywords(toolWithProvider.name, keywords)
- || toolWithProvider.tools.some((tool) => {
- return Object.values(tool.label).some((label) => {
- return isMatchingKeywords(label, keywords)
- })
- })
- )
- })
- }, [currentType, currentCategory, toolList, keywords])
-
- const {
- modelConfig,
- setModelConfig,
- } = useContext(ConfigContext)
-
- const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false)
- const doCreateCustomToolCollection = async (data: CustomCollectionBackend) => {
- await createCustomCollection(data)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- setIsShowEditCustomCollectionModal(false)
- getAllTools()
- }
- const [showSettingAuth, setShowSettingAuth] = useState(false)
- const [collection, setCollection] = useState()
- const toolSelectHandle = (collection: Collection, tool: Tool) => {
- const parameters: Record = {}
- if (tool.parameters) {
- tool.parameters.forEach((item) => {
- parameters[item.name] = ''
- })
- }
-
- const nexModelConfig = produce(modelConfig, (draft: ModelConfig) => {
- draft.agentConfig.tools.push({
- provider_id: collection.id || collection.name,
- provider_type: collection.type as CollectionType,
- provider_name: collection.name,
- tool_name: tool.name,
- tool_label: tool.label[locale] || tool.label[locale.replaceAll('-', '_')],
- tool_parameters: parameters,
- enabled: true,
- })
- })
- setModelConfig(nexModelConfig)
- }
- const authSelectHandle = (provider: Collection) => {
- setCollection(provider)
- setShowSettingAuth(true)
- }
- const updateBuiltinAuth = async (value: Record) => {
- if (!collection)
- return
- await updateBuiltInToolCredential(collection.name, value)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- await getAllTools()
- setShowSettingAuth(false)
- }
- const removeBuiltinAuth = async () => {
- if (!collection)
- return
- await removeBuiltInToolCredential(collection.name)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- await getAllTools()
- setShowSettingAuth(false)
- }
-
- useMount(() => {
- getAllTools()
- })
-
- return (
- <>
-
-
-
-
-
{t('tools.addTool')}
-
-
-
-
-
-
-
-
-
-
-
-
- handleKeywordsChange(e.target.value)}
- onClear={() => handleKeywordsChange('')}
- />
-
-
-
-
-
-
- {listLoading && (
-
-
-
- )}
- {!listLoading && (
-
- )}
-
-
-
- {isShowEditCollectionToolModal && (
- setIsShowEditCustomCollectionModal(false)}
- onAdd={doCreateCustomToolCollection}
- />
- )}
- {showSettingAuth && collection && (
- setShowSettingAuth(false)}
- onSaved={updateBuiltinAuth}
- onRemove={removeBuiltinAuth}
- />
- )}
- >
-
- )
-}
-export default React.memo(AddToolModal)
diff --git a/web/app/components/tools/add-tool-modal/tools.tsx b/web/app/components/tools/add-tool-modal/tools.tsx
deleted file mode 100644
index 20f7e6b0da..0000000000
--- a/web/app/components/tools/add-tool-modal/tools.tsx
+++ /dev/null
@@ -1,158 +0,0 @@
-import {
- memo,
- useCallback,
-} from 'react'
-import { basePath } from '@/utils/var'
-import { useTranslation } from 'react-i18next'
-import {
- RiAddLine,
-} from '@remixicon/react'
-import cn from '@/utils/classnames'
-import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows'
-import { Check } from '@/app/components/base/icons/src/vender/line/general'
-import { Tag01 } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
-import type { ToolWithProvider } from '@/app/components/workflow/types'
-import { BlockEnum } from '@/app/components/workflow/types'
-import BlockIcon from '@/app/components/workflow/block-icon'
-import Tooltip from '@/app/components/base/tooltip'
-import Button from '@/app/components/base/button'
-import { useGetLanguage } from '@/context/i18n'
-import { useStore as useLabelStore } from '@/app/components/tools/labels/store'
-import Empty from '@/app/components/tools/add-tool-modal/empty'
-import type { Tool } from '@/app/components/tools/types'
-import { CollectionType } from '@/app/components/tools/types'
-import type { AgentTool } from '@/types/app'
-import { MAX_TOOLS_NUM } from '@/config'
-import type { TypeWithI18N } from '@/app/components/header/account-setting/model-provider-page/declarations'
-import { renderI18nObject } from '@/i18n-config'
-
-const resolveI18nText = (value: TypeWithI18N | string | undefined, language: string): string => {
- if (!value)
- return ''
- return typeof value === 'string' ? value : renderI18nObject(value, language)
-}
-
-type ToolsProps = {
- showWorkflowEmpty: boolean
- tools: ToolWithProvider[]
- addedTools: AgentTool[]
- onSelect: (provider: ToolWithProvider, tool: Tool) => void
- onAuthSetup: (provider: ToolWithProvider) => void
-}
-const Blocks = ({
- showWorkflowEmpty,
- tools,
- addedTools,
- onSelect,
- onAuthSetup,
-}: ToolsProps) => {
- const { t } = useTranslation()
- const language = useGetLanguage()
- const labelList = useLabelStore(s => s.labelList)
- const addable = addedTools.length < MAX_TOOLS_NUM
-
- const renderGroup = useCallback((toolWithProvider: ToolWithProvider) => {
- const list = toolWithProvider.tools
- const needAuth = toolWithProvider.allow_delete && !toolWithProvider.is_team_authorization && toolWithProvider.type === CollectionType.builtIn
-
- return (
-
-
- {list.map((tool) => {
- const labelContent = (() => {
- if (!tool.labels)
- return ''
- return tool.labels.map((name) => {
- const label = labelList.find(item => item.name === name)
- return resolveI18nText(label?.label, language)
- }).filter(Boolean).join(', ')
- })()
- const added = !!addedTools?.find(v => v.provider_id === toolWithProvider.id && v.provider_type === toolWithProvider.type && v.tool_name === tool.name)
- return (
-
-
- {resolveI18nText(tool.label, language)}
- {resolveI18nText(tool.description, language)}
- {tool.labels?.length > 0 && (
-
- )}
-
- )}
- >
-
-
-
{resolveI18nText(tool.label, language)}
- {!needAuth && added && (
-
-
- {t('tools.addToolModal.added').toLocaleUpperCase()}
-
- )}
- {!needAuth && !added && addable && (
-
- )}
- {needAuth && (
-
- )}
-
-
- )
- })}
-
- )
- }, [addable, language, t, labelList, addedTools, onAuthSetup, onSelect])
-
- return (
-
- {!tools.length && !showWorkflowEmpty && (
-
{t('workflow.tabs.noResult')}
- )}
- {!tools.length && showWorkflowEmpty && (
-
-
-
- )}
- {!!tools.length && tools.map(renderGroup)}
-
- )
-}
-
-export default memo(Blocks)
diff --git a/web/app/components/tools/add-tool-modal/type.tsx b/web/app/components/tools/add-tool-modal/type.tsx
deleted file mode 100644
index 26e78a7525..0000000000
--- a/web/app/components/tools/add-tool-modal/type.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client'
-import { useTranslation } from 'react-i18next'
-import cn from '@/utils/classnames'
-import { Exchange02, FileCode } from '@/app/components/base/icons/src/vender/line/others'
-
-type Props = {
- value: string
- onSelect: (type: string) => void
-}
-
-const Types = ({
- value,
- onSelect,
-}: Props) => {
- const { t } = useTranslation()
-
- return (
-
-
onSelect('builtin')}>
-
-
{t('tools.type.builtIn')}
-
-
onSelect('api')}>
-
- {t('tools.type.custom')}
-
-
onSelect('workflow')}>
-
- {t('tools.type.workflow')}
-
-
- )
-}
-export default Types
diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx
index 1679b4469b..01f9f09127 100644
--- a/web/app/components/tools/provider-list.tsx
+++ b/web/app/components/tools/provider-list.tsx
@@ -11,7 +11,7 @@ import Input from '@/app/components/base/input'
import ProviderDetail from '@/app/components/tools/provider/detail'
import Empty from '@/app/components/plugins/marketplace/empty'
import CustomCreateCard from '@/app/components/tools/provider/custom-create-card'
-import WorkflowToolEmpty from '@/app/components/tools/add-tool-modal/empty'
+import WorkflowToolEmpty from '@/app/components/tools/provider/empty'
import Card from '@/app/components/plugins/card'
import CardMoreInfo from '@/app/components/plugins/card/card-more-info'
import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel'
diff --git a/web/app/components/tools/add-tool-modal/empty.tsx b/web/app/components/tools/provider/empty.tsx
similarity index 100%
rename from web/app/components/tools/add-tool-modal/empty.tsx
rename to web/app/components/tools/provider/empty.tsx
diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx
index c62f6a67f9..66d880d994 100644
--- a/web/app/components/workflow/block-selector/tools.tsx
+++ b/web/app/components/workflow/block-selector/tools.tsx
@@ -4,7 +4,7 @@ import IndexBar, { groupItems } from './index-bar'
import type { ToolDefaultValue, ToolValue } from './types'
import type { ToolTypeEnum } from './types'
import { ViewType } from './view-type-select'
-import Empty from '@/app/components/tools/add-tool-modal/empty'
+import Empty from '@/app/components/tools/provider/empty'
import { useGetLanguage } from '@/context/i18n'
import ToolListTreeView from './tool/tool-list-tree-view/list'
import ToolListFlatView from './tool/tool-list-flat-view/list'
diff --git a/web/i18n/de-DE/tools.ts b/web/i18n/de-DE/tools.ts
index 8aef8e87f9..4e93b4b71e 100644
--- a/web/i18n/de-DE/tools.ts
+++ b/web/i18n/de-DE/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Werkzeuge',
createCustomTool: 'Eigenes Werkzeug erstellen',
type: {
- all: 'Alle',
builtIn: 'Integriert',
custom: 'Benutzerdefiniert',
workflow: 'Arbeitsablauf',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'Nach der Konfiguration der Anmeldeinformationen können alle Mitglieder im Arbeitsbereich dieses Werkzeug beim Orchestrieren von Anwendungen nutzen.',
},
includeToolNum: '{{num}} Werkzeuge inkludiert',
- addTool: 'Werkzeug hinzufügen',
createTool: {
title: 'Eigenes Werkzeug erstellen',
editAction: 'Konfigurieren',
@@ -143,9 +141,7 @@ const translation = {
addToolModal: {
type: 'Art',
category: 'Kategorie',
- add: 'hinzufügen',
added: 'zugefügt',
- manageInTools: 'Verwalten in Tools',
custom: {
title: 'Kein benutzerdefiniertes Werkzeug verfügbar',
tip: 'Benutzerdefiniertes Werkzeug erstellen',
diff --git a/web/i18n/en-US/tools.ts b/web/i18n/en-US/tools.ts
index ec78aa2084..308d4b2b05 100644
--- a/web/i18n/en-US/tools.ts
+++ b/web/i18n/en-US/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Create Custom Tool',
customToolTip: 'Learn more about Dify custom tools',
type: {
- all: 'All',
builtIn: 'Tools',
custom: 'Custom',
workflow: 'Workflow',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'After configuring credentials, all members within the workspace can use this tool when orchestrating applications.',
},
includeToolNum: '{{num}} {{action}} included',
- addTool: 'Add Tool',
addToolModal: {
type: 'type',
category: 'category',
- add: 'add',
added: 'added',
- manageInTools: 'Manage in Tools',
custom: {
title: 'No custom tool available',
tip: 'Create a custom tool',
diff --git a/web/i18n/es-ES/tools.ts b/web/i18n/es-ES/tools.ts
index 304247aee9..f85a44882e 100644
--- a/web/i18n/es-ES/tools.ts
+++ b/web/i18n/es-ES/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Crear Herramienta Personalizada',
customToolTip: 'Aprende más sobre las herramientas personalizadas de Dify',
type: {
- all: 'Todas',
builtIn: 'Incorporadas',
custom: 'Personalizadas',
workflow: 'Flujo de Trabajo',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'Después de configurar las credenciales, todos los miembros dentro del espacio de trabajo pueden usar esta herramienta al orquestar aplicaciones.',
},
includeToolNum: '{{num}} herramientas incluidas',
- addTool: 'Agregar Herramienta',
addToolModal: {
type: 'tipo',
category: 'categoría',
- add: 'agregar',
added: 'agregada',
- manageInTools: 'Administrar en Herramientas',
custom: {
title: 'No hay herramienta personalizada disponible',
tip: 'Crear una herramienta personalizada',
diff --git a/web/i18n/fa-IR/tools.ts b/web/i18n/fa-IR/tools.ts
index a6be1d0d42..bc0510341b 100644
--- a/web/i18n/fa-IR/tools.ts
+++ b/web/i18n/fa-IR/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'ایجاد ابزار سفارشی',
customToolTip: 'بیشتر در مورد ابزارهای سفارشی Dify بیاموزید',
type: {
- all: 'همه',
builtIn: 'سفارشی شده',
custom: 'سفارشی',
workflow: 'جریان کار',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'پس از پیکربندی اعتبارنامهها، همه اعضای موجود در فضای کاری میتوانند از این ابزار هنگام هماهنگی برنامهها استفاده کنند.',
},
includeToolNum: '{{num}} ابزار شامل شد',
- addTool: 'افزودن ابزار',
addToolModal: {
type: 'نوع',
category: 'دستهبندی',
- add: 'افزودن',
added: 'افزوده شد',
- manageInTools: 'مدیریت در ابزارها',
custom: {
title: 'هیچ ابزار سفارشی موجود نیست',
tip: 'یک ابزار سفارشی ایجاد کنید',
diff --git a/web/i18n/fr-FR/tools.ts b/web/i18n/fr-FR/tools.ts
index 7c0e4db020..9f296773f2 100644
--- a/web/i18n/fr-FR/tools.ts
+++ b/web/i18n/fr-FR/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Outils',
createCustomTool: 'Créer un Outil Personnalisé',
type: {
- all: 'Tout',
builtIn: 'Intégré',
custom: 'Personnalisé',
workflow: 'Flux de travail',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'Après avoir configuré les identifiants, tous les membres de l\'espace de travail peuvent utiliser cet outil lors de l\'orchestration des applications.',
},
includeToolNum: '{{num}} outils inclus',
- addTool: 'Ajouter un outil',
createTool: {
title: 'Créer un Outil Personnalisé',
editAction: 'Configurer',
@@ -143,9 +141,7 @@ const translation = {
addToolModal: {
type: 'type',
added: 'supplémentaire',
- add: 'ajouter',
category: 'catégorie',
- manageInTools: 'Gérer dans Outils',
custom: {
title: 'Aucun outil personnalisé disponible',
tip: 'Créer un outil personnalisé',
diff --git a/web/i18n/hi-IN/tools.ts b/web/i18n/hi-IN/tools.ts
index 6e6dcf0ff6..c606f5f0b3 100644
--- a/web/i18n/hi-IN/tools.ts
+++ b/web/i18n/hi-IN/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'कस्टम उपकरण बनाएं',
customToolTip: 'Dify कस्टम उपकरणों के बारे में और जानें',
type: {
- all: 'सभी',
builtIn: 'निर्मित',
custom: 'कस्टम',
workflow: 'कार्यप्रवाह',
@@ -22,13 +21,10 @@ const translation = {
'प्रमाणिकरण कॉन्फ़िगर करने के बाद, कार्यस्थान के सभी सदस्य इस उपकरण का उपयोग कर सकेंगे।',
},
includeToolNum: '{{num}} उपकरण शामिल हैं',
- addTool: 'उपकरण जोड़ें',
addToolModal: {
type: 'प्रकार',
category: 'श्रेणी',
- add: 'जोड़ें',
added: 'जोड़ा गया',
- manageInTools: 'उपकरणों में प्रबंधित करें',
custom: {
title: 'कोई कस्टम टूल उपलब्ध नहीं है',
tip: 'एक कस्टम टूल बनाएं',
diff --git a/web/i18n/id-ID/tools.ts b/web/i18n/id-ID/tools.ts
index 707594446d..d9866dfb58 100644
--- a/web/i18n/id-ID/tools.ts
+++ b/web/i18n/id-ID/tools.ts
@@ -1,6 +1,5 @@
const translation = {
type: {
- all: 'Semua',
workflow: 'Alur Kerja',
builtIn: 'Perkakas',
custom: 'Adat',
@@ -35,8 +34,6 @@ const translation = {
category: 'golongan',
type: 'jenis',
added: 'Ditambahkan',
- add: 'tambah',
- manageInTools: 'Kelola di Alat',
},
createTool: {
exampleOptions: {
@@ -240,7 +237,6 @@ const translation = {
title: 'Perkakas',
createCustomTool: 'Buat Alat Kustom',
customToolTip: 'Pelajari alat kustom Dify lebih lanjut',
- addTool: 'Tambahkan Alat',
author: 'Oleh',
copyToolName: 'Salin Nama',
howToGet: 'Cara mendapatkan',
diff --git a/web/i18n/it-IT/tools.ts b/web/i18n/it-IT/tools.ts
index 0b8b122518..a81898eff2 100644
--- a/web/i18n/it-IT/tools.ts
+++ b/web/i18n/it-IT/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Crea Strumento Personalizzato',
customToolTip: 'Scopri di più sugli strumenti personalizzati di Dify',
type: {
- all: 'Tutti',
builtIn: 'Integrato',
custom: 'Personalizzato',
workflow: 'Flusso di lavoro',
@@ -22,13 +21,10 @@ const translation = {
'Dopo aver configurato le credenziali, tutti i membri all\'interno del workspace possono utilizzare questo strumento durante l\'orchestrazione delle applicazioni.',
},
includeToolNum: '{{num}} strumenti inclusi',
- addTool: 'Aggiungi Strumento',
addToolModal: {
type: 'tipo',
category: 'categoria',
- add: 'aggiungi',
added: 'aggiunto',
- manageInTools: 'Gestisci in Strumenti',
custom: {
title: 'Nessuno strumento personalizzato disponibile',
tip: 'Crea uno strumento personalizzato',
diff --git a/web/i18n/ja-JP/tools.ts b/web/i18n/ja-JP/tools.ts
index 812b5f3c92..8df59af218 100644
--- a/web/i18n/ja-JP/tools.ts
+++ b/web/i18n/ja-JP/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'カスタムツールを作成する',
customToolTip: 'Dify カスタムツールの詳細',
type: {
- all: 'すべて',
builtIn: 'ツール',
custom: 'カスタム',
workflow: 'ワークフロー',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: '資格情報を構成した後、ワークスペース内のすべてのメンバーがアプリケーションのオーケストレーション時にこのツールを使用できます。',
},
includeToolNum: '{{num}}個のツールが含まれています',
- addTool: 'ツールを追加する',
addToolModal: {
type: 'タイプ',
category: 'カテゴリー',
- add: '追加',
added: '追加済',
- manageInTools: 'ツールリストに移動して管理する',
custom: {
title: 'カスタムツールはありません',
tip: 'カスタムツールを作成する',
diff --git a/web/i18n/ko-KR/tools.ts b/web/i18n/ko-KR/tools.ts
index ddcefe4bd4..6bfed4e859 100644
--- a/web/i18n/ko-KR/tools.ts
+++ b/web/i18n/ko-KR/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: '커스텀 도구 만들기',
customToolTip: 'Dify 커스텀 도구에 대해 더 알아보기',
type: {
- all: '모두',
builtIn: '내장',
custom: '커스텀',
workflow: '워크플로우',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: '자격 증명을 구성한 후에 워크스페이스의 모든 멤버가 이 도구를 사용하여 애플리케이션을 조작할 수 있습니다.',
},
includeToolNum: '{{num}}개의 도구가 포함되어 있습니다',
- addTool: '도구 추가',
addToolModal: {
type: '타입',
category: '카테고리',
- add: '추가',
added: '추가됨',
- manageInTools: '도구에서 관리',
custom: {
title: '사용자 정의 도구 없음',
tip: '사용자 정의 도구 생성',
diff --git a/web/i18n/pl-PL/tools.ts b/web/i18n/pl-PL/tools.ts
index 16fe5037df..fa6c5931e7 100644
--- a/web/i18n/pl-PL/tools.ts
+++ b/web/i18n/pl-PL/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Narzędzia',
createCustomTool: 'Utwórz niestandardowe narzędzie',
type: {
- all: 'Wszystkie',
builtIn: 'Wbudowane',
custom: 'Niestandardowe',
workflow: 'Przepływ pracy',
@@ -21,7 +20,6 @@ const translation = {
'Po skonfigurowaniu poświadczeń wszyscy członkowie w przestrzeni roboczej mogą używać tego narzędzia podczas projektowania aplikacji.',
},
includeToolNum: '{{num}} narzędzi zawarte',
- addTool: 'Dodaj narzędzie',
createTool: {
title: 'Utwórz niestandardowe narzędzie',
editAction: 'Konfiguruj',
@@ -145,11 +143,9 @@ const translation = {
notAuthorized: 'Narzędzie nieautoryzowane',
howToGet: 'Jak uzyskać',
addToolModal: {
- manageInTools: 'Zarządzanie w Narzędziach',
added: 'Dodane',
type: 'typ',
category: 'kategoria',
- add: 'dodawać',
custom: {
title: 'Brak dostępnego narzędzia niestandardowego',
tip: 'Utwórz narzędzie niestandardowe',
diff --git a/web/i18n/pt-BR/tools.ts b/web/i18n/pt-BR/tools.ts
index 66b040275d..6d5344b11b 100644
--- a/web/i18n/pt-BR/tools.ts
+++ b/web/i18n/pt-BR/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Ferramentas',
createCustomTool: 'Criar Ferramenta Personalizada',
type: {
- all: 'Todas',
builtIn: 'Integradas',
custom: 'Personalizadas',
workflow: 'Fluxo de trabalho',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'Após configurar as credenciais, todos os membros do espaço de trabalho podem usar essa ferramenta ao orquestrar aplicativos.',
},
includeToolNum: '{{num}} ferramentas incluídas',
- addTool: 'Adicionar Ferramenta',
createTool: {
title: 'Criar Ferramenta Personalizada',
editAction: 'Configurar',
@@ -143,9 +141,7 @@ const translation = {
addToolModal: {
category: 'categoria',
type: 'tipo',
- add: 'adicionar',
added: 'Adicionado',
- manageInTools: 'Gerenciar em Ferramentas',
custom: {
title: 'Nenhuma ferramenta personalizada disponível',
tip: 'Crie uma ferramenta personalizada',
diff --git a/web/i18n/ro-RO/tools.ts b/web/i18n/ro-RO/tools.ts
index 72c3954c97..c9eeb29d97 100644
--- a/web/i18n/ro-RO/tools.ts
+++ b/web/i18n/ro-RO/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Instrumente',
createCustomTool: 'Creează Instrument Personalizat',
type: {
- all: 'Toate',
builtIn: 'Incorporat',
custom: 'Personalizat',
workflow: 'Flux de lucru',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'După configurarea credențialelor, toți membrii din spațiul de lucru pot utiliza acest instrument la orchestrarea aplicațiilor.',
},
includeToolNum: '{{num}} instrumente incluse',
- addTool: 'Adaugă Instrument',
createTool: {
title: 'Creează Instrument Personalizat',
editAction: 'Configurează',
@@ -143,8 +141,6 @@ const translation = {
addToolModal: {
added: 'adăugat',
category: 'categorie',
- manageInTools: 'Gestionați în Instrumente',
- add: 'adăuga',
type: 'tip',
custom: {
title: 'Niciun instrument personalizat disponibil',
diff --git a/web/i18n/ru-RU/tools.ts b/web/i18n/ru-RU/tools.ts
index 7ee263657d..48de76e383 100644
--- a/web/i18n/ru-RU/tools.ts
+++ b/web/i18n/ru-RU/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Создать пользовательский инструмент',
customToolTip: 'Узнать больше о пользовательских инструментах Dify',
type: {
- all: 'Все',
builtIn: 'Встроенные',
custom: 'Пользовательские',
workflow: 'Рабочий процесс',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'После настройки учетных данных все участники рабочего пространства смогут использовать этот инструмент при оркестровке приложений.',
},
includeToolNum: 'Включено {{num}} инструментов',
- addTool: 'Добавить инструмент',
addToolModal: {
type: 'тип',
category: 'категория',
- add: 'добавить',
added: 'добавлено',
- manageInTools: 'Управлять в инструментах',
custom: {
title: 'Нет доступного пользовательского инструмента',
tip: 'Создать пользовательский инструмент',
diff --git a/web/i18n/sl-SI/tools.ts b/web/i18n/sl-SI/tools.ts
index cae126d99d..f8dd1dc831 100644
--- a/web/i18n/sl-SI/tools.ts
+++ b/web/i18n/sl-SI/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Ustvari prilagojeno orodje',
customToolTip: 'Izvedite več o prilagojenih orodjih Dify',
type: {
- all: 'Vsa',
builtIn: 'Vgrajena',
custom: 'Prilagojena',
workflow: 'Potek dela',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'Po konfiguraciji poverilnic bodo vsi člani znotraj delovnega prostora lahko uporabljali to orodje pri orkestraciji aplikacij.',
},
includeToolNum: 'Vključeno {{num}} orodij',
- addTool: 'Dodaj orodje',
addToolModal: {
type: 'tip',
category: 'kategorija',
- add: 'dodaj',
added: 'dodano',
- manageInTools: 'Upravljaj v Orodjih',
custom: {
title: 'Žiadne prispôsobené nástroje nie sú k dispozícii',
tip: 'Vytvorte prispôsobený nástroj',
diff --git a/web/i18n/th-TH/tools.ts b/web/i18n/th-TH/tools.ts
index 848a3f51b6..47e160c9e9 100644
--- a/web/i18n/th-TH/tools.ts
+++ b/web/i18n/th-TH/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'สร้างเครื่องมือที่กําหนดเอง',
customToolTip: 'เรียนรู้เพิ่มเติมเกี่ยวกับเครื่องมือแบบกําหนดเองของ Dify',
type: {
- all: 'ทั้งหมด',
builtIn: 'ในตัว',
custom: 'ธรรมเนียม',
workflow: 'เวิร์กโฟลว์',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'หลังจากกําหนดค่าข้อมูลประจําตัวแล้ว สมาชิกทั้งหมดภายในพื้นที่ทํางานสามารถใช้เครื่องมือนี้เมื่อประสานงานแอปพลิเคชันได้',
},
includeToolNum: '{{num}} รวมเครื่องมือ',
- addTool: 'เพิ่มเครื่องมือ',
addToolModal: {
type: 'ประเภท',
category: 'ประเภท',
- add: 'เพิ่ม',
added: 'เพิ่ม',
- manageInTools: 'จัดการในเครื่องมือ',
custom: {
title: 'ไม่มีเครื่องมือกำหนดเอง',
tip: 'สร้างเครื่องมือกำหนดเอง',
diff --git a/web/i18n/tr-TR/tools.ts b/web/i18n/tr-TR/tools.ts
index ccc97fef10..12849b1879 100644
--- a/web/i18n/tr-TR/tools.ts
+++ b/web/i18n/tr-TR/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: 'Özel Araç Oluştur',
customToolTip: 'Dify özel araçları hakkında daha fazla bilgi edinin',
type: {
- all: 'Hepsi',
builtIn: 'Yerleşik',
custom: 'Özel',
workflow: 'Workflow',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: 'Kimlik bilgilerini yapılandırdıktan sonra, çalışma alanındaki tüm üyeler uygulamaları düzenlerken bu aracı kullanabilir.',
},
includeToolNum: '{{num}} araç dahil',
- addTool: 'Araç Ekle',
addToolModal: {
type: 'Tür',
category: 'Kategori',
- add: 'Ekle',
added: 'Eklendi',
- manageInTools: 'Araçlarda Yönet',
custom: {
title: 'Mevcut özel araç yok',
tip: 'Özel bir araç oluşturun',
diff --git a/web/i18n/uk-UA/tools.ts b/web/i18n/uk-UA/tools.ts
index 40e35a1236..3a3f72b5ba 100644
--- a/web/i18n/uk-UA/tools.ts
+++ b/web/i18n/uk-UA/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Інструменти',
createCustomTool: 'Створити власний інструмент',
type: {
- all: 'Усі',
builtIn: 'Вбудовані',
custom: 'Користувацькі',
workflow: 'Робочий процес',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'Після налаштування облікових даних усі члени робочого простору можуть використовувати цей інструмент під час оркестрування програм.',
},
includeToolNum: '{{num}} інструмент(ів) включено',
- addTool: 'Додати інструмент ',
createTool: {
title: 'Створити власний інструмент',
editAction: 'Налаштування',
@@ -142,10 +140,8 @@ const translation = {
howToGet: 'Як отримати',
addToolModal: {
category: 'категорія',
- add: 'Додати',
added: 'Додано',
type: 'тип',
- manageInTools: 'Керування в інструментах',
custom: {
title: 'Немає доступного користувацького інструмента',
tip: 'Створити користувацький інструмент',
diff --git a/web/i18n/vi-VN/tools.ts b/web/i18n/vi-VN/tools.ts
index 08041ce400..a499a451a3 100644
--- a/web/i18n/vi-VN/tools.ts
+++ b/web/i18n/vi-VN/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: 'Công cụ',
createCustomTool: 'Tạo công cụ tùy chỉnh',
type: {
- all: 'Tất cả',
builtIn: 'Tích hợp sẵn',
custom: 'Tùy chỉnh',
workflow: 'Quy trình làm việc',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: 'Sau khi cấu hình thông tin đăng nhập, tất cả thành viên trong không gian làm việc có thể sử dụng công cụ này khi triển khai ứng dụng.',
},
includeToolNum: 'Bao gồm {{num}} công cụ',
- addTool: 'Thêm công cụ',
createTool: {
title: 'Tạo công cụ tùy chỉnh',
editAction: 'Cấu hình',
@@ -142,9 +140,7 @@ const translation = {
howToGet: 'Cách nhận',
addToolModal: {
category: 'loại',
- manageInTools: 'Quản lý trong Công cụ',
type: 'kiểu',
- add: 'thêm',
added: 'Thêm',
custom: {
title: 'Không có công cụ tùy chỉnh nào',
diff --git a/web/i18n/zh-Hans/tools.ts b/web/i18n/zh-Hans/tools.ts
index ce203a0592..cab4b22164 100644
--- a/web/i18n/zh-Hans/tools.ts
+++ b/web/i18n/zh-Hans/tools.ts
@@ -3,7 +3,6 @@ const translation = {
createCustomTool: '创建自定义工具',
customToolTip: '了解更多关于 Dify 自定义工具的信息',
type: {
- all: '全部',
builtIn: '工具',
custom: '自定义',
workflow: '工作流',
@@ -21,13 +20,10 @@ const translation = {
setupModalTitleDescription: '配置凭据后,工作区中的所有成员都可以在编排应用程序时使用此工具。',
},
includeToolNum: '包含 {{num}} 个 {{action}}',
- addTool: '添加工具',
addToolModal: {
type: '类型',
category: '类别',
- add: '添加',
added: '已添加',
- manageInTools: '去工具列表管理',
custom: {
title: '没有可用的自定义工具',
tip: '创建自定义工具',
diff --git a/web/i18n/zh-Hant/tools.ts b/web/i18n/zh-Hant/tools.ts
index d9aa901278..246d2d9dd5 100644
--- a/web/i18n/zh-Hant/tools.ts
+++ b/web/i18n/zh-Hant/tools.ts
@@ -2,7 +2,6 @@ const translation = {
title: '工具',
createCustomTool: '建立自定義工具',
type: {
- all: '全部',
builtIn: '內建',
custom: '自定義',
workflow: '工作流',
@@ -20,7 +19,6 @@ const translation = {
setupModalTitleDescription: '配置憑據後,工作區中的所有成員都可以在編排應用程式時使用此工具。',
},
includeToolNum: '包含 {{num}} 個工具',
- addTool: '新增工具',
createTool: {
title: '建立自定義工具',
editAction: '編輯',
@@ -141,10 +139,8 @@ const translation = {
notAuthorized: '工具未授權',
howToGet: '如何獲取',
addToolModal: {
- add: '加',
type: '類型',
added: '新增',
- manageInTools: '在工具中管理',
category: '類別',
custom: {
title: '沒有可用的自訂工具',
diff --git a/web/service/tools.ts b/web/service/tools.ts
index 6a88d8d567..2897ccac12 100644
--- a/web/service/tools.ts
+++ b/web/service/tools.ts
@@ -8,8 +8,6 @@ import type {
WorkflowToolProviderRequest,
WorkflowToolProviderResponse,
} from '@/app/components/tools/types'
-import type { ToolWithProvider } from '@/app/components/workflow/types'
-import type { Label } from '@/app/components/tools/labels/constant'
import { buildProviderQuery } from './_tools_util'
export const fetchCollectionList = () => {
@@ -112,26 +110,6 @@ export const testAPIAvailable = (payload: any) => {
})
}
-export const fetchAllBuiltInTools = () => {
- return get('/workspaces/current/tools/builtin')
-}
-
-export const fetchAllCustomTools = () => {
- return get('/workspaces/current/tools/api')
-}
-
-export const fetchAllWorkflowTools = () => {
- return get('/workspaces/current/tools/workflow')
-}
-
-export const fetchAllMCPTools = () => {
- return get('/workspaces/current/tools/mcp')
-}
-
-export const fetchLabelList = () => {
- return get