Files

128 lines
74 KiB
JavaScript

'use strict';
'require form';
'require fs';
'require uci';
'require ui';
'require view';
var LuciView=(()=>{var qt=Object.defineProperty;var nr=Object.getOwnPropertyDescriptor;var sr=Object.getOwnPropertyNames;var or=Object.prototype.hasOwnProperty;var ir=(e,t)=>{for(var r in t)qt(e,r,{get:t[r],enumerable:!0})},ar=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of sr(t))!or.call(e,s)&&s!==r&&qt(e,s,{get:()=>t[s],enumerable:!(n=nr(t,s))||n.enumerable});return e};var lr=e=>ar(qt({},"__esModule",{value:!0}),e);var Gn={};ir(Gn,{default:()=>Hn});var Ee=view;var a=uci;var x=form;var d={CUSTOM:"custom",LOAD_BALANCE:"load_balance",HYSTERIA2:"hysteria2",SHADOWSOCKS:"shadowsocks",TUIC:"tuic",SHADOWTLS:"shadowtls",VLESS:"vless"},m={XRAY:"xray",SING_BOX:"sing-box",CUSTOM:"custom"},tt={NONE:"none",PRE_ROUTING:"pre-routing",ROUTING:"routing"};function k(e){let t=(e||"").trim();return t==="singbox"?m.SING_BOX:t}var qn={[m.XRAY]:[d.SHADOWSOCKS,d.HYSTERIA2,d.VLESS],[m.SING_BOX]:[d.SHADOWSOCKS,d.HYSTERIA2,d.VLESS,d.TUIC,d.SHADOWTLS]},Kn={DNS_STRATEGY_VALUES:[{label:"Prefer IPv6 (sing-box only, xray uses dual stack by default)",value:"64"},{label:"Prefer IPv4 (sing-box only, xray uses dual stack by default)",value:"46"},{label:"IPv6 only",value:"6"},{label:"IPv4 only",value:"4"}],SHUNT_LOG_LEVELS:["info","warn","error","debug"],PROXY_LOG_LEVELS:["info","warn","error","debug"],SHUNT_CONF_TYPE:[m.XRAY,m.SING_BOX],PROXY_TYPES:[{label:"Load Balancing",value:"load_balance"},{label:"Shadowsocks",value:"shadowsocks"},{label:"Hysteria2",value:"hysteria2"},{label:"VLESS",value:"vless"},{label:"TUIC",value:"tuic"},{label:"ShadowTLS",value:"shadowtls"}],SHADOWSOCKS_METHODS:[{label:"2022-blake3-aes-128-gcm",value:"2022-blake3-aes-128-gcm"},{label:"2022-blake3-aes-256-gcm",value:"2022-blake3-aes-256-gcm"},{label:"2022-blake3-chacha20-poly1305",value:"2022-blake3-chacha20-poly1305"},{label:"aes-128-gcm",value:"aes-128-gcm"},{label:"aes-192-gcm",value:"aes-192-gcm"},{label:"aes-256-gcm",value:"aes-256-gcm"},{label:"chacha20-ietf-poly1305",value:"chacha20-ietf-poly1305"},{label:"xchacha20-ietf-poly1305",value:"xchacha20-ietf-poly1305"}],MULTIPLEX_PROTOCOLS:[{label:"smux",value:"smux"},{label:"yamux",value:"yamux"},{label:"h2mux",value:"h2mux"}],TUIC_CONGESTION_CONTROLS:[{label:"cubic",value:"cubic"},{label:"new_reno",value:"new_reno"},{label:"bbr",value:"bbr"}],TUIC_UDP_RELAY_MODES:[{label:"Native UDP",value:"native"},{label:"QUIC Stream",value:"quic"}],SHADOWTLS_VERSIONS:[{label:"v1",value:"1"},{label:"v2",value:"2"},{label:"v3",value:"3"}],VLESS_FLOWS:[{label:"None",value:""},{label:"xtls-rprx-vision",value:"xtls-rprx-vision"},{label:"xtls-rprx-vision-udp443",value:"xtls-rprx-vision-udp443"}],VLESS_PACKET_ENCODINGS:[{label:"Disabled",value:""},{label:"packetaddr",value:"packetaddr"},{label:"xudp",value:"xudp"}],V2RAY_TRANSPORT_TYPES_XRAY:[{label:"None",value:""},{label:"HTTP",value:"http"},{label:"WebSocket",value:"ws"},{label:"gRPC",value:"grpc"},{label:"HTTPUpgrade",value:"httpupgrade"},{label:"XHTTP",value:"xhttp"}],HYSTERIA2_OBFS_TYPES:[{label:"Disabled",value:""},{label:"Salamander",value:"salamander"}],DUAL_CORES:[{label:"sing-box",value:m.SING_BOX},{label:"xray",value:m.XRAY},{label:"Custom",value:m.CUSTOM}]};var h=fs;var M=ui;var X=class{disabled;level;timestamp;constructor(t){this.disabled=!1,this.level=t||"info",this.timestamp=!0}},et=class{type;tag;server;server_port;detour;constructor(t,r,n,s,o){this.type=t,this.tag=r,this.server=n,this.server_port=Number.isFinite(s)&&s>0?s:void 0,this.detour=o==="direct-out"?void 0:o}},lt=class{servers;rules;strategy;disable_cache;disable_expire;final;constructor(t,r,n){this.servers=[],this.rules=[],this.strategy=r||"prefer_ipv6",this.disable_cache=!n,this.disable_expire=!n,this.final=t}},ut=class{action;outbound;constructor(t,r){this.action=t,this.outbound=r}},j=class extends ut{ip_version;protocol;port;port_range;domain;domain_suffix;domain_keyword;domain_regex;rule_set;ip_cidr;network;constructor(t,r){super(t,r)}initRule(t){return this.ip_version=t.ipVersion,this.network=t.network,this.protocol=t.protocol,this.port=t.port,this.port_range=t.portRange.map(r=>r.replace("-",":")),this.domain=t.domain,this.domain_suffix=t.domainSuffix,this.domain_keyword=t.domainKeyword,this.domain_regex=t.domainRegex,this.rule_set=t.ruleSet.map(r=>r.tag),this.ip_cidr=t.ipCidr,this}},pt=class extends ut{domain;domain_keyword;domain_regex;domain_suffix;rule_set;server;strategy;disable_cache;disable_expire;constructor(t,r,n){super(t,void 0),this.action=t,this.server=r,this.strategy=n,this.disable_cache=!0}initRule(t){return this.domain=t.domain,this.domain_suffix=t.domainSuffix,this.domain_keyword=t.domainKeyword,this.domain_regex=t.domainRegex,this.rule_set=t.ruleSet.map(r=>r.tag),this}},Kt=class extends j{constructor(){super("sniff",void 0)}},zt=class extends j{constructor(){super("hijack-dns",void 0),this.protocol=["dns"]}},ct=class{type;tag;format;constructor(t,r,n){this.type=r,this.tag=t,this.format=n}},dt=class extends ct{url;http_client;update_interval;constructor(t,r,n,s,o){super(t,"remote",r),this.url=n,s&&(this.http_client=new Qt(s)),this.update_interval=o}},Qt=class{detour;constructor(t){this.detour=t}},gt=class extends ct{path;constructor(t,r,n){super(t,"local",r),this.path=n}},_t=class{rules;rule_set;default_domain_resolver;final;constructor(t,r){this.rules=[new Kt,new zt],this.rule_set=[],this.default_domain_resolver=r,this.final=t}},V=class{type="tproxy";tag;listen;listen_port;constructor(t,r,n){this.tag=r,this.listen=n??"::",this.listen_port=t}},mt=class{type="direct";tag;listen;listen_port;constructor(t,r){this.tag=r,this.listen="::",this.listen_port=t}},rt=class{type="socks";tag;listen;listen_port;users;constructor(t,r,n){this.tag=r,this.listen=n??"::",this.listen_port=t}},ft=class{type="block";tag;constructor(t){this.tag=t}},ht=class{type="direct";tag;domain_resolver;constructor(t){this.tag=t}},yt=class{type="urltest";tag;url;interval;tolerance;idle_timeout;interrupt_exist_connections;outbounds;constructor(t,r,n,s,o,i){this.tag=t,this.outbounds=[],this.url=r,this.interval=n,this.tolerance=s,this.idle_timeout=o,this.interrupt_exist_connections=i}},W=class{type="socks";tag;server;server_port;version="5";domain_resolver;constructor(t,r,n){this.tag=n,this.server=t,this.server_port=r,this.version="5"}},A=class{enabled;server_name;insecure;reality;constructor(t){this.enabled=!0,this.server_name=t}},q=class{enabled;up_mbps;down_mbps;constructor(){this.enabled=!0}},K=class{enabled;protocol;max_connections;min_streams;max_streams;brutal;constructor(){this.enabled=!0}};var $t=class{protocols=new Map;register(t){this.protocols.set(t.type,t)}build(t,r){let n=this.protocols.get(t);if(!n)throw new Error(`Unsupported sing-box protocol: ${t}`);return n.build(r)}},C=new $t;var Jt=class{type;password;constructor(t){this.type="salamander",this.password=t}},Zt=class{type="hysteria2";tag;server;server_port;password;obfs;up_mbps;down_mbps;server_ports;hop_interval;network;tls;constructor(t,r,n,s){this.tag=t,this.server=r,this.server_port=n,this.tls=new A(s)}},pr={type:"hysteria2",build(e){let t=e,r=new Zt(t.name,t.server,parseInt(t.server_port),t.tls_server_name||t.server);return t.password&&(r.password=t.password),t.up_mbps&&(r.up_mbps=Number(t.up_mbps)),t.down_mbps&&(r.down_mbps=Number(t.down_mbps)),t.server_ports&&t.server_ports.length>0&&(r.server_ports=t.server_ports.map(n=>n.replace("-",":")).filter(n=>n.length>0)),t.hop_interval&&(r.hop_interval=t.hop_interval),t.network&&(r.network=t.network),t.obfs_type==="salamander"&&t.obfs_password&&(r.obfs=new Jt(t.obfs_password)),r.tls.insecure=t.tls_insecure==="1",r}};C.register(pr);var te=class{type="shadowsocks";tag;server;server_port;method;password;network;udp_over_tcp;plugin;plugin_opts;multiplex;constructor(t,r,n,s,o){this.tag=t,this.server=r,this.server_port=n,this.method=s,this.password=o}};function cr(e){let t=new K;if(e.multiplex_protocol&&(t.protocol=e.multiplex_protocol),e.multiplex_max_connections&&(t.max_connections=parseInt(e.multiplex_max_connections)),e.multiplex_min_streams&&(t.min_streams=parseInt(e.multiplex_min_streams)),e.multiplex_max_streams&&(t.max_streams=parseInt(e.multiplex_max_streams)),e.multiplex_brutal_enabled==="1"){let r=new q;e.multiplex_brutal_up_mbps&&(r.up_mbps=parseInt(e.multiplex_brutal_up_mbps)),e.multiplex_brutal_down_mbps&&(r.down_mbps=parseInt(e.multiplex_brutal_down_mbps)),t.brutal=r}return t}var dr={type:"shadowsocks",build(e){let t=e,r=new te(t.name,t.server,parseInt(t.server_port),t.method,t.password);return t.network&&(r.network=t.network),t.udp_over_tcp==="1"&&(r.udp_over_tcp=!0),t.plugin&&(r.plugin=t.plugin),t.plugin_opts&&(r.plugin_opts=t.plugin_opts),t.multiplex_enabled==="1"&&(r.multiplex=cr(t)),r}};C.register(dr);var ee=class{type="vless";tag;server;server_port;uuid;flow;network;packet_encoding;tls;transport;multiplex;constructor(t,r,n,s,o){this.tag=t,this.server=r,this.server_port=n,this.uuid=s,this.tls=new A(o)}};function gr(e){switch(e.transport_type){case"http":{let t={type:"http"};return e.transport_http_host&&(t.host=e.transport_http_host),e.transport_http_path&&(t.path=e.transport_http_path),e.transport_http_method&&(t.method=e.transport_http_method),e.transport_http_idle_timeout&&(t.idle_timeout=e.transport_http_idle_timeout),e.transport_http_ping_timeout&&(t.ping_timeout=e.transport_http_ping_timeout),t}case"ws":{let t={type:"ws"};return e.transport_ws_path&&(t.path=e.transport_ws_path),e.transport_ws_host&&(t.headers={Host:e.transport_ws_host}),e.transport_ws_max_early_data&&(t.max_early_data=parseInt(e.transport_ws_max_early_data)),e.transport_ws_early_data_header_name&&(t.early_data_header_name=e.transport_ws_early_data_header_name),t}case"grpc":{let t={type:"grpc"};return e.transport_grpc_service_name&&(t.service_name=e.transport_grpc_service_name),e.transport_grpc_idle_timeout&&(t.idle_timeout=e.transport_grpc_idle_timeout),e.transport_grpc_ping_timeout&&(t.ping_timeout=e.transport_grpc_ping_timeout),e.transport_grpc_permit_without_stream==="1"&&(t.permit_without_stream=!0),t}case"httpupgrade":{let t={type:"httpupgrade"};return e.transport_httpupgrade_host&&(t.host=e.transport_httpupgrade_host),e.transport_httpupgrade_path&&(t.path=e.transport_httpupgrade_path),t}default:return}}function _r(e){let t=new K;if(e.multiplex_protocol&&(t.protocol=e.multiplex_protocol),e.multiplex_max_connections&&(t.max_connections=parseInt(e.multiplex_max_connections)),e.multiplex_min_streams&&(t.min_streams=parseInt(e.multiplex_min_streams)),e.multiplex_max_streams&&(t.max_streams=parseInt(e.multiplex_max_streams)),e.multiplex_brutal_enabled==="1"){let r=new q;e.multiplex_brutal_up_mbps&&(r.up_mbps=parseInt(e.multiplex_brutal_up_mbps)),e.multiplex_brutal_down_mbps&&(r.down_mbps=parseInt(e.multiplex_brutal_down_mbps)),t.brutal=r}return t}var mr={type:"vless",build(e){let t=e,r=new ee(t.name,t.server,parseInt(t.server_port),t.uuid,t.tls_server_name||t.server);return t.flow&&(r.flow=t.flow),t.network&&(r.network=t.network),t.packet_encoding&&(r.packet_encoding=t.packet_encoding),r.tls.insecure=t.tls_insecure==="1",t.tls_reality_enabled==="1"&&t.tls_reality_public_key&&(r.tls.reality={enabled:!0,public_key:t.tls_reality_public_key,short_id:t.tls_reality_short_id||""}),t.transport_type&&(r.transport=gr(t)),t.multiplex_enabled==="1"&&(r.multiplex=_r(t)),r}};C.register(mr);var re=class{type="tuic";tag;server;server_port;uuid;password;congestion_control;udp_relay_mode;udp_over_stream;zero_rtt_handshake;heartbeat;network;tls;constructor(t,r,n,s,o,i){this.tag=t,this.server=r,this.server_port=n,this.uuid=s,this.password=o,this.tls=new A(i)}},fr={type:"tuic",build(e){let t=e,r=new re(t.name,t.server,parseInt(t.server_port),t.uuid,t.password,t.tls_server_name||t.server);return t.congestion_control&&(r.congestion_control=t.congestion_control),t.udp_relay_mode&&(r.udp_relay_mode=t.udp_relay_mode),t.udp_over_stream==="1"&&(r.udp_over_stream=!0),t.zero_rtt_handshake==="1"&&(r.zero_rtt_handshake=!0),t.heartbeat&&(r.heartbeat=t.heartbeat),t.network&&(r.network=t.network),r.tls.insecure=t.tls_insecure==="1",r}};C.register(fr);var ne=class{type="shadowtls";tag;server;server_port;version;password;tls;constructor(t,r,n,s,o){this.tag=t,this.server=r,this.server_port=n,this.version=s,this.tls=new A(o)}},hr={type:"shadowtls",build(e){let t=e,r=new ne(t.name,t.server,parseInt(t.server_port),parseInt(t.version),t.tls_server_name||t.server);return t.password&&(r.password=t.password),r.tls.insecure=t.tls_insecure==="1",r}};C.register(hr);var bt=class{tag;type;server;port},xt=class{defaultDnsNode;defaultStrategy;rulesetDnsNode;useCache;nodes;constructor(){this.nodes=[]}},z=class{enabled;name;proxyNode;ipVersionSplit;proxyNodeV4;proxyNodeV6;protocol;network;port;portRange;domainList;ipList;dnsNode;dnsProxyNode;dnsStrategy;constructor(){this.port=[],this.portRange=[],this.network=[],this.protocol=[],this.ipVersionSplit="0"}},Tt=class{defaultProxyNode;rulesetOutNode;rulesetConvert;rules;constructor(){this.rules=[]}},Nt=class{type;configType;shuntListenPort;dnsListenPort;logLevel;logPath;route;dns},vt=class{domain;domainRegex;domainKeyword;domainSuffix;ipCidr;network;protocol;port;portRange;ipVersion;ruleSet;geoIp;geoSite;constructor(){this.domain=[],this.domainRegex=[],this.domainKeyword=[],this.domainSuffix=[],this.ruleSet=[],this.ipCidr=[],this.geoIp=[],this.geoSite=[],this.network=[],this.protocol=[],this.port=[],this.portRange=[]}containDomain(){return this.domain.length>0||this.domainRegex.length>0||this.domainSuffix.length>0||this.domainKeyword.length>0}containGeo(){return this.geoSite.length>0||this.geoIp.length>0}containRuleSet(){return this.ruleSet.length>0}containIp(){return this.ipCidr.length>0||this.geoIp.length>0}isEmpty(t){return!(this.containDomain()||this.containIp()||t==="geo"&&this.containGeo()||t==="set"&&this.containRuleSet()||this.network.length>0||this.port.length>0||this.portRange.length>0||this.protocol.length>0)}},St=class{name;type="load_balance";core=m.SING_BOX;enabled="1";listen_port;socks_port;member_node;procd_env;log_level;log_path;url;interval;tolerance;idle_timeout;interrupt_exist_connections;strategy;strategy_expected;strategy_max_rtt;strategy_tolerance;fallback_tag;probe_url;probe_connectivity;probe_interval;probe_timeout;probe_sampling;probe_http_method;constructor(){this.member_node=[],this.procd_env=[]}},Et=class{name;type="custom";enabled="1";command;listen_port;socks_port;procd_env;log_enabled;log_path;constructor(){this.type="custom",this.enabled="1",this.procd_env=[]}},wt=class{name;type="hysteria2";enabled="1";core;server;server_port;server_ports;hop_interval;obfs_type;obfs_password;brutal_debug;udp_idle_timeout;up_mbps;down_mbps;password;network;tls_server_name;tls_insecure;listen_port;socks_port;procd_env;log_path;constructor(){this.type="hysteria2",this.enabled="1",this.core=m.SING_BOX,this.server_ports=[],this.network="",this.brutal_debug="0",this.tls_insecure="0"}},Ot=class{name;type="shadowsocks";enabled="1";core;server;server_port;method;password;plugin;plugin_opts;network;udp_over_tcp;listen_port;socks_port;multiplex_enabled;multiplex_protocol;multiplex_max_connections;multiplex_min_streams;multiplex_max_streams;multiplex_brutal_enabled;multiplex_brutal_up_mbps;multiplex_brutal_down_mbps;procd_env;log_path;constructor(){this.type="shadowsocks",this.enabled="1",this.core=m.SING_BOX,this.network="",this.udp_over_tcp="0",this.multiplex_enabled="0",this.multiplex_protocol="h2mux",this.multiplex_brutal_enabled="0"}},Ct=class{name;type="tuic";enabled="1";core;server;server_port;uuid;password;congestion_control;udp_relay_mode;udp_over_stream;zero_rtt_handshake;heartbeat;network;tls_server_name;tls_insecure;listen_port;socks_port;procd_env;log_path;constructor(){this.type="tuic",this.enabled="1",this.core=m.SING_BOX,this.congestion_control="cubic",this.udp_relay_mode="",this.udp_over_stream="0",this.zero_rtt_handshake="0",this.heartbeat="10s",this.network="",this.tls_insecure="0"}},Pt=class{name;type="shadowtls";enabled="1";core;server;server_port;version;password;tls_server_name;tls_insecure;listen_port;socks_port;procd_env;log_path;constructor(){this.type="shadowtls",this.enabled="1",this.core=m.SING_BOX,this.version="1",this.tls_insecure="0"}},Rt=class{name;type="vless";enabled="1";core;server;server_port;uuid;flow;network;packet_encoding;tls_server_name;tls_insecure;tls_reality_enabled;tls_reality_public_key;tls_reality_short_id;listen_port;socks_port;multiplex_enabled;multiplex_protocol;multiplex_max_connections;multiplex_min_streams;multiplex_max_streams;multiplex_brutal_enabled;multiplex_brutal_up_mbps;multiplex_brutal_down_mbps;transport_type;transport_http_host;transport_http_path;transport_http_method;transport_http_idle_timeout;transport_http_ping_timeout;transport_ws_host;transport_ws_path;transport_ws_max_early_data;transport_ws_early_data_header_name;transport_grpc_service_name;transport_grpc_idle_timeout;transport_grpc_ping_timeout;transport_grpc_permit_without_stream;transport_httpupgrade_host;transport_httpupgrade_path;transport_xhttp_host;transport_xhttp_path;transport_xhttp_mode;procd_env;log_path;constructor(){this.type="vless",this.enabled="1",this.core=m.XRAY,this.network="tcp",this.packet_encoding="",this.tls_insecure="0",this.tls_reality_enabled="0",this.multiplex_enabled="0",this.multiplex_protocol="h2mux",this.multiplex_brutal_enabled="0",this.transport_type="",this.transport_http_idle_timeout="15s",this.transport_http_ping_timeout="15s",this.transport_grpc_idle_timeout="15s",this.transport_grpc_ping_timeout="15s",this.transport_grpc_permit_without_stream="0",this.transport_xhttp_path="/",this.transport_xhttp_mode="auto"}};var F={camelToSnake:function(e){return e.replace(/([A-Z])/g,function(t){return"_"+t.toLowerCase()})},transFromUci:function(e,t){Object.keys(e).forEach(r=>{let n=F.camelToSnake(r);t[n]&&(e[r]=t[n])})},generateUniqueSectionId:function(e="hijpass"){let t="abcdefghijklmnopqrstuvwxyz0123456789",r="";for(;;){r="";for(let n=0;n<8;n++)r+=t.charAt(Math.floor(Math.random()*t.length));if(!a.get(e,r))break}return r}};function we(e,t){let r=e.substring(t==="remote"?16:15),n=r.split("/").pop(),s=n.substring(0,n.lastIndexOf("."))||n,o=(t==="remote"?r:n).endsWith("srs")?"binary":"source";return{tag:s,type:t,format:o,pathOrUrl:r}}var T={getShuntSection:function(){let e=new Nt,t=a.get_first("hijpass","shunt");return F.transFromUci(e,t),e.dns=T.getDnsSection(),e.route=T.getRouteSection(),e},getRouteSection:function(){let e=a.get_first("hijpass","shunt"),t=new Tt;return F.transFromUci(t,e),a.sections("hijpass","shunt_route_rule",function(r){let n=new z;F.transFromUci(n,r),t.rules.push(n)}),t},getRouteRuleVariants:function(e){if(e.ipVersionSplit!=="1")return[{rule:e,proxyNode:e.proxyNode}];let t=[];if(e.proxyNodeV4){let r=Object.assign(new z,e);r.name=e.name?e.name+"-ipv4":e.name,r.proxyNode=e.proxyNodeV4,t.push({rule:r,proxyNode:e.proxyNodeV4,ipVersion:4})}if(e.proxyNodeV6){let r=Object.assign(new z,e);r.name=e.name?e.name+"-ipv6":e.name,r.proxyNode=e.proxyNodeV6,t.push({rule:r,proxyNode:e.proxyNodeV6,ipVersion:6})}return t},getDnsSection:function(){let e=a.get_first("hijpass","shunt"),t=new xt;return t.nodes=[],F.transFromUci(t,e),a.sections("hijpass","shunt_dns_node",function(r){if(r.enabled==="0")return;let n=new bt;F.transFromUci(n,r),t.nodes.push(n)}),t},parseRuleList:function(e){let t=new vt,r=e.domainList,n=e.ipList;if(t.network=e.network?e.network:[],t.protocol=e.protocol?e.protocol:[],e.port&&(t.port=e.port.map(s=>parseInt(s,10)).filter(s=>!isNaN(s))),e.portRange&&(t.portRange=e.portRange.map(s=>s.replace("-",":")).filter(s=>s.length>0)),r&&r.trim()!==""){let s=r.split(`
`);for(let o of s)if(o=o.trim(),!(o===""||o.startsWith("#"))){if(o.startsWith("rule-set:")){let i=o.startsWith("rule-set:remote:")?"remote":"local",l=we(o,i);t.ruleSet.push(l);continue}o.startsWith("regexp:")?t.domainRegex.push(o.substring(7)):o.startsWith("domain:")?t.domainSuffix.push(o.substring(7)):o.startsWith("full:")?t.domain.push(o.substring(5)):o.startsWith("geosite:")?t.geoSite.push(o):t.domainKeyword.push(o)}}if(n&&n.trim()!==""){let s=n.split(`
`);for(let o of s)if(o=o.trim(),!(o===""||o.startsWith("#"))){if(o.startsWith("rule-set:")){let i=o.startsWith("rule-set:remote:")?"remote":"local",l=we(o,i);t.ruleSet.push(l);continue}o.startsWith("geoip:")?t.geoIp.push(o):t.ipCidr.push(o)}}return t}};var se=3,Ut="lb-member-";function Oe(e){return e?.name||e?.[".name"]||""}function oe(e){return k(e?.core||m.SING_BOX)}function ie(e){if(!e)return!1;let t=Number(e);return Number.isInteger(t)&&t>0&&t<=65535}function Ce(){let e=[];return a.sections("hijpass","proxy_node",function(t){e.push(t)}),e}function ae(){let e=new Map;return Ce().forEach(t=>{let r=Oe(t);r&&e.set(r,t)}),e}function Pe(e){return"upstream-"+e}function le(e){return e?(Array.isArray(e)?e:[e]).filter(t=>!!t):[]}function Re(e){return Ut+e}function yr(e,t=ae()){let r=le(e.member_node);if(r.length===0)throw new Error("Load balancing node has no members: "+e.name);return r.map((n,s)=>{if(n===e.name)throw new Error("Load balancing node cannot include itself: "+n);let o=t.get(n);if(!o)throw new Error("Load balancing member node not found: "+n);if(o.type===d.LOAD_BALANCE)throw new Error("Nested load balancing members are not supported: "+n);if(o.enabled!=="1")throw new Error("Load balancing member node disabled: "+n);if(!ie(o.socks_port))throw new Error("Load balancing member node SOCKS port invalid: "+n);return{name:n,socksPort:Number(o.socks_port),tag:Re(s),core:oe(o),section:o}})}function br(e,t=ae()){let r=e.upstream_proxy_node;if(!r)return;if(r===e.name)throw new Error("Upstream proxy node cannot be itself: "+r);let n=t.get(r);if(!n)throw new Error("Upstream proxy node not found: "+r);if(n.enabled!=="1")throw new Error("Upstream proxy node disabled: "+r);if(!ie(n.socks_port))throw new Error("Upstream proxy node SOCKS port invalid: "+r);return{name:r,socksPort:Number(n.socks_port),tag:Pe(r),core:oe(n),section:n}}function xr(e,t){let r=[],n=new Set,s=e;for(;s;){if(n.has(s))return r.push(s),{chain:r,cycle:!0};n.add(s),r.push(s);let o=t.get(s);if(!o||!o.upstream_proxy_node)break;s=o.upstream_proxy_node}return{chain:r,cycle:!1}}function Ue(e){let t=[];return e?.type===d.LOAD_BALANCE?t.push(...le(e.member_node)):e?.upstream_proxy_node&&t.push(e.upstream_proxy_node),t}function Tr(e){let t=new Set,r=new Set,n=[];function s(o){if(r.has(o)){let l=n.indexOf(o);return n.slice(l).concat(o)}if(t.has(o))return;let i=e.get(o);if(!(!i||i.enabled!=="1")){r.add(o),n.push(o);for(let l of Ue(i)){let u=s(l);if(u)return u}n.pop(),r.delete(o),t.add(o)}}for(let o of e.keys()){let i=s(o);if(i)return i}}var N={getProxyName:Oe,getProxyCore:oe,getProxySections:Ce,getProxySectionMap:ae,isPort:ie,getUpstreamProxyOutboundTag:Pe,normalizeProxyNodeList:le,getLoadBalanceMemberOutboundTag:Re,resolveUpstreamProxy:br,resolveLoadBalanceMembers:yr,collectProxyChain:xr,getProxyDependencies:Ue,findProxyDependencyCycle:Tr};var st={genShuntConf:Nr,genProxyConf:vr,writeGeoRule:wr};function Nr(){let e=T.getShuntSection();if(!e)return;let t=new Map,r=new Map,n=e.dns,s=e.route,o=new _t(nt(s.defaultProxyNode),n.defaultDnsNode),i=new lt(n.defaultDnsNode,ke(n.defaultStrategy),n.useCache==="1");n.nodes.forEach(function(p){let f=new et(p.type,p.tag,p.server,parseInt(p.port,10),void 0);t.set(p.tag,f)});let l=[new ht("direct-out"),new ft("block")];a.sections("hijpass","proxy_node",function(p){p.enabled==="1"&&l.push(new W("127.0.0.1",Number(p.socks_port),p.name))});let u=[new V(parseInt(e.shuntListenPort,10),"tproxy-in"),new mt(parseInt(e.dnsListenPort,10),"dns-in")];if(o.default_domain_resolver&&o.final){let p=t.get(o.default_domain_resolver);if(!p)throw new Error(_('Default global DNS "%s" does not exist').format(o.default_domain_resolver));i.servers.push(ue(p.tag,o.final,p))}if(s.rulesetOutNode){let p=nt(s.rulesetOutNode),f=l.find(y=>y.tag===p);if(f){let y=structuredClone(f);if(y.tag="ruleset-out",n.rulesetDnsNode){y.domain_resolver="ruleset-dns-resolver";let b=t.get(n.rulesetDnsNode);if(!b)throw new Error(_('%s "%s" does not exist').format(_("Rule-set DNS"),n.rulesetDnsNode));i.servers.push(ue("ruleset-dns-resolver","ruleset-out",b))}l.push(y)}}return s.rules.forEach(function(p){if(p.enabled!=="1")return;let f=p.ipVersionSplit==="1",y,b=!1;if(T.getRouteRuleVariants(p).forEach(function(S){let c=T.parseRuleList(S.rule),g=Ur(c,s.rulesetConvert);if(c.ipVersion=S.ipVersion,s.rulesetConvert==="1")Cr(c);else if(c.containGeo()&&(Pr(c),!Rr(c)))return;if(c.isEmpty("set"))return;for(let U of c.ruleSet)r.set(U.tag,Or(U,s.rulesetOutNode?"ruleset-out":void 0));let w="route",H=nt(S.proxyNode);if(S.proxyNode==="hijpass-block"&&(w="reject",H=void 0),o.rules.push(new j(w,H).initRule(c)),w!=="reject"){if(f){g&&(y=y||c,b=!0);return}(c.containDomain()||c.containIp()||c.containRuleSet())&&Ae(p,S.rule.name,c,nt(p.dnsProxyNode)||H,t,o,i)}}),f&&b&&y){let S=nt(p.dnsProxyNode);if(!S)throw new Error(_('Route rule "%s" uses IPv4/IPv6 split and must specify a DNS exit node').format(p.name));Ae(p,p.name,y,S,t,o,i)}}),r.forEach(p=>o.rule_set.push(p)),{log:new X(e.logLevel),inbounds:u,outbounds:l,dns:i,route:o}}function vr(e){if(e.type===d.LOAD_BALANCE)return Sr(e);let t=C.build(e.type,e),r=[t];return Er(e,t,r),{log:new X(e.log_level),dns:{servers:[{type:"local",tag:"local"}]},inbounds:[new V(Number(e.listen_port),"tproxy-in","127.0.0.1"),new rt(Number(e.socks_port),"socks-in","127.0.0.1")],outbounds:r}}function Sr(e){let t=N.resolveLoadBalanceMembers(e),r=new yt("slb",e.url||void 0,e.interval||void 0,e.tolerance?parseInt(e.tolerance,10):void 0,e.idle_timeout||void 0,e.interrupt_exist_connections==="1"?!0:void 0);return r.outbounds=t.map(n=>n.tag),{log:new X(e.log_level),dns:{servers:[{type:"local",tag:"local"}]},inbounds:[new V(Number(e.listen_port),"tproxy-in","127.0.0.1"),new rt(Number(e.socks_port),"socks-in","127.0.0.1")],outbounds:[r,...t.map(n=>new W("127.0.0.1",n.socksPort,n.tag))],route:{final:"slb"}}}function Er(e,t,r){let n=N.resolveUpstreamProxy(e);n&&(t.detour=n.tag,r.push(new W("127.0.0.1",n.socksPort,n.tag)))}function wr(){let e=T.getRouteSection(),t=new Set,r=new Set;for(let l of e.rules){if(l.enabled!=="1")continue;let u=T.parseRuleList(l);for(let p of u.geoSite)t.add(p.replace("geosite:",""));for(let p of u.geoIp)r.add(p.replace("geoip:",""))}let n=[...t],s=[...r],o=a.get_first("hijpass","shunt","geoip_ruleset")??[],i=a.get_first("hijpass","shunt","geosite_ruleset")??[];s.length>0?Le(o,s)||a.set_first("hijpass","shunt","geoip_ruleset",s):a.set_first("hijpass","shunt","geoip_ruleset",void 0),n.length>0?Le(i,n)||a.set_first("hijpass","shunt","geosite_ruleset",n):a.set_first("hijpass","shunt","geosite_ruleset",void 0)}function ue(e,t,r){return new et(r.type,e,r.server,r.server_port,t)}function Or(e,t){return e.type==="remote"?new dt(e.tag,e.format,e.pathOrUrl,t,void 0):new gt(e.tag,e.format,e.pathOrUrl)}function ke(e){switch(e){case"4":return"ipv4_only";case"6":return"ipv6_only";case"64":return"prefer_ipv6";case"46":return"prefer_ipv4";default:return}}function Ae(e,t,r,n,s,o,i){let l=e.dnsNode,u=l?s.get(l):s.get(o.default_domain_resolver);if(!u)throw new Error(_('Route rule "%s" DNS node "%s" does not exist').format(e.name||t,e.dnsNode||o.default_domain_resolver||""));i.servers.push(ue(De(t),n,u)),i.rules.push(new pt("route",De(t),ke(e.dnsStrategy)).initRule(r))}function nt(e){return e==="hijpass-block"?"block":e==="hijpass-direct"?"direct-out":e}function De(e){return e+"-dns"}function Cr(e){e.ruleSet=[];for(let t of e.geoSite){let r=t.replace("geosite:","geosite-");e.ruleSet.push({tag:r,type:"local",format:"binary",pathOrUrl:"/etc/hijpass/ruleset/"+r+".srs"})}for(let t of e.geoIp){let r=t.replace("geoip:","geoip-");e.ruleSet.push({tag:r,type:"local",format:"binary",pathOrUrl:"/etc/hijpass/ruleset/"+r+".srs"})}}function Pr(e){e.geoSite=[],e.geoIp=[]}function Rr(e){return e.containDomain()||e.containIp()||e.containRuleSet()}function Ur(e,t){return e.containDomain()||e.containRuleSet()||t==="1"&&e.geoSite.length>0}function Le(e,t){return!e||!t?!1:e.length===t.length&&e.every((r,n)=>r===t[n])}var ce=class{protocols=new Map;register(t){this.protocols.set(t.type,t)}build(t,r){let n=this.protocols.get(t);if(!n)throw new Error(`Unsupported xray protocol: ${t}`);return n.build(r)}},I=new ce;var de=class{settings;protocol;tag;streamSettings;constructor(t,r,n,s,o,i,l,u){this.protocol="hysteria",this.tag=n,this.settings={version:2,address:t,port:r},this.streamSettings={network:"hysteria",security:"tls",tlsSettings:{serverName:o,alpn:["h3"]},hysteriaSettings:{version:2,auth:s,...i!==void 0?{udpIdleTimeout:i}:{}},...l||u?{finalmask:{quicParams:{...l?{brutalUp:l}:{},...u?{brutalDown:u}:{}}}}:{}}}};function Ie(e){let t=(e||"").trim();if(t)return t==="0"?"0":t+" mbps"}var Ar={type:"hysteria2",build(e){let t=e,r=t.udp_idle_timeout?Number(t.udp_idle_timeout):void 0,n=Ie(t.up_mbps),s=Ie(t.down_mbps);return new de(t.server,Number(t.server_port),t.name,t.password||"",t.tls_server_name||t.server,r,n,s)}};I.register(Ar);var ge=class{settings;protocol;tag;constructor(t,r,n,s,o,i){this.protocol="shadowsocks",this.tag=n,this.settings={address:t,port:r,method:s,password:o,uot:i||void 0,level:0}}},Dr={type:"shadowsocks",build(e){let t=e;return new ge(t.server,Number(t.server_port),t.name,t.method,t.password,t.udp_over_tcp==="1"?!0:void 0)}};I.register(Dr);var _e=class{settings;protocol;tag;streamSettings;constructor(t,r,n,s,o="none",i,l=0){this.protocol="vless",this.tag=s,this.settings={address:t,port:r,id:n,encryption:o,level:l},i&&(this.settings.flow=i)}};function At(e){let t=(e||"").trim();if(!t)return;let r=t.match(/^(\d+)(?:s)?$/);if(!r)return;let n=Number(r[1]);return Number.isFinite(n)&&n>0?n:void 0}function Lr(e,t){let r=(t||"").trim();if(!r)return e;let n=e||"/",s=n.indexOf("#"),o=s>=0?n.slice(0,s):n,i=s>=0?n.slice(s):"",l=o.indexOf("?")>=0?"&":"?";return o+l+"ed="+encodeURIComponent(r)+i}var kr={type:"vless",build(e){let t=e,r=new _e(t.server,Number(t.server_port),t.uuid,t.name,"none",t.flow||void 0,0),n=t.tls_reality_enabled==="1",s=n?{fingerprint:"chrome",serverName:t.tls_server_name||t.server,password:t.tls_reality_public_key||"",shortId:t.tls_reality_short_id||""}:void 0,o=n?void 0:{alpn:["h2","http/1.1"],serverName:t.tls_server_name||t.server},i=n?"reality":t.tls_server_name?"tls":"none",l={network:"raw",security:i};switch(s&&(l.realitySettings=s),o&&i==="tls"&&(l.tlsSettings=o),t.transport_type||""){case"xhttp":l.network="xhttp",l.xhttpSettings={host:t.transport_xhttp_host||void 0,path:t.transport_xhttp_path||"/",mode:t.transport_xhttp_mode||"auto"};break;case"ws":l.network="websocket",l.wsSettings={host:t.transport_ws_host||void 0,path:Lr(t.transport_ws_path||"/",t.transport_ws_max_early_data)};break;case"grpc":l.network="grpc",l.grpcSettings={serviceName:t.transport_grpc_service_name||"TunService",...At(t.transport_grpc_idle_timeout)?{idle_timeout:At(t.transport_grpc_idle_timeout)}:{},...At(t.transport_grpc_ping_timeout)?{health_check_timeout:At(t.transport_grpc_ping_timeout)}:{},...t.transport_grpc_permit_without_stream==="1"?{permit_without_stream:!0}:{}};break;case"http":l.network="xhttp",l.xhttpSettings={...t.transport_http_host?{host:t.transport_http_host}:{},path:t.transport_http_path||"/",mode:"stream-one",...t.transport_http_method?{uplinkHTTPMethod:t.transport_http_method}:{}};break;case"httpupgrade":l.network="httpupgrade",l.httpupgradeSettings={host:t.transport_httpupgrade_host||void 0,path:t.transport_httpupgrade_path||"/"};break}return r.streamSettings=l,r}};I.register(kr);var Q=class{loglevel;dnsLog;constructor(t){this.loglevel=t||"info",this.dnsLog=!1}},Dt=class{tag;address;port;queryStrategy;domains;skipFallback;disableCache;constructor(t,r,n,s){switch(t){case"tcp":this.address="tcp://"+n,this.port=s;break;case"https":this.address="https://"+n,s&&(this.address+=":"+s),this.address+="/dns-query";break;case"quic":this.address="quic://"+n,this.port=s;break;case"udp":this.address=n,this.port=s;break;default:throw new Error("Invalid xray DNS server type: "+t)}this.tag=r,this.domains=[],this.skipFallback=!0}},Lt=class{servers;rules;queryStrategy;disableCache;serveStale;serveExpiredTTL;disableFallback;disableFallbackIfMatch;constructor(t,r){this.servers=[],this.rules=[],this.queryStrategy=t||"UseIP",this.disableCache=!r,this.serveStale=!r,this.serveExpiredTTL=3600,this.disableFallback=!1,this.disableFallbackIfMatch=!0}},$=class{ruleTag;inboundTag;outboundTag;balancerTag;constructor(t,r,n){this.ruleTag=t,this.inboundTag=r,n==="slb"?this.balancerTag=n:this.outboundTag=n}},kt=class extends ${domain;network;ip;protocol;port;constructor(t,r){super(t,void 0,r),this.inboundTag=["tproxy-in"],this.domain=[],this.network=[],this.ip=[],this.protocol=[]}},ot=class extends ${constructor(t,r){super(void 0,t,r)}},it=class{rules;domainStrategy;balancers;constructor(){this.rules=[],this.domainStrategy="AsIs",this.balancers=[]}},It=class{settings;protocol;tag;streamSettings;constructor(t){this.protocol="blackhole",this.tag=t}},J=class{settings;protocol;tag;constructor(t,r,n){this.protocol="socks",this.tag=n,this.settings={address:t,port:r}}},Mt=class{settings;protocol;tag;constructor(t){this.protocol="dns",this.tag=t,this.settings={rules:[{action:"hijack",qType:"1,28"},{action:"return",rCode:5}]}}},at=class{settings;protocol;tag;constructor(t){this.protocol="freedom",this.tag=t,this.settings={domainStrategy:"UseIP"}}},Ft=class{tag;selector;fallbackTag;strategy;constructor(t){this.tag=t,this.selector=[],this.fallbackTag=void 0,this.strategy={type:"leastLoad",settings:{expected:1,maxRTT:"1s",tolerance:.05}}}},Bt=class{subjectSelector;pingConfig;constructor(t,r,n,s,o,i){this.subjectSelector=[],this.pingConfig={destination:t||"https://connectivitycheck.gstatic.com/generate_204",connectivity:r||void 0,interval:n||"60s",timeout:s||"2s",sampling:o||3,httpMethod:i||void 0}}},B=class{protocol;tag;listen;port;settings;streamSettings;sniffing;constructor(t,r,n,s){this.protocol="dokodemo-door",this.tag=n,this.listen=s,this.port=r,this.settings={network:"tcp,udp",followRedirect:void 0},t==="tproxy"&&(this.settings.followRedirect=!0,this.streamSettings={sockopt:{tproxy:"tproxy"}},this.sniffing={enabled:!0,destOverride:["http","tls","quic"],routeOnly:!0})}};var fe={genShuntConf:Mr,genProxyConf:Fr};function Mr(){let e=T.getShuntSection(),t=new Map,r=new it,n=e.dns,s=new Lt(He(n.defaultStrategy),n.useCache==="1");n.nodes.forEach(function(c){let g=new Dt(c.type,c.tag,c.server,Number(c.port));t.set(c.tag,g)});let o=e.route,i=[];a.sections("hijpass","proxy_node",function(c){if(c.enabled==="1"){let g=new J("127.0.0.1",Number(c.socks_port),Yt(c.name));c.name===o.defaultProxyNode?i.unshift(g):i.push(g)}}),o.defaultProxyNode==="hijpass-direct"?i.unshift(new at("direct-out")):i.push(new at("direct-out")),i.push(new It("block")),i.push(new Mt("dns-out"));let l=[new B("tproxy",parseInt(e.shuntListenPort,10),"tproxy-in"),new B("direct",parseInt(e.dnsListenPort,10),"dns-in","::")],u=[new ot(["dns-in"],"dns-out")],p=[],f=t.get(n.defaultDnsNode);if(!f)throw new Error(_('Default global DNS "%s" does not exist').format(n.defaultDnsNode||""));let y=new Map;o.rules.forEach(function(c){if(c.enabled!=="1")return;let g=c.ipVersionSplit==="1",w,H=!1;if(T.getRouteRuleVariants(c).forEach(function(U){let Vt=Yt(U.proxyNode)||i[0].tag,G=T.parseRuleList(U.rule),Se=jr(G);if(G.ipVersion=U.ipVersion,!Xr(G)&&(Vr(U.rule.name,Vt,G).forEach(Wt=>{p.push(Wt)}),Vt!=="block")){if(g){Se&&(w=w||G,H=!0);return}if(Se){let Wt=Yt(c.dnsProxyNode)||Vt;Me(c,U.rule.name,Wt,G,t,f,s,y)}}}),g&&H&&w){let U=Yt(c.dnsProxyNode);if(!U)throw new Error(_('Route rule "%s" uses IPv4/IPv6 split and must specify a DNS exit node').format(c.name));Me(c,c.name,U,w,t,f,s,y)}});let b=structuredClone(f);return b.tag=Be("default"),b.skipFallback=!1,s.servers.push(b),y.forEach((c,g)=>u.push(new ot(c,g))),r.rules=r.rules.concat(u),r.rules=r.rules.concat(p),{log:new Q(he(e.logLevel)),inbounds:l,outbounds:i,dns:s,routing:r}}function Fr(e){if(e.type===d.LOAD_BALANCE)return Yr(e);let t=I.build(e.type,e);return Br(e,t)}function Br(e,t){let r=Fe(e),n=[t];return Hr(e,t,n),{log:new Q(he(e.log_level)),inbounds:r,outbounds:n}}function Fe(e){let t=new B("tproxy",Number(e.listen_port),"tproxy-in");t.sniffing=void 0;let r=new B("direct",Number(e.socks_port),"socks-in");return r.settings={udp:!0},r.protocol="socks",[t,r]}function Yr(e){let t=N.resolveLoadBalanceMembers(e),r=new it;r.rules.push(new $(void 0,["tproxy-in","socks-in"],"slb"));let n=new Ft("slb");n.selector=[Ut];let s=t.find(u=>u.name===e.fallback_tag)||t[0];n.fallbackTag=s.tag;let o=e.strategy||"leastLoad";n.strategy.type=o,o==="leastLoad"?(e.strategy_expected&&(n.strategy.settings.expected=parseInt(e.strategy_expected,10)),e.strategy_max_rtt&&(n.strategy.settings.maxRTT=e.strategy_max_rtt),e.strategy_tolerance&&(n.strategy.settings.tolerance=parseFloat(e.strategy_tolerance))):n.strategy.settings=void 0,r.balancers.push(n);let i=new Bt(e.probe_url||void 0,e.probe_connectivity||void 0,e.probe_interval||void 0,e.probe_timeout||void 0,e.probe_sampling?parseInt(e.probe_sampling,10):void 0,e.probe_http_method||void 0);i.subjectSelector=[Ut];let l=t.map(u=>new J("127.0.0.1",u.socksPort,u.tag));return{log:new Q(he(e.log_level)),inbounds:Fe(e),outbounds:l,routing:r,burstObservatory:i}}function he(e){return e==="warn"?"warning":e}function Hr(e,t,r){let n=N.resolveUpstreamProxy(e);n&&(Gr(t,n.tag),r.push(new J("127.0.0.1",n.socksPort,n.tag)))}function Gr(e,t){e.streamSettings=e.streamSettings||{},e.streamSettings.sockopt=e.streamSettings.sockopt||{},e.streamSettings.sockopt.dialerProxy=t,e.streamSettings.sockopt.domainStrategy="UseIP"}function Be(e){return e+"-dns"}function Xr(e){return e.isEmpty("geo")?!0:e.containRuleSet()&&!e.containDomain()&&!e.containIp()&&!e.containGeo()}function jr(e){return e.containDomain()||e.geoSite.length>0}function Me(e,t,r,n,s,o,i,l){let u=Be(t);l.has(r)?l.get(r).push(u):l.set(r,[u]);let p=e.dnsNode?s.get(e.dnsNode):o;if(!p)throw new Error(_('Route rule "%s" DNS node "%s" does not exist').format(e.name||t,e.dnsNode||""));let f=structuredClone(p);f.tag=u,f.queryStrategy=He(e.dnsStrategy),f.domains=Ye(n),i.servers.push(f)}function Vr(e,t,r){let n=new kt(e,t);n.network=r.network,n.protocol=zr(r.protocol);let s=r.port.map(l=>String(l));r.portRange&&r.portRange.length>0&&(s=s.concat(r.portRange)),n.port=s.join(","),n.domain=Ye(r),n.domain=n.domain.length>0?n.domain:void 0,n.ip=Wr(r),n.ip=n.ip.length>0?n.ip:void 0;let o=[],i=Kr(r.ipVersion);if(n.domain){let l=structuredClone(n);i?l.ip=[i]:l.ip=void 0,o.push(l)}if(n.ip){let l=structuredClone(n);l.domain=void 0,o.push(l)}return!n.domain&&!n.ip&&(i&&(n.ip=[i]),o.push(n)),o}function Ye(e){let t=[me(e.domain,"full:"),me(e.domainSuffix,"domain:"),e.domainKeyword,me(e.domainRegex,"regexp:"),e.geoSite];return[].concat(...t.filter(r=>Array.isArray(r)&&r.length>0))}function Wr(e){let t=[qr(e.ipCidr,e.ipVersion),e.geoIp];return[].concat(...t.filter(r=>Array.isArray(r)&&r.length>0))}function qr(e,t){return!t||!Array.isArray(e)?e||[]:e.filter(r=>{let n=r.replace(/^!/,"");return n.startsWith("geoip:")||n.startsWith("ext:")?!0:n.indexOf(":")>=0?t===6:/^\d{1,3}(\.\d{1,3}){3}(\/\d+)?$/.test(n)?t===4:!0})}function Kr(e){if(e===4)return"0.0.0.0/0";if(e===6)return"::/0"}function Yt(e){return e==="hijpass-block"?"block":e==="hijpass-direct"?"direct-out":e}function He(e){switch(e){case"4":return"UseIPv4";case"6":return"UseIPv6";case"64":case"46":return"UseIP";default:return}}function zr(e){if(!e)return;let t=e.map(r=>{switch(r){case"http":case"tls":case"quic":case"bittorrent":return r;default:throw new Error("Unsupported xray rule protocol: "+r)}}).filter(r=>r!==void 0);return t.length===0?void 0:t}function me(e,t){return Array.isArray(e)?e.map(r=>t+r):[]}var v=m,Ge={getCoreAdapter:function(e){switch(k(e)){case v.SING_BOX:return st;case v.XRAY:return fe;default:throw new Error("Unsupported core: "+e)}}},ye={genProxyConf:function(e,t){switch(k(e)){case v.SING_BOX:return st.genProxyConf(t);case v.XRAY:return fe.genProxyConf(t);default:throw new Error("Unsupported core: "+e)}}};var Qr={hijpass:{client_dir:"/etc/hijpass/client",shunt_conf:"/etc/hijpass/shunt.json",ip_direct:"/etc/hijpass/rules/ip-direct.txt",ip_proxy:"/etc/hijpass/rules/ip-proxy.txt",domain_direct:"/etc/hijpass/rules/domain-direct.txt",domain_proxy:"/etc/hijpass/rules/domain-proxy.txt",nft:"/etc/hijpass/fw4-template.nft",nft_hook:"/etc/hijpass/hook/nft-hook.sh",dns_hook:"/etc/hijpass/hook/dns-hook.sh"},hijserver:{server_dir:"/etc/hijpass/server"}};function $r(e){let t=(e||"").trim().replace(/\r\n/g,`
`);return t?t+`
`:""}function be(e,t="hijpass"){let r=a.get_first(t,t,e);if(r)return r;let n=Qr[t]?.[e];return n||(console.log(e+" path is empty"),"")}function Jr(e,t,r,n){if(!t)throw new Error(_("Configuration file directory is empty"));let o=n?.section?.formvalue?.(r,"name")||a.get(e,r,"name")||r;return t+"/"+o+"-"+r+".json"}function Zr(e){let t=e.name||e[".name"];return be("client_dir")+"/"+t+"-"+e[".name"]+".json"}function tn(e){let t=e.name||e[".name"];return be("server_dir","hijserver")+"/"+t+"-"+e[".name"]+".json"}var P={normalizeFileContent:$r,getFilePath:be,getNodeConfigFilePath:Jr,getProxyConfigFilePath:Zr,getServerConfigFilePath:tn};async function en(e){async function t(r,n,s){let o=s?[r,n,s]:[r,n];await h.exec("/usr/lib/hijpass/rm.sh",o)}if(e?.hijpass){for(let r of e.hijpass)if(r.length===2&&r[0]==="remove"&&await t("proxy",r[1]),r.length===4&&r[0]==="set"&&r[2]==="name"){let n=a.get("hijpass",r[1]),s=n?P.getProxyConfigFilePath(n):void 0;await t("proxy",r[1],s)}}if(e?.hijserver){for(let r of e.hijserver)if(r.length===2&&r[0]==="remove"&&await t("server",r[1]),r.length===4&&r[0]==="set"&&r[2]==="name"){let n=a.get("hijserver",r[1]),s=n?P.getServerConfigFilePath(n):void 0;await t("server",r[1],s)}}}var Xe={cleanupChangedNodeFiles:en};function rn(e,t){if(!(Array.isArray(t)&&t.length===0)&&t!==null&&!(typeof t=="number"&&!Number.isFinite(t))&&!(typeof t=="string"&&!t.trim()))return t}var Ht={omitEmptyReplacer:rn};var je={getShuntConfData:function(){if(a.get_first("hijpass","shunt","enabled")==="0"||a.get_first("hijpass","shunt","config_type")!=="tmpl")return"";let r=a.get_first("hijpass","shunt","type");return JSON.stringify(Ge.getCoreAdapter(r).genShuntConf(),Ht.omitEmptyReplacer,2)}};var xe=class{container=null;notifications=new Map;notificationId=0;autoCloseTimers=new Map;constructor(){this.initContainer()}initContainer(){this.container||(this.container=document.createElement("div"),this.container.id="notification-container",this.container.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
pointer-events: none;
`,document.body.appendChild(this.container))}getTypeConfig(t){let r={success:{bgColor:"#4caf50",borderColor:"#45a049",icon:"\u2713",textColor:"#fff"},error:{bgColor:"#f44336",borderColor:"#da190b",icon:"\u2715",textColor:"#fff"},warning:{bgColor:"#ff9800",borderColor:"#e68900",icon:"\u26A0",textColor:"#fff"},info:{bgColor:"#2196f3",borderColor:"#0b7dda",icon:"\u2139",textColor:"#fff"}};return r[t]||r.info}show(t){let{message:r,title:n,content:s,type:o="info",duration:i=3e3,icon:l=!1}=t;this.initContainer();let u=`notification-${++this.notificationId}`,p=this.getTypeConfig(o),f=n||r,y=s,b=document.createElement("div");if(b.id=u,b.style.cssText=`
background-color: ${p.bgColor};
border-left: 4px solid ${p.borderColor};
color: ${p.textColor};
padding: 16px 20px;
margin-bottom: 10px;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
display: flex;
align-items: flex-start;
gap: 12px;
min-width: 300px;
max-width: 400px;
word-break: break-word;
animation: slideInRight 0.3s ease-out;
pointer-events: auto;
transition: all 0.3s ease;
font-size: 14px;
font-weight: 500;
`,l){let g=document.createElement("span");g.style.cssText=`
font-size: 20px;
font-weight: bold;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
margin-top: 2px;
`,g.textContent=p.icon,b.appendChild(g)}let S=document.createElement("div");if(S.style.cssText=`
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
`,f){let g=document.createElement("div");g.style.cssText=`
font-weight: 600;
font-size: 14px;
line-height: 1.4;
`,g.textContent=f,S.appendChild(g)}if(y){let g=document.createElement("div");g.style.cssText=`
font-weight: 400;
font-size: 13px;
line-height: 1.4;
opacity: 0.9;
white-space: pre-line;
`,g.textContent=y,S.appendChild(g)}b.appendChild(S);let c=document.createElement("button");if(c.style.cssText=`
background: none;
border: none;
color: ${p.textColor};
cursor: pointer;
font-size: 20px;
padding: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
opacity: 0.7;
transition: opacity 0.2s;
`,c.innerHTML="\xD7",c.onmouseover=()=>c.style.opacity="1",c.onmouseout=()=>c.style.opacity="0.7",c.onclick=g=>{g.stopPropagation(),this.remove(u)},b.appendChild(c),this.container.appendChild(b),this.notifications.set(u,b),i>0){let g=setTimeout(()=>{this.remove(u)},i);this.autoCloseTimers.set(u,g),b.onmouseenter=()=>{let w=this.autoCloseTimers.get(u);w&&(clearTimeout(w),this.autoCloseTimers.delete(u))},b.onmouseleave=()=>{if(this.notifications.has(u)){let w=setTimeout(()=>{this.remove(u)},i);this.autoCloseTimers.set(u,w)}}}return u}remove(t){let r=this.notifications.get(t);if(!r)return;let n=this.autoCloseTimers.get(t);n&&(clearTimeout(n),this.autoCloseTimers.delete(t)),r.style.animation="slideOutRight 0.3s ease-in",r.style.opacity="0",setTimeout(()=>{r.remove(),this.notifications.delete(t)},300)}success(t,r){return this.show({message:t,type:"success",duration:r})}error(t,r){return this.show({message:t,type:"error",duration:r})}warning(t,r){return this.show({message:t,type:"warning",duration:r})}info(t,r){return this.show({message:t,type:"info",duration:r})}clear(){this.notifications.forEach((t,r)=>{this.remove(r)})}},nn=new xe;function Ve(){if(document.getElementById("notification-styles"))return;let e=document.createElement("style");e.id="notification-styles",e.textContent=`
@keyframes slideInRight {
from {
transform: translateX(400px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOutRight {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(400px);
opacity: 0;
}
}
@media (max-width: 768px) {
#notification-container {
left: 10px !important;
right: 10px !important;
top: 10px !important;
}
#notification-container > div {
min-width: auto !important;
max-width: 100% !important;
}
}
`,document.head.appendChild(e)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Ve):Ve();var Y=nn;var D={show:function(e){return Y.show(e)},success:function(e,t,r){return Y.show({title:e,content:t,type:"success",duration:r})},error:function(e,t,r){return Y.show({title:e,content:t,type:"error",duration:r})},warning:function(e,t,r){return Y.show({title:e,content:t,type:"warning",duration:r})},info:function(e,t,r){return Y.show({title:e,content:t,type:"info",duration:r})},clear:function(){return Y.clear()}};var Te={createProxyConfigFromSection:function(e){let t=e.type,r;switch(t){case d.LOAD_BALANCE:r=new St;break;case d.HYSTERIA2:r=new wt;break;case d.SHADOWSOCKS:r=new Ot;break;case d.TUIC:r=new Ct;break;case d.SHADOWTLS:r=new Pt;break;case d.VLESS:r=new Rt;break;case d.CUSTOM:r=new Et;break;default:return null}return Object.keys(e).forEach(n=>{n!==".type"&&n!==".name"&&n!==".anonymous"&&Reflect.set(r,n,e[n])}),r.cfgid=e[".name"],r}};function sn(e){return/^(\d{1,3}\.){3}\d{1,3}$/.test(e)||/^[0-9a-fA-F:]+$/.test(e)}function on(e){return Array.isArray(e?.outbounds)?e.outbounds[0]:void 0}function an(e,t){let r=on(e);return r?r.server?(r.server=t,!0):r.settings?.address?(r.settings.address=t,!0):r.settings?.servers?.[0]?.address?(r.settings.servers[0].address=t,!0):r.settings?.vnext?.[0]?.address?(r.settings.vnext[0].address=t,!0):!1:!1}async function ln(e,t){if(!e.upstream_proxy_node||!e.server||sn(e.server))return;let r=await h.exec_direct("/usr/lib/hijpass/net.sh",["resolve",e.server],"json");if(!r?.address)throw new Error(_("Resolve proxy server failed: %s").format(e.server));if(!an(t,r.address))throw new Error(_("Unsupported proxy config server field: %s").format(e.name||e.server))}async function un(){let e=[];if(a.sections("hijpass","proxy_node",r=>{let n=Te.createProxyConfigFromSection(r);if(r.enabled!=="1"||!n||n.type===d.CUSTOM||n.core===v.CUSTOM)return;let s=ye.genProxyConf(n.core,n);e.push(ln(n,s).then(()=>{let o=typeof s=="string"?s:JSON.stringify(s,Ht.omitEmptyReplacer,2);return h.write(P.getProxyConfigFilePath(r),o)}))}),e.length===0)return;(await Promise.allSettled(e)).forEach(r=>{if(r.status==="rejected")throw new Error(r.reason?.message||String(r.reason))})}function pn(e){let t=Te.createProxyConfigFromSection(e);if(t)return ye.genProxyConf(t.core,t)}var We={writeGeneratedProxyConfigs:un,generateProxyConfigFromSection:pn};var Z={setAnonymousGridSectionMembers:function(e){Z.setGridSectionMembers(e),e.anonymous=!0,e.sectiontitle=function(t){return a.get("hijpass",t,"name")||a.get("hijpass",t,"tag")||t}},setGridSectionMembers:function(e){e.anonymous=!1,e.addremove=!0,e.sortable=!0,e.nodescriptions=!0,e.rowcolors=!0},setAnonymousSection:function(e){e.anonymous=!0,e.addremove=!1},simpleHash:function(e){let t=0;e=e||"";for(let r=0;r<e.length;r++)t=(t<<5)-t+e.charCodeAt(r),t|=0;return t},setEditorOptionMembers:function(e,t,r){e.rows=30,e.load=function(s){return h.trimmed(t)};async function n(s,o){let i=String(Z.simpleHash(o)),l=a.get("hijpass",s,r);i!==l&&(a.set("hijpass",s,r,i),await h.write(t,(o||"").trim().replace(/\r\n/g,`
`)+`
`))}return e.write=n,e.remove=n,e.monospace=!0,e},setConfContentOptionMembers:function(e,t,r){e.monospace=!0,e.rows=20,e.load=async function(n){return L.resolveDefault(h.read(P.getNodeConfigFilePath(t,r,n)),"")},e.write=async function(n,s){let o=P.normalizeFileContent(s);await h.write(P.getNodeConfigFilePath(t,r,n,this),o),a.set(t,n,"custom_conf_hash",String(Z.simpleHash(o)))},e.remove=async function(n){await h.write(P.getNodeConfigFilePath(t,r,n,this),""),a.set(t,n,"custom_conf_hash","")}},createTextOption:function(e,t,r,n,s,o){let i=e.taboption(t,x.TextValue,r,n,s);return Z.setEditorOptionMembers(i,o,r),i},createLogFlagOption:function(e,t,r){let n=a.get_first(t,t,"log_dir"),s=r?e.taboption(r,x.Flag,"log_enabled",_("Record Logs")):e.option(x.Flag,"log_enabled",_("Record Logs"));return s.modalonly=!0,s.write=function(o,i){let l="shunt.log",u=a.get(t,o,"name");u&&(l=u+"-"+o+".log"),a.set(t,o,"log_path",n+"/"+l)},s.remove=function(o){a.unset(t,o,"log_path")},s.load=function(o){return a.get(t,o,"log_path")?"1":"0"},s.rmempty=!0,s},appendEnabledNodeListenPorts:function(e){a.sections("hijpass","proxy_node",t=>{if(t.listen_port&&t.enabled==="1"){let r=_("Proxy node %s: %s").format(t.name,t.listen_port);e.value(t.listen_port,r)}})},loadProxyNodeOptions:function(e,t=!0){e.load=function(r){return delete this.keylist,delete this.vallist,this.value("hijpass-direct",_("Direct")),t&&this.value("hijpass-block",_("Block")),a.sections("hijpass","proxy_node",function(n){if(n.name&&n.enabled==="1"){let s=n.name;n.socks_port&&(s+=" ("+n.socks_port+")"),this.value(n.name,s)}}.bind(this)),x.ListValue.prototype.load.apply(this,[r])}},getEnabledProxyNodeOptions:function(e=!0){let t=[];return e&&(t.push({value:"hijpass-direct",label:_("Direct")}),t.push({value:"hijpass-block",label:_("Block")})),a.sections("hijpass","proxy_node",r=>{if(r.name&&r.enabled==="1"){let n=r.name;r.socks_port&&(n+=" ("+r.socks_port+")"),t.push({value:r.name,label:n})}}),t}};function ze(e){let t=Number(e);return Number.isInteger(t)&&t>0&&t<=65535}function qe(){let e=a.get_first("hijpass","dns"),t=e?.cdg_port||"";return{available:e?.dns_service==="chinadns-ng"&&ze(t),port:t}}function Ke(){let e=a.get_first("hijpass","shunt"),t=e?.dns_listen_port||"";return{available:e?.enabled!=="0"&&ze(t),port:t}}function cn(e,t){let r=e;return t.port&&(r+=": "+t.port),t.available||(r+=" - "+_("Not available")),r}var Gt={getSource:function(){return a.get_first("hijpass","firewall","dns_forward")||tt.NONE},getPreRoutingTarget:qe,getRoutingTarget:Ke,getTargetLabel:cn,validateSource:function(e){return!e||e===tt.NONE?!0:e===tt.PRE_ROUTING?qe().available?!0:_("Independent DNS is unavailable or has no valid listen port"):e===tt.ROUTING?Ke().available?!0:_("Core DNS is disabled or has no valid listen port"):_("Unknown DNS forwarding source: %s").format(e)}};var Qe=["http","tls","quic","bittorrent"],dn=["hysteria2","vless"];function gn(e){return e?Array.isArray(e)?e.filter(t=>t):[e]:[]}function _n(e){return e==="hijpass-direct"||e==="hijpass-block"}function R(e,t){return t.length===0?!0:(D.warning(e,t.join(`
`),8e3),!1)}function mn(){return a.get_first("hijpass","shunt","enabled")!=="0"&&a.get_first("hijpass","shunt","config_type")==="tmpl"}function fn(){let e=new Set;a.sections("hijpass","proxy_node",function(o){o.name&&e.add(o.name)});let t=[];function r(o,i){o&&!_n(o)&&!e.has(o)&&t.push(i)}let n=a.get_first("hijpass","shunt","default_proxy_node");n?r(n,_('Default global exit "%s" does not exist').format(n)):t.push(_("Default global exit is not configured"));let s=a.get_first("hijpass","shunt","ruleset_out_node");return r(s,_('Rule-set exit "%s" does not exist').format(s)),a.sections("hijpass","shunt_route_rule",function(o){if(o.enabled!=="1")return;let i=o.name||o[".name"];if(o.ip_version_split==="1"){o.proxy_node_v4?r(o.proxy_node_v4,_('Route rule "%s" IPv4 proxy node "%s" does not exist').format(i,o.proxy_node_v4)):t.push(_('Route rule "%s" IPv4 proxy node is not configured').format(i)),o.proxy_node_v6?r(o.proxy_node_v6,_('Route rule "%s" IPv6 proxy node "%s" does not exist').format(i,o.proxy_node_v6)):t.push(_('Route rule "%s" IPv6 proxy node is not configured').format(i));return}o.proxy_node?r(o.proxy_node,_('Route rule "%s" proxy node "%s" does not exist').format(i,o.proxy_node)):t.push(_('Route rule "%s" proxy node is not configured').format(i))}),R(_("Configuration contains missing proxy nodes"),t)}function hn(){let e=new Set;if(a.sections("hijpass","proxy_node",function(s){s.enabled!=="1"&&s.name&&e.add(s.name)}),e.size===0)return!0;let t=[],r=a.get_first("hijpass","shunt","default_proxy_node");r&&e.has(r)&&t.push(_('Default global exit "%s" is not enabled').format(r));let n=a.get_first("hijpass","shunt","ruleset_out_node");return n&&e.has(n)&&t.push(_('Rule-set exit "%s" is not enabled').format(n)),a.sections("hijpass","shunt_route_rule",function(s){if(s.enabled!=="1")return;let o=s.name||s[".name"];s.ip_version_split==="1"?(s.proxy_node_v4&&e.has(s.proxy_node_v4)&&t.push(_('Route rule "%s" IPv4 proxy node "%s" is not enabled').format(o,s.proxy_node_v4)),s.proxy_node_v6&&e.has(s.proxy_node_v6)&&t.push(_('Route rule "%s" IPv6 proxy node "%s" is not enabled').format(o,s.proxy_node_v6))):s.proxy_node&&e.has(s.proxy_node)&&t.push(_('Route rule "%s" proxy node "%s" is not enabled').format(o,s.proxy_node)),s.dns_proxy_node&&e.has(s.dns_proxy_node)&&t.push(_('Route rule "%s" DNS exit node "%s" is not enabled').format(o,s.dns_proxy_node))}),R(_("Configuration contains disabled nodes"),t)}function yn(){let e=N.getProxySectionMap(),t=[];return e.forEach(r=>{if(r.enabled!=="1"||r.type!==d.LOAD_BALANCE)return;let n=N.getProxyName(r),s=k(r.core);s!==m.SING_BOX&&s!==m.XRAY&&t.push(_('Load balancing node "%s" has an unsupported backend core').format(n));let o=N.normalizeProxyNodeList(r.member_node);if(o.length===0){t.push(_('Load balancing node "%s" has no member nodes').format(n));return}let i=o.filter((l,u)=>o.indexOf(l)!==u);i.length>0&&t.push(_('Load balancing node "%s" contains duplicate member nodes: %s').format(n,Array.from(new Set(i)).join(", "))),o.forEach(l=>{if(l===n){t.push(_('Load balancing node "%s" cannot include itself').format(n));return}let u=e.get(l);if(!u){t.push(_('Load balancing node "%s" member node "%s" does not exist').format(n,l));return}u.type===d.LOAD_BALANCE&&t.push(_('Load balancing node "%s" cannot contain load balancing member "%s"').format(n,l)),u.enabled!=="1"&&t.push(_('Load balancing node "%s" member node "%s" is not enabled').format(n,l)),N.isPort(u.socks_port)||t.push(_('Load balancing node "%s" member node "%s" has no valid SOCKS port configured').format(n,l))}),r.fallback_tag&&o.indexOf(r.fallback_tag)<0&&t.push(_('Load balancing node "%s" fallback node "%s" is not a member').format(n,r.fallback_tag))}),R(_("Configuration contains invalid load balancing nodes"),t)}function bn(){let e=N.getProxySectionMap(),t=[];e.forEach(n=>{if(n.enabled!=="1"||n.type===d.LOAD_BALANCE||!n.upstream_proxy_node)return;let s=N.getProxyName(n),o=n.upstream_proxy_node,i=e.get(o);if(!i){t.push(_('Proxy node "%s" upstream proxy node "%s" does not exist').format(s,o));return}i.enabled!=="1"&&t.push(_('Proxy node "%s" upstream proxy node "%s" is not enabled').format(s,o)),N.isPort(i.socks_port)||t.push(_('Proxy node "%s" upstream proxy node "%s" has no valid SOCKS port configured').format(s,o));let l=N.collectProxyChain(s,e);!l.cycle&&l.chain.length>se&&t.push(_('Proxy node "%s" nesting chain exceeds %d nodes: %s').format(s,se,l.chain.join(" -> ")))});let r=N.findProxyDependencyCycle(e);return r&&t.push(_("Proxy node dependency chain has a cycle: %s").format(r.join(" -> "))),R(_("Configuration contains invalid upstream proxy nodes"),t)}function xn(){let e=new Set,t=new Set;a.sections("hijpass","shunt_dns_node",function(i){i.tag&&(e.add(i.tag),i.enabled==="0"&&t.add(i.tag))});let r=[],n=[];function s(i,l){if(i){if(!e.has(i)){r.push(_('%s "%s" does not exist').format(l,i));return}t.has(i)&&n.push(_('%s "%s" is not enabled').format(l,i))}}let o=a.get_first("hijpass","shunt","default_dns_node");return o?s(o,_("Default global DNS")):r.push(_("Default global DNS is not configured")),s(a.get_first("hijpass","shunt","ruleset_dns_node"),_("Rule-set DNS")),a.sections("hijpass","shunt_route_rule",function(i){i.enabled==="1"&&s(i.dns_node,_('Route rule "%s" DNS node').format(i.name||i[".name"]))}),R(_("Configuration contains missing DNS nodes"),r)&&R(_("Configuration contains disabled DNS nodes"),n)}function Tn(){let e=new Set;a.sections("hijpass","proxy_node",function(s){s.name&&e.add(s.name)});let t=a.get_first("hijpass","shunt","type"),r=a.get_first("hijpass","shunt","ruleset_convert"),n=[];return T.getRouteSection().rules.forEach(function(s){if(s.enabled!=="1")return;let o=s.dnsProxyNode,i=s.name||_("Unnamed Rule");if(Nn(s,t,r)&&!o){n.push(_('Route rule "%s" uses IPv4/IPv6 split and must specify a DNS exit node').format(i));return}o&&o!=="hijpass-direct"&&!e.has(o)&&n.push(_('Route rule "%s" DNS exit node "%s" does not exist').format(i,o))}),R(_("Configuration contains invalid DNS exit nodes"),n)}function Nn(e,t,r){if(e.ipVersionSplit!=="1")return!1;let n=T.parseRuleList(e);return t===v.XRAY?n.containDomain()||n.geoSite.length>0:n.containDomain()||n.containRuleSet()||r==="1"&&n.geoSite.length>0}function vn(){let e=new Set;a.sections("hijpass","proxy_node",function(i){i.enabled==="1"&&i.listen_port&&e.add(i.listen_port)});let t=a.get_first("hijpass","firewall","proxy_port"),r=a.get_first("hijpass","firewall","shunt_port"),n=a.get_first("hijpass","shunt","enabled")!=="0",s=a.get_first("hijpass","shunt","shunt_listen_port"),o=[];return t&&!e.has(t)&&o.push(_("Firewall proxy port %s does not reference an enabled proxy node").format(t)),r&&!e.has(r)&&!(n&&s===r)&&o.push(_("Firewall shunt port %s does not reference an enabled proxy node or shunt service").format(r)),R(_("Configuration conflict"),o)}function Sn(){let e=Gt.validateSource(Gt.getSource());return e===!0||R(_("Configuration conflict"),[e])}function En(){if(a.get_first("hijpass","dns","dns_service")!=="chinadns-ng")return!0;let t=Gt.getRoutingTarget(),r=t.port?"127.0.0.1#"+t.port:"",n=[];return[["direct_dns",_("Direct Domain DNS")],["proxy_dns",_("Proxy Domain DNS")]].forEach(([s,o])=>{let i=a.get_first("hijpass","dns",s);!i||i==="dnsmasq"||i==="system"||i==="custom"||(!t.available||i!==r)&&n.push(_("%s references an unavailable Core DNS port").format(o))}),R(_("Configuration conflict"),n)}function wn(){if(a.get_first("hijpass","shunt","type")!==v.XRAY)return!0;let t=[];return a.sections("hijpass","shunt_route_rule",function(r){if(r.enabled!=="1")return;let n=gn(r.protocol).filter(s=>Qe.indexOf(s)===-1);n.length>0&&t.push(_('Route rule "%s" contains protocols unsupported by Xray: %s').format(r.name||r[".name"],n.join(", ")))}),t.length>0?(D.warning(_("Unsupported Xray protocol configuration"),t.join(`
`)+`
`+_("Xray route protocol only supports: %s").format(Qe.join(", ")),8e3),!1):!0}function On(){if(a.get_first("hijpass","shunt","type")!==v.XRAY)return!0;let t=[];return a.sections("hijpass","shunt_dns_node",function(r){r.enabled!=="0"&&r.type==="tls"&&t.push(_('DNS node "%s" uses TLS, which is only supported by sing-box').format(r.tag||r[".name"]))}),R(_("Unsupported Xray DNS configuration"),t)}function Cn(){let e=[];return a.sections("hijpass","proxy_node",function(t){t.enabled!=="1"||k(t.core)!==v.XRAY||t.tls_insecure!=="1"||dn.indexOf(t.type)!==-1&&e.push(_('Proxy node "%s" enables insecure TLS, which is not supported by current Xray').format(t.name||t[".name"]))}),R(_("Unsupported Xray TLS configuration"),e)}function Pn(e,t,r){return new Promise(n=>{M.showModal(e,[E("div",{style:["box-sizing:border-box","width:100%","margin:0 0 14px 0","padding:14px 16px","border-radius:4px","background:rgba(127,127,127,0.08)","line-height:1.55"].join(";")},[E("div",{style:"margin:0 0 12px 0"},t),E("div",{style:"display:flex;flex-direction:column;gap:6px;margin:0"},r.map(s=>E("div",{style:"margin:0;word-break:break-word"},s)))]),E("div",{style:"display:flex;justify-content:flex-end;gap:10px;margin:0"},[E("button",{class:"btn cbi-button",click:function(s){s.preventDefault(),M.hideModal(),n(!1)}},_("Cancel")),E("button",{class:"btn cbi-button-action",click:function(s){s.preventDefault(),M.hideModal(),n(!0)}},_("Continue Apply"))])])})}function Rn(e,t,r){let n=T.parseRuleList(e),s=e.name||e[".name"]||_("Unnamed Rule"),o=r==="1";if(t===v.XRAY)return n.isEmpty("geo")?_('Route rule "%s" has no valid match conditions for Xray').format(s):n.containRuleSet()&&!n.containDomain()&&!n.containIp()&&!n.containGeo()?_('Route rule "%s" only contains rule-set target conditions unsupported by Xray').format(s):null;if(t===v.SING_BOX){if(!o&&n.containGeo()&&(n.geoSite=[],n.geoIp=[],!n.containDomain()&&!n.containIp()&&!n.containRuleSet()))return _('Route rule "%s" has no target conditions for sing-box after removing unconverted geosite/geoip').format(s);if(n.isEmpty("set")&&!(o&&n.containGeo()))return _('Route rule "%s" has no valid match conditions for sing-box').format(s)}return null}function Un(){let e=a.get_first("hijpass","shunt","type"),t=a.get_first("hijpass","shunt","ruleset_convert"),r=[];return T.getRouteSection().rules.forEach(n=>{if(n.enabled!=="1")return;let s=Rn(n,e,t);s&&r.push(s)}),r.length>0?Pn(_("Some route rules will be skipped"),_("The following rules have no valid configuration for the current core and options, so they will not be written to the final configuration. Continue applying the configuration?"),r):!0}var $e={runSaveApplyPrechecks:async function(){return!bn()||!yn()||!Cn()||!vn()||!Sn()||!En()?!1:mn()?fn()&&hn()&&xn()&&Tn()&&await Un()&&wn()&&On():!0}};function An(){return a.get_first("hijpass","hijpass","enabled")==="0"}var Je={genHandleSaveApply:function(){return async function(e,t){try{if(await this.handleSave(e),An()){await a.save(),await M.changes.apply(t=="0");return}if(!await $e.runSaveApplyPrechecks())return;if(a.get_first("hijpass","shunt","type")===v.SING_BOX&&a.get_first("hijpass","shunt","ruleset_convert")==="1"&&st.writeGeoRule(),a.get_first("hijpass","shunt","config_type")==="tmpl"){let o=je.getShuntConfData();await h.write(P.getFilePath("shunt_conf"),o),a.set_first("hijpass","shunt","shunt_hash",o?String(Z.simpleHash(o)):"-1")}await a.save();let s=await a.changes();await Xe.cleanupChangedNodeFiles(s),await We.writeGeneratedProxyConfigs(),await M.changes.apply(t=="0")}catch(r){console.log(r),D.error(_("Configuration Apply Failed"),_(r.message),5e3)}}}};function Dn(e,t){t.disabled=!0,Xt(e,_("Updating Rule Files"),"neutral"),h.exec_direct("/usr/lib/hijpass/rules.sh",["update"],"json").then(function(r){r?.success?Xt(e,_("Rule Files Updated"),"success"):Xt(e,_("Rule File Update Failed: %s").format(_("Update failed")),"error")}).catch(function(r){Xt(e,_("Error occurred while updating: %s").format(r.message),"error")}).finally(function(){t.disabled=!1})}function Xt(e,t,r){e.textContent=t,e.style.color=r==="success"?"#4caf50":r==="error"?"#f44336":"#666"}function Ze(e,t,r,n){let s=e.value.trim(),o=t.value;if(!s){r.textContent=_("Enter Query Keyword"),r.style.color="#f44336";return}switch(r.textContent=_("Querying"),r.style.color="#666",o){case"domain":Ln(s,n,r);break;case"geosite":In(s,"geosite",n,r);break;case"shunt":kn(s,n,r);break;default:r.textContent=_("Unknown Query Type"),r.style.color="#f44336"}}function Ln(e,t,r){ve(t),h.exec("/usr/bin/lua",["/usr/lib/hijpass/luci-utils.lua","iptype",e]).then(function(n){let s=n.code===0?"geoip":"geosite";return h.exec("/usr/lib/hijpass/geoview.sh",["-l",s,e]).then(Ne(t,r,"# "+s+`
`))}).catch(jt(r)),h.exec("/usr/lib/hijpass/rules.sh",["query",e]).then(Ne(t,r,_(`# Local Rule Files
`))).catch(jt(r))}function kn(e,t,r){ve(t),h.exec("/usr/lib/hijpass/route-match.sh",[e]).then(Ne(t,r,_(`# Shunt Rules
`))).catch(jt(r))}function In(e,t,r,n){ve(r),h.exec("/usr/lib/hijpass/geoview.sh",["-e",t,e]).then(function(s){if(s.code!==0)throw new Error(s.stderr||_("Query Failed"));let o=s.stdout||"";o.trim()?(r.value&&(r.value+=`
`),r.value+="# "+t+`
`,r.value+=o,n.textContent=_("Query Complete"),n.style.color="#4caf50"):(n.textContent=_("No Matching Results"),n.style.color="#666")}).catch(jt(n))}function ve(e){e.value=""}function Ne(e,t,r){return function(n){if(n.code===0)n.stdout&&(e.value&&(e.value+=`
`),e.value+=r,e.value+=n.stdout),t.textContent=_("Query Complete"),t.style.color="#4caf50";else throw new Error(n.stderr||_("Query Failed"))}}function jt(e){return function(t){console.log(t),e.textContent=_("Query Failed"),e.style.color="#f44336"}}var tr={createUpdateButtons:function(){let e=E("span",{style:"margin-left: 10px; font-size: 12px; color: #666;"}),t=E("button",{class:"cbi-button cbi-button-neutral",style:"margin-right: 10px;",type:"button",click:function(r){r.preventDefault(),Dn(e,t)}},_("Update Rule Files"));return E("div",{class:"cbi-section"},[E("div",{class:"cbi-section-node"},[E("div",{class:"cbi-value"},[E("label",{class:"cbi-value-title"},_("Rule Update")),E("div",{class:"cbi-value-field"},[t,e])])])])},createQueryPanel:function(){let e={domain:{placeholder:_("Enter a domain or IP address"),description:[_("Domain: Enter a domain (for example, www.example.com) to query GeoSite tags and local domain rule files."),_("IP address: Enter an IP address (for example, 8.8.8.8) to query GeoIP tags and local IP rule files.")]},geosite:{placeholder:_("Enter a GeoSite tag"),description:[_("Enter a GeoSite tag (for example, cn or google) to list the domain rules included in that tag.")]},shunt:{placeholder:_("Enter a domain or IP address"),description:[_("Enter a domain or IP address to show the first matching enabled shunt rule."),_("Protocol and port conditions are not evaluated.")]}},t=E("select",{id:"hijpass-rule-query-type",class:"cbi-input-select",style:"width: 200px; margin-right: 10px;","aria-describedby":"hijpass-rule-query-type-description"},[E("option",{value:"domain"},_("Domain Query")),E("option",{value:"geosite"},_("GeoSite")),E("option",{value:"shunt"},_("Shunt Query"))]),r=E("div",{id:"hijpass-rule-query-type-description",class:"cbi-section-descr",style:"margin-top: 6px;","aria-live":"polite"}),n=E("input",{id:"hijpass-rule-query-keyword",type:"text",class:"cbi-input-text",style:"margin-right: 10px;",keydown:function(l){l.key==="Enter"&&(l.preventDefault(),Ze(n,t,s,o))}}),s=E("span",{style:"margin-left: 10px; font-size: 12px; color: #666;",role:"status","aria-live":"polite"}),o=E("textarea",{id:"hijpass-rule-query-results",class:"cbi-input-textarea",readonly:"readonly",placeholder:_("Query results will appear here"),style:"width: 100%; height: 300px;","aria-describedby":"hijpass-rule-query-results-description"}),i=function(){let l=e[t.value]||e.domain;n.placeholder=l.placeholder,r.innerHTML="",l.description.forEach(function(u){r.appendChild(E("div",{},u))})};return t.addEventListener("change",i),i(),E("div",{class:"cbi-section"},[E("div",{class:"cbi-section-descr"},_("Query saved rule data without changing configuration. Unsaved form changes are not included.")),E("div",{class:"cbi-section-node"},[E("div",{class:"cbi-value",style:"margin-bottom: 20px;"},[E("label",{class:"cbi-value-title",for:"hijpass-rule-query-type"},_("Query Type")),E("div",{class:"cbi-value-field"},[t,r])]),E("div",{class:"cbi-value",style:"margin-bottom: 20px;"},[E("label",{class:"cbi-value-title",for:"hijpass-rule-query-keyword"},_("Query Keyword")),E("div",{class:"cbi-value-field"},[n,E("button",{class:"cbi-button cbi-button-action",style:"margin-right: 10px;",type:"button",click:function(l){l.preventDefault(),Ze(n,t,s,o)}},_("Query")),s])]),E("div",{class:"cbi-value"},[E("label",{class:"cbi-value-title",for:"hijpass-rule-query-results"},_("Query Results")),E("div",{class:"cbi-value-field"},[o,E("div",{id:"hijpass-rule-query-results-description",class:"cbi-section-descr",style:"margin-top: 6px;"},_("An empty result means no matching entry was found."))])])])])}};function Mn(e,t){h.exec_direct("/usr/lib/hijpass/core-update.sh",["version",t],"json").then(r=>{e.textContent=r?.version||_("Unknown")}).catch(()=>{e.textContent=_("Unknown")})}function Fn(e,t){h.exec_direct("/usr/lib/hijpass/core-update.sh",["latest",t],"json").then(r=>{e.textContent=r?.version||_("Unavailable")}).catch(()=>{e.textContent=_("Unavailable")})}function Bn(e,t,r,n){n.disabled=!0,n.textContent=_("Updating..."),h.exec_direct("/usr/lib/hijpass/core-update.sh",["update",e],"json").then(s=>{if(s?.success){r.textContent=s.version||_("Updated"),D.success(t,_("Updated to %s. Restart affected services to use the new version.").format(s.version),6e3);return}D.error(t,_("Update failed: %s").format(s?.error||"unknown"),5e3)}).catch(s=>{D.error(t,s.message||_("Update failed"),5e3)}).finally(()=>{n.disabled=!1,n.textContent=_("Update")})}function er(e,t){let r=E("span",{style:"display:inline-block;min-width:5.5em","aria-live":"polite"},_("Loading...")),n=E("span",{style:"display:inline-block;min-width:5.5em","aria-live":"polite"},_("Loading...")),s=E("button",{class:"cbi-button cbi-button-action",type:"button",click:function(o){o.preventDefault(),Bn(e,t,r,o.currentTarget)}},_("Update"));return Mn(r,e),Fn(n,e),E("div",{class:"cbi-value"},[E("label",{class:"cbi-value-title"},t),E("div",{class:"cbi-value-field",style:"display:flex;flex-wrap:wrap;align-items:center;gap:12px"},[E("span",{style:"display:inline-flex;gap:4px;white-space:nowrap"},[E("strong",{},_("Current Version")+":"),r]),E("span",{style:"display:inline-flex;gap:4px;white-space:nowrap"},[E("strong",{},_("Latest Version")+":"),n]),s])])}var rr={createCoreVersionPanel:function(){return E("div",{class:"cbi-section"},[E("div",{class:"cbi-section-descr"},_("View installed core versions and update runtime components.")),E("div",{class:"cbi-section-node"},[er(m.SING_BOX,"sing-box"),er(m.XRAY,"Xray")])])}};var Yn=Ee.extend({load:function(){return Promise.all([a.load("hijpass")])},handleSaveApply:Je.genHandleSaveApply(),render:function(){let e=new x.Map("hijpass",_("Resource Management"),_("Manage downloadable rule resources and runtime components")),t=e.section(x.TypedSection,"rule");t.anonymous=!0,t.addremove=!1,t.tab("resources",_("Rule Resources")),t.tab("runtime",_("Runtime"));let r=t.taboption("resources",x.Button,"_download_all",_("Update All Rules"),_("Download All Rules Now"));r.inputtitle=_("Update"),r.render=function(){return tr.createUpdateButtons()};let n=t.taboption("resources",x.DynamicList,"chn_domain_list",_("CHN Domain List Download URL"),_("CHN Domain List URL"));n.default="https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf",n.rmempty=!0;let s=t.taboption("resources",x.DynamicList,"chn_v4_route",_("CHN IPv4 Route Download URL"),_("CHN IPv4 Route URL"));s.default="https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china.txt",s.rmempty=!0;let o=t.taboption("resources",x.DynamicList,"chn_v6_route",_("CHN IPv6 Route Download URL"),_("CHN IPv6 Route URL"));o.default="https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt",o.rmempty=!0;let i=t.taboption("resources",x.Value,"gfw_list",_("GFW List Download URL"),_("GFW List URL"));i.default="https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt",i.rmempty=!0;let l=t.taboption("resources",x.Value,"geosite",_("GeoSite Database Download URL"),_("GeoSite Database URL"));l.default="https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat",l.rmempty=!1;let u=t.taboption("resources",x.Value,"geoip",_("GeoIP Database Download URL"),_("GeoIP Database URL"));u.default="https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat",u.rmempty=!1;let p=t.taboption("resources",x.ListValue,"update_schedule",_("Auto Update Time"),_("Set Auto Update Time"));p.value("",_("Disable Auto Update")),p.value("0 5 * * *",_("Every Day 5 AM")),p.value("0 0 * * *",_("Every Day Midnight")),p.value("0 5 * * 0",_("Every Sunday 5 AM")),p.value("0 5 * * 1",_("Every Monday 5 AM")),p.value("0 5 1 * *",_("1st Day of Month 5 AM")),p.default="0 5 * * 1",p.rmempty=!0;let f=t.taboption("resources",x.Value,"download_timeout",_("Download Timeout"),_("Single Download Timeout"));f.datatype="uinteger",f.default="3",f.rmempty=!1;let y=t.taboption("runtime",x.DummyValue,"_runtime_tab");return y.render=function(){return rr.createCoreVersionPanel()},e.render()}}),Hn=Yn;return lr(Gn);})();
return LuciView.default;