diff --git a/README.md b/README.md index 6de39325..30fef875 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,5 @@ This branch contains the pre-built frontend assets for Claude Relay Service. These files are automatically generated by the CI/CD pipeline. -Version: 1.1.219 -Build Date: 2025-12-04 01:49:35 UTC +Version: 1.1.220 +Build Date: 2025-12-04 13:02:31 UTC diff --git a/assets/AccountsView-Def5MYP1.js b/assets/AccountsView-Def5MYP1.js new file mode 100644 index 00000000..777acce8 --- /dev/null +++ b/assets/AccountsView-Def5MYP1.js @@ -0,0 +1,44 @@ +import{a as Bs}from"./element-plus-CqiD73Lu.js";import{r as $,aP as Hs,o as ye,V as zs,x as n,y as o,z as e,L as y,K as k,al as De,aT as Vt,O as x,aq as z,aa as Js,P as u,aV as Ds,aY as ps,C as I,c as ne,Z as Ys,an as Te,Q as be,q as gs,I as Ye,ac as qe,a5 as Rt,R as at,B as Be,u as rt,aX as Zs,D as Rs,_ as Xs,J as us,Y as Tt}from"./vue-vendor-Bsazo-x0.js";import{c as O,s as j,_ as cs,a as ea,A as Ls}from"./index-04PYaMhT.js";import{C as Gs}from"./ConfirmModal-D4ZL95nR.js";import{C as ta}from"./chart-yFHxLHpB.js";import{C as Vs,_ as sa}from"./ActionDropdown-8ouGHGYE.js";import"./vendor-Dr8jvgFu.js";const Ss=$(!1),Es=$({title:"",message:"",confirmText:"继续",cancelText:"取消"}),jt=$(null);function Fs(){return{showConfirmModal:Ss,confirmOptions:Es,showConfirm:(Q,U,H="继续",V="取消")=>new Promise(K=>{Es.value={title:Q,message:U,confirmText:H,cancelText:V},jt.value=K,Ss.value=!0}),handleConfirm:()=>{Ss.value=!1,jt.value&&(jt.value(!0),jt.value=null)},handleCancel:()=>{Ss.value=!1,jt.value&&(jt.value(!1),jt.value=null)}}}const Qs=Hs("accounts",()=>{const J=$([]),Me=$([]),m=$([]),Q=$([]),U=$([]),H=$([]),V=$([]),K=$([]),b=$(!1),h=$(null),F=$(""),ee=$("asc"),ae=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/claude-accounts");if(v.success)J.value=v.data||[];else throw new Error(v.message||"获取Claude账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},ge=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/claude-console-accounts");if(v.success)Me.value=v.data||[];else throw new Error(v.message||"获取Claude Console账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},Z=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/bedrock-accounts");if(v.success)m.value=v.data||[];else throw new Error(v.message||"获取Bedrock账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},E=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/gemini-accounts");if(v.success)Q.value=v.data||[];else throw new Error(v.message||"获取Gemini账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},X=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/openai-accounts");if(v.success)U.value=v.data||[];else throw new Error(v.message||"获取OpenAI账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},w=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/azure-openai-accounts");if(v.success)H.value=v.data||[];else throw new Error(v.message||"获取Azure OpenAI账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},p=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/openai-responses-accounts");if(v.success)V.value=v.data||[];else throw new Error(v.message||"获取OpenAI-Responses账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}},_=async()=>{b.value=!0,h.value=null;try{const v=await O.get("/admin/droid-accounts");if(v.success)K.value=v.data||[];else throw new Error(v.message||"获取Droid账户失败")}catch(v){throw h.value=v.message,v}finally{b.value=!1}};return{claudeAccounts:J,claudeConsoleAccounts:Me,bedrockAccounts:m,geminiAccounts:Q,openaiAccounts:U,azureOpenaiAccounts:H,openaiResponsesAccounts:V,droidAccounts:K,loading:b,error:h,sortBy:F,sortOrder:ee,fetchClaudeAccounts:ae,fetchClaudeConsoleAccounts:ge,fetchBedrockAccounts:Z,fetchGeminiAccounts:E,fetchOpenAIAccounts:X,fetchAzureOpenAIAccounts:w,fetchOpenAIResponsesAccounts:p,fetchDroidAccounts:_,fetchAllAccounts:async()=>{b.value=!0,h.value=null;try{await Promise.all([ae(),ge(),Z(),E(),X(),w(),p(),_()])}catch(v){throw h.value=v.message,v}finally{b.value=!1}},createClaudeAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/claude-accounts",v);if(c.success)return await ae(),c.data;throw new Error(c.message||"创建Claude账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createClaudeConsoleAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/claude-console-accounts",v);if(c.success)return await ge(),c.data;throw new Error(c.message||"创建Claude Console账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createBedrockAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/bedrock-accounts",v);if(c.success)return await Z(),c.data;throw new Error(c.message||"创建Bedrock账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createGeminiAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/gemini-accounts",v);if(c.success)return await E(),c.data;throw new Error(c.message||"创建Gemini账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createOpenAIAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/openai-accounts",v);if(c.success)return await X(),c.data;throw new Error(c.message||"创建OpenAI账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createDroidAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/droid-accounts",v);if(c.success)return await _(),c.data;throw new Error(c.message||"创建Droid账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},updateDroidAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/droid-accounts/${v}`,c);if(D.success)return await _(),D.data;throw new Error(D.message||"更新Droid账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},createAzureOpenAIAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/azure-openai-accounts",v);if(c.success)return await w(),c.data;throw new Error(c.message||"创建Azure OpenAI账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createOpenAIResponsesAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/openai-responses-accounts",v);if(c.success)return await p(),c.data;throw new Error(c.message||"创建OpenAI-Responses账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},createGeminiApiAccount:async v=>{b.value=!0,h.value=null;try{const c=await O.post("/admin/gemini-api-accounts",v);if(c.success)return await E(),c.data;throw new Error(c.message||"创建Gemini API账户失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},updateClaudeAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/claude-accounts/${v}`,c);if(D.success)return await ae(),D;throw new Error(D.message||"更新Claude账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateClaudeConsoleAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/claude-console-accounts/${v}`,c);if(D.success)return await ge(),D;throw new Error(D.message||"更新Claude Console账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateBedrockAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/bedrock-accounts/${v}`,c);if(D.success)return await Z(),D;throw new Error(D.message||"更新Bedrock账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateGeminiAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/gemini-accounts/${v}`,c);if(D.success)return await E(),D;throw new Error(D.message||"更新Gemini账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateOpenAIAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/openai-accounts/${v}`,c);if(D.success)return await X(),D;throw new Error(D.message||"更新OpenAI账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateAzureOpenAIAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/azure-openai-accounts/${v}`,c);if(D.success)return await w(),D;throw new Error(D.message||"更新Azure OpenAI账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateOpenAIResponsesAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/openai-responses-accounts/${v}`,c);if(D.success)return await p(),D;throw new Error(D.message||"更新OpenAI-Responses账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},updateGeminiApiAccount:async(v,c)=>{b.value=!0,h.value=null;try{const D=await O.put(`/admin/gemini-api-accounts/${v}`,c);if(D.success)return await E(),D;throw new Error(D.message||"更新Gemini API账户失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},toggleAccount:async(v,c)=>{b.value=!0,h.value=null;try{let D;v==="claude"?D=`/admin/claude-accounts/${c}/toggle`:v==="claude-console"?D=`/admin/claude-console-accounts/${c}/toggle`:v==="bedrock"?D=`/admin/bedrock-accounts/${c}/toggle`:v==="gemini"?D=`/admin/gemini-accounts/${c}/toggle`:v==="openai"?D=`/admin/openai-accounts/${c}/toggle`:v==="azure_openai"?D=`/admin/azure-openai-accounts/${c}/toggle`:v==="openai-responses"?D=`/admin/openai-responses-accounts/${c}/toggle`:D=`/admin/openai-accounts/${c}/toggle`;const Fe=await O.put(D);if(Fe.success)return v==="claude"?await ae():v==="claude-console"?await ge():v==="bedrock"?await Z():v==="gemini"?await E():v==="openai"?await X():v==="azure_openai"?await w():v==="openai-responses"?await p():await X(),Fe;throw new Error(Fe.message||"切换状态失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},deleteAccount:async(v,c)=>{b.value=!0,h.value=null;try{let D;v==="claude"?D=`/admin/claude-accounts/${c}`:v==="claude-console"?D=`/admin/claude-console-accounts/${c}`:v==="bedrock"?D=`/admin/bedrock-accounts/${c}`:v==="gemini"?D=`/admin/gemini-accounts/${c}`:v==="openai"?D=`/admin/openai-accounts/${c}`:v==="azure_openai"?D=`/admin/azure-openai-accounts/${c}`:v==="openai-responses"?D=`/admin/openai-responses-accounts/${c}`:D=`/admin/openai-accounts/${c}`;const Fe=await O.delete(D);if(Fe.success)return v==="claude"?await ae():v==="claude-console"?await ge():v==="bedrock"?await Z():v==="gemini"?await E():v==="openai"?await X():v==="azure_openai"?await w():v==="openai-responses"?await p():await X(),Fe;throw new Error(Fe.message||"删除失败")}catch(D){throw h.value=D.message,D}finally{b.value=!1}},refreshClaudeToken:async v=>{b.value=!0,h.value=null;try{const c=await O.post(`/admin/claude-accounts/${v}/refresh`);if(c.success)return await ae(),c;throw new Error(c.message||"Token刷新失败")}catch(c){throw h.value=c.message,c}finally{b.value=!1}},generateClaudeAuthUrl:async v=>{try{const c=await O.post("/admin/claude-accounts/generate-auth-url",v);if(c.success)return c.data;throw new Error(c.message||"生成授权URL失败")}catch(c){throw h.value=c.message,c}},exchangeClaudeCode:async v=>{try{const c=await O.post("/admin/claude-accounts/exchange-code",v);if(c.success)return c.data;throw new Error(c.message||"交换授权码失败")}catch(c){throw h.value=c.message,c}},generateClaudeSetupTokenUrl:async v=>{try{const c=await O.post("/admin/claude-accounts/generate-setup-token-url",v);if(c.success)return c.data;throw new Error(c.message||"生成Setup Token URL失败")}catch(c){throw h.value=c.message,c}},exchangeClaudeSetupTokenCode:async v=>{try{const c=await O.post("/admin/claude-accounts/exchange-setup-token-code",v);if(c.success)return c.data;throw new Error(c.message||"交换Setup Token授权码失败")}catch(c){throw h.value=c.message,c}},oauthWithCookie:async v=>{try{const c=await O.post("/admin/claude-accounts/oauth-with-cookie",v);if(c.success)return c.data;throw new Error(c.message||"Cookie授权失败")}catch(c){throw h.value=c.message,c}},oauthSetupTokenWithCookie:async v=>{try{const c=await O.post("/admin/claude-accounts/setup-token-with-cookie",v);if(c.success)return c.data;throw new Error(c.message||"Cookie授权失败")}catch(c){throw h.value=c.message,c}},generateGeminiAuthUrl:async v=>{try{const c=await O.post("/admin/gemini-accounts/generate-auth-url",v);if(c.success)return c.data;throw new Error(c.message||"生成授权URL失败")}catch(c){throw h.value=c.message,c}},exchangeGeminiCode:async v=>{try{const c=await O.post("/admin/gemini-accounts/exchange-code",v);if(c.success)return c.data;throw new Error(c.message||"交换授权码失败")}catch(c){throw h.value=c.message,c}},generateOpenAIAuthUrl:async v=>{try{const c=await O.post("/admin/openai-accounts/generate-auth-url",v);if(c.success)return c.data;throw new Error(c.message||"生成授权URL失败")}catch(c){throw h.value=c.message,c}},exchangeOpenAICode:async v=>{try{const c=await O.post("/admin/openai-accounts/exchange-code",v);if(c.success)return c.data;throw new Error(c.message||"交换授权码失败")}catch(c){throw h.value=c.message,c}},generateDroidAuthUrl:async v=>{h.value=null;try{const c=await O.post("/admin/droid-accounts/generate-auth-url",v);if(c.success)return c.data;throw new Error(c.message||"生成授权URL失败")}catch(c){throw h.value=c.message,c}},exchangeDroidCode:async v=>{h.value=null;try{return await O.post("/admin/droid-accounts/exchange-code",v)}catch(c){throw h.value=c.message,c}},sortAccounts:v=>{F.value===v?ee.value=ee.value==="asc"?"desc":"asc":(F.value=v,ee.value="asc")},reset:()=>{J.value=[],Me.value=[],m.value=[],Q.value=[],U.value=[],H.value=[],V.value=[],K.value=[],b.value=!1,h.value=null,F.value="",ee.value="asc"}}}),aa={class:"space-y-4"},ra={class:"flex items-center justify-between"},la={class:"flex cursor-pointer items-center"},oa={key:0,class:"space-y-4 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-600 dark:bg-gray-800"},na={class:"relative"},ia={key:0,class:"mt-1 text-xs text-red-500"},da={key:1,class:"mt-1 text-xs text-green-500"},ua={class:"grid grid-cols-2 gap-4"},pa={class:"space-y-4"},ga={class:"flex items-center"},ca={key:0,class:"grid grid-cols-2 gap-4"},ma={class:"relative"},ya=["type"],Os={__name:"ProxyConfig",props:{modelValue:{type:Object,default:()=>({enabled:!1,type:"socks5",host:"",port:"",username:"",password:""})}},emits:["update:modelValue"],setup(J,{emit:Me}){const m=J,Q=Me,U=$({...m.modelValue}),H=$(!!(U.value.username||U.value.password)),V=$(!1),K=$(""),b=$(""),h=$(!1);ye(()=>m.modelValue,X=>{JSON.stringify(X)!==JSON.stringify(U.value)&&(U.value={...X},H.value=!!(X.username||X.password))},{deep:!0}),ye(()=>U.value.enabled,()=>{ee()}),ye(()=>U.value.type,()=>{ee()}),ye(()=>U.value.host,()=>{ee()}),ye(()=>U.value.port,()=>{ee()}),ye(()=>U.value.username,()=>{ee()}),ye(()=>U.value.password,()=>{ee()}),ye(H,X=>{X||(U.value.username="",U.value.password="",ee())});let F=null;function ee(){F&&clearTimeout(F),F=setTimeout(()=>{const X={...U.value};H.value||(X.username="",X.password=""),Q("update:modelValue",X)},100)}function ae(){if(b.value="",h.value=!1,!!K.value)try{const X=K.value.split("#")[0].trim();if(!X)return;const w=/^(socks5|https?):\/\/(?:([^:@]+):([^@]+)@)?([^:]+):(\d+)$/i,p=X.match(w);if(!p){const ve=/^([^:]+):(\d+)$/,ie=X.match(ve);if(ie){U.value.type="socks5",U.value.host=ie[1],U.value.port=ie[2],U.value.username="",U.value.password="",H.value=!1,h.value=!0,ee(),setTimeout(()=>{h.value=!1},3e3);return}b.value="无效的代理URL格式,请检查输入";return}const[,_,te,Y,P,W]=p;U.value.type=_.toLowerCase(),U.value.host=P,U.value.port=W,te&&Y?(U.value.username=decodeURIComponent(te),U.value.password=decodeURIComponent(Y),H.value=!0):(U.value.username="",U.value.password="",H.value=!1),h.value=!0,ee(),setTimeout(()=>{h.value=!1},3e3)}catch{b.value="解析失败,请检查URL格式"}}function ge(){K.value="",b.value="",h.value=!1}function Z(){setTimeout(()=>{ae()},0)}function E(){const X=K.value.trim();X.includes("://")?(/^(socks5|https?):\/\/[^:]+:\d+/i.test(X)||/^(socks5|https?):\/\/[^:@]+:[^@]+@[^:]+:\d+/i.test(X))&&ae():/^[^:]+:\d{2,5}$/.test(X)&&ae()}return zs(()=>{F&&clearTimeout(F)}),(X,w)=>(o(),n("div",aa,[e("div",ra,[w[10]||(w[10]=e("h4",{class:"text-sm font-semibold text-gray-700 dark:text-gray-300"},"代理设置 (可选)",-1)),e("label",la,[k(e("input",{"onUpdate:modelValue":w[0]||(w[0]=p=>U.value.enabled=p),class:"h-4 w-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-blue-500",type:"checkbox"},null,512),[[De,U.value.enabled]]),w[9]||(w[9]=e("span",{class:"ml-2 text-sm text-gray-700 dark:text-gray-300"},"启用代理",-1))])]),U.value.enabled?(o(),n("div",oa,[w[22]||(w[22]=Vt('
配置代理以访问受限的网络资源。支持 SOCKS5 和 HTTP 代理。
请确保代理服务器稳定可用,否则会影响账户的正常使用。
sessionKey 通常以 sk-ant-sid01- 开头
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Claude 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Gemini 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。
重要提示:授权后页面可能会加载较长时间,请耐心等待。
当浏览器地址栏变为 http://localhost:1455/... 开头时,表示授权已完成。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
提示:您可以直接复制整个链接或仅复制 code 参数值,系统会自动识别。
• 完整链接示例:http://localhost:1455/auth/callback?code=ac_4hm8...
• 仅 Code 示例:ac_4hm8iqmx9A2fzMy_cwye7U3W7...
在浏览器中打开链接并完成授权
在浏览器中打开授权页面,输入上方验证码并登录 Factory / Droid 账户,最后点击允许授权。
完成授权后点击下方“完成授权”按钮,系统会自动获取访问令牌。
若提示授权仍在等待确认,请稍候片刻后系统会自动重试。
配置代理以访问受限的网络资源。支持 SOCKS5 和 HTTP 代理。
请确保代理服务器稳定可用,否则会影响账户的正常使用。
sessionKey 通常以 sk-ant-sid01- 开头
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Claude 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Gemini 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。
重要提示:授权后页面可能会加载较长时间,请耐心等待。
当浏览器地址栏变为 http://localhost:1455/... 开头时,表示授权已完成。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
提示:您可以直接复制整个链接或仅复制 code 参数值,系统会自动识别。
• 完整链接示例:http://localhost:1455/auth/callback?code=ac_4hm8...
• 仅 Code 示例:ac_4hm8iqmx9A2fzMy_cwye7U3W7...
在浏览器中打开链接并完成授权
在浏览器中打开授权页面,输入上方验证码并登录 Factory / Droid 账户,最后点击允许授权。
完成授权后点击下方“完成授权”按钮,系统会自动获取访问令牌。
若提示授权仍在等待确认,请稍候片刻后系统会自动重试。
自定义您的站点品牌名称
上传自定义图标或输入图标URL
控制登录按钮在首页的显示
Claude Code 需要 Node.js 环境才能运行。
方法一:官网下载(推荐)
https://nodejs.org/.msi 文件 方法二:使用包管理器
如果你安装了 Chocolatey 或 Scoop,可以使用命令行安装:
安装完成后,打开 PowerShell 或 CMD,输入以下命令:
如果显示版本号,说明安装成功了!
打开 PowerShell 或 CMD,运行以下命令:
这个命令会从 npm 官方仓库下载并安装最新版本的 Claude Code。
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
查看已设置的环境变量:
💡 设置后需要重新打开 PowerShell 窗口才能生效。
',3))])])]),t[35]||(t[35]=m('如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:C:\\Users\\你的用户名\\.claude\\config.json
💡 如果该文件不存在,请手动创建。
设置完环境变量后,可以通过以下命令验证是否设置成功:
在 PowerShell 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Windows 中可直接编辑 C:\\Users\\你的用户名\\.factory\\config.json。
现在你可以开始使用 Claude Code 了!
这通常是权限问题,尝试以下解决方法:
npm config set prefix %APPDATA%\\npm如果遇到执行策略限制,运行:
设置永久环境变量后需要:
echo $env:ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用 Homebrew(推荐)
如果你已经安装了 Homebrew,使用它安装 Node.js 会更方便:
方法二:官网下载
https://nodejs.org/.pkg 文件 sudo安装完成后,打开 Terminal,输入以下命令:
如果显示版本号,说明安装成功了!
打开 Terminal,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
在 Terminal 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;你可以在 Finder 中按 ⌘ + Shift + G 并输入路径,或运行 open ~/.factory 快速打开配置目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-global如果系统阻止运行 Claude Code:
sudo spctl --master-disable检查以下几点:
echo $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用官方仓库(推荐)
方法二:使用系统包管理器
虽然版本可能不是最新的,但对于基本使用已经足够:
sudo安装完成后,打开终端,输入以下命令:
如果显示版本号,说明安装成功了!
打开终端,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
在终端中验证:
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Linux 或 WSL2 中,可直接编辑 /home/你的用户名/.factory/config.json 或在终端运行 xdg-open ~/.factory 打开目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-globalexport PATH=~/.npm-global/bin:$PATH某些 Linux 发行版需要安装额外依赖:
检查以下几点:
source ~/.bashrcecho $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:官网下载(推荐)
https://nodejs.org/.msi 文件 方法二:使用包管理器
如果你安装了 Chocolatey 或 Scoop,可以使用命令行安装:
安装完成后,打开 PowerShell 或 CMD,输入以下命令:
如果显示版本号,说明安装成功了!
打开 PowerShell 或 CMD,运行以下命令:
这个命令会从 npm 官方仓库下载并安装最新版本的 Claude Code。
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
查看已设置的环境变量:
💡 设置后需要重新打开 PowerShell 窗口才能生效。
',3))])])]),t[35]||(t[35]=m('如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:C:\\Users\\你的用户名\\.claude\\config.json
💡 如果该文件不存在,请手动创建。
设置完环境变量后,可以通过以下命令验证是否设置成功:
在 PowerShell 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Windows 中可直接编辑 C:\\Users\\你的用户名\\.factory\\config.json。
现在你可以开始使用 Claude Code 了!
这通常是权限问题,尝试以下解决方法:
npm config set prefix %APPDATA%\\npm如果遇到执行策略限制,运行:
设置永久环境变量后需要:
echo $env:ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用 Homebrew(推荐)
如果你已经安装了 Homebrew,使用它安装 Node.js 会更方便:
方法二:官网下载
https://nodejs.org/.pkg 文件 sudo安装完成后,打开 Terminal,输入以下命令:
如果显示版本号,说明安装成功了!
打开 Terminal,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
在 Terminal 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;你可以在 Finder 中按 ⌘ + Shift + G 并输入路径,或运行 open ~/.factory 快速打开配置目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-global如果系统阻止运行 Claude Code:
sudo spctl --master-disable检查以下几点:
echo $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用官方仓库(推荐)
方法二:使用系统包管理器
虽然版本可能不是最新的,但对于基本使用已经足够:
sudo安装完成后,打开终端,输入以下命令:
如果显示版本号,说明安装成功了!
打开终端,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
在终端中验证:
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Linux 或 WSL2 中,可直接编辑 /home/你的用户名/.factory/config.json 或在终端运行 xdg-open ~/.factory 打开目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-globalexport PATH=~/.npm-global/bin:$PATH某些 Linux 发行版需要安装额外依赖:
检查以下几点:
source ~/.bashrcecho $ANTHROPIC_BASE_URLDaily usage trends would be displayed here
(Chart integration can be added with Chart.js, D3.js, or similar library)
Daily usage trends would be displayed here
(Chart integration can be added with Chart.js, D3.js, or similar library)
Sign in to your account to manage your API keys
Sign in to your account to manage your API keys
配置代理以访问受限的网络资源。支持 SOCKS5 和 HTTP 代理。
请确保代理服务器稳定可用,否则会影响账户的正常使用。
sessionKey 通常以 sk-ant-sid01- 开头
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Claude 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Gemini 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。
重要提示:授权后页面可能会加载较长时间,请耐心等待。
当浏览器地址栏变为 http://localhost:1455/... 开头时,表示授权已完成。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
提示:您可以直接复制整个链接或仅复制 code 参数值,系统会自动识别。
• 完整链接示例:http://localhost:1455/auth/callback?code=ac_4hm8...
• 仅 Code 示例:ac_4hm8iqmx9A2fzMy_cwye7U3W7...
在浏览器中打开链接并完成授权
在浏览器中打开授权页面,输入上方验证码并登录 Factory / Droid 账户,最后点击允许授权。
完成授权后点击下方“完成授权”按钮,系统会自动获取访问令牌。
若提示授权仍在等待确认,请稍候片刻后系统会自动重试。
配置代理以访问受限的网络资源。支持 SOCKS5 和 HTTP 代理。
请确保代理服务器稳定可用,否则会影响账户的正常使用。
sessionKey 通常以 sk-ant-sid01- 开头
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Claude 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 Gemini 账户并授权。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
在浏览器中打开链接并完成授权
请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。
重要提示:授权后页面可能会加载较长时间,请耐心等待。
当浏览器地址栏变为 http://localhost:1455/... 开头时,表示授权已完成。
注意:如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
提示:您可以直接复制整个链接或仅复制 code 参数值,系统会自动识别。
• 完整链接示例:http://localhost:1455/auth/callback?code=ac_4hm8...
• 仅 Code 示例:ac_4hm8iqmx9A2fzMy_cwye7U3W7...
在浏览器中打开链接并完成授权
在浏览器中打开授权页面,输入上方验证码并登录 Factory / Droid 账户,最后点击允许授权。
完成授权后点击下方“完成授权”按钮,系统会自动获取访问令牌。
若提示授权仍在等待确认,请稍候片刻后系统会自动重试。
自定义您的站点品牌名称
上传自定义图标或输入图标URL
控制登录按钮在首页的显示
Claude Code 需要 Node.js 环境才能运行。
方法一:官网下载(推荐)
https://nodejs.org/.msi 文件 方法二:使用包管理器
如果你安装了 Chocolatey 或 Scoop,可以使用命令行安装:
安装完成后,打开 PowerShell 或 CMD,输入以下命令:
如果显示版本号,说明安装成功了!
打开 PowerShell 或 CMD,运行以下命令:
这个命令会从 npm 官方仓库下载并安装最新版本的 Claude Code。
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
查看已设置的环境变量:
💡 设置后需要重新打开 PowerShell 窗口才能生效。
',3))])])]),t[35]||(t[35]=m('如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:C:\\Users\\你的用户名\\.claude\\config.json
💡 如果该文件不存在,请手动创建。
设置完环境变量后,可以通过以下命令验证是否设置成功:
在 PowerShell 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Windows 中可直接编辑 C:\\Users\\你的用户名\\.factory\\config.json。
现在你可以开始使用 Claude Code 了!
这通常是权限问题,尝试以下解决方法:
npm config set prefix %APPDATA%\\npm如果遇到执行策略限制,运行:
设置永久环境变量后需要:
echo $env:ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用 Homebrew(推荐)
如果你已经安装了 Homebrew,使用它安装 Node.js 会更方便:
方法二:官网下载
https://nodejs.org/.pkg 文件 sudo安装完成后,打开 Terminal,输入以下命令:
如果显示版本号,说明安装成功了!
打开 Terminal,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
在 Terminal 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;你可以在 Finder 中按 ⌘ + Shift + G 并输入路径,或运行 open ~/.factory 快速打开配置目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-global如果系统阻止运行 Claude Code:
sudo spctl --master-disable检查以下几点:
echo $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用官方仓库(推荐)
方法二:使用系统包管理器
虽然版本可能不是最新的,但对于基本使用已经足够:
sudo安装完成后,打开终端,输入以下命令:
如果显示版本号,说明安装成功了!
打开终端,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
在终端中验证:
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Linux 或 WSL2 中,可直接编辑 /home/你的用户名/.factory/config.json 或在终端运行 xdg-open ~/.factory 打开目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-globalexport PATH=~/.npm-global/bin:$PATH某些 Linux 发行版需要安装额外依赖:
检查以下几点:
source ~/.bashrcecho $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:官网下载(推荐)
https://nodejs.org/.msi 文件 方法二:使用包管理器
如果你安装了 Chocolatey 或 Scoop,可以使用命令行安装:
安装完成后,打开 PowerShell 或 CMD,输入以下命令:
如果显示版本号,说明安装成功了!
打开 PowerShell 或 CMD,运行以下命令:
这个命令会从 npm 官方仓库下载并安装最新版本的 Claude Code。
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
查看已设置的环境变量:
💡 设置后需要重新打开 PowerShell 窗口才能生效。
',3))])])]),t[35]||(t[35]=m('如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:C:\\Users\\你的用户名\\.claude\\config.json
💡 如果该文件不存在,请手动创建。
设置完环境变量后,可以通过以下命令验证是否设置成功:
在 PowerShell 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Windows 中可直接编辑 C:\\Users\\你的用户名\\.factory\\config.json。
现在你可以开始使用 Claude Code 了!
这通常是权限问题,尝试以下解决方法:
npm config set prefix %APPDATA%\\npm如果遇到执行策略限制,运行:
设置永久环境变量后需要:
echo $env:ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用 Homebrew(推荐)
如果你已经安装了 Homebrew,使用它安装 Node.js 会更方便:
方法二:官网下载
https://nodejs.org/.pkg 文件 sudo安装完成后,打开 Terminal,输入以下命令:
如果显示版本号,说明安装成功了!
打开 Terminal,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
在 Terminal 中验证:
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;你可以在 Finder 中按 ⌘ + Shift + G 并输入路径,或运行 open ~/.factory 快速打开配置目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-global如果系统阻止运行 Claude Code:
sudo spctl --master-disable检查以下几点:
echo $ANTHROPIC_BASE_URLClaude Code 需要 Node.js 环境才能运行。
方法一:使用官方仓库(推荐)
方法二:使用系统包管理器
虽然版本可能不是最新的,但对于基本使用已经足够:
sudo安装完成后,打开终端,输入以下命令:
如果显示版本号,说明安装成功了!
打开终端,运行以下命令:
如果遇到权限问题,可以使用 sudo:
安装完成后,输入以下命令检查是否安装成功:
如果显示版本号,恭喜你!Claude Code 已经成功安装了。
在终端中验证:
如果使用 VSCode 的 Claude 插件,需要在配置文件中进行设置:
配置文件位置:~/.claude/config.json
💡 如果该文件不存在,请手动创建。
Droid CLI 使用 ~/.factory/config.json 保存自定义模型;在 Linux 或 WSL2 中,可直接编辑 /home/你的用户名/.factory/config.json 或在终端运行 xdg-open ~/.factory 打开目录。
现在你可以开始使用 Claude Code 了!
尝试以下解决方法:
sudo npm install -g @anthropic-ai/claude-codenpm config set prefix ~/.npm-globalexport PATH=~/.npm-global/bin:$PATH某些 Linux 发行版需要安装额外依赖:
检查以下几点:
source ~/.bashrcecho $ANTHROPIC_BASE_URLDaily usage trends would be displayed here
(Chart integration can be added with Chart.js, D3.js, or similar library)
Daily usage trends would be displayed here
(Chart integration can be added with Chart.js, D3.js, or similar library)
Sign in to your account to manage your API keys
Sign in to your account to manage your API keys
=0;--u)if(!g()){this.updateRangeFromParsed(c,t,f,l);break}}return c}getAllParsedValues(t){const e=this._cachedMeta._parsed,s=[];let n,o,a;for(n=0,o=e.length;n m&&(m=_),h=(d*h+y)/++d):(v(),i.lineTo(y,_),g=k,d=0,p=m=_),b=_}v()}function pi(i){const t=i.options,e=t.borderDash&&t.borderDash.length;return!i._decimated&&!i._loop&&!t.tension&&t.cubicInterpolationMode!=="monotone"&&!t.stepped&&!e?cl:ll}function hl(i){return i.stepped?la:i.tension||i.cubicInterpolationMode==="monotone"?ca:At}function dl(i,t,e,s){let n=t._path;n||(n=t._path=new Path2D,t.path(n,e,s)&&n.closePath()),Wn(i,t.options),i.stroke(n)}function ul(i,t,e,s){const{segments:n,options:o}=t,a=pi(t);for(const r of n)Wn(i,o,r.style),i.beginPath(),a(i,t,r,{start:e,end:e+s-1})&&i.closePath(),i.stroke()}const fl=typeof Path2D=="function";function gl(i,t,e,s){fl&&!t.options.segment?dl(i,t,e,s):ul(i,t,e,s)}class bt extends ot{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const s=this.options;if((s.tension||s.cubicInterpolationMode==="monotone")&&!s.stepped&&!this._pointsUpdated){const n=s.spanGaps?this._loop:this._fullLoop;ta(this._points,s,t,n,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=pa(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,s=t.length;return s&&e[t[s-1].end]}interpolate(t,e){const s=this.options,n=t[e],o=this.points,a=Pn(this,{property:e,start:n,end:n});if(!a.length)return;const r=[],l=hl(s);let c,h;for(c=0,h=a.length;cc.box.fullSize),!0),s=Xt(Ut(t,"left"),!0),n=Xt(Ut(t,"right")),o=Xt(Ut(t,"top"),!0),a=Xt(Ut(t,"bottom")),r=ds(t,"x"),l=ds(t,"y");return{fullSize:e,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ut(t,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}function us(i,t,e,s){return Math.max(i[e],t[e])+Math.max(i[s],t[s])}function Ln(i,t){i.top=Math.max(i.top,t.top),i.left=Math.max(i.left,t.left),i.bottom=Math.max(i.bottom,t.bottom),i.right=Math.max(i.right,t.right)}function er(i,t,e,s){const{pos:n,box:o}=e,a=i.maxPadding;if(!T(n)){e.size&&(i[n]-=e.size);const d=s[e.stack]||{size:0,count:1};d.size=Math.max(d.size,e.horizontal?o.height:o.width),e.size=d.size/d.count,i[n]+=e.size}o.getPadding&&Ln(a,o.getPadding());const r=Math.max(0,t.outerWidth-us(a,i,"left","right")),l=Math.max(0,t.outerHeight-us(a,i,"top","bottom")),c=r!==i.w,h=l!==i.h;return i.w=r,i.h=l,e.horizontal?{same:c,other:h}:{same:h,other:c}}function ir(i){const t=i.maxPadding;function e(s){const n=Math.max(t[s]-i[s],0);return i[s]+=n,n}i.y+=e("top"),i.x+=e("left"),e("right"),e("bottom")}function sr(i,t){const e=t.maxPadding;function s(n){const o={left:0,top:0,right:0,bottom:0};return n.forEach(a=>{o[a]=Math.max(t[a],e[a])}),o}return s(i?["left","right"]:["top","bottom"])}function Jt(i,t,e,s){const n=[];let o,a,r,l,c,h;for(o=0,a=i.length,c=0;o{typeof p.beforeLayout=="function"&&p.beforeLayout()});const h=l.reduce((p,m)=>m.box.options&&m.box.options.display===!1?p:p+1,0)||1,d=Object.freeze({outerWidth:t,outerHeight:e,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/h,hBoxMaxHeight:a/2}),u=Object.assign({},n);Ln(u,J(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=Za(l.concat(c),d);Jt(r.fullSize,f,d,g),Jt(l,f,d,g),Jt(c,f,d,g)&&Jt(l,f,d,g),ir(f),fs(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,fs(r.rightAndBottom,f,d,g),i.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},I(r.chartArea,p=>{const m=p.box;Object.assign(m,i.chartArea),m.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})})}};class Rn{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,s){}removeEventListener(t,e,s){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,s,n){return e=Math.max(0,e||t.width),s=s||t.height,{width:e,height:Math.max(0,n?Math.floor(e/n):s)}}isAttached(t){return!0}updateConfig(t){}}class nr extends Rn{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const Te="$chartjs",or={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},gs=i=>i===null||i==="";function ar(i,t){const e=i.style,s=i.getAttribute("height"),n=i.getAttribute("width");if(i[Te]={initial:{height:s,width:n,style:{display:e.display,height:e.height,width:e.width}}},e.display=e.display||"block",e.boxSizing=e.boxSizing||"border-box",gs(n)){const o=Ji(i,"width");o!==void 0&&(i.width=o)}if(gs(s))if(i.style.height==="")i.height=i.width/(t||2);else{const o=Ji(i,"height");o!==void 0&&(i.height=o)}return i}const In=ra?{passive:!0}:!1;function rr(i,t,e){i&&i.addEventListener(t,e,In)}function lr(i,t,e){i&&i.canvas&&i.canvas.removeEventListener(t,e,In)}function cr(i,t){const e=or[i.type]||i.type,{x:s,y:n}=Ct(i,t);return{type:e,chart:t,native:i,x:s!==void 0?s:null,y:n!==void 0?n:null}}function We(i,t){for(const e of i)if(e===t||e.contains(t))return!0}function hr(i,t,e){const s=i.canvas,n=new MutationObserver(o=>{let a=!1;for(const r of o)a=a||We(r.addedNodes,s),a=a&&!We(r.removedNodes,s);a&&e()});return n.observe(document,{childList:!0,subtree:!0}),n}function dr(i,t,e){const s=i.canvas,n=new MutationObserver(o=>{let a=!1;for(const r of o)a=a||We(r.removedNodes,s),a=a&&!We(r.addedNodes,s);a&&e()});return n.observe(document,{childList:!0,subtree:!0}),n}const he=new Map;let ps=0;function En(){const i=window.devicePixelRatio;i!==ps&&(ps=i,he.forEach((t,e)=>{e.currentDevicePixelRatio!==i&&t()}))}function ur(i,t){he.size||window.addEventListener("resize",En),he.set(i,t)}function fr(i){he.delete(i),he.size||window.removeEventListener("resize",En)}function gr(i,t,e){const s=i.canvas,n=s&&Ii(s);if(!n)return;const o=hn((r,l)=>{const c=n.clientWidth;e(r,l),ci==="left"?"right":i==="right"?"left":i,ms=(i,t,e)=>t==="top"||t==="left"?i[t]+e:i[t]-e,bs=(i,t)=>Math.min(t||i,i);function xs(i,t){const e=[],s=i.length/t,n=i.length;let o=0;for(;o({width:a[P]||0,height:r[P]||0});return{first:w(0),last:w(e-1),widest:w(k),highest:w(S),widths:a,heights:r}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return fo(this._alignToPixels?wt(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&te.length&&delete this._stacks,t.forEach((s,n)=>{e.filter(o=>o===s._dataset).length===0&&this._destroyDatasetMeta(n)})}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let s,n;for(this._removeUnreferencedMetasets(),s=0,n=e.length;s=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,s={meta:t,index:t.index,cancelable:!0},n=Dn(this,t);this.notifyPlugins("beforeDatasetDraw",s)!==!1&&(n&&$e(e,n),t.controller.draw(),n&&Ye(e),s.cancelable=!1,this.notifyPlugins("afterDatasetDraw",s))}isPointInArea(t){return gt(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,s,n){const o=qa.modes[e];return typeof o=="function"?o(this,t,s,n):[]}getDatasetMeta(t){const e=this.data.datasets[t],s=this._metasets;let n=s.filter(o=>o&&o._dataset===e).pop();return n||(n={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},s.push(n)),n}getContext(){return this.$context||(this.$context=vt(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const s=this.getDatasetMeta(t);return typeof s.hidden=="boolean"?!s.hidden:!e.hidden}setDatasetVisibility(t,e){const s=this.getDatasetMeta(t);s.hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,s){const n=s?"show":"hide",o=this.getDatasetMeta(t),a=o.controller._resolveAnimations(void 0,n);re(e)?(o.data[e].hidden=!s,this.update()):(this.setDatasetVisibility(t,s),a.update(o,{visible:s}),this.update(r=>r.datasetIndex===t?n:void 0))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),ht.remove(this),t=0,e=this.data.datasets.length;ti.height-s/2?"bottom":"center"}function cc(i,t,e,s){const{x:n,width:o}=s,a=e.caretSize+e.caretPadding;if(i==="left"&&n+o+a>t.width||i==="right"&&n-o-a<0)return!0}function hc(i,t,e,s){const{x:n,width:o}=e,{width:a,chartArea:{left:r,right:l}}=i;let c="center";return s==="center"?c=n<=(r+l)/2?"left":"right":n<=o/2?c="left":n>=a-o/2&&(c="right"),cc(c,i,t,e)&&(c="center"),c}function Ns(i,t,e){const s=e.yAlign||t.yAlign||lc(i,e);return{xAlign:e.xAlign||t.xAlign||hc(i,t,e,s),yAlign:s}}function dc(i,t){let{x:e,width:s}=i;return t==="right"?e-=s:t==="center"&&(e-=s/2),e}function uc(i,t,e){let{y:s,height:n}=i;return t==="top"?s+=e:t==="bottom"?s-=n+e:s-=n/2,s}function Hs(i,t,e,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=i,{xAlign:r,yAlign:l}=e,c=n+o,{topLeft:h,topRight:d,bottomLeft:u,bottomRight:f}=Tt(a);let g=dc(t,r);const p=uc(t,l,c);return l==="center"?r==="left"?g+=c:r==="right"&&(g-=c):r==="left"?g-=Math.max(h,u)+n:r==="right"&&(g+=Math.max(d,f)+n),{x:Y(g,0,s.width-t.width),y:Y(p,0,s.height-t.height)}}function Se(i,t,e){const s=J(e.padding);return t==="center"?i.x+i.width/2:t==="right"?i.x+i.width-s.right:i.x+s.left}function js(i){return at([],dt(i))}function fc(i,t,e){return vt(i,{tooltip:t,tooltipItems:e,type:"tooltip"})}function $s(i,t){const e=t&&t.dataset&&t.dataset.tooltip&&t.dataset.tooltip.callbacks;return e?i.override(e):i}const Gn={beforeTitle:ct,title(i){if(i.length>0){const t=i[0],e=t.chart.data.labels,s=e?e.length:0;if(this&&this.options&&this.options.mode==="dataset")return t.dataset.label||"";if(t.label)return t.label;if(s>0&&t.dataIndex"u"?Gn[t].call(e,s):n}class xi extends ot{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,s=this.options.setContext(this.getContext()),n=s.enabled&&e.options.animation&&s.animations,o=new Cn(this.chart,n);return n._cacheable&&(this._cachedAnimations=Object.freeze(o)),o}getContext(){return this.$context||(this.$context=fc(this.chart.getContext(),this,this._tooltipItems))}getTitle(t,e){const{callbacks:s}=e,n=Q(s,"beforeTitle",this,t),o=Q(s,"title",this,t),a=Q(s,"afterTitle",this,t);let r=[];return r=at(r,dt(n)),r=at(r,dt(o)),r=at(r,dt(a)),r}getBeforeBody(t,e){return js(Q(e.callbacks,"beforeBody",this,t))}getBody(t,e){const{callbacks:s}=e,n=[];return I(t,o=>{const a={before:[],lines:[],after:[]},r=$s(s,o);at(a.before,dt(Q(r,"beforeLabel",this,o))),at(a.lines,Q(r,"label",this,o)),at(a.after,dt(Q(r,"afterLabel",this,o))),n.push(a)}),n}getAfterBody(t,e){return js(Q(e.callbacks,"afterBody",this,t))}getFooter(t,e){const{callbacks:s}=e,n=Q(s,"beforeFooter",this,t),o=Q(s,"footer",this,t),a=Q(s,"afterFooter",this,t);let r=[];return r=at(r,dt(n)),r=at(r,dt(o)),r=at(r,dt(a)),r}_createItems(t){const e=this._active,s=this.chart.data,n=[],o=[],a=[];let r=[],l,c;for(l=0,c=e.length;ln?{start:t-e,end:t}:{start:t,end:t+e}}function kc(i){const t={l:i.left+i._padding.left,r:i.right-i._padding.right,t:i.top+i._padding.top,b:i.bottom-i._padding.bottom},e=Object.assign({},t),s=[],n=[],o=i._pointLabels.length,a=i.options.pointLabels,r=a.centerPointLabels?R/o:0;for(let l=0;l{const n=z(this.options.pointLabels.callback,[e,s],this);return n||n===0?n:""}).filter((e,s)=>this.chart.getDataVisibility(s))}fit(){const t=this.options;t.display&&t.pointLabels.display?kc(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,s,n){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((s-n)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,s,n))}getIndexAngle(t){const e=F/(this._pointLabels.length||1),s=this.options.startAngle||0;return G(t*e+st(s))}getDistanceFromCenterForValue(t){if(O(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(O(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t+p)}getLabelForValue(t){const e=this._adapter,s=this.options.time;return s.tooltipFormat?e.format(t,s.tooltipFormat):e.format(t,s.displayFormats.datetime)}format(t,e){const n=this.options.time.displayFormats,o=this._unit,a=e||n[o];return this._adapter.format(t,a)}_tickFormatFunction(t,e,s,n){const o=this.options,a=o.ticks.callback;if(a)return z(a,[t,e,s],this);const r=o.time.displayFormats,l=this._unit,c=this._majorUnit,h=l&&r[l],d=c&&r[c],u=s[e],f=c&&d&&u&&u.major;return this._adapter.format(t,n||(f?d:h))}generateTickLabels(t){let e,s,n;for(e=0,s=t.length;e0?r:1}getDataTimestamps(){let t=this._cache.data||[],e,s;if(t.length)return t;const n=this.getMatchingVisibleMetas();if(this._normalized&&n.length)return this._cache.data=n[0].controller.getAllParsedValues(this);for(e=0,s=n.length;e=i[s].pos&&t<=i[n].pos&&({lo:s,hi:n}=ft(i,"pos",t)),{pos:o,time:r}=i[s],{pos:a,time:l}=i[n]):(t>=i[s].time&&t<=i[n].time&&({lo:s,hi:n}=ft(i,"time",t)),{time:o,pos:r}=i[s],{time:a,pos:l}=i[n]);const c=a-o;return c?r+(l-r)*(t-o)/c:r}class ki extends ue{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=we(e,this.min),this._tableRange=we(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:s}=this,n=[],o=[];let a,r,l,c,h;for(a=0,r=t.length;a{const[a,s]=[t[l],t[$r[l]]];return(s>0?a[s].offset:0)>=n?Ov(e,t,0,s,n,l):sN(e,t,rs(0,s),n,l)},Lv=({totalRow:e},{estimatedRowHeight:t,lastVisitedRowIndex:n,row:l})=>{let a=0;if(n>=e&&(n=e-1),n>=0){const i=l[n];a=i.offset+i.size}const r=(e-n-1)*t;return a+r},Bv=({totalColumn:e},{column:t,estimatedColumnWidth:n,lastVisitedColumnIndex:l})=>{let a=0;if(l>e&&(l=e-1),l>=0){const i=t[l];a=i.offset+i.size}const r=(e-l-1)*n;return a+r},rN={column:Bv,row:Lv},uc=(e,t,n,l,a,s,r)=>{const[i,u]=[s==="row"?e.height:e.width,rN[s]],c=sl(e,t,a,s),d=u(e,a),f=rs(0,Rv(d-i,c.offset)),m=rs(0,c.offset-i+r+c.size);switch(n===Ns&&(l>=m-i&&l<=f+i?n=xn:n=Jn),n){case ta:return f;case na:return m;case Jn:return Math.round(m+(f-m)/2);case xn:default:return l>=m&&l<=f?l:m>f||l0&&n.lazy&&n.defaultExpandAll&&!this.isLeafByUser&&this.expand(),ke(this.data)||gc(this,this.data),!this.data)return;const a=n.defaultExpandedKeys,s=n.key;s&&!qt(this.key)&&a&&a.includes(this.key)&&this.expand(null,n.autoExpandParent),s&&n.currentNodeKey!==void 0&&this.key===n.currentNodeKey&&(n.currentNode=this,n.currentNode.isCurrent=!0),n.lazy&&n._initDefaultCheckedNode(this),this.updateLeafState(),(this.level===1||((t=this.parent)==null?void 0:t.expanded)===!0)&&(this.canFocus=!0)}setData(t){ke(t)||gc(this,t),this.data=t,this.childNodes=[];let n;this.level===0&&ke(this.data)?n=this.data:n=Ma(this,"children")||[];for(let l=0,a=n.length;l-1)return t.childNodes[n+1]}return null}get previousSibling(){const t=this.parent;if(t){const n=t.childNodes.indexOf(this);if(n>-1)return n>0?t.childNodes[n-1]:null}return null}contains(t,n=!0){return(this.childNodes||[]).some(l=>l===t||n&&l.contains(t))}remove(){const t=this.parent;t&&t.removeChild(this)}insertChild(t,n,l){if(!t)throw new Error("InsertChild error: child is required.");if(!(t instanceof Wl)){if(!l){const a=this.getChildren(!0);a!=null&&a.includes(t.data)||(vt(n)||n<0?a==null||a.push(t.data):a==null||a.splice(n,0,t.data))}Object.assign(t,{parent:this,store:this.store}),t=kt(new Wl(t)),t instanceof Wl&&t.initialize()}t.level=this.level+1,vt(n)||n<0?this.childNodes.push(t):this.childNodes.splice(n,0,t),this.updateLeafState()}insertBefore(t,n){let l;n&&(l=this.childNodes.indexOf(n)),this.insertChild(t,l)}insertAfter(t,n){let l;n&&(l=this.childNodes.indexOf(n),l!==-1&&(l+=1)),this.insertChild(t,l)}removeChild(t){const n=this.getChildren()||[],l=n.indexOf(t.data);l>-1&&n.splice(l,1);const a=this.childNodes.indexOf(t);a>-1&&(this.store&&this.store.deregisterNode(t),t.parent=null,this.childNodes.splice(a,1)),this.updateLeafState()}removeChildByData(t){let n=null;for(let l=0;l1)&&(s=1),s}function zo(s){return s<=1?"".concat(Number(s)*100,"%"):s}function Va(s){return s.length===1?"0"+s:String(s)}function NF(s,f,o){return{r:Dr(s,255)*255,g:Dr(f,255)*255,b:Dr(o,255)*255}}function c2(s,f,o){s=Dr(s,255),f=Dr(f,255),o=Dr(o,255);var c=Math.max(s,f,o),r=Math.min(s,f,o),e=0,w=0,A=(c+r)/2;if(c===r)w=0,e=0;else{var k=c-r;switch(w=A>.5?k/(2-c-r):k/(c+r),c){case s:e=(f-o)/k+(f