mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:12:51 +08:00
2 lines
44 KiB
JavaScript
2 lines
44 KiB
JavaScript
import{r as g,j as r}from"./vendor-react-Bf71BWbF.js";import{cH as Fe,V as Ze,cI as Ye,cx as en,b3 as hn,aV as ie,a0 as K,aZ as gn,a_ as xn,aq as nn,a2 as ce,h as wn,aQ as Se,$ as ee,au as yn,a1 as le,cr as vn,aT as sn,bf as kn,X as G,b8 as jn,cJ as _n,cK as Nn,cL as Mn,y as Sn,b5 as tn,cM as Ln,u as E,a as Le,bo as Cn,a5 as ve,a9 as We,a7 as P,a8 as rn,cN as Rn,bp as Tn,bb as we,b as Pn,U as Pe,cO as on,aE as J,aC as je,ab as In,cP as Dn,b6 as Hn,cA as En,cQ as On,cR as Fn,ba as Wn,cS as An,cT as Vn,cU as Bn,aH as ye,B as W,cV as Un,ae as _e,bx as an,aG as Ne,I as $n,E as de,cW as Qn,b1 as Ce,b2 as ae,T as Y,cw as qn,bm as Gn,aN as Kn,ct as Jn,c as $e,f as zn,bi as Xn,b0 as Zn,bl as Yn,j as Ae,aD as Me,L as Qe,af as ln,be as es,bn as ns,cG as ss,by as ts}from"./index-CXHBmSa5.js";import{u as Re,r as rs,a as Ve,b as os}from"./flows-C0byZ3sY.js";import{q as as}from"./dns-DQrpG8y_.js";import{i as qe}from"./setup-B5f1cfyO.js";import{a as is,t as ls,b as ds,w as H,p as cs,r as us}from"./link-D6L0Eg5i.js";import{g as ps}from"./policyText-CAFy3qpo.js";import{r as ms}from"./nav-D1cfWFA0.js";import{r as fs}from"./recorder-DlDpPhd4.js";import{p as bs}from"./probe-C8ejAKwA.js";import{D as Te}from"./Table-D0NFHHNQ.js";import{D as ge}from"./DaeCode-STEiRZuV.js";import{T as hs}from"./TimeCell-gSIuLEFc.js";import{u as gs}from"./outbounds-f8QoVoCV.js";import"./useGridSelectionCheckbox-BV96yL-N.js";import"./Virtualizer--Vfl8O3n.js";import"./ListLayout-CPapuywx.js";const xs=["client","rule","outbound","node"],ws=e=>new Map(e.map(n=>[n.id,n.name])),Ee="\0";function ys(e,n){return e.rule_id?n.get(e.rule_id)?.expression===e.rule_expression?e.rule_id:e.rule_id+Ee+e.rule_expression:void 0}function dn(e,n,s,a){switch(n){case"client":{const o=Ze(e.input?.src??void 0);return{label:o??"unknown",unknown:!o}}case"rule":return e.rule_expression?{label:e.rule_expression,unknown:!1,key:ys(e,a)}:{label:"unknown",unknown:!0};case"outbound":return e.outbound?{label:e.outbound,unknown:!1}:{label:"unknown",unknown:!0};case"node":{if(Fe(e.outbound))return null;const o=e.chain.at(-1)??null;return o?{label:s.get(o)??o,unknown:!1,key:o}:{label:"unknown",unknown:!0}}}}const xe=(e,n)=>ls(e,n.unknown?"":n.key??n.label),cn=e=>is(e,xs)?.kind,vs=new Map;function un(e,n,s){const a=cn(n);if(!a)return[];const o=new Map(s.map(t=>[t.rule_id,t]));return e.filter(t=>{const i=dn(t,a,vs,o);return i!==null&&xe(a,i)===n})}function ks(e,n,s,a){const o=e.slice(0,e.indexOf(":")),t=e.slice(e.indexOf(":")+1);return t===""?a(null):o==="rule"?t.includes(Ee)?t.slice(t.indexOf(Ee)+1):n.find(i=>i.rule_id===t)?.expression??t:o==="node"?s.get(t)??t:o==="client"?t:a(t)}function js(e,n,s,a,o="rule"){const t=ws(s),i=new Map(n.map(b=>[b.id,b])),l=new Map(n.map(b=>[b.name,b])),d=new Map(s.map(b=>[b.id,b])),p=new Map(a.map(b=>[b.rule_id,b])),h=new Map,m=new Map,u=new Map,f=new Map,v=(b,x)=>{const L=b+">"+x;let y=f.get(L);return y||f.set(L,y={source:b,target:x,count:0}),y},M=(b,x,L=!1)=>{const y=xe("node",{key:b,label:x,unknown:L});let R=u.get(y);if(!R){const V=L?void 0:d.get(b),B=V&&en(V);u.set(y,R={id:y,label:x,count:0,unknown:L||void 0,latency:hn(B),unavailable:B?.state==="unavailable"})}return R},c=(b,x=!1)=>{const L=xe("outbound",{label:b,unknown:x});let y=m.get(L);if(y)return y;const R=x?void 0:l.get(b),V=x?{groups:[],member:null}:Ye(b,R?.selection.tcp_member_id?"tcp":"udp",l,i,d),B=V.groups.map(I=>({name:I.name,kind:I.policy.kind,policy:I.policy.native})),U=V.member,ne=x?"unknown":b==="direct"||b==="block"?b:B.length?"group":"unknown";return y={id:L,label:b,count:0,unknown:x||void 0,kind:ne,groups:B,node:U&&M(U,t.get(U)??U).id},m.set(L,y),y.node&&v(L,y.node),y},w=(b,x,L=!1)=>{let y=h.get(b);return y||h.set(b,y={id:b,label:x,count:0,unknown:L||void 0,outbound:null,must:!1,fallback:!1}),y};if(o==="rule")for(const b of a){const x=w(xe("rule",{key:b.rule_id,label:b.expression}),b.expression);x.must=b.must,x.fallback=b.kind==="fallback",b.outbound&&(x.outbound=c(b.outbound).id,v(x.id,x.outbound))}const N=[o,"outbound","node"];for(const b of e){let x;for(const L of N){const y=dn(b,L,t,p);if(!y)break;const R=L==="outbound"?c(y.label,y.unknown):L==="node"?M(y.key??y.label,y.label,y.unknown):w(xe(L,y),y.label,y.unknown);R.count++,x&&v(x.id,R.id).count++,x=R}}for(const b of n)c(b.name);const _=new Set([...h.values()].map(b=>b.outbound)),S=new Set([...m.values()].flatMap(b=>b.groups.slice(1).map(x=>x.name))),C=[...m.values()].filter(b=>b.count||_.has(b.id)||!S.has(b.label)),A=new Set(C.map(b=>b.id));return{by:o,leaves:[...h.values()],outbounds:C,nodes:[...u.values()],links:[...f.values()].filter(b=>A.has(b.source)||A.has(b.target))}}const Ge=new WeakMap;function Be(e){const n=Ge.get(e);if(n)return n;const s=new Map,a=new Map,o=new Map;for(const l of e.links){for(const[d,p]of[[s,l.source],[a,l.target]]){let h=d.get(p);h||d.set(p,h=[]),h.push(l)}(!o.has(l.source)||o.get(l.source).count<l.count)&&o.set(l.source,l)}const t=new Map;for(const l of[...e.leaves,...e.outbounds]){const d=("groups"in l?l.node:l.outbound)??o.get(l.id)?.target;d&&t.set(l.id,d)}const i={outgoing:s,incoming:a,parents:t};return Ge.set(e,i),i}function _s(e){const n=new Map;let s=0;const a=new Map,{parents:o}=Be(e);for(const l of[...e.leaves,...e.outbounds]){const d=o.get(l.id);if(d){let p=a.get(d);p||a.set(d,p=[]),p.push(l.id)}}const t=l=>{const d=a.get(l)??[];if(!d.length){n.set(l,s++);return}for(const p of d)t(p);n.set(l,(n.get(d[0])+n.get(d[d.length-1]))/2)},i=new Set;for(const l of e.outbounds)i.add(o.get(l.id)??l.id);for(const l of e.nodes)i.add(l.id);for(const l of e.leaves)o.has(l.id)||i.add(l.id);for(const l of i)t(l);return{rows:s,at:n}}function Ns(e,n){const s=new Set([n]),a=new Set;for(const[o,t]of[[e.outgoing,"target"],[e.incoming,"source"]]){const i=[n];for(const l of i)for(const d of o.get(l)??[])a.has(d)||(a.add(d),s.has(d[t])||(s.add(d[t]),i.push(d[t])))}return{items:s,edges:a}}const Ms={not_instrumented:"flow.m.notInstrumented",started_late:"flow.m.startedLate",buffer_overflow:"flow.m.bufferOverflow",sampled:"flow.m.sampled",redacted:"flow.m.redacted",evicted:"flow.m.evicted"},Ss={src:"ui.device",dst:"conn.f.dst",domain:"ui.domain",domain_source:"conn.f.domainSource",ingress:"conn.f.ingress",pname:"ui.process",network:"ui.protocol",dscp:"DSCP",mark:"fwmark",uid:"UID",pid:"PID"},Ke=e=>e==null?"—":{key:e?"ui.yes":"ui.no"};function Ls(e){const n=s=>s==null?"—":typeof s=="object"?JSON.stringify(s):String(s);switch(e.stage){case"input":return Object.entries(e.data.values).filter(([,s])=>s!=null&&s!=="").map(([s,a])=>{const o=Ss[s];return[o===void 0||!o.includes(".")?{key:"flow.f.input",params:{name:o??s}}:o,typeof a=="string"&&(s==="ingress"||s==="domain_source")?H(a):n(a)]});case"route":return[["flow.f.chain",e.data.chain],["flow.f.plane",H(e.data.plane)],["ui.rule",e.data.rules.filter(s=>s.result==="matched").map(s=>s.expression??s.rule_id).join(", ")||"—"],["ui.outbound",n(e.data.outbound)],["flow.f.must",Ke(e.data.must)]];case"dial_mode":return[["flow.f.dialTarget",e.data.configured+" → "+e.data.effective_target],["flow.f.verification",H(e.data.verification)]];case"dns":return[["ui.name",e.data.name],["flow.f.source",H(e.data.source)],["flow.f.cache",H(e.data.cache)],["ui.upstream",n(e.data.upstream)],["flow.f.selectedIp",n(e.data.selected_ip)]];case"outbound":return[["ui.outbound",n(e.data.routed_outbound)+" → "+n(e.data.effective_outbound)],["flow.f.selectionPath",e.data.selection_path.map(s=>s.group_id+" → "+n(s.member_name??s.member_id)).join(" / ")||"—"],["flow.f.leafNode",n(e.data.leaf_node_id)],["ui.target",n(e.data.target)],["ui.state",H(e.data.status)]];case"connection":return[["ui.state",Object.hasOwn(ie,e.data.state)?{key:ie[e.data.state]}:e.data.state],["flow.f.milestone",H(e.data.milestone)],["flow.f.reason",H(e.data.reason)]];case"datapath":return[["flow.f.plane",H(e.data.plane)],["flow.f.action",H(e.data.action)],["flow.f.reason",H(e.data.reason)]];case"reroute":return[["flow.f.performed",Ke(e.data.performed)],["flow.f.reason",H(e.data.reason)]];default:return null}}function Cs(e,n,s){const a=(d,p)=>d.unknown?n("flow.mapUnknown"):p,o=[...e.leaves.map(d=>({id:d.id,stage:e.by,name:a(d,d.label),badge:d.must?"must":void 0,notes:[],count:d.count})),...e.outbounds.map(d=>({id:d.id,stage:"outbound",name:a(d,Se(d.label,n)),notes:[...d.groups.slice(1).map(p=>({text:"› "+p.name})),...d.groups.slice(-1).map(p=>({text:ps({kind:p.kind,native:p.policy},n).label})),...d.kind==="group"&&!d.node?[{text:n("flow.treeNoNode")}]:[]],count:d.count})),...e.nodes.map(d=>({id:d.id,stage:"node",name:a(d,d.label),notes:d.latency!=null?[{text:sn(d.latency,n),tone:vn(d.latency)}]:d.unavailable?[{text:n("ui.unavailable"),tone:"err"}]:[],count:d.count}))],t=new Map(o.map(d=>[d.id,d.name])),{outgoing:i,incoming:l}=Be(e);return o.map(d=>{const p=(i.get(d.id)??[]).map(u=>t.get(u.target)),h=d.stage==="node"?(l.get(d.id)??[]).map(u=>t.get(u.source)):[],m=[d.name,...d.badge?[d.badge]:[],...d.notes.map(u=>u.text),n("flow.treeFlows",{n:d.count})];return h.length&&m.push(n("flow.treeFrom",{names:ee(s,h)})),p.length&&m.push(n("flow.treeTo",{names:ee(s,p)})),{...d,countText:le(d.count,ce[s]),label:m.join(n("ui.separator"))}})}const Rs={userspace_tcp:"flow.userspaceTcp",userspace_udp:"flow.userspaceUdp",kernel_direct:"flow.kernelDirect",kernel_block:"flow.kernelBlock",dns_intercept:"flow.dnsIntercept",kernel_bypass:"flow.kernelBypass"},Ts={full:"flow.full",partial:"flow.partialVisibility",none:"ui.none"};function pn(e,n,s){const a=Object.entries(e.coverage).filter(([,i])=>i!=="full"),o=yn(e.dropped_records),t=o?n("flow.dropped",{n:le(o,ce[s])}):null;return!a.length&&!t?null:{summary:a.length?n("flow.coverageSummary",{n:a.length}):null,detail:ee(s,a.map(([i,l])=>n("ui.valuePair",{label:K(Rs,i,n),value:K(Ts,l,n)}))),dropped:t}}function Ps(e,n,s,a,o,t){return{tree:e,state:n?!e.leaves.length&&!e.outbounds.length?"empty":"ready":s?"error":"loading",pinLabel:a?t("flow.viewPinned",{n:o}):null}}const Is={input:"flow.stage.input",route:"flow.stage.route",dial_mode:"flow.stage.dialMode",dns:"flow.stage.dns",outbound:"flow.stage.outbound",connection:"flow.stage.connection",datapath:"flow.stage.datapath",reroute:"flow.stage.reroute"},Ds={complete:"flow.status.complete",partial:"flow.status.partial",disabled:"flow.status.disabled"};function Hs(e,n,s,a,o){return{rows:e.map(t=>({id:t.id,target:t.input?.domain||t.input?.dst||t.id,node:xn(t,a,s),path:gn(t,a,s),expression:t.rule_expression,ruleId:t.rule_id,recomputed:t.rule_source==="recomputed",network:t.network.toUpperCase(),state:K(ie,t.state,a),startedAt:t.started_at})),coverage:n?pn(n,a,o):null,stateOptions:[{id:"all",label:a("flow.allStates")},...Object.entries(ie).map(([t,i])=>({id:t,label:a(i)}))]}}function Es(e,n,s,a,o){if(!e)return null;const t=ce[a],i=Ze(e.input.dst??void 0),l=e.input.domain?{kind:"domainSuffix",value:e.input.domain}:i?{kind:"dip",value:i}:null;return{title:e.input.domain||e.input.dst||e.id,status:K(Ds,e.trace.status,s),tone:e.trace.status==="complete"?void 0:"warn",revision:s("flow.revision",{n:e.revision}),fields:[[s("ui.state"),K(ie,e.state,s)],[s("ui.outbound"),Se(e.outbound,s)],...o?[[s("conn.node"),o.path??o.node]]:[],...o?.expression?[[s("conn.rule"),o.expression]]:[],...e.trace.missing.length?[[s("flow.missing"),ee(a,e.trace.missing.map(d=>K(Ms,d,s)))]]:[]],connectionHref:e.connection_id?wn("connections",{id:e.connection_id}):null,seedHref:n&&l?ds(l):null,steps:[...e.trace.steps].sort((d,p)=>d.seq-p.seq).map(d=>{const p=Ls(d);return{id:d.seq,stage:K(Is,d.stage,s),observed:nn(d.observed_at,t),elapsed:d.elapsed_us==null?"—":s("ui.microseconds",{n:d.elapsed_us}),fields:p?.map(([h,m])=>[typeof h=="string"?s(h):s(h.key,h.params),typeof m=="string"?m:s(m.key,m.params)])??null,raw:p?"":JSON.stringify(d.data,null,2)}})}}const oe=30,Os=720,he=44,Ie=36,Je=56,De=[5,4,3],Fs={rule:0,client:0,outbound:1,node:2};function Ws(e,n){return e.leaves.length<=n?e:{...e,leaves:e.leaves.slice(0,n)}}function As(e,n,s,a){const o=n===null?void 0:Math.max(n,Os),t=((o??0)-2*Je)/De.reduce((m,u)=>m+u),i=m=>{const u=Fs[m];return{left:De.slice(0,u).reduce((f,v)=>f+v*t+Je,0),width:De[u]*t}},l=_s(e),d=Cs(e,s,a).map(m=>({view:m,style:{top:l.at.get(m.id)*he,...i(m.stage)}})),p=new Map(e.outbounds.map(m=>[m.id,m])),h=e.links.flatMap(m=>{if(!l.at.has(m.source)||!l.at.has(m.target))return[];const u=cn(m.source)==="outbound"?"outbound":e.by,f=i(u),v=f.left+f.width,M=i(u==="outbound"?"node":"outbound").left,c=l.at.get(m.source)*he+Ie/2,w=l.at.get(m.target)*he+Ie/2,N=(v+M)/2;return[{link:m,id:m.source+">"+m.target,path:`M${v},${c} C${N},${c} ${N},${w} ${M},${w}`,width:Math.min(8,1.5+Math.log2(1+m.count)*1.25),dash:m.count?void 0:"4 4",kind:u==="outbound"?"node":p.get(m.target)?.kind??"group"}]});return{width:o,height:l.rows*he-(he-Ie),captions:[{stage:e.by,label:s(e.by==="rule"?"flow.mapRule":"flow.stageClient"),style:i(e.by)},{stage:"outbound",label:s("flow.mapOutbound"),style:i("outbound")},{stage:"node",label:s("flow.mapNode"),style:i("node")}],placed:d,geometry:h}}function mn(e){const n=new Map;for(const a of e){const o=a.rule_id,t=o===null?null:a.rule_expression,i=a.rule_source,l=JSON.stringify([o,t,i]),d=n.get(l);d?d.count++:n.set(l,{id:o,expression:t,source:i,count:1,share:0})}const s=[...n.values()];for(const a of s)a.share=a.count/e.length;return s.sort((a,o)=>o.count-a.count)}const Vs={domainSuffix:"rule.kind.domainSuffix",domain:"rule.kind.domain",geosite:"rule.kind.geosite",dip:"rule.kind.dip",geoip:"rule.kind.geoip",sip:"rule.kind.sip",dport:"rule.kind.dport",sport:"rule.kind.sport",pname:"rule.kind.pname",l4proto:"rule.kind.l4proto"},Bs={domainSuffix:"example.com, example.org",domain:"www.example.com",geosite:"netflix, cn",dip:"10.0.0.0/8, 224.0.0.0/4",geoip:"cn, private",sip:"192.168.1.10",dport:"80, 443",sport:"53",pname:"curl, firefox",l4proto:"udp"},He={kernel:"rule.sourceKernel",recomputed:"rule.sourceRecomputed",unknown:"rule.sourceUnknown"},Us={kernel:"rule.sourceHelp.kernel",recomputed:"rule.sourceHelp.recomputed",unknown:"rule.sourceHelp.unknown"};function fn(e,n){return n?Mn(n):e.file==="<redacted>"?"":e.file}const ze=(e,n,s)=>e?s("conn.ruleNoPosition"):n?s("ui.changeApplying"):void 0;function $s(e,n,s){return e.valid?n?null:s("rule.outboundMissing"):e.mode==="pick"?e.pickError??s("rule.valuesMissing"):s(e.rawInvalid?"rule.conditionInvalid":"rule.conditionMissing")}function Qs({loaded:e,busy:n,available:s,invalid:a,modeOffered:o},t){return!e||n?null:s?a?t(a):o?null:t("rule.resolveUnavailable"):t("rule.traceUnavailable")}function qs(e,n,s,a,o,t,i){const l=ce[i],d=new Map(e.map(c=>[c.rule_id,c.expression])),p=new Map;for(const c of mn(s?.flows??[]))c.id!==null&&d.get(c.id)===c.expression&&p.set(c.id,(p.get(c.id)??0)+c.count);const h=new Map(a.map(c=>[c.id,c])),m=c=>{if(c)return h.get(c.source_id)},u=new Map,f=c=>{const w=c.source&&h.get(c.source.source_id);return!w?.writable||w.content===void 0?!1:(u.has(w.id)||u.set(w.id,Sn(w.content)),tn(w,c,u.get(w.id))!==null)},v=e.map(c=>{const w=m(c.source),N=c.source?fn(c.source,w):"";return{id:c.rule_id,number:c.kind==="fallback"?"—":le(c.index+1,l),expression:c.expression,outbound:c.outbound??"",must:c.must,position:c.source?N?`${N}:${c.source.line}`:t("rule.lineOnly",{n:c.source.line}):"—",hits:p.has(c.rule_id)?le(p.get(c.rule_id),l):"—",removable:c.kind==="rule"&&f(c),sourceQuery:w&&c.source?G("",{tab:"source",source:w.id,line:String(c.source.line)}):null}}),M=e.find(c=>c.kind==="fallback");return{rows:v,caption:n!==void 0?t("rule.dictionaryCaption",{n:e.length,generation:n}):null,positions:[...M&&f(M)?[{id:"end",label:t("rule.positionEnd")}]:[],...e.filter((c,w)=>v[w].removable).map(c=>({id:c.rule_id,label:t("rule.positionBefore",{n:c.index+1}),desc:c.expression}))],outbounds:jn(o)}}function Gs(e,n,s){return s(fs(e,n!=="all",{forbidden:"rule.distributionForbidden",off:"rule.distributionNotRecorded",filtered:"rule.distributionFiltered",empty:"rule.distributionEmpty"}))}function Ks(e,n,s,a,o){const t=ce[a];return{rows:mn(e?.flows??[]).map(l=>({...l,key:JSON.stringify([l.id,l.expression,l.source])})).sort((l,d)=>(l.id===null||d.id===null?+(l.id===null)-+(d.id===null):l.id.localeCompare(d.id,void 0,{numeric:!0}))||d.count-l.count).filter(l=>n==="all"||l.source===n).map(l=>({id:l.key,ruleId:l.id??"—",expression:l.expression??s("rule.unknownRule"),expressionClass:l.expression?"rp-code":void 0,source:K(He,l.source,s),hits:le(l.count,t),share:s("ui.percent",{n:le(l.share*100,t,1)})})),choices:[["all",s("ui.all")],...Object.entries(He).map(([l,d])=>[l,s(d)])],caption:e?s("rule.distributionCaption",{n:e.flows.length}):null,coverage:e?pn(e,s,a):null,droppedUnknown:e?.dropped_records===null,empty:Gs(o,n,s),sourceHelp:{title:s("rule.distributionSource"),text:Object.entries(Us).map(([l,d])=>s("ui.valuePair",{label:s(He[l]),value:s(d)}))}}}const Xe=e=>/\w\(/.test(e)&&!e.includes("->")&&Ln(e);function Js(e,n,s,a,o,t){const i=n.trim()!=="";return{choices:_n.map(l=>({id:l,label:t(Vs[l])})),hint:Bs[e],preview:s&&i?a:null,mode:s?"pick":"text",valid:s?i&&a!==null:Xe(o),rawInvalid:o!==""&&!Xe(o),pickError:i&&a===null?t("rule.valuesInvalid"):void 0}}function zs(e,n,s){return{expression:e.expression,help:s("rule.removeHelp",{file:e.source?fn(e.source,Nn(n,e.source)):"",line:e.source?.line??""})}}function Xs(e,n,s){const a=ms(e).map(t=>({id:t.id,label:s(t.titleKey)})),o=a[0]?.id??"map";return{tabs:a,tab:kn(n,a.map(t=>t.id),o),fallback:e?o:null}}const Zs={matched:"rule.result.matched",not_matched:"rule.result.not_matched",skipped:"rule.result.skipped",indeterminate:"rule.result.indeterminate"};function Ys(e,n,s,a,o,t,i,l,d){const p=o?.node,h=p?en(p):void 0,m=p?h?.state==="healthy"&&h.latency_ms!=null?sn(h.latency_ms,l):h?.state==="unavailable"?l("ui.unavailable"):l("rule.untested"):l("rule.noMember");return{heading:e.dst_ip??s??"",label:l("rule.evaluation",{n:n+1}),fields:[[l("rule.decision"),l(e.decision==="determinate"?"rule.determinate":"rule.result.indeterminate")],[l(a?"rule.likelyOutbound":"ui.outbound"),Se(a??e.outbound,l)],...e.missing_inputs.length?[[l("rule.missing"),ee(d,e.missing_inputs)]]:[],...o?[[l("rule.node"),[...o.groups.map(u=>u.name),...p?[p.name]:[]].join(" → ")],[l("rule.reach"),m]]:[]],hint:a?l("rule.likelyHelp",{inputs:ee(d,e.missing_inputs)}):null,probe:p&&t&&!Fe(p.protocol)?{id:p.id,label:l("nodes.probe",{name:p.name}),pending:i===p.id,disabled:!!i}:null,rows:e.rules.map(u=>({id:u.rule_id,expression:u.expression??u.rule_id,outcome:K(Zs,u.result,l),tone:u.result==="matched"?"ok":u.result==="indeterminate"?"warn":u.result==="skipped"?"muted":"neutral",missing:ee(d,u.missing_inputs)||"—"}))}}function et(e,n,s){const a=o=>{const t=H(o);return typeof t=="string"?t:n(t.key,t.params)};return{id:e.lookup_id,heading:n("rule.dnsHeading",{name:e.name}),fields:[[n("ui.type"),e.qtype],[n("ui.state"),e.status],[n("ui.source"),a(e.source)],[n("ui.cache"),a(e.cache)],[n("rule.address"),ee(s,e.addresses)||"—"],...e.selected_ip?[[n("rule.simulatedAddress"),e.selected_ip]]:[],...e.error?[[n("ui.error"),e.error]]:[]]}}function nt(e,n,s){return n("ui.valuePair",{label:n("rule.observed"),value:nn(e.observed_at,ce[s])})+n("ui.separator")+n("ui.valuePair",{label:n("ui.generation"),value:e.generation_id})}const st={none:"rule.resolveNone",live:"rule.resolveLive",query:"rule.resolveQuery"},Oe={network:"tcp",domain:"",dst_ip:"",dst_port:"",src_ip:"",src_port:"",pname:"",resolve:null};function tt(){const[e,n]=g.useState(Oe),[s,a]=g.useState(!1);return{form:e,setForm:n,advanced:s,setAdvanced:a}}function rt({form:e,setForm:n,advanced:s,setAdvanced:a}){const o=E(),t=Le(),i=Cn(),l=ve(),d=l.data?.resources,p=We(P(d,"groups",{whileLoading:!1})),h=rn(P(d,"nodes",{whileLoading:!1})),m=Re(P(d,"rules",{whileLoading:!1})),u=Rn(h.refetch),f=g.useMemo(()=>new Map(p.data?.map(k=>[k.name,k])??[]),[p.data]),v=g.useMemo(()=>new Map(p.data?.map(k=>[k.id,k])??[]),[p.data]),M=g.useMemo(()=>new Map(h.data?.map(k=>[k.id,k])??[]),[h.data]),c=g.useMemo(()=>new Map(m.data?.rules.map(k=>[k.rule_id,k])??[]),[m.data]),[w,N]=g.useState(null),{busy:_,error:S,run:C}=Tn(),A=S??l.error,b=g.useEffectEvent(k=>we("negative",o("rule.traceFailed"),{detail:Pn(k,o)}));g.useEffect(()=>{A&&b(A)},[A]);const x=!e.domain.trim()&&!e.dst_ip.trim()?{field:"domain",key:"rule.invalidTarget"}:e.dst_ip.trim()&&!Pe(e.dst_ip)?{field:"dst_ip",key:"ui.invalidIp"}:qe(e.dst_port)?e.src_ip.trim()&&!Pe(e.src_ip)?{field:"src_ip",key:"ui.invalidIp"}:e.src_port.trim()&&!qe(e.src_port)?{field:"src_port",key:"rule.invalidPort"}:(e.resolve==="live"||e.resolve==="query")&&!e.domain.trim()?{field:"domain",key:"rule.invalidLive"}:(e.resolve==="live"||e.resolve==="query")&&e.dst_ip.trim()?{field:"dst_ip",key:"rule.invalidLive"}:null:{field:"dst_port",key:"rule.invalidPort"},y=Object.keys(Oe).some(k=>k!=="resolve"&&k!=="network"&&e[k]!==Oe[k])?x:null,R=l.data?.resources.routing_trace,V=R?.resolve_modes??[],B=l.data?.resources.dns_query,U=B?.record_types,ne=g.useMemo(()=>(U??[]).filter(k=>k==="A"||k==="AAAA"),[U]),I=B?.limits?.max_types_per_request??1,z=[...V,...!V.includes("live")&&V.includes("none")&&B?.available&&ne.length?["query"]:[]],ue=R?.available!==!1,se=e.domain.trim()!==""&&!e.dst_ip.trim(),X=e.resolve??(se&&z.includes("live")?"live":se&&z.includes("query")?"query":"none"),re=!x&&ue&&z.includes(X),$=g.useCallback(async()=>{if(_||!re)return;const k=D=>Pe(D),T={network:e.network,dst_port:Number(e.dst_port),...e.domain.trim()?{domain:e.domain.trim()}:{dst_ip:k(e.dst_ip)}};e.domain.trim()&&e.dst_ip.trim()&&(T.dst_ip=k(e.dst_ip)),e.src_ip.trim()&&(T.src_ip=k(e.src_ip)),e.src_port.trim()&&(T.src_port=Number(e.src_port)),e.pname.trim()&&(T.pname=e.pname.trim());const O=await C("trace",D=>rs({...i,dnsQuery:(F,be)=>as(i.dnsQuery,F,be,I,D)},{input:T,resolve:X,recordTypes:ne},D));N(O?{response:O,input:T}:null)},[i,_,re,e,X,ne,I,C]),pe=m.data?.generation_id,me=g.useMemo(()=>w?.response.evaluations.map((k,T)=>{const O=k.rules.find(j=>j.result==="matched"),D=k.decision!=="determinate"&&!k.outbound&&pe===w.response.generation_id?(O&&c.get(O.rule_id)?.outbound)??null:null,F=k.outbound??D,be=F&&!Fe(F)?Ye(F,w.input.network,f,v,M):null;return Ys(k,T,w.input.domain??void 0,D,be,u.canProbe,u.busy,o,t)})??[],[w,pe,c,f,v,M,u.canProbe,u.busy,o,t]),fe=g.useMemo(()=>w?{status:nt(w.response,o,t),dns:w.response.dns.map(k=>et(k,o,t))}:null,[w,o,t]),ke=async k=>{const T=M.get(k);if(T)try{const O=await u.probe(k);if(!O)return;const{kind:D,text:F}=bs(O,k,T.name,o);we(D,F)}catch(O){on(O,o,o("nodes.probeError",{name:T.name}))}};return{form:e,resolve:X,setForm:n,busy:_!==null,canSubmit:!_&&re,reason:Qs({loaded:!!l.data,busy:_!==null,available:ue,invalid:x?.key??null,modeOffered:z.includes(X)},o),submit:$,available:ue,modes:z.map(k=>({id:k,label:o(st[k])})),errors:{domain:y?.field==="domain"?o(y.key):void 0,dst_ip:y?.field==="dst_ip"?o(y.key):void 0,dst_port:y?.field==="dst_port"?o(y.key):void 0,src_ip:y?.field==="src_ip"?o(y.key):void 0,src_port:y?.field==="src_port"?o(y.key):void 0},advanced:s||x?.field==="src_ip"||x?.field==="src_port",setAdvanced:a,ipOnly:!x&&!!e.dst_ip.trim()&&!e.domain.trim(),result:fe&&{...fe,evaluations:me},probeNode:ke}}function bn({view:e}){const n=E();return r.jsxs("div",{className:"rp-cluster",role:"group","aria-label":n("flow.coverage"),children:[e.summary&&r.jsx(J,{text:e.detail,children:r.jsx(je,{small:!0,tone:"warn",children:e.summary})}),e.dropped&&r.jsx(je,{small:!0,tone:"warn",children:e.dropped})]})}const ot={rows:[],caption:null,positions:[],outbounds:[]},at={rows:[],choices:[],caption:null,coverage:null,droppedUnknown:!1,empty:"",sourceHelp:{title:"",text:""}};function it({go:e,query:n}){const s=E(),a=Le(),o=ve().data?.resources,t=P(o,"rules",{whileLoading:!1}),i=Re(t),l=Ve({},P(o,"flows",{whileLoading:!0})),d=We(t&&P(o,"groups",{whileLoading:!1})),p=t&&P(o,"config",{whileLoading:!1})&&o?.config.writable===!0,h=In(p),m=()=>{h.refetch(),i.refetch()},u=Dn(m),f=g.useEffectEvent(j=>on(j,s,s("ui.writeFailed")));g.useEffect(()=>{u.error&&f(u.error)},[u.error]);const[v,M]=g.useState(null),c=g.useRef(!1),[w,N]=g.useState({condition:"",outbound:"",must:!1,before:"end"}),[_,S]=g.useState({on:!0,kind:"domainSuffix",value:""}),C=_.on?Hn(_.kind,_.value):w.condition.trim(),A=En(v?.kind==="add"&&!!(_.value.trim()||w.condition.trim()),()=>M(null)),b=i.data?.rules??[],x=h.data?.sources??[],L=new URLSearchParams(n),y=L.get("rule"),[R,V]=g.useState({landed:y,row:y}),B=R.landed===y?R.row:y,[U,ne]=g.useState("all"),I=g.useMemo(()=>t?qs(i.data?.rules??[],i.data?.generation_id,l.data,h.data?.sources??[],d.data??[],s,a):ot,[t,i.data,l.data,h.data,d.data,s,a]),z=On(!t&&(o?.runtime_settings.available??!1)).data?.recording?.flows,ue=g.useMemo(()=>t?at:Ks(l.data,U,s,a,z),[t,l.data,U,s,a,z]),se=()=>{we("negative",s("rule.stale")),m()},X=(j,Q)=>{u.busy||!i.data||(N({condition:"",outbound:d.data?.[0]?.name??"direct",must:!1,before:I.positions[0]?.id??"end"}),S({on:!0,kind:"domainSuffix",value:"",...Q}),M({...j,generation:i.data.generation_id,sources:x,rules:b}))},re=j=>{if(!c.current){if(i.data?.generation_id!==h.data?.generation_id){se();return}X(j)}},$=L.get("add"),pe=g.useMemo(()=>cs($),[$]),[me,fe]=g.useState({seed:$,consumed:!1}),ke=me.seed===$?me:{seed:$,consumed:!1};me.seed!==$&&fe(ke),!ke.consumed&&pe&&p&&i.data&&h.data&&i.data.generation_id===h.data.generation_id&&I.positions.length&&(fe({seed:$,consumed:!0}),X({kind:"add"},pe));const k=()=>{c.current&&(u.cancel(),c.current=!1,m()),A.clear(),M(null),$&&e("rules",G(n,{add:null}))},T=async(j,Q)=>{const q=await u.apply(j,te=>{const Z=Q(te);return Z===null&&se(),Z});return q?q.diagnostics?(we("negative",s("ui.writeInvalid",{n:q.diagnostics.filter(te=>te.level==="error").length})),!1):!0:!1},O=async j=>{if(c.current)return;if(!v||!i.data||!h.data||i.data.generation_id!==v.generation||h.data.generation_id!==v.generation){se();return}const Q=v.kind==="remove"?v.rule:v.rules.find(Z=>w.before==="end"?Z.kind==="fallback":Z.rule_id===w.before),q=v.sources.find(Z=>Z.id===Q?.source?.source_id),te=q&&Q?tn(q,Q):null;if(C!==null){if(!q||!te){se();return}c.current=!0;try{await T(q,Ue=>v.kind==="remove"?Vn(Ue,te):Bn(Ue,te,C,w.outbound,w.must))&&(we("positive",s(v.kind==="remove"?"rule.removed":"rule.added")),c.current=!1,j())}finally{c.current=!1}}},D=Js(_.kind,_.value,_.on,C,w.condition,s),F=Fn(),be=v?.kind==="remove"?{kind:"remove",...zs(v.rule,x,s)}:v;return{kind:t?"dictionary":"distribution",table:I,distribution:ue,source:U,setSource:ne,selected:B,select:j=>V({landed:y,row:j}),held:An(F.rules,F.failure,s),discard:j=>{F.applying||Wn.remove([j])},applying:F.applying,canWrite:p,busy:!!u.busy,addDisabled:!I.positions.length||!!u.busy,addTip:ze(!!i.data&&!!h.data&&!I.positions.length,!!u.busy,s),addReason:ze(!!i.data&&!!h.data&&!I.positions.length,!1,s)??null,editHelp:p&&x.some(j=>j.writable&&j.content===void 0)?s("config.incomplete"):null,loading:t?i.loading&&!i.data:l.loading&&!l.data,error:t?i.error??h.error:l.error,retry:t?m:l.refetch,dialog:be,dialogTitle:s(v?.kind==="remove"?"rule.removeTitle":"rule.add"),submitLabel:s(v?.kind==="remove"?"rule.remove":"rule.add"),close:k,openAdd:()=>{i.data&&re({kind:"add"})},openRemove:j=>{const Q=b.find(q=>q.rule_id===j);Q&&i.data&&re({kind:"remove",rule:Q})},openSource:j=>e("config",j),submit:O,form:w,setForm:j=>{c.current||N(j)},pick:_,setPick:j=>{c.current||S(j)},draft:D,submitDisabled:v?.kind!=="remove"&&(!D.valid||!w.outbound),submitReason:v?.kind==="add"&&!u.busy?$s(D,w.outbound,s):null,changeMode:j=>{c.current||(j==="text"&&_.on&&_.value.trim()&&C&&N({...w,condition:C}),S({..._,on:j==="pick"}))}}}function lt(e){const n=it(e);return n.kind==="dictionary"?r.jsx(dt,{view:n}):r.jsx(ct,{view:n})}function dt({view:e}){const n=E(),{form:s,setForm:a,pick:o,setPick:t,draft:i,dialog:l}=e,d=g.useId(),p=g.useRef(e);g.useLayoutEffect(()=>{p.current=e});const{canWrite:h,busy:m}=e,u=g.useMemo(()=>[{id:"n",label:n("rule.id"),minWidth:44,grow:0,drop:3,render:f=>f.number},{id:"expression",label:n("rule.expression"),minWidth:160,grow:3,isRowHeader:!0,render:f=>r.jsx(J,{className:"rp-code",children:r.jsx(ge,{text:f.expression})})},{id:"outbound",label:n("ui.outbound"),minWidth:100,grow:0,drop:4,render:f=>r.jsxs("span",{className:"rp-chain",children:[f.outbound,f.must&&r.jsx(ye,{children:"must"})]})},{id:"source",label:n("rule.where"),minWidth:116,grow:0,drop:2,render:f=>f.position},{id:"hits",label:n("rule.hits"),minWidth:60,grow:0,align:"end",drop:1,render:f=>f.hits},{id:"actions",label:n("ui.actions"),minWidth:h?96:56,grow:0,render:f=>r.jsxs("span",{className:"rp-chain",children:[f.sourceQuery&&r.jsx(W,{small:!0,quiet:!0,icon:!0,label:n("rule.openSource"),onPress:()=>p.current.openSource(f.sourceQuery),children:r.jsx(Un,{})}),h&&f.removable&&r.jsx(W,{small:!0,quiet:!0,icon:!0,isDisabled:m,label:n("rule.remove"),onPress:()=>p.current.openRemove(f.id),children:r.jsx(_e,{})})]})}],[n,h,m]);return r.jsxs("div",{className:"rp-col",children:[r.jsx(an,{reason:e.canWrite?e.addReason:null,children:r.jsxs("div",{className:"rp-toolbar",children:[e.table.caption&&r.jsx("span",{className:"rp-label",children:e.table.caption}),r.jsx("span",{className:"rp-grow"}),e.canWrite&&r.jsx(W,{small:!0,isDisabled:e.addDisabled,tip:e.addTip,onPress:e.openAdd,children:n("rule.add")})]})}),e.editHelp&&r.jsx("p",{className:"rp-note",children:e.editHelp}),e.held&&r.jsxs(Ne,{className:"rp-list","aria-label":e.held.title,children:[r.jsxs("div",{className:"rp-cluster",children:[r.jsx("h3",{className:"rp-h3",children:e.held.title}),e.held.files&&r.jsx("span",{className:"rp-label",children:e.held.files})]}),e.held.failure&&r.jsxs($n,{children:[e.held.failure.text,e.held.failure.lines.map((f,v)=>r.jsx("span",{className:"rp-label",children:f},v))]}),e.held.rows.map(f=>r.jsxs("div",{className:"rp-cluster",children:[r.jsx(ge,{text:f.line}),r.jsx("span",{className:"rp-label",children:f.position}),r.jsx("span",{className:"rp-grow"}),r.jsx(W,{small:!0,quiet:!0,icon:!0,label:n("rule.discard"),isDisabled:e.applying,onPress:()=>e.discard(f.id),children:r.jsx(_e,{})})]},f.id))]}),r.jsx(de,{error:e.error,onRetry:e.retry}),r.jsx(Te,{label:n("rule.listTitle"),loading:e.loading,rows:e.table.rows,selected:e.selected,reveal:!0,onSelect:e.select,height:560,fit:!0,empty:n("rule.dictionaryEmpty"),cols:u}),r.jsxs(Qn,{title:e.dialogTitle,isOpen:l!==null,onCancel:e.close,tone:l?.kind==="remove"?"negative":"accent",confirmLabel:e.submitLabel,isDisabled:e.submitDisabled,reason:e.submitReason,isPending:e.busy,onConfirm:()=>void e.submit(e.close),children:[l?.kind==="remove"&&r.jsxs("div",{className:"rp-list",children:[r.jsx("span",{className:"rp-label",children:l.help}),r.jsx(ge,{text:l.expression})]}),l?.kind==="add"&&r.jsxs("div",{className:"rp-list",children:[r.jsx("span",{className:"rp-label",children:n("rule.addHelp")}),r.jsx(Ce,{isDisabled:e.busy,label:n("rule.conditionMode"),value:i.mode,onChange:e.changeMode,items:[["pick",n("rule.pick")],["text",n("rule.expression")]]}),o.on?r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"rp-toolbar top",children:[r.jsx(ae,{isDisabled:e.busy,label:n("rule.kind"),value:o.kind,onChange:f=>t({...o,kind:f}),items:i.choices}),r.jsx(Y,{isDisabled:e.busy,label:n("rule.values"),value:o.value,placeholder:i.hint,description:n("rule.valuesHelp"),error:i.pickError,spellCheck:!1,onChange:f=>t({...o,value:f})})]}),i.preview&&r.jsx(ge,{text:i.preview})]}):r.jsx(Y,{isDisabled:e.busy,label:n("rule.condition"),value:s.condition,placeholder:"domain(geosite:netflix)",isInvalid:i.rawInvalid,spellCheck:!1,onChange:f=>a({...s,condition:f})}),r.jsxs("div",{className:"rp-toolbar end",children:[r.jsx(ae,{isDisabled:e.busy,label:n("ui.outbound"),value:s.outbound,onChange:f=>a({...s,outbound:f}),items:e.table.outbounds}),r.jsxs(qn,{isDisabled:e.busy,isSelected:s.must,onChange:f=>a({...s,must:f}),"aria-describedby":d,children:[n("rule.must")," ",r.jsx("code",{children:"must"})]})]}),r.jsx("span",{id:d,className:"rp-label",children:n("rule.mustHelp")}),r.jsx(ae,{isDisabled:e.busy,label:n("rule.position"),value:s.before,onChange:f=>a({...s,before:f}),items:e.table.positions})]})]})]})}function ct({view:e}){const n=E(),s=e.distribution,a=g.useMemo(()=>[{id:"n",label:n("rule.id"),minWidth:72,grow:0,drop:2,render:o=>o.ruleId},{id:"expression",label:n("rule.expression"),minWidth:240,grow:3,isRowHeader:!0,render:o=>r.jsx(J,{className:o.expressionClass,children:o.expressionClass?r.jsx(ge,{text:o.expression}):o.expression})},{id:"source",label:n("rule.distributionSource"),minWidth:96,grow:0,drop:1,render:o=>r.jsx(ye,{children:o.source})},{id:"hits",label:n("rule.hits"),minWidth:72,grow:0,align:"end",render:o=>o.hits},{id:"share",label:n("rule.share"),minWidth:72,grow:0,align:"end",drop:3,render:o=>o.share}],[n]);return r.jsxs("div",{className:"rp-col",children:[r.jsxs("div",{className:"rp-toolbar",children:[r.jsx(Gn,{help:s.sourceHelp,children:r.jsx(Ce,{label:n("rule.distributionSource"),value:e.source,onChange:e.setSource,items:s.choices})}),s.caption&&r.jsx(J,{text:n("rule.distributionScope"),className:"rp-label",children:s.caption}),s.coverage&&r.jsx(bn,{view:s.coverage}),s.droppedUnknown&&r.jsx(je,{small:!0,tone:"warn",children:n("rule.droppedUnknown")})]}),r.jsx(de,{error:e.error,onRetry:e.retry}),r.jsx(Te,{label:n("rule.listTitle"),loading:e.loading,rows:s.rows,fit:!0,empty:s.empty,cols:a})]})}function ut(e,n,s){const a=E(),o=Le(),[t,i]=g.useState(oe),[l,d]=g.useState(null),[p,h]=Kn(),m=g.useMemo(()=>Be(e),[e]),u=g.useMemo(()=>Ws(e,t),[e,t]),f=g.useMemo(()=>As(u,h,a,o),[u,h,a,o]),v=g.useMemo(()=>new Set(f.placed.map(S=>S.view.id)),[f.placed]),M=g.useMemo(()=>new Set([...e.leaves,...e.outbounds,...e.nodes].map(S=>S.id)),[e]),c=l&&v.has(l)?l:n&&M.has(n)?n:null,w=g.useMemo(()=>c?Ns(m,c):null,[m,c]);g.useEffect(()=>{if(!n)return;const S=C=>{C.key==="Escape"&&s(null)};return document.addEventListener("keydown",S),()=>document.removeEventListener("keydown",S)},[n,s]);const N=g.useRef(n);g.useLayoutEffect(()=>{N.current=n},[n]);const _=g.useCallback(S=>s(N.current===S?null:S),[s]);return{...f,ref:p,ready:f.width!==void 0,active:w,pinned:n,pin:_,hover:d,more:e.leaves.length>t?a("flow.treeShowMore",{n:Math.min(oe,e.leaves.length-t)}):null,fewer:t>oe?a("flow.treeFewer",{n:oe}):null,showMore:()=>i(S=>Math.min(e.leaves.length,S+oe)),showFewer:()=>i(oe)}}const pt=g.memo(function({view:n,style:s,dim:a,selected:o,pin:t,hover:i}){return r.jsxs(Jn,{"aria-label":n.label,className:$e("rp-tree-tile",a&&"dim"),"data-id":n.id,"data-stage":n.stage,style:s,isSelected:o,onChange:()=>t(n.id),onHoverStart:()=>i(n.id),onHoverEnd:()=>i(null),onFocus:()=>i(n.id),onBlur:()=>i(null),children:[r.jsxs("span",{className:"l",children:[n.stage==="rule"||n.stage==="client"?n.name:r.jsx("b",{children:n.name}),n.notes.map((l,d)=>r.jsx("span",{className:$e("s",l.tone),children:l.text},d))]}),n.badge&&r.jsx(ye,{children:n.badge}),r.jsx("span",{className:"c",children:n.countText})]})});function mt({tree:e,pinned:n,onPin:s}){const{ref:a,...o}=ut(e,n,s);return r.jsxs("div",{className:"rp-tree",ref:a,children:[r.jsx("div",{className:"rp-tree-captions",style:{width:o.width},children:o.captions.map(t=>r.jsx("span",{className:"rp-label",style:t.style,children:t.label},t.stage))}),r.jsxs("div",{className:"rp-tree-canvas",style:{height:o.height,width:o.width},children:[o.ready&&r.jsx("svg",{className:"rp-tree-links",width:o.width,height:o.height,"aria-hidden":!0,children:o.geometry.map(t=>r.jsx("path",{d:t.path,strokeWidth:t.width,"data-kind":t.kind,"data-state":o.active?o.active.edges.has(t.link)?"active":"dim":void 0,strokeDasharray:t.dash},t.id))}),o.ready&&o.placed.map(({view:t,style:i})=>r.jsx(pt,{view:t,style:i,dim:!!o.active&&!o.active.items.has(t.id),selected:o.pinned===t.id,pin:o.pin,hover:o.hover},t.id))]}),o.more&&r.jsx(W,{small:!0,quiet:!0,onPress:o.showMore,children:o.more}),o.fewer&&r.jsx(W,{small:!0,quiet:!0,onPress:o.showFewer,children:o.fewer})]})}function ft({go:e,query:n}){const s=E(),a=new URLSearchParams(n),o=ve().data?.resources,t=Ve({},P(o,"flows",{whileLoading:!0})),i=We(P(o,"groups",{whileLoading:!1})),l=rn(P(o,"nodes",{whileLoading:!1})),d=Re(P(o,"rules",{whileLoading:!1})),p=a.get("by")==="client"?"client":"rule",h=g.useMemo(()=>js(t.data?.flows??[],i.data??[],l.data??[],d.data?.rules??[],p),[t.data,i.data,l.data,d.data,p]),m=a.get("path"),u=g.useRef(n);g.useLayoutEffect(()=>{u.current=n},[n]);const f=g.useCallback(c=>e("rules",G(u.current,{path:c})),[e]),v=g.useMemo(()=>m?un(t.data?.flows??[],m,d.data?.rules??[]).length:0,[t.data,m,d.data]),M=[t,d,i,l].every(c=>c.data!==void 0||c.error||!c.loading);return{...Ps(h,M&&!!(t.data||d.data||i.data),!!t.error,m,v,s),by:p,pinned:m,error:t.error??i.error??l.error??d.error,retry:()=>{t.refetch(),i.refetch(),l.refetch(),d.refetch()},pin:f,changeBy:c=>e("rules",G(n,{by:c==="client"?"client":null,path:null})),viewPinned:()=>e("rules",G(n,{tab:"flows"}))}}function bt({go:e,query:n}){const s=E(),a=Le(),o=zn(Xn),t=g.useMemo(()=>new URLSearchParams(n),[n]),i=t.get("network"),l=i==="tcp"||i==="udp"?i:"all",d=t.get("state")??"",p=Object.hasOwn(ie,d)?d:"all",h=t.get("connection_id")??void 0,m=ve().data?.resources,u=Ve({connection_id:h,network:l,state:p},P(m,"flows",{whileLoading:!0})),f=P(m,"rules",{whileLoading:!1}),v=Re(f),M=f&&P(m,"config",{whileLoading:!1})&&m?.config.writable===!0,c=gs(),w=t.get("id"),N=os(w),_=t.get("path"),S=g.useMemo(()=>{const x=u.data?.flows??[];return _?un(x,_,v.data?.rules??[]):x},[u.data,_,v.data]),C=g.useMemo(()=>Hs(S,u.data,c,s,a),[S,u.data,c,s,a]),A=C.rows.find(x=>x.id===w),b=g.useMemo(()=>Es(N.data??void 0,M,s,a,A),[N.data,M,s,a,A]);return{...C,detail:b,network:l,setNetwork:x=>e("rules",G(n,{network:x==="all"?null:x})),state:p,setState:x=>e("rules",G(n,{state:x==="all"?null:x})),wide:o,id:w,rulesListed:f,error:u.error,retry:u.refetch,loading:u.loading&&!u.data,panelOpen:!!w&&(!!N.data||N.loading||!!N.error),panelTitle:b?.title??w??"",detailError:N.error,detailRetry:N.refetch,detailLoading:!N.data&&N.loading,select:x=>e("rules",G(n,{id:x}),{replace:w!==null}),pinLabel:_?s("flow.mapFilter",{label:ks(_,v.data?.rules??[],c,x=>x===null?s("flow.mapUnknown"):Se(x,s))}):null,clearPin:()=>e("rules",G(n,{path:null})),connectionLabel:h?s("flow.connectionFilter",{id:h}):null,clearConnection:()=>e("rules",G(n,{connection_id:null}))}}function ht(e){const n=E(),s=ft(e);return r.jsxs("section",{className:"rp-col","aria-label":n("flow.map"),children:[r.jsx(de,{error:s.error,onRetry:s.retry}),r.jsxs(Ne,{title:n("flow.topology"),note:n("flow.topologyNote"),className:"rp-topology",aside:r.jsx(Ce,{label:n("flow.topology"),value:s.by,onChange:s.changeBy,items:[["rule",n("flow.byRule")],["client",n("flow.byClient")]]}),children:[s.state==="loading"&&r.jsx(Ae,{}),s.state==="empty"&&r.jsx(ln,{children:n("flow.mapEmpty")}),s.state==="ready"&&r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"rp-tree-hint",children:n("flow.treePanHint")}),r.jsx(mt,{tree:s.tree,pinned:s.pinned,onPin:s.pin})]})]}),s.pinLabel&&r.jsxs("div",{className:"rp-toolbar",children:[r.jsx(W,{small:!0,onPress:s.viewPinned,children:s.pinLabel}),r.jsx(W,{small:!0,quiet:!0,onPress:()=>s.pin(null),children:n("flow.clearMapFilter")})]})]})}function gt(e){const n=E(),s=bt(e),a=s.detail,o=g.useMemo(()=>[{id:"target",label:n("ui.target"),minWidth:128,grow:2,isRowHeader:!0,render:t=>r.jsx(J,{children:t.target})},{id:"node",label:n("conn.node"),minWidth:96,drop:2,render:t=>r.jsx(J,{className:"rp-chain",text:t.path??void 0,children:t.node})},{id:"rule",label:n("conn.rule"),minWidth:152,grow:2,drop:1,render:t=>r.jsxs("span",{className:"rp-rule",children:[r.jsx(Zn,{expression:t.expression,href:us(t.ruleId,s.rulesListed)}),t.recomputed&&r.jsx("small",{className:"rp-provenance",children:n("conn.recomputed")})]})},{id:"network",label:n("ui.protocol"),minWidth:64,grow:0,drop:3,render:t=>t.network},{id:"state",label:n("ui.state"),minWidth:80,grow:0,drop:5,render:t=>t.state},{id:"started",label:n("ui.started"),minWidth:80,grow:0,drop:4,render:t=>r.jsx(hs,{at:t.startedAt})}],[n,s.rulesListed]);return r.jsxs(r.Fragment,{children:[r.jsx(de,{error:s.error,onRetry:s.retry}),r.jsxs("div",{className:"rp-toolbar",children:[r.jsx(Ce,{label:n("ui.network"),value:s.network,onChange:s.setNetwork,items:[["all",n("ui.all")],["tcp",n("ui.tcp")],["udp",n("ui.udp")]]}),r.jsx(ae,{label:n("ui.state"),side:!0,value:s.state,onChange:s.setState,items:s.stateOptions}),s.pinLabel&&r.jsxs(W,{small:!0,label:n("ui.valuePair",{label:n("flow.clearMapFilter"),value:s.pinLabel}),onPress:s.clearPin,children:[s.pinLabel,r.jsx(_e,{})]}),s.connectionLabel&&r.jsxs(W,{small:!0,label:n("ui.valuePair",{label:n("flow.clearConnectionFilter"),value:s.connectionLabel}),onPress:s.clearConnection,children:[s.connectionLabel,r.jsx(_e,{})]}),s.coverage&&r.jsx(bn,{view:s.coverage})]}),r.jsxs("div",{className:"rp-with-panel","data-open":s.panelOpen?"":void 0,children:[r.jsx(Te,{label:n("rule.flows"),rowDetail:!0,loading:s.loading,rows:s.rows,height:442,selected:s.id,onSelect:s.select,selectOnFocus:s.wide,empty:n("flow.empty"),cols:o}),r.jsxs(Yn,{open:s.panelOpen,title:s.panelTitle,onClose:()=>s.select(null),children:[r.jsx(de,{error:s.detailError,onRetry:s.detailRetry}),s.detailLoading&&r.jsx(Ae,{children:n("flow.detailLoading")}),a&&r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"rp-cluster",children:[r.jsx(ye,{tone:a.tone,children:a.status}),r.jsx("span",{className:"rp-label",children:a.revision})]}),r.jsx(Me,{inline:!0,items:a.fields}),r.jsxs("div",{className:"rp-cluster",children:[a.connectionHref&&r.jsx(Qe,{appearance:"button",small:!0,href:a.connectionHref,children:n("flow.viewConnection")}),a.seedHref&&r.jsx(Qe,{appearance:"button",small:!0,href:a.seedHref,children:n("flow.addRule")})]}),r.jsxs("div",{className:"rp-list",children:[!a.steps.length&&r.jsx(ln,{children:n("ui.empty")}),a.steps.map(t=>r.jsxs("div",{className:"rp-col rp-step",children:[r.jsxs("div",{className:"rp-cluster",children:[r.jsx(ye,{children:t.stage}),r.jsx(J,{text:t.observed,className:"rp-label",children:t.elapsed})]}),t.fields?r.jsx(Me,{inline:!0,items:t.fields}):r.jsx("pre",{className:"rp-flow-raw rp-code",children:r.jsx("code",{children:t.raw})})]},t.id))]})]})]})]})]})}function xt({go:e,query:n}){const s=E(),a=ve(),o=Xs(a.data?.resources,n,s);return{...o,loading:a.loading&&!a.data,error:a.error,retry:a.refetch,changeTab:t=>e("rules",es(n,t,o.fallback))}}function Ot(e){const n=E(),s=xt(e),a=tt(),o={map:r.jsx(ht,{...e}),list:r.jsx(lt,{...e}),flows:r.jsx(gt,{...e}),trace:r.jsx(wt,{form:a})};return s.loading?r.jsx(Ae,{}):s.error?r.jsx(de,{error:s.error,onRetry:s.retry}):r.jsx("div",{className:"rp-page",children:r.jsx(ns,{label:n("nav.rules"),items:s.tabs.map(t=>({...t,content:o[t.id]})),value:s.tab,onChange:s.changeTab})})}function wt({form:e}){const n=E(),s=rt(e),{form:a,setForm:o}=s,t=g.useMemo(()=>[{id:"expression",label:n("rule.expression"),minWidth:240,grow:2,isRowHeader:!0,render:i=>r.jsx(J,{className:"rp-code",text:i.id,children:i.expression})},{id:"result",label:n("rule.outcome"),minWidth:120,grow:0,render:i=>r.jsx(je,{small:!0,tone:i.tone,children:i.outcome})},{id:"missing",label:n("rule.missing"),minWidth:144,render:i=>i.missing}],[n]);return r.jsxs(r.Fragment,{children:[r.jsxs("form",{className:ts(),onSubmit:i=>{i.preventDefault(),s.submit()},children:[r.jsx(an,{reason:s.reason,children:r.jsxs("div",{className:"rp-toolbar top",children:[r.jsx(ae,{label:n("ui.network"),value:a.network,onChange:i=>o({...a,network:i}),items:[{id:"tcp",label:n("ui.tcp")},{id:"udp",label:n("ui.udp")}]}),r.jsx(Y,{label:n("ui.domain"),value:a.domain,placeholder:"example.com",onChange:i=>o({...a,domain:i}),error:s.errors.domain}),r.jsx(Y,{label:n("ui.destinationIp"),value:a.dst_ip,onChange:i=>o({...a,dst_ip:i}),error:s.errors.dst_ip}),r.jsx(Y,{label:n("rule.dstPort"),value:a.dst_port,placeholder:"443",onChange:i=>o({...a,dst_port:i}),error:s.errors.dst_port}),r.jsx(ae,{label:n("rule.resolve"),value:s.resolve,onChange:i=>o({...a,resolve:i}),items:s.modes}),r.jsx(W,{accent:!0,className:"rp-field-row",isPending:s.busy,isDisabled:!s.canSubmit,type:"submit",children:n("rule.run")})]})}),r.jsx(ss,{id:"rules-trace-advanced",title:n("rule.advanced"),isExpanded:s.advanced,onExpandedChange:s.setAdvanced,children:r.jsxs("div",{className:"rp-toolbar",children:[r.jsx(Y,{label:n("ui.sourceIp"),value:a.src_ip,onChange:i=>o({...a,src_ip:i}),error:s.errors.src_ip}),r.jsx(Y,{label:n("rule.srcPort"),value:a.src_port,onChange:i=>o({...a,src_port:i}),error:s.errors.src_port}),r.jsx(Y,{label:n("ui.process"),value:a.pname,onChange:i=>o({...a,pname:i})})]})}),s.ipOnly&&r.jsx("span",{className:"rp-label",children:n("rule.ipOnly")})]}),s.result&&r.jsxs("section",{className:"rp-col","aria-label":n("rule.result"),children:[r.jsx("div",{className:"rp-toolbar",children:r.jsx(J,{text:n("rule.note"),className:"rp-label",children:s.result.status})}),s.result.evaluations.map((i,l)=>r.jsxs(Ne,{children:[r.jsxs("div",{className:"rp-row",children:[r.jsx("h3",{className:"rp-h3",children:i.heading}),r.jsx(Me,{inline:!0,items:i.fields}),i.probe&&r.jsx(W,{small:!0,isPending:i.probe.pending,isDisabled:i.probe.disabled,onPress:()=>void s.probeNode(i.probe.id),children:i.probe.label})]}),i.hint&&r.jsx("p",{className:"rp-label",children:i.hint}),r.jsx(Te,{label:i.label,height:360,rows:i.rows,cols:t})]},l)),s.result.dns.map(i=>r.jsxs(Ne,{children:[r.jsx("h3",{className:"rp-h3",children:i.heading}),r.jsx(Me,{inline:!0,items:i.fields})]},i.id))]})]})}export{Ot as Rules};
|