@fudrouter/fsrouter 0.6.74 → 0.6.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/routes/headroom/extras/route.js +2 -2
- package/package.json +1 -1
- package/public/assets/EndpointPageClient.BnlQVTIB.js +6 -0
- package/public/assets/{Loading.BHPtQ9vj.js → Loading.C1il44u0.js} +1 -1
- package/public/assets/{NoAuthProxyCard.BDcXaWvM.js → NoAuthProxyCard.WHGGEUIp.js} +1 -1
- package/public/assets/{index.Be3gbrBl.js → index.D4FwOBBU.js} +2 -2
- package/public/assets/{page.DiL4Gwqe.js → page.0Rt4rWPG.js} +1 -1
- package/public/assets/{page.B3QqvLep.js → page.1numFcXc.js} +1 -1
- package/public/assets/{page.C8sLEMa6.js → page.1w9bTOPd.js} +1 -1
- package/public/assets/{page.tE7PpWYW.js → page.3ARdH6tE.js} +1 -1
- package/public/assets/{page.B-dzeIUC.js → page.A4gD6oiw.js} +1 -1
- package/public/assets/{page.C6bYizL7.js → page.AhxgKhsm.js} +1 -1
- package/public/assets/{page.BFb7yUd8.js → page.B1og8_GD.js} +1 -1
- package/public/assets/{page.11hpNKmq.js → page.B5nk3H0f.js} +1 -1
- package/public/assets/{page.BgGJovOg.js → page.BGDrqCcI.js} +1 -1
- package/public/assets/{page.uziaGZsT.js → page.BJIIZWfZ.js} +1 -1
- package/public/assets/{page.Dl1apZE2.js → page.BdB6udZG.js} +1 -1
- package/public/assets/{page.sUIPWIiF.js → page.BfGkHTDS.js} +1 -1
- package/public/assets/{page.Df9qtrdG.js → page.Bfr4417O.js} +1 -1
- package/public/assets/{page.N1x4YL8_.js → page.BpcyRUKz.js} +1 -1
- package/public/assets/{page.CyUqJPmx.js → page.BvcbHe5b.js} +1 -1
- package/public/assets/{page.B-LxsnqU.js → page.C6WsIDgW.js} +1 -1
- package/public/assets/{page.P2Ny5veR.js → page.CCEJ5tPH.js} +1 -1
- package/public/assets/{page.Cged1bOZ.js → page.CMUifPIU.js} +1 -1
- package/public/assets/{page.HV0w1d5C.js → page.CR7Yees9.js} +1 -1
- package/public/assets/{page.B-nBR75u.js → page.CXCEdPh6.js} +1 -1
- package/public/assets/{page.B8xdkCWA.js → page.CsroRewc.js} +1 -1
- package/public/assets/{page.CF_YSLwP.js → page.CtLa-V_T.js} +1 -1
- package/public/assets/{page.C0gBvR4O.js → page.DINPUA6N.js} +1 -1
- package/public/assets/{page.BdS20a1O.js → page.DSEK9UW0.js} +1 -1
- package/public/assets/{page.CrBl7f8N.js → page.DSTzvOQ8.js} +1 -1
- package/public/assets/{page.fOOCr18J.js → page.DT7cpJ8d.js} +1 -1
- package/public/assets/{page.CpvXDkQF.js → page.DT_RnrSs.js} +1 -1
- package/public/assets/{page.Ch647dVk.js → page.DU7jwIPk.js} +1 -1
- package/public/assets/{page.D8Rp8fFR.js → page.DcmbyZGV.js} +1 -1
- package/public/assets/{page.-lpNgYAw.js → page.DjguJpCk.js} +1 -1
- package/public/assets/{page.CvUFZzXr.js → page.Dr6yAoTO.js} +1 -1
- package/public/assets/{page.CCNsZBXp.js → page.FR_Izkgi.js} +1 -1
- package/public/assets/{page.CrP7niA2.js → page.GhgvWftU.js} +1 -1
- package/public/assets/{page.CPTtRDxw.js → page.UoGOSKkx.js} +1 -1
- package/public/assets/page.cAR8tR7Z.js +1 -0
- package/public/assets/{page.BfmI9KYe.js → page.feKgaG20.js} +1 -1
- package/public/assets/{page.CdMmlUEm.js → page.t4nKFefI.js} +1 -1
- package/public/index.html +1 -1
- package/public/assets/EndpointPageClient.C2WMTYy0.js +0 -6
- package/public/assets/page.BbPPdoas.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,u}from"./index.
|
|
1
|
+
import{j as e,u}from"./index.D4FwOBBU.js";import{C as l,B as d}from"./NoAuthProxyCard.WHGGEUIp.js";import"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";const c="nexusrouters/fsrouter",m="main",x="skills",h=`https://github.com/${c}`,f=`https://raw.githubusercontent.com/${c}/refs/heads/${m}/${x}`,b=`https://github.com/${c}/blob/${m}/${x}`,n=[{id:"fsrouter",name:"FSRouter (Entry)",description:"Setup + index of all capabilities. Start here — covers base URL, auth, model discovery, and links to every capability skill.",endpoint:null,icon:"hub",isEntry:!0},{id:"fsrouter-chat",name:"Chat",description:"Chat / code-gen via OpenAI or Anthropic format with streaming.",endpoint:"/v1/chat/completions",icon:"chat"},{id:"fsrouter-image",name:"Image Generation",description:"Text-to-image via DALL-E, Imagen, FLUX, MiniMax, SDWebUI…",endpoint:"/v1/images/generations",icon:"image"},{id:"fsrouter-tts",name:"Text-to-Speech",description:"OpenAI / ElevenLabs / Edge / Google / Deepgram voices.",endpoint:"/v1/audio/speech",icon:"record_voice_over"},{id:"fsrouter-stt",name:"Speech-to-Text",description:"Transcribe audio via OpenAI Whisper, Groq, Gemini, Deepgram, AssemblyAI…",endpoint:"/v1/audio/transcriptions",icon:"mic"},{id:"fsrouter-embeddings",name:"Embeddings",description:"Vectors for RAG / semantic search via OpenAI, Gemini, Mistral…",endpoint:"/v1/embeddings",icon:"scatter_plot"},{id:"fsrouter-web-search",name:"Web Search",description:"Tavily / Exa / Brave / Serper / SearXNG / Google PSE / You.com.",endpoint:"/v1/search",icon:"search"},{id:"fsrouter-web-fetch",name:"Web Fetch",description:"URL → markdown / text / HTML via Firecrawl, Jina, Tavily, Exa.",endpoint:"/v1/web/fetch",icon:"language"},{id:"using-superpowers",name:"Using Superpowers",description:"Use when starting any conversation — establishes how to find and use skills before ANY response.",endpoint:null,icon:"bolt"},{id:"multi-brain",name:"Multi-Brain Memory",description:"Share work and memory across Claude Code, OpenCode, Codex, and other agents via a two-level memory index.",endpoint:null,icon:"memory"}];function o(t){return`${f}/${t}/SKILL.md`}function g(t){return`${b}/${t}/SKILL.md`}function p({value:t,label:i="Copy link"}){const{copied:r,copy:s}=u(2e3);return e.jsxs("button",{onClick:()=>s(t),className:"px-2 py-1 rounded-md bg-primary text-white text-[11px] font-medium hover:bg-primary/90 transition-colors cursor-pointer shrink-0 inline-flex items-center gap-1",title:t,children:[e.jsx("span",{className:"material-symbols-outlined text-[12px]",children:r?"check":"content_copy"}),r?"Copied!":i]})}function a({skill:t}){const i=o(t.id);return e.jsxs("div",{className:`flex items-start gap-3 p-4 rounded-[14px] border shadow-[var(--shadow-soft)] transition-colors ${t.isEntry?"border-primary/40 bg-primary/5":"border-border-subtle bg-surface hover:bg-surface-2"}`,children:[e.jsx("div",{className:`size-9 rounded-lg flex items-center justify-center shrink-0 ${t.isEntry?"bg-primary text-white":"bg-primary/10 text-primary"}`,children:e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:t.icon})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h3",{className:"font-semibold text-sm text-text-main",children:t.name}),t.isEntry&&e.jsx(d,{variant:"primary",size:"sm",children:"START HERE"}),t.endpoint&&e.jsx(d,{variant:"default",size:"sm",children:e.jsx("code",{className:"text-[10px]",children:t.endpoint})})]}),e.jsx("p",{className:"text-xs text-text-muted mt-0.5",children:t.description}),e.jsxs("a",{href:g(t.id),target:"_blank",rel:"noreferrer",className:"text-[11px] text-text-muted hover:text-primary mt-1 inline-flex items-center gap-1 break-all",children:[i,e.jsx("span",{className:"material-symbols-outlined text-[12px]",children:"open_in_new"})]})]}),e.jsx(p,{value:i})]})}const y=["fsrouter-chat","fsrouter-image","fsrouter-tts","fsrouter-stt","fsrouter-embeddings","fsrouter-web-search","fsrouter-web-fetch"],j=["using-superpowers","multi-brain"];function L(){const t=n.find(s=>s.isEntry),i=n.filter(s=>y.includes(s.id)),r=n.filter(s=>j.includes(s.id));return e.jsxs("div",{className:"max-w-4xl mx-auto space-y-8",children:[e.jsx("div",{children:e.jsxs("div",{className:"flex items-center gap-3 mb-2",children:[e.jsx("div",{className:"size-10 rounded-xl bg-primary/10 flex items-center justify-center",children:e.jsx("span",{className:"material-symbols-outlined text-primary text-[22px]",children:"extension"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-bold text-text-main",children:"Agent Skills"}),e.jsx("p",{className:"text-sm text-text-muted",children:"Raw SKILL.md URLs to paste into any AI agent or coding assistant."})]})]})}),e.jsxs(l,{padding:"md",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px] text-primary",children:"rocket_launch"}),e.jsx("span",{className:"text-xs font-semibold text-text-main uppercase tracking-wide",children:"Quick Start — Paste this to your AI"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("div",{className:"flex-1 px-3 py-2 rounded-lg bg-surface-2 font-mono text-[12px] text-text-main border border-border-subtle min-w-0 break-all",children:["Read this skill and use it: ",o("fsrouter")]}),e.jsx(p,{value:`Read this skill and use it: ${o("fsrouter")}`,label:"Copy prompt"})]}),e.jsx("p",{className:"text-[11px] text-text-muted mt-2",children:"This entry skill covers setup, authentication, model discovery, and links to all capability skills below."})]}),t&&e.jsxs("section",{className:"space-y-2",children:[e.jsx("h2",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider px-1",children:"Entry Point"}),e.jsx(a,{skill:t})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h2",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider px-1",children:"API Capabilities"}),e.jsx("div",{className:"space-y-2",children:i.map(s=>e.jsx(a,{skill:s},s.id))})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h2",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider px-1",children:"Agent Workflow"}),e.jsx("div",{className:"space-y-2",children:r.map(s=>e.jsx(a,{skill:s},s.id))})]}),e.jsx(l,{padding:"md",children:e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main",children:"Browse on GitHub"}),e.jsx("p",{className:"text-xs text-text-muted mt-0.5",children:"View source, README, and full skill documentation."})]}),e.jsxs("a",{href:`${h}/tree/master/skills`,target:"_blank",rel:"noreferrer",className:"text-sm text-primary hover:underline inline-flex items-center gap-1 shrink-0",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"open_in_new"}),"View on GitHub"]})]})})]})}export{L as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as t}from"./index.
|
|
1
|
+
import{j as t}from"./index.D4FwOBBU.js";import{b as a}from"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";function g(){const[s,u]=a.useState(""),[n,i]=a.useState(""),[r,l]=a.useState(null),[o,c]=a.useState(!1),d=async()=>{c(!0);try{const e=await fetch("/api/rerank",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:s,documents:n.split(`
|
|
2
2
|
`).filter(Boolean)})});l(await e.json())}catch(e){l({error:e.message})}c(!1)};return t.jsxs("div",{className:"space-y-6 p-6",children:[t.jsx("h1",{className:"text-2xl font-bold",children:"Rerank"}),t.jsx("p",{className:"text-text-muted",children:"Rerank documents by relevance using Cohere-compatible API"}),t.jsx("input",{className:"w-full p-3 rounded-lg border",placeholder:"Query",value:s,onChange:e=>u(e.target.value)}),t.jsx("textarea",{className:"w-full p-3 rounded-lg border h-40",placeholder:"Documents (one per line)",value:n,onChange:e=>i(e.target.value)}),t.jsx("button",{onClick:d,disabled:o,className:"px-4 py-2 bg-primary text-white rounded-lg",children:o?"Reranking...":"Rerank"}),r&&t.jsx("pre",{className:"p-4 bg-black/5 rounded-lg text-sm overflow-auto",children:JSON.stringify(r,null,2)})]})}export{g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as a}from"./index.
|
|
1
|
+
import{j as a}from"./index.D4FwOBBU.js";import{b as e}from"./router.Cjj1--8t.js";import{g as m}from"./machine.CagOtseJ.js";import{A as c}from"./EndpointPageClient.BnlQVTIB.js";import"./zustand.akaTi5uX.js";import"./NoAuthProxyCard.WHGGEUIp.js";import"./Loading.C1il44u0.js";function h(){const[i,s]=e.useState(null),[n,r]=e.useState(!0);return e.useEffect(()=>{let t=!0;return m().then(o=>{t&&(s(o),r(!1))}).catch(()=>{t&&r(!1)}),()=>{t=!1}},[]),n?a.jsx("div",{className:"text-text-muted text-sm py-12 text-center",children:"Loading..."}):a.jsx(c,{machineId:i})}export{h as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,B as be,C as $t,g as Ae,M as gt,f as w,u as ve,i as Be,h as pe,N as bt,Q as yt,P as Pt,R as pt,S as Tt,V as _t}from"./index.Be3gbrBl.js";import{b as s,h as Lt,d as It,L as Dt}from"./router.Cjj1--8t.js";import{C as we,T as Ue,E as Ut,B as Oe,S as Ot,N as Bt,A as Kt}from"./NoAuthProxyCard.BDcXaWvM.js";import"./zustand.akaTi5uX.js";const Ft={mode:{label:"Mode",format:t=>t},defaultModel:{label:"Model",format:t=>t,mono:!0},baseUrl:{label:"Endpoint",format:t=>t,isLink:!0,mono:!0},costPerQuery:{label:"Cost / call",format:t=>t===0?"Free":`$${t.toFixed(4)}`},pricingUrl:{label:"Pricing",format:()=>"View pricing",isLink:!0},freeTier:{label:"Free tier",format:t=>t},freeMonthlyQuota:{label:"Free quota",format:t=>t===0?"—":t>=999999?"Unlimited":`${t.toLocaleString()} / mo`},searchTypes:{label:"Types",format:t=>t.join(", ")},formats:{label:"Formats",format:t=>t.join(", ")},maxMaxResults:{label:"Max results",format:t=>t},maxCharacters:{label:"Max chars",format:t=>t.toLocaleString()}};function Vt({config:t,provider:r,title:i="Provider Info"}){var d,p;if(!t)return null;const S=Object.entries(Ft).filter(([h])=>t[h]!==void 0&&t[h]!==null&&t[h]!=="").map(([h,y])=>({key:h,label:y.label,value:y.format(t[h]),isLink:y.isLink,mono:y.mono,raw:t[h]})),c=((d=r==null?void 0:r.notice)==null?void 0:d.apiKeyUrl)||(r==null?void 0:r.website),M=(p=r==null?void 0:r.notice)==null?void 0:p.text;return e.jsxs(we,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:i}),c&&e.jsxs("a",{href:c,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline inline-flex items-center gap-1",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"open_in_new"}),"Get API Key"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-2",children:[S.map(h=>e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx("span",{className:"text-xs text-text-muted w-28 shrink-0",children:h.label}),h.isLink?e.jsx("a",{href:h.raw,target:"_blank",rel:"noopener noreferrer",className:`text-sm text-primary hover:underline truncate ${h.mono?"font-mono":""}`,children:h.value}):e.jsx("span",{className:`text-sm text-text-main truncate ${h.mono?"font-mono":""}`,children:h.value})]},h.key)),M&&e.jsxs("div",{className:"flex items-start gap-3 min-w-0 sm:col-span-2",children:[e.jsx("span",{className:"text-xs text-text-muted w-28 shrink-0 mt-0.5",children:"Notice"}),e.jsx("span",{className:"text-sm text-text-main leading-relaxed",children:M})]})]})]})}function jt({until:t}){const[r,i]=s.useState("");return s.useEffect(()=>{const S=()=>{const M=new Date(t).getTime()-Date.now();if(M<=0){i("");return}const d=Math.floor(M/1e3);d<60?i(`${d}s`):d<3600?i(`${Math.floor(d/60)}m ${d%60}s`):i(`${Math.floor(d/3600)}h ${Math.floor(d%3600/60)}m`)};S();const c=setInterval(S,1e3);return()=>clearInterval(c)},[t]),r?e.jsxs("span",{className:"text-xs text-orange-500 font-mono",children:["⏱ ",r]}):null}jt.propTypes={until:w.string.isRequired};function vt({connection:t,proxyPools:r,isOAuth:i,isFirst:S,isLast:c,onMoveUp:M,onMoveDown:d,onToggleActive:p,onUpdateProxy:h,onEdit:y,onDelete:$}){var a,g,P,K,f,D;const[R,A]=s.useState(!1),[u,v]=s.useState(!1),[U,O]=s.useState(!1),L=s.useRef(null),I=new Map((r||[]).map(b=>[b.id,b])),j=((a=t.providerSpecificData)==null?void 0:a.proxyPoolId)||null,x=j?I.get(j):null,N=((g=t.providerSpecificData)==null?void 0:g.connectionProxyEnabled)===!0&&!!((P=t.providerSpecificData)!=null&&P.connectionProxyUrl),B=!!j||N,X=x?`Pool: ${x.name}`:j?`Pool: ${j} (inactive/missing)`:N?`Legacy: ${(K=t.providerSpecificData)==null?void 0:K.connectionProxyUrl}`:"";let Q="";const V=(x==null?void 0:x.proxyUrl)||((f=t.providerSpecificData)==null?void 0:f.connectionProxyUrl);if(V)try{const b=new URL(V);Q=`${b.protocol}//${b.hostname}${b.port?`:${b.port}`:""}`}catch{Q=V}const re=(x==null?void 0:x.noProxy)||((D=t.providerSpecificData)==null?void 0:D.connectionNoProxy)||"",ae=(x==null?void 0:x.isActive)===!0?"success":j||N?"error":"default",H=Object.entries(t).filter(([b])=>b.startsWith("modelLock_")).map(([,b])=>b).filter(Boolean).sort()[0]||null;s.useEffect(()=>{const b=()=>{const ne=Object.entries(t).filter(([G])=>G.startsWith("modelLock_")).map(([,G])=>G).filter(G=>G&&new Date(G).getTime()>Date.now()).sort()[0]||null;O(!!ne)};b();const Z=H?setInterval(b,1e3):null;return()=>{Z&&clearInterval(Z)}},[H]),s.useEffect(()=>{if(!R)return;const b=Z=>{L.current&&!L.current.contains(Z.target)&&A(!1)};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[R]);const W=t.testStatus==="unavailable"&&!U?"active":t.testStatus,le=()=>t.isActive===!1?"default":W==="active"||W==="success"?"success":W==="error"||W==="expired"||W==="unavailable"?"error":"default",m=i?t.name||t.email||t.displayName||"OAuth Account":t.name,o=async b=>{v(!0);try{await h(b==="__none__"?null:b)}finally{v(!1),A(!1)}};return e.jsxs("div",{className:`group flex flex-col gap-3 p-2 rounded-lg sm:flex-row sm:items-center sm:justify-between hover:bg-black/[0.02] dark:hover:bg-white/[0.02] transition-colors ${t.isActive===!1?"opacity-60":""}`,children:[e.jsxs("div",{className:"flex w-full min-w-0 flex-1 items-start gap-3 sm:items-center",children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("button",{onClick:M,disabled:S,className:`p-0.5 rounded ${S?"text-text-muted/30 cursor-not-allowed":"hover:bg-sidebar text-text-muted hover:text-primary"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"keyboard_arrow_up"})}),e.jsx("button",{onClick:d,disabled:c,className:`p-0.5 rounded ${c?"text-text-muted/30 cursor-not-allowed":"hover:bg-sidebar text-text-muted hover:text-primary"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"keyboard_arrow_down"})})]}),e.jsx("span",{className:"material-symbols-outlined text-base text-text-muted",children:i?"lock":"key"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium truncate",children:m}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mt-1",children:[e.jsx(Oe,{variant:le(),size:"sm",dot:!0,children:t.isActive===!1?"disabled":W||"Unknown"}),B&&e.jsx(Oe,{variant:ae,size:"sm",children:"Proxy"}),U&&t.isActive!==!1&&e.jsx(jt,{until:H}),t.lastError&&t.isActive!==!1&&e.jsx("span",{className:"text-xs text-red-500 truncate max-w-[300px]",title:t.lastError,children:t.lastError}),e.jsxs("span",{className:"text-xs text-text-muted",children:["#",t.priority]})]}),B&&e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-[11px] text-text-muted truncate max-w-[420px]",title:X,children:X}),Q&&e.jsx("code",{className:"text-[10px] font-mono bg-black/5 dark:bg-white/5 px-1 py-0.5 rounded text-text-muted",children:Q}),re&&e.jsxs("span",{className:"text-[11px] text-text-muted truncate max-w-[320px]",title:re,children:["no_proxy: ",re]})]})]})]}),e.jsxs("div",{className:"flex w-full flex-wrap items-center justify-between gap-2 sm:w-auto sm:justify-end",children:[e.jsxs("div",{className:"flex flex-wrap gap-1",children:[(r||[]).length>0&&e.jsxs("div",{className:"relative",ref:L,children:[e.jsxs("button",{onClick:()=>A(b=>!b),className:`flex flex-col items-center px-2 py-1 rounded hover:bg-black/5 dark:hover:bg-white/5 transition-colors ${B?"text-primary":"text-text-muted hover:text-primary"}`,disabled:u,children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:u?"progress_activity":"lan"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Proxy"})]}),R&&e.jsxs("div",{className:"absolute right-0 top-full mt-1 z-50 bg-bg border border-border rounded-lg shadow-lg py-1 min-w-[160px]",children:[e.jsx("button",{onClick:()=>o("__none__"),className:`w-full text-left px-3 py-1.5 text-sm hover:bg-black/5 dark:hover:bg-white/5 ${j?"text-text-main":"text-primary font-medium"}`,children:"None"}),(r||[]).map(b=>e.jsx("button",{onClick:()=>o(b.id),className:`w-full text-left px-3 py-1.5 text-sm hover:bg-black/5 dark:hover:bg-white/5 ${j===b.id?"text-primary font-medium":"text-text-main"}`,children:b.name},b.id))]})]}),e.jsxs("button",{onClick:y,className:"flex flex-col items-center px-2 py-1 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-primary",children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"edit"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Edit"})]}),e.jsxs("button",{onClick:$,className:"flex flex-col items-center px-2 py-1 rounded hover:bg-red-500/10 text-red-500",children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"delete"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Delete"})]})]}),e.jsx(Ue,{size:"sm",checked:t.isActive??!0,onChange:p,title:t.isActive??!0?"Disable":"Enable"})]})]})}vt.propTypes={connection:w.shape({id:w.string,name:w.string,email:w.string,displayName:w.string,testStatus:w.string,isActive:w.bool,lastError:w.string,priority:w.number}).isRequired,proxyPools:w.array,isOAuth:w.bool.isRequired,isFirst:w.bool.isRequired,isLast:w.bool.isRequired,onMoveUp:w.func.isRequired,onMoveDown:w.func.isRequired,onToggleActive:w.func.isRequired,onUpdateProxy:w.func,onEdit:w.func.isRequired,onDelete:w.func.isRequired};function wt({isOpen:t,provider:r,providerName:i,proxyPools:S,onSave:c,onClose:M}){var j;const d="__none__",[p,h]=s.useState({name:"",apiKey:"",priority:1,proxyPoolId:d,supportsImageRef:!0,supportsVideoRef:!0,supportsStartEndFrame:!0}),[y,$]=s.useState(!1),[R,A]=s.useState(null),[u,v]=s.useState(!1),U=Ae[r],O=((j=U==null?void 0:U.serviceKinds)==null?void 0:j.includes("video"))||r==="leonardo"||r==="runwayml",L=async()=>{$(!0);try{const N=await(await fetch("/api/providers/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:r,apiKey:p.apiKey})})).json();A(N.valid?"success":"failed")}catch{A("failed")}finally{$(!1)}},I=async()=>{if(!(!r||!p.apiKey)){v(!0);try{let x=!1;try{$(!0),A(null),x=!!(await(await fetch("/api/providers/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:r,apiKey:p.apiKey})})).json()).valid,A(x?"success":"failed")}catch{A("failed")}finally{$(!1)}await c({name:p.name,apiKey:p.apiKey,priority:p.priority,proxyPoolId:p.proxyPoolId===d?null:p.proxyPoolId,testStatus:x?"active":"unknown",providerSpecificData:{supportsImageRef:p.supportsImageRef,supportsVideoRef:p.supportsVideoRef,supportsStartEndFrame:p.supportsStartEndFrame}})}finally{v(!1)}}};return r?e.jsx(gt,{isOpen:t,title:`Add ${i||r} API Key`,onClose:M,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Name"}),e.jsx("input",{className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.name,onChange:x=>h({...p,name:x.target.value}),placeholder:"Production Key"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"API Key"}),e.jsx("input",{type:"password",className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.apiKey,onChange:x=>h({...p,apiKey:x.target.value})})]}),e.jsx("div",{className:"pt-6",children:e.jsx(be,{onClick:L,disabled:!p.apiKey||y||u,variant:"secondary",children:y?"Checking...":"Check"})})]}),R&&e.jsx(Oe,{variant:R==="success"?"success":"error",children:R==="success"?"Valid":"Invalid"}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Priority"}),e.jsx("input",{type:"number",className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.priority,onChange:x=>h({...p,priority:Number.parseInt(x.target.value)||1})})]}),e.jsx(Ot,{label:"Proxy Pool",value:p.proxyPoolId,onChange:x=>h({...p,proxyPoolId:x.target.value}),options:[{value:d,label:"None"},...(S||[]).map(x=>({value:x.id,label:x.name}))]}),O&&e.jsxs("div",{className:"bg-sidebar/30 p-4 rounded-lg border border-accent/10 flex flex-col gap-3 my-2",children:[e.jsx("h4",{className:"text-xs font-semibold uppercase tracking-wider text-text-muted",children:"Capabilities"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Image Reference"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports image URL inputs as prompts"})]}),e.jsx(Ue,{checked:p.supportsImageRef??!0,onChange:x=>h({...p,supportsImageRef:x})})]}),e.jsxs("div",{className:"flex items-center justify-between border-t border-accent/5 pt-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Video Reference"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports video URL inputs as prompts"})]}),e.jsx(Ue,{checked:p.supportsVideoRef??!0,onChange:x=>h({...p,supportsVideoRef:x})})]}),e.jsxs("div",{className:"flex items-center justify-between border-t border-accent/5 pt-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Start/End Frame"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports specifying start/end frames"})]}),e.jsx(Ue,{checked:p.supportsStartEndFrame??!0,onChange:x=>h({...p,supportsStartEndFrame:x})})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(be,{onClick:I,fullWidth:!0,disabled:!p.name||!p.apiKey||u,children:u?"Saving...":"Save"}),e.jsx(be,{onClick:M,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})}):null}wt.propTypes={isOpen:w.bool.isRequired,provider:w.string,providerName:w.string,proxyPools:w.array,onSave:w.func.isRequired,onClose:w.func.isRequired};function Nt({providerId:t,isOAuth:r}){const[i,S]=s.useState([]),[c,M]=s.useState([]),[d,p]=s.useState(!0),[h,y]=s.useState(!1),[$,R]=s.useState(!1),[A,u]=s.useState(null),[v,U]=s.useState(null),[O,L]=s.useState("1"),[I,j]=s.useState(null),[x,N]=s.useState(!1),B=s.useCallback(async()=>{try{const[o,a,g]=await Promise.all([fetch("/api/providers",{cache:"no-store"}),fetch("/api/proxy-pools?isActive=true",{cache:"no-store"}),fetch("/api/settings",{cache:"no-store"})]),P=await o.json(),K=await a.json(),f=g.ok?await g.json():{};o.ok&&S((P.connections||[]).filter(b=>b.provider===t)),a.ok&&M(K.proxyPools||[]);const D=(f.providerStrategies||{})[t]||{};U(D.fallbackStrategy||null),L(D.stickyRoundRobinLimit!=null?String(D.stickyRoundRobinLimit):"1")}catch(o){console.log("ConnectionsCard fetch error:",o)}finally{p(!1)}},[t]);s.useEffect(()=>{B()},[B]);const X=async(o,a)=>{try{const g=await fetch("/api/settings",{cache:"no-store"}),K=(g.ok?await g.json():{}).providerStrategies||{},f={};o&&(f.fallbackStrategy=o),o==="round-robin"&&a!==""&&(f.stickyRoundRobinLimit=Number(a)||3);const D={...K};Object.keys(f).length===0?delete D[t]:D[t]=f,await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerStrategies:D})})}catch(g){console.log("saveStrategy error:",g)}},Q=async(o,a)=>{const g=[...i];[g[o],g[a]]=[g[a],g[o]],S(g);try{await Promise.all([fetch(`/api/providers/${g[o].id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({priority:o})}),fetch(`/api/providers/${g[a].id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({priority:a})})])}catch{await B()}},V=async o=>{j({title:"Delete Connection",message:"Delete this connection?",onConfirm:async()=>{j(null);try{(await fetch(`/api/providers/${o}`,{method:"DELETE"})).ok&&S(g=>g.filter(P=>P.id!==o))}catch(a){console.log("delete error:",a)}}})},re=async(o,a)=>{try{(await fetch(`/api/providers/${o}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:a})})).ok&&S(P=>P.map(K=>K.id===o?{...K,isActive:a}:K))}catch(g){console.log("toggle error:",g)}},ae=async(o,a)=>{try{(await fetch(`/api/providers/${o}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({proxyPoolId:a||null})})).ok&&S(P=>P.map(K=>K.id===o?{...K,providerSpecificData:{...K.providerSpecificData,proxyPoolId:a||null}}:K))}catch(g){console.log("proxy error:",g)}},H=async()=>{if(i.length!==0){N(!0);try{await Promise.all(i.map(o=>fetch(`/api/providers/${o.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({testStatus:"active",lastError:"",lastErrorAt:null})}))),S(o=>o.map(a=>({...a,testStatus:"active",lastError:"",lastErrorAt:null})))}catch(o){console.log("reset all status error:",o)}finally{N(!1)}}},W=async o=>{try{(await fetch("/api/providers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:t,...o})})).ok&&(await B(),y(!1))}catch(a){console.log("save apikey error:",a)}},le=async o=>{try{(await fetch(`/api/providers/${A.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)})).ok&&(await B(),R(!1))}catch(a){console.log("update connection error:",a)}};if(d)return e.jsx(we,{children:e.jsx("div",{className:"h-20 animate-pulse bg-black/5 rounded-lg"})});const m=i.some(o=>o.lastError||o.testStatus==="error");return e.jsxs(e.Fragment,{children:[e.jsxs(we,{children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Connections"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.length>0&&e.jsxs("button",{onClick:H,disabled:x,title:"Reset testStatus and lastError for all connections",className:"flex items-center gap-1.5 px-2.5 py-1 rounded-lg border border-border text-xs text-text-muted hover:text-amber-500 hover:border-amber-500/40 hover:bg-amber-500/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:x?"progress_activity":"restart_alt"}),x?"Resetting...":"Reset All Status",m&&!x&&e.jsx("span",{className:"inline-flex items-center justify-center w-4 h-4 rounded-full bg-red-500/15 text-red-500 text-[10px] font-bold",children:"!"})]}),e.jsx("span",{className:"text-xs text-text-muted font-medium",children:"Round Robin"}),e.jsx(Ue,{checked:v==="round-robin",onChange:o=>{const a=o?"round-robin":null;U(a),o&&!O&&L("1"),X(a,o?O||"1":O)}}),v==="round-robin"&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-text-muted",children:"Sticky:"}),e.jsx("input",{type:"number",min:1,value:O,onChange:o=>{L(o.target.value),X("round-robin",o.target.value)},className:"w-16 px-2 py-1 text-xs border border-border rounded-md bg-background focus:outline-none focus:border-primary"})]})]})]}),i.length===0?e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("p",{className:"text-sm text-text-muted",children:"No connections yet"}),e.jsx(be,{size:"sm",icon:"add",onClick:()=>y(!0),children:"Add Connection"})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex flex-col divide-y divide-black/[0.03] dark:divide-white/[0.03]",children:i.map((o,a)=>e.jsx(vt,{connection:o,proxyPools:c,isOAuth:r,isFirst:a===0,isLast:a===i.length-1,onMoveUp:()=>Q(a,a-1),onMoveDown:()=>Q(a,a+1),onToggleActive:g=>re(o.id,g),onUpdateProxy:g=>ae(o.id,g),onEdit:()=>{u(o),R(!0)},onDelete:()=>V(o.id)},o.id))}),e.jsx("div",{className:"mt-4 flex justify-stretch sm:justify-start",children:e.jsx(be,{size:"sm",icon:"add",onClick:()=>y(!0),children:"Add"})})]})]}),e.jsx(wt,{isOpen:h,provider:t,proxyPools:c,onSave:W,onClose:()=>y(!1)}),e.jsx(Ut,{isOpen:$,connection:A,proxyPools:c,onSave:le,onClose:()=>R(!1)}),e.jsx($t,{isOpen:!!I,onClose:()=>j(null),onConfirm:I==null?void 0:I.onConfirm,title:(I==null?void 0:I.title)||"Confirm",message:I==null?void 0:I.message,variant:"danger"})]})}Nt.propTypes={providerId:w.string.isRequired,isOAuth:w.bool};function Xe({model:t,fullModel:r,copied:i,onCopy:S,testStatus:c,isCustom:M,isFree:d,onDeleteAlias:p,onTest:h,isTesting:y}){const $=c==="ok"?"border-green-500/40":c==="error"?"border-red-500/40":"border-border",R=c==="ok"?"#22c55e":c==="error"?"#ef4444":void 0;return e.jsx("div",{className:`group px-3 py-2 rounded-lg border ${$} hover:bg-sidebar/50`,children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-base",style:R?{color:R}:void 0,children:c==="ok"?"check_circle":c==="error"?"cancel":"smart_toy"}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("code",{className:"text-xs text-text-muted font-mono bg-sidebar px-1.5 py-0.5 rounded",children:r}),t.name&&e.jsx("span",{className:"text-[9px] text-text-muted/70 italic pl-1",children:t.name})]}),h&&e.jsxs("div",{className:"relative group/btn",children:[e.jsx("button",{onClick:h,disabled:y,className:`p-0.5 hover:bg-sidebar rounded text-text-muted hover:text-primary transition-opacity ${y?"opacity-100":"opacity-0 group-hover:opacity-100"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",style:y?{animation:"spin 1s linear infinite"}:void 0,children:y?"progress_activity":"science"})}),e.jsx("span",{className:"pointer-events-none absolute mt-1 top-5 left-1/2 -translate-x-1/2 text-[10px] text-text-muted whitespace-nowrap opacity-0 group-hover/btn:opacity-100 transition-opacity",children:y?"Testing...":"Test"})]}),e.jsxs("div",{className:"relative group/btn",children:[e.jsx("button",{onClick:()=>S(r,`model-${t.id}`),className:"p-0.5 hover:bg-sidebar rounded text-text-muted hover:text-primary",children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:i===`model-${t.id}`?"check":"content_copy"})}),e.jsx("span",{className:"pointer-events-none absolute mt-1 top-5 left-1/2 -translate-x-1/2 text-[10px] text-text-muted whitespace-nowrap opacity-0 group-hover/btn:opacity-100 transition-opacity",children:i===`model-${t.id}`?"Copied!":"Copy"})]}),d&&e.jsx("span",{className:"text-[10px] font-bold text-green-500 bg-green-500/10 px-1.5 py-0.5 rounded",children:"FREE"}),M&&e.jsx("button",{onClick:p,className:"p-0.5 hover:bg-red-500/10 rounded text-text-muted hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity ml-auto",title:"Remove custom model",children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"close"})})]})})}Xe.propTypes={model:w.shape({id:w.string.isRequired}).isRequired,fullModel:w.string.isRequired,copied:w.string,onCopy:w.func.isRequired,testStatus:w.oneOf(["ok","error"]),isCustom:w.bool,isFree:w.bool,onDeleteAlias:w.func,onTest:w.func,isTesting:w.bool};function kt({isOpen:t,onSave:r,onClose:i}){const[S,c]=s.useState(""),M=()=>{S.trim()&&(r(S.trim()),c(""))};return e.jsx(gt,{isOpen:t,title:"Add Custom Model",onClose:i,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Model ID"}),e.jsx("input",{className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:S,onChange:d=>c(d.target.value),onKeyDown:d=>d.key==="Enter"&&M(),placeholder:"e.g. tts-1-hd",autoFocus:!0})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(be,{onClick:M,fullWidth:!0,disabled:!S.trim(),children:"Add"}),e.jsx(be,{onClick:i,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})})}kt.propTypes={isOpen:w.bool.isRequired,onSave:w.func.isRequired,onClose:w.func.isRequired};function St({providerId:t,kindFilter:r,providerAliasOverride:i}){const{copied:S,copy:c}=ve(),[M,d]=s.useState({}),[p,h]=s.useState([]),[y,$]=s.useState({}),[R,A]=s.useState(null),[u,v]=s.useState(""),[U,O]=s.useState(!1),[L,I]=s.useState([]),j=i||Be(t),x=r||"llm",N=s.useCallback(async()=>{try{const[m,o,a]=await Promise.all([fetch("/api/models/alias"),fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/custom",{cache:"no-store"})]),g=await m.json(),P=await o.json(),K=await a.json();m.ok&&d(g.aliases||{}),o.ok&&I((P.connections||[]).filter(f=>f.provider===t)),a.ok&&h(K.models||[])}catch(m){console.log("ModelsCard fetch error:",m)}},[t]);s.useEffect(()=>{N()},[N]);const B=async(m,o)=>{const a=`${j}/${m}`;try{(await fetch("/api/models/alias",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:a,alias:o})})).ok&&await N()}catch(g){console.log("set alias error:",g)}},X=async m=>{try{(await fetch(`/api/models/alias?alias=${encodeURIComponent(m)}`,{method:"DELETE"})).ok&&await N()}catch(o){console.log("delete alias error:",o)}},Q=async m=>{try{(await fetch("/api/models/custom",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerAlias:j,id:m,type:x})})).ok&&(await N(),window.dispatchEvent(new CustomEvent("customModelChanged")))}catch(o){console.log("add custom model error:",o)}},V=async m=>{try{const o=new URLSearchParams({providerAlias:j,id:m,type:x});(await fetch(`/api/models/custom?${o}`,{method:"DELETE"})).ok&&(await N(),window.dispatchEvent(new CustomEvent("customModelChanged")))}catch(o){console.log("delete custom model error:",o)}},re=async m=>{if(!R){A(m);try{const a=await(await fetch("/api/models/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:`${j}/${m}`,kind:r})})).json();$(g=>({...g,[m]:a.ok?"ok":"error"})),v(a.ok?"":a.error||"Model not reachable")}catch{$(o=>({...o,[m]:"error"})),v("Network error")}finally{A(null)}}},ae=pe(t),H=r?ae.filter(m=>m.kinds?m.kinds.includes(r):(m.type||"llm")===r):ae,W=p.filter(m=>m.providerAlias===j&&(m.type||"llm")===x&&!H.some(o=>o.id===m.id)),le=H;return e.jsxs(e.Fragment,{children:[e.jsxs(we,{children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsxs("h2",{className:"text-lg font-semibold",children:["Models",r?` — ${r.toUpperCase()}`:""]})}),u&&e.jsx("p",{className:"text-xs text-red-500 mb-3 break-words",children:u}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[le.map(m=>{var g;const o=`${j}/${m.id}`,a=(g=Object.entries(M).find(([,P])=>P===o))==null?void 0:g[0];return e.jsx(Xe,{model:m,fullModel:`${j}/${m.id}`,alias:a,copied:S,onCopy:c,onSetAlias:P=>B(m.id,P),onDeleteAlias:()=>X(a),testStatus:y[m.id],onTest:L.length>0?()=>re(m.id):void 0,isTesting:R===m.id,isFree:m.isFree},m.id)}),W.map(m=>e.jsx(Xe,{model:{id:m.id,name:m.name},fullModel:`${j}/${m.id}`,copied:S,onCopy:c,onSetAlias:()=>{},onDeleteAlias:()=>V(m.id),testStatus:y[m.id],onTest:L.length>0?()=>re(m.id):void 0,isTesting:R===m.id,isCustom:!0},`${m.id}-${m.type}`)),e.jsxs("button",{onClick:()=>O(!0),className:"flex items-center gap-1.5 px-3 py-2 rounded-lg border border-dashed border-black/15 dark:border-white/15 text-xs text-text-muted hover:text-primary hover:border-primary/40 transition-colors",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"add"}),"Add Model"]})]})]}),e.jsx(kt,{isOpen:U,onSave:async m=>{await Q(m),O(!1)},onClose:()=>O(!1)})]})}St.propTypes={providerId:w.string.isRequired,kindFilter:w.string,providerAliasOverride:w.string};const xt={"google-tts":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"hardcoded"},openai:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"openai-tts-models",voiceKey:"openai-tts-voices",voicesPerModel:!0},openrouter:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"openrouter-tts-models",voiceKey:"openrouter-tts-voices",voicesPerModel:!0},elevenlabs:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",modelKey:"elevenlabs-tts-models",apiEndpoint:"/api/media-providers/tts/elevenlabs/voices"},"edge-tts":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language"},"local-device":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language"},nvidia:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},hyperbolic:{hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"config"},deepgram:{hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/deepgram/voices"},huggingface:{hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"config"},cartesia:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},playht:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},coqui:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},tortoise:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},inworld:{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",modelKey:"inworld-tts-models",apiEndpoint:"/api/media-providers/tts/inworld/voices"},qwen:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},minimax:{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/minimax/voices",defaultVoiceId:"English_expressive_narrator"},"minimax-cn":{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/minimax/voices?provider=minimax-cn",defaultVoiceId:"English_expressive_narrator"},gemini:{hasLanguageDropdown:!1,hasLanguageHint:!0,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"gemini-tts-models",voiceKey:"gemini-tts-voices",voicesPerModel:!0}};function _({label:t,children:r}){return e.jsxs("div",{className:"flex min-w-0 flex-col gap-1.5 sm:flex-row sm:items-center sm:gap-3",children:[e.jsx("span",{className:"w-full text-xs font-medium text-text-muted sm:w-20 sm:shrink-0",children:t}),e.jsx("div",{className:"w-full min-w-0 flex-1",children:r})]})}const qt=`// Audio will appear here after running.
|
|
1
|
+
import{j as e,B as be,C as $t,g as Ae,M as gt,f as w,u as ve,i as Be,h as pe,N as bt,Q as yt,P as Pt,R as pt,S as Tt,V as _t}from"./index.D4FwOBBU.js";import{b as s,h as Lt,d as It,L as Dt}from"./router.Cjj1--8t.js";import{C as we,T as Ue,E as Ut,B as Oe,S as Ot,N as Bt,A as Kt}from"./NoAuthProxyCard.WHGGEUIp.js";import"./zustand.akaTi5uX.js";const Ft={mode:{label:"Mode",format:t=>t},defaultModel:{label:"Model",format:t=>t,mono:!0},baseUrl:{label:"Endpoint",format:t=>t,isLink:!0,mono:!0},costPerQuery:{label:"Cost / call",format:t=>t===0?"Free":`$${t.toFixed(4)}`},pricingUrl:{label:"Pricing",format:()=>"View pricing",isLink:!0},freeTier:{label:"Free tier",format:t=>t},freeMonthlyQuota:{label:"Free quota",format:t=>t===0?"—":t>=999999?"Unlimited":`${t.toLocaleString()} / mo`},searchTypes:{label:"Types",format:t=>t.join(", ")},formats:{label:"Formats",format:t=>t.join(", ")},maxMaxResults:{label:"Max results",format:t=>t},maxCharacters:{label:"Max chars",format:t=>t.toLocaleString()}};function Vt({config:t,provider:r,title:i="Provider Info"}){var d,p;if(!t)return null;const S=Object.entries(Ft).filter(([h])=>t[h]!==void 0&&t[h]!==null&&t[h]!=="").map(([h,y])=>({key:h,label:y.label,value:y.format(t[h]),isLink:y.isLink,mono:y.mono,raw:t[h]})),c=((d=r==null?void 0:r.notice)==null?void 0:d.apiKeyUrl)||(r==null?void 0:r.website),M=(p=r==null?void 0:r.notice)==null?void 0:p.text;return e.jsxs(we,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:i}),c&&e.jsxs("a",{href:c,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline inline-flex items-center gap-1",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"open_in_new"}),"Get API Key"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-2",children:[S.map(h=>e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx("span",{className:"text-xs text-text-muted w-28 shrink-0",children:h.label}),h.isLink?e.jsx("a",{href:h.raw,target:"_blank",rel:"noopener noreferrer",className:`text-sm text-primary hover:underline truncate ${h.mono?"font-mono":""}`,children:h.value}):e.jsx("span",{className:`text-sm text-text-main truncate ${h.mono?"font-mono":""}`,children:h.value})]},h.key)),M&&e.jsxs("div",{className:"flex items-start gap-3 min-w-0 sm:col-span-2",children:[e.jsx("span",{className:"text-xs text-text-muted w-28 shrink-0 mt-0.5",children:"Notice"}),e.jsx("span",{className:"text-sm text-text-main leading-relaxed",children:M})]})]})]})}function jt({until:t}){const[r,i]=s.useState("");return s.useEffect(()=>{const S=()=>{const M=new Date(t).getTime()-Date.now();if(M<=0){i("");return}const d=Math.floor(M/1e3);d<60?i(`${d}s`):d<3600?i(`${Math.floor(d/60)}m ${d%60}s`):i(`${Math.floor(d/3600)}h ${Math.floor(d%3600/60)}m`)};S();const c=setInterval(S,1e3);return()=>clearInterval(c)},[t]),r?e.jsxs("span",{className:"text-xs text-orange-500 font-mono",children:["⏱ ",r]}):null}jt.propTypes={until:w.string.isRequired};function vt({connection:t,proxyPools:r,isOAuth:i,isFirst:S,isLast:c,onMoveUp:M,onMoveDown:d,onToggleActive:p,onUpdateProxy:h,onEdit:y,onDelete:$}){var a,g,P,K,f,D;const[R,A]=s.useState(!1),[u,v]=s.useState(!1),[U,O]=s.useState(!1),L=s.useRef(null),I=new Map((r||[]).map(b=>[b.id,b])),j=((a=t.providerSpecificData)==null?void 0:a.proxyPoolId)||null,x=j?I.get(j):null,N=((g=t.providerSpecificData)==null?void 0:g.connectionProxyEnabled)===!0&&!!((P=t.providerSpecificData)!=null&&P.connectionProxyUrl),B=!!j||N,X=x?`Pool: ${x.name}`:j?`Pool: ${j} (inactive/missing)`:N?`Legacy: ${(K=t.providerSpecificData)==null?void 0:K.connectionProxyUrl}`:"";let Q="";const V=(x==null?void 0:x.proxyUrl)||((f=t.providerSpecificData)==null?void 0:f.connectionProxyUrl);if(V)try{const b=new URL(V);Q=`${b.protocol}//${b.hostname}${b.port?`:${b.port}`:""}`}catch{Q=V}const re=(x==null?void 0:x.noProxy)||((D=t.providerSpecificData)==null?void 0:D.connectionNoProxy)||"",ae=(x==null?void 0:x.isActive)===!0?"success":j||N?"error":"default",H=Object.entries(t).filter(([b])=>b.startsWith("modelLock_")).map(([,b])=>b).filter(Boolean).sort()[0]||null;s.useEffect(()=>{const b=()=>{const ne=Object.entries(t).filter(([G])=>G.startsWith("modelLock_")).map(([,G])=>G).filter(G=>G&&new Date(G).getTime()>Date.now()).sort()[0]||null;O(!!ne)};b();const Z=H?setInterval(b,1e3):null;return()=>{Z&&clearInterval(Z)}},[H]),s.useEffect(()=>{if(!R)return;const b=Z=>{L.current&&!L.current.contains(Z.target)&&A(!1)};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[R]);const W=t.testStatus==="unavailable"&&!U?"active":t.testStatus,le=()=>t.isActive===!1?"default":W==="active"||W==="success"?"success":W==="error"||W==="expired"||W==="unavailable"?"error":"default",m=i?t.name||t.email||t.displayName||"OAuth Account":t.name,o=async b=>{v(!0);try{await h(b==="__none__"?null:b)}finally{v(!1),A(!1)}};return e.jsxs("div",{className:`group flex flex-col gap-3 p-2 rounded-lg sm:flex-row sm:items-center sm:justify-between hover:bg-black/[0.02] dark:hover:bg-white/[0.02] transition-colors ${t.isActive===!1?"opacity-60":""}`,children:[e.jsxs("div",{className:"flex w-full min-w-0 flex-1 items-start gap-3 sm:items-center",children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("button",{onClick:M,disabled:S,className:`p-0.5 rounded ${S?"text-text-muted/30 cursor-not-allowed":"hover:bg-sidebar text-text-muted hover:text-primary"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"keyboard_arrow_up"})}),e.jsx("button",{onClick:d,disabled:c,className:`p-0.5 rounded ${c?"text-text-muted/30 cursor-not-allowed":"hover:bg-sidebar text-text-muted hover:text-primary"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"keyboard_arrow_down"})})]}),e.jsx("span",{className:"material-symbols-outlined text-base text-text-muted",children:i?"lock":"key"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium truncate",children:m}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mt-1",children:[e.jsx(Oe,{variant:le(),size:"sm",dot:!0,children:t.isActive===!1?"disabled":W||"Unknown"}),B&&e.jsx(Oe,{variant:ae,size:"sm",children:"Proxy"}),U&&t.isActive!==!1&&e.jsx(jt,{until:H}),t.lastError&&t.isActive!==!1&&e.jsx("span",{className:"text-xs text-red-500 truncate max-w-[300px]",title:t.lastError,children:t.lastError}),e.jsxs("span",{className:"text-xs text-text-muted",children:["#",t.priority]})]}),B&&e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-[11px] text-text-muted truncate max-w-[420px]",title:X,children:X}),Q&&e.jsx("code",{className:"text-[10px] font-mono bg-black/5 dark:bg-white/5 px-1 py-0.5 rounded text-text-muted",children:Q}),re&&e.jsxs("span",{className:"text-[11px] text-text-muted truncate max-w-[320px]",title:re,children:["no_proxy: ",re]})]})]})]}),e.jsxs("div",{className:"flex w-full flex-wrap items-center justify-between gap-2 sm:w-auto sm:justify-end",children:[e.jsxs("div",{className:"flex flex-wrap gap-1",children:[(r||[]).length>0&&e.jsxs("div",{className:"relative",ref:L,children:[e.jsxs("button",{onClick:()=>A(b=>!b),className:`flex flex-col items-center px-2 py-1 rounded hover:bg-black/5 dark:hover:bg-white/5 transition-colors ${B?"text-primary":"text-text-muted hover:text-primary"}`,disabled:u,children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:u?"progress_activity":"lan"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Proxy"})]}),R&&e.jsxs("div",{className:"absolute right-0 top-full mt-1 z-50 bg-bg border border-border rounded-lg shadow-lg py-1 min-w-[160px]",children:[e.jsx("button",{onClick:()=>o("__none__"),className:`w-full text-left px-3 py-1.5 text-sm hover:bg-black/5 dark:hover:bg-white/5 ${j?"text-text-main":"text-primary font-medium"}`,children:"None"}),(r||[]).map(b=>e.jsx("button",{onClick:()=>o(b.id),className:`w-full text-left px-3 py-1.5 text-sm hover:bg-black/5 dark:hover:bg-white/5 ${j===b.id?"text-primary font-medium":"text-text-main"}`,children:b.name},b.id))]})]}),e.jsxs("button",{onClick:y,className:"flex flex-col items-center px-2 py-1 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-primary",children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"edit"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Edit"})]}),e.jsxs("button",{onClick:$,className:"flex flex-col items-center px-2 py-1 rounded hover:bg-red-500/10 text-red-500",children:[e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"delete"}),e.jsx("span",{className:"text-[10px] leading-tight",children:"Delete"})]})]}),e.jsx(Ue,{size:"sm",checked:t.isActive??!0,onChange:p,title:t.isActive??!0?"Disable":"Enable"})]})]})}vt.propTypes={connection:w.shape({id:w.string,name:w.string,email:w.string,displayName:w.string,testStatus:w.string,isActive:w.bool,lastError:w.string,priority:w.number}).isRequired,proxyPools:w.array,isOAuth:w.bool.isRequired,isFirst:w.bool.isRequired,isLast:w.bool.isRequired,onMoveUp:w.func.isRequired,onMoveDown:w.func.isRequired,onToggleActive:w.func.isRequired,onUpdateProxy:w.func,onEdit:w.func.isRequired,onDelete:w.func.isRequired};function wt({isOpen:t,provider:r,providerName:i,proxyPools:S,onSave:c,onClose:M}){var j;const d="__none__",[p,h]=s.useState({name:"",apiKey:"",priority:1,proxyPoolId:d,supportsImageRef:!0,supportsVideoRef:!0,supportsStartEndFrame:!0}),[y,$]=s.useState(!1),[R,A]=s.useState(null),[u,v]=s.useState(!1),U=Ae[r],O=((j=U==null?void 0:U.serviceKinds)==null?void 0:j.includes("video"))||r==="leonardo"||r==="runwayml",L=async()=>{$(!0);try{const N=await(await fetch("/api/providers/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:r,apiKey:p.apiKey})})).json();A(N.valid?"success":"failed")}catch{A("failed")}finally{$(!1)}},I=async()=>{if(!(!r||!p.apiKey)){v(!0);try{let x=!1;try{$(!0),A(null),x=!!(await(await fetch("/api/providers/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:r,apiKey:p.apiKey})})).json()).valid,A(x?"success":"failed")}catch{A("failed")}finally{$(!1)}await c({name:p.name,apiKey:p.apiKey,priority:p.priority,proxyPoolId:p.proxyPoolId===d?null:p.proxyPoolId,testStatus:x?"active":"unknown",providerSpecificData:{supportsImageRef:p.supportsImageRef,supportsVideoRef:p.supportsVideoRef,supportsStartEndFrame:p.supportsStartEndFrame}})}finally{v(!1)}}};return r?e.jsx(gt,{isOpen:t,title:`Add ${i||r} API Key`,onClose:M,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Name"}),e.jsx("input",{className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.name,onChange:x=>h({...p,name:x.target.value}),placeholder:"Production Key"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"API Key"}),e.jsx("input",{type:"password",className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.apiKey,onChange:x=>h({...p,apiKey:x.target.value})})]}),e.jsx("div",{className:"pt-6",children:e.jsx(be,{onClick:L,disabled:!p.apiKey||y||u,variant:"secondary",children:y?"Checking...":"Check"})})]}),R&&e.jsx(Oe,{variant:R==="success"?"success":"error",children:R==="success"?"Valid":"Invalid"}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Priority"}),e.jsx("input",{type:"number",className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:p.priority,onChange:x=>h({...p,priority:Number.parseInt(x.target.value)||1})})]}),e.jsx(Ot,{label:"Proxy Pool",value:p.proxyPoolId,onChange:x=>h({...p,proxyPoolId:x.target.value}),options:[{value:d,label:"None"},...(S||[]).map(x=>({value:x.id,label:x.name}))]}),O&&e.jsxs("div",{className:"bg-sidebar/30 p-4 rounded-lg border border-accent/10 flex flex-col gap-3 my-2",children:[e.jsx("h4",{className:"text-xs font-semibold uppercase tracking-wider text-text-muted",children:"Capabilities"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Image Reference"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports image URL inputs as prompts"})]}),e.jsx(Ue,{checked:p.supportsImageRef??!0,onChange:x=>h({...p,supportsImageRef:x})})]}),e.jsxs("div",{className:"flex items-center justify-between border-t border-accent/5 pt-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Video Reference"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports video URL inputs as prompts"})]}),e.jsx(Ue,{checked:p.supportsVideoRef??!0,onChange:x=>h({...p,supportsVideoRef:x})})]}),e.jsxs("div",{className:"flex items-center justify-between border-t border-accent/5 pt-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Start/End Frame"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Supports specifying start/end frames"})]}),e.jsx(Ue,{checked:p.supportsStartEndFrame??!0,onChange:x=>h({...p,supportsStartEndFrame:x})})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(be,{onClick:I,fullWidth:!0,disabled:!p.name||!p.apiKey||u,children:u?"Saving...":"Save"}),e.jsx(be,{onClick:M,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})}):null}wt.propTypes={isOpen:w.bool.isRequired,provider:w.string,providerName:w.string,proxyPools:w.array,onSave:w.func.isRequired,onClose:w.func.isRequired};function Nt({providerId:t,isOAuth:r}){const[i,S]=s.useState([]),[c,M]=s.useState([]),[d,p]=s.useState(!0),[h,y]=s.useState(!1),[$,R]=s.useState(!1),[A,u]=s.useState(null),[v,U]=s.useState(null),[O,L]=s.useState("1"),[I,j]=s.useState(null),[x,N]=s.useState(!1),B=s.useCallback(async()=>{try{const[o,a,g]=await Promise.all([fetch("/api/providers",{cache:"no-store"}),fetch("/api/proxy-pools?isActive=true",{cache:"no-store"}),fetch("/api/settings",{cache:"no-store"})]),P=await o.json(),K=await a.json(),f=g.ok?await g.json():{};o.ok&&S((P.connections||[]).filter(b=>b.provider===t)),a.ok&&M(K.proxyPools||[]);const D=(f.providerStrategies||{})[t]||{};U(D.fallbackStrategy||null),L(D.stickyRoundRobinLimit!=null?String(D.stickyRoundRobinLimit):"1")}catch(o){console.log("ConnectionsCard fetch error:",o)}finally{p(!1)}},[t]);s.useEffect(()=>{B()},[B]);const X=async(o,a)=>{try{const g=await fetch("/api/settings",{cache:"no-store"}),K=(g.ok?await g.json():{}).providerStrategies||{},f={};o&&(f.fallbackStrategy=o),o==="round-robin"&&a!==""&&(f.stickyRoundRobinLimit=Number(a)||3);const D={...K};Object.keys(f).length===0?delete D[t]:D[t]=f,await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerStrategies:D})})}catch(g){console.log("saveStrategy error:",g)}},Q=async(o,a)=>{const g=[...i];[g[o],g[a]]=[g[a],g[o]],S(g);try{await Promise.all([fetch(`/api/providers/${g[o].id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({priority:o})}),fetch(`/api/providers/${g[a].id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({priority:a})})])}catch{await B()}},V=async o=>{j({title:"Delete Connection",message:"Delete this connection?",onConfirm:async()=>{j(null);try{(await fetch(`/api/providers/${o}`,{method:"DELETE"})).ok&&S(g=>g.filter(P=>P.id!==o))}catch(a){console.log("delete error:",a)}}})},re=async(o,a)=>{try{(await fetch(`/api/providers/${o}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:a})})).ok&&S(P=>P.map(K=>K.id===o?{...K,isActive:a}:K))}catch(g){console.log("toggle error:",g)}},ae=async(o,a)=>{try{(await fetch(`/api/providers/${o}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({proxyPoolId:a||null})})).ok&&S(P=>P.map(K=>K.id===o?{...K,providerSpecificData:{...K.providerSpecificData,proxyPoolId:a||null}}:K))}catch(g){console.log("proxy error:",g)}},H=async()=>{if(i.length!==0){N(!0);try{await Promise.all(i.map(o=>fetch(`/api/providers/${o.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({testStatus:"active",lastError:"",lastErrorAt:null})}))),S(o=>o.map(a=>({...a,testStatus:"active",lastError:"",lastErrorAt:null})))}catch(o){console.log("reset all status error:",o)}finally{N(!1)}}},W=async o=>{try{(await fetch("/api/providers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:t,...o})})).ok&&(await B(),y(!1))}catch(a){console.log("save apikey error:",a)}},le=async o=>{try{(await fetch(`/api/providers/${A.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)})).ok&&(await B(),R(!1))}catch(a){console.log("update connection error:",a)}};if(d)return e.jsx(we,{children:e.jsx("div",{className:"h-20 animate-pulse bg-black/5 rounded-lg"})});const m=i.some(o=>o.lastError||o.testStatus==="error");return e.jsxs(e.Fragment,{children:[e.jsxs(we,{children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Connections"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.length>0&&e.jsxs("button",{onClick:H,disabled:x,title:"Reset testStatus and lastError for all connections",className:"flex items-center gap-1.5 px-2.5 py-1 rounded-lg border border-border text-xs text-text-muted hover:text-amber-500 hover:border-amber-500/40 hover:bg-amber-500/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:x?"progress_activity":"restart_alt"}),x?"Resetting...":"Reset All Status",m&&!x&&e.jsx("span",{className:"inline-flex items-center justify-center w-4 h-4 rounded-full bg-red-500/15 text-red-500 text-[10px] font-bold",children:"!"})]}),e.jsx("span",{className:"text-xs text-text-muted font-medium",children:"Round Robin"}),e.jsx(Ue,{checked:v==="round-robin",onChange:o=>{const a=o?"round-robin":null;U(a),o&&!O&&L("1"),X(a,o?O||"1":O)}}),v==="round-robin"&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-text-muted",children:"Sticky:"}),e.jsx("input",{type:"number",min:1,value:O,onChange:o=>{L(o.target.value),X("round-robin",o.target.value)},className:"w-16 px-2 py-1 text-xs border border-border rounded-md bg-background focus:outline-none focus:border-primary"})]})]})]}),i.length===0?e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("p",{className:"text-sm text-text-muted",children:"No connections yet"}),e.jsx(be,{size:"sm",icon:"add",onClick:()=>y(!0),children:"Add Connection"})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex flex-col divide-y divide-black/[0.03] dark:divide-white/[0.03]",children:i.map((o,a)=>e.jsx(vt,{connection:o,proxyPools:c,isOAuth:r,isFirst:a===0,isLast:a===i.length-1,onMoveUp:()=>Q(a,a-1),onMoveDown:()=>Q(a,a+1),onToggleActive:g=>re(o.id,g),onUpdateProxy:g=>ae(o.id,g),onEdit:()=>{u(o),R(!0)},onDelete:()=>V(o.id)},o.id))}),e.jsx("div",{className:"mt-4 flex justify-stretch sm:justify-start",children:e.jsx(be,{size:"sm",icon:"add",onClick:()=>y(!0),children:"Add"})})]})]}),e.jsx(wt,{isOpen:h,provider:t,proxyPools:c,onSave:W,onClose:()=>y(!1)}),e.jsx(Ut,{isOpen:$,connection:A,proxyPools:c,onSave:le,onClose:()=>R(!1)}),e.jsx($t,{isOpen:!!I,onClose:()=>j(null),onConfirm:I==null?void 0:I.onConfirm,title:(I==null?void 0:I.title)||"Confirm",message:I==null?void 0:I.message,variant:"danger"})]})}Nt.propTypes={providerId:w.string.isRequired,isOAuth:w.bool};function Xe({model:t,fullModel:r,copied:i,onCopy:S,testStatus:c,isCustom:M,isFree:d,onDeleteAlias:p,onTest:h,isTesting:y}){const $=c==="ok"?"border-green-500/40":c==="error"?"border-red-500/40":"border-border",R=c==="ok"?"#22c55e":c==="error"?"#ef4444":void 0;return e.jsx("div",{className:`group px-3 py-2 rounded-lg border ${$} hover:bg-sidebar/50`,children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-base",style:R?{color:R}:void 0,children:c==="ok"?"check_circle":c==="error"?"cancel":"smart_toy"}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("code",{className:"text-xs text-text-muted font-mono bg-sidebar px-1.5 py-0.5 rounded",children:r}),t.name&&e.jsx("span",{className:"text-[9px] text-text-muted/70 italic pl-1",children:t.name})]}),h&&e.jsxs("div",{className:"relative group/btn",children:[e.jsx("button",{onClick:h,disabled:y,className:`p-0.5 hover:bg-sidebar rounded text-text-muted hover:text-primary transition-opacity ${y?"opacity-100":"opacity-0 group-hover:opacity-100"}`,children:e.jsx("span",{className:"material-symbols-outlined text-sm",style:y?{animation:"spin 1s linear infinite"}:void 0,children:y?"progress_activity":"science"})}),e.jsx("span",{className:"pointer-events-none absolute mt-1 top-5 left-1/2 -translate-x-1/2 text-[10px] text-text-muted whitespace-nowrap opacity-0 group-hover/btn:opacity-100 transition-opacity",children:y?"Testing...":"Test"})]}),e.jsxs("div",{className:"relative group/btn",children:[e.jsx("button",{onClick:()=>S(r,`model-${t.id}`),className:"p-0.5 hover:bg-sidebar rounded text-text-muted hover:text-primary",children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:i===`model-${t.id}`?"check":"content_copy"})}),e.jsx("span",{className:"pointer-events-none absolute mt-1 top-5 left-1/2 -translate-x-1/2 text-[10px] text-text-muted whitespace-nowrap opacity-0 group-hover/btn:opacity-100 transition-opacity",children:i===`model-${t.id}`?"Copied!":"Copy"})]}),d&&e.jsx("span",{className:"text-[10px] font-bold text-green-500 bg-green-500/10 px-1.5 py-0.5 rounded",children:"FREE"}),M&&e.jsx("button",{onClick:p,className:"p-0.5 hover:bg-red-500/10 rounded text-text-muted hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity ml-auto",title:"Remove custom model",children:e.jsx("span",{className:"material-symbols-outlined text-sm",children:"close"})})]})})}Xe.propTypes={model:w.shape({id:w.string.isRequired}).isRequired,fullModel:w.string.isRequired,copied:w.string,onCopy:w.func.isRequired,testStatus:w.oneOf(["ok","error"]),isCustom:w.bool,isFree:w.bool,onDeleteAlias:w.func,onTest:w.func,isTesting:w.bool};function kt({isOpen:t,onSave:r,onClose:i}){const[S,c]=s.useState(""),M=()=>{S.trim()&&(r(S.trim()),c(""))};return e.jsx(gt,{isOpen:t,title:"Add Custom Model",onClose:i,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-text-muted mb-1 block",children:"Model ID"}),e.jsx("input",{className:"w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",value:S,onChange:d=>c(d.target.value),onKeyDown:d=>d.key==="Enter"&&M(),placeholder:"e.g. tts-1-hd",autoFocus:!0})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(be,{onClick:M,fullWidth:!0,disabled:!S.trim(),children:"Add"}),e.jsx(be,{onClick:i,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})})}kt.propTypes={isOpen:w.bool.isRequired,onSave:w.func.isRequired,onClose:w.func.isRequired};function St({providerId:t,kindFilter:r,providerAliasOverride:i}){const{copied:S,copy:c}=ve(),[M,d]=s.useState({}),[p,h]=s.useState([]),[y,$]=s.useState({}),[R,A]=s.useState(null),[u,v]=s.useState(""),[U,O]=s.useState(!1),[L,I]=s.useState([]),j=i||Be(t),x=r||"llm",N=s.useCallback(async()=>{try{const[m,o,a]=await Promise.all([fetch("/api/models/alias"),fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/custom",{cache:"no-store"})]),g=await m.json(),P=await o.json(),K=await a.json();m.ok&&d(g.aliases||{}),o.ok&&I((P.connections||[]).filter(f=>f.provider===t)),a.ok&&h(K.models||[])}catch(m){console.log("ModelsCard fetch error:",m)}},[t]);s.useEffect(()=>{N()},[N]);const B=async(m,o)=>{const a=`${j}/${m}`;try{(await fetch("/api/models/alias",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:a,alias:o})})).ok&&await N()}catch(g){console.log("set alias error:",g)}},X=async m=>{try{(await fetch(`/api/models/alias?alias=${encodeURIComponent(m)}`,{method:"DELETE"})).ok&&await N()}catch(o){console.log("delete alias error:",o)}},Q=async m=>{try{(await fetch("/api/models/custom",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerAlias:j,id:m,type:x})})).ok&&(await N(),window.dispatchEvent(new CustomEvent("customModelChanged")))}catch(o){console.log("add custom model error:",o)}},V=async m=>{try{const o=new URLSearchParams({providerAlias:j,id:m,type:x});(await fetch(`/api/models/custom?${o}`,{method:"DELETE"})).ok&&(await N(),window.dispatchEvent(new CustomEvent("customModelChanged")))}catch(o){console.log("delete custom model error:",o)}},re=async m=>{if(!R){A(m);try{const a=await(await fetch("/api/models/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:`${j}/${m}`,kind:r})})).json();$(g=>({...g,[m]:a.ok?"ok":"error"})),v(a.ok?"":a.error||"Model not reachable")}catch{$(o=>({...o,[m]:"error"})),v("Network error")}finally{A(null)}}},ae=pe(t),H=r?ae.filter(m=>m.kinds?m.kinds.includes(r):(m.type||"llm")===r):ae,W=p.filter(m=>m.providerAlias===j&&(m.type||"llm")===x&&!H.some(o=>o.id===m.id)),le=H;return e.jsxs(e.Fragment,{children:[e.jsxs(we,{children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsxs("h2",{className:"text-lg font-semibold",children:["Models",r?` — ${r.toUpperCase()}`:""]})}),u&&e.jsx("p",{className:"text-xs text-red-500 mb-3 break-words",children:u}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[le.map(m=>{var g;const o=`${j}/${m.id}`,a=(g=Object.entries(M).find(([,P])=>P===o))==null?void 0:g[0];return e.jsx(Xe,{model:m,fullModel:`${j}/${m.id}`,alias:a,copied:S,onCopy:c,onSetAlias:P=>B(m.id,P),onDeleteAlias:()=>X(a),testStatus:y[m.id],onTest:L.length>0?()=>re(m.id):void 0,isTesting:R===m.id,isFree:m.isFree},m.id)}),W.map(m=>e.jsx(Xe,{model:{id:m.id,name:m.name},fullModel:`${j}/${m.id}`,copied:S,onCopy:c,onSetAlias:()=>{},onDeleteAlias:()=>V(m.id),testStatus:y[m.id],onTest:L.length>0?()=>re(m.id):void 0,isTesting:R===m.id,isCustom:!0},`${m.id}-${m.type}`)),e.jsxs("button",{onClick:()=>O(!0),className:"flex items-center gap-1.5 px-3 py-2 rounded-lg border border-dashed border-black/15 dark:border-white/15 text-xs text-text-muted hover:text-primary hover:border-primary/40 transition-colors",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"add"}),"Add Model"]})]})]}),e.jsx(kt,{isOpen:U,onSave:async m=>{await Q(m),O(!1)},onClose:()=>O(!1)})]})}St.propTypes={providerId:w.string.isRequired,kindFilter:w.string,providerAliasOverride:w.string};const xt={"google-tts":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"hardcoded"},openai:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"openai-tts-models",voiceKey:"openai-tts-voices",voicesPerModel:!0},openrouter:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"openrouter-tts-models",voiceKey:"openrouter-tts-voices",voicesPerModel:!0},elevenlabs:{hasLanguageDropdown:!1,hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",modelKey:"elevenlabs-tts-models",apiEndpoint:"/api/media-providers/tts/elevenlabs/voices"},"edge-tts":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language"},"local-device":{hasLanguageDropdown:!1,hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language"},nvidia:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},hyperbolic:{hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"config"},deepgram:{hasModelSelector:!1,hasBrowseButton:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/deepgram/voices"},huggingface:{hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"config"},cartesia:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},playht:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},coqui:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},tortoise:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},inworld:{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",modelKey:"inworld-tts-models",apiEndpoint:"/api/media-providers/tts/inworld/voices"},qwen:{hasModelSelector:!0,hasBrowseButton:!1,hasVoiceIdInput:!0,voiceSource:"config"},minimax:{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/minimax/voices",defaultVoiceId:"English_expressive_narrator"},"minimax-cn":{hasModelSelector:!0,hasBrowseButton:!0,hasVoiceIdInput:!0,voiceSource:"api-language",apiEndpoint:"/api/media-providers/tts/minimax/voices?provider=minimax-cn",defaultVoiceId:"English_expressive_narrator"},gemini:{hasLanguageDropdown:!1,hasLanguageHint:!0,hasModelSelector:!0,hasBrowseButton:!1,voiceSource:"hardcoded",modelKey:"gemini-tts-models",voiceKey:"gemini-tts-voices",voicesPerModel:!0}};function _({label:t,children:r}){return e.jsxs("div",{className:"flex min-w-0 flex-col gap-1.5 sm:flex-row sm:items-center sm:gap-3",children:[e.jsx("span",{className:"w-full text-xs font-medium text-text-muted sm:w-20 sm:shrink-0",children:t}),e.jsx("div",{className:"w-full min-w-0 flex-1",children:r})]})}const qt=`// Audio will appear here after running.
|
|
2
2
|
// Example JSON response (response_format=json):
|
|
3
3
|
{
|
|
4
4
|
"format": "mp3",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index.
|
|
1
|
+
import{j as e}from"./index.D4FwOBBU.js";import{b as n}from"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";function x(){const[s,a]=n.useState(null),[c,r]=n.useState(!1),i=async m=>{const o=m.target.files[0];if(!o)return;r(!0);const l=new FormData;l.append("file",o);try{const t=await fetch("/api/ocr",{method:"POST",body:l});a(await t.json())}catch(t){a({error:t.message})}r(!1)};return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsx("h1",{className:"text-2xl font-bold",children:"OCR"}),e.jsx("p",{className:"text-text-muted",children:"Extract text from images using Mistral OCR API"}),e.jsx("input",{type:"file",accept:"image/*,.pdf",onChange:i,className:"block"}),c&&e.jsx("p",{children:"Processing..."}),s&&e.jsx("pre",{className:"p-4 bg-black/5 rounded-lg text-sm overflow-auto max-h-96",children:JSON.stringify(s,null,2)})]})}export{x as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index.
|
|
1
|
+
import{j as e}from"./index.D4FwOBBU.js";import{b as r}from"./router.Cjj1--8t.js";import{C as j}from"./Loading.C1il44u0.js";import"./zustand.akaTi5uX.js";function P(){return e.jsx(r.Suspense,{fallback:e.jsx(j,{}),children:e.jsx(v,{})})}function v(){const[o,u]=r.useState([]),[p,b]=r.useState(!0),[s,f]=r.useState(""),[a,n]=r.useState(null),[i,d]=r.useState(!1),[l,x]=r.useState(""),[c,m]=r.useState(null);r.useEffect(()=>{fetch("/api/media-providers/moderation").then(t=>t.json()).then(t=>{u(Array.isArray(t)?t:[]),t.length>0&&x(t[0].id)}).catch(()=>{}).finally(()=>b(!1))},[]);const h=async()=>{if(s.trim()){d(!0),m(null),n(null);try{const t=await fetch("/api/media/moderation",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({input:s,providerId:l||void 0})});if(!t.ok)throw new Error(`HTTP ${t.status}`);const g=await t.json();n(g)}catch(t){m(t.message)}finally{d(!1)}}};return e.jsxs("div",{className:"flex min-w-0 flex-col gap-6 px-1 sm:px-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"material-symbols-outlined text-[28px] text-primary",children:"shield"}),e.jsx("h1",{className:"text-xl font-semibold text-text-main",children:"Moderations"})]}),e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Moderation Providers"}),p?e.jsx("p",{className:"text-xs text-text-muted",children:"Loading providers..."}):o.length===0?e.jsx("p",{className:"text-xs text-text-muted",children:"No moderation providers configured. Add one in Media Providers."}):e.jsx("div",{className:"flex flex-wrap gap-2",children:o.map(t=>e.jsx("button",{onClick:()=>x(t.id),className:`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors cursor-pointer ${l===t.id?"bg-primary/10 text-primary border border-primary/30":"bg-surface-2 text-text-muted hover:text-text-main border border-transparent"}`,children:t.name||t.id},t.id))})]}),e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Test Moderation"}),e.jsx("textarea",{value:s,onChange:t=>f(t.target.value),placeholder:"Enter text to moderate...",rows:4,className:"w-full rounded-lg border border-border-subtle bg-surface-2 px-3 py-2 text-sm text-text-main placeholder:text-text-muted/50 focus:outline-none focus:ring-1 focus:ring-primary/50 resize-none mb-3"}),e.jsx("button",{onClick:h,disabled:i||!s.trim(),className:"px-4 py-2 rounded-lg bg-primary text-white text-sm font-medium hover:bg-primary/90 disabled:opacity-50 transition-colors cursor-pointer",children:i?"Testing...":"Run Moderation"})]}),c&&e.jsx("div",{className:"rounded-xl border border-red-500/30 bg-red-500/10 p-4",children:e.jsx("p",{className:"text-sm text-red-400",children:c})}),a&&e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Result"}),e.jsx("pre",{className:"text-xs text-text-muted overflow-auto max-h-96 bg-surface-2 rounded-lg p-3 font-mono whitespace-pre-wrap",children:JSON.stringify(a,null,2)})]})]})}export{P as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,P as i,u as d}from"./index.Be3gbrBl.js";import{b as l,d as n}from"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";function c(){const[t,r]=l.useState(!1),s=n();return e.jsxs("nav",{className:"fixed top-0 z-50 w-full bg-[#181411]/80 backdrop-blur-md border-b border-[#3a2f27]",children:[e.jsxs("div",{className:"max-w-7xl mx-auto px-6 h-16 flex items-center justify-between",children:[e.jsxs("button",{type:"button",className:"flex items-center gap-3 cursor-pointer bg-transparent border-none p-0",onClick:()=>s("/"),"aria-label":"Navigate to home",children:[e.jsx("img",{src:"/logo_fsrouter.png",alt:"FSRouter v2",className:"size-8 rounded object-cover"}),e.jsx("h2",{className:"text-white text-xl font-bold tracking-tight",children:"FSRouter"})]}),e.jsxs("div",{className:"hidden md:flex items-center gap-8",children:[e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#features",children:"Features"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#how-it-works",children:"How it Works"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Docs"}),e.jsxs("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors flex items-center gap-1",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:["GitHub ",e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"open_in_new"})]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("button",{onClick:()=>s("/dashboard"),className:"hidden sm:flex h-9 items-center justify-center rounded-lg px-4 bg-[#f97815] hover:bg-[#e0650a] transition-all text-[#181411] text-sm font-bold shadow-[0_0_15px_rgba(249,120,21,0.4)] hover:shadow-[0_0_20px_rgba(249,120,21,0.6)]",children:"Get Started"}),e.jsx("button",{className:"md:hidden text-white",onClick:()=>r(!t),children:e.jsx("span",{className:"material-symbols-outlined",children:t?"close":"menu"})})]})]}),t&&e.jsx("div",{className:"md:hidden border-t border-[#3a2f27] bg-[#181411]/95 backdrop-blur-md",children:e.jsxs("div",{className:"flex flex-col gap-4 p-6",children:[e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#features",onClick:()=>r(!1),children:"Features"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#how-it-works",onClick:()=>r(!1),children:"How it Works"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Docs"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("button",{onClick:()=>s("/dashboard"),className:"h-9 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-sm font-bold",children:"Get Started"})]})})]})}function x(){return e.jsxs("section",{className:"relative pt-32 pb-20 px-6 min-h-[90vh] flex flex-col items-center justify-center overflow-hidden",children:[e.jsx("div",{className:"absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[500px] bg-[#f97815]/10 rounded-full blur-[120px] pointer-events-none"}),e.jsxs("div",{className:"relative z-10 max-w-4xl w-full text-center flex flex-col items-center gap-8",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full border border-[#3a2f27] bg-[#23180f]/50 px-3 py-1 text-xs font-medium text-[#f97815]",children:[e.jsx("span",{className:"flex h-2 w-2 rounded-full bg-[#f97815] animate-pulse"}),"v1.0 is now live"]}),e.jsxs("h1",{className:"text-5xl md:text-7xl font-black leading-[1.1] tracking-tight",children:["One Endpoint for ",e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:"All AI Providers"})]}),e.jsx("p",{className:"text-lg md:text-xl text-gray-400 max-w-2xl mx-auto font-light",children:"AI endpoint proxy with web dashboard - A JavaScript port of CLIProxyAPI. Works seamlessly with Claude Code, OpenAI Codex, Cline, RooCode, and other CLI tools."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-4 w-full",children:[e.jsxs("button",{className:"h-12 px-8 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-base font-bold transition-all shadow-[0_0_15px_rgba(249,120,21,0.4)] flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined",children:"rocket_launch"}),"Get Started"]}),e.jsxs("a",{href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",className:"h-12 px-8 rounded-lg border border-[#3a2f27] bg-[#23180f] hover:bg-[#3a2f27] text-white text-base font-bold transition-all flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined",children:"code"}),"View on GitHub"]})]})]})]})}const m=[{id:"claude",name:"Claude Code",image:"/providers/claude.png"},{id:"codex",name:"OpenAI Codex",image:"/providers/codex.png"},{id:"cline",name:"Cline",image:"/providers/cline.png"},{id:"cursor",name:"Cursor",image:"/providers/cursor.png"}],o=[{id:"openai",name:"OpenAI",color:"bg-emerald-500",textColor:"text-white"},{id:"anthropic",name:"Anthropic",color:"bg-orange-400",textColor:"text-white"},{id:"gemini",name:"Gemini",color:"bg-blue-500",textColor:"text-white"},{id:"github",name:"GitHub Copilot",color:"bg-gray-700",textColor:"text-white"}];function h(){const[t,r]=l.useState(0);return l.useEffect(()=>{const s=setInterval(()=>{r(a=>(a+1)%o.length)},2e3);return()=>clearInterval(s)},[]),e.jsxs("div",{className:"mt-16 w-full max-w-4xl relative h-[360px] hidden md:flex items-center justify-center animate-[float_6s_ease-in-out_infinite]",children:[e.jsxs("div",{className:"relative z-20 w-32 h-32 rounded-full bg-[#23180f] border-2 border-[#f97815] shadow-[0_0_40px_rgba(249,120,21,0.3)] flex flex-col items-center justify-center gap-1 group cursor-pointer hover:scale-105 transition-transform duration-500",children:[e.jsx("span",{className:"material-symbols-outlined text-4xl text-[#f97815]",children:"hub"}),e.jsx("span",{className:"text-xs font-bold text-white tracking-widest uppercase",children:"FSRouter"}),e.jsx("div",{className:"absolute inset-0 rounded-full border border-[#f97815]/30 animate-ping opacity-20"})]}),e.jsx("div",{className:"absolute left-0 top-1/2 -translate-y-1/2 flex flex-col gap-7",children:m.map(s=>e.jsx("div",{className:"flex items-center gap-3 opacity-70 hover:opacity-100 transition-opacity group",children:e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[#23180f] border border-[#3a2f27] flex items-center justify-center overflow-hidden p-2 hover:border-[#f97815]/50 transition-all hover:scale-105",children:e.jsx(i,{src:s.image,alt:s.name,size:48,className:"object-contain rounded-xl max-w-[48px] max-h-[48px]",fallbackText:s.name.slice(0,2).toUpperCase()})})},s.id))}),e.jsxs("svg",{className:"absolute inset-0 w-full h-full z-10 pointer-events-none stroke-yellow-700",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 50 C 250 70, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 140 C 250 140, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 210 C 250 210, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 300 C 250 280, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"})]}),e.jsxs("svg",{className:"absolute inset-0 w-full h-full z-10 pointer-events-none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M 440 180 C 550 180, 550 50, 740 50",fill:"none",stroke:t===0?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===0?"3":"2",className:t===0?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 130, 740 130",fill:"none",stroke:t===1?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===1?"3":"2",className:t===1?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 230, 740 230",fill:"none",stroke:t===2?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===2?"3":"2",className:t===2?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 310, 740 310",fill:"none",stroke:t===3?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===3?"3":"2",className:t===3?"animate-pulse":""})]}),e.jsx("div",{className:"absolute right-0 top-0 bottom-0 flex flex-col justify-between py-6",children:o.map((s,a)=>e.jsx("div",{className:`px-4 py-2 rounded-lg ${s.color} ${s.textColor} flex items-center justify-center font-bold text-xs shadow-lg hover:scale-110 transition-all cursor-help min-w-[140px] ${t===a?"ring-4 ring-[#f97815]/50 scale-110":""}`,title:s.name,children:s.name},s.id))}),e.jsx("div",{className:"md:hidden mt-8 w-full p-4 rounded-lg bg-[#23180f] border border-[#3a2f27]",children:e.jsx("p",{className:"text-sm text-center text-gray-400",children:"Interactive diagram visible on desktop"})})]})}function u(){return e.jsx("section",{className:"py-24 border-y border-[#3a2f27] bg-[#23180f]/30",id:"how-it-works",children:e.jsxs("div",{className:"max-w-7xl mx-auto px-6",children:[e.jsxs("div",{className:"mb-16",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-4",children:"How FSRouter Works"}),e.jsx("p",{className:"text-gray-400 max-w-xl text-lg",children:"Data flows seamlessly from your application through our intelligent routing layer to the best provider for the job."})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 relative",children:[e.jsx("div",{className:"hidden md:block absolute top-12 left-[16%] right-[16%] h-[2px] bg-linear-to-r from-gray-700 via-[#f97815] to-gray-700 -z-10"}),e.jsxs("div",{className:"flex flex-col gap-6 relative group",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0",children:e.jsx("span",{className:"material-symbols-outlined text-4xl text-gray-300",children:"terminal"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2",children:"1. CLI & SDKs"}),e.jsx("p",{className:"text-sm text-gray-400",children:"Your requests start from your favorite tools or our unified SDK. Just change the base URL."})]})]}),e.jsxs("div",{className:"flex flex-col gap-6 relative group md:items-center md:text-center",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border-2 border-[#f97815] flex items-center justify-center shadow-[0_0_30px_rgba(249,120,21,0.2)] z-10 mx-auto",children:e.jsx("span",{className:"material-symbols-outlined text-4xl text-[#f97815] animate-pulse",children:"hub"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2 text-[#f97815]",children:"2. FSRouter Hub"}),e.jsx("p",{className:"text-sm text-gray-400",children:"Our engine analyzes the prompt, checks provider health, and routes for lowest latency or cost."})]})]}),e.jsxs("div",{className:"flex flex-col gap-6 relative group md:items-end md:text-right",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0",children:e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"})]})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2",children:"3. AI Providers"}),e.jsx("p",{className:"text-sm text-gray-400",children:"The request is fulfilled by OpenAI, Anthropic, Gemini, or others instantly."})]})]})]})]})})}const f=[{icon:"link",title:"Unified Endpoint",desc:"Access all providers via a single standard API URL.",colors:{border:"hover:border-blue-500/50",bg:"hover:bg-blue-500/5",iconBg:"bg-blue-500/10",iconText:"text-blue-500",titleHover:"group-hover:text-blue-400"}},{icon:"bolt",title:"Easy Setup",desc:"Get up and running in minutes with npx command.",colors:{border:"hover:border-orange-500/50",bg:"hover:bg-orange-500/5",iconBg:"bg-orange-500/10",iconText:"text-orange-500",titleHover:"group-hover:text-orange-400"}},{icon:"shield_with_heart",title:"Model Fallback",desc:"Automatically switch providers on failure or high latency.",colors:{border:"hover:border-rose-500/50",bg:"hover:bg-rose-500/5",iconBg:"bg-rose-500/10",iconText:"text-rose-500",titleHover:"group-hover:text-rose-400"}},{icon:"monitoring",title:"Usage Tracking",desc:"Detailed analytics and cost monitoring across all models.",colors:{border:"hover:border-purple-500/50",bg:"hover:bg-purple-500/5",iconBg:"bg-purple-500/10",iconText:"text-purple-500",titleHover:"group-hover:text-purple-400"}},{icon:"key",title:"OAuth & API Keys",desc:"Securely manage credentials in one vault.",colors:{border:"hover:border-amber-500/50",bg:"hover:bg-amber-500/5",iconBg:"bg-amber-500/10",iconText:"text-amber-500",titleHover:"group-hover:text-amber-400"}},{icon:"cloud_sync",title:"Cloud Sync",desc:"Sync your configurations across devices instantly.",colors:{border:"hover:border-sky-500/50",bg:"hover:bg-sky-500/5",iconBg:"bg-sky-500/10",iconText:"text-sky-500",titleHover:"group-hover:text-sky-400"}},{icon:"terminal",title:"CLI Support",desc:"Works with Claude Code, Codex, Cline, Cursor, and more.",colors:{border:"hover:border-emerald-500/50",bg:"hover:bg-emerald-500/5",iconBg:"bg-emerald-500/10",iconText:"text-emerald-500",titleHover:"group-hover:text-emerald-400"}},{icon:"dashboard",title:"Dashboard",desc:"Visual dashboard for real-time traffic analysis.",colors:{border:"hover:border-fuchsia-500/50",bg:"hover:bg-fuchsia-500/5",iconBg:"bg-fuchsia-500/10",iconText:"text-fuchsia-500",titleHover:"group-hover:text-fuchsia-400"}}];function g(){return e.jsx("section",{className:"py-24 px-6",id:"features",children:e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"mb-16",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-4",children:"Powerful Features"}),e.jsx("p",{className:"text-gray-400 max-w-xl text-lg",children:"Everything you need to manage your AI infrastructure in one place, built for scale."})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:f.map(t=>e.jsxs("div",{className:`p-6 rounded-xl bg-[#23180f] border border-[#3a2f27] ${t.colors.border} ${t.colors.bg} transition-all duration-300 group`,children:[e.jsx("div",{className:`w-10 h-10 rounded-lg ${t.colors.iconBg} flex items-center justify-center mb-4 ${t.colors.iconText} group-hover:scale-110 transition-transform duration-300`,children:e.jsx("span",{className:"material-symbols-outlined",children:t.icon})}),e.jsx("h3",{className:`text-lg font-bold mb-2 ${t.colors.titleHover} transition-colors`,children:t.title}),e.jsx("p",{className:"text-sm text-gray-400 leading-relaxed",children:t.desc})]},t.title))})]})})}function b(){const{copied:t,copy:r}=d(),s=a=>{r(a,"landing")};return e.jsx("section",{className:"py-24 px-6 bg-[#120f0d]",children:e.jsx("div",{className:"max-w-7xl mx-auto",children:e.jsxs("div",{className:"flex flex-col lg:flex-row gap-16 items-start",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-6",children:"Get Started in 30 Seconds"}),e.jsx("p",{className:"text-gray-400 text-lg mb-8",children:"Install FSRouter, configure your providers via web dashboard, and start routing AI requests."}),e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"1"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Install FSRouter"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Run npx command to start the server instantly"})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"2"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Open Dashboard"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Configure providers and API keys via web interface"})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"3"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Route Requests"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Point your CLI tools to http://localhost:20128"})]})]})]})]}),e.jsx("div",{className:"flex-1 w-full",children:e.jsxs("div",{className:"rounded-xl overflow-hidden bg-[#1e1e1e] border border-[#3a2f27] shadow-2xl",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 bg-[#252526] border-b border-gray-700",children:[e.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"}),e.jsx("div",{className:"ml-2 text-xs text-gray-500 font-mono",children:"terminal"})]}),e.jsxs("div",{className:"p-6 font-mono text-sm leading-relaxed overflow-x-auto",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4 group cursor-pointer",onClick:()=>s("npx fsrouter"),children:[e.jsx("span",{className:"text-green-400",children:"$"}),e.jsx("span",{className:"text-white",children:"npx fsrouter"}),e.jsx("span",{className:"ml-auto text-gray-500 text-xs opacity-0 group-hover:opacity-100",children:t==="landing"?"✓ Copied":"Copy"})]}),e.jsxs("div",{className:"text-gray-400 mb-6",children:[e.jsx("span",{className:"text-[#f97815]",children:">"})," Starting FSRouter...",e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:">"})," Server running on ",e.jsx("span",{className:"text-blue-400",children:"http://localhost:20128"}),e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:">"})," Dashboard: ",e.jsx("span",{className:"text-blue-400",children:"http://localhost:20128/dashboard"}),e.jsx("br",{}),e.jsx("span",{className:"text-green-400",children:">"})," Ready to route! ✓"]}),e.jsx("div",{className:"text-xs text-gray-500 mb-2 border-t border-gray-700 pt-4",children:"📝 Configure providers in dashboard or use environment variables"}),e.jsxs("div",{className:"text-gray-400 text-xs",children:[e.jsx("span",{className:"text-purple-400",children:"Data Location:"}),e.jsx("br",{}),e.jsx("span",{className:"text-gray-500",children:" macOS/Linux:"})," ~/.fsrouter/db/data.sqlite",e.jsx("br",{}),e.jsx("span",{className:"text-gray-500",children:" Windows:"})," %APPDATA%/fsrouter/db/data.sqlite"]})]})]})})]})})})}function p(){return e.jsx("footer",{className:"border-t border-[#3a2f27] bg-[#120f0d] pt-16 pb-8 px-6",children:e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 mb-16",children:[e.jsxs("div",{className:"col-span-2 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"size-6 rounded bg-[#f97815] flex items-center justify-center text-white",children:e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"hub"})}),e.jsx("h3",{className:"text-white text-lg font-bold",children:"FSRouter"})]}),e.jsx("p",{className:"text-gray-500 text-sm max-w-xs mb-6",children:"The unified endpoint for AI generation. Connect, route, and manage your AI providers with ease."}),e.jsx("div",{className:"flex gap-4",children:e.jsx("a",{className:"text-gray-400 hover:text-white transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:e.jsx("span",{className:"material-symbols-outlined",children:"code"})})})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Product"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"#features",children:"Features"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"/dashboard",children:"Dashboard"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"Changelog"})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Resources"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Documentation"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://www.npmjs.com/package/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"NPM"})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Legal"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer",children:"MIT License"})]})]}),e.jsxs("div",{className:"border-t border-[#3a2f27] pt-8 flex flex-col md:flex-row justify-between items-center gap-4",children:[e.jsx("p",{className:"text-gray-600 text-sm",children:"© 2025 FSRouter. All rights reserved."}),e.jsxs("div",{className:"flex gap-6",children:[e.jsx("a",{className:"text-gray-600 hover:text-white text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("a",{className:"text-gray-600 hover:text-white text-sm transition-colors",href:"https://www.npmjs.com/package/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"NPM"})]})]})]})})}function w(){const t=n();return e.jsxs("div",{className:"relative text-white font-sans overflow-x-hidden antialiased selection:bg-[#f97815] selection:text-white",children:[e.jsxs("div",{className:"fixed inset-0 z-0 overflow-hidden pointer-events-none bg-[#181411]",children:[e.jsx("div",{className:"absolute inset-0 opacity-[0.06]",style:{backgroundImage:"linear-gradient(to right, #f97815 1px, transparent 1px), linear-gradient(to bottom, #f97815 1px, transparent 1px)",backgroundSize:"50px 50px"}}),e.jsx("div",{className:"absolute top-0 left-1/4 w-[700px] h-[700px] bg-[#f97815]/12 rounded-full blur-[130px] animate-blob"}),e.jsx("div",{className:"absolute top-1/3 right-1/4 w-[600px] h-[600px] bg-purple-500/10 rounded-full blur-[130px] animate-blob",style:{animationDelay:"2s",animationDuration:"22s"}}),e.jsx("div",{className:"absolute bottom-0 left-1/2 w-[650px] h-[650px] bg-blue-500/8 rounded-full blur-[130px] animate-blob",style:{animationDelay:"4s",animationDuration:"25s"}}),e.jsx("div",{className:"absolute inset-0",style:{background:"radial-gradient(circle at center, transparent 0%, rgba(24, 20, 17, 0.4) 100%)"}})]}),e.jsxs("div",{className:"relative z-10",children:[e.jsx(c,{}),e.jsxs("main",{children:[e.jsxs("div",{className:"relative",children:[e.jsx(x,{}),e.jsx("div",{className:"flex justify-center pb-20",children:e.jsx(h,{})})]}),e.jsx(b,{}),e.jsx(u,{}),e.jsx(g,{}),e.jsxs("section",{className:"py-32 px-6 relative overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 bg-linear-to-t from-[#f97815]/5 to-transparent pointer-events-none"}),e.jsxs("div",{className:"max-w-4xl mx-auto text-center relative z-10",children:[e.jsx("h2",{className:"text-4xl md:text-5xl font-black mb-6",children:"Ready to Simplify Your AI Infrastructure?"}),e.jsx("p",{className:"text-xl text-gray-400 mb-10 max-w-2xl mx-auto",children:"Join developers who are streamlining their AI integrations with FSRouter. Open source and free to start."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[e.jsx("button",{onClick:()=>t("/dashboard"),className:"w-full sm:w-auto h-14 px-10 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-lg font-bold transition-all shadow-[0_0_20px_rgba(249,120,21,0.5)]",children:"Start Free"}),e.jsx("button",{onClick:()=>window.open("https://github.com/nexusrouters/fsrouter#readme","_blank"),className:"w-full sm:w-auto h-14 px-10 rounded-lg border border-[#3a2f27] hover:bg-[#23180f] text-white text-lg font-bold transition-all",children:"Read Documentation"})]})]})]})]}),e.jsx(p,{})]})]})}export{w as default};
|
|
1
|
+
import{j as e,P as i,u as d}from"./index.D4FwOBBU.js";import{b as l,d as n}from"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";function c(){const[t,r]=l.useState(!1),s=n();return e.jsxs("nav",{className:"fixed top-0 z-50 w-full bg-[#181411]/80 backdrop-blur-md border-b border-[#3a2f27]",children:[e.jsxs("div",{className:"max-w-7xl mx-auto px-6 h-16 flex items-center justify-between",children:[e.jsxs("button",{type:"button",className:"flex items-center gap-3 cursor-pointer bg-transparent border-none p-0",onClick:()=>s("/"),"aria-label":"Navigate to home",children:[e.jsx("img",{src:"/logo_fsrouter.png",alt:"FSRouter v2",className:"size-8 rounded object-cover"}),e.jsx("h2",{className:"text-white text-xl font-bold tracking-tight",children:"FSRouter"})]}),e.jsxs("div",{className:"hidden md:flex items-center gap-8",children:[e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#features",children:"Features"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#how-it-works",children:"How it Works"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Docs"}),e.jsxs("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors flex items-center gap-1",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:["GitHub ",e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"open_in_new"})]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("button",{onClick:()=>s("/dashboard"),className:"hidden sm:flex h-9 items-center justify-center rounded-lg px-4 bg-[#f97815] hover:bg-[#e0650a] transition-all text-[#181411] text-sm font-bold shadow-[0_0_15px_rgba(249,120,21,0.4)] hover:shadow-[0_0_20px_rgba(249,120,21,0.6)]",children:"Get Started"}),e.jsx("button",{className:"md:hidden text-white",onClick:()=>r(!t),children:e.jsx("span",{className:"material-symbols-outlined",children:t?"close":"menu"})})]})]}),t&&e.jsx("div",{className:"md:hidden border-t border-[#3a2f27] bg-[#181411]/95 backdrop-blur-md",children:e.jsxs("div",{className:"flex flex-col gap-4 p-6",children:[e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#features",onClick:()=>r(!1),children:"Features"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"#how-it-works",onClick:()=>r(!1),children:"How it Works"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Docs"}),e.jsx("a",{className:"text-gray-300 hover:text-white text-sm font-medium transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("button",{onClick:()=>s("/dashboard"),className:"h-9 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-sm font-bold",children:"Get Started"})]})})]})}function x(){return e.jsxs("section",{className:"relative pt-32 pb-20 px-6 min-h-[90vh] flex flex-col items-center justify-center overflow-hidden",children:[e.jsx("div",{className:"absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[500px] bg-[#f97815]/10 rounded-full blur-[120px] pointer-events-none"}),e.jsxs("div",{className:"relative z-10 max-w-4xl w-full text-center flex flex-col items-center gap-8",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full border border-[#3a2f27] bg-[#23180f]/50 px-3 py-1 text-xs font-medium text-[#f97815]",children:[e.jsx("span",{className:"flex h-2 w-2 rounded-full bg-[#f97815] animate-pulse"}),"v1.0 is now live"]}),e.jsxs("h1",{className:"text-5xl md:text-7xl font-black leading-[1.1] tracking-tight",children:["One Endpoint for ",e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:"All AI Providers"})]}),e.jsx("p",{className:"text-lg md:text-xl text-gray-400 max-w-2xl mx-auto font-light",children:"AI endpoint proxy with web dashboard - A JavaScript port of CLIProxyAPI. Works seamlessly with Claude Code, OpenAI Codex, Cline, RooCode, and other CLI tools."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-4 w-full",children:[e.jsxs("button",{className:"h-12 px-8 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-base font-bold transition-all shadow-[0_0_15px_rgba(249,120,21,0.4)] flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined",children:"rocket_launch"}),"Get Started"]}),e.jsxs("a",{href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",className:"h-12 px-8 rounded-lg border border-[#3a2f27] bg-[#23180f] hover:bg-[#3a2f27] text-white text-base font-bold transition-all flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined",children:"code"}),"View on GitHub"]})]})]})]})}const m=[{id:"claude",name:"Claude Code",image:"/providers/claude.png"},{id:"codex",name:"OpenAI Codex",image:"/providers/codex.png"},{id:"cline",name:"Cline",image:"/providers/cline.png"},{id:"cursor",name:"Cursor",image:"/providers/cursor.png"}],o=[{id:"openai",name:"OpenAI",color:"bg-emerald-500",textColor:"text-white"},{id:"anthropic",name:"Anthropic",color:"bg-orange-400",textColor:"text-white"},{id:"gemini",name:"Gemini",color:"bg-blue-500",textColor:"text-white"},{id:"github",name:"GitHub Copilot",color:"bg-gray-700",textColor:"text-white"}];function h(){const[t,r]=l.useState(0);return l.useEffect(()=>{const s=setInterval(()=>{r(a=>(a+1)%o.length)},2e3);return()=>clearInterval(s)},[]),e.jsxs("div",{className:"mt-16 w-full max-w-4xl relative h-[360px] hidden md:flex items-center justify-center animate-[float_6s_ease-in-out_infinite]",children:[e.jsxs("div",{className:"relative z-20 w-32 h-32 rounded-full bg-[#23180f] border-2 border-[#f97815] shadow-[0_0_40px_rgba(249,120,21,0.3)] flex flex-col items-center justify-center gap-1 group cursor-pointer hover:scale-105 transition-transform duration-500",children:[e.jsx("span",{className:"material-symbols-outlined text-4xl text-[#f97815]",children:"hub"}),e.jsx("span",{className:"text-xs font-bold text-white tracking-widest uppercase",children:"FSRouter"}),e.jsx("div",{className:"absolute inset-0 rounded-full border border-[#f97815]/30 animate-ping opacity-20"})]}),e.jsx("div",{className:"absolute left-0 top-1/2 -translate-y-1/2 flex flex-col gap-7",children:m.map(s=>e.jsx("div",{className:"flex items-center gap-3 opacity-70 hover:opacity-100 transition-opacity group",children:e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[#23180f] border border-[#3a2f27] flex items-center justify-center overflow-hidden p-2 hover:border-[#f97815]/50 transition-all hover:scale-105",children:e.jsx(i,{src:s.image,alt:s.name,size:48,className:"object-contain rounded-xl max-w-[48px] max-h-[48px]",fallbackText:s.name.slice(0,2).toUpperCase()})})},s.id))}),e.jsxs("svg",{className:"absolute inset-0 w-full h-full z-10 pointer-events-none stroke-yellow-700",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 50 C 250 70, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 140 C 250 140, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 210 C 250 210, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"}),e.jsx("path",{className:"animate-[dash_2s_linear_infinite]",d:"M 60 300 C 250 280, 250 180, 360 180",fill:"none",strokeDasharray:"5,5",strokeWidth:"2"})]}),e.jsxs("svg",{className:"absolute inset-0 w-full h-full z-10 pointer-events-none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M 440 180 C 550 180, 550 50, 740 50",fill:"none",stroke:t===0?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===0?"3":"2",className:t===0?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 130, 740 130",fill:"none",stroke:t===1?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===1?"3":"2",className:t===1?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 230, 740 230",fill:"none",stroke:t===2?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===2?"3":"2",className:t===2?"animate-pulse":""}),e.jsx("path",{d:"M 440 180 C 550 180, 550 310, 740 310",fill:"none",stroke:t===3?"#f97815":"rgb(75, 85, 99)",strokeWidth:t===3?"3":"2",className:t===3?"animate-pulse":""})]}),e.jsx("div",{className:"absolute right-0 top-0 bottom-0 flex flex-col justify-between py-6",children:o.map((s,a)=>e.jsx("div",{className:`px-4 py-2 rounded-lg ${s.color} ${s.textColor} flex items-center justify-center font-bold text-xs shadow-lg hover:scale-110 transition-all cursor-help min-w-[140px] ${t===a?"ring-4 ring-[#f97815]/50 scale-110":""}`,title:s.name,children:s.name},s.id))}),e.jsx("div",{className:"md:hidden mt-8 w-full p-4 rounded-lg bg-[#23180f] border border-[#3a2f27]",children:e.jsx("p",{className:"text-sm text-center text-gray-400",children:"Interactive diagram visible on desktop"})})]})}function u(){return e.jsx("section",{className:"py-24 border-y border-[#3a2f27] bg-[#23180f]/30",id:"how-it-works",children:e.jsxs("div",{className:"max-w-7xl mx-auto px-6",children:[e.jsxs("div",{className:"mb-16",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-4",children:"How FSRouter Works"}),e.jsx("p",{className:"text-gray-400 max-w-xl text-lg",children:"Data flows seamlessly from your application through our intelligent routing layer to the best provider for the job."})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 relative",children:[e.jsx("div",{className:"hidden md:block absolute top-12 left-[16%] right-[16%] h-[2px] bg-linear-to-r from-gray-700 via-[#f97815] to-gray-700 -z-10"}),e.jsxs("div",{className:"flex flex-col gap-6 relative group",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0",children:e.jsx("span",{className:"material-symbols-outlined text-4xl text-gray-300",children:"terminal"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2",children:"1. CLI & SDKs"}),e.jsx("p",{className:"text-sm text-gray-400",children:"Your requests start from your favorite tools or our unified SDK. Just change the base URL."})]})]}),e.jsxs("div",{className:"flex flex-col gap-6 relative group md:items-center md:text-center",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border-2 border-[#f97815] flex items-center justify-center shadow-[0_0_30px_rgba(249,120,21,0.2)] z-10 mx-auto",children:e.jsx("span",{className:"material-symbols-outlined text-4xl text-[#f97815] animate-pulse",children:"hub"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2 text-[#f97815]",children:"2. FSRouter Hub"}),e.jsx("p",{className:"text-sm text-gray-400",children:"Our engine analyzes the prompt, checks provider health, and routes for lowest latency or cost."})]})]}),e.jsxs("div",{className:"flex flex-col gap-6 relative group md:items-end md:text-right",children:[e.jsx("div",{className:"w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0",children:e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"}),e.jsx("div",{className:"w-6 h-6 rounded bg-white/10"})]})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-bold mb-2",children:"3. AI Providers"}),e.jsx("p",{className:"text-sm text-gray-400",children:"The request is fulfilled by OpenAI, Anthropic, Gemini, or others instantly."})]})]})]})]})})}const f=[{icon:"link",title:"Unified Endpoint",desc:"Access all providers via a single standard API URL.",colors:{border:"hover:border-blue-500/50",bg:"hover:bg-blue-500/5",iconBg:"bg-blue-500/10",iconText:"text-blue-500",titleHover:"group-hover:text-blue-400"}},{icon:"bolt",title:"Easy Setup",desc:"Get up and running in minutes with npx command.",colors:{border:"hover:border-orange-500/50",bg:"hover:bg-orange-500/5",iconBg:"bg-orange-500/10",iconText:"text-orange-500",titleHover:"group-hover:text-orange-400"}},{icon:"shield_with_heart",title:"Model Fallback",desc:"Automatically switch providers on failure or high latency.",colors:{border:"hover:border-rose-500/50",bg:"hover:bg-rose-500/5",iconBg:"bg-rose-500/10",iconText:"text-rose-500",titleHover:"group-hover:text-rose-400"}},{icon:"monitoring",title:"Usage Tracking",desc:"Detailed analytics and cost monitoring across all models.",colors:{border:"hover:border-purple-500/50",bg:"hover:bg-purple-500/5",iconBg:"bg-purple-500/10",iconText:"text-purple-500",titleHover:"group-hover:text-purple-400"}},{icon:"key",title:"OAuth & API Keys",desc:"Securely manage credentials in one vault.",colors:{border:"hover:border-amber-500/50",bg:"hover:bg-amber-500/5",iconBg:"bg-amber-500/10",iconText:"text-amber-500",titleHover:"group-hover:text-amber-400"}},{icon:"cloud_sync",title:"Cloud Sync",desc:"Sync your configurations across devices instantly.",colors:{border:"hover:border-sky-500/50",bg:"hover:bg-sky-500/5",iconBg:"bg-sky-500/10",iconText:"text-sky-500",titleHover:"group-hover:text-sky-400"}},{icon:"terminal",title:"CLI Support",desc:"Works with Claude Code, Codex, Cline, Cursor, and more.",colors:{border:"hover:border-emerald-500/50",bg:"hover:bg-emerald-500/5",iconBg:"bg-emerald-500/10",iconText:"text-emerald-500",titleHover:"group-hover:text-emerald-400"}},{icon:"dashboard",title:"Dashboard",desc:"Visual dashboard for real-time traffic analysis.",colors:{border:"hover:border-fuchsia-500/50",bg:"hover:bg-fuchsia-500/5",iconBg:"bg-fuchsia-500/10",iconText:"text-fuchsia-500",titleHover:"group-hover:text-fuchsia-400"}}];function g(){return e.jsx("section",{className:"py-24 px-6",id:"features",children:e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"mb-16",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-4",children:"Powerful Features"}),e.jsx("p",{className:"text-gray-400 max-w-xl text-lg",children:"Everything you need to manage your AI infrastructure in one place, built for scale."})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:f.map(t=>e.jsxs("div",{className:`p-6 rounded-xl bg-[#23180f] border border-[#3a2f27] ${t.colors.border} ${t.colors.bg} transition-all duration-300 group`,children:[e.jsx("div",{className:`w-10 h-10 rounded-lg ${t.colors.iconBg} flex items-center justify-center mb-4 ${t.colors.iconText} group-hover:scale-110 transition-transform duration-300`,children:e.jsx("span",{className:"material-symbols-outlined",children:t.icon})}),e.jsx("h3",{className:`text-lg font-bold mb-2 ${t.colors.titleHover} transition-colors`,children:t.title}),e.jsx("p",{className:"text-sm text-gray-400 leading-relaxed",children:t.desc})]},t.title))})]})})}function b(){const{copied:t,copy:r}=d(),s=a=>{r(a,"landing")};return e.jsx("section",{className:"py-24 px-6 bg-[#120f0d]",children:e.jsx("div",{className:"max-w-7xl mx-auto",children:e.jsxs("div",{className:"flex flex-col lg:flex-row gap-16 items-start",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h2",{className:"text-3xl md:text-4xl font-bold mb-6",children:"Get Started in 30 Seconds"}),e.jsx("p",{className:"text-gray-400 text-lg mb-8",children:"Install FSRouter, configure your providers via web dashboard, and start routing AI requests."}),e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"1"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Install FSRouter"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Run npx command to start the server instantly"})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"2"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Open Dashboard"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Configure providers and API keys via web interface"})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold",children:"3"}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-lg",children:"Route Requests"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Point your CLI tools to http://localhost:20128"})]})]})]})]}),e.jsx("div",{className:"flex-1 w-full",children:e.jsxs("div",{className:"rounded-xl overflow-hidden bg-[#1e1e1e] border border-[#3a2f27] shadow-2xl",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 bg-[#252526] border-b border-gray-700",children:[e.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"}),e.jsx("div",{className:"ml-2 text-xs text-gray-500 font-mono",children:"terminal"})]}),e.jsxs("div",{className:"p-6 font-mono text-sm leading-relaxed overflow-x-auto",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4 group cursor-pointer",onClick:()=>s("npx fsrouter"),children:[e.jsx("span",{className:"text-green-400",children:"$"}),e.jsx("span",{className:"text-white",children:"npx fsrouter"}),e.jsx("span",{className:"ml-auto text-gray-500 text-xs opacity-0 group-hover:opacity-100",children:t==="landing"?"✓ Copied":"Copy"})]}),e.jsxs("div",{className:"text-gray-400 mb-6",children:[e.jsx("span",{className:"text-[#f97815]",children:">"})," Starting FSRouter...",e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:">"})," Server running on ",e.jsx("span",{className:"text-blue-400",children:"http://localhost:20128"}),e.jsx("br",{}),e.jsx("span",{className:"text-[#f97815]",children:">"})," Dashboard: ",e.jsx("span",{className:"text-blue-400",children:"http://localhost:20128/dashboard"}),e.jsx("br",{}),e.jsx("span",{className:"text-green-400",children:">"})," Ready to route! ✓"]}),e.jsx("div",{className:"text-xs text-gray-500 mb-2 border-t border-gray-700 pt-4",children:"📝 Configure providers in dashboard or use environment variables"}),e.jsxs("div",{className:"text-gray-400 text-xs",children:[e.jsx("span",{className:"text-purple-400",children:"Data Location:"}),e.jsx("br",{}),e.jsx("span",{className:"text-gray-500",children:" macOS/Linux:"})," ~/.fsrouter/db/data.sqlite",e.jsx("br",{}),e.jsx("span",{className:"text-gray-500",children:" Windows:"})," %APPDATA%/fsrouter/db/data.sqlite"]})]})]})})]})})})}function p(){return e.jsx("footer",{className:"border-t border-[#3a2f27] bg-[#120f0d] pt-16 pb-8 px-6",children:e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 mb-16",children:[e.jsxs("div",{className:"col-span-2 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"size-6 rounded bg-[#f97815] flex items-center justify-center text-white",children:e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"hub"})}),e.jsx("h3",{className:"text-white text-lg font-bold",children:"FSRouter"})]}),e.jsx("p",{className:"text-gray-500 text-sm max-w-xs mb-6",children:"The unified endpoint for AI generation. Connect, route, and manage your AI providers with ease."}),e.jsx("div",{className:"flex gap-4",children:e.jsx("a",{className:"text-gray-400 hover:text-white transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:e.jsx("span",{className:"material-symbols-outlined",children:"code"})})})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Product"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"#features",children:"Features"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"/dashboard",children:"Dashboard"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"Changelog"})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Resources"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter#readme",target:"_blank",rel:"noopener noreferrer",children:"Documentation"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://www.npmjs.com/package/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"NPM"})]}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("h4",{className:"font-bold text-white",children:"Legal"}),e.jsx("a",{className:"text-gray-400 hover:text-[#f97815] text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer",children:"MIT License"})]})]}),e.jsxs("div",{className:"border-t border-[#3a2f27] pt-8 flex flex-col md:flex-row justify-between items-center gap-4",children:[e.jsx("p",{className:"text-gray-600 text-sm",children:"© 2025 FSRouter. All rights reserved."}),e.jsxs("div",{className:"flex gap-6",children:[e.jsx("a",{className:"text-gray-600 hover:text-white text-sm transition-colors",href:"https://github.com/nexusrouters/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e.jsx("a",{className:"text-gray-600 hover:text-white text-sm transition-colors",href:"https://www.npmjs.com/package/fsrouter",target:"_blank",rel:"noopener noreferrer",children:"NPM"})]})]})]})})}function w(){const t=n();return e.jsxs("div",{className:"relative text-white font-sans overflow-x-hidden antialiased selection:bg-[#f97815] selection:text-white",children:[e.jsxs("div",{className:"fixed inset-0 z-0 overflow-hidden pointer-events-none bg-[#181411]",children:[e.jsx("div",{className:"absolute inset-0 opacity-[0.06]",style:{backgroundImage:"linear-gradient(to right, #f97815 1px, transparent 1px), linear-gradient(to bottom, #f97815 1px, transparent 1px)",backgroundSize:"50px 50px"}}),e.jsx("div",{className:"absolute top-0 left-1/4 w-[700px] h-[700px] bg-[#f97815]/12 rounded-full blur-[130px] animate-blob"}),e.jsx("div",{className:"absolute top-1/3 right-1/4 w-[600px] h-[600px] bg-purple-500/10 rounded-full blur-[130px] animate-blob",style:{animationDelay:"2s",animationDuration:"22s"}}),e.jsx("div",{className:"absolute bottom-0 left-1/2 w-[650px] h-[650px] bg-blue-500/8 rounded-full blur-[130px] animate-blob",style:{animationDelay:"4s",animationDuration:"25s"}}),e.jsx("div",{className:"absolute inset-0",style:{background:"radial-gradient(circle at center, transparent 0%, rgba(24, 20, 17, 0.4) 100%)"}})]}),e.jsxs("div",{className:"relative z-10",children:[e.jsx(c,{}),e.jsxs("main",{children:[e.jsxs("div",{className:"relative",children:[e.jsx(x,{}),e.jsx("div",{className:"flex justify-center pb-20",children:e.jsx(h,{})})]}),e.jsx(b,{}),e.jsx(u,{}),e.jsx(g,{}),e.jsxs("section",{className:"py-32 px-6 relative overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 bg-linear-to-t from-[#f97815]/5 to-transparent pointer-events-none"}),e.jsxs("div",{className:"max-w-4xl mx-auto text-center relative z-10",children:[e.jsx("h2",{className:"text-4xl md:text-5xl font-black mb-6",children:"Ready to Simplify Your AI Infrastructure?"}),e.jsx("p",{className:"text-xl text-gray-400 mb-10 max-w-2xl mx-auto",children:"Join developers who are streamlining their AI integrations with FSRouter. Open source and free to start."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[e.jsx("button",{onClick:()=>t("/dashboard"),className:"w-full sm:w-auto h-14 px-10 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-lg font-bold transition-all shadow-[0_0_20px_rgba(249,120,21,0.5)]",children:"Start Free"}),e.jsx("button",{onClick:()=>window.open("https://github.com/nexusrouters/fsrouter#readme","_blank"),className:"w-full sm:w-auto h-14 px-10 rounded-lg border border-[#3a2f27] hover:bg-[#23180f] text-white text-lg font-bold transition-all",children:"Read Documentation"})]})]})]})]}),e.jsx(p,{})]})]})}export{w as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as Re,r as ce,v as Ue,j as t,M as Ie,B as b,C as Oe}from"./index.Be3gbrBl.js";import{b as s}from"./router.Cjj1--8t.js";import{C as Be,T as y,I as Me}from"./NoAuthProxyCard.BDcXaWvM.js";import"./zustand.akaTi5uX.js";const $e=["zh-CN","zh-TW"],S=[{id:"lite",label:"Lite",desc:"Drop filler, keep grammar"},{id:"full",label:"Full",desc:"Drop articles, fragments OK"},{id:"ultra",label:"Ultra",desc:"Telegraphic, max compression"},{id:"wenyan-lite",label:"文 Lite",desc:"Classical Chinese, light compression",wenyan:!0},{id:"wenyan",label:"文 Full",desc:"Maximum 文言文, 80-90% reduction",wenyan:!0},{id:"wenyan-ultra",label:"文 Ultra",desc:"Extreme classical compression",wenyan:!0}],de=[{id:"lite",label:"Lite",desc:"Build asked, name lazier option"},{id:"full",label:"Full",desc:"Ladder enforced: stdlib/native first"},{id:"ultra",label:"Ultra",desc:"YAGNI extremist, deletion first"}];function Ke(){var le,ie;const[M,$]=s.useState(!0),[D,J]=s.useState(!1),[L,j]=s.useState("http://localhost:8787"),[l,T]=s.useState({installed:!1,running:!1,python:null,loading:!0}),[me,A]=s.useState(!1),[v,w]=s.useState(!1),[_,G]=s.useState(""),[N,h]=s.useState({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),[c,x]=s.useState([]),[P,K]=s.useState(!1),[W,p]=s.useState(""),[H,z]=s.useState(null),[F,Y]=s.useState(""),[n,C]=s.useState(null),[he,V]=s.useState(!1),[xe,q]=s.useState(!0),[Q,X]=s.useState(!1),u=s.useRef(null),[R,Z]=s.useState(!1),[k,U]=s.useState("full"),[I,ee]=s.useState(!1),[te,ae]=s.useState("full"),[pe,se]=s.useState("en"),{copied:ue,copy:fe}=Re();s.useEffect(()=>(se(ce()),Ue(()=>se(ce()))),[]);const O=$e.includes(pe),ge=O?S:S.filter(e=>!e.wenyan);s.useEffect(()=>{const e=S.find(a=>a.id===k);e!=null&&e.wenyan&&!O&&(U("ultra"),m({cavemanLevel:"ultra"}))},[O,k]);const m=async e=>{try{await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}catch(a){console.log("Error updating setting:",a)}},be=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({rtkEnabled:e})})).ok&&$(e)}catch(a){console.log("Error updating rtkEnabled:",a)}},ye=e=>{Z(e),m({cavemanEnabled:e})},je=e=>{U(e),m({cavemanLevel:e})},ve=e=>{const a=L.trim()||"http://localhost:8787";j(a),J(e),m({headroomEnabled:e,headroomUrl:a})},we=async()=>{const e=L.trim()||"http://localhost:8787";j(e),await m({headroomUrl:e}),i()},i=s.useCallback(async()=>{T(e=>({...e,loading:!0}));try{const a=await(await fetch("/api/headroom/status",{headers:{"Cache-Control":"no-store"}})).json();if(T({...a,loading:!1}),!(a!=null&&a.installed)){h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([]);return}try{const r=await fetch("/api/headroom/extras",{headers:{"Cache-Control":"no-store"}});if(!r.ok)throw new Error("extras status failed");const o=await r.json();h(g=>({...g,version:o.version??null,extras:o.extras||{code:!1,ml:!1},available:o.available||["code","ml"],loading:!1})),x([])}catch{h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([])}}catch{T({installed:!1,running:!1,python:null,loading:!1}),h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([])}},[]),Ne=s.useCallback(async()=>{G(""),w(!0);try{const e=await fetch("/api/headroom/start",{method:"POST"}),a=await e.json().catch(()=>({}));if(!e.ok)throw new Error(a.error||"Failed to start proxy");await i()}catch(e){G(e.message)}finally{w(!1)}},[i]),Ce=s.useCallback(async()=>{w(!0);try{await fetch("/api/headroom/stop",{method:"POST"}),await i()}finally{w(!1)}},[i]),ke=e=>{x(a=>a.includes(e)?a.filter(r=>r!==e):[...a,e])},E=s.useCallback(()=>{Y(""),u.current&&clearInterval(u.current);const e=async()=>{try{const r=await(await fetch("/api/headroom/extras?log=1",{headers:{"Cache-Control":"no-store"}})).json().catch(()=>({}));typeof r.log=="string"&&Y(r.log)}catch{}};e(),u.current=setInterval(e,1500)},[]),f=s.useCallback(()=>{u.current&&(clearInterval(u.current),u.current=null)},[]);s.useEffect(()=>()=>f(),[f]);const B=s.useCallback(async()=>{if(c.length!==0){K(!0),p(""),E();try{const e=await fetch("/api/headroom/extras",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({extras:c})}),a=await e.json().catch(()=>({}));if(!e.ok)throw new Error(a.error||"Install failed");h(r=>({...r,version:a.version??r.version,extras:a.extras||r.extras})),x([])}catch(e){p(e.message)}finally{f(),K(!1)}}},[c,E,f]),re=s.useCallback(async e=>{z(e),p(""),E();try{const a=await fetch("/api/headroom/extras",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({extras:[e]})}),r=await a.json().catch(()=>({}));if(!a.ok)throw new Error(r.error||"Remove failed");h(o=>({...o,version:r.version??o.version,extras:r.extras||o.extras}))}catch(a){p(a.message)}finally{f(),z(null)}},[E,f]),Ee=s.useCallback(()=>{if(c.length!==0){if(c.includes("ml")){C({title:"Install [ml]",message:"[ml] downloads ~1 GB (torch + huggingface-hub). Continue?",confirmText:"Install",variant:"primary",onConfirm:B});return}B()}},[c,B]),Se=s.useCallback(e=>{C({title:`Remove [${e}]`,message:`Remove [${e}] and its packages?`,confirmText:"Remove",variant:"danger",onConfirm:()=>re(e)})},[re]),Le=s.useCallback(async(e,a)=>{if(p(""),e==="code"&&V(a),e==="ml"&&q(a),await m({[e==="code"?"headroomCodeAware":"headroomKompress"]:a}),!!l.running){X(!0);try{const o=await fetch("/api/headroom/restart",{method:"POST"}),g=await o.json().catch(()=>({}));if(!o.ok)throw new Error(g.error||"Restart failed");await i()}catch(o){p(o.message)}finally{X(!1)}}},[l.running,i]),Te=e=>{ee(e),m({ponytailEnabled:e})},Ae=e=>{ae(e),m({ponytailLevel:e})};s.useEffect(()=>{(async()=>{try{const a=await fetch("/api/settings");if(!a.ok)return;const r=await a.json();$(r.rtkEnabled!==!1),J(!!r.headroomEnabled),j(r.headroomUrl||"http://localhost:8787"),V(r.headroomCodeAware===!0),q(r.headroomKompress!==!1),Z(!!r.cavemanEnabled),U(r.cavemanLevel||"full"),ee(!!r.ponytailEnabled),ae(r.ponytailLevel||"full"),i()}catch{}})()},[i]);const d=!!l.running,ne=l.loading?"Checking…":d?"Running":l.localUrl!==!1&&!l.installed?"Not installed":l.localUrl!==!1?"Stopped":"External",oe=l.localUrl!==!1,Pe=!!l.canStart,He=oe&&!!l.managedPid;return t.jsxs("div",{className:"space-y-6 p-6",children:[t.jsxs(Be,{id:"rtk",children:[t.jsx("div",{className:"flex items-center justify-between mb-2",children:t.jsxs("h2",{className:"text-lg font-semibold flex items-center gap-2",children:[t.jsx("span",{className:"material-symbols-outlined text-primary",children:"bolt"}),"Token Saver"]})}),t.jsxs("div",{className:"flex items-center justify-between pt-2 pb-4 border-b border-border gap-4",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Compress tool output"," ",t.jsx("a",{href:"https://github.com/rtk-ai/rtk",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(RTK)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"git/grep/ls/tree/logs → 60-90% fewer input tokens"})]}),t.jsx(y,{checked:M,onChange:()=>be(!M)})]}),t.jsxs("div",{className:"flex items-center justify-between py-4 gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[t.jsxs("p",{className:"font-medium",children:["Compress context"," ",t.jsx("a",{href:"https://github.com/chopratejas/headroom",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Headroom)"})]}),t.jsx("span",{className:`text-xs px-2 py-0.5 rounded ${d?"bg-success/15 text-success":"bg-warning/15 text-warning"}`,children:ne}),t.jsx("button",{type:"button",onClick:()=>A(!0),className:"text-xs text-primary underline hover:opacity-80",children:d?"Manage":"Setup"})]}),t.jsx("p",{className:"text-sm text-text-muted mt-1",children:"Compress prompts via /v1/compress before routing to the model"})]}),t.jsx(y,{checked:D&&d,disabled:!d,onChange:()=>ve(!D)})]}),l.installed&&t.jsxs("div",{className:"mb-3 ml-1 pl-3 pb-4 border-l-2 border-border",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsxs("span",{className:"text-xs text-text-muted",children:["Compression extras",N.version?` · v${N.version}`:"",":"]}),N.available.map(e=>{const a=!!N.extras[e],r=c.includes(e),o=e==="code"?"tree-sitter AST compression for code responses":"Kompress-v2 HF model for prose/agentic traces (~+1GB)";if(a){const g=e==="code"?he:xe;return t.jsxs("div",{className:"flex items-center gap-1.5 text-xs px-2 py-1 rounded border border-success/40 bg-success/5 text-text",title:o,children:[t.jsx(y,{size:"sm",checked:g,disabled:Q,onChange:()=>Le(e,!g)}),t.jsxs("span",{className:"font-medium",children:["[",e,"]"]}),t.jsx("button",{type:"button",onClick:()=>Se(e),disabled:H===e,className:"ml-1 text-error underline hover:opacity-80 disabled:opacity-50",title:`Uninstall [${e}]`,children:H===e?"Uninstalling…":"Uninstall"})]},e)}return t.jsxs("label",{className:`flex items-center gap-1.5 text-xs px-2 py-1 rounded border cursor-pointer transition-colors ${r?"border-primary bg-primary/10 text-primary":"border-border text-text-muted hover:bg-surface-2"}`,title:o,children:[t.jsx("input",{type:"checkbox",className:"w-3 h-3",checked:r,onChange:()=>ke(e)}),t.jsxs("span",{className:"font-medium",children:["[",e,"]"]}),t.jsx("span",{className:"opacity-70",children:"not installed"})]},e)}),c.length>0&&t.jsx("button",{onClick:Ee,disabled:P,className:"text-xs px-2.5 py-1 rounded bg-primary text-white hover:opacity-90 disabled:opacity-50",children:P?"Installing…":`Install [proxy,${c.join(",")}]`})]}),W&&t.jsx("p",{className:"text-xs text-error mt-1",children:W}),Q&&t.jsx("p",{className:"text-xs text-text-muted mt-1",children:"Restarting proxy…"}),(P||H)&&F&&t.jsx("pre",{className:"mt-2 max-h-32 overflow-auto rounded bg-surface-2 p-2 text-[10px] leading-tight text-text-muted whitespace-pre-wrap",children:F}),t.jsxs("p",{className:"text-xs text-text-muted mt-1",children:["Installing adds the package; use ",t.jsx("code",{children:"on"}),"/",t.jsx("code",{children:"off"})," ","to activate it (restarts the proxy). Default install is"," ",t.jsx("code",{children:"[proxy]"})," only (SmartCrusher for JSON). Adding"," ",t.jsx("code",{children:"[code]"})," enables AST compression (Python/JS/TS/Go/Rust/Java/C/C++/Perl). Adding ",t.jsx("code",{children:"[ml]"})," ","enables the Kompress-v2 HF model for prose/agentic traces but adds ~1 GB (torch + huggingface-hub)."]})]}),t.jsxs("div",{className:"flex items-center justify-between pt-4 border-t border-border gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Compress LLM output"," ",t.jsx("a",{href:"https://github.com/JuliusBrussee/caveman",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Caveman)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"Terse-style system prompt → ~65% fewer output tokens (up to 87%)"})]}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[R&&t.jsxs("div",{className:"flex flex-col items-end gap-1",children:[t.jsx("div",{className:"flex items-center gap-1.5",children:ge.map(e=>t.jsx("button",{onClick:()=>je(e.id),className:`px-3 py-1.5 rounded text-xs font-medium border transition-colors ${k===e.id?"bg-primary text-white border-primary":"bg-transparent border-border text-text-muted hover:bg-surface-2"}`,title:e.desc,children:e.label},e.id))}),t.jsx("p",{className:"text-xs text-primary",children:(le=S.find(e=>e.id===k))==null?void 0:le.desc})]}),t.jsx(y,{checked:R,onChange:()=>ye(!R)})]})]}),t.jsxs("div",{className:"flex items-center justify-between pt-4 mt-4 border-t border-border gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Lazy senior dev"," ",t.jsx("a",{href:"https://github.com/DietrichGebert/ponytail",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Ponytail)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"Bias the model toward minimal code: YAGNI, reuse stdlib, deletion over addition"})]}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[I&&t.jsxs("div",{className:"flex flex-col items-end gap-1",children:[t.jsx("div",{className:"flex items-center gap-1.5",children:de.map(e=>t.jsx("button",{onClick:()=>Ae(e.id),className:`px-3 py-1.5 rounded text-xs font-medium border transition-colors ${te===e.id?"bg-primary text-white border-primary":"bg-transparent border-border text-text-muted hover:bg-surface-2"}`,title:e.desc,children:e.label},e.id))}),t.jsx("p",{className:"text-xs text-primary",children:(ie=de.find(e=>e.id===te))==null?void 0:ie.desc})]}),t.jsx(y,{checked:I,onChange:()=>Te(!I)})]})]})]}),t.jsx(Ie,{isOpen:me,title:d?"Headroom":"Setup Headroom",onClose:()=>A(!1),children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsxs("div",{className:"flex items-center justify-between text-sm",children:[t.jsx("span",{children:"Status"}),t.jsx("span",{className:d?"text-success":"text-warning",children:ne})]}),d&&t.jsx("a",{href:"/api/headroom/proxy/dashboard",target:"_blank",rel:"noreferrer",className:"w-full rounded border border-border px-4 py-2 text-center text-sm hover:bg-surface-2",children:"Open Headroom Dashboard"}),t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("p",{className:"text-sm font-medium",children:"Proxy URL"}),t.jsx(Me,{value:L,onChange:e=>j(e.target.value),onBlur:we,placeholder:"http://localhost:8787",className:"font-mono text-sm"}),t.jsx("p",{className:"text-xs text-text-muted",children:"Use a local proxy for Start/Stop, or an external Docker sidecar like http://headroom:8787."})]}),He?t.jsx(b,{onClick:Ce,variant:"ghost",fullWidth:!0,disabled:v,children:v?"Stopping…":"Stop Headroom"}):d?t.jsx("p",{className:"text-sm text-success",children:"Headroom proxy is reachable. You can enable the token saver."}):Pe?t.jsx(b,{onClick:Ne,fullWidth:!0,disabled:v,children:v?"Starting…":"Start Headroom"}):oe?l.python?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("p",{className:"text-sm font-medium",children:"Install then click Start:"}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("pre",{className:"flex-1 rounded bg-black/5 dark:bg-white/5 p-2 text-xs font-mono overflow-x-auto",children:'pip install "headroom-ai[proxy]"'}),t.jsx(b,{size:"sm",variant:"ghost",onClick:()=>fe('pip install "headroom-ai[proxy]"'),children:ue?"Copied":"Copy"})]})]}):t.jsx("p",{className:"text-sm text-warning",children:"Python ≥ 3.10 required for local managed mode. Install Python first, or use an external proxy URL."}):t.jsx("p",{className:"text-sm text-warning",children:"Start Headroom separately at the configured URL, then recheck."}),_&&t.jsx("p",{className:"text-sm text-warning",children:_}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(b,{onClick:()=>i(),variant:"ghost",fullWidth:!0,children:"Recheck"}),t.jsx(b,{onClick:()=>A(!1),fullWidth:!0,children:"Done"})]})]})}),t.jsx(Oe,{isOpen:!!n,onClose:()=>C(null),onConfirm:()=>{const e=n==null?void 0:n.onConfirm;C(null),e==null||e()},title:n==null?void 0:n.title,message:n==null?void 0:n.message,confirmText:n==null?void 0:n.confirmText,variant:n==null?void 0:n.variant})]})}export{Ke as default};
|
|
1
|
+
import{u as Re,r as ce,v as Ue,j as t,M as Ie,B as b,C as Oe}from"./index.D4FwOBBU.js";import{b as s}from"./router.Cjj1--8t.js";import{C as Be,T as y,I as Me}from"./NoAuthProxyCard.WHGGEUIp.js";import"./zustand.akaTi5uX.js";const $e=["zh-CN","zh-TW"],S=[{id:"lite",label:"Lite",desc:"Drop filler, keep grammar"},{id:"full",label:"Full",desc:"Drop articles, fragments OK"},{id:"ultra",label:"Ultra",desc:"Telegraphic, max compression"},{id:"wenyan-lite",label:"文 Lite",desc:"Classical Chinese, light compression",wenyan:!0},{id:"wenyan",label:"文 Full",desc:"Maximum 文言文, 80-90% reduction",wenyan:!0},{id:"wenyan-ultra",label:"文 Ultra",desc:"Extreme classical compression",wenyan:!0}],de=[{id:"lite",label:"Lite",desc:"Build asked, name lazier option"},{id:"full",label:"Full",desc:"Ladder enforced: stdlib/native first"},{id:"ultra",label:"Ultra",desc:"YAGNI extremist, deletion first"}];function Ke(){var le,ie;const[M,$]=s.useState(!0),[D,J]=s.useState(!1),[L,j]=s.useState("http://localhost:8787"),[l,T]=s.useState({installed:!1,running:!1,python:null,loading:!0}),[me,A]=s.useState(!1),[v,w]=s.useState(!1),[_,G]=s.useState(""),[N,h]=s.useState({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),[c,x]=s.useState([]),[P,K]=s.useState(!1),[W,p]=s.useState(""),[H,z]=s.useState(null),[F,Y]=s.useState(""),[n,C]=s.useState(null),[he,V]=s.useState(!1),[xe,q]=s.useState(!0),[Q,X]=s.useState(!1),u=s.useRef(null),[R,Z]=s.useState(!1),[k,U]=s.useState("full"),[I,ee]=s.useState(!1),[te,ae]=s.useState("full"),[pe,se]=s.useState("en"),{copied:ue,copy:fe}=Re();s.useEffect(()=>(se(ce()),Ue(()=>se(ce()))),[]);const O=$e.includes(pe),ge=O?S:S.filter(e=>!e.wenyan);s.useEffect(()=>{const e=S.find(a=>a.id===k);e!=null&&e.wenyan&&!O&&(U("ultra"),m({cavemanLevel:"ultra"}))},[O,k]);const m=async e=>{try{await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}catch(a){console.log("Error updating setting:",a)}},be=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({rtkEnabled:e})})).ok&&$(e)}catch(a){console.log("Error updating rtkEnabled:",a)}},ye=e=>{Z(e),m({cavemanEnabled:e})},je=e=>{U(e),m({cavemanLevel:e})},ve=e=>{const a=L.trim()||"http://localhost:8787";j(a),J(e),m({headroomEnabled:e,headroomUrl:a})},we=async()=>{const e=L.trim()||"http://localhost:8787";j(e),await m({headroomUrl:e}),i()},i=s.useCallback(async()=>{T(e=>({...e,loading:!0}));try{const a=await(await fetch("/api/headroom/status",{headers:{"Cache-Control":"no-store"}})).json();if(T({...a,loading:!1}),!(a!=null&&a.installed)){h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([]);return}try{const r=await fetch("/api/headroom/extras",{headers:{"Cache-Control":"no-store"}});if(!r.ok)throw new Error("extras status failed");const o=await r.json();h(g=>({...g,version:o.version??null,extras:o.extras||{code:!1,ml:!1},available:o.available||["code","ml"],loading:!1})),x([])}catch{h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([])}}catch{T({installed:!1,running:!1,python:null,loading:!1}),h({version:null,extras:{code:!1,ml:!1},available:["code","ml"],loading:!1}),x([])}},[]),Ne=s.useCallback(async()=>{G(""),w(!0);try{const e=await fetch("/api/headroom/start",{method:"POST"}),a=await e.json().catch(()=>({}));if(!e.ok)throw new Error(a.error||"Failed to start proxy");await i()}catch(e){G(e.message)}finally{w(!1)}},[i]),Ce=s.useCallback(async()=>{w(!0);try{await fetch("/api/headroom/stop",{method:"POST"}),await i()}finally{w(!1)}},[i]),ke=e=>{x(a=>a.includes(e)?a.filter(r=>r!==e):[...a,e])},E=s.useCallback(()=>{Y(""),u.current&&clearInterval(u.current);const e=async()=>{try{const r=await(await fetch("/api/headroom/extras?log=1",{headers:{"Cache-Control":"no-store"}})).json().catch(()=>({}));typeof r.log=="string"&&Y(r.log)}catch{}};e(),u.current=setInterval(e,1500)},[]),f=s.useCallback(()=>{u.current&&(clearInterval(u.current),u.current=null)},[]);s.useEffect(()=>()=>f(),[f]);const B=s.useCallback(async()=>{if(c.length!==0){K(!0),p(""),E();try{const e=await fetch("/api/headroom/extras",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({extras:c})}),a=await e.json().catch(()=>({}));if(!e.ok)throw new Error(a.error||"Install failed");h(r=>({...r,version:a.version??r.version,extras:a.extras||r.extras})),x([])}catch(e){p(e.message)}finally{f(),K(!1)}}},[c,E,f]),re=s.useCallback(async e=>{z(e),p(""),E();try{const a=await fetch("/api/headroom/extras",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({extras:[e]})}),r=await a.json().catch(()=>({}));if(!a.ok)throw new Error(r.error||"Remove failed");h(o=>({...o,version:r.version??o.version,extras:r.extras||o.extras}))}catch(a){p(a.message)}finally{f(),z(null)}},[E,f]),Ee=s.useCallback(()=>{if(c.length!==0){if(c.includes("ml")){C({title:"Install [ml]",message:"[ml] downloads ~1 GB (torch + huggingface-hub). Continue?",confirmText:"Install",variant:"primary",onConfirm:B});return}B()}},[c,B]),Se=s.useCallback(e=>{C({title:`Remove [${e}]`,message:`Remove [${e}] and its packages?`,confirmText:"Remove",variant:"danger",onConfirm:()=>re(e)})},[re]),Le=s.useCallback(async(e,a)=>{if(p(""),e==="code"&&V(a),e==="ml"&&q(a),await m({[e==="code"?"headroomCodeAware":"headroomKompress"]:a}),!!l.running){X(!0);try{const o=await fetch("/api/headroom/restart",{method:"POST"}),g=await o.json().catch(()=>({}));if(!o.ok)throw new Error(g.error||"Restart failed");await i()}catch(o){p(o.message)}finally{X(!1)}}},[l.running,i]),Te=e=>{ee(e),m({ponytailEnabled:e})},Ae=e=>{ae(e),m({ponytailLevel:e})};s.useEffect(()=>{(async()=>{try{const a=await fetch("/api/settings");if(!a.ok)return;const r=await a.json();$(r.rtkEnabled!==!1),J(!!r.headroomEnabled),j(r.headroomUrl||"http://localhost:8787"),V(r.headroomCodeAware===!0),q(r.headroomKompress!==!1),Z(!!r.cavemanEnabled),U(r.cavemanLevel||"full"),ee(!!r.ponytailEnabled),ae(r.ponytailLevel||"full"),i()}catch{}})()},[i]);const d=!!l.running,ne=l.loading?"Checking…":d?"Running":l.localUrl!==!1&&!l.installed?"Not installed":l.localUrl!==!1?"Stopped":"External",oe=l.localUrl!==!1,Pe=!!l.canStart,He=oe&&!!l.managedPid;return t.jsxs("div",{className:"space-y-6 p-6",children:[t.jsxs(Be,{id:"rtk",children:[t.jsx("div",{className:"flex items-center justify-between mb-2",children:t.jsxs("h2",{className:"text-lg font-semibold flex items-center gap-2",children:[t.jsx("span",{className:"material-symbols-outlined text-primary",children:"bolt"}),"Token Saver"]})}),t.jsxs("div",{className:"flex items-center justify-between pt-2 pb-4 border-b border-border gap-4",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Compress tool output"," ",t.jsx("a",{href:"https://github.com/rtk-ai/rtk",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(RTK)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"git/grep/ls/tree/logs → 60-90% fewer input tokens"})]}),t.jsx(y,{checked:M,onChange:()=>be(!M)})]}),t.jsxs("div",{className:"flex items-center justify-between py-4 gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[t.jsxs("p",{className:"font-medium",children:["Compress context"," ",t.jsx("a",{href:"https://github.com/chopratejas/headroom",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Headroom)"})]}),t.jsx("span",{className:`text-xs px-2 py-0.5 rounded ${d?"bg-success/15 text-success":"bg-warning/15 text-warning"}`,children:ne}),t.jsx("button",{type:"button",onClick:()=>A(!0),className:"text-xs text-primary underline hover:opacity-80",children:d?"Manage":"Setup"})]}),t.jsx("p",{className:"text-sm text-text-muted mt-1",children:"Compress prompts via /v1/compress before routing to the model"})]}),t.jsx(y,{checked:D&&d,disabled:!d,onChange:()=>ve(!D)})]}),l.installed&&t.jsxs("div",{className:"mb-3 ml-1 pl-3 pb-4 border-l-2 border-border",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsxs("span",{className:"text-xs text-text-muted",children:["Compression extras",N.version?` · v${N.version}`:"",":"]}),N.available.map(e=>{const a=!!N.extras[e],r=c.includes(e),o=e==="code"?"tree-sitter AST compression for code responses":"Kompress-v2 HF model for prose/agentic traces (~+1GB)";if(a){const g=e==="code"?he:xe;return t.jsxs("div",{className:"flex items-center gap-1.5 text-xs px-2 py-1 rounded border border-success/40 bg-success/5 text-text",title:o,children:[t.jsx(y,{size:"sm",checked:g,disabled:Q,onChange:()=>Le(e,!g)}),t.jsxs("span",{className:"font-medium",children:["[",e,"]"]}),t.jsx("button",{type:"button",onClick:()=>Se(e),disabled:H===e,className:"ml-1 text-error underline hover:opacity-80 disabled:opacity-50",title:`Uninstall [${e}]`,children:H===e?"Uninstalling…":"Uninstall"})]},e)}return t.jsxs("label",{className:`flex items-center gap-1.5 text-xs px-2 py-1 rounded border cursor-pointer transition-colors ${r?"border-primary bg-primary/10 text-primary":"border-border text-text-muted hover:bg-surface-2"}`,title:o,children:[t.jsx("input",{type:"checkbox",className:"w-3 h-3",checked:r,onChange:()=>ke(e)}),t.jsxs("span",{className:"font-medium",children:["[",e,"]"]}),t.jsx("span",{className:"opacity-70",children:"not installed"})]},e)}),c.length>0&&t.jsx("button",{onClick:Ee,disabled:P,className:"text-xs px-2.5 py-1 rounded bg-primary text-white hover:opacity-90 disabled:opacity-50",children:P?"Installing…":`Install [proxy,${c.join(",")}]`})]}),W&&t.jsx("p",{className:"text-xs text-error mt-1",children:W}),Q&&t.jsx("p",{className:"text-xs text-text-muted mt-1",children:"Restarting proxy…"}),(P||H)&&F&&t.jsx("pre",{className:"mt-2 max-h-32 overflow-auto rounded bg-surface-2 p-2 text-[10px] leading-tight text-text-muted whitespace-pre-wrap",children:F}),t.jsxs("p",{className:"text-xs text-text-muted mt-1",children:["Installing adds the package; use ",t.jsx("code",{children:"on"}),"/",t.jsx("code",{children:"off"})," ","to activate it (restarts the proxy). Default install is"," ",t.jsx("code",{children:"[proxy]"})," only (SmartCrusher for JSON). Adding"," ",t.jsx("code",{children:"[code]"})," enables AST compression (Python/JS/TS/Go/Rust/Java/C/C++/Perl). Adding ",t.jsx("code",{children:"[ml]"})," ","enables the Kompress-v2 HF model for prose/agentic traces but adds ~1 GB (torch + huggingface-hub)."]})]}),t.jsxs("div",{className:"flex items-center justify-between pt-4 border-t border-border gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Compress LLM output"," ",t.jsx("a",{href:"https://github.com/JuliusBrussee/caveman",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Caveman)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"Terse-style system prompt → ~65% fewer output tokens (up to 87%)"})]}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[R&&t.jsxs("div",{className:"flex flex-col items-end gap-1",children:[t.jsx("div",{className:"flex items-center gap-1.5",children:ge.map(e=>t.jsx("button",{onClick:()=>je(e.id),className:`px-3 py-1.5 rounded text-xs font-medium border transition-colors ${k===e.id?"bg-primary text-white border-primary":"bg-transparent border-border text-text-muted hover:bg-surface-2"}`,title:e.desc,children:e.label},e.id))}),t.jsx("p",{className:"text-xs text-primary",children:(le=S.find(e=>e.id===k))==null?void 0:le.desc})]}),t.jsx(y,{checked:R,onChange:()=>ye(!R)})]})]}),t.jsxs("div",{className:"flex items-center justify-between pt-4 mt-4 border-t border-border gap-4 flex-wrap",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"font-medium",children:["Lazy senior dev"," ",t.jsx("a",{href:"https://github.com/DietrichGebert/ponytail",target:"_blank",rel:"noreferrer",className:"text-xs font-normal text-primary underline hover:opacity-80",children:"(Ponytail)"})]}),t.jsx("p",{className:"text-sm text-text-muted",children:"Bias the model toward minimal code: YAGNI, reuse stdlib, deletion over addition"})]}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[I&&t.jsxs("div",{className:"flex flex-col items-end gap-1",children:[t.jsx("div",{className:"flex items-center gap-1.5",children:de.map(e=>t.jsx("button",{onClick:()=>Ae(e.id),className:`px-3 py-1.5 rounded text-xs font-medium border transition-colors ${te===e.id?"bg-primary text-white border-primary":"bg-transparent border-border text-text-muted hover:bg-surface-2"}`,title:e.desc,children:e.label},e.id))}),t.jsx("p",{className:"text-xs text-primary",children:(ie=de.find(e=>e.id===te))==null?void 0:ie.desc})]}),t.jsx(y,{checked:I,onChange:()=>Te(!I)})]})]})]}),t.jsx(Ie,{isOpen:me,title:d?"Headroom":"Setup Headroom",onClose:()=>A(!1),children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsxs("div",{className:"flex items-center justify-between text-sm",children:[t.jsx("span",{children:"Status"}),t.jsx("span",{className:d?"text-success":"text-warning",children:ne})]}),d&&t.jsx("a",{href:"/api/headroom/proxy/dashboard",target:"_blank",rel:"noreferrer",className:"w-full rounded border border-border px-4 py-2 text-center text-sm hover:bg-surface-2",children:"Open Headroom Dashboard"}),t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("p",{className:"text-sm font-medium",children:"Proxy URL"}),t.jsx(Me,{value:L,onChange:e=>j(e.target.value),onBlur:we,placeholder:"http://localhost:8787",className:"font-mono text-sm"}),t.jsx("p",{className:"text-xs text-text-muted",children:"Use a local proxy for Start/Stop, or an external Docker sidecar like http://headroom:8787."})]}),He?t.jsx(b,{onClick:Ce,variant:"ghost",fullWidth:!0,disabled:v,children:v?"Stopping…":"Stop Headroom"}):d?t.jsx("p",{className:"text-sm text-success",children:"Headroom proxy is reachable. You can enable the token saver."}):Pe?t.jsx(b,{onClick:Ne,fullWidth:!0,disabled:v,children:v?"Starting…":"Start Headroom"}):oe?l.python?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("p",{className:"text-sm font-medium",children:"Install then click Start:"}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("pre",{className:"flex-1 rounded bg-black/5 dark:bg-white/5 p-2 text-xs font-mono overflow-x-auto",children:'pip install "headroom-ai[proxy]"'}),t.jsx(b,{size:"sm",variant:"ghost",onClick:()=>fe('pip install "headroom-ai[proxy]"'),children:ue?"Copied":"Copy"})]})]}):t.jsx("p",{className:"text-sm text-warning",children:"Python ≥ 3.10 required for local managed mode. Install Python first, or use an external proxy URL."}):t.jsx("p",{className:"text-sm text-warning",children:"Start Headroom separately at the configured URL, then recheck."}),_&&t.jsx("p",{className:"text-sm text-warning",children:_}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(b,{onClick:()=>i(),variant:"ghost",fullWidth:!0,children:"Recheck"}),t.jsx(b,{onClick:()=>A(!1),fullWidth:!0,children:"Done"})]})]})}),t.jsx(Oe,{isOpen:!!n,onClose:()=>C(null),onConfirm:()=>{const e=n==null?void 0:n.onConfirm;C(null),e==null||e()},title:n==null?void 0:n.title,message:n==null?void 0:n.message,confirmText:n==null?void 0:n.confirmText,variant:n==null?void 0:n.variant})]})}export{Ke as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,B as h}from"./index.
|
|
1
|
+
import{j as e,B as h}from"./index.D4FwOBBU.js";import{b as r}from"./router.Cjj1--8t.js";import"./NoAuthProxyCard.WHGGEUIp.js";import"./zustand.akaTi5uX.js";function R(){const[l,s]=r.useState(!1),[c,a]=r.useState(""),[o,m]=r.useState(""),i=r.useRef(null),f=()=>{window.location.href="/api/db"},b=()=>{i.current&&i.current.click()},g=async n=>{const t=n.target.files[0];if(t){if(!t.name.endsWith(".fud")&&!t.name.endsWith(".json")){a("Format file tidak didukung. Harap gunakan file berekstensi .fud");return}if(!window.confirm("PERINGATAN: Memulihkan database akan MENIMPA semua data, pengaturan, dan provider saat ini! Server akan di-restart otomatis. Lanjutkan?")){n.target.value="";return}a(""),m(""),s(!0);try{const d=new FileReader;d.onload=async j=>{try{const x=j.target.result,k=JSON.parse(x),u=await fetch("/api/db",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(k)}),p=await u.json();u.ok&&p.success?(m("Restore berhasil! Server sedang merestart, harap tunggu beberapa saat..."),setTimeout(()=>{window.location.reload()},5e3)):(a(p.error||"Gagal melakukan restore."),s(!1))}catch{a("File backup corrupt atau tidak valid."),s(!1)}},d.readAsText(t)}catch{a("Gagal membaca file."),s(!1)}n.target.value=""}};return e.jsxs("div",{className:"max-w-4xl mx-auto p-4 space-y-6",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("h1",{className:"text-2xl font-bold text-text-main flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-[28px] text-primary",children:"backup"}),"Backup & Restore"]}),e.jsx("p",{className:"text-xs text-text-muted",children:"Amankan seluruh data FSRouter Anda ke dalam satu file .fud, atau pulihkan data dari file backup sebelumnya."})]}),c&&e.jsxs("div",{className:"p-4 bg-red-500/10 border border-red-500/20 text-red-500 text-sm rounded-lg flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"error"}),c]}),o&&e.jsxs("div",{className:"p-4 bg-green-500/10 border border-green-500/20 text-green-500 text-sm rounded-lg flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-sm",children:"check_circle"}),o]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"p-6 rounded-[14px] border border-border-subtle bg-surface flex flex-col gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3 text-text-main",children:[e.jsx("div",{className:"size-10 rounded-full bg-blue-500/10 text-blue-500 flex items-center justify-center",children:e.jsx("span",{className:"material-symbols-outlined text-xl",children:"cloud_download"})}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Buat Backup"}),e.jsx("p",{className:"text-[11px] text-text-muted",children:"Simpan data ke perangkat Anda"})]})]}),e.jsxs("div",{className:"text-xs text-text-muted leading-relaxed flex-1",children:[e.jsx("p",{className:"mb-2",children:"File backup (.fud) berisi keseluruhan state sistem:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1 ml-1",children:[e.jsx("li",{children:"Konfigurasi Providers & Endpoint"}),e.jsx("li",{children:"Riwayat Penggunaan & Limits"}),e.jsx("li",{children:"Akun Otomatis & FSmail"}),e.jsx("li",{children:"Proxy Pools & Identitas Perangkat"})]})]}),e.jsx(h,{variant:"primary",fullWidth:!0,onClick:f,icon:"download",children:"Download Backup (.fud)"})]}),e.jsxs("div",{className:"p-6 rounded-[14px] border border-border-subtle bg-surface flex flex-col gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3 text-text-main",children:[e.jsx("div",{className:"size-10 rounded-full bg-amber-500/10 text-amber-500 flex items-center justify-center",children:e.jsx("span",{className:"material-symbols-outlined text-xl",children:"restore"})}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Pulihkan Backup"}),e.jsx("p",{className:"text-[11px] text-text-muted",children:"Timpa data dari file .fud"})]})]}),e.jsxs("div",{className:"text-xs text-text-muted leading-relaxed flex-1",children:[e.jsx("p",{className:"mb-2 text-amber-500/90 font-medium",children:"Perhatian sebelum memulihkan:"}),e.jsx("p",{children:"Proses restore akan menghapus dan menimpa database yang berjalan saat ini dengan database yang ada di file backup. FSRouter akan melakukan restart layanan setelah proses restore selesai."})]}),e.jsx("input",{type:"file",accept:".fud,.json",ref:i,onChange:g,className:"hidden"}),e.jsx(h,{variant:"secondary",fullWidth:!0,onClick:b,disabled:l,icon:l?"sync":"upload",children:l?"Sedang Memulihkan...":"Pilih File & Restore"})]})]})]})}export{R as default};
|