From e81a9c438c71226c909cfd7005de6962bb138cb5 Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:04:15 +0800 Subject: [PATCH 1/8] Add Mihomo Control plugin Monitor and control a Mihomo (Clash Meta) external controller from the bar: live traffic graph, proxy mode, proxy-group management with latency tests, and core restart. Works locally (127.0.0.1) or remotely via host/port/secret settings. --- mihomo-control/README.md | 94 +++++ mihomo-control/icon-connecting.png | Bin 0 -> 25303 bytes mihomo-control/icon-offline.png | Bin 0 -> 23950 bytes mihomo-control/icon-online.png | Bin 0 -> 24491 bytes mihomo-control/icon.png | Bin 0 -> 14428 bytes mihomo-control/panel.luau | 434 +++++++++++++++++++++ mihomo-control/plugin.toml | 94 +++++ mihomo-control/service.luau | 567 ++++++++++++++++++++++++++++ mihomo-control/shortcut.luau | 33 ++ mihomo-control/thumbnail.webp | Bin 0 -> 17120 bytes mihomo-control/translations/en.json | 90 +++++ mihomo-control/widget.luau | 100 +++++ 12 files changed, 1412 insertions(+) create mode 100644 mihomo-control/README.md create mode 100644 mihomo-control/icon-connecting.png create mode 100644 mihomo-control/icon-offline.png create mode 100644 mihomo-control/icon-online.png create mode 100644 mihomo-control/icon.png create mode 100644 mihomo-control/panel.luau create mode 100644 mihomo-control/plugin.toml create mode 100644 mihomo-control/service.luau create mode 100644 mihomo-control/shortcut.luau create mode 100644 mihomo-control/thumbnail.webp create mode 100644 mihomo-control/translations/en.json create mode 100644 mihomo-control/widget.luau diff --git a/mihomo-control/README.md b/mihomo-control/README.md new file mode 100644 index 00000000..ad13d321 --- /dev/null +++ b/mihomo-control/README.md @@ -0,0 +1,94 @@ +# Mihomo Control + +Monitor and control a Mihomo (Clash Meta) instance right from the Noctalia +bar: live traffic, proxy mode, proxy-group selection, latency tests and active +connections. It talks to the Mihomo external controller, which can run on this +machine (`127.0.0.1`) or on a remote host — just configure the IP, port and +secret. + +## Plugin + +| Field | Value | +| ------- | --------------------------- | +| ID | `mdj2812/mihomo-control` | +| Entries | Bar widget: `widget`; panel: `panel`; service: `service`; shortcut: `mode` | + +## Usage + +Add the **Mihomo Control** widget from the Add-widget picker. It shows the +current proxy mode (rule / global / direct); hover it for the connection +status, live download and upload rates, connection count and each proxy +group's current selection. Left-click the widget to toggle the control panel, +or open it with: + +```sh +noctalia msg panel-toggle mdj2812/mihomo-control:panel +``` + +The panel lets you switch the proxy mode (rule / global / direct), restart the +server, refresh the status, and manage every proxy group. Each group card +lists all of its members with their latency — sourced from mihomo's health +checks and refreshed by the group's **Test latency** button. Each card also +shows an overall latency (the selected member's, or the best tested one) right +in its subtitle, visible without expanding. Member lists are collapsed by +default; click a group header to expand it. Click a member to select it; the +current selection is marked with a dot. + +Add the **Mihomo: Rule** shortcut from Settings → Control Center shortcuts to +quickly toggle between rule and global mode. + +Before the widget shows anything, enable the plugin's `service` entry — it owns +all communication with the external controller and streams the traffic data. + +## Settings + +| Setting | Type | Default | Description | +| ------------------- | ------- | ------------ | --------------------------------------------------------------------------- | +| Host | string | `127.0.0.1` | Hostname or IP of the Mihomo external controller. | +| Port | string | `9090` | Port of the Mihomo external controller. | +| Secret | string | *(empty)* | `secret` from your Mihomo config; empty when authentication is disabled. | +| HTTPS | bool | off | Use `https://` (external-controller-tls or a TLS reverse proxy). | +| Allow insecure TLS | bool | off | Skip certificate verification for self-signed TLS controllers. | +| Test URL | string | `https://www.gstatic.com/generate_204` | URL used for latency tests; empty uses each group's configured test URL. | +| Refresh interval | int | `2` | Seconds between status polls (1–60); traffic rates stream in real time. | + +## IPC + +The service exposes two IPC events for scripting and debugging: + +```sh +noctalia msg plugin mdj2812/mihomo-control:service all refresh +noctalia msg plugin mdj2812/mihomo-control:service all cmd '{"op":"mode","mode":"global"}' +``` + +`refresh` re-polls version, config, connections and proxy groups. `cmd` accepts +the same command tables the panel sends (`mode`, `select`, `delay_test`, +`restart`, `close_connections`, `refresh`). + +## Notes + +- The plugin only talks HTTP to the configured external controller. It spawns + no processes, runs no external commands, and writes no files. +- The bar widget and card use the Clash cat logo (`icon.png`), the official + mascot of the Clash / mihomo project. In the bar widget the cat is tinted by + connection status: green online, amber while connecting, red offline; the + panel uses the neutral logo next to its own status indicator. +- The traffic rate uses mihomo's streaming `GET /traffic` endpoint; status, + connections and proxy groups are polled every refresh interval. +- The secret is stored in your Noctalia config and sent as the standard + `Authorization: Bearer ` header. It is sent in plain text unless + HTTPS is enabled — use HTTPS for remote controllers. +- **Restart** posts to `/restart`, which re-executes the core; the plugin + reconnects automatically once it is back. There is no API endpoint that + stops the core — switching the mode to `direct` is the closest equivalent. +- A latency test where every node fails is reported as *all nodes timed out*: + mihomo answers the delay endpoint with HTTP 504 in that case. If that keeps + happening, set **Test URL** to an endpoint your network can reach. + +## Development + +- `service.luau` — headless API backend, publishes `mihomo.*` state. +- `widget.luau` — bar widget (rates + tooltip). +- `panel.luau` — control panel. +- `shortcut.luau` — rule/global mode toggle. +- `translations/` — user-facing strings. diff --git a/mihomo-control/icon-connecting.png b/mihomo-control/icon-connecting.png new file mode 100644 index 0000000000000000000000000000000000000000..b48ff0d17e1f781ae81e12adbba61a531f65ce17 GIT binary patch literal 25303 zcmeEt_dk_?{P%T^y@`-5GRh2DaSjs7j6&HXS=oD>BSOh2vRB#Jl|7CSva_=@vbW9nxq_wnoG#QBD02MuP z6_to@SjbTSpf=|C+fDJ->@R8CnO}N)1AQK22z9@oDWQ9Mx669>`ovM#50c>B{{PSa zn-V}mW>@Thw>@gyN{t;~rzYs|QO4rbisAtO>Zf=vc_qomAyOfG-?yW z@_B}ugf1v_d)wOTv9oIeOXk~COAGHit|kEz)S5`bcuwo7IHyLi+@bpJw^sL(gP7!> z&i=kCPcPTl*c@zbej5KcsH8P(%&CFpt|CTS`(Gd~K6!DQnD1hx@~Gw4MqR$m zw7$lT@d->+h6RK5B=>Zys>p_bRxc9X#X50&up=>wh}LRa#;jO#Y413$?7C z{mW54tD(~PUHnR<3&(wi{d4iI8%I>U;F81RtjgvH0Z0HQE@KHjnU}Q-zZd=v0J*OH ze}F?DCc(wtTYU?17b`Vc`cU}O;cwn2zno``nV%92ecB0V5`zLr zUh{tGQ*cx`_9)4LA-X0KUC>?mn^m;SSj9=VbZw}gz#dpTwkG-p+7z63=KD4JQ#$-n zE`YqPZ{FP4n9-bjK_ehjIDe;nT;$#Y_hN{&Mn-?FZ~H?_kh=7SfEOdUXutU29r|Bq@`K#UgI^Hia#*&5{AO+=}Y~|Vx#z_w1)-UDKeX4>e-+&XSj~ zni^${u`#BD4&WyNNh>WaFeIPjT6v;dzBh*ctSw61d#0iC!?eeU8Y2 zV0PBi0eH~A%R>0#yZ@2_AE2Ow+4`1}=e&HW`w1yH02^pj7+X4&S~ll3e-=B`yf41U zL{1$H(`{d%^ICi!56*fc-T&9=iLEwUY>VgMe zlopgPH05zW>ckhKd?4^EAl%p0jt(52mCikzz!0O~YIhlh2bw}!#JZWe3+>G$nE+^2 zHg@`_;mW}hlifhep*RFJ40&)AJaZU#8-%RPDzRnkeF0=4J ztcsF^lgnBLfo_5dc+W||W{YRF$sRjy)b8Zj1;ERZ^_Qq;>$SKC$OMzfz``mi5j6~P zP7Db=H&!-p^`W8~Can^e7uJSaWrq*M->NzVw)XYfY)R|9|GCc;O$GAXu8{rV&Ww%u zwXyIA^vbEKB!r(uITw3Yo+P-nzx}vm`-8OA*Asix%PhPFNvd|EMy6xr(L`Jv`kJ#A z10p(px8tzvH}v(jZ?x5BEp+Jv`yxgQr~OofBo6h_INkD&CT=J+jQ{eQ5zQGp+26*q zcJ1PNDkgo-W=Gs?gaEV9fQ{sT57ulQ^&Y%=c0?Fx)r-MPe=EI0!g<6%JH)V|SN_y|*F^+idd+V! z89Aj?jlrg!A&BU<4>C{ucCd#8t%(wouZlvqt*CpT2b*3;f`7@$mo7~VZ8yWQ+2Hpl zO?8DIa$j2b_OGO)cQvY>wE3%0F7V~RE|}99t|-1w9mS9JrP1StYN&2uZ0zCmWFYU0 zX^~PPWN_Z#qK&mbi|02c_v$HrytH_RBPOv8gSAa*Ut~N@bHhE?7kVS|XQjP8fMD+k zYN_r2E+3{v;_kmBx0tvYsvI$PO8H~{Z~zu?AS=Nnp{#-kWIEP}{!abiO&A}~e?Xg& z!Rs)3D@sF8e~N$Dn&y5r&N9Otw7JDX*G?&Mu7Y^7m9?;$F|Tz-WjZ7HkaV7ccafaj zhKK}s7fH0J&)~%*z^Vq}8|b`L#`ve`m(4v%!u0u8Q%Xg9i8{I|-gk-}!iSs{wD|4f{ zPX$UuzrH2)51JgQ9BXcITEV!Ij+m^gh=*4D`=A$cLJp^WsY%}1?GZX!;zG&@DNhL% zF!-=jtB2%)sShXQmj4No0=&ehT#NoQhqXOV7Y9CQZa(qK2IHc$=SSk!xAaTz`+64aQKlkJdYr~ zw{cL~#z5Z*0X2N~N?V1zR6Qo|+7)^=E=r`@;)`Rv)|()_qH(BCE{6Nynr1uP1+vH0 z81%+Rqs=<1AGiSp*HJSKWhMi@18F}5{C-jNxgDVLbxm5oQLk{N4)PjE)HV;FbIK7X zXWXh3**i$Spb6nx)q{JttAlXEoKJfps!djwb!%0G5F=i_u30CYjU1A z&Lj=9V0#`q6$%PZ@_P|&?{{$*!LnCR`nzAPHnqZuOAVcCf~b;7Nd>^Q>NbJ)pIYur zDo|dd_B;H(TUYyZcy`t6Axi754y7qk$2v}<+;iX?gRgXXJ;b;Bk0PSPgZ?2=c=6?0 zPaty>w01a70nyL1xBOrR-Bx@Bf_pKaiTzW`0vr&h?}u_)=$5~(Zs96pe`qxK3|*&R zWXTn9cCnuJ-isXo0Y8U?eYT|Tx&{)AzP=@SBbUC-APd?OU-#%)()hGd5p0)n!!?Ax zz&bg~mBjXYu*gT62k?MELQ93zWF<<78MtwM1-TZQTx!~DQMp_AcyFEv~-!;^}-oTPUx4?F~yQw->?& zE~plZ%{p^Wd(WH@UOR@}IKpDkT`@?7Tkz@gfi1ne#5}*9yfMG^+1d@lg+SSFoJ@_!2kSo3jeOAhI@|~PVC_sio-ge#Girl zs>f1Uu^S264QO&avAXpL6{LCoO)~pjD$RbNYPRXP;_l9oVm9dreWb%bpCS@`HyDmv zmd_ulM|~t7^7{)W1EYJ_o-xlnc-C!w>pQNkTUY#dt+xH`Gz<#=!ax2aN61ZaX+Ax( z-Yt*?e!KPdeO>|fG)XK%fYo|J!^qduK=MVJ#P#XtEeGaqtKLUnlEM|jxP8s$D>FLF zSKJbt>1|&AeY7mgYWuw+IA*nz1z(h>!J*;e@NOqN^$S<6s{;$8i=gdxg8jiM zW8ThNyY`imgUpSt7tQtu8Skpu-yOuz1#gb4-{E+kfgY@+H7Zg#;M+V}GiO2v#Hc2% z_05Sby!gP~ruLhWY#CHG32!s6)g<;F{lx} z74kd7iOjWDgX#bFbpv1n^;7i)R&=;&hUtdR)Ozg);r1SzzgnM^JQeqO+7k2bV6Uiz z-@k>R!L5Mlla3EHPYsOkd|KO2kZGU&{XZ#pJe0Djtp%yH5*Gw@O3Rxn7Yr>!~FTJ#}`8!*Lf{V zOx>>Y4#}g&cjfEwXM0K^{^e7dXa%Q7j{cAS#V9_}?d_ONAK{r-Z3;B6bZM`Vt~#oD z(<|T2Aj|47RG%F24HR*^l;lgrhqv%F>u%Zm7(Ulggb@k}kQhFB@(QP~2t z^*opEyDR0^qRb}f_D7FqA=OVFKF{e)Y}zDMyca%Te!Yn2Uv?7 zI_F3scF`>72vXAcYc5;TdSXh1GIBpzl^n}+OiSD7=X8vw})AWnx!hX1;sO3507tuFX)eQg_K!a`;(A`?)S&dxj2ixY2#hwp;VX zCx;x-I6hjx={qzj&GBUCc5;bhe-61 zWM~!s8;6o-jUJSog8DNA4C<^%;kXG%Ny+={Y^jMrGGUkAC(uOa7bzyKC9Zwg!pKs8x7ri>i3pOp|gT5 zJ|z5auUyw@I>h<6bVQeug)d3!G zpAy8gc!+x~_^B)rT#-2UPMj0V15P~}Z8^9#`Fb_U4dY13BatJ+$ippqhU~hw+c&-g z{DW0N;{>*Kw2OKwj<>ot{zW zktH}Z8rVDl=tvmrSehJ1eRLQu$%ijf)vQ#{4a5Rqi4-gTC$Emp>&oFUAHM`S z5hcL7NsX+M0Y;Ll?z&9p=1krJgx^2KJbP@yH=8?C8$S}1{Disf1&A>n{a-SX%zc@~=j8Z{{AG1)}iN!H39^hnqiB zeT7gS;t2T3*G80kcioGvDVxplwSVyq%(4J!n;Ilife2nd@TralC1ev`k!F0gG@NCE z2rb2#|EJ?I%%gY6aN9Z$`)f0&K%cWkMrejFMm$v+*Y zOIr*x4_ZqeDLyvc;r*38>=`e&?*GVWXiILAbX9GjayM}FFymjhG(w@P8f!2TmuP9K zMWvHoc?*)2Jcl8&dMBzb4zQAe5YO^P@i(pYUuIVNeCq8e)cEuruk|?=gEsqEg|fvI zSU?6p?sE!knZd}-N1>0eMZ-&#B^YyUQy)sSgYi#CuFd09yUOM5H+S(UUz=l6 zDXPB=-mpXuLY1w`8H@189Ou@e_4R*2mRZZ@6RUI&^!!?PL$yTt3entuvkw)=ccy|I zdqtl^fvcwg(po3hvb?5m-s!g{>J z!+#pP5j}M9y+1MWmMv6L5G17tz+-Htkw3lkaa@t=X!HWD??cm=lei$E*@sfm>Ekya zl{}LZ@Iq}x#VYWBv_HeW6h9kSj~q&_kkzvh0QAE^aKe9eJ-VnZrqy|Ku*+D}U3_xt zJxPW(OO)QXcHA719YCCZ{C!K`LWb;0qE_Ugw2Sz(7n0v{ANnl+wq9Fjb8mQ$ao*SIuF?rgGU%Q? z5<(CMjbc%`nrCzM~IfRfRy$R1-g4l)Uf9;aqrxE&}mn^ZEoad8`J`@4= zg6!7XB$oK!*CHoY)vlTpw)5_IxF^9D&h<1G=#XS4fLWtx5KJBlzGA`;dZ6d3=e;Yc z+D($Zb6L-Ib?)Dj{Pm^#F=PF7p7D_EukaiSGY1>vqdcz3w4Vm}r3nP(z3PPDUoyaI zR-G-lLl_kBe9iHmSxoljC)U*rx|=P<($UvJNjK{Pf=U$~MpkJznS>D4Tb62;juR&A z>zRFP$vp?PALg@E{#+g(!jOCUA6`ePL)MZpwYN z8hMb#<4Qz8PSC-k@8Yydp!wR9G78`>sPuRLj93zD{&2g3T%dSQ(!6n|Cg4g^=t9ZR zi^8{^Q+kaq2yTb8YXdxBSz<+=#Jv$ku0L_qI=3hkrc}tlk~+z(X-W|8MaP>H7s@ZYJ`^pOM;ZSRxjs+N;Q*Rc>2ppBjx^5|)arZQx@U#+H zhOjJB?l2YoRAkr&4@(2Ah+c&8OsXTdvs2%$=8CIE0>RH|BI4gacRtj)3HLthQ^4it zf>u~VvGeMuFTr{q3yL5wxGs4S1DK;s1nE|S$({LqXk12)js&(2bFt4+#)A>^xHE9` zHqb%!knr9sZ=F&u*us%{uMbF?E||}=EE?6f#(IW6f^1=k@*6V6doBCV<5l$0QFCOV z0V2x;RJcsQw!@RWpcuD~FWVp3Ywr0|oCaJw50Uk0r&NHwO8jgPSh#-J0d390c2p9| zM5rE}r-HaxL4dSnG3Bq4BoeAdqee3-=5)^{mvsYC%|S_x*j((-a)OA*sGF@0un4-@ zm0C)x(s}bENKfOZzH=@|D!b9GZ@S`JprC$*qR3%IyHF5pa*!I8!pLuPaV>Q)x?e>q zlsLszT1i0tJ|>tQcBCwLCwW?AP z&@}`|w0s>_t`$3ddnCt{0r#vo%BvN z{-wtGsTu(Gg74$0=(Lbb?#2{*--EsjbSG`)QgtyIDfgT}o;h0;&J4`&_OPtZ?r{4R zsU{&JHen*mb^%_ncIJsoZxF-b?bXjI#415RYJVb)d<8TJbk}h86!HS75Yn(GNqr-6 zGar02vzw2?4^v9Vv+pcw6zGBZH3(^rtFc1YsFmlh$9wSLvS%bgXrnjb}-so4l(S43~VIemlVBb_7>8=@2j1L7Cyww=~3gVxAH zIut(fMse%Im%R_@E1u*v#dAQ+HRg1m){(733b_+x5^=)FuWueRpN6(13VA@=U21_O zPU~}QpRLsgd(ocWi8|m|h;32&IrN=4s3v$rz+Och^F)=cRG$a?quBb8^7ty$IPB!& zc<7J6RYl;%RQ6&uYpi0NEZv}>}LysUS;jp7%0gZ(F?cE$o9bysqMBm^0l~RQ5UDe-a-dw z9Bv>mrG`z(_h|EGleh01Q8Pzs!Emd)o73NbG6E-FwMXGz>3mCf28DjhT8wV(H4=4D zb%iFF;D5N`*>z=JY}$$RmCk)jOSQ5)e+BpEIt1#qw1(RQ71q}zl4?3*q% zKN(@1{L@fWLDkLhFD-71ge#?a&-go*`ddZFQR4hj<)Foj3hx&>KtC9wgSyaP1dN#E z1@ctkPMl{||J|m$lORkHjr_Gt_Arh*dI4%Lmo zxgx8EV?TZA9;dV29^_sanm@rmODlmVd~z11dEi{te|{15&lr7WC>PtR%;GrED`ave zRlZfcx<_z5#g=vxeMs4mzL=2z-^+uF97y~t26A23_OM0ZLAYB_Jbv52_u`qGwWEq7 zZheR|R?KQO#6YtF`xH{1QTSXT)+>6oDDYQVMQoqjKDKo27V%ZoOtoLXrPKCLZR7#i zmSx4?L>iOt?7`t&D_NKwhp3keKSm-)^1n-MFqC%tY-|M%s~gJQzDdyERFFm# z4xw%b30!B%wv^MsD|E5E8o6{hjg(ewhrB*eV)B5HqCf0LpT2K!sR_D5vi;7rew9|Z zW!$nmn~B}!Eu)ag25n5*Vmg!T6Nq#}G7WcW`%k4kh19caTZIFumCOJP96^&NIv!a%+hRWXohAm3Nrh=Kl#J zZ>uQVzS(DIl;L16XjlmNjbhPDUijXZbIWmUQljP4m`@V6i#3_fGmX3{_wn9`oWXa? z5vWqDWBBWEmmR%^11GCY+4g_sJrX zX0!r(#&<+0r9;6N`lAam;zWIQfAy#cwn2Q)iX*JXJMwSpB+4P7ZDhqbsI^&KH?U-2 zBwDyiN`x@Hsqm&fnR%qiAMEsG+12#n3v)FueX$*7uKhu*FmiM3w$G;NM6oKI(J6JQ zWlg6LBQ1hr9^HEUDLLrH+TtNyd4<$X6o_)I zMZm3=RV_lcN6?CJ3hWV`rHpk(W=^g8b(OQICzHa-u#w`Y!xw8KWqx`iRpw*2k-vdy zuFDsF{5LV95cu-`-wH3}wTV*p`ZbQh)Y7dnLwuE5{Bg3Z_fYQ7C2wbRzIiCRKAjtF+nAh?Zizm>+XpLayd#XNZNC!FP*&}3k0xH@ zPy=kiR(itCT~?d&@%8(brs{&$&0Z@{2UKjTvLnTmIxL6hYvoWcGqB4scS0ol3`!e`;W;ILll}g z*8tN!2}Y}65U5A5GovHuM{9S==pZjRyT--hErG;bmCbi@7dYp^%?DBTG;`s*AJ1ap z4O{OgeMw;a-M-o-npLPI;Vi;5sS4}EVG#1K;oHVLX(aSSf5j;8g*AV$V@v`YkUWng=xhExz#!Q)#Y{hsJi%wH zNug)+Ql^~6MGCXU3bY)z)h!Kr+zG6k;+6k?j#WVX$_cZg>=Xxz8Yb+5)=Z63@^(gkaK7JTm+}U6m z)|+E$E+~w68&NLvfA1q>w)eN><;?swd->B@{h&7rVf1ZV;`4SXmKL76%>k7@hx1A< zo)1M2XWi2A>RgKrrYYt2>5?&Cn8*+$}3z4D5diyNXSEnGxy#m>skkvj`Xx@Qse zIZOsh4K{grE>CduQ+WR!vEMuvftckgUN~c5f8jJ{iJgCZvb1dcr-JC){|ydsGV?9= z7LL^{Z!x;OmcpAe%`B(t^=dCY4pY!)41L_G7OC!U6D=UUdItxL<31l2Ml0_MGt_1$ zHVF-j6hh<3Kq@#TV5*j*f9dwkOOEA?yO~Yx1zmw$XU#yg%oA8;*BvoEJ{t~3_^CC} zSo2R^_;4OzKPAH=ct%lCbLP*O)_bxPhYAsX`qGQUf61uoXlvcipNL>S+OKlu zOkZp{XioRWdW;>dhIs52SyU>%r0lgEJRf@ZgWAd<_W0f zTBwQj^Yv-)db<>`lBzDj59*qcdrPDvX`2B;(ZM}DqTUv;3s)f0@bV>$?#TJM4>~@E z_e3#}U8Nq$gv!mmJn_w#mbZogR;g;hmIDSh{~69SNrb*Vo%>3~$q?AdmRcR;BL$LF z*WDtYA51AZkQzcXxIxfrgpp5P>op!l$G&I3S`21rR|)6qYwc`6 z+dn@+of{34)oyu?EvH!;>@WOyYV48EVt2E11G*hC(;XuZ0}*p*t@xr4*yyqMe_7S( zJyh!MsM9g+gBWNS1Ib4!@cb#aS>*wXriH`yucL_@IG>G;IM6hdACi?9Mjytz;kq?% z>_=OkO%KdN(kY|UfIJ$|@NV92Q|XI+xqal^(*IP$oQN~3%Gn1hCtSFya@O61A2`qx z(*E?x5qXrt7UZ|PaQNV91Mrhb4d5xaM+%PFBb9pp{o=M~voQ)|DA-mg5}QLih9Aaj z;4b88dhMI{vF(oO^BMRomCHK($Wv1Pm^y0r1VAe$-*(niYFqO3uK&zMe6{6ij^4MX z1(oEbgIfqz)0BnG#e`WEO0qEZu>1c(W{-SLFBvGZZk0rH<@_>0`%**Mge$MBQmb?0 z_D$~M2>4QN+8@jFI{Z>aA4ulqT7k$3ixF`Ybzi?8+Yre^LW{G@YH!PFY93&!B3M8&?F>odP0&Xyc2xh-{pHp}$5uR{k zQIJb+uy(J2WTkCi6xbA;ZyNjJcOeC-5*l6y6WsiIYWF7s+9r@l8ub3cIbMZx@7x&; zxv{u|z}yjnH1JY0y0f&25t6Rl+QCpSh_NT9Qm-U#4 z?=N90WeBsi@;ho!0d~+v;T(UfQ%ft?8rrx!?!Yp27%SjB(Nv~jU~MS%xYmn6J>wTV z15a93u4#xP3T&z$xT+0);F%9}^VZm7 z;cDv54p|vFSK6+q;yT-YxSj3CX$NLZiU}19Oe!!Q25CC zu#{`EfV&0D@4|gC5-?%$`1MOUyKARgupmeHX%HrFBWDOZ?z}xiIGb%G;k{{WVfs8i z_(X(#8|Pq*Hz+|Q){}qvv%o)M|g|nW=f4&P+J{nXLehbq2 z>akXtL8E19HlYOCF-FWrtRUBQmx+N$VtBQC5meXe=Hd%5pQLA(h4*+P7;>Q$`_|o` zWm^!_)e8oAaL=(^>{KeHTra5QTDHJgBj*}CJM2O`D|;oxv8=1`;leSPQ((i*~tg!=j2K%AUe~Fk?6y`74gmL`i(s7vH>CB zH}{fl*}sYlNaY{{RDd%)QcC zh$N%cF_@L`$3xn_?i{din#YT7ZAH=a!cG;77rx1()Hw;Q&5hnyew%G@{V;0#4OTENA8GfYpI$kt z6I-*ECeHQmd0W30PQTBaUxKuX010NJvK$u2SL-hc+-u`Uwv8Ks)7YQJ*E#uPaul!9 zzauZ!rcdcz`q<_B7D7K#!ipt&#f|*Ce5AZ-F`!!-1$qN|69E316)+fFSb+k!0AS<+C zyz%ImTXi5GFMD;JAupZE@B77zd8cg~WIm540q7Z5AJ0WEGjLHdfI-7$vHB%7@>eJ| zFmUMC%1Lh?Uw{z3Ns81=ZH2v^B%D{|t_sch{mG&<>G*=oBLeHGUs-`hlHa&}=X{=h zNVLXNWtsHx_p>F)#Nxu=5N04jgcLsf8J%wR@BYr?-%-@wXAjd6Nw7bADKdE$go^9P z5@a43Xb4QHfpNQfU)5r$1ic_n%y{@XyUR_ar`p_E;}(vC6We-}844sJ%C=w+&{2Ym zdt}2ePlPrFpOA3yT0wvVTi`hJX=XwHyR2j#@%;>6`iaf6pUN~&ZG3^IQ71rRGTEvI z?$*%558a4mc{i=_3l}9rdB#^4lRWEx*+S^ zRg4EGO7WlJ9Sw?_>>!d@RzN{|^zB#GNuu72%d+O$MNmq)@`ua!Cjnd3Fj6=NHj><~ zpiM(XqGqa4$*z)1uPID##wPwS-VztJz_W;Z`zgT|#4+r@)8QO;&d4v+r=3^Guee*} zadnqW@72E6G?at{@Nl10}n;fYW*P?||$tOOsmo?WVB_{ z9*E{9;=y(<;uLa_k^~MnJuue#P5irbRd^~-oHJx|w z%z)77a96$Rk`+{dL@Y!#`A9O~*iTYh_BF$%nH^fnnwvwwU>q5Ju`o%wcMF{9)9jUfLGS9$X{! zgoG0QCybQrx|$&(f}Zia$ollcHN8Lafkau8UP+F6)@!BQb7-f~F})G&Cu}hxcMWF$ z>VBofRd;F7Ag1bH2J3UKGa)4K9r$x62sztP+^E{4x!MDU+PP;2{8_}#Sn>B<7vQdxz7 z4_^+IkLA==$IfY8v)SuP&4==DpgTxc#eHynr18addp<7d6w+A_NmZU(kprwhffq83 zO|Nu^O+jn-lP@mb*11Nb8t(K`aO9U@5sxeADtaUVk(kN!Tb!=c$lJa)5LRRCykQGT z+nrb?^gAl18Apn)GfVoJygESJ`mn{$h>=w%R7f7o3s+cy@6<2q?A^w5 znyMdXr6ek75&``^?LXnpGJGsfp5M_r@|r zz~P-A^4$`iZ@_1$UjfyitwXZTMddp7Hwq5{fRy&K+0RF$at=H9QzD5ZuU2(}e%GMH z?DR)_xmF{cfldM_#sn@?;n~a1rL>IPYmryHpk;mG5gszO8B^Zj=somUPz4px10e0} z*q*@2@6-N}mSOeGZ@%0p%|#~gV)V4(EizYx#w}3 zlT2gK2o*Y|bqMKahAUp{uGX|m;~qWM4;@4820Y}<0fQnXO3FL0?Zf)0?#ihc34jCF zuC1T&ksKu=4}9C>Hb!DRQMo?>T!k#jDjh+|fRK^XJ@ygE;hx=9kOEVjCg0tKS8;Y) zpcKB>v*9}fsR0zTocd?-{#-8o4?(2wBjI#?l^ZtRjmJyK!+1ZOhU#E$-}q6Vh975Y zfXK39_&X%nSK>Nf|IL~F^Bg+qG1W_y6X@e%67b22JM-v`ZfRZh6|1iDSY4j9JEpoRQ`yf%N$j+_Yz^`C-ae--V$l-;Sj%^N!C(dpQ? z6qSLd4VbJrO0%3sOng0+swwGpP(IdR;qFx=MJ`8+&ebYYT5+XP_8Snba$`Bi_VRS! zZ!VZK*WceU0YA91G06P@A+d^9MUAiHmU3_t%ZL<7UsdH@xmLF$if#r$a8!d#^IB?l zdB`ylchIus>hZ{9=1S>WDh+C(8vv5wx{LO8BsiBZH$dMj9K~b5*!=$6B4N~09vrw0 zU3#MdN_|u{I=-|WcI8#p3zeb3jy+!c-TdGx23zwT6_dO=7x?TxdB7mX}CCc*O0saDMjuJ%YlzC_t}8P z04D&s#3)U7XT{tX_p0iq6^L3w-eUatjPb#|dZ0L`!G=#J?7xqBuHA&J0CHeuD(V>k z0ILF#&;`doird*z;g2DG6ii5J9&7BdMtr7#A;NN>%6LCU1;R!3lg+^|O9}i)Db(+Y zfE+l>|4!R4y+z65WIVoBu8JPe4-8&F@ZPL!sj83Xcpa4mv!Z1}j*$?4bLQYW83|y^ zU+LPPG4Y4LS+Dp$?_N>qTME%LOV*)Arn|-+O)MzUnuh3aKf-p(s)%^hEmn{|4iUWjj(*8t z@XT-}%GR{G`%#zA&9ZTpXHjI^SmjWP&;azznsKnLhU)nDl2BQ77HxBx_nW(wiWT!i z-ahI{Ff2yKzJCj5>hJzahQ;-s_(DwOY$mjOhG<*__#fasMBGNp2xIk)YT%k ziMlO8l~P)!B)Ca+i9NbENUa9dt7U7!wWcNBb{xsmC&8a%iUoSVr|3!Pi1*^!qdj3s zu$FVS<#SBH;~Gl;VULA-B|6(yri)*pByGt5zH>aCD^i9toC=ZaExu`#?X8+CHuAs7 z_TzGyKd`;XwtuHIz}(iqmLu9+|Z^ zUA!cC<353h0@2Oz@jLO8RA7a)1+X0zeX1)nhI)qs zIzEcJ`w9T>y&8bpKpF}d*`#jI+K1gTVXilWL!#IBCtd#_RFx1qX4yu>E3>;ByL#BH zWpS;RP_XkLUt~d`^cg%dAx(V+cnn^eIC%miRLq--&kj}O@|7GQ=badSX2QpkU{YzD z_|ZLGvNnQJ7_7b@w-a_xoc2%&9hTG2H+7hS!KpXgf0}~#g5vLXu;yjs{Wvx5f*-Y( z(Ju+CHGhm+OtA&`5@_6+cez{H8aym7b3+NWo(l#lV>u3Lg4q*J@yt}E4bC6zt|SuY z(=j3G{}NUv#W-9in&@u-5E$M6Ov9)-`mJU@9((*gBWiEzfZz6AKOXVW3oBX*>qe=J zVh@?{Vpn-hJ~juBV-JPG@sXnX>Cn5|6AFUG`Iw=nJbB<@{6i?_*hJlhA_Mu^Ex90b zDnN)qAAo{#wb`7-R1%*3eSH$UZVFZwihrEc+uH_m$D$GOk|%Pu+hvLq3z`1QDW35a ztD++JRFEsT{m&+Crl2K78RYKhrV_Z!WAc$NgyIb_V-D2-qr;8C#%r_ZN{F5DUEini zooIIG4G1NY&aUgcms|OQ-FGNyByB}&7oEo9nPATp>vl+G1CG(`f&GMw0ho{f*-A@LNjE{sEzq*SX)d<`*RhT+ zbssEcA{Hu!#LkA^TZe8DXJeI0ewiCvI+E*iEwsNq%)?8C;1ic7X@`};=!#n(xRcT1 zFcd;KC+x_v8{oCO?ZO8ST8+Lm<4)+Z{Ot(`4cxc8T6fa1mOajamPWUt?GJ=0p-iPJ z1_pEAEXY$am>A#gq9@3D?Mj6TkMXea0@E61qS`d#>nzX4?9@IY#nCzuD-A z1hU~iL!c#oEG=Fxu3mgST3PP8r0>{8T*+W@rHsDx?&8@VN;w- z`_DgliG3Bim%r9`@!3vR3rEJp4Q6%@80=AmICAJ{3xoB0dP18{v3N!ownRjQq*D40 zHbJHr%r@|QrhmqS@+)s)x$WPDfS1TuoU5c4KwO(lbNE~{Ju|-WzCg!73t`B&_LGUc zm=1Mc@`0PkKDNyDOZu@vXo0Rip+uQrATAMt&A64d{M|SDpR_(tZi$u!K`#{DUU{N0 zm>njl92wb6QGMs1I0eD2aTI&rjcXY*Q@%K*RrE&$hkvvsI%-gV{~*m5u|X|FP4);Dzix1097<-!?f$xl-$v7uIaHg_@4 zhY*hNAB)|v^#5B)3Ym^zr_et43SnPecChBugzJv&k#2ezYLAY}>uiJq=I56KRL{`` zw$xiNk%l&mWd11;MLqW>e6D$7_8%?xt1A){S65?ku=C*t%iVa~s3FHH$yh8y<3c%Q z-NFgp7NOG;Iw&82vlMCEPbn@ZgB%JYKAe2@&KE`Yk@i}ipRe(9H)uT*PbRO#=bpsd zK!*3Nb$>!Bt~rw+7c=!_!LOrXR^f&>Op;`~G_31)27=gTe0738g;)xI=>WT!pb}MK zd6lx|IN1QWZ-nW}7$#Ap8cF&c@lpi&;QmiQSZab2xmB)EcXy%DZSjqs)5!8W9k+7y zZphyIp@!!K7NPHMrV*%%rsHtnbuuhB2Ik2O01x7RUC0jiVJ;%%sCk&-4Xn=u;eMG- zC*@>Ap%TMq;$p9=758QcH*L2~pZ<?)Oz$L+5bAslyW zmVJ1MMb|FAEJxo@i$HM@_v|Wogn6;y=N=^i>o_<$tD9l*by`+Txwo=J&pf1L!GM4tdS*8k zrKsOGXGX*X&SwFMGhu%vYng%DhN2cPu`AQYhT^b~vCh7nnU3JJhgvov<)QSd8zYVf z&gsyF$sOz)+Fu((BgdBuYYLi_Tc-5{5#a4%F>A0I7OOY zzMY1ise@i5K$%c&i9~W-XNCu`_VEIfzg!17D@Tr-J~#fX*vUxyKkaEM zqqKm4bVx{dD1wrLw1iGc=@eueC5i~BARw)jq;xYtWeU=#*A3UL_?C49%Q}a%7!9RHNz0p5HAs%2h!Y-)h!KcxxUEH>+;XaRZXn`h#}_y#4+$ zLu*s>K#l{t@Q81%+mb9@I_MTC`}H)P&DtBb-?j;^+=9&q`14CDP-Oqwg`Q7Vp)ITRF*pZ!tp20C6((G9=E6)kJU9{KSmIvfe zBB)9Ho8wgYrIAa+12+PfVhJ^j%{#XW`Da12@2YA*NtW(5FQ)2$@_F;9x8~DQq!Zg< zkEqGHYs506&*K>HQ_{v!8O`}VlNs}zv}-fFEsEGopX#auhqMgq&oVcK(=_KuA|6G6 zM)B*XK-qpSorA#9%x5w6**3FkMjJI|QJFe*8&dbClUA_w44H2giMrf2)>;<&k*%>(bG+?l_`K+wsQ z7IlR)A@h?3AomRDHooOwH%x_Qt=ZS=We83h$xxx-bzCYUOHHp6K|UL{A1h6K&7YqU zS8KE`HUA;g{oSUE~oS0Xf>?CbKDggpOWz(s@;NpVAzAN3NlJ#wrDQ}TVU7( zn~XT(eT)a??;8#msw-f8FUFtV<8l7G4ZYbL(}36|bep+IJtkw$0k*%9PfVP-`sPul zt1&{XV$UEZCG6$xr+|Z&zwD$0a{KIu4(?Ge=|sOJw!Am-cxXim5c2>u11E}n9kHE0 zcxB~BXRP$*DZ^*X>ia|sNEIlqFU=NYo$_bKt!P69m3;L-@vsV4z(ekv_Y+ql-4b0# zwTPDxmkvn9AN)^C@pb)rak(~@qaU4^b0^}nARXVUvPQ$!v-b?r*}CR4t?cNeZtpsG zNr1k8ucgU4AU==U^**65KJRqV@m@$K=qhW*L6DY^%_Y(v=`&y_V8>gva8`^L=bVon7;zJ)T%h_ARTm5A5{8M z`hEF+JmAQ3Y!!W9KK7)YR)wbH&X;$ViMGO89}XMeBFMg}g^^L|*IMLPSG_O0R${fU{ zXPP$K|05v9a;rBQsK#YSKS(Y~gPw0q*}J%m?(xl&iLgC?y$sk&^nah`-N_!NDo*|u z%=1Y-)naikl@l+d39{4>+e=-y5{d=tBgIKyCkgZmf5)tP5-Mp)R`jC zWaz!!-9R{wBAN$a4*Mz!eM0xt=dbD~0yCE=MVUE<0cp2ClX=P=OG4Ah?y%-J35SwN z5OY&$)3ACHx~=Q#w_;z4-F5Bsgm*$LMm30Xy5Gjt) zSWR(8+Tx>RU8RCM0H*dHJoqI323|wSUtP}Y4OPzrKQwDfYEJXn!0*y_T1$}PW2ZG?LOPoOrn0?q)5vq$sedoj_a+LBqyXlT-t5eUb1jf(pgw=Y^cZ=U{ zcM5-dSh=CL4WvJ(?BX!y4zLX<;9bw?M&RD3vBa;SzoN8mb|By`MNADK3b)_#fhfqu z6qZUr6PbI*3#vhC&Fy+#$Pewj@2~i-ZT6X@@ZFr(V(w5Ha%D=Y?~udgm97c)nV69! z0y%OG{7m+z5o+95=rV2b1hcKkQ!biZ$!P2J^o-W#HHtB6#xcDPJtq})-$j4a=`u>< zI35`xg7od>AyftWGTH&Kg7%-JaW?SB; zRM=Ks>h;bK(>abC6LB5%6+UCWQ$2HvS3cBl#Tt0OT9PiU8hySBICsN?@27xi6gr7d${ZdPsQe137>*u+-#%l#}pk|vS>yCJCopPhoNg^{h8Y8F8wu! zK&|*zRcDgWeN!Jb1Q^@Ob94sJXHidZj+#&T{sGu#6yTCgZ;EWEJrzOL;~uo`hH+M& zymr0|0^K3!DO!s-G;!Akv`TSOH_OT*ed0u3`DsJ{mOd!w)Oj`TrCg7DdbwK7!*MXo z?#kI83-AmgoNvwRQhUoviaL&L0qk<= zwTf;?Zl9fMr-zB#^MGoJgqkwZn=m`k>?#<$Po8M}d3mZZOLD zrYPClmHzQJ3S3&Yq2X15A-Kd&Sa{5(_dLiQ-olZ}nX~6?6ZI2DJGwJU{JBo?o&}BH zL7s6_Eef>Kcc~-rt!46$BoAJtAZBGWArYij({MqjuX~D)7vPgMvmnyn!4tsmF`Cy! z)!uPJQIrsnso`}Mb?>e1XSHmzkW(Aoc%$W%K&Lx=(F4-4WbCkU4j9&roi}87GZ$%f z{*_us)6-_y^CrYch)brSc_w_jCMRUkkxh##=`$$w>8z>G=x!Nm`HWx4Lu-)Sl>Pz4 z{`41?aibF9L&EmK0$f;(8h!6*b+T{V+j$8L&t}~A6u)FyfHF-&tjYuB?y*h?{mU8Q zWUERT;$#56vBRcuUK-28{_*M=DEP4w5*2f z^X^#rY1UZE-gT+Yl?9{#>?H`vcV)Z%j>kaPwB`WViICZIQqXM)99bb)IfyZHj~=#3 z3ENx&Dx6^WXH%=Bs zK%lsYDUBGSoUYe-zI8VCSDk!0 z!XO>?*FsYK;qPP)M>*&GR|iC;lN6MKi*+)))+Ig8$OwUUZJO>9b&kXlM994MF4Hd^ z4&FVk7_zPUu$rizw~7>ta6FrfKY5-4@4Du}$)8wS!&__{6fbia$W258YS9^Fyzr5KYxs8~kG9HWlxDVXO+S!N?!QU}M}MSnh)IC*(fO9z_;bM6*vdiS0qx%|5FskRfBoc zOwGuig@$KR%Ju>VD`%9;U!Vjzy=QrTb}tfYY~pqv${oh=ljC)eVv=w%GgZH`5!DNA z=+4pfEMlV`=oWLH)!kQ5^nOwzEr4VOJHKI4fC;yTWByJ-yLrw}!woEB9EDdp`nn8e zmGeag>lNH?yjTd%c}z<1B>9$unOr}cs!+V}gyx|F6TLS_CYf&X;;x}gcFA!$s*%@O z5aEvJN`T5nYJZRCJ`7rG-N+P+QK+1*Z!j}oqF1g|wu#aKL7WDuwPe8+(%t$_*FNVV zQN)^5#38=9+t#%uMH`;`SX4@z!&KA#Wq$bmo-gof5tLh%xtPYq3NU*-N8o5)ESm1p z!;5eOxHVa3u2msAh;;YaVFJ%Iq3*l)#3XIl!tfmexD=l)<`hZs{^YC&tJnWvlvQs; zXN}^sBgglN&7Yg$3|D?FV7`qSLu%NjZ})^h{_IjwcFwdqcQM7cSJVN_@f7}A8eO|f7}zQW#L{eu z@!4?*)wcBwYcq&Z;#Z@NQP)yco)w<2$Aqx6x3g>o0UW0wzcATvbC>;fpw=L2fa+uv z?C|{&r^>vIS(}{V$Df1=JA9f{c(ef@{YDTk)2qzR=>W5R$|+`j8Nm57naX2xQ7);u zTXsky0ZP~UQ0M@DAFLOHF?qdQ+%|gzhgrkFxQHz5S^M0MMzKj&dUb{Zy44!ceknw< zu?8&EfXjB)BpNi-c)$1;GtJq{U4Can{#FS@3sVA@Uni=F>%89|ZLR)nLlvhbrX#(m z9=TPdnk{#lj}?A8)9ZNi0ZDgaZZ;IuLjR|O+Em(!Y>)vG5X}g@Y$gC0T;oaD4~Fli zdLbSKk(Q^PkQhH7P8dn}-H)!3RL|1Ys-p*ikdAiCBuv+9| z-yc#nuG)gnBDu)t_TDrg@LLT$)>QV`F8o_DDmdM%uLGff)vIeE)n0!odQdy6xo3)+ zJZ_pfg#+Gy2N0RG!;xCcdMN@NNg6)j_$t>V#zpyl5`E+-$-50WM$M{(ftfvwRC{#| zW|JsxvCjFGK9hyL>AwDZ$~UX|#gErV)8y1qtpH(xP&=1#2x7Bk6j@*4)yxI`FbDq< zp1<<5(I*92@I83bdMe!Y@MuosWEYp(f5YhIJ@!C5CtY6SL>*zLk(=Vxk%h590*gK* zS{Xs3*hV6?av6nXe!$W##1UAD9CmA z$vtOPZz~&-3JtX>a@^mqHb$+k={7~QT<6UM(NIc&s8TNIHc?}(-nU%(3sK&)p`nD~ z_9cH(_VMvgrpnCpx$Bv)DpNyklb&k1kShw}_JLF__LYG5HvyjrB!ri5EUaC>9Rz@c zF?45=u+851s>&q!c{F0-C_U%Au0@hZX`!E4`sYZlQCmQOSi2igsewW9!tSKYosnyj zRJ6~{fe_Oll0v?uka+V!aQ-T6Q@$GdY_4TxGz`9T$OO>TDk1;g8TgMo*uTb7WjsL+ z3}AVmC7J0B9)OU$Upy{FqK^Wdpck@eeT06laI~v`KU)kVn=;nhDIU{?Kbr9*B@A%4 z?S!6o?9DY*;}#j%iuf7mDEQ2Fb>1woR?cdciI~!ZL=;M{cpsldnE@1Diw$^O32#SU zp_C8;JW8V76WlEf{j-M&3|SM7s7Z|g;6-ZydP2gR+b4`0t{FlCro4V=uVsJ=$dJ$G zs=mopU*2LtUuLHiVKfC**H9*1Hx1?*s+MTizXeXIE%FpKXw0zwJnQv&Un%)f50Ji?MaqonTGW+wYQrs|J~m8l1MT(q`WcT2$HS^Fne z;D=3!IkT+dKR8v51{kmlH{z>qY&9{pC8*n=CM(J%YCX#DG*mawe67D~Upi73zREPXG=~vX>0d-KgBr@oA!HxQspA^F>X%-XJoPx*x%)iATs&U8vv&k^329?X?HGUsDzJ^z0zCd_3^@`Fy4< z-))3J$ebG|1aqK`CIf{A;6JPp3(==(7!5bPiqf=lfIDfuyeJqEBXfw2uks$Lb^Q&d zeo1RPc|{ze1AXIfY?&Fy__{B+<|&^A?Co6#1BP1c`wKvzwbp57?ppw)Fh z0F@>%7Pvbn5$k!=kH)&B3b5?(S*dGi{NfM@m2BLqN;PPJYk zKGSAmbzIhLw?1Uk3rTmQ+WPXpNk-(tO2bVc^p!;b)Js@Pct|>ld-{? zHODWO#<>7i+fPU?@Y)wJby=;;sUv6=juIYaZ33j4>r9VwTt(g6IKH^ z;}lEt#tS&;`aAwmei|CYP53xb6vTvL#!8-Am9SPCTYpx$?<;2U=G|b$Ust;|8n4o> zwKSuyjI-<+v$|3y7Hx2=icMZPeU@rn{oFeWW%K&knUjivA{^Xy%jGvl!G6IZIB^_P zXRr2}+l0A@n2sEdygOi*5OI=5M&_>xA1vW%!6ZA@@4U!YZ)w zN_k3xq4cjyhC6iHNqx@NRszRF2Xn^N@8hVJdof{|BN}Fst6VMPnhoBOyn^4WbP=fJ zzf<@H2a|iT82?6}XaMzU%11(nP^@{G24MB!l=Z1vx&9{JPJ_9-M}DQ}!RJle(LU$a zp5>wTojp$?HqZLR$J#p_TI!vjgPYD9#PZkF@GZ%871zsF@UxaIv)ZI5+Wi6%Tj^WV z6-kHD!FI<1_6w4BWGch(=GYt2tG@l*=*tPJeGFjKMKjpfFX)&xqvDp6tOH|SjIs2y zOo|R!u%~^N3yDL9mKTUH{&5i>aNQnGX@HYX5{O2r56&$Kp45|uJ+}}WVieV8e0V&< zdzu`dS5(%BW#BSrp*4G=fU%p@yGP&4aV2tH!$gEW6I(N&9=vx@!Fa&?s2TpuZz=6X zxkT{_EUx1q>C4#fuGE-KJjKIG>J<_6bdM#=)NWPa0*>10%3}89EYtif(H?zS0eiZn zfSn1dEGj41v;I59Z^gb~qM!;nmZW)p%qev02N=Vj6bS6Qhz~0K5FL`8?7c^h+bdMJ zEWoq0U`LBnS*2_8SaYGjsI@Ji+J9-K&SJ`(e(7LZUd9;aC7*vBAdpn`??Y`jv>PaI zkIG+Sf+NG#03AMcf!r@vN}K0NEYO^EI+h&#ldNL>E(c4A zwETy^#`hbtKQGMs&$Ekid$o&QeN<{reUcpg$uUXN%r@UI7J@HfHKc-GY0b-?7w8xb zuK*piw0nq5L>BJPGhO8Z1laS@O$C*t}O%y zw&CpUL#Fv_jLW=$>d$F3g^EGyWmku*v(RYeYdvT+aeZC>Ut{|Z1b-&x z*2XO+GO`{C_S8zN@|KfnuN7(OtGnO=Kgos1iUENroTi@7*w~JOP{^}Wnu0*=?S9~! n6kRL;ZuWnl|4ln!w{(6q@_ba8UaZK1f&hRK~hQy1*IFAp%DwD8x#vF9|EL9y>dcehLgLAEw`=XJEd5vPjHAhpc!~U#M$Wk^6B!`^SRw7mem|FcklBj|aAJuA{wt4+IIk}BWuRw~@+Rx!ZuJt;q_wr{hZf_` zH;G73hI19M?pb(|B(1{0{%W^2!e}n+9iHliu~yr|Q1&a@g=15_Q&VQ>AAhUMzWbG; z@lN>%tL}s@+bqlk?iAjq#FAH4%K;1cX9dTv6TI*{)2J<+g@ms6gBK3}2uXN7+vr+* zkI43)QiGq0XxJNz=3m05PP6=iO9i3G^TSkxfHpBzj)7Ex{@r%W_;=LBs;!bs`kL~Q zyguffQeP?1yWOAkCqMxl&*xd(O1^o^+nW%QbkxOTz;R8EZ|!jsAV~3-<}{0 zHrJyGdq1Z&8qxlYJemg?d4P&7cf{Jj_h*>{rrRiWylzXI@6ue8Ksz?M@p(E{&Oqj*b<*S1f&I2vP?|mBGCs(~;_ZV(w?%u>D?Mg4DMjIBlKQs?AS{?gOGwDbO^q&#(8fNCMhzun49R z_>M*FVx0wX+UCk?!u`${u4y^G+lFcTJs~5lJb_E-^$4c2>Ut`YQV_A}+R&Gfv`Q7qW7` z?)V`E{a9o01^TRCoZz}?^#ZTSGL#F?HUITjgdv&%Tm`Ax+Hg+W{nosi);D}kpIBer zo^=Ym!Ajxaj|g_r*3Q*zu{$8L^XAeZ0v~>tJ~ms~cJjG)lF$}kHv@WSfU-6uK6+F6 z9pcL_sYLdpX^AJG3oU)pHDDgfZc!|9U1B8r%{1{dh9LWD6cLdm4?o$tdI4|=2?7Ss z9ds8Y-fv@!G|MmX635h0X>@SjjpnVondoT#L^e)AtvlY~{ z_$a|Q)n|!499W&}Jiq?*wlw_dbFFZ~mGMb11hz zTe>(OUOSkq=6(A0yMZb_=zJSE@8;&l0JBQByu^UjX=lO>B2i*;xTi_T>Sht4=`8MF zVHQWwT6*vl3y=^B1sRAgm2pjMzE$f7WJ+Q`{5}Jk|^p z%~2*O83G%rBch;L9Qp*V-k5n+Z)xRy&Ad(G{g7RY$5JQZ2Mj{HbtZu0k5ej1a+%nk ze6t#68s?@73BBKAJUlees+_7SP4?5^OXL8%G9Ez}Ozp}}xXONJ&~qTJ&p$3<;^?+# zO8&_)kfND{1b92(;0uH4JKOEn(R1N}58W|{%K)EDd!iZ-Gq{!fmD$;u@M62)Ss|JWj#vcqTI^6ar(o6F@ykuB zLin|`*^lo$ffts?-+OKf$UnME9+oEzZdnz1=nw*TVqNNFhIy|*qmaU$RjO?QkcUU# zLlWfW?cp{K@tl-sZcJe|=Cvsn!kgbc}mSRlE> zB=O`;=jm}65h~$LypH(4y}85ZrI zqVMnhs6ws}=ip=#-jl#XKa*oKiwB1ACA^W7$GW6((%4>E-1MrkT@xl}^Z{Fce?zq- zmk$vIz&HaLx%Lm*6+E+D&N1`^!-b;iV9~EzK>tKwN|o(}>;e+-wHbp$Zt%Y}cQ$h& zhJrSWWMr3%kMaY?oGpbLL!j0BlpfTL7{Z)c>A)cFk2aEk*DC`ea*v&xjLvPdP{$Ss zC0_kO=Pu{iew@z#Uhnb)-rt{L2K=WU%d+w5N@zof2B-8nf_D(*k4uA};=awcUt0`b z?)D^ha8`Lk3Bq$S(c-P679}?Qd!t?pM1ADf`>fEInB2gf@5sgU>k2RXhsKtpC<%gn z=j{{UWO3q7aAtKCM&R;YMv7qC%spAaPk3x4!)`wC$`0DBA;Qc~Gy3z|P}Vt(x=nyR zFE|4^EWxDo&(!W@E|oYZT|?rx+)$cLc=qT6w-G;Lk`+qYpSeRjh|JYuvB~3SR!w3~ zUw_fjK8*mkYZf|n*V#|eyn8`O_MzdMQsPBgS=Ji3;qq0&jxz%3c9+PR@Pa|8q2n7T zYcsE1`z-x^+spSVPQ*iQ zcNfgKo^T`$^pOei4*77X|7Wim`knFN5$7kB5XBN=;lHH=M<($bkfj3!@0*ttYyhZMGC%5wqwy>U`w(1_@UIg`h5A| z?s00skn`|$`K!|@g$`Kr5;iRr!T{c?d?H#8>u3+rm@Vqsbk{1G`TJM&B{h}dB{bVv zn5skK89RhIE@0tGPw&d4Gj3#6!hugPF-g4M;UIt5i{COSm^;db2To2Dka+HvZ zi)-9Uxs&(l#dM7s7{P|LJ;I?p5(}D;vf+$l)w|C-#{I1*`a-M^TS>s9hWmq+$Ax@OD!H|aSBB}D zaEXhB4v{+#?4F+nZS{U)lX*FP*#FY)>J@U3SjauC5J}b&778^hJRHy3G`;e}jo2%L z$ZHB+Cp|r6?;KxWM$Mv^i)ScI+7Y%jmOB{4?zPOkY>>HCSizc^HZ|_nAY+x{+w^(t zv0BsXM=jHHP8JijA(h72w*>1J@aJbpg|o#-8=IDSo5y(Yx7|7p%o7Urd|R?eTCxg< z2-NvT9M?)LzXp!s@uEK^#H6;-&kBuR=n47iUF(jGQ$mlGZBdW*C-|+YB^H0W~i&g4KI^91$2R@U;8Qydf{rKa)qf6Es-pUu#)f znz3l(z%07^JhjHGDw0Dyq?FxohHO(HT<=?=kt{W{>^tm$hVC!q=hLD6X+ey&#_S`KzWX{8po*Eehf$xOEYx`iR;gU*&LlOUFnV-4-c zg{1?2!R~=R$9{B&Y9&6eTBci1+&Nx*n5|nDCX^Ar!FoQnv8>uZP=6sY=>Oa7mAWAv z|I(MjrOQN#&9p@{C4%LZcIP%H4u5L9vs^t|y@I@@AEJI1yyS+JO3gd2z7V-OGV#>mT!p~fBpxPnnb?1Y#J?2Q3W>oDq)|SadWJYy zhzr>5;hh8sfBVQZ6)c#2ghSZe?{vU={`&JJn zzp&P34z5R(T^ZW3HB*vbB|&y<5n|A7vf8FL%s?)_Ew)*D} zP2WKKyc?pYx{NK$0<|^n_vRaWtz|je@yYo%4y&Kk(`_R)ySr}nq1&4`KVKPfnQm&Q zXfcaFIa7D-`;%$wu3xDXKPJHM5RLM6SJie%__gut^Ml}updR^;{Wrt@xIv@ozz~z> zzilQaF6PG$;KS_!K!bZCR5xqn5}qDXpO#YB zUpDF3^zY|WQCh^C%Pbk@;Nw$2{k&`j-dWyJZnXAPcC*V!_Ge1%(=+1UKyOLOVE=iK zpT>V+z)y;sJc8l$_r_mJnX&`(0gih|>!K@OPI? z^Zw=^Ip3MXi%SwoNi0nNL?MfEsSp>n zzA^2vl^QsV3Yel&+64BRb6S{7>Dfw_DSVV6&!}R<7p(|Yuxk^XE4PaGQbR-zk#iCn znJ^sI%pQw+1uO%-zLWOtJtL_H@>BC;y(_gUROkavO)UK2KAeb!xe z=%W8QtF~`jz;rclWOi~K|NXVmeN5^)y^(=QI9tD05pg#Spzs5Xnm0hB-*_nNofWUF z@1{-#L9KqwH_dYoFPwgT+W5W-s0C+1Y+M2ReH z6pe7$EREQ3DHN{J=HkFz!}#vbwyRLswe=qi_pTf(Ks$z>q}VjUmLlvW#exAeHY6?e zwa7ko@6}w1=3Z?b?q9z9K2{HX1P~%jd}dm9q0+P@KwBK}{H~e%kFDfd0W~LS+nO4) zV!JG)e1jRSIK21yZvmjPKu>jDaB@9w;!qZAs)csFz`Y;R z&!dZzSMlslkbN{oOc=KoHfCtwIz--+aPZwF_Gt)+W;dekCH@fUgF(tl2e{I7i;0hI ziad2vZs?dKMZDX%01OXi1_X%A`(vau2k-xzBoHM%mH#yXx_Z?m zA2cOaVO+jx}6E#l)-&h#NUyOw8%EmhV&01=j%NdlpAp?3E?F7&5AEGmbYCWk~$Wz^w9R+7?pC=^!nD`+N$p)nEl~#=M~vgDj`9J zjLCz7M#ajO^KxWJBT8oH)N`Bj6t=uz%lgxtAn54tjc86_Hm_}aw$`N)`jIo#$VDlL z#Eun2iaEMXq+8wBU(iJ|f`(S8k{xqw8Of80##E-(J$<;o5$w-4r_V=DPbLcgbk8l6 z=@p);CnX!7fDZvO*?~n&thES(Jt)>jI zzA7GcE}t8brtH5L!~^M|zFgA5*2P86T*Vqyt0Ae~Y3PlUU_`nry(*K5lli$PO8En3 z`?L(c?)yaMvwB@)Kr-jC%x@!2kJRh}{Ix|#>MCA{S}ZYe<25*yUvwoVw{&N7e&^Wq zyV1XLT05PsLT}`GcV6)bi9fx*zfxfzlZ{g1@Euf)!>BhQYy0~x$u*8(47VW746jCN zOsp*Fqkm02* zi}p89s-*u()X1X6-LOR}jFc8&I(Qe_Uohi^Q>_2t;Ks6UbHyGGR~PVGzsbV@p) z{oPL((9>M>z#Pc;-KMT;F!aBBhfPSz$C4N9Ndobbd-xsL=6XOjCzCwA-HjC`+5bKF zY*39CBNl2MdI!Ko1_$;l{ye=Wa3|x@uaCrONrR2_3wNltLPDVvW^a5OgdiEvo!z@FcK65uSIjW z0B+l54_qP)v!r!^jjMqRSpskW`{#l0GMpCV5Guyq2UXd^D&ihF#ZKkjIlu@6^yFC* zk0ztdGk|Lb60}alv>rVrA^a_zx(d zd`*4rmt0PWLG8JhpV;H%cvE=5&kFiEWZ3&Pk-~6?01!Q0BCba8Cx*pW>OKoRH~qiQ z?t>Zqoy8}=ViPBb+mH5M+eDd}sHB0u!3nZBvxhppJIL)oFPl`o>SGOn^(nY~nwzO> zYkrkfmKD?Qg9WX8lZpY>yY!a8TtEqhB_Hs6F`5;e1!Hh%`g2g{jLhD?O1IP6W4+>B z0${RYf?Kx6$g<9CwSuJQHO%*8Keqq$CI`UwZ*w&Cr*L`KJ|d4&>%gD5m+VSGi}< z6OUd0z4=?STiJ^U!_XFP5ke;bRyo)zAQ?%4`S!}sRU%Xzcb{C2b|*a)55R6nak zTnFyT`I$wZRM5a&b+S^$f;Q(}smDX+c72%E95!t7se_v;Ik7afN3artN*&ysaLS0M z+d`V#v|F(Iyi&Jjy+4BIa=lc4n{9MH3L_h{Aw*6DLs7s@eEl)X(1X%ITssQpHh0a= zfZbn4azL=B7>=xm&*3=(bQ=<$jh0RN|31uOCHi7Ue3?}DQUyD4X9B-fYBIPOT*n|{ z!e7Wnq$b})IAynmUWQR(N|CU*(&}VNO8q!ou+^wryf>{G zsQ?Mn27r){Of`faOKA0rF_#2tj|7d-B~V2^q=6h;8Z$LN5r1^{Gtd6lF2S1bYJy|a zC7-xSZx;X}#zG{}teXTQGBbEmV{Br|1Z>a+5k8I)a9Q*Z(lXPhwfQ>s!)btjEYLR%eJ7#q7hb@_G_^6G`=cxuWRs8w95NG_m{a?Ep6 zJ+P`Y2Ta@F;2(~qq_}zVK-4$_ItKn-`CJ8pz?k%AV1k#^_0VRbi(Ow5PU2L z*S=B~>Am8ox03}oHwOh}{Y^ppgNN3)BTh2nb&s`wN%o{|} zA^n1KzqMaq%jT6RjO0-nyxg+wts>;IX4OkPTd;8hIz^h)=eXS+y!ZR!o)>kK=^6{v zHoC1mm4)ThB1QVoHa7GEoMPu5bV{4=LO7Pe+~nVNukrzL;&!TFtIXY#@o4+^yfo1? z;0L9MM_x7@p`O{eez`rV#{X4b{GX-p^xWSm)|*k7b*-6Gwwl(QTHhq>puNRHwaDXA zlVAGIeeW46D2X7{SJR_`wKc1;E+;`4(f;ae1NJ8DH?%3mAwyfYgTIWBarjp4En57w z)q3bd=s>PwOO9^X|3)=%Vm+jv%QgOa1J8Jq>teZh*Nbn}b-|}%Q=sbpp3L!UT#H+u zwvbl7Ygo2DE_h->ld(Q&B)7|0{o|aVY0H2(MO3&>XuKwwU5SY$ImD+77;2%CJ)904 zW^bS+)07rDUpTrs>e^if7xaXqm|f(G{H}h356|3-!C-}^_nh^Wz~ZZes~uw~HxVV^ zzyaN;2MWY4<|RiOB`qhZbnXWK&K#1)IgRaMHjt0xY%B9w>?I9OJx|e5T&vtKuW&Xf z2~8l1Ufn2EB9C9!hLilc1hbUgomF{OdXVhgoxd_FXz^e30^$CkOPC6k0{|Gw1YORo-{oYNatiT!}-Bl^pzkRJX8T~>& zLV$`KBpf8G)1yU|9x(t$4ziXLCFRhOtO(j>(zTmO_8MjJ+@CFpjaR#ljz?a7b;)RQ zFkHawOoJ(y`ul6l#viME{7sQNTt|XX7BmN0l+6tj}|nOei(W zV3?J9h3O1OfIWX+@mRSFPI_TK?KYi-Ki z-eK6R$@hcg);HE$5ZZ~O>Tym+ZhtDsaibG39I{+R!0^4Rwsu36(1-_^VOmH`gIM2v z9+s-FVj~HYVbRMrLa(mQRR~NbxZcMi0t9TQF;op)HRH#h_<8!d&s`E8@D#CI3>$j@TxxuOE-D2+l5;=L+e+5&D3Mt(s8qzhbXwJ( z_M+ZU#EndNegT?07Z^3@1NoZ`H^7P<*JF@rSyz};JW13Pvq%?4r5Dlp9c)Ps7dO}j zi=w>>b%fa7KKL_xkAaib?5V(AlIvpNOXGM4*6sjbm{O{u>F9OZpIODQgKSj6J^7^S zf&n*8`P)Vdu_*}&j<{UxNdx8hMEZ)+mubf5ja-{V1<@}umX-OqLt9L5c(}VI{2iF@ zKiFJe6)S&-c?G}jGiRN{CD|C|y*~EgbT0p^J@C#n`bmeR2 zHd6`SqRuw~Q}h-aIA&*@w*)pO82voq$N?EqDydt0LT9xK`&`X0iLk|<-;=hfd}3?9 z4fCeWdndEwXa5}jO}Ud3=xIDWq1v}-gC4_U8WH}LR;Leeqb{!NL7Ll~MIk(ta9m*R zcNvn5ss|9Z-{NGCuKaI^+MltcX0ymYTuRmnS^u3;e644k6z32-$`4`AhDtUXHL0RP8LuJbY^a{~ecGP@Z_9 z*tV5;9l~~RIuokPKq1QxI+n|u)2bI4)ztf6ZSWRt6H#qS0(4x5=NG>dv(4rpio4eW zE4Prl=QwjX-Ok?$!(o&oj_BYvPCl*N)Y&+%bm8FRHKvFT?K?h)aSzgV{8lUXi)#PMN-hEbidIl_xpA0WCREdgCd07`e1eH@r)1tm zcgph@FhY7CNg2ERqQTNQ5_(k$gd9r{{GX)Ic8tpbU%t?o?(suUDecS;==W^2UFcFK zE-rljwLBxG*<(=ekaEBAmXrc0cocX^@4<$O3?-&uO%>aQ_ur$*frEn}vGw8X77h}- zeemEsZh-8moypfQBd#GP-;>(0l4l%j=SJLTdmv_5YEqF>WrLlLhD3qK4+Z^Q6HxO` z%?sUFe@YFQV|NOQ`5H0?73nAXa|5eXTO!8lAr)q&R=F7w3cK4~ zqT*CrwsR+_1akz)xsY~6^+L2%f>L4y2XueZ;O_eaREq%s* zmW)N2A@DKqVz)-@-sdtnm&K&=%`l-R9OG3GVJJX^X?qpgHevt3F6a;Z%?L6OhjwxB zF|mfPXK(dw^E=BK%)*`hax_81<1+JO zbeMY$^ZvOrt;Sj1-1=GTKSvhY?k;bgOy8c}E#+?}mAl<|8D+D8Kla%v>>tM8fW3Zi zq1+8SZfkwiW)9uM^s0|xMCTpDqJ2bxJ+p>kqgO9V7|1)msziVV_RAqnZ|al*ZR$>E z{tIxzH`HY_#V!8DHpF?RAVki-%OKBe=)0Lk(hJ|52}eD{jVh3+$yc6@siJCT^iZmKm~-d^u?=G5v~fP#p{M zDE70}h_YE_uk*d)@T$RZ9q(hXrqQw^$jPeGO9aHm|M>B;p@{w!5xeA`we9H+`_HR8?;TnDP^u+5dXb{>ye#z%6)I=b*FoFG0EDWyr^r&Z{g1VsE_NyQK*vbTCajR|DY(cATEmgHfYZ1 zlT(x8mfFT~FcbRZ#yix`OQT@t_n3^4Sw}ve?5Bj91DoA%_KC+3!{ydGv$VKSCi@R2 zoOx}n#VZ{Ch`C8yggkmmdsW_!P@$F!9% zJ_oH;5`wzIX_LV=fs!29v0>pbzNUBrP_EiwFNabw6OZI#$L16n4Qk7uIN=v??Mb8?xnp`?@>g(`kUD2s;ga0te%zYu�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 literal 0 HcmV?d00001 diff --git a/mihomo-control/icon-online.png b/mihomo-control/icon-online.png new file mode 100644 index 0000000000000000000000000000000000000000..a4cfddb7d343a1192c175cb78744405c828d4cfa GIT binary patch literal 24491 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 literal 0 HcmV?d00001 diff --git a/mihomo-control/icon.png b/mihomo-control/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c624b94d23b333e4cb2406ccc04c9599552e0bac GIT binary patch literal 14428 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 TRAFFIC_HISTORY then + table.remove(down_history, 1) + table.remove(up_history, 1) + end + end +end + +local function normalized_series(values, peak) + local out = {} + for i, value in ipairs(values) do + out[i] = peak > 0 and value / peak or 0 + end + return out +end + +local function refresh_snapshot() + snapshot.connection = noctalia.state.get("mihomo.connection") or snapshot.connection + snapshot.config = noctalia.state.get("mihomo.config") or snapshot.config + snapshot.traffic = noctalia.state.get("mihomo.traffic") or snapshot.traffic + snapshot.connections = noctalia.state.get("mihomo.connections") or snapshot.connections + snapshot.groups = noctalia.state.get("mihomo.groups") or snapshot.groups + record_traffic(snapshot.traffic) +end + +local function send_command(cmd) + cmd.seq = math.floor(os.clock() * 1000000) + noctalia.state.set("mihomo.command", cmd) +end + +-- Expansion state for proxy-group cards: collapsed by default so long member +-- lists do not flood the panel. Persists across re-renders while the panel +-- script stays loaded; a fresh panel starts collapsed again. +local expanded_groups = {} +local render -- forward declaration; assigned below + +local function toggle_group(group_name) + expanded_groups[group_name] = not expanded_groups[group_name] + render() +end + +-- ── Formatting helpers (small duplicates per the plugin sandbox) ──────────── + +local function format_rate(bytes_per_second) + local value = tonumber(bytes_per_second) or 0 + if value >= 1024 * 1024 * 1024 then + return string.format("%.2f GB/s", value / (1024 * 1024 * 1024)) + end + if value >= 1024 * 1024 then + return string.format("%.1f MB/s", value / (1024 * 1024)) + end + if value >= 1024 then + return string.format("%.1f KB/s", value / 1024) + end + return string.format("%d B/s", value) +end + +local function format_total(bytes) + local value = tonumber(bytes) or 0 + if value >= 1024 ^ 4 then + return string.format("%.2f TB", value / (1024 ^ 4)) + end + if value >= 1024 ^ 3 then + return string.format("%.2f GB", value / (1024 ^ 3)) + end + if value >= 1024 ^ 2 then + return string.format("%.1f MB", value / (1024 ^ 2)) + end + if value >= 1024 then + return string.format("%.1f KB", value / 1024) + end + return string.format("%d B", value) +end + +local function latency_text(delay) + if delay == nil then + return "—" + end + if delay > 0 then + return `{delay} ms` + end + return noctalia.tr("panel.timeout") +end + +local function latency_color(delay) + if delay == nil then + return "on_surface_variant" + end + if delay > 0 then + if delay <= 300 then + return "#4ade80" + end + if delay <= 800 then + return "#facc15" + end + return "#f87171" + end + return "#f87171" +end + +-- A single "overall" latency per group: the currently selected member's delay +-- (Selector/URLTest/Fallback), or the best tested member latency otherwise +-- (LoadBalance has no selection). Returns 0 when every tested member failed. +local function group_latency(group) + if group.now and group.now ~= "" then + for _, member in ipairs(group.members) do + if member.name == group.now and member.delay ~= nil then + return member.delay + end + end + end + + local best = nil + local any_tested = false + for _, member in ipairs(group.members) do + local delay = member.delay + if delay ~= nil then + any_tested = true + if delay > 0 and (best == nil or delay < best) then + best = delay + end + end + end + if best ~= nil then + return best + end + if any_tested then + return 0 + end + return nil +end + +-- ── UI helpers ────────────────────────────────────────────────────────────── + +local function section(title) + return ui.label({ text = title, fontWeight = "medium", color = "on_surface_variant" }) +end + +local function connection_text() + local conn = snapshot.connection + local endpoint = `{conn.host or ""}:{conn.port or ""}` + if conn.status == "online" then + local version = tostring(conn.version or "") + return version ~= "" + and noctalia.tr("panel.online_with_version", { version = version, endpoint = endpoint }) + or noctalia.tr("panel.online_plain", { endpoint = endpoint }) + end + if conn.status == "connecting" then + return endpoint + end + local err = tostring(conn.error or "") + return err ~= "" + and noctalia.tr("panel.offline_with_error", { error = err }) + or noctalia.tr("panel.offline_plain", { endpoint = endpoint }) +end + +local function status_chip() + local conn = snapshot.connection + local online = conn.status == "online" + local connecting = conn.status == "connecting" + local text = online + and noctalia.tr("panel.status_online") + or (connecting and noctalia.tr("panel.status_connecting") or noctalia.tr("panel.status_offline")) + local color = online and "#4ade80" or (connecting and "#facc15" or "#f87171") + return ui.row({ gap = 6, align = "center", fill = "surface/0.6", radius = 999, paddingH = 10, paddingV = 4 }, { + ui.box({ width = 8, height = 8, radius = 4, fill = color }), + ui.label({ text = text, fontSize = 12, color = "on_surface_variant" }), + }) +end + +local function controls_row() + local mode = snapshot.config.mode or "rule" + local index = 0 + for i, candidate in MODES do + if candidate == mode then + index = i - 1 + break + end + end + return ui.row({ gap = 8, align = "center" }, { + ui.select({ + options = { + noctalia.tr("panel.mode_rule"), + noctalia.tr("panel.mode_global"), + noctalia.tr("panel.mode_direct"), + }, + selectedIndex = index, + onChange = function(index_text) + local chosen = MODES[(tonumber(index_text) or 0) + 1] + if chosen then + send_command({ op = "mode", mode = chosen }) + end + end, + }), + ui.button({ + text = noctalia.tr("panel.restart"), + variant = "outline", + onClick = function() + send_command({ op = "restart" }) + end, + }), + }) +end + +local function traffic_card() + local traffic = snapshot.traffic + local connections = snapshot.connections + local peak = 1 + for _, value in ipairs(down_history) do + if value > peak then + peak = value + end + end + for _, value in ipairs(up_history) do + if value > peak then + peak = value + end + end + return ui.column({ gap = 8, fill = "surface/0.5", radius = 12, padding = 12 }, { + ui.row({ justify = "space_between", align = "center" }, { + ui.label({ text = noctalia.tr("panel.traffic"), fontWeight = "medium" }), + ui.label({ + text = `{connections.count or 0} {noctalia.tr("panel.connections")}`, + color = "on_surface_variant", + fontSize = 12, + }), + }), + ui.graph({ + values = normalized_series(down_history, peak), + values2 = normalized_series(up_history, peak), + color = "#4ade80", + color2 = "#38bdf8", + lineWidth = 2, + fillOpacity = 0.15, + height = 72, + }), + ui.row({ gap = 16, align = "center" }, { + ui.label({ text = `▼ {format_rate(traffic.down)}`, fontSize = 16, fontWeight = "bold", color = "#4ade80" }), + ui.label({ text = `▲ {format_rate(traffic.up)}`, fontSize = 16, fontWeight = "bold", color = "#38bdf8" }), + }), + ui.row({ gap = 16, align = "center" }, { + ui.label({ + text = `↓ {format_total(traffic.downTotal)} · ↑ {format_total(traffic.upTotal)} · {format_total(connections.memory)} {noctalia.tr("panel.memory")}`, + color = "on_surface_variant", + fontSize = 12, + }), + }), + }) +end + +local function group_card(group) + local name_text = group.name + if group.hidden == true then + name_text = name_text .. ` ({noctalia.tr("panel.hidden")})` + end + local expanded = expanded_groups[group.name] == true + local overall = group_latency(group) + + local children = { + ui.row({ gap = 6, align = "center", justify = "space_between", onClick = function() + toggle_group(group.name) + end }, { + ui.button({ + glyph = expanded and "chevron-down" or "chevron-right", + variant = "ghost", + onClick = function() + toggle_group(group.name) + end, + }), + ui.glyph({ name = "list", size = 14, color = "secondary" }), + ui.label({ text = name_text, fontWeight = "medium", flexGrow = 1 }), + ui.button({ + glyph = "activity", + tooltip = noctalia.tr("panel.delay_test"), + variant = "ghost", + onClick = function() + send_command({ op = "delay_test", group = group.name }) + end, + }), + }), + ui.row({ gap = 6, align = "center", justify = "space_between" }, { + ui.label({ + text = `{group.type or ""} · {noctalia.trp("panel.members_count", #group.members)}`, + color = "on_surface_variant", + fontSize = 12, + flexGrow = 1, + }), + ui.label({ + text = latency_text(overall), + fontSize = 12, + fontWeight = "medium", + color = latency_color(overall), + }), + }), + } + + if expanded and #group.members > 0 then + local member_rows = {} + for _, member in ipairs(group.members) do + local is_current = member.name == group.now + local delay_text = latency_text(member.delay) + local delay_color = latency_color(member.delay) + table.insert(member_rows, ui.row({ gap = 6, align = "center", onClick = function() + send_command({ op = "select", group = group.name, proxy = member.name }) + end }, { + ui.box({ width = 6, height = 6, radius = 3, fill = is_current and "primary" or "surface_variant" }), + ui.label({ + text = member.name, + flexGrow = 1, + color = is_current and "on_surface" or "on_surface_variant", + fontSize = 12, + }), + ui.label({ text = delay_text, fontSize = 12, color = delay_color }), + })) + end + table.insert(children, ui.column({ gap = 3 }, member_rows)) + elseif expanded then + table.insert(children, ui.label({ + text = noctalia.tr("panel.no_members"), + color = "on_surface_variant", + fontSize = 12, + })) + end + + return ui.column({ gap = 8, fill = "surface/0.5", radius = 12, padding = 12, flexGrow = 1 }, children) +end + +render = function() + local groups = type(snapshot.groups) == "table" and snapshot.groups or {} + + local body = { + controls_row(), + traffic_card(), + } + + if #groups > 0 then + table.insert(body, section(noctalia.tr("panel.proxy_groups"))) + for i = 1, #groups, 2 do + local row_children = { group_card(groups[i]) } + if groups[i + 1] then + table.insert(row_children, group_card(groups[i + 1])) + else + table.insert(row_children, ui.box({ flexGrow = 1 })) + end + table.insert(body, ui.row({ gap = 10, align = "stretch" }, row_children)) + end + else + table.insert(body, ui.label({ text = noctalia.tr("panel.no_groups"), color = "on_surface_variant" })) + end + + panel.render(ui.column({ flexGrow = 1, gap = 12 }, { + ui.column({ gap = 6 }, { + ui.row({ align = "center", gap = 8 }, { + ui.image({ path = "icon.png", width = 16, height = 16 }), + ui.label({ text = noctalia.tr("panel.title"), fontSize = 16, fontWeight = "bold", flexGrow = 1 }), + status_chip(), + ui.button({ + glyph = "refresh", + tooltip = noctalia.tr("panel.refresh"), + variant = "ghost", + onClick = function() + send_command({ op = "refresh" }) + end, + }), + ui.button({ + glyph = "close", + onClick = function() + panel.close() + end, + }), + }), + ui.label({ text = connection_text(), color = "on_surface_variant", fontSize = 12 }), + }), + ui.scroll({ flexGrow = 1, gap = 12 }, body), + })) +end + +for _, key in { + "mihomo.connection", + "mihomo.config", + "mihomo.traffic", + "mihomo.connections", + "mihomo.groups", +} do + noctalia.state.watch(key, function(_value) + refresh_snapshot() + render() + end) +end + +function onOpen(_context) + refresh_snapshot() + render() +end + +refresh_snapshot() +render() diff --git a/mihomo-control/plugin.toml b/mihomo-control/plugin.toml new file mode 100644 index 00000000..8d135645 --- /dev/null +++ b/mihomo-control/plugin.toml @@ -0,0 +1,94 @@ +# Mihomo Control — monitor and control a Mihomo (Clash Meta) external +# controller: live traffic, proxy mode, group selection, latency tests and +# active connections, locally (127.0.0.1) or on a remote host. +# +# The service entry owns every HTTP request and publishes "mihomo.*" state; +# the widget, panel and shortcut are pure subscribers and send commands +# through the "mihomo.command" state channel. + +id = "mdj2812/mihomo-control" +name = "Mihomo Control" +version = "0.1.0" +plugin_api = 9 +author = "mdj2812" +license = "MIT" +icon = "cat" +description = "Monitor and control Mihomo (Clash Meta) — live traffic, proxy mode, group selection, and connections, local or remote." +tags = ["network", "indicator", "utility", "bar", "panel", "service", "shortcut"] +dependencies = [] + +# ── Shared settings ────────────────────────────────────────────────────────── +[[setting]] +key = "host" +type = "string" +default = "127.0.0.1" +label_key = "settings.host.label" +description_key = "settings.host.description" + +[[setting]] +key = "port" +type = "string" +default = "9090" +label_key = "settings.port.label" +description_key = "settings.port.description" + +[[setting]] +key = "secret" +type = "string" +default = "" +label_key = "settings.secret.label" +description_key = "settings.secret.description" + +[[setting]] +key = "use_https" +type = "bool" +default = false +advanced = true +label_key = "settings.use_https.label" +description_key = "settings.use_https.description" + +[[setting]] +key = "allow_insecure_tls" +type = "bool" +default = false +advanced = true +label_key = "settings.allow_insecure_tls.label" +description_key = "settings.allow_insecure_tls.description" + +[[setting]] +key = "test_url" +type = "string" +default = "https://www.gstatic.com/generate_204" +label_key = "settings.test_url.label" +description_key = "settings.test_url.description" + +[[setting]] +key = "refresh_interval" +type = "int" +default = 2 +min = 1 +max = 60 +advanced = true +label_key = "settings.refresh_interval.label" +description_key = "settings.refresh_interval.description" + +# ── Entries ────────────────────────────────────────────────────────────────── +[[widget]] +id = "widget" +entry = "widget.luau" + +[[panel]] +id = "panel" +entry = "panel.luau" +width = 560 +height = 720 +placement = "floating" +position = "center" + +[[service]] +id = "service" +entry = "service.luau" + +[[shortcut]] +id = "mode" +entry = "shortcut.luau" diff --git a/mihomo-control/service.luau b/mihomo-control/service.luau new file mode 100644 index 00000000..e0f885c0 --- /dev/null +++ b/mihomo-control/service.luau @@ -0,0 +1,567 @@ +--!nonstrict +-- Mihomo Control — background service. +-- +-- This entry owns every request to the Mihomo external controller +-- (http(s)://host:port) and publishes the results as shared "mihomo.*" state. +-- The widget, panel and shortcut never touch the network; to make the service +-- act they write a command table to "mihomo.command": +-- +-- { op = "select", group = "", proxy = "" } +-- { op = "mode", mode = "rule" | "global" | "direct" } +-- { op = "delay_test", group = "" } +-- { op = "restart" } POST /restart (core re-execs) +-- { op = "close_connections" } +-- { op = "refresh" } +-- +-- Endpoints used (MetaCubeX/Meta-Docs "API" reference): +-- GET /version /configs /connections /proxies polling +-- GET /traffic streamed (httpStream) +-- PATCH /configs {"mode": ...} switch proxy mode +-- PUT /proxies/ {"name": ...} select group member +-- GET /group//delay?url=..&timeout=.. latency test +-- DELETE /connections close all connections + +local MODES = { rule = true, global = true, direct = true } +local DEFAULT_TEST_URL = "https://www.gstatic.com/generate_204" +local GROUPS_REFRESH_EVERY = 5 -- every Nth tick, re-fetch /proxies +local STREAM_RETRY_EVERY = 5 -- ticks between traffic-stream retry attempts + +-- ── Settings ──────────────────────────────────────────────────────────────── + +local settings = { + host = "127.0.0.1", + port = 9090, + secret = "", + use_https = false, + insecure = false, + test_url = "", + interval = 2, +} + +local function reload_settings() + local host = noctalia.getConfig("host") + local port = noctalia.getConfig("port") + local secret = noctalia.getConfig("secret") + local test_url = noctalia.getConfig("test_url") + local interval = tonumber(noctalia.getConfig("refresh_interval")) or 2 + + settings.host = type(host) == "string" and host ~= "" and host or "127.0.0.1" + local port_number = tonumber(port) + settings.port = (type(port_number) == "number" and port_number >= 1 and port_number <= 65535) + and math.floor(port_number) + or 9090 + settings.secret = type(secret) == "string" and secret or "" + settings.use_https = noctalia.getConfig("use_https") == true + settings.insecure = noctalia.getConfig("allow_insecure_tls") == true + settings.test_url = type(test_url) == "string" and noctalia.string.trim(test_url) or "" + settings.interval = math.max(1, math.min(60, interval)) +end + +local function base_url() + local scheme = settings.use_https and "https" or "http" + return `{scheme}://{settings.host}:{settings.port}` +end + +local function auth_headers() + if settings.secret == "" then + return {} + end + return { `Authorization: Bearer {settings.secret}` } +end + +local function json_headers() + local headers = { "Content-Type: application/json" } + for _, header in auth_headers() do + table.insert(headers, header) + end + return headers +end + +-- ── Shared state ──────────────────────────────────────────────────────────── + +local state = { + connection = { + status = "connecting", -- connecting | online | offline + host = settings.host, + port = settings.port, + version = "", + meta = false, + error = "", + }, + config = { mode = "rule", mixedPort = 0, port = 0, socksPort = 0, allowLan = false, ipv6 = false }, + traffic = { up = 0, down = 0, upTotal = 0, downTotal = 0 }, + connections = { count = 0, downloadTotal = 0, uploadTotal = 0, memory = 0 }, + groups = {}, + delay = {}, +} + +local function publish(key) + noctalia.state.set("mihomo." .. key, state[key]) +end + +local function set_online() + state.connection.status = "online" + state.connection.error = "" + publish("connection") +end + +local function set_offline(err) + state.connection.status = "offline" + state.connection.error = err or "" + publish("connection") +end + +-- ── HTTP helpers ──────────────────────────────────────────────────────────── + +local function request(method, path, headers, body, on_done) + local req = { + url = base_url() .. path, + method = method, + headers = headers, + } + if body ~= nil then + req.body = noctalia.json.encode(body) + end + if settings.insecure then + req.allow_insecure_tls = true + end + noctalia.http(req, function(res) + on_done(res) + end) +end + +local function success(res) + return res.ok and res.status >= 200 and res.status < 300 +end + +local function decode(body) + local ok, data = pcall(noctalia.json.decode, body) + if ok and type(data) == "table" then + return data + end + return nil +end + +-- ── Polling ───────────────────────────────────────────────────────────────── + +local function poll_version() + request("GET", "/version", auth_headers(), nil, function(res) + if not success(res) then + local reason + if res.status == 401 then + reason = "unauthorized" + elseif not res.ok then + reason = "connection failed" + else + reason = `HTTP {res.status}` + end + set_offline(reason) + return + end + local data = decode(res.body) + if data then + -- Some builds report "v1.19.0", others "1.19.0"; normalize so the UI + -- never shows a doubled or forced "v". + state.connection.version = tostring(data.version or ""):gsub("^v", "") + state.connection.meta = data.meta == true + set_online() + end + end) +end + +local function poll_configs() + request("GET", "/configs", auth_headers(), nil, function(res) + if not success(res) then + return + end + local data = decode(res.body) + if data then + state.config.mode = type(data.mode) == "string" and data.mode or state.config.mode + state.config.mixedPort = tonumber(data["mixed-port"]) or 0 + state.config.port = tonumber(data.port) or 0 + state.config.socksPort = tonumber(data["socks-port"]) or 0 + state.config.allowLan = data["allow-lan"] == true + state.config.ipv6 = data.ipv6 == true + publish("config") + end + end) +end + +local function poll_connections() + request("GET", "/connections", auth_headers(), nil, function(res) + if not success(res) then + return + end + local data = decode(res.body) + if data then + state.connections.count = type(data.connections) == "table" and #data.connections or 0 + state.connections.downloadTotal = tonumber(data.downloadTotal) or 0 + state.connections.uploadTotal = tonumber(data.uploadTotal) or 0 + state.connections.memory = tonumber(data.memory) or 0 + publish("connections") + end + end) +end + +-- ── Proxy groups ──────────────────────────────────────────────────────────── + +local function merge_delays(group_name) + local delays = state.delay[group_name] + if type(delays) ~= "table" or type(delays.byName) ~= "table" then + return + end + for _, group in state.groups do + if group.name == group_name then + for _, member in group.members do + local delay = delays.byName[member.name] + if delay ~= nil then + member.delay = delay + end + end + end + end +end + +local function poll_proxies() + request("GET", "/proxies", auth_headers(), nil, function(res) + if not success(res) then + return + end + local data = decode(res.body) + if not data or type(data.proxies) ~= "table" then + return + end + + -- Every proxy (and nested group) carries a `history` array with the last + -- known delay from mihomo's health checks; 0 means the last probe failed. + -- Use the newest entry as each proxy's latency so the panel can show + -- per-node latencies without waiting for a manual test. + local proxy_delays = {} + for name, info in data.proxies do + if type(info) == "table" and type(info.history) == "table" and #info.history > 0 then + local last = info.history[#info.history] + if type(last) == "table" and last.delay ~= nil then + proxy_delays[tostring(name)] = tonumber(last.delay) or 0 + end + end + end + + local groups = {} + for name, info in data.proxies do + -- Any entry with an `all` list is a proxy group (Selector, URLTest, + -- Fallback, LoadBalance, and Relay on forks that still ship it). + -- Filtering by type would silently drop group kinds we did not think of. + if type(info) == "table" and type(info.all) == "table" then + local members = {} + for _, member_name in info.all do + table.insert(members, { + name = tostring(member_name), + delay = proxy_delays[tostring(member_name)], + }) + end + table.insert(groups, { + name = tostring(name), + type = tostring(info.type), + now = info.now ~= nil and tostring(info.now) or nil, + hidden = info.hidden == true, + testUrl = type(info.testUrl) == "string" and info.testUrl or DEFAULT_TEST_URL, + members = members, + }) + end + end + table.sort(groups, function(a, b) + return a.name < b.name + end) + state.groups = groups + for _, group in groups do + merge_delays(group.name) + end + publish("groups") + end) +end + +-- ── Traffic stream ────────────────────────────────────────────────────────── + +local traffic_stream = nil +local stream_attempt_tick = -100 + +local function start_traffic_stream() + if traffic_stream ~= nil then + return + end + traffic_stream = noctalia.httpStream( + { + url = base_url() .. "/traffic", + headers = auth_headers(), + allow_insecure_tls = settings.insecure, + }, + function(line) + if line == "" then + return + end + local data = decode(line) + if data then + state.traffic.up = tonumber(data.up) or state.traffic.up + state.traffic.down = tonumber(data.down) or state.traffic.down + state.traffic.upTotal = tonumber(data.upTotal) or state.traffic.upTotal + state.traffic.downTotal = tonumber(data.downTotal) or state.traffic.downTotal + publish("traffic") + end + end, + function(result) + traffic_stream = nil + if result and not result.ok then + stream_attempt_tick = -1 -- retry soon + end + end + ) + if traffic_stream == nil then + stream_attempt_tick = -1 -- could not start; retry later + end +end + +-- ── Commands ──────────────────────────────────────────────────────────────── + +local last_cmd_seq = 0 + +local function run_delay_test(group_name) + local group = nil + for _, candidate in state.groups do + if candidate.name == group_name then + group = candidate + end + end + local test_url = settings.test_url ~= "" + and settings.test_url + or (group and group.testUrl or DEFAULT_TEST_URL) + local path = "/group/" + .. noctalia.string.urlEncode(group_name) + .. "/delay?url=" + .. noctalia.string.urlEncode(test_url) + .. "&timeout=5000" + + request("GET", path, auth_headers(), nil, function(res) + if res.status == 504 then + -- mihomo reports a failed group latency test as HTTP 504 Gateway Timeout + -- (every node timed out or errored). That is a test result, not a + -- request failure, so surface it as such and drop stale latencies. + state.delay[group_name] = { tested = 0, timedOut = true, byName = {}, at = os.time() } + for _, candidate in state.groups do + if candidate.name == group_name then + for _, member in candidate.members do + member.delay = 0 -- every member failed, show as timeout + end + end + end + publish("groups") + publish("delay") + noctalia.notify(noctalia.tr("notify.delay_done"), noctalia.tr("notify.delay_timeout")) + return + end + if not success(res) then + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + return + end + local data = decode(res.body) + if not data then + return + end + + local count = 0 + local by_name = {} + for name, delay in data do + count += 1 + by_name[tostring(name)] = tonumber(delay) + end + + local selected_delay = nil + local selected = group and group.now + if selected and by_name[selected] ~= nil then + selected_delay = by_name[selected] + end + + state.delay[group_name] = { + tested = count, + selectedDelay = selected_delay, + byName = by_name, + at = os.time(), + } + merge_delays(group_name) + publish("groups") + publish("delay") + + local message = selected_delay ~= nil + and noctalia.tr("notify.delay_body", { count = count, delay = selected_delay }) + or noctalia.tr("notify.delay_body_no_selection", { count = count }) + noctalia.notify(noctalia.tr("notify.delay_done"), message) + end) +end + +local function handle_command(cmd) + local op = cmd.op + if op == "refresh" then + poll_version() + poll_configs() + poll_connections() + poll_proxies() + return + end + if op == "mode" then + local mode = cmd.mode + if MODES[mode] then + request("PATCH", "/configs", json_headers(), { mode = mode }, function(res) + if success(res) then + state.config.mode = mode + publish("config") + noctalia.notify( + noctalia.tr("notify.mode_changed"), + noctalia.tr("panel.mode_" .. mode) + ) + else + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + end + end) + end + return + end + if op == "select" then + local group = tostring(cmd.group or "") + local proxy = tostring(cmd.proxy or "") + if group ~= "" and proxy ~= "" then + local path = "/proxies/" .. noctalia.string.urlEncode(group) + request("PUT", path, json_headers(), { name = proxy }, function(res) + if success(res) then + for _, candidate in state.groups do + if candidate.name == group then + candidate.now = proxy + end + end + publish("groups") + noctalia.notify( + noctalia.tr("notify.proxy_selected"), + noctalia.tr("notify.proxy_selected_body", { group = group, proxy = proxy }) + ) + else + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + end + end) + end + return + end + if op == "delay_test" then + local group = tostring(cmd.group or "") + if group ~= "" then + run_delay_test(group) + end + return + end + if op == "restart" then + state.connection.status = "connecting" + state.connection.error = "" + publish("connection") + noctalia.notify(noctalia.tr("notify.restarting")) + request("POST", "/restart", auth_headers(), nil, function(res) + -- The core re-execs and drops the connection mid-response; a transport + -- failure with no status is the expected outcome, anything else is an error. + if success(res) or (not res.ok and res.status == 0) then + return + end + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + end) + return + end + if op == "close_connections" then + request("DELETE", "/connections", auth_headers(), nil, function(res) + if success(res) then + state.connections.count = 0 + publish("connections") + noctalia.notify(noctalia.tr("notify.connections_closed")) + else + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + end + end) + end +end + +noctalia.state.watch("mihomo.command", function(cmd) + if type(cmd) ~= "table" then + return + end + local seq = tonumber(cmd.seq) or 0 + if seq <= last_cmd_seq then + return + end + last_cmd_seq = seq + handle_command(cmd) +end) + +-- ── Entry-point callbacks ─────────────────────────────────────────────────── + +local tick = 0 + +function update() + tick += 1 + noctalia.setUpdateInterval(settings.interval * 1000) + + poll_version() + poll_configs() + poll_connections() + if tick % GROUPS_REFRESH_EVERY == 1 then + poll_proxies() + end + + if traffic_stream == nil and tick - stream_attempt_tick >= STREAM_RETRY_EVERY then + stream_attempt_tick = tick + start_traffic_stream() + end +end + +function onConfigChanged() + reload_settings() + state.connection.host = settings.host + state.connection.port = settings.port + publish("connection") + + if traffic_stream ~= nil then + traffic_stream.stop() + traffic_stream = nil + end + stream_attempt_tick = -1 + + poll_version() + poll_configs() + poll_connections() + poll_proxies() +end + +function onIpc(event, payload) + if event == "refresh" then + poll_version() + poll_configs() + poll_connections() + poll_proxies() + elseif event == "cmd" and payload then + local ok, cmd = pcall(noctalia.json.decode, payload) + if ok and type(cmd) == "table" then + handle_command(cmd) + end + end +end + +-- ── Init ──────────────────────────────────────────────────────────────────── + +reload_settings() +state.connection.host = settings.host +state.connection.port = settings.port +publish("connection") +publish("config") +publish("traffic") +publish("connections") +publish("groups") +publish("delay") + +poll_version() +poll_configs() +poll_connections() +poll_proxies() +start_traffic_stream() diff --git a/mihomo-control/shortcut.luau b/mihomo-control/shortcut.luau new file mode 100644 index 00000000..9726e07d --- /dev/null +++ b/mihomo-control/shortcut.luau @@ -0,0 +1,33 @@ +--!nonstrict +-- Mihomo Control — control-center shortcut. +-- +-- Quick toggle for the proxy mode: clicking switches between rule and global. +-- The tile shows the current mode and lights up while global mode is active. + +local function current_mode() + local config = noctalia.state.get("mihomo.config") or {} + return config.mode or "rule" +end + +local function render() + local mode = current_mode() + shortcut.setLabel(noctalia.tr("shortcut.label", { mode = noctalia.tr("shortcut.mode_" .. mode) })) + shortcut.setIcon("cat") + shortcut.setActive(mode == "global") + shortcut.setEnabled(true) +end + +noctalia.state.watch("mihomo.config", function(_value) + render() +end) + +function onClick() + local next_mode = current_mode() == "global" and "rule" or "global" + noctalia.state.set("mihomo.command", { + op = "mode", + mode = next_mode, + seq = math.floor(os.clock() * 1000000), + }) +end + +render() diff --git a/mihomo-control/thumbnail.webp b/mihomo-control/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..7f1898c5aff94a77e64ed5947ac27dac36cfd40f GIT binary patch literal 17120 zcmY&-V{|4>+wC25V%xTDXJTVw+t$R%#I`Z9ZQHgcww?RT^Ss~po^$#~udZ5s)up|6 z*Q!>QmXKH#0RS|_MHJN)xriqJKHu4$MHw(?aqaOkYFY-;IZRT3y2KV zSY>=AeAd@ec7T%9PV`qRLf}D`2bOH(>bJ z!aMKF^(Anq=h|1O2mOojbL1WIlJP}wvziTGVG?e`J{uVF_5NP`x$x}0HuI7z0;Ky| z`mDJR`%qYgy3IWy+y~Zv-T3{nJ(s_DVnyJHfCZHlN1VO$%(|)I8?_AFX z@Sm{HhyUjB8zHp8YG;M>&_C{#`+=z+(}m7^o1ArxNUbPB!GyR4aXGaP%{ZldQZS9x zL37MajHw_HKPXwF{YScO%;2Rh-@STJ`p^xTv4$n2mh?jM;Q!<$u>SEkFI0uU6Wukp ziA!T=ChJt!W+ie3f@3p}dFaSWuyg;dY|Ou<{xwEj>Vu7E=~TCf(eZDE3jvCDvGqDg zpZ~47P5VD}Utkoy7Qi*3I=j5TMC^PQJtau~96FC_usWz*Z$0Nz`zH!tkA*|qU}dtB zf0`8ujv^-gPdv&yruu&^#CZM*k5T1Pz2>@I3H~vt)uB-Ydu4ByMuBPM?}FC?vtQ`o zUW5X(@3Z`~?=!#tzL~kW%}_Byi|vUS3mp}h*dh}3oP%fbJRGuI(IoIMO4bRakp~T= zk*ThQi^1d0|JuAJa9~o8i7~H`X`sif|7Y#1jX!@w`NzLDQJCjbm<*~ecdQb3Xaq6U zi=v&VZn!q_)raq1ui~7JxLqY@RsM46-=sLId8R62ZsaOrX78kV&^X_ zY+|s%>12Ij6R3Q>zpn^(xkrIeB!M~fth06g7omS!E&JnmPqgzLd7MwplJgb5bh787 zO!Z(e_T{T;KnNRX;d^w>{gmZ% zTfjWgTDGe>rouS$U&G^d!oO+k>3{8!|3$QXfdbR8OQGjzHwz-Q9)=)jl99Z$+PcJn z4Sh;Rldfw?(cg|l^8U8){cGn1SI$A&jLgvhW6TyJCS#$N+1DB|O|@%Suu<(r#JsVf zFz}aYvEY9jyAe|XL;Wx7+B|npVYES(lUAE0yF!(Ebi{l~!WI$|neh_RL3}<3d!s6v zs#S}BfAT_r$D^nyq=LKVQ$_s8wr7V>(Hrbq;7|ubooDe~1K)vE13&*yeDc5O_>0!L zXTnjlkAM2IZRwWlfb{WvN06hQq?bIn=K8k5PSE5ct6^!NPB zgR24G4s1e|FfV7*!Om02q{qW;+WhI`LXk*A-lpb#O&F%sZW>^uqT{qT5A}Q|0|mI& zp%qzHS}@{FP8(KlM~Xal;AQ<_O>V%`p52p*K9-n?KTN>sN3JUr#QCWoQwt;a#$vy4 z-fh-NqTK6d=90~iS@Fw%$-Da>tyD~V60B7qg6^cgq0G(-HVFkf^n^K}e&mRwlG_NRjvN~a27>rv_YD15(U|5WmE(?} zwYd&G4nDn$SPvO(g%Jk1ri)TqsbRui^S(;Ya0Ef&wp9?F?AGE;DNO_>+x(^CU%{#V z2b=4yr<=}}y!buK;sH#SRA#l*=D$N>*rITbTcVZ?wF!Xv9O95{2!?P72gw|e--w9=IIIK9`q9k zcKeUE&E84G?k&=tJ;@_2pyB+e^R@4jdlM&&|(P&(Oe*QL#a4LQy} zYt@SrlO>l9K)Cknh%D6iUd(!qAkerB6EioIFe&j+4CbKK=EH&5kfTDsT9}^%TObp6 zW-oE|lMn+bBCOfwAjEOM!~b6e`F8WovdJAlyW{L6l__+l&GP_Y#MyymL;!#<{-Sq`v}dW~X1%5g-6t!DP!R+#1hUTReIR|) zM?;cl8}Czj`NuOzqkINka)7zA5=C==+-IHrM|=-kvaq{J&gE$kUlcwU$GJx>uqq0~ ztS+xt?$@>Tp5s!6#L&pR+XhH0S1T0ad&7PN9DyODl!}#&LXYm0aTqrX%InV4dD^5K z64S1JgS7ohCjN`zb6H?!VIC;aV1cEZGITZVa_)9D;v#Ivl12IO1((VXGRQP z;1SFKzjg}zN9`)nugfR^2)av`nII9rqpG*Ipnoq!lhj}lxsP$;CZ`Hg>O5ly&f75+ zMC>t_RVJce)WY_VTA5$wBHIdopf$lITL(quQsbtbd-P^b@|*XyMzFYtkk+W}z3Z9> z-RmF4dg~Mindy8_bN^T;8wr%kjk3}gtBffUsA}`mpeXh_^lh^w+LP(j?uC* zu(~fdzsN!b&RoW4Y-qe&@u;_UfTDU_W*K)gPNAJX&`wY0mALNWG&w@L`-}7{emFdY z0Da;`8Qg7K%VQ_PLOHBJRm5jI|zGI;eHmU}F z=^N!q7oT6ayPz7Gd{V7wkI%TPo|75Q&G+!no1`^Rw3Qu^u>O1&N?%k2cD))J?l?JoY@N!|G$%;Z<5nVPC` zG?rKf*PYW-mNaEh%fF8EQ*@$Z*UjIt0+32@uf6$|AsKxX1<%5pTn7aYxw!!d+kWZY zIZ;BVuS&Z=Pi^(Tlyu*`J~5g-qcxmF-N&Vx1UF6=7`j-uia22(HTG7sa2?nLu5JqeLhM#Ql0)nDBQ#$xkAN~7-I7%j{@oDv zT{K>SIiPNnjlr?il~;m%d=WrXnAr^O^&_*bpSL3dSiLca4esZzOIfB|it1GAdn_>t zO3L5t;!nnBW=TLl&+jW`;nfdF$HuYek>`3)4faPxvj)Ti1VGeey&uULqnF=fTt&f( zbljl@k-nMZq~N*4A<7Nl`!YjoJ0JOxGw~eu{P7#92(zIf>eW)NN&bjtx0O{XOcV^I z^Tx#CU)%4BOI~-9F3Qcf&~p;54EYER3f0KN+O@Cw*u<&hRQn}d_pGk66z@y** zMIk)Vw+4wQy@$gMEH=DOMk{axd6Ok+NL-G>=MITpQ-#HbZlk_OSaJA|ckslkUep!# zV4@c$``zUC?b%l|a#1Y_9k%}NqhM-AXFB3N;(QNOaGJz#rRc8t*!~vB?6j?LXhGb) zugL}xO#-36TjQxlv$Idnhx>Ks=-U4*n;L#CIYK(8V7$ak;3g292R-8QF$kfZQXjfu z?2}zu`Ra%~>25)n>)BPVR4{#cy6W#0Md-TkZDp3LTJ_;RE_0Fk)VhSZYx>8xi+Qto z9(N_LmNeHSS?2GQHKYZH3zf`bM)P z71w3Q><49;f3dY;za&vZ{24$IJEmh;MRrE^G!Ik;JZ8;ZMEXfW}11 zsH~0&MbbL^D`)H8EYS=fv!tO)c4iLFH_r>)5USSLKMv?dRw(Wa`g+eq$lcbuw^|L4 z+oU%Z;QVb3%XP-_ucWq?Ur7fgmn*>@xTrEwDbV#FLFH`d*OFBGL$G~rI4jDr;lz1U zbS_L}f07kZNZgq0w1g+Vl@sx1y)uP6rzb9Zy1*zeZ)vciqlIBJ*8d1=Jx+dNaSM0z zK>NiEl{isjheCRTmO<4sNY)^2)&kqQTcloiuNiUAjO=pNsh$WHNmOtroTfC}5F5G$ zgv@%Bog+;9Ja^cu%z}^HYIHnyt9IBz2$RV% zFs@Y1@7k3(0K~RAWbTbA)w(ZLaB>>;WzdqTKTjplH-_3^`8gK9;i+kLgLnIy`sPJpB2yMcsl;*gq^m{qQf6SuvwI{1|2%f10umM&~NDT z^^gRy(ssO}*TC^y+E%UYq-+MyRUVP>qy*SnV|PHeasBd)X6f30rB)T}?82kaiaI27 z7nh5#BSyM~LGt9Z6$*$cA48B{(RutDy;@{PJ&7J{TAnAEnaGz_EqC0e?NId(WabNs zDT%D82L4_-rNZ90IX=jG=#Q(2_=cVT$=i~!Par*KfZ;@io9RcX?|$USV?kqDfu5$& z>JLMC?}$fNmj;G8+O+D_{IfD}BCKL=S)Lj(bhz5f%{WRX>hqG7@$J~jzR)2HsHcRp zcqu??J(AK}I|vm)9+93nnXQ|369lKoxJ?ST>a}e)%!;-?CXNvM>#4-_ zc=Whmp0_e{e^}_;O8eQe{wBjxRdsC42`o)B(_;&ZHW=v#J3KsFoi5j$TAAGN35&$s z`if|gII1IWvD)y@Y7iZFfBy$)_>Rwqf!+8i(7C=>BwStEFM6ER6m=uoS@DDKV`0Aa zg&eb@egxjBqFd4Y3{9j1dCR2fWC!h6QfS-DuMh1ka%n-iYU<`6FofRNzvk)~2rb^r zt(*_>x!Qnq)alQ#OOr*TIubB~*00iK4>*n3nH7E<3H~%jFQ)cm)eUu^Yvv8n#CbP_ z%l&7DvbWDwVS+wnSH5y)mmK>Av-N3WhJjnCHt<{8L9~J5V$p4H;qLrkD?chkZQneXMB|cbK!rGc^zF1Apar_&_Jl;U z_a4=G#yX0lLBeth_&$FvKa>0bJ1{hZ1?sbV4EX>6iPiE*uy)cbwx5&9y4nw|M(-;F zK(u+JWV2-D4Yth(+uPgZ$P?@Oi5PA5tz-}6EZ#)DY5+h|DgVUFM(@J$&*p42zW8)& zk6fr!^9?%{|Lg!;@9v?$b{8vV2c|iE3p|q$K+Ia2iLD8Cv0y#oNGWB0d;zdsF-`J- zQoiQg!AKv^Es3+0{KaA78f$u$*J9>n6W}GBa6fs}Rir5arM@fKWSvpHc?NxdO%@x+ z4-aqr#8<1vSUs|ajRgP@(+k--AkSK;3;5l^;bO(SEAl#5StpX6f zieEwWC98<97<2xXBM_K5E8244i>Y#Xbqz4l}0%UtS?6OiUGrFUgP(RP~870#WKkKr^tcd4j2m~yfe zZ^O~mo!+xuneBZCl$Gw_qV>=(tzZPnV_@Uq+6}q_A*fey@f31Jz=y-%$dNbr^PtA! zjSF%518EwjT-JQx7%}VYy@biqZfsGKMy*qb#ksF%&4qr~fwm9ww9R2yL96J{*vC5g zK0ODH;G?|?L)Kd$86UP)5@{UwHK*+}g+H_wSW0p&WmJU)>OlIL4BNjN?^Nz171XNm zO=&XIb+-LlKtdm^Q%2RVId%y^0do|2nQEyNBEG$aKK$x+WSGv=i2C4DDo_GNHwQcA z&kZY7C>`wIY0_#F-l7pk8zv7ISjYf`iQmLpT2w2u@}tR>CI(4l)<7QL^JM<)ucopu zYVGkbJ@$*$l#w=7<3toeuOz2EL0T1+zrZo===T#XF_0VQO$u$IG}Ls{)phD_i4Yvf zR%Yq&Rdqph`c3{?TA^m>CAqc6P@%p`ke3JvN^mV<`=>IWo(Q7pyNGVNrUL-Hs#!j( zI@gfF(WFCh+JlA(pR+gl^ODN6k}%><&1)m)Nvl+sf(XE9kngT1&Il@=6<5!if$?M? zPJ7E1Wqn^%FXKYr(ni#38hm9I5!T0CT6xo@2)RR@*NJ0hU=akdnjnnX@_xpBmv(3R~;Sl_EJ2z}9 zu^|?cL5sHLX$zcC2$cB*Xa8qvA0<;vBQ{8)>!EHSJ36hp!_;L@%~0}jnA4yH`#+&jvtqTm6aRX=vGcbtX11s+JS14&e3o(R`C zPdW*4;XdDnlh5kIPh|M5uKE`Eqw;V-_R)M+9#ei_b#6O1hjdtSKTvtCW3lD$A#eU@ zA-H2#YpN7paO$qCpi{4aU(CAg$dnDjXN#s9qhpf)voS*zl5HS90Y4_NiD-&>#R0q= zHDANPKY+ZOV%68l=2M)~yU-N8E^%CUa3vv%~ z{_ycRMM<_DD{SXf!0w_V(JC5tc;%S{aZWCR1A7uzqZLV%n;m}?W__V*78BP_C218~ z3_A-nZ%|OkN2KknP>PvAMQ;Fkz69%~fuG@pvjxDKsNPowKqjtaPwj|>#0xcMbD)Ri zaq9SsJY+)W&b{46$iW?qrkSwW-mkFDKio@pr^RG%ih-YMH(V}`*LTuLTZ4btM}DAz zZ*S9)OAe2XA#-i&kn+pQFt*|=i(IJ*gUbA3XM&y_^wjeDrtjE8sdCqfn$L6O?Q4;n zqXI{UdI_5=lYu|p5X`jl8b8LG8j1J_FbdHTW(APqH^{AHYaF1vPIZHg!S?BQ8fOWd z-_pbP%OdGRO335#UPZXlBmqU9XFY{q9~l0!>N__tJzMJR8~v)%V!e|{aC9~4j&1y@ zB!=8h#VABlJT)e0`s;N+`ozs~UBy=me<*!#Z{(?3=E5mFQC|EwK!_^_qej|$sdvZ# zfb_B7`Ho=E<&v5uy3JABCDzsdTXzfYnK$A{rV59)0QL-Dz9|JD%#v~t)KkdhBxM<| z`-#~SZ%8d#5!_fXnqBj4>=n06S5=QQP8dD2pVSjCeD#6sSI7~#1U3ozZl3%H<8a+w zP#2Bu3n;%iyYcbjFaoHwPSSm}mq{U5kOD>`-(TbjqNJElNwPoX)zR zOp;M_LNqKb%8^xyl(L?wegVz~TI1dkQd?47Z())jzFL$~bll)IBex>wKHOoJ%>wV zTXb8tw%mMm#8n%!JT@1asUpK#tf?r@LX!R@@nUS1ro&RwC7ZWDMi+9*+IK0Vm2i&0 zJi!s?plE~O=Pmdx@*0rY`i=5b|A@Ihppo}*E0dTojYx@+XTfH`6;eptvi4xEQ8n=4 z^!qqag-Ui&jYdaBB2q+N%_k%exD_gkljk4|X+2lnl(+jSjkkMdB{cE-_N4pnOnc@| z_~<3t%)b+p`e$NbN0=JsEDTH=!|PLwbY%H^Y1(*`S~9P-1>z2~6xf?KTh!=i(N!#1 z67PFaAB6Hx|6rGpA_?4jJJmQM5Ygke78z1nR3XqxNE9{VAqi&1cjneX4xIZA&*8?6 zMmfqhAazY#TwXCr)au98Vj(>Kn(qrzMjqNT;N3D=!DK)ajXl?&w=zjm5+vNs^@MaMHqwBC)Q8eHIm&pM`@8#xs<)yuq6}RUs zpd8E&#ex?0^sXL(-0}m3AD}tu#`uuVg=zzUNVsoSek^N{GeN(s>WN!)P#_K8uWjjg zFC40fmFeYZTVnZ>!wtxSlVA)v=GMO=%p5QnvQ{8c^~865uKHAb>f37pESqp&S07mKZg0K1Fas1yMJ00?AH zx7R9wlr_|?wiD`jMS0HA9F4<_NW=&V%8bfu6^c{NsH#?3E%0s~LqXXiRFyNh5BSiB zowF_Yc<$+`zmJ-hu2EA1Oa}|i4Cbj?Mzq)0C9wK_ZFk^2z!6jak^#|`$IAAmd^uO~ zaD%pVaFN!h;ru3q+_LFvYn*nE^EC~_v_@pHeN4XQp_74YOuOuq1?6tVXNBNepXo5# zTQ4CHUfE1g=8J?EEZyg}OvHFi?WgAjAl3{ZreZ@+&L->zvGPrR;Hq*)_tWs(c2gYp zHP?T9`?C@mcsu8p_cAABZbAF$FvlC>ElvRQy9Uo@jmFE3E zf{2cNpYJ)BnjgZQN*+T968Q7`wJqwV5*ovAcke`*taHeZSEU1M?A==XRQpFN{SdhE zm_UN&hM(6zrg9f`Z^Id|{G@$K5rqh!o^M?4ynHq2IEX_^6Tz3hs zr}mdc$uSu`ivcKI+EOcMTk>4CRwoP_qZp#x;)k3#9;YBtnmt+q%w{%WR6Ov zJ8;ycc~I;BTAO`%BS7_D2n@DP!Tc{cygNJ zzE7ak$(|yID!tyJ?z&H0Nf+-PNLWI&lMUV~jEf(`mi=SJTHXkKwQ{e%-;vbC42OFL z-o#XbyH${qQw=mN=-!W_T-MU*C)W>qH$muTR4rIi9&I|)v@pI4&;fLFAJ^OC7 z3Xz+txF~VRw*?Dd05-NWAj)+G zx=IcbPx)ynj;IdfwuD-{tS|%bH@+qvxoVqNC#QzWI5lZGX{kD*b+I<+RN;K~M~Ht- zMw-Amx`0J9Wbu+&W|=ln$7^ckT9y%f`{8FWs1OJGcdAc+x ze2`Kl2tRl@Eo4;-kT!7@G*&C})MZlw_c_uQwxpEv4qI$6@T{1WXIF7bRS+TGziZgf zBoRBBHS;K8PH)#{VPgikV7qSW?|cNcO0mU)YN@aNisxxo^^EM#vDXRpM>Urask3VK zaPWV(#n@q`s-2bb*Z0B0+lCA9Sn}i^1{v5+IyCpv5c>|8IVzSCzfXf89NY`>33o#2K0pM;!Ce?}8MDsw|Q(@Gzh8?NVvu z3!7B35ckOLj)Y&un%{jo&fSPBQ%a(`#8E-X+`@mk+F3N9tFS(TlL0c+_|1i2+ez?N zei}tz$_j8`qaRZpZcWFu&Tee)$ux!ULDEp%%gUX&eBOb>Y&kQQp;3d-OUv0a0D4_6XZg# zwAvD-HIL(I+gBgbDVs)kn2WmJuA%2DMJ(-Wcs0P~_+nGhr zDGPcvOx<}7JoG4+On|v#`5{H#*{>b zCgz-lAwgF2ginqa2us;Z>~Wcie#>_r@P4chcc4tsl2?3@(STQi16q~EX!|TcbkOq2 z+N@lHS#Cof#aQm3fmcqbl+)gakp_27X+3+#0FUWl4f|t%Dj57IWS-GGh@H@ZEI2u_ z81-m|E0PdL&p!sR*i~yhW)S*%bLI?=asA2RVkehf8ELu?JA&qqO`|&ffFh)cGicyr zjURDOt!|`ME!K>aNY|VXfW7Tjf&UUhDlvrMqk`R6a9hjuas!Tth2aQ`&6^oWI5E^} z3o_j*W^JZ%fpYT>=HUNIstLztdYO?`y7HI#Z5D&6xPcgKwz3eK^x!xqS7!@}(nknZgsuJg zmSgaO7zb2P;h14y_q|a6(f3K@W=?C6pftCAw5RGX%6tudhWW&_EPA;S?vUhypGe@~EgXr^(}Z}@ zpYJ`BcLh+FZ$NAn8a0elY%(hI?{F`*iMcpmtXqZZAEwK*mx$sTmBTFf-peGD)2HqQQhbk zt1NR~R=rYzk%k>HuB4KFQJpQZUYdn2F<%k9lK&x|Q4pnJ(bK-9{-;tN7f6-$9r8us z(i7&MKXro#u=sQoYD3xtYup6BPuvlR2hYJJ!3mu~2f+Z9GtD$&5rTb0) z=Y~%)4|eYYEI<8%f@Y9GI2GkI>YG12ABjfcWbaH*ku!l`e6 zs%{%0dg-7m2I2LReBV!!^G>zj1}}pwrDg>l7g#`iLu-{E9_D6`C5aq^vOOnW#M^Bn zfZO#s?Y_i_TvI$HlWE!cnwDKnaO^Cl2vgK|(sl2RBYHh1a)oz>i*2D{x|M~eRZM)8 z`BnQrE4@dL-O{{PI>FV{5)({QFVK?kl({E?VTq!C^R>p z;nirCOEx?TB_R5|Jj8aDfXh1rhaq-1%((&Cm|km~F9WTMkG4T1UL)jMnKd#;tQGRy z)mCMHAA~Cwd0vj!e0D3_i=bG7RNy0buT6!~Bo#5F;v&L=DSu~seq#$3VP{c8hMT?| zPD)Hd=koe2w_)SLAvUBG1eKZ!TMPAn^r7m%f8 z2A3QBrmv2$$Qrw=Y1zceth27tA2ld8H?Qzx3j@_p3K+geFF_(3q_?VaR}pp8kUtMi zzddYX;+w0aNM|x3^{KIR+;H0Xk^-XIstFGH8!|M<6Y({9e6;aPy<4^=g}#-()9VGY zwv6Ni`;Q9lE*X#$GOu@oWilMYOUQ>};)2;+@<`HkO|LOCk!cvR6@^l0Rlev_QYmxu zC~)MS(E9ABKH4w+IgVjGo0|H0w3k`cEE(Q5Ew&t18)gz^-itoS`Z)I;v2zc_;fVf> z`4j)ZfbtpR(`lH>_4IGGeoYM@SYzKoKNMFrcyCso`b<(dWm<>B%s;U)DqvSy+uh_v ziJ%#V{Hel8lWFLR-+%E&J@H_vN~Y#Yzr_)1cWEpg%IjYi1sk{lQ3PtgiL_5Qw0nC} z5VoS)6l?qZQFIK)Uu*sHzv2zm)IMe@U~FQ4r1?BZ&TwUA{8Z{h3nWoM*BbxflN&Db zk`^b3yR|xb*rnPU+J`yhmMsB^*>Pq1^7|@2$zw)%L5Ty46p)UM0jLsosC?WW40BkjdWeoN(A!V<1*`-EbLBU}pz zf#5~1n!a@Y&M0VuCu;`!u9W$Mx_1Ua)gy91jTueAl&-lA0_v!p*=n_OG=e}L5&jWk zxIgQfy?z2aS-?r`>Vk9wSGhu-N-OHy5Ou~Dj48g-(W<;x+T0DmGyDzCMMTwoYYZ?y z!ia5TDPdiVp$$^tqN{Sx??^RDfA%x+$JTbpMGIRo?Z~ahqrdUORH}IdsY9FP3UQyu zcS-h(H5=hK=JyWYrXR1km`T=+Eu^1{j!rRcrbu#g2%#RM2gd>_rqqgaGj1_my}3Nd zKa(FhkYP5wVx{4AvXFVTR|=so+!_LVj&K_nY%Fpgtos#{MVVmu3+&=RRuscrrh(L5 zwNA_v(x5nEYUShv8!lqjjukiTcnyX{_njewal|dQhMD}Mm+0i)_`a9Gk+E5@X{$>Pqx~eP=NTyrx5~{&5!Sf&p`_|yr7EKP z_Mt=^OYsmIwpLt}^tzuK*JKHR@6;w=>X6{%^v*J|2Tn^Vx<)u@2e`+QH#&VNp$%&s z-_>mI2{-PS1~Y0e1VaM=NzyYDzonhy&P=17x-i38PpgGbFWC>ePBhCU=^RGmaPzAp zvu=C4Gtfgi(!-&g-rfg_!u=}CK6sGL-c^bT`6Gm#mGpDS-O{=z%;_;>@&yVYOVwM9 z=T0SVIee4ZZI)hM>m&`}HM!cOR$*-z@v|mToTItk}!$by>ngNNpWs_!ZEyM&K$peI!rMZlrJogzg8|Lb%9iB$k+dT|5jkV z9$S-*Hu!ZM-9auKzkARG=2u{J%L}pM*4QD0rpmyTUY!<@=P~xe{g6(VM0a(+sQcA9 zu~>P4y)`1%a7V>s9D^Nanh#~Mxz{J%UAq_3$7$hqrURV|^0mI z_cCPMd%gw`w5Uu72BpLkN0xteIQb~8nk>)Pxk#HQ{F=*Q0D)4jL9s{lCE7y6F}lw% z6tuNuIAYH*PEr$nsl>ow2q&fdol`R>CjP2~i9MzRXCC8;_A3ur@e$0vJ(m*ghx_k* z1OlCEqZ_WlrCsk%l8B8t&LX!@Yb{=rWB&BK4-JhJ4=%%STRF+)XuZLx&`X*Jpl5qPAW4TG(I22@)6dT|cZ% zSWv0gA0UAAg<%_W#ZB`+L|ZuSL0W$nbvEh;>ZNY)C9f!t+%%kpvC?T6#sl0A=JP6s`{67=4;KJjPwDzTvsem1?J_cyFU?I5 zcrV=C9FgbS`(fo2ZsT(6&EPYHP}!?)($goq$vb!>+>*-G&djmjRUAWqJOsfBw6_X* zQ(OYwa&IzR515wmjS1}Z=)JIh524O7gTHF!B-W@G0 z6Gc3?Q+wZG1$DLU7=vP-9iF)B^$0&DCJGBGToNYmcmdTy*^&JKV|B1bpwD|Xea}TT zA>J?-Hlu1n6H&1{;@>WZ6yqy@X{!!Qm+fJ_GsOpuA>Hs(CrN5iODySr+N}h025JeM zXM_5HvI_)3eZ}e^Z3GAy@5Q;og=%Ut6;|L&g@9{asHnyLOnM7wcBf5k=|9GW>5DwE z{Vk@FZ>qG-=eDo3en)jIY_bEs-x1GmYud?3xwN9K;v>)~vJFw5o#L2)C51%yYEpqo zoCz|#x{&|#NufgDuf0U9x6-xTQ={ov{rj+ol)IYRnJo3?u`fJX`5@#___Go2CdDV-yJqi{Zn})8Cg(AdkP5j zQWxANO`A#LI3>1P&Cj-6ywr|Mw~FLC^TRJ=bGsQ6^oD_m60`hhmJg=g(W3D|@$>xRT(%~H29no?i-YT97 z8*1v}Pw?E^{s7UoXtsDYq3JVi-ck?6I!8b|;^HW%Zg;~%rN3R3{&hM2GaD@-&sSnG zoEIqR5fZu>qyFLpN%duMF*)+Pw zFohrxT7@|-G44d_4{GI56^}`D+kGKUBM>5d%&|DDoiqFA=?VFUUzU+F<(}9tr3v1^ zO~Xm(yTYk==Wz3O6_s)Cc$0aw)z7RZ`U}~aSVUs2N(~a*D~ct)qEJUy@+O3-a@RP( zufZx8gvv(~;@eB(H-mvK>>Cf9=bkO z>}|qA#|W9-9q4jPQ^n439mUk)34?KZGP#P?9OM`}fZ-Ukv&Vz-_#f;O%>qV&tkb<~ zJ#h27*|>6Y32VZGej}RC(4J?VWvqDAG}m=^m$qA`WjcCm10MIUqnc((ogQIwvF846>#Qns3D0uM;k8~-_fbD((LqWj2I31Pgv)4_=?Qa zwzy~5Rk7q_9!E06xR2lhMLVHHrN@BE)Q!hRZ$&WloaFlO)s3xrPn1B3mSOR<1+fi7 zYDoB2`7!*K`f-t9unYL^lw2OuBA1l4b!`jkVs}d;3u}f@LaT({@%=O4)VMg6dS@#< zNw5+&MvcHcKlhXy2;Jtj1^y{3@}w-=^NVTM2I z*uSFh{xn}g{*dl=uc6rBM8Z3cJ6AG$`qB~G_Qi6P=oBreV%kTxDhxOj^IHmj`Newe zq`mR#t0F+@$Ui7UMwz3Mb9>B`PFEdc{L>*L$0^XlZew@aP4QGhs^v97 zvBLk}h+Kms?hB^EEr20ZWU zC*2pQ7R6~xcl3;IXkXSIf1SzcGo!E%*pG{9xV+rmfqVo6zV((pdr!?8NpnVy#em^W z8{9f$1rw?)@ti4Bb-QK!#=L8Nj_v90so&kQ50~Zwgs0&!zdrUnRGOWKK9Jj#@|c38 z+!sf$O(g9-wvOB@-D9asu9#s%tzf~zqw4PYOLx=9J z9@_!N@NOJ^Ic>~cvX8l-!`JpsJ%HvHjJ$Krhb~aLj3YQkS{d%_$WFQ36VD&X6vvc< zoT|33P4!^w5Xb*0fee|M)cqDu90xaH~K7Wzq~kVXUb&!DqkmIVq@s?aK7ZEOviq(D6kmrD9DK)Y&1=%$^aPsIqNJ4N5|KvL_8wMokS?(CVIh1gVq+7E`38gE~R zgsFxCQ`pqcuk7!y@eaEC*aV~g#m=ky=q!=gR7#5b#CWmqWb!>+=}k`r9laxPeR^;& zCJ0})$4v7KZF`AXt3uM;zkvcR(9GDY^uHR-f5>#Qt1LSuF^Fydj@2(bWRMEY`ac1s z0b2faexeEtvi=^werqpEtve4F`!Id9@0st|JMcTR6xy{bPYn$6#}7b~6lR~l98|!8Q~TaSkz*( z8MQ)WoTskBl4LgLiNf26;EUaZ+#3JRAXR;LEky{^^#J6A^&%= 1024 * 1024 * 1024 then + return string.format("%.2f GB/s", value / (1024 * 1024 * 1024)) + end + if value >= 1024 * 1024 then + return string.format("%.1f MB/s", value / (1024 * 1024)) + end + if value >= 1024 then + return string.format("%.1f KB/s", value / 1024) + end + return string.format("%d B/s", value) +end + +local function render() + local conn = noctalia.state.get("mihomo.connection") or {} + local config = noctalia.state.get("mihomo.config") or {} + local traffic = noctalia.state.get("mihomo.traffic") or {} + local connections = noctalia.state.get("mihomo.connections") or {} + local groups = noctalia.state.get("mihomo.groups") or {} + + local online = conn.status == "online" + local mode = noctalia.tr("panel.mode_" .. (config.mode or "rule")) + local icon_path = "icon-offline.png" + if online then + icon_path = "icon-online.png" + elseif conn.status == "connecting" then + icon_path = "icon-connecting.png" + end + + local container = barWidget.isVertical() and ui.column or ui.row + barWidget.render(container({ gap = 6, align = "center" }, { + ui.image({ path = icon_path, width = 16, height = 16 }), + ui.label({ text = mode, fontSize = 12, color = "on_surface", fontWeight = "medium" }), + })) + + local status_value = "Offline" + if online then + local version = tostring(conn.version or "") + status_value = version ~= "" + and noctalia.tr("widget.status_online_with_version", { version = version }) + or noctalia.tr("widget.status_online_plain") + elseif conn.status == "connecting" then + status_value = noctalia.tr("widget.status_connecting") + elseif tostring(conn.error or "") ~= "" then + status_value = noctalia.tr("widget.status_offline_with_error", { error = conn.error }) + else + status_value = noctalia.tr("widget.status_offline_plain") + end + + local tooltip = { + { key = noctalia.tr("widget.status"), value = status_value }, + { key = noctalia.tr("widget.mode"), value = noctalia.tr("panel.mode_" .. (config.mode or "rule")) }, + { key = noctalia.tr("widget.down"), value = `▼ {format_rate(traffic.down)}` }, + { key = noctalia.tr("widget.up"), value = `▲ {format_rate(traffic.up)}` }, + { key = noctalia.tr("widget.connections"), value = tostring(connections.count or 0) }, + } + for _, group in ipairs(type(groups) == "table" and groups or {}) do + if #tooltip < 14 then + table.insert(tooltip, { + key = tostring(group.name or ""), + value = tostring(group.now or "—"), + }) + end + end + barWidget.setTooltip(tooltip) +end + +for _, key in { + "mihomo.connection", + "mihomo.config", + "mihomo.traffic", + "mihomo.connections", + "mihomo.groups", +} do + noctalia.state.watch(key, function(_value) + render() + end) +end + +function update() + noctalia.setUpdateInterval(1000) + render() +end + +function onClick() + noctalia.togglePanel(PLUGIN_ID .. ":panel") +end + +render() From c295e24c88cf3d1286569044bf299e990ef7b3a7 Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:09:26 +0800 Subject: [PATCH 2/8] Add Chinese (Simplified) translation --- mihomo-control/translations/zh-Hans.json | 90 ++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 mihomo-control/translations/zh-Hans.json diff --git a/mihomo-control/translations/zh-Hans.json b/mihomo-control/translations/zh-Hans.json new file mode 100644 index 00000000..0fc5c677 --- /dev/null +++ b/mihomo-control/translations/zh-Hans.json @@ -0,0 +1,90 @@ +{ + "settings": { + "host": { + "label": "主机", + "description": "Mihomo 外部控制器的地址或 IP。" + }, + "port": { + "label": "端口", + "description": "Mihomo 外部控制器的端口(默认为 9090)。" + }, + "secret": { + "label": "密钥", + "description": "Mihomo 配置中的外部控制器密钥;未启用认证时留空。" + }, + "use_https": { + "label": "HTTPS", + "description": "使用 https:// 而非 http://(external-controller-tls 或 TLS 反向代理)。" + }, + "allow_insecure_tls": { + "label": "允许不安全的 TLS", + "description": "控制器使用自签名证书时跳过证书校验。" + }, + "test_url": { + "label": "测试 URL", + "description": "延迟测试使用的 URL;留空则使用各策略组配置的测试 URL。" + }, + "refresh_interval": { + "label": "刷新间隔", + "description": "状态轮询间隔(1–60 秒)。" + } + }, + "panel": { + "title": "Mihomo 控制", + "status_online": "在线", + "status_offline": "离线", + "status_connecting": "连接中", + "mode_rule": "规则", + "mode_global": "全局", + "mode_direct": "直连", + "refresh": "刷新", + "traffic": "流量", + "connections": "条连接", + "memory": "内存", + "proxy_groups": "策略组", + "no_groups": "未找到策略组。", + "delay_test": "测试延迟", + "restart": "重启", + "timeout": "超时", + "no_members": "无成员", + "members_count": { + "one": "{count} 个成员", + "other": "{count} 个成员" + }, + "hidden": "隐藏", + "online_with_version": "{version} · {endpoint}", + "online_plain": "{endpoint}", + "offline_with_error": "{error}", + "offline_plain": "{endpoint}" + }, + "widget": { + "status": "状态", + "mode": "模式", + "connections": "连接数", + "up": "上传", + "down": "下载", + "status_online_with_version": "在线 · {version}", + "status_online_plain": "在线", + "status_connecting": "连接中", + "status_offline_with_error": "离线 — {error}", + "status_offline_plain": "离线" + }, + "shortcut": { + "label": "Mihomo:{mode}", + "mode_rule": "规则", + "mode_global": "全局", + "mode_direct": "直连" + }, + "notify": { + "mode_changed": "Mihomo 模式已更改", + "proxy_selected": "已选择代理", + "proxy_selected_body": "{group} → {proxy}", + "delay_done": "延迟测试完成", + "delay_body": "已测试 {count} 个节点,选中 {delay} 毫秒", + "delay_body_no_selection": "已测试 {count} 个节点", + "delay_timeout": "所有节点均超时(504)——请检查测试 URL", + "restarting": "Mihomo 正在重启", + "connections_closed": "所有连接已关闭", + "request_failed": "Mihomo 请求失败" + } +} From 42af28957cef59d40323106e61db1942653a079b Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:16:02 +0800 Subject: [PATCH 3/8] Add test-all latency button Adds a Test all button next to the Proxy groups heading that runs latency tests on every group sequentially, with a single summary notification. --- mihomo-control/README.md | 5 ++- mihomo-control/panel.luau | 11 ++++- mihomo-control/service.luau | 54 ++++++++++++++++++++++-- mihomo-control/translations/en.json | 2 + mihomo-control/translations/zh-Hans.json | 2 + 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/mihomo-control/README.md b/mihomo-control/README.md index ad13d321..13fbd34f 100644 --- a/mihomo-control/README.md +++ b/mihomo-control/README.md @@ -32,7 +32,8 @@ checks and refreshed by the group's **Test latency** button. Each card also shows an overall latency (the selected member's, or the best tested one) right in its subtitle, visible without expanding. Member lists are collapsed by default; click a group header to expand it. Click a member to select it; the -current selection is marked with a dot. +current selection is marked with a dot. Use **Test all** next to the Proxy +groups heading to run a latency test on every group at once. Add the **Mihomo: Rule** shortcut from Settings → Control Center shortcuts to quickly toggle between rule and global mode. @@ -63,7 +64,7 @@ noctalia msg plugin mdj2812/mihomo-control:service all cmd '{"op":"mode","mode": `refresh` re-polls version, config, connections and proxy groups. `cmd` accepts the same command tables the panel sends (`mode`, `select`, `delay_test`, -`restart`, `close_connections`, `refresh`). +`delay_test_all`, `restart`, `close_connections`, `refresh`). ## Notes diff --git a/mihomo-control/panel.luau b/mihomo-control/panel.luau index 37fe31a8..c840dfa6 100644 --- a/mihomo-control/panel.luau +++ b/mihomo-control/panel.luau @@ -371,7 +371,16 @@ render = function() } if #groups > 0 then - table.insert(body, section(noctalia.tr("panel.proxy_groups"))) + table.insert(body, ui.row({ align = "center", gap = 8 }, { + section(noctalia.tr("panel.proxy_groups")), + ui.button({ + text = noctalia.tr("panel.test_all"), + variant = "ghost", + onClick = function() + send_command({ op = "delay_test_all" }) + end, + }), + })) for i = 1, #groups, 2 do local row_children = { group_card(groups[i]) } if groups[i + 1] then diff --git a/mihomo-control/service.luau b/mihomo-control/service.luau index e0f885c0..bd0f24b3 100644 --- a/mihomo-control/service.luau +++ b/mihomo-control/service.luau @@ -324,7 +324,15 @@ end local last_cmd_seq = 0 -local function run_delay_test(group_name) +local function run_delay_test(group_name, opts) + local silent = opts ~= nil and opts.silent == true + local on_done = opts ~= nil and opts.on_done + local function finish() + if on_done then + on_done() + end + end + local group = nil for _, candidate in state.groups do if candidate.name == group_name then @@ -355,15 +363,22 @@ local function run_delay_test(group_name) end publish("groups") publish("delay") - noctalia.notify(noctalia.tr("notify.delay_done"), noctalia.tr("notify.delay_timeout")) + if not silent then + noctalia.notify(noctalia.tr("notify.delay_done"), noctalia.tr("notify.delay_timeout")) + end + finish() return end if not success(res) then - noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + if not silent then + noctalia.notifyError(noctalia.tr("notify.request_failed"), `HTTP {res.status}`) + end + finish() return end local data = decode(res.body) if not data then + finish() return end @@ -393,10 +408,37 @@ local function run_delay_test(group_name) local message = selected_delay ~= nil and noctalia.tr("notify.delay_body", { count = count, delay = selected_delay }) or noctalia.tr("notify.delay_body_no_selection", { count = count }) - noctalia.notify(noctalia.tr("notify.delay_done"), message) + if not silent then + noctalia.notify(noctalia.tr("notify.delay_done"), message) + end + finish() end) end +-- Run latency tests for every group, one at a time, with a single summary +-- notification at the end. +local function test_all_groups() + local queue = {} + for _, group in state.groups do + table.insert(queue, group.name) + end + if #queue == 0 then + return + end + + local index = 1 + local function next_test() + if index > #queue then + noctalia.notify(noctalia.tr("notify.delay_all_done")) + return + end + local name = queue[index] + index += 1 + run_delay_test(name, { silent = true, on_done = next_test }) + end + next_test() +end + local function handle_command(cmd) local op = cmd.op if op == "refresh" then @@ -448,6 +490,10 @@ local function handle_command(cmd) end return end + if op == "delay_test_all" then + test_all_groups() + return + end if op == "delay_test" then local group = tostring(cmd.group or "") if group ~= "" then diff --git a/mihomo-control/translations/en.json b/mihomo-control/translations/en.json index 49aa5f98..9c670859 100644 --- a/mihomo-control/translations/en.json +++ b/mihomo-control/translations/en.json @@ -44,6 +44,7 @@ "proxy_groups": "Proxy groups", "no_groups": "No proxy groups found.", "delay_test": "Test latency", + "test_all": "Test all", "restart": "Restart", "timeout": "timeout", "no_members": "no members", @@ -80,6 +81,7 @@ "proxy_selected": "Proxy selected", "proxy_selected_body": "{group} → {proxy}", "delay_done": "Latency test finished", + "delay_all_done": "All groups tested", "delay_body": "{count} nodes tested, selected {delay} ms", "delay_body_no_selection": "{count} nodes tested", "delay_timeout": "All nodes timed out (504) — check the test URL", diff --git a/mihomo-control/translations/zh-Hans.json b/mihomo-control/translations/zh-Hans.json index 0fc5c677..838ca6e7 100644 --- a/mihomo-control/translations/zh-Hans.json +++ b/mihomo-control/translations/zh-Hans.json @@ -44,6 +44,7 @@ "proxy_groups": "策略组", "no_groups": "未找到策略组。", "delay_test": "测试延迟", + "test_all": "全部测试", "restart": "重启", "timeout": "超时", "no_members": "无成员", @@ -80,6 +81,7 @@ "proxy_selected": "已选择代理", "proxy_selected_body": "{group} → {proxy}", "delay_done": "延迟测试完成", + "delay_all_done": "全部策略组测试完成", "delay_body": "已测试 {count} 个节点,选中 {delay} 毫秒", "delay_body_no_selection": "已测试 {count} 个节点", "delay_timeout": "所有节点均超时(504)——请检查测试 URL", From c5262305c4ce209064d00c27693102db6497ac82 Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:16:35 +0800 Subject: [PATCH 4/8] Unify traffic and proxy groups section styles Give both sections the same card look: muted medium-weight heading on the left, secondary info on the right, and proxy-group cards restyled as bordered sub-cards inside the section. --- mihomo-control/panel.luau | 50 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/mihomo-control/panel.luau b/mihomo-control/panel.luau index c840dfa6..ce1dcba9 100644 --- a/mihomo-control/panel.luau +++ b/mihomo-control/panel.luau @@ -169,10 +169,6 @@ end -- ── UI helpers ────────────────────────────────────────────────────────────── -local function section(title) - return ui.label({ text = title, fontWeight = "medium", color = "on_surface_variant" }) -end - local function connection_text() local conn = snapshot.connection local endpoint = `{conn.host or ""}:{conn.port or ""}` @@ -253,9 +249,9 @@ local function traffic_card() peak = value end end - return ui.column({ gap = 8, fill = "surface/0.5", radius = 12, padding = 12 }, { + return ui.column({ gap = 10, fill = "surface/0.5", radius = 12, padding = 12 }, { ui.row({ justify = "space_between", align = "center" }, { - ui.label({ text = noctalia.tr("panel.traffic"), fontWeight = "medium" }), + ui.label({ text = noctalia.tr("panel.traffic"), fontWeight = "medium", color = "on_surface_variant" }), ui.label({ text = `{connections.count or 0} {noctalia.tr("panel.connections")}`, color = "on_surface_variant", @@ -359,7 +355,14 @@ local function group_card(group) })) end - return ui.column({ gap = 8, fill = "surface/0.5", radius = 12, padding = 12, flexGrow = 1 }, children) + return ui.column({ + gap = 8, + border = "outline", + borderWidth = 1, + radius = 10, + padding = 10, + flexGrow = 1, + }, children) end render = function() @@ -371,16 +374,23 @@ render = function() } if #groups > 0 then - table.insert(body, ui.row({ align = "center", gap = 8 }, { - section(noctalia.tr("panel.proxy_groups")), - ui.button({ - text = noctalia.tr("panel.test_all"), - variant = "ghost", - onClick = function() - send_command({ op = "delay_test_all" }) - end, + local group_children = { + ui.row({ align = "center", gap = 8 }, { + ui.label({ + text = noctalia.tr("panel.proxy_groups"), + fontWeight = "medium", + color = "on_surface_variant", + flexGrow = 1, + }), + ui.button({ + text = noctalia.tr("panel.test_all"), + variant = "ghost", + onClick = function() + send_command({ op = "delay_test_all" }) + end, + }), }), - })) + } for i = 1, #groups, 2 do local row_children = { group_card(groups[i]) } if groups[i + 1] then @@ -388,10 +398,14 @@ render = function() else table.insert(row_children, ui.box({ flexGrow = 1 })) end - table.insert(body, ui.row({ gap = 10, align = "stretch" }, row_children)) + table.insert(group_children, ui.row({ gap = 10, align = "stretch" }, row_children)) end + table.insert(body, ui.column({ gap = 10, fill = "surface/0.5", radius = 12, padding = 12 }, group_children)) else - table.insert(body, ui.label({ text = noctalia.tr("panel.no_groups"), color = "on_surface_variant" })) + table.insert(body, ui.column({ gap = 10, fill = "surface/0.5", radius = 12, padding = 12 }, { + ui.label({ text = noctalia.tr("panel.proxy_groups"), fontWeight = "medium", color = "on_surface_variant" }), + ui.label({ text = noctalia.tr("panel.no_groups"), color = "on_surface_variant" }), + })) end panel.render(ui.column({ flexGrow = 1, gap = 12 }, { From 100c1d4176062b73cd3f8c36475def3b27d844ae Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:26:12 +0800 Subject: [PATCH 5/8] Polish proxy group cards Show the selected proxy next to the bold group name (ECS > ecs-proxy), move the expand chevron to the type/members row where the list opens, and drop the list glyph from the card header. --- mihomo-control/panel.luau | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/mihomo-control/panel.luau b/mihomo-control/panel.luau index ce1dcba9..d26605ca 100644 --- a/mihomo-control/panel.luau +++ b/mihomo-control/panel.luau @@ -289,29 +289,43 @@ local function group_card(group) local expanded = expanded_groups[group.name] == true local overall = group_latency(group) + local name_children = { + ui.label({ text = name_text, fontWeight = "bold" }), + } + if group.now and group.now ~= "" then + table.insert(name_children, ui.label({ text = ">", color = "on_surface_variant" })) + table.insert(name_children, ui.label({ + text = group.now, + color = "on_surface_variant", + fontSize = 12, + flexGrow = 1, + })) + end + local children = { ui.row({ gap = 6, align = "center", justify = "space_between", onClick = function() toggle_group(group.name) end }, { + ui.row({ gap = 4, align = "center", flexGrow = 1 }, name_children), ui.button({ - glyph = expanded and "chevron-down" or "chevron-right", + glyph = "activity", + tooltip = noctalia.tr("panel.delay_test"), variant = "ghost", onClick = function() - toggle_group(group.name) + send_command({ op = "delay_test", group = group.name }) end, }), - ui.glyph({ name = "list", size = 14, color = "secondary" }), - ui.label({ text = name_text, fontWeight = "medium", flexGrow = 1 }), + }), + ui.row({ gap = 6, align = "center", justify = "space_between", onClick = function() + toggle_group(group.name) + end }, { ui.button({ - glyph = "activity", - tooltip = noctalia.tr("panel.delay_test"), + glyph = expanded and "chevron-down" or "chevron-right", variant = "ghost", onClick = function() - send_command({ op = "delay_test", group = group.name }) + toggle_group(group.name) end, }), - }), - ui.row({ gap = 6, align = "center", justify = "space_between" }, { ui.label({ text = `{group.type or ""} · {noctalia.trp("panel.members_count", #group.members)}`, color = "on_surface_variant", From 826e0e7d2c68905cdf2b2c3bacdd3c97a888ebe1 Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:29:42 +0800 Subject: [PATCH 6/8] Decouple heights of paired group cards Keep each card in a two-column row at its natural height instead of stretching the neighbor when one is expanded. --- mihomo-control/panel.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mihomo-control/panel.luau b/mihomo-control/panel.luau index d26605ca..f3cc6417 100644 --- a/mihomo-control/panel.luau +++ b/mihomo-control/panel.luau @@ -412,7 +412,7 @@ render = function() else table.insert(row_children, ui.box({ flexGrow = 1 })) end - table.insert(group_children, ui.row({ gap = 10, align = "stretch" }, row_children)) + table.insert(group_children, ui.row({ gap = 10, align = "start" }, row_children)) end table.insert(body, ui.column({ gap = 10, fill = "surface/0.5", radius = 12, padding = 12 }, group_children)) else From 6c303b6c71d304ee013be90ef229e28d88af7847 Mon Sep 17 00:00:00 2001 From: mdj2812 Date: Wed, 12 Aug 2026 01:55:28 +0800 Subject: [PATCH 7/8] Use thumbnail generator to generate thumbnail --- mihomo-control/thumbnail.webp | Bin 17120 -> 55744 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mihomo-control/thumbnail.webp b/mihomo-control/thumbnail.webp index 7f1898c5aff94a77e64ed5947ac27dac36cfd40f..6e69fd8c076ecacf49a5af0d62d3a781baf5f18a 100644 GIT binary patch literal 55744 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 Date: Wed, 12 Aug 2026 08:26:00 +0800 Subject: [PATCH 8/8] mihomo-control: theme-aware panel colors Use theme roles for traffic and latency colors so they stay readable in light mode, and keep the status chip's green/amber/red identity with darker light-mode shades. --- mihomo-control/panel.luau | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/mihomo-control/panel.luau b/mihomo-control/panel.luau index f3cc6417..955edfa5 100644 --- a/mihomo-control/panel.luau +++ b/mihomo-control/panel.luau @@ -125,14 +125,24 @@ local function latency_color(delay) end if delay > 0 then if delay <= 300 then - return "#4ade80" + return "primary" end if delay <= 800 then - return "#facc15" + return "warning" end - return "#f87171" + return "error" end - return "#f87171" + return "error" +end + +-- The status chip keeps the classic green/amber/red identity instead of theme +-- roles, but uses darker shades in light mode so it stays readable on light +-- surfaces. +local function status_color() + if noctalia.isDarkMode() then + return { online = "#4ade80", connecting = "#facc15", offline = "#f87171" } + end + return { online = "#15803d", connecting = "#a16207", offline = "#b91c1c" } end -- A single "overall" latency per group: the currently selected member's delay @@ -191,10 +201,11 @@ local function status_chip() local conn = snapshot.connection local online = conn.status == "online" local connecting = conn.status == "connecting" + local colors = status_color() local text = online and noctalia.tr("panel.status_online") or (connecting and noctalia.tr("panel.status_connecting") or noctalia.tr("panel.status_offline")) - local color = online and "#4ade80" or (connecting and "#facc15" or "#f87171") + local color = online and colors.online or (connecting and colors.connecting or colors.offline) return ui.row({ gap = 6, align = "center", fill = "surface/0.6", radius = 999, paddingH = 10, paddingV = 4 }, { ui.box({ width = 8, height = 8, radius = 4, fill = color }), ui.label({ text = text, fontSize = 12, color = "on_surface_variant" }), @@ -261,15 +272,15 @@ local function traffic_card() ui.graph({ values = normalized_series(down_history, peak), values2 = normalized_series(up_history, peak), - color = "#4ade80", - color2 = "#38bdf8", + color = "primary", + color2 = "secondary", lineWidth = 2, fillOpacity = 0.15, height = 72, }), ui.row({ gap = 16, align = "center" }, { - ui.label({ text = `▼ {format_rate(traffic.down)}`, fontSize = 16, fontWeight = "bold", color = "#4ade80" }), - ui.label({ text = `▲ {format_rate(traffic.up)}`, fontSize = 16, fontWeight = "bold", color = "#38bdf8" }), + ui.label({ text = `▼ {format_rate(traffic.down)}`, fontSize = 16, fontWeight = "bold", color = "primary" }), + ui.label({ text = `▲ {format_rate(traffic.up)}`, fontSize = 16, fontWeight = "bold", color = "secondary" }), }), ui.row({ gap = 16, align = "center" }, { ui.label({