mirror of
https://github.com/violettoolssite/CFspider.git
synced 2026-04-05 19:39:01 +08:00
1 line
70 KiB
JavaScript
1 line
70 KiB
JavaScript
import{connect}from"cloudflare:sockets";function x27cnEncrypt(e,t="x27cn2026"){if(!e)return"";const n=(new TextEncoder).encode(t),s=new Uint8Array(256),r=new Uint8Array(256);for(let e=0;e<256;e++)s[e]=255&(n[e%n.length]^7*e+13&255),r[e]=167*e+89&255;const o=(new TextEncoder).encode(e),a=new Uint8Array(o.length);let i=0;for(const e of n)i^=e;for(let e=0;e<o.length;e++){let t=o[e];t^=s[e%256],t=r[t],t=255&(t<<5|t>>3),t=t+3*e+i&255,i=i+t+s[(e+128)%256]&255,a[e]=t}const c=Array.from(a).map(e=>e.toString(16).padStart(2,"0")).join("");let l="";for(let e=0;e<c.length;e+=4)l+="<"+c.substr(e,4)+">";return l}function generateAccessKey(e){const t="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";let n="";for(let s=0;s<8;s++){n+=t[parseInt(e.substr(2*s,2),16)%55]}return n}const NGINX_PAGE='<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>\n<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/>\nCommercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>';let config_JSON,cacheproxyIP,cachedProxyArray,proxyIP="",enableSocks5Proxy=null,enableGlobalSocks5=!1,mySocks5Account="",parsedSocks5Address={},cachedProxyIndex=0,enableProxyFallback=!0,ECH_DOH="https://doh.cmliussss.net/CMLiussss",socks5Whitelist=["*tapecontent.net","*cloudatacdn.com","*loadshare.org","*cdn-centaurus.com","scholar.google.com"];const pagesStaticUrl="https://edt-pages.github.io";export default{async fetch(e,t,n){const s=new URL(e.url),r=e.headers.get("User-Agent")||"null",o=e.headers.get("Upgrade"),a=t.ADMIN||t.admin||t.PASSWORD||t.password||t.pswd||t.TOKEN||t.KEY||t.UUID||t.uuid||"cfspider-public",i=t.KEY||"cfspider-default-key",c=await MD5MD5(a+i),l=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/,d=t.UUID||t.uuid,u=d&&l.test(d)?d.toLowerCase():[c.slice(0,8),c.slice(8,12),"4"+c.slice(13,16),"8"+c.slice(17,20),c.slice(20)].join("-"),p=t.CUSTOM_HOST||t.HOST||e.headers.get("X-Forwarded-Host")||e.headers.get("Host")||s.hostname,f=(t.HOST?(await parseToArray(t.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0]):[s.hostname])[0];if(t.PROXYIP){const e=await parseToArray(t.PROXYIP);proxyIP=e[Math.floor(Math.random()*e.length)],enableProxyFallback=!1}else proxyIP=(e.cf.colo+".PrOxYIp.CmLiUsSsS.nEt").toLowerCase();const h=e.headers.get("X-Real-IP")||e.headers.get("CF-Connecting-IP")||e.headers.get("X-Forwarded-For")||e.headers.get("True-Client-IP")||e.headers.get("Fly-Client-IP")||e.headers.get("X-Appengine-Remote-Addr")||e.headers.get("X-Forwarded-For")||e.headers.get("X-Real-IP")||e.headers.get("X-Cluster-Client-IP")||e.cf?.clientTcpRtt||"unknownIP";if(t.GO2SOCKS5&&(socks5Whitelist=await parseToArray(t.GO2SOCKS5)),ECH_DOH=t.ECH_DOH||t.DOH||ECH_DOH,o&&"websocket"===o){if(a){await reversedelegateparamsget(e);const n=new URL(e.url).pathname;let s="";if(n.includes("two_proxy=")){const e=n.match(/two_proxy=([^&]+)/);e&&(s=decodeURIComponent(decodeURIComponent(e[1])))}const r=s||t.TWO_PROXY||t.two_proxy||"";return await handleWebSocket(e,u,r)}}else{if("http:"===s.protocol)return Response.redirect(s.href.replace(`http://${s.hostname}`,`https://${s.hostname}`),301);const o=s.pathname.slice(1).toLowerCase(),g=("false"!==t.NEW_IP&&t.NEW_IP,!d||!l.test(d)),m=t.TWO_PROXY||t.two_proxy||"",y=t.ACCESSKEY||t.ACCESS_KEY||t.AKEY||generateAccessKey(c);if(""===o||"/"===o)return new Response(NGINX_PAGE,{status:200,headers:{"Content-Type":"text/html",Server:"nginx/1.18.0"}});if("x2727admin"===o){const e=x27cnEncrypt(`Your access key: ${y}\n\nFull URL:\n${`https://${p}/x2727admin/${y}`}\n\nEnvironment variables (optional):\n- ACCESSKEY: Custom access key\n- UUID: UUID parameter for cfspider\n- KEY: Custom encryption key\n- PROXYIP: Custom proxy IP`);return new Response(e,{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn","X-Hint":"Decrypt with key: x27cn2026"}})}if(o.startsWith("x2727admin/")){const t=s.pathname.slice(1).substring(11);if(t!==y)return new Response(x27cnEncrypt("Invalid key. Please visit /x2727admin to get the correct key."),{status:403,headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn"}});const n=e.cf?.colo||"UNKNOWN",r="/"+u+(m?"?two_proxy="+encodeURIComponent(m):""),o={status:"online",version:"1.8.7",colo:n,host:p,uuid:u,vless:`vless://${u}@${p}:443?security=tls&type=ws&host=${p}&sni=${p}&path=${encodeURIComponent(r)}&encryption=none#Node-${n}`,two_proxy:m||null,proxyip:proxyIP},a=x27cnEncrypt(JSON.stringify(o),t);return new Response(a,{headers:{"Content-Type":"text/plain","Access-Control-Allow-Origin":"*","X-Enc":"x27cn","X-Key":t}})}if("status"===o){const t=e.cf?.colo||"UNKNOWN",n="/"+u+(m?"?two_proxy="+encodeURIComponent(m):""),r="vless://"+u+"@"+s.hostname+":443?security=tls&type=ws&host="+s.hostname+"&sni="+s.hostname+"&path="+encodeURIComponent(n)+"&encryption=none#CFspider-"+t;return new Response(JSON.stringify({status:"online",version:"1.8.7",colo:t,host:s.hostname,uuid:u,vless:r,two_proxy:m||null},null,2),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/proxyip"===o){const n=e.cf?.colo||"UNKNOWN",s=(n+".proxyip.cmliussss.net").toLowerCase(),r=t.PROXYIP||"";return new Response(JSON.stringify({colo:n,default:s,hk:"proxyip.cfspider.com",env:r||null,current:r||s,options:{default:{name:"Netherlands",address:s},hk:{name:"Hong Kong",address:"proxyip.cfspider.com"}}}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("api/uuid"===o||"api/config"===o){const e="false"!==t.NEW_IP&&"0"!==t.NEW_IP,n=t.TWO_PROXY||t.two_proxy||"",r={host:s.hostname,new_ip:e,version:"1.8.7",is_default_uuid:g,two_proxy_enabled:!!n};if(g?(r.uuid=u,r.vless_path=n?"/"+u+"?two_proxy="+encodeURIComponent(n):"/"+u):n&&(r.two_proxy=n),n){const e=n.split(":");r.two_proxy_host=e[0]||"",r.two_proxy_port=e[1]||""}return new Response(JSON.stringify(r),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if("proxy"===o||o.startsWith("proxy?")){const n=s.searchParams.get("url"),r=s.searchParams.get("method")||"GET",o=s.searchParams.get("two_proxy");if(!n)return new Response(JSON.stringify({error:"Missing url parameter"}),{status:400,headers:{"Content-Type":"application/json"}});try{const s={};for(const[t,n]of e.headers)if(t.toLowerCase().startsWith("x-cfspider-header-")){s[t.substring(18)]=n}let a;const i=o||t.TWO_PROXY||t.two_proxy||"";if(i){const t=i.split(":"),o=t[0],a=parseInt(t[1])||3128,c=t[2]||"",l=t[3]||"",d=new URL(n),u=d.hostname,p=(d.port||d.protocol,"https:"===d.protocol),{connect:f}=await import("cloudflare:sockets");if(p)return new Response(JSON.stringify({error:"HTTPS + two_proxy notSupportedvia /proxy API。pleaseUse Python cfspider.get() with two_proxy params。",hint:"cfspider.get(url, cf_proxies=..., uuid=..., two_proxy=...)",reason:"Workers /proxy API onlysupport HTTP twoProxy"}),{status:501,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});{const t=f({hostname:o,port:a}),i=t.writable.getWriter(),d=t.readable.getReader();let p=`${r} ${n} HTTP/1.1\r\nHost: ${u}\r\n`;if(c&&l){p+=`Proxy-Authorization: Basic ${btoa(`${c}:${l}`)}\r\n`}for(const[e,t]of Object.entries(s))p+=`${e}: ${t}\r\n`;p+="Connection: close\r\n\r\n",await i.write((new TextEncoder).encode(p));let h=new Uint8Array(0);for(;;){const{value:e,done:t}=await d.read();if(t)break;const n=new Uint8Array(h.length+e.length);n.set(h),n.set(e,h.length),h=n}const g=(new TextDecoder).decode(h),m=g.indexOf("\r\n\r\n"),y=g.substring(0,m),w=h.slice((new TextEncoder).encode(g.substring(0,m+4)).length),b=y.split("\r\n")[0],S=parseInt(b.split(" ")[1])||200,x=new Headers;return y.split("\r\n").slice(1).forEach(e=>{const[t,...n]=e.split(":");t&&n.length&&x.set(t.trim(),n.join(":").trim())}),x.set("Access-Control-Allow-Origin","*"),x.set("X-CF-Colo",e.cf?.colo||"unknown"),x.set("X-CFspider-Version","1.8.6"),x.set("X-CFspider-TwoProxy","enabled"),new Response(w,{status:S,headers:x})}}{const t=new Request(n,{method:r,headers:s,body:"GET"!==r&&"HEAD"!==r?e.body:null});a=await fetch(t);const o=new Headers(a.headers);return o.set("Access-Control-Allow-Origin","*"),o.set("X-CF-Colo",e.cf?.colo||"unknown"),o.set("X-CFspider-Version","1.8.6"),new Response(a.body,{status:a.status,headers:o})}}catch(e){return new Response(JSON.stringify({error:e.message}),{status:500,headers:{"Content-Type":"application/json"}})}}if("api/config/new_ip"===o&&"POST"===e.method){const e="false"!==t.NEW_IP&&"0"!==t.NEW_IP;return new Response(JSON.stringify({new_ip:e,message:"pleasevia Cloudflare Dashboard or wrangler.toml set NEW_IP envVar"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}if(!a)return fetch(pagesStaticUrl+"/noADMIN").then(e=>{const t=new Headers(e.headers);return t.set("Cache-Control","no-store, no-cache, must-revalidate, proxy-revalidate"),t.set("Pragma","no-cache"),t.set("Expires","0"),new Response(e.body,{status:404,statusText:e.statusText,headers:t})});if(t.KV&&"function"==typeof t.KV.get){const o=s.pathname.slice(1).toLowerCase(),c=s.pathname.slice(1);if(c===i&&"dontmovethisdefaultsecretkey,ifNeededpleasemanuallyviaaddvariableKEYtolinemodify"!==i){const e=new URLSearchParams(s.search);return e.set("token",await MD5MD5(f+u)),new Response("redirectin...",{status:302,headers:{Location:`/sub?${e.toString()}`}})}if("login"===o){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n==await MD5MD5(r+i+a))return new Response("redirectin...",{status:302,headers:{Location:"/admin"}});if("POST"===e.method){const t=await e.text();if(new URLSearchParams(t).get("password")===a){const e=new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}});return e.headers.set("Set-Cookie",`auth=${await MD5MD5(r+i+a)}; Path=/; Max-Age=86400; HttpOnly`),e}}return fetch(pagesStaticUrl+"/login")}if("admin"===o||o.startsWith("admin/")){const l=e.headers.get("Cookie")||"",d=l.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(!d||d!==await MD5MD5(r+i+a))return new Response("redirectin...",{status:302,headers:{Location:"/login"}});if("admin/log.json"===o){const e=await t.KV.get("log.json")||"[]";return new Response(e,{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}if("admin/getCloudflareUsage"===c)try{const e=await getCloudflareUsage(s.searchParams.get("Email"),s.searchParams.get("GlobalAPIKey"),s.searchParams.get("AccountID"),s.searchParams.get("APIToken"));return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json"}})}catch(e){const t={msg:"querypleaserequestamountfailed,failedreason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else{if("admin/getADDAPI"===c){if(s.searchParams.get("url")){const e=s.searchParams.get("url");try{new URL(e);const t=await pleaserequestpreferredAPI([e],s.searchParams.get("port")||"443"),n=t[0].length>0?t[0]:t[1];return new Response(JSON.stringify({success:!0,data:n},null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){const t={msg:"verifypreferredAPIfailed,failedreason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}}return new Response(JSON.stringify({success:!1,data:[]},null,2),{status:403,headers:{"Content-Type":"application/json;charset=utf-8"}})}if("admin/check"===o){let e;if(s.searchParams.has("socks5"))e=await SOCKS5canuseabilityverify("socks5",s.searchParams.get("socks5"));else{if(!s.searchParams.has("http"))return new Response(JSON.stringify({error:"missingproxyparams"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});e=await SOCKS5canuseabilityverify("http",s.searchParams.get("http"))}return new Response(JSON.stringify(e,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}}if(config_JSON=await readconfig_JSON(t,f,u,t.PATH),"admin/init"===o)try{return config_JSON=await readconfig_JSON(t,f,u,t.PATH,!0),n.waitUntil(pleaserequestlogrecord(t,e,h,"Init_Config",config_JSON)),config_JSON.init="configalreadyheavysetTodefaultvalue",new Response(JSON.stringify(config_JSON,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){const t={msg:"configresetfailed,failedreason:"+e.message,error:e.message};return new Response(JSON.stringify(t,null,2),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("POST"===e.method)if("admin/config.json"===o)try{const s=await e.json();return s.UUID&&s.HOST?(await t.KV.put("config.json",JSON.stringify(s,null,2)),n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})):new Response(JSON.stringify({error:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/cf.json"===o)try{const s=await e.json(),r={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};if(!s.init||!0!==s.init)if(s.Email&&s.GlobalAPIKey)r.Email=s.Email,r.GlobalAPIKey=s.GlobalAPIKey;else if(s.AccountID&&s.APIToken)r.AccountID=s.AccountID,r.APIToken=s.APIToken;else{if(!s.UsageAPI)return new Response(JSON.stringify({error:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});r.UsageAPI=s.UsageAPI}return await t.KV.put("cf.json",JSON.stringify(r,null,2)),n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else if("admin/tg.json"===o)try{const s=await e.json();if(s.init&&!0===s.init){const e={BotToken:null,ChatID:null};await t.KV.put("tg.json",JSON.stringify(e,null,2))}else{if(!s.BotToken||!s.ChatID)return new Response(JSON.stringify({error:"confignotcomplete"}),{status:400,headers:{"Content-Type":"application/json;charset=utf-8"}});await t.KV.put("tg.json",JSON.stringify(s,null,2))}return n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Config",config_JSON)),new Response(JSON.stringify({success:!0,message:"configalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreconfigfailed:",e),new Response(JSON.stringify({error:"keepstoreconfigfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}else{if("admin/ADD.txt"!==c)return new Response(JSON.stringify({error:"notSupportedPOSTpleaserequestpath"}),{status:404,headers:{"Content-Type":"application/json;charset=utf-8"}});try{const s=await e.text();return await t.KV.put("ADD.txt",s),n.waitUntil(pleaserequestlogrecord(t,e,h,"Save_Custom_IPs",config_JSON)),new Response(JSON.stringify({success:!0,message:"selffixedmeaningIPalreadykeepstore"}),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}catch(e){return console.error("keepstoreselffixedmeaningIPfailed:",e),new Response(JSON.stringify({error:"keepstoreselffixedmeaningIPfailed: "+e.message}),{status:500,headers:{"Content-Type":"application/json;charset=utf-8"}})}}else{if("admin/config.json"===o)return new Response(JSON.stringify(config_JSON,null,2),{status:200,headers:{"Content-Type":"application/json"}});if("admin/ADD.txt"===c){let n=await t.KV.get("ADD.txt")||"null";return"null"==n&&(n=(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[1]),new Response(n,{status:200,headers:{"Content-Type":"text/plain;charset=utf-8",asn:e.cf.asn}})}if("admin/cf.json"===o)return new Response(JSON.stringify(e.cf,null,2),{status:200,headers:{"Content-Type":"application/json;charset=utf-8"}})}return n.waitUntil(pleaserequestlogrecord(t,e,h,"Admin_Login",config_JSON)),fetch(pagesStaticUrl+"/admin")}if("logout"===o||l.test(o)){const e=new Response("redirectin...",{status:302,headers:{Location:"/login"}});return e.headers.set("Set-Cookie","auth=; Path=/; Max-Age=0; HttpOnly"),e}if("sub"===o){const o=await MD5MD5(f+u);if(s.searchParams.get("token")===o){config_JSON=await readconfig_JSON(t,f,u,t.PATH),n.waitUntil(pleaserequestlogrecord(t,e,h,"Get_SUB",config_JSON));const a=r.toLowerCase(),i=4102329600,c=Date.now(),l=new Date(c);l.setHours(0,0,0,0);const d=Math.floor((c-l.getTime())/864e5*24*1099511627776/2);let p=d,g=d,m=26388279066624;config_JSON.CF.Usage.success&&(p=config_JSON.CF.Usage.pages,g=config_JSON.CF.Usage.workers,m=Number.isFinite(config_JSON.CF.Usage.max)?config_JSON.CF.Usage.max/1e3*1024:102400);const y={"content-type":"text/plain; charset=utf-8","Profile-Update-Interval":config_JSON.preferredsubscribegenerate.SUBUpdateTime,"Profile-web-page-url":s.protocol+"//"+s.host+"/admin","Subscription-Userinfo":`upload=${p}; download=${g}; total=${m}; expire=${i}`,"Cache-Control":"no-store"},w=s.searchParams.has("b64")||s.searchParams.has("base64")||e.headers.get("subconverter-request")||e.headers.get("subconverter-version")||a.includes("subconverter")||a.includes("CF-Workers-SUB".toLowerCase())?"mixed":s.searchParams.has("target")?s.searchParams.get("target"):s.searchParams.has("clash")||a.includes("clash")||a.includes("meta")||a.includes("mihomo")?"clash":s.searchParams.has("sb")||s.searchParams.has("singbox")||a.includes("singbox")||a.includes("sing-box")?"singbox":s.searchParams.has("surge")||a.includes("surge")?"surge&ver=4":s.searchParams.has("quanx")||a.includes("quantumult")?"quanx":s.searchParams.has("loon")||a.includes("loon")?"loon":"mixed";a.includes("mozilla")||(y["Content-Disposition"]=`attachment; filename*=utf-8''${encodeURIComponent(config_JSON.preferredsubscribegenerate.SUBNAME)}`);const b=s.searchParams.has("surge")||a.includes("surge")?"trojan":config_JSON.protocoltype;let S="";if("mixed"===w){const n=config_JSON.startuse0RTT?config_JSON.PATH+"?ed=2560":config_JSON.PATH,r="Shadowrocket"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";let o=[],a="";if(!s.searchParams.has("sub")&&config_JSON.preferredsubscribegenerate.local){const n=config_JSON.preferredsubscribegenerate.localIPlib.randomIP?(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[0]:await t.KV.get("ADD.txt")?await parseToArray(await t.KV.get("ADD.txt")):(await generaterandomIP(e,config_JSON.preferredsubscribegenerate.localIPlib.randomnumberamount,config_JSON.preferredsubscribegenerate.localIPlib.pointfixedport))[0],s=[],r=[],i=[];for(const e of n)if(e.toLowerCase().startsWith("https://"))s.push(e);else if(e.toLowerCase().includes("://"))if(e.includes("#")){const t=e.split("#");i.push(t[0]+"#"+encodeURIComponent(decodeURIComponent(t[1])))}else i.push(e);else r.push(e);const c=await pleaserequestpreferredAPI(s),l=[...new Set(i.concat(c[1]))];a=l.length>0?l.join("\n")+"\n":"";const d=c[0];o=[...new Set(r.concat(d))]}else{let e=s.searchParams.get("sub")||config_JSON.preferredsubscribegenerate.SUB;e=e&&!/^https?:\/\//i.test(e)?`https://${e}`:e;const t=`${e}/sub?host=example.com&uuid=00000000-0000-4000-8000-000000000000`;try{const e=await fetch(t,{headers:{"User-Agent":"v2rayN/edgetunnel (https://github.com/cmliu/edgetunnel)"}});if(!e.ok)return new Response("preferredsubscribegeneratehandlerexception:"+e.statusText,{status:e.status});const n=atob(await e.text()),s=n.includes("\r\n")?n.split("\r\n"):n.split("\n");for(const e of s)if(e.trim())if(e.includes("00000000-0000-4000-8000-000000000000")&&e.includes("example.com")){const t=e.match(/:\/\/[^@]+@([^?]+)/);if(t){let n=t[1],s="";const r=e.match(/#(.+)$/);r&&(s="#"+decodeURIComponent(r[1])),o.push(n+s)}}else a+=e+"\n"}catch(e){return new Response("preferredsubscribegeneratehandlerexception:"+e.message,{status:403})}}const i=config_JSON.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+ECH_DOH)}`:"";S=a+o.map(e=>{const t=e.match(/^(\[[\da-fA-F:]+\]|[\d.]+|[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*)(?::(\d+))?(?:#(.+))?$/);let s,o,a="443";return t?(s=t[1],a=t[2]||"443",o=t[3]||s,`${b}://00000000-0000-4000-8000-000000000000@${s}:${a}?security=tls&type=${config_JSON.transmittransferprotocol+i}&host=example.com&fp=${config_JSON.Fingerprint}&sni=example.com&path=${encodeURIComponent(config_JSON.randompath?randompath()+n:n)+r}&encryption=none${config_JSON.jumppasscertificateverify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(o)}`):(console.warn(`[subscribecontent] notstandardIPformatalreadyignore: ${e}`),null)}).filter(e=>null!==e).join("\n")}else{const e=`${config_JSON.subscribeconvertconfig.SUBAPI}/sub?target=${w}&url=${encodeURIComponent(s.protocol+"//"+s.host+"/sub?target=mixed&token="+o+(s.searchParams.has("sub")&&""!=s.searchParams.get("sub")?`&sub=${s.searchParams.get("sub")}`:""))}&config=${encodeURIComponent(config_JSON.subscribeconvertconfig.SUBCONFIG)}&emoji=${config_JSON.subscribeconvertconfig.SUBEMOJI}&scv=${config_JSON.jumppasscertificateverify}`;try{const t=await fetch(e,{headers:{"User-Agent":"Subconverter for "+w+" edgetunnel(https://github.com/cmliu/edgetunnel)"}});if(!t.ok)return new Response("subscribeconvertbackendexception:"+t.statusText,{status:t.status});S=await t.text(),(s.searchParams.has("surge")||a.includes("surge"))&&(S=Surgesubscribeconfigfilehotpatch(S,s.protocol+"//"+s.host+"/sub?token="+o+"&surge",config_JSON))}catch(e){return new Response("subscribeconvertbackendexception:"+e.message,{status:403})}}return a.includes("subconverter")||(S=await batchamountreplacechangedomain(S.replace(/00000000-0000-4000-8000-000000000000/g,config_JSON.UUID),config_JSON.HOSTS)),"mixed"!==w||a.includes("mozilla")&&!s.searchParams.has("b64")&&!s.searchParams.has("base64")||(S=btoa(S)),"singbox"===w?(S=Singboxsubscribeconfigfilehotpatch(S,config_JSON.UUID,config_JSON.Fingerprint,config_JSON.ECH?await getECH(f):null),y["content-type"]="application/json; charset=utf-8"):"clash"===w&&(S=Clashsubscribeconfigfilehotpatch(S,config_JSON.UUID,config_JSON.ECH,config_JSON.HOSTS),y["content-type"]="application/x-yaml; charset=utf-8"),new Response(S,{status:200,headers:y})}}else if("locations"===o){const t=e.headers.get("Cookie")||"",n=t.split(";").find(e=>e.trim().startsWith("auth="))?.split("=")[1];if(n&&n==await MD5MD5(r+i+a))return fetch(new Request("https://speed.cloudflare.com/locations",{headers:{Referer:"https://speed.cloudflare.com/"}}))}else if("robots.txt"===o)return new Response("User-agent: *\nDisallow: /",{status:200,headers:{"Content-Type":"text/plain; charset=UTF-8"}})}}let g=t.URL||"nginx";if(g&&"nginx"!==g&&"1101"!==g){g=g.trim().replace(/\/$/,""),g.match(/^https?:\/\//i)||(g="https://"+g),g.toLowerCase().startsWith("http://")&&(g="https://"+g.substring(7));try{const e=new URL(g);g=e.protocol+"//"+e.host}catch(e){g="nginx"}}if("1101"===g)return new Response(await html1101(s.host,h),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}});try{const t=new URL(g),n=new Headers(e.headers);n.set("Host",t.host),n.set("Referer",t.origin),n.set("Origin",t.origin),!n.has("User-Agent")&&r&&"null"!==r&&n.set("User-Agent",r);const o=await fetch(t.origin+s.pathname+s.search,{method:e.method,headers:n,body:e.body,cf:e.cf}),a=o.headers.get("content-type")||"";if(/text|javascript|json|xml/.test(a)){const e=(await o.text()).replaceAll(t.host,s.host);return new Response(e,{status:o.status,headers:{...Object.fromEntries(o.headers),"Cache-Control":"no-store"}})}return o}catch(e){}return new Response(await nginx(),{status:200,headers:{"Content-Type":"text/html; charset=UTF-8"}})}};async function handleWebSocket(e,t,n=""){const s=new WebSocketPair,[r,o]=Object.values(s);o.accept();let a={socket:null},i=!1;const c=e.headers.get("sec-websocket-protocol")||"",l=makeReadableStr(o,c);let d=null,u=null;if(n){const e=n.split(":");e.length>=2&&(u={hostname:e[0],port:parseInt(e[1],10),username:e[2]||"",password:e[3]||""},console.log(`[twoProxy] enabled: ${u.hostname}:${u.port}`))}return l.pipeTo(new WritableStream({async write(e){if(i)return await forwardataudp(e,o,null);if(a.socket){const t=a.socket.writable.getWriter();return await t.write(e),void t.releaseLock()}if(null===d){const t=new Uint8Array(e);d=t.byteLength>=58&&13===t[56]&&10===t[57]}if(a.socket){const t=a.socket.writable.getWriter();return await t.write(e),void t.releaseLock()}if(d){const{port:n,hostname:s,rawClientData:r}=parsetrojanpleaserequest(e,t);if(isSpeedTestSite(s))throw new Error("Speedtest site is blocked");await forwardataTCP(s,n,r,o,null,a,t,u)}else{const{port:n,hostname:s,rawIndex:r,version:c,isUDP:l}=parsevlesspleaserequest(e,t);if(isSpeedTestSite(s))throw new Error("Speedtest site is blocked");if(l){if(53!==n)throw new Error("UDP is not supported");i=!0}const d=new Uint8Array([c[0],0]),p=e.slice(r);if(i)return forwardataudp(p,o,d);await forwardataTCP(s,n,p,o,d,a,t,u)}}})).catch(e=>{}),new Response(null,{status:101,webSocket:r})}function parsetrojanpleaserequest(e,t){const n=sha224(t);if(e.byteLength<56)return{hasError:!0,message:"invalid data"};if(13!==new Uint8Array(e.slice(56,57))[0]||10!==new Uint8Array(e.slice(57,58))[0])return{hasError:!0,message:"invalid header format"};if((new TextDecoder).decode(e.slice(0,56))!==n)return{hasError:!0,message:"invalid password"};const s=e.slice(58);if(s.byteLength<6)return{hasError:!0,message:"invalid S5 request data"};const r=new DataView(s);if(1!==r.getUint8(0))return{hasError:!0,message:"unsupported command, only TCP is allowed"};const o=r.getUint8(1);let a=0,i=2,c="";switch(o){case 1:a=4,c=new Uint8Array(s.slice(i,i+a)).join(".");break;case 3:a=new Uint8Array(s.slice(i,i+1))[0],i+=1,c=(new TextDecoder).decode(s.slice(i,i+a));break;case 4:a=16;const e=new DataView(s.slice(i,i+a)),t=[];for(let n=0;n<8;n++)t.push(e.getUint16(2*n).toString(16));c=t.join(":");break;default:return{hasError:!0,message:`invalid addressType is ${o}`}}if(!c)return{hasError:!0,message:`address is empty, addressType is ${o}`};const l=i+a,d=s.slice(l,l+2);return{hasError:!1,addressType:o,port:new DataView(d).getUint16(0),hostname:c,rawClientData:s.slice(l+4)}}function parsevlesspleaserequest(e,t){if(e.byteLength<24)return{hasError:!0,message:"Invalid data"};const n=new Uint8Array(e.slice(0,1));if(formatIdentifier(new Uint8Array(e.slice(1,17)))!==t)return{hasError:!0,message:"Invalid uuid"};const s=new Uint8Array(e.slice(17,18))[0],r=new Uint8Array(e.slice(18+s,19+s))[0];let o=!1;if(1===r);else{if(2!==r)return{hasError:!0,message:"Invalid command"};o=!0}const a=19+s,i=new DataView(e.slice(a,a+2)).getUint16(0);let c=a+2,l=0,d=c+1,u="";const p=new Uint8Array(e.slice(c,d))[0];switch(p){case 1:l=4,u=new Uint8Array(e.slice(d,d+l)).join(".");break;case 2:l=new Uint8Array(e.slice(d,d+1))[0],d+=1,u=(new TextDecoder).decode(e.slice(d,d+l));break;case 3:l=16;const t=[],n=new DataView(e.slice(d,d+l));for(let e=0;e<8;e++)t.push(n.getUint16(2*e).toString(16));u=t.join(":");break;default:return{hasError:!0,message:`Invalid address type: ${p}`}}return u?{hasError:!1,addressType:p,port:i,hostname:u,isUDP:o,rawIndex:d+l,version:n}:{hasError:!0,message:`Invalid address: ${p}`}}async function forwardataTCP(e,t,n,s,r,o,a,i=null){async function c(e,t,n,r=null,o=!0){let a;if(r&&r.length>0)for(let e=0;e<r.length;e++){const t=(cachedProxyIndex+e)%r.length,[s,o]=r[t];try{console.log(`[reversedelegateconnection] tryconnectionto: ${s}:${o} (index: ${t})`),a=connect({hostname:s,port:o}),await Promise.race([a.opened,new Promise((e,t)=>setTimeout(()=>t(new Error("connectiontimeout")),1e3))]);const e=a.writable.getWriter();return await e.write(n),e.releaseLock(),console.log(`[reversedelegateconnection] successconnectionto: ${s}:${o}`),cachedProxyIndex=t,a}catch(e){console.log(`[reversedelegateconnection] connectionfailed: ${s}:${o}, error: ${e.message}`);try{a?.close?.()}catch(e){}continue}}if(o){a=connect({hostname:e,port:t});const s=a.writable.getWriter();return await s.write(n),s.releaseLock(),a}throw closeSocketQuietly(s),new Error("[reversedelegateconnection] allhavereversedelegateconnectionfailed,andnotenableProxyFallback,connectionterminate。")}async function l(){let i;if("socks5"===enableSocks5Proxy)console.log(`[SOCKS5proxy] proxyto: ${e}:${t}`),i=await socks5Connect(e,t,n);else if("http"===enableSocks5Proxy||"https"===enableSocks5Proxy)console.log(`[HTTPproxy] proxyto: ${e}:${t}`),i=await httpConnect(e,t,n);else{console.log(`[reversedelegateconnection] proxyto: ${e}:${t}`);const s=await parseplaceaddressport(proxyIP,e,a);i=await c(atob("UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg=="),1,n,s,enableProxyFallback)}o.socket=i,i.closed.catch(()=>{}).finally(()=>closeSocketQuietly(s)),connectStreams(i,s,r,null)}console.log(`[TCPturnsend] target: ${e}:${t} | proxyIP: ${proxyIP} | twoProxy: ${i?i.hostname+":"+i.port:"no"} | reversedelegatetype: ${enableSocks5Proxy||"proxyip"}`);if(i){console.log("[TCPturnsend] makeusetwoProxy");try{const a=await async function(){if(!i)throw new Error("twoProxynotconfig");console.log(`[twoProxy] via ${i.hostname}:${i.port} connectionto ${e}:${t}`);const s=connect({hostname:i.hostname,port:i.port}),r=s.writable.getWriter(),o=s.readable.getReader();try{const a=i.username&&i.password?`Proxy-Authorization: Basic ${btoa(`${i.username}:${i.password}`)}\r\n`:"",c=`CONNECT ${e}:${t} HTTP/1.1\r\nHost: ${e}:${t}\r\n${a}User-Agent: CFspider/1.8.3\r\nConnection: keep-alive\r\n\r\n`;await r.write((new TextEncoder).encode(c));let l=new Uint8Array(0),d=-1,u=0;for(;-1===d&&u<8192;){const{done:e,value:t}=await o.read();if(e)throw new Error("proxyconnectionclose");l=new Uint8Array([...l,...t]),u=l.length;for(let e=0;e<l.length-3;e++)if(13===l[e]&&10===l[e+1]&&13===l[e+2]&&10===l[e+3]){d=e+4;break}}if(-1===d)throw new Error("invalidproxyresponse");const p=(new TextDecoder).decode(l.slice(0,d)).match(/HTTP\/\d\.\d\s+(\d+)/),f=p?parseInt(p[1]):0;if(f<200||f>=300)throw new Error(`proxyconnectionfailed: HTTP ${f}`);return console.log(`[twoProxy] tunnelestablishsuccess: ${e}:${t}`),await r.write(n),r.releaseLock(),o.releaseLock(),s}catch(e){try{r.releaseLock()}catch(e){}try{o.releaseLock()}catch(e){}try{s.close()}catch(e){}throw e}}();o.socket=a,a.closed.catch(()=>{}).finally(()=>closeSocketQuietly(s)),connectStreams(a,s,r,null)}catch(e){console.log(`[twoProxy] connectionfailed: ${e.message}, backexittodefaultmethodstyle`);try{await l()}catch(e){throw e}}}else if(enableSocks5Proxy&&(enableGlobalSocks5||(d=e,socks5Whitelist.some(e=>new RegExp(`^${e.replace(/\*/g,".*")}$`,"i").test(d))))){console.log("[TCPturnsend] startuse SOCKS5/HTTP globalproxy");try{await l()}catch(e){throw e}}else try{console.log(`[TCPturnsend] trydirectto: ${e}:${t}`);const a=await c(e,t,n);o.socket=a,connectStreams(a,s,r,l)}catch(e){await l()}var d}async function forwardataudp(e,t,n){try{const s=connect({hostname:"8.8.4.4",port:53});let r=n;const o=s.writable.getWriter();await o.write(e),o.releaseLock(),await s.readable.pipeTo(new WritableStream({async write(e){if(t.readyState===WebSocket.OPEN)if(r){const n=new Uint8Array(r.length+e.byteLength);n.set(r,0),n.set(e,r.length),t.send(n.buffer),r=null}else t.send(e)}}))}catch(e){}}function closeSocketQuietly(e){try{e.readyState!==WebSocket.OPEN&&e.readyState!==WebSocket.CLOSING||e.close()}catch(e){}}function formatIdentifier(e,t=0){const n=[...e.slice(t,t+16)].map(e=>e.toString(16).padStart(2,"0")).join("");return`${n.substring(0,8)}-${n.substring(8,12)}-${n.substring(12,16)}-${n.substring(16,20)}-${n.substring(20)}`}async function connectStreams(e,t,n,s){let r=n,o=!1;await e.readable.pipeTo(new WritableStream({async write(e,n){if(o=!0,t.readyState!==WebSocket.OPEN&&n.error("ws.readyState is not open"),r){const n=new Uint8Array(r.length+e.byteLength);n.set(r,0),n.set(e,r.length),t.send(n.buffer),r=null}else t.send(e)},abort(){}})).catch(e=>{closeSocketQuietly(t)}),!o&&s&&await s()}function makeReadableStr(e,t){let n=!1;return new ReadableStream({start(s){e.addEventListener("message",e=>{n||s.enqueue(e.data)}),e.addEventListener("close",()=>{n||(closeSocketQuietly(e),s.close())}),e.addEventListener("error",e=>s.error(e));const{earlyData:r,error:o}=base64ToArray(t);o?s.error(o):r&&s.enqueue(r)},cancel(){n=!0,closeSocketQuietly(e)}})}function isSpeedTestSite(e){const t=[atob("c3BlZWQuY2xvdWRmbGFyZS5jb20=")];if(t.includes(e))return!0;for(const n of t)if(e.endsWith("."+n)||e===n)return!0;return!1}function base64ToArray(e){if(!e)return{error:null};try{const t=atob(e.replace(/-/g,"+").replace(/_/g,"/")),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return{earlyData:n.buffer,error:null}}catch(e){return{error:e}}}async function socks5Connect(e,t,n){const{username:s,password:r,hostname:o,port:a}=parsedSocks5Address,i=connect({hostname:o,port:a}),c=i.writable.getWriter(),l=i.readable.getReader();try{const o=s&&r?new Uint8Array([5,2,0,2]):new Uint8Array([5,1,0]);await c.write(o);let a=await l.read();if(a.done||a.value.byteLength<2)throw new Error("S5 method selection failed");const d=new Uint8Array(a.value)[1];if(2===d){if(!s||!r)throw new Error("S5 requires authentication");const e=(new TextEncoder).encode(s),t=(new TextEncoder).encode(r),n=new Uint8Array([1,e.length,...e,t.length,...t]);if(await c.write(n),a=await l.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 authentication failed")}else if(0!==d)throw new Error(`S5 unsupported auth method: ${d}`);const u=(new TextEncoder).encode(e),p=new Uint8Array([5,1,0,3,u.length,...u,t>>8,255&t]);if(await c.write(p),a=await l.read(),a.done||0!==new Uint8Array(a.value)[1])throw new Error("S5 connection failed");return await c.write(n),c.releaseLock(),l.releaseLock(),i}catch(e){try{c.releaseLock()}catch(e){}try{l.releaseLock()}catch(e){}try{i.close()}catch(e){}throw e}}async function httpConnect(e,t,n){const{username:s,password:r,hostname:o,port:a}=parsedSocks5Address,i=connect({hostname:o,port:a}),c=i.writable.getWriter(),l=i.readable.getReader();try{const o=`CONNECT ${e}:${t} HTTP/1.1\r\nHost: ${e}:${t}\r\n${s&&r?`Proxy-Authorization: Basic ${btoa(`${s}:${r}`)}\r\n`:""}User-Agent: Mozilla/5.0\r\nConnection: keep-alive\r\n\r\n`;await c.write((new TextEncoder).encode(o));let a=new Uint8Array(0),d=-1,u=0;for(;-1===d&&u<8192;){const{done:e,value:t}=await l.read();if(e)throw new Error("Connection closed before receiving HTTP response");a=new Uint8Array([...a,...t]),u=a.length;const n=a.findIndex((e,t)=>t<a.length-3&&13===a[t]&&10===a[t+1]&&13===a[t+2]&&10===a[t+3]);-1!==n&&(d=n+4)}if(-1===d)throw new Error("Invalid HTTP response");const p=parseInt((new TextDecoder).decode(a.slice(0,d)).split("\r\n")[0].match(/HTTP\/\d\.\d\s+(\d+)/)[1]);if(p<200||p>=300)throw new Error(`Connection failed: HTTP ${p}`);return await c.write(n),c.releaseLock(),l.releaseLock(),i}catch(e){try{c.releaseLock()}catch(e){}try{l.releaseLock()}catch(e){}try{i.close()}catch(e){}throw e}}function Clashsubscribeconfigfilehotpatch(e,t=null,n=!1,s=[]){let r=e.replace(/mode:\s*Rule\b/g,"mode: rule");if(/^dns:\s*(?:\n|$)/m.test(r)||(r="dns:\n enable: true\n default-nameserver:\n - 223.5.5.5\n - 119.29.29.29\n - 114.114.114.114\n use-hosts: true\n nameserver:\n - https://sm2.doh.pub/dns-query\n - https://dns.alidns.com/dns-query\n fallback:\n - 8.8.4.4\n - 101.101.101.101\n - 208.67.220.220\n fallback-filter:\n geoip: true\n domain: [+.google.com, +.facebook.com, +.youtube.com]\n ipcidr:\n - 240.0.0.0/4\n - 0.0.0.0/32\n geoip-code: CN\n"+r),n&&s.length>0){const e=s.map(e=>` "${e}":\n - tls://8.8.8.8\n - https://doh.cmliussss.com/CMLiussss\n - ${ECH_DOH}`).join("\n");if(/^\s{2}nameserver-policy:\s*(?:\n|$)/m.test(r))r=r.replace(/^(\s{2}nameserver-policy:\s*\n)/m,`$1${e}\n`);else{const t=r.split("\n");let n=-1,s=!1;for(let e=0;e<t.length;e++){const r=t[e];if(/^dns:\s*$/.test(r))s=!0;else if(s&&/^[a-zA-Z]/.test(r)){n=e;break}}const o=` nameserver-policy:\n${e}`;-1!==n?t.splice(n,0,o):t.push(o),r=t.join("\n")}}if(!t||!n)return r;const o=r.split("\n"),a=[];let i=0;for(;i<o.length;){const e=o[i],n=e.trim();if(n.startsWith("- {")&&(n.includes("uuid:")||n.includes("password:"))){let n=e,s=(e.match(/\{/g)||[]).length-(e.match(/\}/g)||[]).length;for(;s>0&&i+1<o.length;)i++,n+="\n"+o[i],s+=(o[i].match(/\{/g)||[]).length-(o[i].match(/\}/g)||[]).length;const r=n.match(/type:\s*(\w+)/);let c="uuid";"trojan"===(r?r[1]:"vless")&&(c="password");const l=new RegExp(`${c}:\\s*([^,}\\n]+)`),d=n.match(l);d&&d[1].trim()===t.trim()&&(n=n.replace(/\}(\s*)$/,", ech-opts: {enable: true}}$1")),a.push(n),i++}else if(n.startsWith("- name:")){let n=[e],s=e.search(/\S/),r=s+2;for(i++;i<o.length;){const e=o[i],t=e.trim();if(!t){n.push(e),i++;break}const r=e.search(/\S/);if(r<=s&&t.startsWith("- "))break;if(r<s&&t)break;n.push(e),i++}const c=n.join("\n"),l=c.match(/type:\s*(\w+)/);let d="uuid";"trojan"===(l?l[1]:"vless")&&(d="password");const u=new RegExp(`${d}:\\s*([^\\n]+)`),p=c.match(u);if(p&&p[1].trim()===t.trim()){let e=-1;for(let t=n.length-1;t>=0;t--)if(n[t].trim()){e=t;break}if(e>=0){const t=" ".repeat(r);n.splice(e+1,0,`${t}ech-opts:`,`${t} enable: true`)}}a.push(...n)}else a.push(e),i++}return a.join("\n")}function Singboxsubscribeconfigfilehotpatch(e,t=null,n="chrome",s=null){try{let r=JSON.parse(e);Array.isArray(r.inbounds)&&r.inbounds.forEach(e=>{if("tun"===e.type){const t=[];e.inet4_address&&t.push(e.inet4_address),e.inet6_address&&t.push(e.inet6_address),t.length>0&&(e.address=t,delete e.inet4_address,delete e.inet6_address);const n=[];Array.isArray(e.inet4_route_address)&&n.push(...e.inet4_route_address),Array.isArray(e.inet6_route_address)&&n.push(...e.inet6_route_address),n.length>0&&(e.route_address=n,delete e.inet4_route_address,delete e.inet6_route_address);const s=[];Array.isArray(e.inet4_route_exclude_address)&&s.push(...e.inet4_route_exclude_address),Array.isArray(e.inet6_route_exclude_address)&&s.push(...e.inet6_route_exclude_address),s.length>0&&(e.route_exclude_address=s,delete e.inet4_route_exclude_address,delete e.inet6_route_exclude_address)}});const o=new Map,a=(e,t=!1)=>{Array.isArray(e)&&e.forEach(e=>{if(e.geosite){const t=Array.isArray(e.geosite)?e.geosite:[e.geosite];e.rule_set=t.map(e=>{const t=`geosite-${e}`;return o.has(t)||o.set(t,{tag:t,type:"remote",format:"binary",url:`https://gh.090227.xyz/https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${e}.srs`,download_detour:"DIRECT"}),t}),delete e.geosite}if(e.geoip){const t=Array.isArray(e.geoip)?e.geoip:[e.geoip];e.rule_set=e.rule_set||[],t.forEach(t=>{const n=`geoip-${t}`;o.has(n)||o.set(n,{tag:n,type:"remote",format:"binary",url:`https://gh.090227.xyz/https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-${t}.srs`,download_detour:"DIRECT"}),e.rule_set.push(n)}),delete e.geoip}const n=t?"server":"outbound",s=String(e[n]).toUpperCase();"REJECT"!==s&&"BLOCK"!==s||(e.action="reject",e.method="drop",delete e[n])})};r.dns&&r.dns.rules&&a(r.dns.rules,!0),r.route&&r.route.rules&&a(r.route.rules,!1),o.size>0&&(r.route||(r.route={}),r.route.rule_set=Array.from(o.values())),r.outbounds||(r.outbounds=[]),r.outbounds=r.outbounds.filter(e=>"REJECT"!==e.tag&&"block"!==e.tag);const i=new Set(r.outbounds.map(e=>e.tag));if(i.has("DIRECT")||(r.outbounds.push({type:"direct",tag:"DIRECT"}),i.add("DIRECT")),r.dns&&r.dns.servers){const e=new Set(r.dns.servers.map(e=>e.tag));r.dns.rules&&r.dns.rules.forEach(t=>{t.server&&!e.has(t.server)&&("dns_block"===t.server&&e.has("block")?t.server="block":t.server.toLowerCase().includes("block")&&!e.has(t.server)&&(r.dns.servers.push({tag:t.server,address:"rcode://success"}),e.add(t.server)))})}return r.outbounds.forEach(e=>{"selector"!==e.type&&"urltest"!==e.type||Array.isArray(e.outbounds)&&(e.outbounds=e.outbounds.filter(e=>{const t=e.toUpperCase();return i.has(e)&&"REJECT"!==t&&"BLOCK"!==t}),0===e.outbounds.length&&e.outbounds.push("DIRECT"))}),t&&r.outbounds.forEach(e=>{(e.uuid&&e.uuid===t||e.password&&e.password===t)&&(e.tls||(e.tls={enabled:!0}),n&&(e.tls.utls={enabled:!0,fingerprint:n}),s&&(e.tls.ech={enabled:!0,config:`-----BEGIN ECH CONFIGS-----\n${s}\n-----END ECH CONFIGS-----`}))}),JSON.stringify(r,null,2)}catch(t){return console.error("Singboxhotpatchexecutelinefailed:",t),JSON.stringify(JSON.parse(e),null,2)}}function Surgesubscribeconfigfilehotpatch(e,t,n){const s=e.includes("\r\n")?e.split("\r\n"):e.split("\n");let r="";const o=n.startuse0RTT?n.PATH+"?ed=2560":n.PATH;for(let e of s)if(!e.includes("= trojan,")||e.includes("ws=true")||e.includes("ws-path="))r+=e+"\n";else{const t=e.split("sni=")[1].split(",")[0],s=`sni=${t}, skip-cert-verify=${n.jumppasscertificateverify}`,a=`sni=${t}, skip-cert-verify=${n.jumppasscertificateverify}, ws=true, ws-path=${o}, ws-headers=Host:"${t}"`;r+=e.replace(new RegExp(s,"g"),a).replace("[","").replace("]","")+"\n"}return r=`#!MANAGED-CONFIG ${t} interval=${60*n.preferredsubscribegenerate.SUBUpdateTime*60} strict=false`+r.substring(r.indexOf("\n")),r}async function pleaserequestlogrecord(e,t,n,s="Get_SUB",r){try{const o=new Date,a={TYPE:s,IP:n,ASN:`AS${t.cf.asn||"0"} ${t.cf.asOrganization||"Unknown"}`,CC:`${t.cf.country||"N/A"} ${t.cf.city||"N/A"}`,URL:t.url,UA:t.headers.get("User-Agent")||"Unknown",TIME:o.getTime()};let i=[];const c=await e.KV.get("log.json");if(c)try{if(i=JSON.parse(c),Array.isArray(i))if("Get_SUB"!==s){const e=o.getTime()-18e5;if(i.some(s=>"Get_SUB"!==s.TYPE&&s.IP===n&&s.URL===t.url&&s.UA===(t.headers.get("User-Agent")||"Unknown")&&s.TIME>=e))return;for(i.push(a);JSON.stringify(i,null,2).length>4194304&&i.length>0;)i.shift()}else for(i.push(a);JSON.stringify(i,null,2).length>4194304&&i.length>0;)i.shift();else i=[a];if(r.TG.startuse)try{const t=await e.KV.get("tg.json"),n=JSON.parse(t);await sendMessage(n.BotToken,n.ChatID,a,r)}catch(e){console.error(`readtg.jsonouterror: ${e.message}`)}}catch(e){i=[a]}else i=[a];await e.KV.put("log.json",JSON.stringify(i,null,2))}catch(e){console.error(`logrecordfailed: ${e.message}`)}}async function sendMessage(e,t,n,s){if(e&&t)try{const r=new Date(n.TIME).toLocaleString("zh-CN",{timeZone:"Asia/Shanghai"}),o=new URL(n.URL),a=`<b>#${s.preferredsubscribegenerate.SUBNAME} logthroughknow</b>\n\n📌 <b>type:</b>#${n.TYPE}\n🌐 <b>IP:</b><code>${n.IP}</code>\n📍 <b>bitset:</b>${n.CC}\n🏢 <b>ASN:</b>${n.ASN}\n🔗 <b>domain:</b><code>${o.host}</code>\n🔍 <b>path:</b><code>${o.pathname+o.search}</code>\n🤖 <b>UA:</b><code>${n.UA}</code>\n📅 <b>time:</b>${r}\n`+(s.CF.Usage.success?`📊 <b>pleaserequestuseamount:</b>${s.CF.Usage.total}/100000 <b>${(s.CF.Usage.total/1e5*100).toFixed(2)}%</b>\n`:""),i=`https://api.telegram.org/bot${e}/sendMessage?chat_id=${t}&parse_mode=HTML&text=${encodeURIComponent(a)}`;return fetch(i,{method:"GET",headers:{Accept:"text/html,application/xhtml+xml,application/xml;","Accept-Encoding":"gzip, deflate, br","User-Agent":n.UA||"Unknown"}})}catch(e){console.error("Error sending message:",e)}}function maskcodesensitiveinfo(e,t=3,n=2){if(!e||"string"!=typeof e)return e;if(e.length<=t+n)return e;const s=e.slice(0,t),r=e.slice(-n),o=e.length-t-n;return`${s}${"*".repeat(o)}${r}`}async function MD5MD5(e){const t=new TextEncoder,n=await crypto.subtle.digest("MD5",t.encode(e)),s=Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,"0")).join(""),r=await crypto.subtle.digest("MD5",t.encode(s.slice(7,27)));return Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,"0")).join("").toLowerCase()}function randompath(){const e=Math.floor(3*Math.random()+1);return`/${["about","account","acg","act","activity","ad","ads","ajax","album","albums","anime","api","app","apps","archive","archives","article","articles","ask","auth","avatar","bbs","bd","blog","blogs","book","books","bt","buy","cart","category","categories","cb","channel","channels","chat","china","city","class","classify","clip","clips","club","cn","code","collect","collection","comic","comics","community","company","config","contact","content","course","courses","cp","data","detail","details","dh","directory","discount","discuss","dl","dload","doc","docs","document","documents","doujin","download","downloads","drama","edu","en","ep","episode","episodes","event","events","f","faq","favorite","favourites","favs","feedback","file","files","film","films","forum","forums","friend","friends","game","games","gif","go","go.html","go.php","group","groups","help","home","hot","htm","html","image","images","img","index","info","intro","item","items","ja","jp","jump","jump.html","jump.php","jumping","knowledge","lang","lesson","lessons","lib","library","link","links","list","live","lives","m","mag","magnet","mall","manhua","map","member","members","message","messages","mobile","movie","movies","music","my","new","news","note","novel","novels","online","order","out","out.html","out.php","outbound","p","page","pages","pay","payment","pdf","photo","photos","pic","pics","picture","pictures","play","player","playlist","post","posts","product","products","program","programs","project","qa","question","rank","ranking","read","readme","redirect","redirect.html","redirect.php","reg","register","res","resource","retrieve","sale","search","season","seasons","section","seller","series","service","services","setting","settings","share","shop","show","shows","site","soft","sort","source","special","star","stars","static","stock","store","stream","streaming","streams","student","study","tag","tags","task","teacher","team","tech","temp","test","thread","tool","tools","topic","topics","torrent","trade","travel","tv","txt","type","u","upload","uploads","url","urls","user","users","v","version","video","videos","view","vip","vod","watch","web","wenku","wiki","work","www","zh","zh-cn","zh-tw","zip"].sort(()=>.5-Math.random()).slice(0,e).join("/")}`}function randomreplacechangethroughconfigsymbol(e){if(!e?.includes("*"))return e;return e.replace(/\*/g,()=>{let e="";for(let t=0;t<Math.floor(14*Math.random())+3;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e})}function batchamountreplacechangedomain(e,t,n=2){const s=[...t].sort(()=>Math.random()-.5);let r=0,o=null;return e.replace(/example\.com/g,()=>(r%n===0&&(o=randomreplacechangethroughconfigsymbol(s[Math.floor(r/n)%s.length])),r++,o))}async function getECH(e){try{const t=await fetch(`https://1.1.1.1/dns-query?name=${encodeURIComponent(e)}&type=65`,{headers:{accept:"application/dns-json"}}),n=await t.json();if(!n.Answer?.length)return"";for(let e of n.Answer){if(65!==e.type||!e.data)continue;const t=e.data.match(/ech=([^\s]+)/);if(t)return t[1].replace(/"/g,"");if(e.data.startsWith("\\#")){const t=e.data.split(" ").slice(2).join(""),n=new Uint8Array(t.match(/.{1,2}/g).map(e=>parseInt(e,16)));let s=2;for(;s<n.length&&0!==n[s++];)s+=n[s-1];for(;s+4<=n.length;){const e=n[s]<<8|n[s+1],t=n[s+2]<<8|n[s+3];if(s+=4,5===e)return btoa(String.fromCharCode(...n.slice(s,s+t)));s+=t}}}return""}catch{return""}}async function readconfig_JSON(e,t,n,s,r=!1){const o=t,a=performance.now(),i={TIME:(new Date).toISOString(),HOST:o,HOSTS:[t],UUID:n,protocoltype:"vless",transmittransferprotocol:"ws",jumppasscertificateverify:!0,startuse0RTT:!1,TLSsplitslice:null,randompath:!1,ECH:!1,Fingerprint:"chrome",preferredsubscribegenerate:{local:!0,localIPlib:{randomIP:!0,randomnumberamount:16,pointfixedport:-1},SUB:null,SUBNAME:"edgetunnel",SUBUpdateTime:3,TOKEN:await MD5MD5(t+n)},subscribeconvertconfig:{SUBAPI:"https://SUBAPI.cmliussss.net",SUBCONFIG:"https://raw.githubusercontent.com/cmliu/ACL4SSR/refs/heads/main/Clash/config/ACL4SSR_Online_Mini_MultiMode_CF.ini",SUBEMOJI:!1},reversedelegate:{PROXYIP:"auto",SOCKS5:{startuse:enableSocks5Proxy,global:enableGlobalSocks5,accountid:mySocks5Account,whitenamelist:socks5Whitelist}},TG:{startuse:!1,BotToken:null,ChatID:null},CF:{Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null,Usage:{success:!1,pages:0,workers:0,total:0,max:1e5}}};try{let t=await e.KV.get("config.json");t&&1!=r?config_JSON=JSON.parse(t):(await e.KV.put("config.json",JSON.stringify(i,null,2)),config_JSON=i)}catch(e){console.error(`readconfig_JSONouterror: ${e.message}`),config_JSON=i}config_JSON.HOST=o,config_JSON.HOSTS||(config_JSON.HOSTS=[t]),e.HOST&&(config_JSON.HOSTS=(await parseToArray(e.HOST)).map(e=>e.toLowerCase().replace(/^https?:\/\//,"").split("/")[0].split(":")[0])),config_JSON.UUID=n,config_JSON.PATH=s?s.startsWith("/")?s:"/"+s:config_JSON.reversedelegate.SOCKS5.startuse?"/"+config_JSON.reversedelegate.SOCKS5.startuse+(config_JSON.reversedelegate.SOCKS5.global?"://":"=")+config_JSON.reversedelegate.SOCKS5.accountid:"auto"===config_JSON.reversedelegate.PROXYIP?"/":`/proxyip=${config_JSON.reversedelegate.PROXYIP}`;const c="Shadowrocket"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("1,40-60,30-50,tlshello")}`:"Happ"==config_JSON.TLSsplitslice?`&fragment=${encodeURIComponent("3,1,tlshello")}`:"";config_JSON.Fingerprint||(config_JSON.Fingerprint="chrome"),config_JSON.ECH?config_JSON.preferredsubscribegenerate.SUBUpdateTime=1:config_JSON.ECH=!1;const l=config_JSON.ECH?`&ech=${encodeURIComponent("cloudflare-ech.com+"+ECH_DOH)}`:"";config_JSON.LINK=`${config_JSON.protocoltype}://${n}@${o}:443?security=tls&type=${config_JSON.transmittransferprotocol+l}&host=${o}&fp=${config_JSON.Fingerprint}&sni=${o}&path=${encodeURIComponent(config_JSON.startuse0RTT?config_JSON.PATH+"?ed=2560":config_JSON.PATH)+c}&encryption=none${config_JSON.jumppasscertificateverify?"&insecure=1&allowInsecure=1":""}#${encodeURIComponent(config_JSON.preferredsubscribegenerate.SUBNAME)}`,config_JSON.preferredsubscribegenerate.TOKEN=await MD5MD5(t+n);const d={BotToken:null,ChatID:null};config_JSON.TG={startuse:!!config_JSON.TG.startuse&&config_JSON.TG.startuse,...d};try{const t=await e.KV.get("tg.json");if(t){const e=JSON.parse(t);config_JSON.TG.ChatID=e.ChatID?e.ChatID:null,config_JSON.TG.BotToken=e.BotToken?maskcodesensitiveinfo(e.BotToken):null}else await e.KV.put("tg.json",JSON.stringify(d,null,2))}catch(e){console.error(`readtg.jsonouterror: ${e.message}`)}const u={Email:null,GlobalAPIKey:null,AccountID:null,APIToken:null,UsageAPI:null};config_JSON.CF={...u,Usage:{success:!1,pages:0,workers:0,total:0,max:1e5}};try{const t=await e.KV.get("cf.json");if(t){const e=JSON.parse(t);if(e.UsageAPI)try{const t=await fetch(e.UsageAPI),n=await t.json();config_JSON.CF.Usage=n}catch(e){console.error(`pleaserequest CF_JSON.UsageAPI failed: ${e.message}`)}else{config_JSON.CF.Email=e.Email?e.Email:null,config_JSON.CF.GlobalAPIKey=e.GlobalAPIKey?maskcodesensitiveinfo(e.GlobalAPIKey):null,config_JSON.CF.AccountID=e.AccountID?maskcodesensitiveinfo(e.AccountID):null,config_JSON.CF.APIToken=e.APIToken?maskcodesensitiveinfo(e.APIToken):null,config_JSON.CF.UsageAPI=null;const t=await getCloudflareUsage(e.Email,e.GlobalAPIKey,e.AccountID,e.APIToken);config_JSON.CF.Usage=t}}else await e.KV.put("cf.json",JSON.stringify(u,null,2))}catch(e){console.error(`readcf.jsonouterror: ${e.message}`)}return config_JSON.plusloadtime=(performance.now()-a).toFixed(2)+"ms",config_JSON}async function generaterandomIP(e,t=16,n=-1){const s={9808:"cmcc",4837:"cu",4134:"ct"},r=e.cf.asn,o=s[r]?`https://raw.githubusercontent.com/cmliu/cmliu/main/CF-CIDR/${s[r]}.txt`:"https://raw.githubusercontent.com/cmliu/cmliu/main/CF-CIDR.txt",a={9808:"CFmovemovepreferred",4837:"CFconnectthroughpreferred",4134:"CFtelecompreferred"}[r]||"CFofficialmethodpreferred",i=[443,2053,2083,2087,2096,8443];let c=[];try{const e=await fetch(o);c=e.ok?await parseToArray(await e.text()):["104.16.0.0/13"]}catch{c=["104.16.0.0/13"]}const l=Array.from({length:t},()=>`${(e=>{const[t,n]=e.split("/"),s=32-parseInt(n),r=((t.split(".").reduce((e,t,n)=>e|parseInt(t)<<24-8*n,0)&4294967295<<s>>>0)>>>0)+Math.floor(Math.random()*Math.pow(2,s))>>>0;return[r>>>24&255,r>>>16&255,r>>>8&255,255&r].join(".")})(c[Math.floor(Math.random()*c.length)])}:${-1===n?i[Math.floor(Math.random()*i.length)]:n}#${a}`);return[l,l.join("\n")]}async function parseToArray(e){var t=e.replace(/[ "'\r\n]+/g,",").replace(/,+/g,",");","==t.charAt(0)&&(t=t.slice(1)),","==t.charAt(t.length-1)&&(t=t.slice(0,t.length-1));return t.split(",")}function isValidBase64(e){if("string"!=typeof e)return!1;const t=e.replace(/\s/g,"");if(0===t.length||t.length%4!=0)return!1;if(!/^[A-Za-z0-9+/]+={0,2}$/.test(t))return!1;try{return atob(t),!0}catch{return!1}}function base64Decode(e){const t=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));return new TextDecoder("utf-8").decode(t)}async function pleaserequestpreferredAPI(e,t="443",n=3e3){if(!e?.length)return[[],[],[]];const s=new Set;let r="";await Promise.allSettled(e.map(async e=>{try{const o=new AbortController,a=setTimeout(()=>o.abort(),n),i=await fetch(e,{signal:o.signal});clearTimeout(a);let c="";try{const e=await i.arrayBuffer(),t=(i.headers.get("content-type")||"").toLowerCase(),n=t.match(/charset=([^\s;]+)/i)?.[1]?.toLowerCase()||"";let s=["utf-8","gb2312"];(n.includes("gb")||n.includes("gbk")||n.includes("gb2312"))&&(s=["gb2312","utf-8"]);let r=!1;for(const t of s)try{const n=new TextDecoder(t).decode(e);if(n&&n.length>0&&!n.includes("<22>")){c=n,r=!0;break}if(n&&n.length>0)continue}catch(e){continue}if(r||(c=await i.text()),!c||0===c.trim().length)return}catch(e){return void console.error("Failed to decode response:",e)}const l=isValidBase64(c)?base64Decode(c):c;if(l.split("#")[0].includes("://"))return void(r+=l+"\n");const d=c.trim().split("\n").map(e=>e.trim()).filter(e=>e),u=d.length>1&&d[0].includes(","),p=/^[^\[\]]*:[^\[\]]*:[^\[\]]/;if(u){const n=d[0].split(",").map(e=>e.trim()),r=d.slice(1);if(n.includes("IPplaceaddress")&&n.includes("port")&&n.includes("dataincenter")){const e=n.indexOf("IPplaceaddress"),t=n.indexOf("port"),o=n.indexOf("country")>-1?n.indexOf("country"):n.indexOf("city")>-1?n.indexOf("city"):n.indexOf("dataincenter"),a=n.indexOf("TLS");r.forEach(n=>{const r=n.split(",").map(e=>e.trim());if(-1!==a&&"true"!==r[a]?.toLowerCase())return;const i=p.test(r[e])?`[${r[e]}]`:r[e];s.add(`${i}:${r[t]}#${r[o]}`)})}else if(n.some(e=>e.includes("IP"))&&n.some(e=>e.includes("delay"))&&n.some(e=>e.includes("downloadspeed"))){const o=n.findIndex(e=>e.includes("IP")),a=n.findIndex(e=>e.includes("delay")),i=n.findIndex(e=>e.includes("downloadspeed")),c=new URL(e).searchParams.get("port")||t;r.forEach(e=>{const t=e.split(",").map(e=>e.trim()),n=p.test(t[o])?`[${t[o]}]`:t[o];s.add(`${n}:${c}#CFpreferred ${t[a]}ms ${t[i]}MB/s`)})}}else d.forEach(n=>{const r=n.indexOf("#"),[o,a]=r>-1?[n.substring(0,r),n.substring(r)]:[n,""];let i=!1;if(o.startsWith("["))i=/\]:(\d+)$/.test(o);else{const e=o.lastIndexOf(":");i=e>-1&&/^\d+$/.test(o.substring(e+1))}const c=new URL(e).searchParams.get("port")||t;s.add(i?n:`${o}:${c}${a}`)})}catch(e){}}));const o=r.trim()?[...new Set(r.split(/\r?\n/).filter(e=>""!==e.trim()))]:[];return[Array.from(s),o,[]]}async function reversedelegateparamsget(e){const t=new URL(e.url),{pathname:n,searchParams:s}=t,r=n.toLowerCase();mySocks5Account=s.get("socks5")||s.get("http")||null,enableGlobalSocks5=s.has("globalproxy")||!1;const o=r.match(/\/(proxyip[.=]|pyip=|ip=)(.+)/);if(s.has("proxyip")){const e=s.get("proxyip");return proxyIP=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(enableProxyFallback=!1)}if(o){const e="proxyip."===o[1]?`proxyip.${o[2]}`:o[2];return proxyIP=e.includes(",")?e.split(",")[Math.floor(Math.random()*e.split(",").length)]:e,void(enableProxyFallback=!1)}let a;if(a=n.match(/\/(socks5?|http):\/?\/?(.+)/i)){if(enableSocks5Proxy="http"===a[1].toLowerCase()?"http":"socks5",mySocks5Account=a[2].split("#")[0],enableGlobalSocks5=!0,mySocks5Account.includes("@")){const e=mySocks5Account.lastIndexOf("@");let t=mySocks5Account.substring(0,e).replaceAll("%3D","=");/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i.test(t)&&!t.includes(":")&&(t=atob(t)),mySocks5Account=`${t}@${mySocks5Account.substring(e+1)}`}}else if(a=n.match(/\/(g?s5|socks5|g?http)=(.+)/i)){const e=a[1].toLowerCase();mySocks5Account=a[2],enableSocks5Proxy=e.includes("http")?"http":"socks5",enableGlobalSocks5=e.startsWith("g")||enableGlobalSocks5}if(mySocks5Account)try{parsedSocks5Address=await getSOCKS5accountid(mySocks5Account),enableSocks5Proxy=s.get("http")?"http":enableSocks5Proxy}catch(e){console.error("parseSOCKS5placeaddressfailed:",e.message),enableSocks5Proxy=null}else enableSocks5Proxy=null}async function getSOCKS5accountid(e){if(e.includes("@")){const t=e.lastIndexOf("@");let n=e.substring(0,t).replaceAll("%3D","=");/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i.test(n)&&!n.includes(":")&&(n=atob(n)),e=`${n}@${e.substring(t+1)}`}const t=e.lastIndexOf("@"),[n,s]=-1===t?[e,void 0]:[e.substring(t+1),e.substring(0,t)];let r,o,a,i;if(s&&([r,o]=s.split(":"),!o))throw new Error('invalid SOCKS placeaddressformat:confirmcertpartsplitmustis "username:password" formstyle');if(n.includes("]:"))[a,i]=[n.split("]:")[0]+"]",Number(n.split("]:")[1].replace(/[^\d]/g,""))];else if(n.startsWith("["))[a,i]=[n,80];else{const e=n.split(":");[a,i]=2===e.length?[e[0],Number(e[1].replace(/[^\d]/g,""))]:[n,80]}if(isNaN(i))throw new Error("invalid SOCKS placeaddressformat:portidmustisnumberchar");if(a.includes(":")&&!/^\[.*\]$/.test(a))throw new Error("invalid SOCKS placeaddressformat:IPv6 placeaddressmustusemethodbracketidbracketup,if [2001:db8::1]");return{username:r,password:o,hostname:a,port:i}}async function getCloudflareUsage(e,t,n,s){const r="https://api.cloudflare.com/client/v4",o=e=>e?.reduce((e,t)=>e+(t?.sum?.requests||0),0)||0,a={"Content-Type":"application/json"};try{if(!(n||e&&t))return{success:!1,pages:0,workers:0,total:0,max:1e5};if(!n){const s=await fetch(`${r}/accounts`,{method:"GET",headers:{...a,"X-AUTH-EMAIL":e,"X-AUTH-KEY":t}});if(!s.ok)throw new Error(`accountusergetfailed: ${s.status}`);const o=await s.json();if(!o?.result?.length)throw new Error("notfindtoaccountuser");const i=o.result.findIndex(t=>t.name?.toLowerCase().startsWith(e.toLowerCase()));n=o.result[i>=0?i:0]?.id}const i=new Date;i.setUTCHours(0,0,0,0);const c=s?{...a,Authorization:`Bearer ${s}`}:{...a,"X-AUTH-EMAIL":e,"X-AUTH-KEY":t},l=await fetch(`${r}/graphql`,{method:"POST",headers:c,body:JSON.stringify({query:"query getBillingMetrics($AccountID: String!, $filter: AccountWorkersInvocationsAdaptiveFilter_InputObject) {\n viewer { accounts(filter: {accountTag: $AccountID}) {\n pagesFunctionsInvocationsAdaptiveGroups(limit: 1000, filter: $filter) { sum { requests } }\n workersInvocationsAdaptive(limit: 10000, filter: $filter) { sum { requests } }\n } }\n }",variables:{AccountID:n,filter:{datetime_geq:i.toISOString(),datetime_leq:(new Date).toISOString()}}})});if(!l.ok)throw new Error(`queryfailed: ${l.status}`);const d=await l.json();if(d.errors?.length)throw new Error(d.errors[0].message);const u=d?.data?.viewer?.accounts?.[0];if(!u)throw new Error("notfindtoaccountuserdata");const p=o(u.pagesFunctionsInvocationsAdaptiveGroups),f=o(u.workersInvocationsAdaptive),h=p+f,g=1e5;return console.log(`statsresult - Pages: ${p}, Workers: ${f}, totalcount: ${h}, uplimit: 100000`),{success:!0,pages:p,workers:f,total:h,max:g}}catch(e){return console.error("getmakeuseamounterror:",e.message),{success:!1,pages:0,workers:0,total:0,max:1e5}}}function sha224(e){const t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],n=(e,t)=>(e>>>t|e<<32-t)>>>0,s=8*(e=unescape(encodeURIComponent(e))).length;for(e+=String.fromCharCode(128);8*e.length%512!=448;)e+=String.fromCharCode(0);const r=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],o=Math.floor(s/4294967296),a=4294967295&s;e+=String.fromCharCode(o>>>24&255,o>>>16&255,o>>>8&255,255&o,a>>>24&255,a>>>16&255,a>>>8&255,255&a);const i=[];for(let t=0;t<e.length;t+=4)i.push(e.charCodeAt(t)<<24|e.charCodeAt(t+1)<<16|e.charCodeAt(t+2)<<8|e.charCodeAt(t+3));for(let e=0;e<i.length;e+=16){const s=new Array(64).fill(0);for(let t=0;t<16;t++)s[t]=i[e+t];for(let e=16;e<64;e++){const t=n(s[e-15],7)^n(s[e-15],18)^s[e-15]>>>3,r=n(s[e-2],17)^n(s[e-2],19)^s[e-2]>>>10;s[e]=s[e-16]+t+s[e-7]+r>>>0}let[o,a,c,l,d,u,p,f]=r;for(let e=0;e<64;e++){const r=f+(n(d,6)^n(d,11)^n(d,25))+(d&u^~d&p)+t[e]+s[e]>>>0,i=o&a^o&c^a&c;f=p,p=u,u=d,d=l+r>>>0,l=c,c=a,a=o,o=r+((n(o,2)^n(o,13)^n(o,22))+i>>>0)>>>0}for(let e=0;e<8;e++)r[e]=r[e]+(0===e?o:1===e?a:2===e?c:3===e?l:4===e?d:5===e?u:6===e?p:f)>>>0}let c="";for(let e=0;e<7;e++)for(let t=24;t>=0;t-=8)c+=(r[e]>>>t&255).toString(16).padStart(2,"0");return c}async function parseplaceaddressport(e,t="dash.cloudflare.com",n="00000000-0000-4000-8000-000000000000"){if(cacheproxyIP&&cachedProxyArray&&cacheproxyIP===e)console.log(`[reversedelegateparse] readcache totalnumber: ${cachedProxyArray.length}one\n${cachedProxyArray.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`);else{async function s(e,t){try{const n=await fetch(`https://1.1.1.1/dns-query?name=${e}&type=${t}`,{headers:{Accept:"application/dns-json"}});if(!n.ok)return[];return(await n.json()).Answer||[]}catch(e){return console.error(`DoHqueryfailed (${t}):`,e),[]}}function r(e){let t=e,n=443;if(e.includes("]:")){const s=e.split("]:");t=s[0]+"]",n=parseInt(s[1],10)||n}else if(e.includes(":")&&!e.startsWith("[")){const s=e.lastIndexOf(":");t=e.slice(0,s),n=parseInt(e.slice(s+1),10)||n}return[t,n]}let o=[];if((e=e.toLowerCase()).includes(".william"))try{const d=(await s(e,"TXT")).filter(e=>16===e.type).map(e=>e.data);if(d.length>0){let u=d[0];u.startsWith('"')&&u.endsWith('"')&&(u=u.slice(1,-1));o=u.replace(/\\010/g,",").replace(/\n/g,",").split(",").map(e=>e.trim()).filter(Boolean).map(e=>r(e))}}catch(p){console.error("parseWilliamdomainfailed:",p)}else{let[f,h]=r(e);if(e.includes(".tp")){const m=e.match(/\.tp(\d+)/);m&&(h=parseInt(m[1],10))}const g=/^\[?([a-fA-F0-9:]+)\]?$/;if(/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/.test(f)||g.test(f))o=[[f,h]];else{const[y,w]=await Promise.all([s(f,"A"),s(f,"AAAA")]),b=[...y.filter(e=>1===e.type).map(e=>e.data),...w.filter(e=>28===e.type).map(e=>`[${e.data}]`)];o=b.length>0?b.map(e=>[e,h]):[[f,h]]}}const a=o.sort((e,t)=>e[0].localeCompare(t[0])),i=t.includes(".")?t.split(".").slice(-2).join("."):t;let c=[...i+n].reduce((e,t)=>e+t.charCodeAt(0),0);console.log(`[reversedelegateparse] randomseed: ${c}\ntargetstationpoint: ${i}`);const l=[...a].sort(()=>(c=1103515245*c+12345&2147483647)/2147483647-.5);cachedProxyArray=l.slice(0,8),console.log(`[reversedelegateparse] parsecomplete totalnumber: ${cachedProxyArray.length}one\n${cachedProxyArray.map(([e,t],n)=>`${n+1}. ${e}:${t}`).join("\n")}`),cacheproxyIP=e}return cachedProxyArray}async function SOCKS5canuseabilityverify(e="socks5",t){const n=Date.now();try{parsedSocks5Address=await getSOCKS5accountid(t)}catch(s){return{success:!1,error:s.message,proxy:e+"://"+t,responseTime:Date.now()-n}}const{username:s,password:r,hostname:o,port:a}=parsedSocks5Address,i=s&&r?`${s}:${r}@${o}:${a}`:`${o}:${a}`;try{const t=new Uint8Array(0),s="socks5"==e?await socks5Connect("check.socks5.090227.xyz",80,t):await httpConnect("check.socks5.090227.xyz",80,t);if(!s)return{success:!1,error:"nonemethodconnectiontoproxyservicehandler",proxy:e+"://"+i,responseTime:Date.now()-n};try{const t=s.writable.getWriter(),r=new TextEncoder;await t.write(r.encode("GET /cdn-cgi/trace HTTP/1.1\r\nHost: check.socks5.090227.xyz\r\nConnection: close\r\n\r\n")),t.releaseLock();const o=s.readable.getReader(),a=new TextDecoder;let c="";try{for(;;){const{done:e,value:t}=await o.read();if(e)break;c+=a.decode(t,{stream:!0})}}finally{o.releaseLock()}return await s.close(),{success:!0,proxy:e+"://"+i,ip:c.match(/ip=(.*)/)[1],loc:c.match(/loc=(.*)/)[1],responseTime:Date.now()-n}}catch(t){try{await s.close()}catch(e){console.log("closeconnectionwhenouterror:",e)}return{success:!1,error:t.message,proxy:e+"://"+i,responseTime:Date.now()-n}}}catch(t){return{success:!1,error:t.message,proxy:e+"://"+i,responseTime:Date.now()-n}}}async function nginx(){return'\n\t<!DOCTYPE html>\n\t<html>\n\t<head>\n\t<title>Welcome to nginx!</title>\n\t<style>\n\t\tbody {\n\t\t\twidth: 35em;\n\t\t\tmargin: 0 auto;\n\t\t\tfont-family: Tahoma, Verdana, Arial, sans-serif;\n }\n </style>\n</head>\n<body>\n\t<h1>Welcome to nginx!</h1>\n\t<p>If you see this page, the nginx web server is successfully installed and\n\tworking. Further configuration is required.</p>\n\t\n\t<p>For online documentation and support please refer to\n\t<a href="http://nginx.org/">nginx.org</a>.<br/>\n\tCommercial support is available at\n\t<a href="http://nginx.com/">nginx.com</a>.</p>\n\t\n\t<p><em>Thank you for using nginx.</em></p>\n\t</body>\n\t</html>\n\t'}async function html1101(e,t){const n=new Date,s=n.getFullYear()+"-"+String(n.getMonth()+1).padStart(2,"0")+"-"+String(n.getDate()).padStart(2,"0")+" "+String(n.getHours()).padStart(2,"0")+":"+String(n.getMinutes()).padStart(2,"0")+":"+String(n.getSeconds()).padStart(2,"0"),r=Array.from(crypto.getRandomValues(new Uint8Array(8))).map(e=>e.toString(16).padStart(2,"0")).join("");return`<!DOCTYPE html>\n\x3c!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if IE 7]> <html class="no-js ie7 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if IE 8]> <html class="no-js ie8 oldie" lang="en-US"> <![endif]--\x3e\n\x3c!--[if gt IE 8]>\x3c!--\x3e <html class="no-js" lang="en-US"> \x3c!--<![endif]--\x3e\n<head>\n<title>Worker threw exception | ${e} | Cloudflare</title>\n<meta charset="UTF-8" />\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\n<meta http-equiv="X-UA-Compatible" content="IE=Edge" />\n<meta name="robots" content="noindex, nofollow" />\n<meta name="viewport" content="width=device-width,initial-scale=1" />\n<link rel="stylesheet" id="cf_styles-css" href="/cdn-cgi/styles/cf.errors.css" />\n\x3c!--[if lt IE 9]><link rel="stylesheet" id='cf_styles-ie-css' href="/cdn-cgi/styles/cf.errors.ie.css" /><![endif]--\x3e\n<style>body{margin:0;padding:0}</style>\n\n\n\x3c!--[if gte IE 10]>\x3c!--\x3e\n<script>\n if (!navigator.cookieEnabled) {\n window.addEventListener('DOMContentLoaded', function () {\n var cookieEl = document.getElementById('cookie-alert');\n cookieEl.style.display = 'block';\n })\n }\n<\/script>\n\x3c!--<![endif]--\x3e\n\n</head>\n<body>\n <div id="cf-wrapper">\n <div class="cf-alert cf-alert-error cf-cookie-error" id="cookie-alert" data-translate="enable_cookies">Please enable cookies.</div>\n <div id="cf-error-details" class="cf-error-details-wrapper">\n <div class="cf-wrapper cf-header cf-error-overview">\n <h1>\n <span class="cf-error-type" data-translate="error">Error</span>\n <span class="cf-error-code">1101</span>\n <small class="heading-ray-id">Ray ID: ${r} • ${s} UTC</small>\n </h1>\n <h2 class="cf-subheadline" data-translate="error_desc">Worker threw exception</h2>\n </div>\x3c!-- /.header --\x3e\n \n <section></section>\x3c!-- spacer --\x3e\n \n <div class="cf-section cf-wrapper">\n <div class="cf-columns two">\n <div class="cf-column">\n <h2 data-translate="what_happened">What happened?</h2>\n <p>You've requested a page on a website (${e}) that is on the <a href="https://www.cloudflare.com/5xx-error-landing?utm_source=error_100x" target="_blank">Cloudflare</a> network. An unknown error occurred while rendering the page.</p>\n </div>\n \n <div class="cf-column">\n <h2 data-translate="what_can_i_do">What can I do?</h2>\n <p><strong>If you are the owner of this website:</strong><br />refer to <a href="https://developers.cloudflare.com/workers/observability/errors/" target="_blank">Workers - Errors and Exceptions</a> and check Workers Logs for ${e}.</p>\n </div>\n \n </div>\n </div>\x3c!-- /.section --\x3e\n \n <div class="cf-error-footer cf-wrapper w-240 lg:w-full py-10 sm:py-4 sm:px-8 mx-auto text-center sm:text-left border-solid border-0 border-t border-gray-300">\n <p class="text-13">\n <span class="cf-footer-item sm:block sm:mb-1">Cloudflare Ray ID: <strong class="font-semibold"> ${r}</strong></span>\n <span class="cf-footer-separator sm:hidden">•</span>\n <span id="cf-footer-item-ip" class="cf-footer-item hidden sm:block sm:mb-1">\n Your IP:\n <button type="button" id="cf-footer-ip-reveal" class="cf-footer-ip-reveal-btn">Click to reveal</button>\n <span class="hidden" id="cf-footer-ip">${t}</span>\n <span class="cf-footer-separator sm:hidden">•</span>\n </span>\n <span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> <a rel="noopener noreferrer" href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" target="_blank">Cloudflare</a></span>\n \n </p>\n <script>(function(){function d(){var b=a.getElementById("cf-footer-item-ip"),c=a.getElementById("cf-footer-ip-reveal");b&&"classList"in b&&(b.classList.remove("hidden"),c.addEventListener("click",function(){c.classList.add("hidden");a.getElementById("cf-footer-ip").classList.remove("hidden")}))}var a=document;document.addEventListener&&a.addEventListener("DOMContentLoaded",d)})();<\/script>\n </div>\x3c!-- /.error-footer --\x3e\n\n </div>\x3c!-- /#cf-error-details --\x3e\n </div>\x3c!-- /#cf-wrapper --\x3e\n\n <script>\n window._cf_translation = {};\n \n \n <\/script> \n</body>\n</html>`} |