@juejin-opensource/jusage 0.1.9 → 0.1.11
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/args.d.ts +8 -0
- package/dist/args.js +29 -4
- package/dist/dashboard/assets/autoclaw-CP85Wy6L.svg +41 -0
- package/dist/dashboard/assets/dashboard-BW9PQ-aW.js +60 -0
- package/dist/dashboard/assets/download-C1JZSDMp.js +6 -0
- package/dist/dashboard/assets/{downloads-BGBukFcp.js → downloads-BWVeZf1b.js} +1 -1
- package/dist/dashboard/assets/{index-sxwOKh3b.js → index-Cl161mdg.js} +1 -1
- package/dist/dashboard/assets/index-Dt-v3FGI.css +1 -0
- package/dist/dashboard/assets/index-mevy0vLr.js +151 -0
- package/dist/dashboard/assets/{model-provider-z76eVBRd.js → model-provider-CXm-Ru1s.js} +1 -1
- package/dist/dashboard/assets/{pricing-Bix3wcTu.js → pricing-DumQppSX.js} +1 -1
- package/dist/dashboard/assets/qwenwork-CW5htBDs.ico +0 -0
- package/dist/dashboard/assets/rank-CqwpjE6-.js +16 -0
- package/dist/dashboard/assets/{settings-BItuk443.js → settings-BHpRKDCP.js} +1 -1
- package/dist/dashboard/assets/{useLocalStorage-CqfyLuzE.js → useLocalStorage-CKd3SYzL.js} +1 -1
- package/dist/dashboard/brand-logos/command-code.svg +4 -0
- package/dist/dashboard/brand-logos/qwenwork.ico +0 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/doctor.d.ts +2 -0
- package/dist/doctor.js +91 -0
- package/dist/index.js +21 -4
- package/dist/service-linux.js +5 -3
- package/dist/service-windows.js +5 -1
- package/dist/service.js +21 -2
- package/package.json +3 -3
- package/dist/dashboard/assets/dashboard-BuoaCKAO.js +0 -55
- package/dist/dashboard/assets/download-Dxb9oVNa.js +0 -6
- package/dist/dashboard/assets/index-D3jJkpMe.css +0 -1
- package/dist/dashboard/assets/index-DLtjtn6U.js +0 -143
- package/dist/dashboard/assets/rank-wigwKGFb.js +0 -16
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{r as _,c as J,j as e,B as M,C as we,a as C,M as T,A as be,b as ge,Q as ke,e as ve,f as ye,g as je,h as ie,i as q,k as A,l as Ne,T as E,P as Y,L as Se,u as le,m as Re,n as ne,D as Z,o as Ce,S as G,d as Le,p as Ie}from"./index-mevy0vLr.js";import{g as Me,S as P,M as Ae}from"./model-provider-CXm-Ru1s.js";import{P as U,C as K,G as ee}from"./downloads-BWVeZf1b.js";import{L as Q,S as k,a as S,b as R}from"./index-Cl161mdg.js";import{C as H,T as F,L as ze,a as Te,S as V,i as Ee,u as Pe}from"./useLocalStorage-CKd3SYzL.js";const Oe=t=>_.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",width:16,height:16,fill:"none",viewBox:"0 0 16 16"},t),_.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M5.47 13.03a.75.75 0 0 1 0-1.06L9.44 8 5.47 4.03a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 0 1-1.06 0",clipRule:"evenodd"}));/**
|
|
2
|
+
* @license lucide-react v1.24.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const De=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8",key:"1h4pet"}],["path",{d:"M12 18V6",key:"zqpxq5"}]],Ue=J("circle-dollar-sign",De);/**
|
|
7
|
+
* @license lucide-react v1.24.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const Fe=[["path",{d:"M13.744 17.736a6 6 0 1 1-7.48-7.48",key:"bq4yh3"}],["path",{d:"M15 6h1v4",key:"11y1tn"}],["path",{d:"m6.134 14.768.866-.5 2 3.464",key:"17snzx"}],["circle",{cx:"16",cy:"8",r:"6",key:"14bfc9"}]],Ve=J("coins",Fe);/**
|
|
12
|
+
* @license lucide-react v1.24.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const $e=[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]],He=J("share-2",$e),Be=["today","week","month","all"];function Ge(t){return typeof t=="string"&&Be.includes(t)}const ce=[{key:"anthropic",label:"Anthropic",icon:"claude"},{key:"openai",label:"OpenAI",icon:"openai"},{key:"google",label:"Google",icon:"google"},{key:"alibaba",label:"阿里",icon:"alibaba"},{key:"moonshot",label:"Moonshot",icon:"moonshot"},{key:"doubao",label:"Doubao",icon:"doubao"},{key:"minimax",label:"MiniMax",icon:"minimax"},{key:"xai",label:"xAI",icon:"grok"},{key:"deepseek",label:"DeepSeek",icon:"deepseek"},{key:"zhipu",label:"Zhipu",icon:"zhipu"}],Ke={anthropic:"anthropic",claude:"anthropic",codex:"openai",openai:"openai",gemini:"google",google:"google",alibaba:"alibaba",qwen:"alibaba",kimi:"moonshot",moonshot:"moonshot",grok:"xai",xai:"xai",deepseek:"deepseek",zai:"zhipu",zhipu:"zhipu"},te=new Map(ce.map((t,a)=>[t.key,a]));function qe(t){const a=Ke[t.key]??t.key,s=ce.find(r=>r.key===a);return s||(a==="unknown"?{key:"other",label:"其他",icon:"unknown"}:{key:a,label:t.label,icon:t.icon})}function We(t,a){if(t.key==="other")return 1;if(a.key==="other")return-1;const s=te.get(t.key),r=te.get(a.key);return s!==void 0||r!==void 0?(s??Number.MAX_SAFE_INTEGER)-(r??Number.MAX_SAFE_INTEGER):t.label.localeCompare(a.label)}function ae(t,a=""){const s=new Map;s.set("other",{key:"other",label:"其他",icon:"unknown",models:[]});for(const o of new Set(t.filter(Boolean))){const n=Me(o),i=qe(n),c=s.get(i.key)??{...i,models:[]};c.models.push(o),s.set(i.key,c)}const r=a.trim().toLocaleLowerCase();return[...s.values()].flatMap(o=>{const n=o.label.toLocaleLowerCase().includes(r),i=r&&!n?o.models.filter(c=>`${o.label} ${c}`.toLocaleLowerCase().includes(r)):o.models;return i.length===0&&!(o.key==="other"&&(!r||n))?[]:[{...o,models:i.sort((c,f)=>c.localeCompare(f))}]}).sort(We)}function Je(t,a=""){const s=new Set,r=[];for(const o of t)a&&o.tool!==a||!o.model||s.has(o.model)||(s.add(o.model),r.push(o));return r}function de(t){return t==null||!Number.isFinite(t)||t<1?"—":String(Math.floor(t))}function z(t){return t?t.currentUser?t.currentUser:t.rows.find(a=>a.isCurrentUser)??null:null}function Qe(t,a={}){if(a.hideFromLeaderboard)return{kind:"hidden"};const s=z(t);return s?{kind:"row",row:s}:a.isSignedIn?{kind:"off_board"}:{kind:"anonymous"}}function Xe(t){return t==="off_board"?"100+名":"登录后查看"}function Ye(t,a){const s=t.map(r=>({pinned:!1,row:r}));return a?[{pinned:!0,row:a},...s]:s}const Ze="!h-8 !min-h-8";function et({models:t,onChange:a,value:s}){var x;const[r,o]=_.useState(!1),[n,i]=_.useState(""),c=_.useMemo(()=>ae(t),[t]),f=_.useMemo(()=>ae(t,n),[t,n]),h=c.find(m=>m.models.includes(s)),d=_.useMemo(()=>[...new Set(t.filter(Boolean))].sort((m,N)=>m.localeCompare(N)),[t]),[w,l]=_.useState((h==null?void 0:h.key)??"all"),u=!n&&w==="all"?"all":f.some(m=>m.key===w)?w:(x=f[0])==null?void 0:x.key,b=f.find(m=>m.key===u),g=u==="all"?d:(b==null?void 0:b.models)??[],p=h&&s?`${h.label} › ${s}`:"全部模型";_.useEffect(()=>{r&&l((h==null?void 0:h.key)??"all")},[r,h]);const v=m=>{o(m),m||i("")},L=m=>{a(m),o(!1),i("")};return e.jsxs(U,{isOpen:r,onOpenChange:v,children:[e.jsxs(M,{"aria-label":`模型筛选:${p}`,className:`${Ze} min-w-0 max-w-[7.5rem] shrink justify-between gap-1.5 px-2.5 !text-xs font-normal sm:max-w-52 sm:shrink-0 sm:px-3`,size:"sm",variant:"secondary",children:[e.jsx("span",{className:"min-w-0 truncate",children:p}),e.jsx(we,{className:"size-3.5 shrink-0 text-muted"})]}),e.jsx(U.Content,{className:"w-[min(34rem,calc(100vw-1rem))] overflow-hidden rounded-xl border-0 bg-overlay p-0 text-overlay-foreground shadow-surface",placement:"bottom start",children:e.jsxs(U.Dialog,{className:"p-0 outline-none",children:[e.jsx(U.Heading,{className:"sr-only",children:"模型筛选"}),e.jsxs(P,{className:"border-b border-border p-2",value:n,onChange:i,children:[e.jsx(Q,{className:"sr-only",children:"搜索厂商或模型"}),e.jsxs(P.Group,{className:"!h-8 !min-h-8 focus-within:!border-border focus-within:!shadow-none focus-within:!outline-none focus-within:!ring-0",children:[e.jsx(P.SearchIcon,{}),e.jsx(P.Input,{autoFocus:!0,className:"!text-xs",placeholder:"搜索厂商或模型"}),e.jsx(P.ClearButton,{})]})]}),f.length>0?e.jsxs("div",{className:"grid min-h-56 grid-cols-[minmax(7.5rem,0.8fr)_minmax(0,1.4fr)] divide-x divide-border",children:[e.jsxs("div",{"aria-label":"模型厂商",className:"max-h-72 overscroll-contain overflow-y-auto p-1.5",role:"listbox",children:[n?null:e.jsxs("button",{className:C("mb-1 flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left text-xs transition-colors hover:bg-surface-secondary",!s&&"bg-accent/10 text-foreground"),type:"button",onClick:()=>{s?L(""):l("all")},children:[e.jsx("span",{className:"flex size-4 shrink-0 items-center justify-center",children:s?null:e.jsx(K,{className:"size-3 text-accent"})}),e.jsx("span",{className:"min-w-0 flex-1 font-medium",children:"全部厂商"}),e.jsx("span",{className:"shrink-0 tabular-nums text-[10px] text-muted",children:d.length})]}),f.map(m=>{const N=m.key===u,O=m.models.includes(s);return e.jsxs("button",{"aria-selected":N,className:C("flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left text-xs transition-colors hover:bg-surface-secondary",N&&"bg-surface-secondary text-foreground"),role:"option",type:"button",onClick:()=>l(m.key),onMouseEnter:()=>l(m.key),children:[e.jsx("span",{className:"flex size-5 shrink-0 items-center justify-center rounded-md bg-white",children:e.jsx(Ae,{provider:m,size:13})}),e.jsx("span",{className:"min-w-0 flex-1 truncate font-medium",children:m.label}),e.jsx("span",{className:"shrink-0 tabular-nums text-[10px] text-muted",children:m.models.length}),O?e.jsx(K,{className:"size-3 shrink-0 text-accent"}):e.jsx(Oe,{className:"size-3 shrink-0 text-muted"})]},m.key)})]}),e.jsx("div",{"aria-label":u==="all"?"全部模型":"具体模型",className:"max-h-72 overscroll-contain overflow-y-auto p-1.5",role:"listbox",children:g.map(m=>{const N=m===s;return e.jsxs("button",{"aria-selected":N,className:C("flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-xs transition-colors hover:bg-surface-secondary",N&&"bg-accent/10 text-foreground hover:bg-accent/15"),role:"option",type:"button",onClick:()=>L(m),children:[e.jsx("span",{className:"min-w-0 flex-1 truncate",children:m}),N?e.jsx(K,{className:"size-3 shrink-0 text-accent"}):null]},m)})})]}):e.jsx("div",{className:"flex min-h-40 items-center justify-center px-6 text-center text-xs text-muted",children:"没有匹配的厂商或模型"})]})})]})}const tt="https://juejin.cn/aiusage/rank",ue=5;function at({board:t,hideFromLeaderboard:a=!1,isSignedIn:s=!1,loading:r,metric:o,modelLabel:n,onOpenChange:i,open:c,profiles:f,toolLabel:h}){const d=Qe(t,{hideFromLeaderboard:a,isSignedIn:s}),w=d.kind==="row"?d.row:null,l=d.kind==="anonymous"||d.kind==="off_board"?d.kind:null,u=_.useRef(null),[b,g]=_.useState(null),[p,v]=_.useState(null);_.useEffect(()=>{c&&(g(null),v(null))},[c]);const L=y=>b===y?y==="download"?"生成中…":"复制中…":(p==null?void 0:p.action)===y?p.state==="success"?y==="download"?"已下载":"已复制":y==="download"?"下载失败":"复制失败":y==="download"?"下载到本地":"复制分享图",x=(y,D)=>{g(null),v({action:y,state:D})},m=()=>u.current?Ne(u.current):Promise.reject(new Error("分享海报尚未准备完成")),N=async()=>{if(!(b||r)){g("download"),v(null);try{ye(await m()),x("download","success")}catch(y){console.error("[rank-share] download failed",y),x("download","error")}}},O=async()=>{if(!(b||r)){g("copy"),v(null);try{await je(m()),x("copy","success")}catch(y){console.error("[rank-share] clipboard write failed",y),x("copy","error")}}};return e.jsx(T,{children:e.jsx(T.Backdrop,{isOpen:c,onOpenChange:i,variant:"blur",children:e.jsx(T.Container,{className:"px-3 py-8 sm:px-4",scroll:"inside",size:"sm",children:e.jsx(T.Dialog,{"aria-label":"分享排行榜",className:"!w-full !max-w-[420px] !overflow-visible !border-0 !bg-transparent !p-0 !shadow-none",children:e.jsxs(T.Body,{className:"space-y-3 p-0",children:[e.jsxs("section",{"aria-label":`${o==="tokens"?"Token":"消费"} 排行榜分享预览`,className:"relative isolate overflow-hidden rounded-[22px] border border-white/85 bg-[#edf7ff] px-4 pb-4 pt-5 text-[#18283a] shadow-[0_18px_36px_rgb(56_121_188_/0.18)] dark:border-white/10 dark:bg-[#0d1b2d] dark:text-[#eaf4ff] dark:shadow-[0_18px_36px_rgb(0_0_0_/0.38)] sm:px-5 sm:pb-5 sm:pt-6",ref:u,children:[e.jsx(nt,{}),e.jsxs("div",{className:"relative z-10",children:[e.jsxs("header",{className:"flex items-start justify-between gap-3",children:[e.jsxs("h2",{className:"inline-flex whitespace-nowrap pt-0.5 text-[28px] font-black italic leading-none tracking-[-0.055em] text-[#14243a] dark:text-[#f1f8ff] sm:text-[32px]",children:[e.jsx("span",{children:"Token"}),e.jsx("span",{className:"ml-2",children:"排行榜"})]}),e.jsx("div",{"aria-label":"排行榜指标",className:"-mr-1.5 -mt-1 shrink-0",children:e.jsx(lt,{children:o==="tokens"?"按 Token":"按消费"})})]}),e.jsxs("section",{className:"mt-5","aria-label":"排行榜",children:[e.jsxs("div",{className:"flex flex-wrap gap-1.5 text-[10px] font-medium text-[#5c7d9c] dark:text-[#a8c1da]",children:[e.jsx("span",{className:"max-w-32 truncate rounded-full border border-white/80 bg-white/[0.5] px-2 py-1 shadow-[inset_0_1px_0_rgb(255_255_255_/0.9)] backdrop-blur-sm dark:border-white/10 dark:bg-white/[0.08] dark:shadow-none",children:h}),e.jsx("span",{className:"max-w-44 truncate rounded-full border border-white/80 bg-white/[0.5] px-2 py-1 shadow-[inset_0_1px_0_rgb(255_255_255_/0.9)] backdrop-blur-sm dark:border-white/10 dark:bg-white/[0.08] dark:shadow-none",children:n})]}),r?e.jsx(rt,{}):e.jsx(st,{currentUser:w,fallbackKind:l,profiles:f,rows:(t==null?void 0:t.rows)??[]})]}),e.jsx(it,{})]})]}),e.jsxs("div",{className:"flex items-center justify-center gap-2 pb-1",children:[e.jsxs(M,{isDisabled:r||b==="copy",isPending:b==="download",onPress:()=>void N(),size:"sm",children:[e.jsx(be,{className:"size-3.5"}),L("download")]}),e.jsxs(M,{isDisabled:r||b==="download",isPending:b==="copy",onPress:()=>void O(),size:"sm",variant:"tertiary",children:[e.jsx(ge,{className:"size-3.5"}),L("copy")]}),e.jsx(M,{size:"sm",slot:"close",variant:"tertiary",children:"关闭"})]})]})})})})})}function st({currentUser:t,fallbackKind:a,profiles:s,rows:r}){const o=r.slice(0,ue),n=t?o.some(i=>oe(i,t)):!1;return e.jsxs("div",{className:"mt-5","aria-label":"排行榜列表",children:[o.length>0?e.jsx("ol",{className:"space-y-1.5",children:o.map(i=>e.jsx(se,{isCurrentUser:!!(t&&oe(i,t)),profiles:s,row:i},`${i.userHash}-${i.rank}`))}):e.jsx("p",{className:"mt-3 px-2 text-[11px] text-[#7892ac] dark:text-[#9bb7d2]",children:"暂无排行榜数据"}),t&&!n?e.jsxs(e.Fragment,{children:[o.length>0&&e.jsx("div",{"aria-hidden":!0,className:"py-2 text-center text-sm font-black tracking-[0.3em] text-[#7892ac] dark:text-[#9bb7d2]",children:"· · ·"}),e.jsx("ol",{className:"my-1.5 py-1.5",children:e.jsx(se,{isCurrentUser:!0,profiles:s,row:t})})]}):null,a&&e.jsxs("div",{className:"mt-4 flex items-center justify-between rounded-xl border border-dashed border-[#b9d8ff] bg-white/[0.32] px-3 py-2.5 text-[11px] dark:border-white/15 dark:bg-white/[0.05]",children:[e.jsx("span",{className:"font-semibold text-[#5c7d9c] dark:text-[#a8c1da]",children:"我的排名"}),e.jsx("span",{className:"font-bold text-[#334e69] dark:text-[#f1f8ff]",children:Xe(a)})]})]})}function se({isCurrentUser:t,profiles:a,row:s}){const r=ct(s,a),o=ie(s.totalTokens??s.tokens),n=q(s.costUsd),i=de(s.rank);return e.jsxs("li",{className:t?"relative mx-5 my-4 origin-center scale-110 py-1.5":"relative","data-current-user":t?"true":void 0,children:[t&&e.jsxs("p",{className:"mb-3 text-[10px] font-semibold tracking-[0.04em] text-[#1e80ff] dark:text-[#79b7ff]",children:["@",r.displayName," · 排名"]}),e.jsxs("div",{className:`grid grid-cols-[2.75rem_minmax(0,1fr)_auto] items-center gap-1 rounded-xl px-2 py-2.5 ${t?"border border-[#8ec0ff]/80 bg-[#dcedff]/90 shadow-[0_8px_18px_rgb(30_128_255_/0.16),inset_0_1px_0_rgb(255_255_255_/0.9)] dark:border-[#4b91d1] dark:bg-[#173b5f]/90 dark:shadow-[0_8px_18px_rgb(0_0_0_/0.25)]":"border border-white/55 bg-white/[0.38] shadow-[inset_0_1px_0_rgb(255_255_255_/0.72)] dark:border-white/[0.07] dark:bg-white/[0.045] dark:shadow-none"}`,children:[e.jsx("span",{className:`min-w-0 text-center font-black leading-none tabular-nums ${t?"text-[#1e80ff] dark:text-[#79b7ff]":ot(s.rank)} ${i==="—"||i.length>=3?"text-[12px]":"text-[17px]"}`,children:i==="—"?"未上榜":`#${i}`}),e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsxs(A,{className:"size-7 shrink-0 border border-white/80 shadow-sm dark:border-white/15",size:"sm",children:[r.avatarUrl?e.jsx(A.Image,{alt:"",loading:"eager",src:r.avatarUrl}):null,e.jsx(A.Fallback,{color:"accent",delayMs:0,children:r.displayName.slice(0,1).toUpperCase()||"J"})]}),e.jsx("span",{className:"min-w-0 truncate text-[12px] font-semibold text-[#294560] dark:text-[#dceeff]",children:r.displayName})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-3 text-right text-[10px] font-bold tabular-nums",children:[e.jsxs("span",{className:"inline-flex w-auto shrink-0 items-center gap-1 whitespace-nowrap rounded-full border border-[#b9d8ff]/85 bg-[#e4f1ff]/80 px-2 py-1 text-[#1e80ff] shadow-[inset_0_1px_0_rgb(255_255_255_/0.82)] dark:border-[#356796] dark:bg-[#193755]/80 dark:text-[#79b7ff] dark:shadow-none",title:`Token:${o}`,children:[e.jsx(Ve,{"aria-hidden":!0,className:"size-3 shrink-0"}),e.jsx("span",{children:o})]}),e.jsxs("span",{className:"inline-flex w-auto shrink-0 items-center gap-1 whitespace-nowrap rounded-full border border-[#a8d9ba]/85 bg-[#e6f8ec]/80 px-2 py-1 text-[#22a05a] shadow-[inset_0_1px_0_rgb(255_255_255_/0.82)] dark:border-[#377b55] dark:bg-[#153d29]/80 dark:text-[#63d98a] dark:shadow-none",title:`消费:${n}`,children:[e.jsx(Ue,{"aria-hidden":!0,className:"size-3 shrink-0"}),e.jsx("span",{children:n})]})]})]})]})}function oe(t,a){return t.userHash===a.userHash||!!t.uid&&t.uid===a.uid||t.isCurrentUser&&a.isCurrentUser}function ot(t){return t===1?"text-[#f26b42] dark:text-[#ff9b74]":t===2?"text-[#e39a3a] dark:text-[#ffc36b]":t===3?"text-[#8f79d8] dark:text-[#b9a7ff]":"text-[#5c7d9c] dark:text-[#a8c1da]"}function rt(){return e.jsxs("div",{className:"mt-5","aria-label":"排行榜加载中",children:[e.jsx("div",{className:"space-y-1.5",children:Array.from({length:ue},(t,a)=>e.jsxs("div",{className:"grid grid-cols-[2.75rem_minmax(0,1fr)_auto] items-center gap-1 rounded-xl border border-white/55 bg-white/[0.38] px-2 py-2.5 dark:border-white/[0.07] dark:bg-white/[0.045]",children:[e.jsx(k,{className:"mx-auto h-5 w-7 rounded"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{className:"size-7 rounded-full"}),e.jsx(k,{className:"h-3 w-24 rounded"})]}),e.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[e.jsx(k,{className:"h-6 w-16 rounded-full"}),e.jsx(k,{className:"h-6 w-14 rounded-full"})]})]},a))}),e.jsxs("div",{className:"my-4 py-1.5",children:[e.jsx(k,{className:"mb-1.5 ml-3 h-3 w-24 rounded"}),e.jsx(k,{className:"h-11 w-full rounded-xl"})]})]})}function it(){return e.jsxs("footer",{className:"mt-8 flex items-center justify-between gap-3 rounded-2xl border border-white/75 bg-white/[0.52] px-3 py-2.5 shadow-[inset_0_1px_0_rgb(255_255_255_/0.9)] backdrop-blur-sm dark:border-white/10 dark:bg-white/[0.06] dark:shadow-none",children:[e.jsxs("div",{className:"min-w-0 pl-1",children:[e.jsx("p",{className:"text-[13px] font-semibold text-[#385775] dark:text-[#d6e8fa]",children:"扫码查看排行榜"}),e.jsx("p",{className:"mt-1 truncate text-[11px] text-[#7892ac] dark:text-[#9bb7d2]",children:"Juejin Usage · Token 排行榜"})]}),e.jsx(ke,{bgColor:"#ffffff",className:"size-[58px] shrink-0 rounded-lg bg-white p-1 shadow-sm",fgColor:"#14243a",imageSettings:{excavate:!0,height:12,src:ve,width:12},level:"H",marginSize:1,size:58,title:"扫码查看 Juejin Usage 排行榜",value:tt})]})}function lt({children:t}){return e.jsx(H,{className:"h-6 min-h-6 border border-[#b9d8ff] bg-[#e4f1ff]/90 px-2.5 text-[#1e80ff] shadow-[inset_0_1px_0_rgb(255_255_255_/0.9),0_2px_8px_rgb(56_121_188_/0.08)] backdrop-blur-md dark:border-[#356796] dark:bg-[#193755]/90 dark:text-[#79b7ff] dark:shadow-none",size:"sm",variant:"secondary",children:e.jsx(H.Label,{className:"text-[10px] font-semibold leading-none",children:t})})}function nt(){return e.jsxs("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 overflow-hidden",children:[e.jsx("div",{className:"absolute -right-16 -top-20 size-72 rounded-full bg-[#cfe8ff]/75 blur-3xl dark:bg-[#1e80ff]/20"}),e.jsx("div",{className:"absolute right-12 top-5 size-24 rounded-full bg-white/70 blur-2xl dark:bg-[#4b9cff]/15"}),e.jsx("div",{className:"absolute -left-12 bottom-24 size-40 rounded-full bg-[#dbeeff]/80 blur-3xl dark:bg-[#347ff0]/15"}),e.jsx("span",{className:"absolute right-9 top-12 size-2.5 rounded-full bg-[#7eb6ff]/75"}),e.jsx("span",{className:"absolute right-28 top-20 size-1.5 rounded-full bg-[#5aa2ff]/60"}),e.jsx("span",{className:"absolute right-5 top-40 size-2 rounded-full border-2 border-[#8ec0ff]/80"}),e.jsxs("svg",{className:"absolute -right-1 top-9 h-32 w-24 rotate-[16deg] opacity-60 dark:opacity-15",fill:"none",viewBox:"0 0 112 148",children:[e.jsx("rect",{fill:"#f5f9ff",height:"132",rx:"14",stroke:"#c5dcff",strokeWidth:"2",width:"96",x:"8",y:"8"}),e.jsx("path",{d:"M28 40H84M28 56H72M28 72H78M28 88H64",stroke:"#c5dcff",strokeLinecap:"round",strokeWidth:"6"})]}),e.jsxs("svg",{className:"absolute right-6 top-20 h-36 w-28 rotate-[7deg] opacity-70 drop-shadow-[0_10px_18px_rgb(30_128_255_/0.12)] dark:opacity-25",fill:"none",viewBox:"0 0 128 168",children:[e.jsx("rect",{fill:"#eef6ff",height:"148",rx:"16",stroke:"#7eb6ff",strokeWidth:"2.5",width:"108",x:"10",y:"10"}),e.jsx("path",{d:"M34 46H94M34 66H82M34 86H88M34 106H70",stroke:"#8ec0ff",strokeLinecap:"round",strokeWidth:"7"})]}),e.jsxs("svg",{className:"absolute -bottom-4 -right-2 size-20 rotate-[14deg] opacity-65 dark:opacity-25",fill:"none",viewBox:"0 0 64 64",children:[e.jsx("path",{d:"M20 14h24v12c0 8-5.5 14-12 14s-12-6-12-14V14z",fill:"#e8f3ff",stroke:"#7eb6ff",strokeLinejoin:"round",strokeWidth:"2"}),e.jsx("path",{d:"M20 18H14c0 8 4 12 8 13M44 18h6c0 8-4 12-8 13",stroke:"#5aa2ff",strokeLinecap:"round",strokeWidth:"2"}),e.jsx("path",{d:"M28 40v6h8v-6M24 50h16",stroke:"#8ec0ff",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2.5"}),e.jsx("circle",{cx:"32",cy:"24",fill:"#1e80ff",r:"3"})]})]})}function ct(t,a){const s=t,r=s.uid??t.userHash,o=a[r];return{avatarUrl:(o==null?void 0:o.avatarUrl)??s.avatarUrl??null,displayName:(o==null?void 0:o.userName)??t.displayName}}const re=[{id:"today",label:"今天"},{id:"week",label:"本周"},{id:"month",label:"本月"},{id:"all",label:"全部"}],me="!h-8 !min-h-8",_e="w-50 !max-h-64 overflow-hidden rounded-xl bg-surface shadow-md",fe="!max-h-64 overflow-y-auto!";function dt(){const t=window.open(ee,"_blank");if(t){t.opener=null;return}window.location.assign(ee)}function ut({hideFromLeaderboard:t=!1,isSignedIn:a=!1,loading:s,metric:r,model:o,modelOptions:n,onModelChange:i,onToolChange:c,profiles:f,board:h,tool:d,tools:w,value:l,onChange:u}){var L;const[b,g]=_.useState(!1),p=((L=w.find(x=>x.key===d))==null?void 0:L.displayName)??"全部工具",v=o||"全部模型";return e.jsxs("div",{"aria-label":"排行榜筛选",className:"mb-4 flex w-full min-w-0 items-center gap-1.5 sm:gap-2",children:[e.jsx("div",{className:"shrink-0 sm:hidden",children:e.jsx(_t,{ariaLabel:"时间范围",options:re.map(x=>({id:x.id,label:x.label})),placeholder:"时间范围",value:l,onChange:x=>u(x),allowEmpty:!1})}),e.jsx(E,{className:"hidden w-fit shrink-0 text-center sm:block",selectedKey:l,onSelectionChange:x=>u(String(x)),children:e.jsx(E.ListContainer,{children:e.jsx(E.List,{"aria-label":"时间范围",className:"w-fit *:h-6 *:w-fit *:px-3 *:text-sm *:font-normal *:data-[selected=true]:text-accent-foreground",children:re.map(x=>e.jsxs(E.Tab,{id:x.id,children:[e.jsx("span",{className:"text-xs font-normal",children:x.label}),e.jsx(E.Indicator,{className:"bg-accent"})]},x.id))})})}),e.jsx(mt,{tools:w,value:d,onChange:c}),e.jsx(et,{models:n.map(x=>x.model),value:o,onChange:i}),e.jsxs("div",{className:"ml-auto flex shrink-0 items-center gap-1",children:[e.jsxs(F,{closeDelay:80,delay:100,children:[e.jsx(M,{"aria-label":"GitHub 仓库",className:"size-8 min-h-8 min-w-8 shrink-0 p-0",isIconOnly:!0,onPress:dt,size:"sm",variant:"tertiary",children:e.jsx(ze,{className:"size-4"})}),e.jsx(F.Content,{placement:"bottom",children:e.jsx("p",{children:"GitHub 仓库"})})]}),e.jsxs(F,{closeDelay:80,delay:100,children:[e.jsx(M,{"aria-label":"分享排行榜",className:"size-8 min-h-8 min-w-8 shrink-0 p-0",isIconOnly:!0,onPress:()=>g(!0),size:"sm",variant:"tertiary",children:e.jsx(He,{className:"size-4"})}),e.jsx(F.Content,{placement:"bottom",children:e.jsx("p",{children:"分享"})})]}),e.jsx(Te,{})]}),e.jsx(at,{board:h,hideFromLeaderboard:t,isSignedIn:a,loading:s,metric:r,modelLabel:v,onOpenChange:g,open:b,profiles:f,toolLabel:p})]})}function mt({onChange:t,tools:a,value:s}){const r=a.find(o=>o.key===s);return e.jsxs(S,{"aria-label":"工具筛选",className:"min-w-0 max-w-[7.5rem] shrink text-xs sm:max-w-52 sm:shrink-0",variant:"secondary",value:s||"all",onChange:o=>t(o==="all"||o==null?"":String(o)),children:[e.jsx(Q,{className:"sr-only",children:"工具筛选"}),e.jsxs(S.Trigger,{className:`${me} !w-fit max-w-[7.5rem] items-center leading-none ps-2.5 pe-7 !text-xs font-normal sm:max-w-52 sm:ps-3 sm:pe-8`,children:[e.jsx(S.Value,{className:"min-w-0 max-w-20 !text-xs sm:max-w-40",children:()=>r?e.jsxs("span",{className:"flex min-w-0 items-center gap-1.5",children:[e.jsx(Y,{provider:r.key,size:14}),e.jsx("span",{className:"truncate",children:r.displayName})]}):"全部工具"}),e.jsx(S.Indicator,{className:"size-3.5 text-muted"})]}),e.jsx(S.Popover,{className:_e,placement:"bottom start",children:e.jsxs(R,{"aria-label":"工具筛选",className:fe,children:[e.jsxs(R.Item,{id:"all",textValue:"全部工具",children:["全部工具",e.jsx(R.ItemIndicator,{})]}),a.map(o=>e.jsxs(R.Item,{className:"gap-2! rounded-lg px-1.5 py-1 text-xs",id:o.key,textValue:o.displayName,children:[e.jsx("span",{className:"flex size-5 shrink-0 items-center justify-center",children:e.jsx(Y,{provider:o.key,size:14})}),e.jsx("span",{className:"min-w-0 flex-1 truncate",children:o.displayName}),e.jsx(R.ItemIndicator,{})]},o.key))]})})]})}function _t({allowEmpty:t=!0,ariaLabel:a,onChange:s,options:r,placeholder:o,value:n}){return e.jsxs(S,{"aria-label":a,className:"min-w-0 max-w-[7.5rem] shrink text-xs sm:max-w-52 sm:shrink-0",variant:"secondary",value:t?n||"all":n,onChange:i=>{if(t){s(i==="all"||i==null?"":String(i));return}i!=null&&s(String(i))},children:[e.jsx(Q,{className:"sr-only",children:a}),e.jsxs(S.Trigger,{className:`${me} !w-fit max-w-[7.5rem] items-center leading-none ps-2.5 pe-7 !text-xs font-normal sm:max-w-52 sm:ps-3 sm:pe-8`,children:[e.jsx(S.Value,{className:"min-w-0 max-w-20 !text-xs sm:max-w-40"}),e.jsx(S.Indicator,{className:"size-3.5 text-muted"})]}),e.jsx(S.Popover,{className:_e,placement:"bottom start",children:e.jsxs(R,{"aria-label":a,className:fe,children:[t?e.jsxs(R.Item,{id:"all",textValue:o,children:[o,e.jsx(R.ItemIndicator,{})]}):null,r.map(i=>e.jsxs(R.Item,{id:i.id,textValue:i.label,children:[i.label,e.jsx(R.ItemIndicator,{})]},i.id))]})})]})}const ft="inline-flex h-8 max-w-full items-center rounded-full border border-white/70 bg-white/55 p-0.5 shadow-[0_1px_2px_rgb(15_60_120_/0.06)] backdrop-blur-md dark:border-white/10 dark:bg-white/[0.08] dark:shadow-none";function ht({cost:t,hideFromLeaderboard:a=!1,loading:s,metric:r,onMetricChange:o,tokens:n}){var c,f;const i=[{id:"tokens",label:"按 Token",rank:(c=z(n))==null?void 0:c.rank},{id:"cost",label:"按消费",rank:(f=z(t))==null?void 0:f.rank}];return e.jsx("div",{"aria-label":"排行指标",className:ft,role:"tablist",children:i.map(({id:h,label:d,rank:w})=>{const l=r===h,u=a||s?null:pt(w);return e.jsxs("button",{"aria-label":u?`${d} ${u}`:d,"aria-selected":l,className:C("inline-flex h-full items-center gap-1 rounded-full px-2 text-xs font-medium transition-colors sm:px-2.5",l?"bg-white text-[#1e80ff] shadow-xs dark:bg-white/15 dark:text-[#4b9cff]":"text-muted hover:text-foreground dark:text-foreground/55 dark:hover:text-foreground/85"),onClick:()=>o(h),role:"tab",type:"button",children:[e.jsx("span",{children:d}),a?null:s?e.jsx(k,{"aria-label":`${d}排名加载中`,className:"h-3 w-6 rounded-sm"}):u?e.jsx("span",{className:"tabular-nums opacity-80",children:u}):null]},h)})})}function pt(t){const a=de(t);return a==="—"?null:`#${a}`}function xt({aside:t,children:a}){const s=Math.max(0,a.length-2),r=a.slice(0,s),o=a.slice(s,s+1),n=a.slice(s+1);return e.jsxs("span",{className:"inline-flex flex-wrap items-center gap-2.5 sm:gap-3",children:[e.jsxs("span",{className:"relative inline-flex items-baseline leading-none",children:[r,e.jsxs("span",{className:"relative inline-block",children:[o,e.jsx("svg",{"aria-hidden":!0,className:"pointer-events-none absolute left-1/2 top-[calc(100%-1px)] h-2.5 w-7 -translate-x-1/2 text-[#1e80ff] sm:h-3 sm:w-9 dark:text-[#4b9cff]",fill:"none",viewBox:"0 0 36 12",children:e.jsx("path",{d:"M2 7.5C8 3.5 13 2.5 18 5C23 7.5 28 8.5 34 4.5",stroke:"currentColor",strokeLinecap:"round",strokeWidth:"2.8"})})]}),n]}),t]})}const W="rounded-2xl border border-white/60 bg-white/90 shadow-[0_8px_30px_rgb(15_60_120_/0.06)] dark:border-white/8 dark:bg-surface dark:shadow-[0_8px_30px_rgb(0_0_0_/0.35)]",wt="240px 0px";function bt({global:t,hideFromLeaderboard:a=!1,hideToggleDisabled:s=!1,loading:r,metric:o,onHideFromLeaderboardChange:n,onMetricChange:i,profiles:c,refreshing:f=!1,showHideToggle:h=!1}){const d=(t==null?void 0:t[o])??null;return e.jsxs("section",{"aria-labelledby":"rank-users-title",className:"space-y-3 sm:space-y-4",children:[e.jsxs("div",{className:"flex w-full min-w-0 flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-3",children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight sm:text-3xl",id:"rank-users-title",children:e.jsx(xt,{children:"用户排行榜"})}),e.jsx(ht,{cost:(t==null?void 0:t.cost)??null,hideFromLeaderboard:a,loading:r,metric:o,onMetricChange:i,tokens:(t==null?void 0:t.tokens)??null})]}),h?e.jsx(V,{className:"shrink-0 self-start sm:self-center",isDisabled:s,isSelected:a,size:"sm",onChange:w=>n==null?void 0:n(w),children:e.jsxs(V.Content,{className:"gap-1.5 text-xs font-normal text-muted",children:[e.jsx(V.Control,{children:e.jsx(V.Thumb,{})}),"隐藏自己"]})}):null]}),r&&d==null?e.jsx(jt,{}):e.jsx("div",{className:C("transition-opacity duration-150",f&&"pointer-events-none opacity-60"),children:e.jsx(gt,{board:d,hideFromLeaderboard:a,profiles:c})})]})}function gt({board:t,hideFromLeaderboard:a,profiles:s}){const r=(t==null?void 0:t.rows)??[],o=a?null:z(t),n=Ye(r,o);return r.length===0&&!o?e.jsxs("div",{className:C(W,"flex min-h-56 flex-col items-center justify-center gap-2 overflow-hidden text-center"),children:[e.jsx("p",{className:"text-sm",children:"当前范围暂无用户排行数据"}),e.jsx("p",{className:"text-xs text-muted",children:"产生用量后再回来看看"})]}):e.jsxs("div",{className:C(W,"min-w-0"),children:[e.jsxs("div",{"aria-hidden":!0,className:"flex items-center gap-2 px-4 py-2.5 text-[11px] text-muted sm:gap-5 sm:px-6 sm:py-3 sm:text-xs",children:[e.jsx("span",{className:"w-10 shrink-0 sm:w-12"}),e.jsx("span",{className:"min-w-0 flex-1",children:"用户"}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2 sm:gap-8",children:[e.jsx("span",{className:"w-[3.25rem] text-right sm:w-24",children:"总 Token"}),e.jsx("span",{className:"w-[3.25rem] text-right sm:w-20",children:"总费用"})]})]}),e.jsx("ol",{className:"min-w-0",children:n.map(({pinned:i,row:c})=>{const f=c,h=f.uid??c.userHash,d=s[h],w=(d==null?void 0:d.userName)??c.displayName,l=(d==null?void 0:d.avatarUrl)??f.avatarUrl,u=(d==null?void 0:d.profileUrl)??`https://juejin.cn/user/${encodeURIComponent(h)}`,b=f.totalTokens??c.tokens;return e.jsx("li",{className:C("min-w-0 transition-colors",i?"sticky top-0 z-10 border-b border-[#1e80ff]/15 bg-[#eef6ff] shadow-[0_8px_16px_rgb(15_60_120_/0.06)] hover:bg-[#e4f1ff] dark:border-[#4b9cff]/20 dark:bg-[#16324f] dark:shadow-[0_8px_16px_rgb(0_0_0_/0.25)] dark:hover:bg-[#1a3d5c]":"hover:bg-black/[0.02] dark:hover:bg-white/[0.04] [content-visibility:auto] [contain-intrinsic-size:auto_56px]"),children:e.jsxs("div",{className:"flex min-w-0 items-center gap-2 px-4 py-3 sm:gap-5 sm:px-6 sm:py-4",children:[e.jsx(vt,{rank:c.rank}),e.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2 sm:gap-2.5",children:[e.jsx(kt,{fallback:w.slice(0,1),src:l}),e.jsx("a",{className:"min-w-0 truncate text-sm font-semibold text-foreground underline-offset-2 hover:underline sm:text-[15px]",href:u,rel:"noreferrer",target:"_blank",title:w,children:w}),c.isCurrentUser&&e.jsx(H,{className:"shrink-0",color:"success",size:"sm",variant:"soft",children:e.jsx(H.Label,{children:"我"})})]}),e.jsx(yt,{costUsd:c.costUsd,tokens:b})]})},i?`pinned-${c.userHash}`:c.userHash)})})]})}function kt({fallback:t,src:a}){const s=_.useRef(null),[r,o]=_.useState(!a);return _.useEffect(()=>{if(!a){o(!0);return}const n=s.current;if(!n)return;if(typeof IntersectionObserver>"u"){o(!0);return}const i=new IntersectionObserver(c=>{c.some(f=>f.isIntersecting)&&(o(!0),i.disconnect())},{rootMargin:wt,threshold:.01});return i.observe(n),()=>i.disconnect()},[a]),e.jsx("span",{className:"inline-flex shrink-0",ref:s,children:e.jsxs(A,{className:"size-7 sm:size-8",size:"sm",children:[r&&a?e.jsx(A.Image,{alt:"",decoding:"async",loading:"lazy",src:a}):null,e.jsx(A.Fallback,{children:t})]})})}function vt({rank:t}){return e.jsx("span",{"aria-label":`第 ${t} 名`,className:C("w-10 shrink-0 text-center font-bold tabular-nums leading-none sm:w-12",t>99?"text-base sm:text-lg":"text-xl sm:text-2xl",t===1&&"text-[#F53F3F] dark:text-[#ff6b6b]",t===2&&"text-[#F77234] dark:text-[#ff9a5c]",t===3&&"text-[#FF7D00] dark:text-[#ffb020]",t>3&&"text-foreground/55 dark:text-foreground/45"),children:t})}function yt({costUsd:t,tokens:a}){return e.jsxs("div",{className:"flex shrink-0 items-center gap-2 sm:gap-8",children:[e.jsx("span",{className:"w-[3.25rem] truncate text-right text-xs font-medium tabular-nums text-foreground sm:w-24 sm:text-sm",title:`${a.toLocaleString("zh-CN")} Token`,children:ie(a)}),e.jsx("span",{className:"w-[3.25rem] truncate text-right text-xs font-medium tabular-nums text-foreground sm:w-20 sm:text-sm",title:q(t),children:q(t)})]})}function jt(){return e.jsxs("div",{"aria-label":"用户排行榜加载中",className:C(W,"min-w-0 overflow-hidden"),children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2.5 sm:gap-5 sm:px-6 sm:py-3",children:[e.jsx("span",{className:"w-10 shrink-0 sm:w-12"}),e.jsx(k,{className:"h-3 w-8 rounded-md"}),e.jsxs("div",{className:"ml-auto flex shrink-0 items-center gap-2 sm:gap-8",children:[e.jsx(k,{className:"h-3 w-12 rounded-md sm:w-16"}),e.jsx(k,{className:"h-3 w-12 rounded-md sm:w-14"})]})]}),Array.from({length:7},(t,a)=>e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 sm:gap-5 sm:px-6 sm:py-4",children:[e.jsx(k,{className:"h-6 w-10 shrink-0 rounded-md sm:h-7 sm:w-12"}),e.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2 sm:gap-2.5",children:[e.jsx(k,{className:"size-7 shrink-0 rounded-full sm:size-8"}),e.jsx(k,{className:"h-4 w-24 max-w-full rounded-md sm:w-36"})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2 sm:gap-8",children:[e.jsx(k,{className:"h-3.5 w-12 rounded-md sm:h-4 sm:w-20"}),e.jsx(k,{className:"h-3.5 w-12 rounded-md sm:h-4 sm:w-16"})]})]},a))]})}const Nt=JSON.parse('[{"content":{"content_id":"7668309258707386378","item_type":2,"format":"","author_id":"1468603264447661","title":"我的AI工作流整理【个人向】","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640642101116936","7337236878996799522"]},"content_counter":{"view":1255,"like":20,"collect":20,"hot_rank":801,"comment_count":8,"interact_count":28},"author":{"user_id":"1468603264447661","name":"昭阳","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/be57be505955ef23e4ad41465db23038~300x300.image","is_followed":false},"author_counter":{"level":3,"power":502,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668540866239529010","item_type":2,"format":"","author_id":"3271760779459694","title":"DeepSeek V4-Flash 更新:代码与 Agent 能力全面增强","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640408797167623","7467857238493757466"]},"content_counter":{"view":1060,"like":10,"collect":1,"hot_rank":558,"comment_count":0,"interact_count":10},"author":{"user_id":"3271760779459694","name":"勇宝趣学前端","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/5a2596246a214e4bff4a4ceff6213c54~300x300.image","is_followed":false},"author_counter":{"level":4,"power":3937,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667863898348126271","item_type":2,"format":"","author_id":"817692379985752","title":"KotlinLLM 开源 ,一个可以在运行时自己生成永久 Kotlin 代码的 Agent 库","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809640407484334093","6809640400832167949","6809640642101116936"]},"content_counter":{"view":936,"like":13,"collect":9,"hot_rank":549,"comment_count":2,"interact_count":15},"author":{"user_id":"817692379985752","name":"恋猫de小郭","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/f4117a39915ab646a21a190e1fc5795d~300x300.image","is_followed":false},"author_counter":{"level":8,"power":162020,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668191994554073142","item_type":2,"format":"","author_id":"817692379985752","title":"Flutter Starling : 用 Swift和 Flutter 写了一个 Linux 桌面系统,震惊我一整年","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809640407484334093","6809641090145058824","6809640400832167949"]},"content_counter":{"view":789,"like":16,"collect":8,"hot_rank":522,"comment_count":3,"interact_count":19},"author":{"user_id":"817692379985752","name":"恋猫de小郭","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/f4117a39915ab646a21a190e1fc5795d~300x300.image","is_followed":false},"author_counter":{"level":8,"power":162020,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668634785267695625","item_type":2,"format":"","author_id":"2101921964109880","title":"DeepSeek-V4-Flash 正式版来了!这次提升有点夸张。","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640408797167623","6809640482725953550","6809640642101116936"]},"content_counter":{"view":795,"like":10,"collect":3,"hot_rank":441,"comment_count":0,"interact_count":10},"author":{"user_id":"2101921964109880","name":"cxuanAI","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/5920859b1d1dd54b8e09b7a55c956f0b~300x300.image","is_followed":false},"author_counter":{"level":6,"power":66857,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668305038255521838","item_type":2,"format":"","author_id":"465848661970824","title":"Spring之父再次出山,开发了新的AI框架!","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623"]},"content_counter":{"view":725,"like":8,"collect":16,"hot_rank":387,"comment_count":0,"interact_count":8},"author":{"user_id":"465848661970824","name":"苏三说技术","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/dc678f02170ae25eb82989d0f7715e1f~300x300.image","is_followed":false},"author_counter":{"level":7,"power":77230,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667895598095826970","item_type":2,"format":"","author_id":"1046390797768519","title":"别再只用 Loading、Success、Error 表示所有页面状态了","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809640615584727053","6809640400832167949"]},"content_counter":{"view":574,"like":5,"collect":13,"hot_rank":315,"comment_count":2,"interact_count":7},"author":{"user_id":"1046390797768519","name":"RockByte","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/dc915432f9ea15229a7cbaeb90b832a9~300x300.image","is_followed":false},"author_counter":{"level":5,"power":11195,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668535450420019236","item_type":2,"format":"","author_id":"1239904848718135","title":"我用AI写了半年代码——回头看,这5个能力正在退化","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","7467857238494019610","6809640398105870343"]},"content_counter":{"view":497,"like":4,"collect":3,"hot_rank":279,"comment_count":3,"interact_count":7},"author":{"user_id":"1239904848718135","name":"kyriewen","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/dc010ce441d17f8236be40eb2d03ef25~300x300.image","is_followed":false},"author_counter":{"level":5,"power":8065,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668341210563870720","item_type":2,"format":"","author_id":"3109843365802925","title":"公司取消前端岗后,做了 10 年 Java 的我,第一次认真拥抱 AI","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637771511070734","tag_ids":["6809640408797167623","6809640407484334093","6809641073527226376"]},"content_counter":{"view":572,"like":1,"collect":3,"hot_rank":270,"comment_count":1,"interact_count":2},"author":{"user_id":"3109843365802925","name":"天天摸鱼的java工程师","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/154899ea78d48ae7f7b6f942da934035~300x300.image","is_followed":false},"author_counter":{"level":5,"power":20605,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668490153107783732","item_type":2,"format":"","author_id":"1747564987417529","title":"DeepSeek-V4-Flash 接入 Codex(Windows 版)","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637776263217160","tag_ids":["6809640419505209358"]},"content_counter":{"view":516,"like":0,"collect":1,"hot_rank":234,"comment_count":1,"interact_count":1},"author":{"user_id":"1747564987417529","name":"iMountTai","avatar":"https://p6-passport.byteacctimg.com/img/mosaic-legacy/3793/3131589739~300x300.image","is_followed":false},"author_counter":{"level":1,"power":36,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668608790367682595","item_type":2,"format":"","author_id":"3280598428302727","title":"DeepSeek V4-Flash 正式版深度解读:一行 changelog 里的暗涌与野心","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640642101116936","7257794499869573175"]},"content_counter":{"view":422,"like":4,"collect":1,"hot_rank":216,"comment_count":0,"interact_count":4},"author":{"user_id":"3280598428302727","name":"土豆1250","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/d885d8cedee72a3f762988d43f4e6cf9~300x300.image","is_followed":false},"author_counter":{"level":4,"power":3230,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667863898349289535","item_type":2,"format":"","author_id":"131597124767479","title":"用户埋点怎么设计","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637776263217160","tag_ids":["6809640408797167623"]},"content_counter":{"view":340,"like":6,"collect":8,"hot_rank":207,"comment_count":0,"interact_count":6},"author":{"user_id":"131597124767479","name":"Harries","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/a4c138f466be404ddcc48d60e50672d7~300x300.image","is_followed":false},"author_counter":{"level":6,"power":33562,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668204673984675850","item_type":2,"format":"","author_id":"3193422001474199","title":"从零开发一个 Coding Agent(四):使用状态机校验大模型事件流","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640408797167623","6809640642101116936"]},"content_counter":{"view":398,"like":3,"collect":6,"hot_rank":198,"comment_count":0,"interact_count":3},"author":{"user_id":"3193422001474199","name":"东方小月","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/2361b8d5a0de5981a126064173e399d6~300x300.image","is_followed":false},"author_counter":{"level":5,"power":23223,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668532403132301362","item_type":2,"format":"","author_id":"1081575170131006","title":"全栈工程师必会技术栈:从入门到架构的完整成长地图 🗺️","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640408797167623","6809640458684203021"]},"content_counter":{"view":296,"like":5,"collect":10,"hot_rank":189,"comment_count":2,"interact_count":7},"author":{"user_id":"1081575170131006","name":"前端小小栈","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/d214cb622791e83300abdd4c3260ec4b~300x300.image","is_followed":false},"author_counter":{"level":5,"power":5595,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668589503620546611","item_type":2,"format":"","author_id":"1239904846873326","title":"bm2,MoonBit实现的pm2替代品","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637772874219534","tag_ids":["6809640407484334093","6809640408797167623","6809640482725953550"]},"content_counter":{"view":212,"like":4,"collect":4,"hot_rank":162,"comment_count":4,"interact_count":8},"author":{"user_id":"1239904846873326","name":"前端之虎陈随易","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/1e53615038b0e9a227c4627ee0bb0a65~300x300.image","is_followed":false},"author_counter":{"level":5,"power":22346,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668274158058504201","item_type":2,"format":"","author_id":"4001878056904584","title":"Spring Boot 集成 OnlyOffice,5 分钟搞定 Word/Excel 在线编辑","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623","6809640445233070094","6809640482725953550"]},"content_counter":{"view":288,"like":3,"collect":11,"hot_rank":153,"comment_count":0,"interact_count":3},"author":{"user_id":"4001878056904584","name":"SimonKing","avatar":"https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/mirror-assets/16cadd4c73660bef648~tplv-t2oaga2asx-image.image","is_followed":false},"author_counter":{"level":5,"power":12998,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7669024144831168518","item_type":2,"format":"","author_id":"4441682708283191","title":"DeepSeek-V4-Flash 正式版上线了,但这 3 个坑我帮你提前踩了","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637776263217160","tag_ids":["6809640407484334093","6809640408797167623","6809640398105870343"]},"content_counter":{"view":298,"like":2,"collect":1,"hot_rank":144,"comment_count":0,"interact_count":2},"author":{"user_id":"4441682708283191","name":"万少","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/3559b8826a8e632112e62195b3a1c745~300x300.image","is_followed":false},"author_counter":{"level":5,"power":12410,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668933720747638834","item_type":2,"format":"","author_id":"1204720476890477","title":"架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640407484334093","7467857238493757466","7197380506562871333"]},"content_counter":{"view":283,"like":2,"collect":1,"hot_rank":135,"comment_count":0,"interact_count":2},"author":{"user_id":"1204720476890477","name":"小帅不太帅","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/939ad8ae4c08781557a64b2b48b77a7d~300x300.image","is_followed":false},"author_counter":{"level":5,"power":6158,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667907789688274953","item_type":2,"format":"","author_id":"1662117311414462","title":"JS 代码技巧 vol.10 — 20 个 V8 引擎原理,解释\\"为什么这样写快\\"","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640398105870343","6809640404791590919"]},"content_counter":{"view":204,"like":3,"collect":4,"hot_rank":117,"comment_count":0,"interact_count":3},"author":{"user_id":"1662117311414462","name":"不简说","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/079dd96c51924889586213e3d88d5890~300x300.image","is_followed":false},"author_counter":{"level":4,"power":2596,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667748470229860378","item_type":2,"format":"","author_id":"3271760779459694","title":"《道德经》第 9 章:别把系统和自己都推到过载","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637772874219534","tag_ids":["6809640407484334093","6809640408797167623","6809640482725953550"]},"content_counter":{"view":123,"like":5,"collect":2,"hot_rank":108,"comment_count":1,"interact_count":6},"author":{"user_id":"3271760779459694","name":"勇宝趣学前端","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/5a2596246a214e4bff4a4ceff6213c54~300x300.image","is_followed":false},"author_counter":{"level":4,"power":3937,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668524314757349385","item_type":2,"format":"","author_id":"4371313964097565","title":"Agentic AI 工程实战","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640642101116936"]},"content_counter":{"view":151,"like":4,"collect":3,"hot_rank":99,"comment_count":0,"interact_count":4},"author":{"user_id":"4371313964097565","name":"Shockang","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/4665bb630e37a2f96abecb263cd5f753~300x300.image","is_followed":false},"author_counter":{"level":4,"power":2368,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668309258707320842","item_type":2,"format":"","author_id":"1380642337863272","title":"SDKMAN vs jEnv vs JetTUI,JDK 版本管理到底选哪个","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637771511070734","tag_ids":["6809640408797167623"]},"content_counter":{"view":74,"like":2,"collect":1,"hot_rank":99,"comment_count":6,"interact_count":8},"author":{"user_id":"1380642337863272","name":"极客悟道","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/4a2d5c0741c2ab9451777574d769dab2~300x300.image","is_followed":false},"author_counter":{"level":3,"power":474,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668880520002240566","item_type":2,"format":"","author_id":"149189314230039","title":"GPT-5.6 Luna 降价 80%:Agent 真正该重算的是单次成功成本","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640642101116936","7257794499869573175","7197380216015028281"]},"content_counter":{"view":142,"like":4,"collect":1,"hot_rank":99,"comment_count":0,"interact_count":4},"author":{"user_id":"149189314230039","name":"武子康","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/2176f1cd005191db850b0d9d8967a45b~300x300.image","is_followed":false},"author_counter":{"level":5,"power":10970,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668906037449834502","item_type":2,"format":"","author_id":"1239904846873326","title":"MoonBit抓包模块pcap,查看电脑的每一次联网通信","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637772874219534","tag_ids":["6809640407484334093","6809640408797167623","6809640482725953550"]},"content_counter":{"view":106,"like":3,"collect":4,"hot_rank":90,"comment_count":2,"interact_count":5},"author":{"user_id":"1239904846873326","name":"前端之虎陈随易","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/1e53615038b0e9a227c4627ee0bb0a65~300x300.image","is_followed":false},"author_counter":{"level":5,"power":22346,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668613701019467782","item_type":2,"format":"","author_id":"1239904848718135","title":"面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640398105870343","6809640404791590919"]},"content_counter":{"view":164,"like":2,"collect":2,"hot_rank":90,"comment_count":0,"interact_count":2},"author":{"user_id":"1239904848718135","name":"kyriewen","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/dc010ce441d17f8236be40eb2d03ef25~300x300.image","is_followed":false},"author_counter":{"level":5,"power":8065,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668508411719090230","item_type":2,"format":"","author_id":"1694775710064217","title":"iOS 客户端视角扫盲:WKWebView 里 window、messageHandlers 与 Native 回调到底怎么工作?","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626661445640","tag_ids":["6809640398105870343"]},"content_counter":{"view":111,"like":5,"collect":9,"hot_rank":90,"comment_count":0,"interact_count":5},"author":{"user_id":"1694775710064217","name":"大龄秃头程序员","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/b57565666e223f09fdfeb2c5102c6e4a~300x300.image","is_followed":false},"author_counter":{"level":3,"power":525,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668247452035579939","item_type":2,"format":"","author_id":"1151943919285431","title":"面试官突然问:“数仓哪一层最适合做RAG?”他一下被问住了…","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640404791590919"]},"content_counter":{"view":179,"like":2,"collect":4,"hot_rank":90,"comment_count":0,"interact_count":2},"author":{"user_id":"1151943919285431","name":"神奇小汤圆","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/7faa641980319649e45a847fcd54c46e~300x300.image","is_followed":false},"author_counter":{"level":5,"power":11601,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668613701018583046","item_type":2,"format":"","author_id":"220360279590862","title":"AI时代,程序员该往哪走?","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640407484334093","6809640408797167623"]},"content_counter":{"view":128,"like":2,"collect":2,"hot_rank":81,"comment_count":1,"interact_count":3},"author":{"user_id":"220360279590862","name":"程序员_小雨","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/254baefb585a9a27d77df8976366f55e~300x300.image","is_followed":false},"author_counter":{"level":4,"power":3173,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668341210564214784","item_type":2,"format":"","author_id":"3148645291002232","title":"从火焰图到代码:如何揪出“用久必卡”的前端性能瓶颈","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093"]},"content_counter":{"view":189,"like":0,"collect":5,"hot_rank":81,"comment_count":0,"interact_count":0},"author":{"user_id":"3148645291002232","name":"IT橘子皮","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/e1dcb4a9ffbfc57847420b18b52b1296~300x300.image","is_followed":false},"author_counter":{"level":5,"power":10129,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668198031946809380","item_type":2,"format":"","author_id":"858052674727959","title":"15|(前端转全栈)从一个副标题字段看懂后端完整交付链路","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640407484334093","6809640408797167623","6809640404791590919"]},"content_counter":{"view":109,"like":3,"collect":4,"hot_rank":81,"comment_count":1,"interact_count":4},"author":{"user_id":"858052674727959","name":"swipe","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/ba6476a882ad6e83b4332cd6b7d48c6e~300x300.image","is_followed":false},"author_counter":{"level":4,"power":4558,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668494151793803305","item_type":2,"format":"","author_id":"2770425030646920","title":"深入理解 Flutter 架构:从 Widget 到 GPU 像素的全链路解析","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809641090145058824","6809641091428515853","6809640404791590919"]},"content_counter":{"view":104,"like":3,"collect":1,"hot_rank":81,"comment_count":1,"interact_count":4},"author":{"user_id":"2770425030646920","name":"GitLqr","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/ccc4bb40b0cda1df6b2b885e69c63cc4~300x300.image","is_followed":false},"author_counter":{"level":5,"power":20432,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7669321508946919451","item_type":2,"format":"","author_id":"1574156382242637","title":"给 AI Agent 加上语音交互:ASR + 流式 TTS 实战","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640642101116936","6809640407484334093","6809640408797167623"]},"content_counter":{"view":58,"like":6,"collect":3,"hot_rank":72,"comment_count":0,"interact_count":6},"author":{"user_id":"1574156382242637","name":"云浪","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/f56a64387805ddf3200e9d065da433b9~300x300.image","is_followed":false},"author_counter":{"level":4,"power":4022,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668632356999462946","item_type":2,"format":"","author_id":"3350967174045047","title":"从 mldong 到 jeeflow:一个工作流引擎的独立进化","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623"]},"content_counter":{"view":108,"like":2,"collect":3,"hot_rank":72,"comment_count":1,"interact_count":3},"author":{"user_id":"3350967174045047","name":"mldong","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/cd319eca3d1c3138ae5798e314786040~300x300.image","is_followed":false},"author_counter":{"level":5,"power":9064,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668247452035350563","item_type":2,"format":"","author_id":"3386151544043960","title":"腾讯 Mars XLog 日志框架的编译和修改","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809640400832167949"]},"content_counter":{"view":119,"like":3,"collect":4,"hot_rank":72,"comment_count":0,"interact_count":3},"author":{"user_id":"3386151544043960","name":"李斯维","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/e202048c011082de7974c4447a899765~300x300.image","is_followed":false},"author_counter":{"level":3,"power":1636,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668718271143952435","item_type":2,"format":"","author_id":"976022055165608","title":"DeepSeek V4-Flash 正式版发布:Agent 基准、价格与 Codex 接入保姆级教程","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["7467857238494019610","7467857238493757466","7516396389476401162"]},"content_counter":{"view":152,"like":0,"collect":1,"hot_rank":63,"comment_count":0,"interact_count":0},"author":{"user_id":"976022055165608","name":"极客密码","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/31dc63f4c1be7194a4e3ba134d121210~300x300.image","is_followed":false},"author_counter":{"level":5,"power":5744,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668598831861661722","item_type":2,"format":"","author_id":"2832784963939438","title":"2840亿参数只卖白菜价:DeepSeek V4 Flash 正式版上线,Agent 能力暴涨6倍","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640499062767624","6809640642101116936"]},"content_counter":{"view":130,"like":1,"collect":1,"hot_rank":63,"comment_count":0,"interact_count":1},"author":{"user_id":"2832784963939438","name":"怕浪猫","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/0e141e0ee39472b8dbddd3a4d8983a38~300x300.image","is_followed":false},"author_counter":{"level":5,"power":5955,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668331078025773071","item_type":2,"format":"","author_id":"199452905712459","title":"教你用最简单的数学自底向上地高效学习SQL注入","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623"]},"content_counter":{"view":104,"like":2,"collect":0,"hot_rank":63,"comment_count":0,"interact_count":2},"author":{"user_id":"199452905712459","name":"大侠在此在在此","avatar":"https://p26-passport.byteacctimg.com/img/mosaic-legacy/3793/3131589739~300x300.image","is_followed":false},"author_counter":{"level":1,"power":26,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668316523342987270","item_type":2,"format":"","author_id":"1020824523126637","title":"从原始采样到可缩放心电图:用 h5ECG 绘制自己的 ECG","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093"]},"content_counter":{"view":65,"like":0,"collect":2,"hot_rank":63,"comment_count":4,"interact_count":4},"author":{"user_id":"1020824523126637","name":"洪贺","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/76096d8d5fc4b8f99a2428512573b74c~300x300.image","is_followed":false},"author_counter":{"level":1,"power":28,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668206734344667174","item_type":2,"format":"","author_id":"392940069589529","title":"React 状态提升:一个 ColorPicker,彻底搞懂状态该放哪里","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640357354012685","6809640543006490638","6809640406058270733"]},"content_counter":{"view":70,"like":4,"collect":0,"hot_rank":63,"comment_count":0,"interact_count":4},"author":{"user_id":"392940069589529","name":"烬羽","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/17a70c62f5d39e21845ced34dd665b0a~300x300.image","is_followed":false},"author_counter":{"level":4,"power":1840,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668202727697317922","item_type":2,"format":"","author_id":"3667626523633389","title":"tailwind 速记","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093"]},"content_counter":{"view":95,"like":3,"collect":7,"hot_rank":63,"comment_count":0,"interact_count":3},"author":{"user_id":"3667626523633389","name":"时光不负努力","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/0a77281dbfaaeb49a2feb08a5d5db15f~300x300.image","is_followed":false},"author_counter":{"level":3,"power":1066,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7669268061262397503","item_type":2,"format":"","author_id":"2172290706715565","title":"栗子前端技术周刊第 140 期 - pnpm、Node 新 API 文档网站、Oxlint...","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093","6809640398105870343","6809640361531539470"]},"content_counter":{"view":90,"like":3,"collect":1,"hot_rank":63,"comment_count":0,"interact_count":3},"author":{"user_id":"2172290706715565","name":"晓得迷路了","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/2245abbd9a1b2147a918ec036c2149e1~300x300.image","is_followed":false},"author_counter":{"level":5,"power":26100,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7669068704309329960","item_type":2,"format":"","author_id":"3192637495714686","title":"网页端OCR, 加载6mb大小模型, 又快又准, 百度这次真香","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623","6809640407484334093"]},"content_counter":{"view":77,"like":3,"collect":4,"hot_rank":54,"comment_count":0,"interact_count":3},"author":{"user_id":"3192637495714686","name":"半刻纬度","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/07e4b5b998a373958f919e974f769f01~300x300.image","is_followed":false},"author_counter":{"level":5,"power":24376,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7669036838767034387","item_type":2,"format":"","author_id":"1611207712190058","title":"Android:Hilt框架入门 · 在ViewUI和ComposeUI下的应用","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809635626879549454","tag_ids":["6809640400832167949","6809641107346063368"]},"content_counter":{"view":70,"like":3,"collect":0,"hot_rank":54,"comment_count":0,"interact_count":3},"author":{"user_id":"1611207712190058","name":"Lesile","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/c861ba9bf058d6b23878f43ea1708508~300x300.image","is_followed":false},"author_counter":{"level":2,"power":150,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668692837795725347","item_type":2,"format":"","author_id":"3806962499980916","title":" 08|韧性:一套接口接三家 API —— LLMProvider","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["7467857238494019610"]},"content_counter":{"view":71,"like":3,"collect":2,"hot_rank":54,"comment_count":0,"interact_count":3},"author":{"user_id":"3806962499980916","name":"浪遏","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/5c1619281bed61a788ee074772296e90~300x300.image","is_followed":false},"author_counter":{"level":5,"power":6111,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668602914118041610","item_type":2,"format":"","author_id":"2463384809252397","title":"Go语言第四章(类型转换)","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640408797167623","6809640364677267469"]},"content_counter":{"view":66,"like":3,"collect":2,"hot_rank":54,"comment_count":0,"interact_count":3},"author":{"user_id":"2463384809252397","name":"小满zs","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/f406e4f16ef06556e95d7fe50241a5e8~300x300.image","is_followed":false},"author_counter":{"level":6,"power":31270,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668564914921881636","item_type":2,"format":"","author_id":"245921884145240","title":"VS Code 内置浏览器打开网页","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640407484334093"]},"content_counter":{"view":85,"like":1,"collect":1,"hot_rank":54,"comment_count":1,"interact_count":2},"author":{"user_id":"245921884145240","name":"笨笨狗吞噬者","avatar":"https://p3-passport.byteacctimg.com/img/user-avatar/24ee78f33f9379577dc9dffa1b6669a8~300x300.image","is_followed":false},"author_counter":{"level":4,"power":4767,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668547554775695400","item_type":2,"format":"","author_id":"3669540352043419","title":"React 组件重新渲染时,到底重新执行了什么","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637767543259144","tag_ids":["6809640357354012685","6809640407484334093","6809640404791590919"]},"content_counter":{"view":88,"like":2,"collect":3,"hot_rank":54,"comment_count":1,"interact_count":3},"author":{"user_id":"3669540352043419","name":"Revolution61","avatar":"https://p26-passport.byteacctimg.com/img/user-avatar/abdd9a332b03603e265e249e7f415bf9~300x300.image","is_followed":false},"author_counter":{"level":3,"power":654,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668247452035874851","item_type":2,"format":"","author_id":"3737995265453661","title":"改了20字描述,MCP工具调用准确率飙到85%","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["7467857241178259507","7467857238494019610","7516396389476401162"]},"content_counter":{"view":89,"like":1,"collect":0,"hot_rank":54,"comment_count":1,"interact_count":2},"author":{"user_id":"3737995265453661","name":"码哥字节","avatar":"https://p6-passport.byteacctimg.com/img/user-avatar/8be362627ed4532e3af99463b755598f~300x300.image","is_followed":false},"author_counter":{"level":5,"power":9471,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7667750500684152867","item_type":2,"format":"","author_id":"3956505282886506","title":"BCrypt 还是 Argon2?Spring Security 密码加密方案深度解析与实战对比","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637769959178254","tag_ids":["6809640445233070094","6809640703325372423"]},"content_counter":{"view":89,"like":2,"collect":2,"hot_rank":54,"comment_count":0,"interact_count":2},"author":{"user_id":"3956505282886506","name":"都叫我大帅哥","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/4330d38b5347bc9896ed88eaf9592a9a~300x300.image","is_followed":false},"author_counter":{"level":5,"power":7163,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}},{"content":{"content_id":"7668977124872732722","item_type":2,"format":"","author_id":"3456520291098686","title":"AI编程出海第二步:验证关键词能否做站","brief":"","status":2,"ctime":0,"mtime":0,"category_id":"6809637773935378440","tag_ids":["6809640408797167623","6809640407484334093","6809640642101116936"]},"content_counter":{"view":62,"like":2,"collect":2,"hot_rank":45,"comment_count":0,"interact_count":2},"author":{"user_id":"3456520291098686","name":"卷福同学","avatar":"https://p9-passport.byteacctimg.com/img/user-avatar/ea20d1a80e4b73968e0be6c4027915d8~300x300.image","is_followed":false},"author_counter":{"level":5,"power":6374,"follower":0,"followee":0,"publish":0,"view":0,"like":0,"hot_rank":0},"user_interact":{"is_user_like":false,"is_user_collect":false,"is_follow":false}}]'),St=Se,$=(()=>{const t=new Map;for(const a of Nt){const s=a.author;!(s!=null&&s.user_id)||t.has(s.user_id)||t.set(s.user_id,{userId:s.user_id,name:s.name,avatar:s.avatar})}return Array.from(t.values())})();Array.from({length:St},(t,a)=>{const s=$.length>0?$[a%$.length]:void 0,r=a===0,o=r?"c0dec001":(Math.imul(73244475,a+17)>>>0).toString(16).padStart(8,"0"),n=s?a<$.length?s.userId:`${s.userId}-${a}`:o;return{displayName:(s==null?void 0:s.name)??`用户 ${o}`,userHash:o,uid:n,avatarUrl:s==null?void 0:s.avatar,tokens:r?15e9:Math.max(12e7,95e8-a*175e6+a*7%5*45e6),costUsd:r?14e3:Math.max(80,Number((8200-a*145+a*11%7*38).toFixed(2))),isCurrentUser:r}});const Rt=1e4;function Ct(t,a){return`${t}|${a.tool??""}|${a.model??""}`}function Lt(t,a={}){const s=Ee(),r=ne(),{authStatus:o}=le(),[n,i]=_.useState(0),c=_.useRef(null),f=_.useRef(!1),[h,d]=_.useState({data:null,loading:!0,refreshing:!1,error:null}),w=_.useCallback(l=>{f.current=(l==null?void 0:l.silent)!==!0,i(u=>u+1)},[]);return _.useEffect(()=>{let l=!1;const u=Ct(t,a),b=f.current;return f.current=!1,d(p=>p.data==null?{...p,loading:!0,refreshing:!1,error:null}:c.current!=null&&c.current!==u||b?{...p,loading:!1,refreshing:!0,error:null}:p),Re(t,void 0,a).then(p=>{l||(c.current=u,d({data:p,loading:!1,refreshing:!1,error:null}))}).catch(p=>{l||d(v=>({data:v.data,loading:!1,refreshing:!1,error:p instanceof Error?p.message:"排行榜加载失败"}))}),()=>{l=!0}},[t,n,s,r,o,a.model,a.tool]),_.useEffect(()=>{let l=0,u=performance.now();const b=p=>{p-u>=Rt&&(u=p,w({silent:!0})),l=requestAnimationFrame(b)};l=requestAnimationFrame(b);const g=()=>{u=performance.now(),w({silent:!0})};return window.addEventListener("focus",g),()=>{cancelAnimationFrame(l),window.removeEventListener("focus",g)}},[w]),{...h,reload:w}}function It(){const[t,a]=Pe("tud.rankRange","today",Ge),[s,r]=_.useState(""),[o,n]=_.useState(""),[i,c]=_.useState("tokens"),[f,h]=_.useState(!1),[d,w]=_.useState(!1),{data:l,error:u,loading:b,refreshing:g,reload:p}=Lt(t,{tool:s||void 0,model:o||void 0}),v=b||g,{authStatus:L,userId:x,userName:m,avatarLarge:N}=le(),y=ne(),D=!0;_.useEffect(()=>{const j=()=>{p()};return window.addEventListener(Z,j),()=>window.removeEventListener(Z,j)},[p]),_.useEffect(()=>{let j=!1;return Ce().then(B=>{j||h(B.hideFromLeaderboard)}).catch(()=>{j||h(!1)}),()=>{j=!0}},[D]);const he=!b&&!u&&l!=null&&z(l.global.cost)==null&&z(l.global.tokens)==null,I=l==null?void 0:l.filterOptions,pe=_.useMemo(()=>Je((I==null?void 0:I.models)??[],s),[I==null?void 0:I.models,s]),X=_.useMemo(()=>{const j={...(l==null?void 0:l.profiles)??{}};return x&&m&&(j[x]={uid:x,userName:m,avatarUrl:N,profileUrl:`https://juejin.cn/user/${encodeURIComponent(x)}`}),j},[l==null?void 0:l.profiles,x,m,N]),xe=j=>{const B=f;h(j),w(!0),Ie(j).then(()=>{p()}).catch(()=>{h(B)}).finally(()=>{w(!1)})};return e.jsxs("div",{"aria-busy":v,className:"relative flex w-full min-w-0 flex-col",children:[e.jsx(ut,{board:(l==null?void 0:l.global[i])??null,hideFromLeaderboard:f,isSignedIn:y,loading:v,metric:i,model:o,modelOptions:pe,onChange:a,onModelChange:n,onToolChange:j=>{r(j),n("")},profiles:X,tool:s,tools:(I==null?void 0:I.tools)??[],value:t}),e.jsxs("div",{className:"space-y-6",children:[u!=null&&l==null&&e.jsxs("div",{className:"flex w-full flex-col gap-4 sm:flex-row sm:items-center",children:[e.jsx("div",{className:"min-w-0 flex-1",children:e.jsx(G,{description:u,title:"排行榜加载失败",tone:"error"})}),e.jsx(M,{className:"shrink-0 self-start sm:self-center",onPress:()=>p(),variant:"secondary",children:"重试"})]}),u!=null&&l!=null&&e.jsxs("div",{className:"flex w-full flex-col gap-4 sm:flex-row sm:items-center",children:[e.jsx("div",{className:"min-w-0 flex-1",children:e.jsx(G,{description:`${u}。下面显示的是上次成功加载的数据,可能不是最新的。`,title:"排行榜刷新失败",tone:"warn"})}),e.jsx(M,{className:"shrink-0 self-start sm:self-center",onPress:()=>p(),variant:"secondary",children:"重试"})]}),he&&e.jsxs("div",{className:"flex w-full flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsx("div",{className:"min-w-0 flex-1",children:e.jsx(G,{description:"无法标注你的排名。请前往设置绑定鉴权 Token,或登录后再查看个人名次。",title:"鉴权无效或未登录",tone:"warn"})}),e.jsx(M,{className:"shrink-0 self-start sm:self-center",onPress:()=>{Le()},variant:"secondary",children:"去设置"})]}),!(u!=null&&l==null)&&e.jsx(bt,{global:(l==null?void 0:l.global)??null,hideFromLeaderboard:f,hideToggleDisabled:d,loading:b,metric:i,onHideFromLeaderboardChange:xe,onMetricChange:c,profiles:X,refreshing:g,showHideToggle:D})]})]})}const Pt=It;export{Pt as component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,d as n}from"./index-
|
|
1
|
+
import{r as t,d as n}from"./index-mevy0vLr.js";function e(){return t.useEffect(()=>{n()},[]),null}const s=e;export{s as component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as _,an as f,j as u,aS as T,aU as O,r,bI as ce,aD as Q,b0 as de,b1 as ue,ai as fe,aJ as pe,bJ as be,b3 as $e,am as A,X as D,ay as H,_ as P,ao as X,b4 as he,b6 as me,ak as xe,al as B,bK as ve,aV as L,bL as ge,bM as ye,aF as we,bN as Pe,G as Ce,aa as Y,bO as Se,a6 as Re,bP as Ee,bQ as Te,bR as Oe,bS as Me,bT as Ne,bU as De,c as F,bt as Ie,B as je}from"./index-DLtjtn6U.js";import{u as U}from"./index-sxwOKh3b.js";const ke=_({defaultVariants:{color:"default",variant:"secondary"},slots:{base:"chip",label:"chip__label"},variants:{color:{accent:{base:"chip--accent"},danger:{base:"chip--danger"},default:{base:"chip--default"},success:{base:"chip--success"},warning:{base:"chip--warning"}},size:{lg:{base:"chip--lg"},md:{base:"chip--md"},sm:{base:"chip--sm"}},variant:{primary:{base:"chip--primary"},secondary:{base:"chip--secondary"},soft:{base:"chip--soft"},tertiary:{base:"chip--tertiary"}}}}),_e=_({defaultVariants:{size:"md"},slots:{base:"switch",content:"switch__content",control:"switch__control",icon:"switch__icon",thumb:"switch__thumb"},variants:{size:{lg:{base:"switch--lg"},md:{base:"switch--md"},sm:{base:"switch--sm"}}}}),Ae=_({slots:{base:"tooltip",trigger:"tooltip__trigger"}}),Z=r.createContext({}),z=({children:e,className:t,color:a,size:n,variant:o,...s})=>{const i=f.useMemo(()=>ke({color:a,size:n,variant:o}),[a,n,o]),d=f.useMemo(()=>typeof e=="string"||typeof e=="number"?u.jsx(ee,{children:e}):e,[e]);return u.jsx(Z,{value:{slots:i},children:u.jsx(T.span,{...s,className:O(i.base,t),"data-slot":"chip",children:d})})},ee=({children:e,className:t,...a})=>{const{slots:n}=r.use(Z);return u.jsx(T.span,{className:O(n==null?void 0:n.label,t),"data-slot":"chip-label",...a,children:e})},$t=Object.assign(z,{Root:z,Label:ee});function He(e,t,a){let{labelProps:n,inputProps:o,isSelected:s,...i}=ce(e,t,a);return{labelProps:n,inputProps:{...o,role:"switch",checked:s},isSelected:s,...i}}const Be=r.createContext(null),te=r.createContext(null),ae=r.createContext(null),Le=r.forwardRef(function(t,a){let{inputRef:n=null,...o}=t;[t,a]=Q(o,a,Be);let{validationBehavior:s}=de(ue)||{},i=t.validationBehavior??s??"native",d=fe(pe(n,t.inputRef!==void 0?t.inputRef:null)),l=be(t),c=He({...$e(t),children:typeof t.children=="function"?!0:t.children,validationBehavior:i},l,d),{descriptionProps:b,errorMessageProps:h,isSelected:m,isDisabled:$,isReadOnly:x,isInvalid:y,validationDetails:p,validationErrors:C}=c,v=A({...t,defaultClassName:"react-aria-SwitchField",values:{isSelected:m,isDisabled:$,isReadOnly:x,isInvalid:y,isRequired:t.isRequired||!1,state:l}}),w=D(t,{global:!0});return delete w.id,delete w.onClick,f.createElement(H.div,{...P(w,v),ref:a,slot:t.slot||void 0,"data-selected":m||void 0,"data-disabled":$||void 0,"data-readonly":x||void 0,"data-invalid":y||void 0,"data-required":t.isRequired||void 0},f.createElement(X,{values:[[te,l],[ae,{...c,inputRef:d,defaultClassName:"react-aria-SwitchButton",isRequired:t.isRequired}],[he,{slots:{description:b,errorMessage:h}}],[me,{isInvalid:y,validationDetails:p,validationErrors:C}]]},v.children))}),Fe=r.forwardRef(function(t,a){let{labelProps:n,inputProps:o,isSelected:s,isDisabled:i,isReadOnly:d,isPressed:l,isInvalid:c,inputRef:b,defaultClassName:h,isRequired:m}=r.useContext(ae),{isFocused:$,isFocusVisible:x,focusProps:y}=xe(),p=i||d,C=r.useContext(te),{hoverProps:v,isHovered:w}=B({...t,isDisabled:p}),q=A({...t,defaultClassName:h,values:{isSelected:s,isPressed:l,isHovered:w,isFocused:$,isFocusVisible:x,isDisabled:i,isReadOnly:d,isInvalid:c,isRequired:m||!1,state:C}}),I=D(t,{global:!0});return delete I.id,delete I.onClick,f.createElement(H.label,{...P(I,n,v,q),ref:a,slot:t.slot||void 0,"data-selected":s||void 0,"data-pressed":l||void 0,"data-hovered":w||void 0,"data-focused":$||void 0,"data-focus-visible":x||void 0,"data-disabled":i||void 0,"data-readonly":d||void 0,"data-invalid":c||void 0,"data-required":m||void 0},f.createElement(ve,{elementType:"span"},f.createElement("input",{...P(o,y),ref:b})),q.children)}),N=r.createContext({}),j=({children:e,className:t,size:a,...n})=>{const o=f.useMemo(()=>_e({size:a}),[a]);return u.jsx(Le,{"data-slot":"switch",...n,className:L(t,o.base()),children:s=>u.jsx(N,{value:{slots:o,state:s},children:typeof e=="function"?e(s):e})})};j.displayName="HeroUI.Switch";const ne=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(Fe,{"data-slot":"switch-content",...a,className:L(t,n==null?void 0:n.content()),children:e})};ne.displayName="HeroUI.Switch.Content";const oe=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.control,t),"data-slot":"switch-control",...a,children:e})};oe.displayName="HeroUI.Switch.Control";const re=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.thumb,t),"data-slot":"switch-thumb",...a,children:e})};re.displayName="HeroUI.Switch.Thumb";const se=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.icon,t),"data-slot":"switch-icon",...a,children:e})};se.displayName="HeroUI.Switch.Icon";const ht=Object.assign(j,{Root:j,Content:ne,Control:oe,Thumb:re,Icon:se}),k=f.createContext(null);function Ve(e){let{children:t}=e,a=r.useContext(k),[n,o]=r.useState(0),s=r.useMemo(()=>({parent:a,modalCount:n,addModal(){o(i=>i+1),a&&a.addModal()},removeModal(){o(i=>i-1),a&&a.removeModal()}}),[a,n]);return f.createElement(k.Provider,{value:s},t)}function qe(){let e=r.useContext(k);return{modalProviderProps:{"aria-hidden":e&&e.modalCount>0?!0:void 0}}}function Ue(e){let{modalProviderProps:t}=qe();return f.createElement("div",{"data-overlay-container":!0,...e,...t})}function ze(e){return f.createElement(Ve,null,f.createElement(Ue,e))}function We(e){let t=ge(),{portalContainer:a=t?null:document.body,...n}=e,{getContainer:o}=ye();if(!e.portalContainer&&o&&(a=o()),f.useEffect(()=>{if(a!=null&&a.closest("[data-overlay-container]"))throw new Error("An OverlayContainer must not be inside another container. Please change the portalContainer prop.")},[a]),!a)return null;let s=f.createElement(ze,n);return we.createPortal(s,a)}const Je=1500,W=500;let S={},Ke=0,E=!1,g=null,R=null;function ie(e={}){let{delay:t=Je,closeDelay:a=W}=e,{isOpen:n,open:o,close:s}=Pe(e),[i,d]=r.useState(!1),l=r.useMemo(()=>`${++Ke}`,[]),c=r.useRef(null),b=r.useRef(s),h=()=>{S[l]=x},m=()=>{for(let p in S)p!==l&&(S[p](!0,!0),delete S[p])},$=p=>{c.current&&clearTimeout(c.current),c.current=null,m(),h(),d(!!p),E=!0,o(),g&&(clearTimeout(g),g=null),R&&(clearTimeout(R),R=null)},x=(p,C)=>{d(!!C),p||a<=0?(c.current&&clearTimeout(c.current),c.current=null,b.current()):c.current||(c.current=setTimeout(()=>{c.current=null,b.current()},a)),g&&(clearTimeout(g),g=null),E&&(R&&clearTimeout(R),R=setTimeout(()=>{delete S[l],R=null,E=!1},Math.max(W,a)))},y=()=>{m(),h(),!n&&!E?(g&&clearTimeout(g),g=setTimeout(()=>{g=null,E=!0,$(!1)},t)):n||$(!0)};return r.useEffect(()=>{b.current=s},[s]),r.useEffect(()=>()=>{c.current&&clearTimeout(c.current),S[l]&&delete S[l]},[l]),{isOpen:n,shouldSkipAnimation:i,open:p=>{!p&&t>0&&!c.current?y():$(E)},close:x}}function Ge(e,t){let a=D(e,{labelable:!0}),{hoverProps:n}=B({onHoverStart:()=>t==null?void 0:t.open(!0),onHoverEnd:()=>t==null?void 0:t.close()});return{tooltipProps:P(a,n,{role:"tooltip"})}}function Qe(e,t,a){let{isDisabled:n,trigger:o,shouldCloseOnPress:s=!0}=e,i=Ce(),d=r.useRef(!1),l=r.useRef(!1),c=()=>{(d.current||l.current)&&t.open(l.current)},b=v=>{!d.current&&!l.current&&t.close(v)};r.useEffect(()=>{let v=w=>{a&&a.current&&w.key==="Escape"&&(w.stopPropagation(),t.close(!0))};if(t.isOpen)return document.addEventListener("keydown",v,!0),()=>{document.removeEventListener("keydown",v,!0)}},[a,t]);let h=()=>{o!=="focus"&&(Se()==="pointer"?d.current=!0:d.current=!1,c())},m=()=>{o!=="focus"&&(l.current=!1,d.current=!1,b())},$=()=>{s&&(l.current=!1,d.current=!1,b(!0))},x=()=>{Re()&&(l.current=!0,c())},y=()=>{l.current=!1,d.current=!1,b(!0)},{hoverProps:p}=B({isDisabled:n,onHoverStart:h,onHoverEnd:m}),{focusableProps:C}=Y({isDisabled:n,onFocus:x,onBlur:y},a);return{triggerProps:{"aria-describedby":t.isOpen?i:void 0,...P(C,p,{onPointerDown:$,onKeyDown:$}),tabIndex:void 0},tooltipProps:{id:i}}}const M=r.createContext(null),le=r.createContext(null);function Xe(e){let t=ie(e),a=r.useRef(null),{triggerProps:n,tooltipProps:o}=Qe(e,t,a);return f.createElement(X,{values:[[M,t],[le,{...o,triggerRef:a}]]},f.createElement(Ee,{...n,ref:a},e.children))}const Ye=r.forwardRef(function({UNSTABLE_portalContainer:t,...a},n){[a,n]=Q(a,n,le);let o=r.useContext(M),s=ie(a),i=a.isOpen!=null||a.defaultOpen!=null||!o?s:o,d=Te(n,i.isOpen),l=a.isExiting||!i.shouldSkipAnimation&&d||!1;return!i.isOpen&&!l?null:f.createElement(We,{portalContainer:t},f.createElement(Ze,{...a,tooltipRef:n,isExiting:l}))});function Ze(e){let t=r.useContext(M),a=r.useRef(null),{overlayProps:n,arrowProps:o,placement:s,triggerAnchorPoint:i}=Oe({placement:e.placement||"top",targetRef:e.triggerRef,overlayRef:e.tooltipRef,arrowRef:a,offset:e.offset,crossOffset:e.crossOffset,isOpen:t.isOpen,arrowBoundaryOffset:e.arrowBoundaryOffset,shouldFlip:e.shouldFlip,containerPadding:e.containerPadding,onClose:()=>t.close(!0)}),d=Me(e.tooltipRef,!!s),l=e.isEntering||!t.shouldSkipAnimation&&d||!1,c=A({...e,defaultClassName:"react-aria-Tooltip",values:{placement:s,isEntering:l,isExiting:e.isExiting,state:t}});e=P(e,n);let{tooltipProps:b}=Ge(e,t),h=D(e,{global:!0});return f.createElement(H.div,{...P(h,c,b),ref:e.tooltipRef,style:{...n.style,"--trigger-anchor-point":i?`${i.x}px ${i.y}px`:void 0,...c.style},"data-placement":s??void 0,"data-entering":l||void 0,"data-exiting":e.isExiting||void 0},f.createElement(Ne.Provider,{value:{...o,placement:s,ref:a}},c.children))}const J=e=>{if(!e)return;const t=e.trim(),a=parseFloat(t);if(!Number.isNaN(a))return t.endsWith("ms")?a:t.endsWith("s")?a*1e3:a},V=r.createContext({}),et=({children:e,shouldSkipAnimation:t})=>{const a=r.use(M);return!a||t?e:u.jsx(M,{value:{...a,shouldSkipAnimation:!1},children:e})},K=({children:e,closeDelay:t,delay:a,shouldSkipAnimation:n=!1,...o})=>{const s=f.useMemo(()=>Ae(),[]),i=U("--tooltip-delay"),d=U("--tooltip-close-delay"),l=a??J(i),c=t??J(d);return u.jsx(V,{value:{slots:s},children:u.jsx(Xe,{closeDelay:c,"data-slot":"tooltip-root",delay:l,...o,children:u.jsx(et,{shouldSkipAnimation:n,children:e})})})},tt=({children:e,className:t,offset:a,showArrow:n=!1,...o})=>{const{slots:s}=r.use(V),i=a||(n?7:3);return u.jsx(Ye,{...o,className:L(t,s==null?void 0:s.base()),offset:i,children:e})},at=({children:e,className:t,...a})=>{const n=u.jsx("svg",{"data-slot":"overlay-arrow",fill:"none",height:"12",viewBox:"0 0 12 12",width:"12",xmlns:"http://www.w3.org/2000/svg",children:u.jsx("path",{d:"M0 0C5.48483 8 6.5 8 12 0Z"})}),o=f.isValidElement(e)?f.cloneElement(e,{"data-slot":"overlay-arrow"}):n;return u.jsx(De,{"data-slot":"tooltip-arrow",...a,className:t,children:o})},nt=({children:e,className:t,...a})=>{const{slots:n}=r.use(V),o=r.useRef(null),{focusableProps:s}=Y({},o);return u.jsx(T.div,{ref:o,className:O(n==null?void 0:n.trigger,t),"data-slot":"tooltip-trigger",role:"button",...P(s,a),children:e})},G=Object.assign(K,{Root:K,Trigger:nt,Content:tt,Arrow:at}),mt=e=>r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",width:16,height:16,fill:"none",viewBox:"0 0 16 16"},e),r.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M10.418 2.489c.9-1.196 2.382-1.724 3.154-1.391.852.367 1.539 2.08 1.054 3.702a4 4 0 0 1-2.616 5.559c.309.471.49 1.035.49 1.641v2.25a.75.75 0 0 1-1.5 0V12a1.5 1.5 0 0 0-3 0v2.25a.75.75 0 0 1-1.5 0v-.75h-.876a2.626 2.626 0 0 1-2.625-2.625c0-.621-.504-1.125-1.125-1.125h-.125a.75.75 0 0 1 0-1.5h.125a2.625 2.625 0 0 1 2.625 2.625c0 .621.504 1.125 1.125 1.125H6.5c0-.606.18-1.17.488-1.641A4 4 0 0 1 4.373 4.8c-.484-1.623.202-3.335 1.054-3.702.772-.333 2.254.195 3.155 1.39zm2.549.02a1.4 1.4 0 0 0-.35.098 2.5 2.5 0 0 0-1 .784l-.451.598H7.834l-.45-.598a2.5 2.5 0 0 0-1.001-.784 1.4 1.4 0 0 0-.352-.099c-.063.088-.14.231-.204.429a2.5 2.5 0 0 0-.016 1.434l.163.546-.242.517c-.13.279-.21.586-.228.913l-.004.142a2.5 2.5 0 0 0 2.5 2.5h3a2.5 2.5 0 0 0 2.267-3.555l-.242-.517.163-.547a2.5 2.5 0 0 0-.016-1.433 1.6 1.6 0 0 0-.205-.429",clipRule:"evenodd"}));/**
|
|
1
|
+
import{t as _,an as f,j as u,aS as T,aU as O,r,bI as ce,aD as Q,b0 as de,b1 as ue,ai as fe,aJ as pe,bJ as be,b3 as $e,am as A,X as D,ay as H,_ as P,ao as X,b4 as he,b6 as me,ak as xe,al as B,bK as ve,aV as L,bL as ge,bM as ye,aF as we,bN as Pe,G as Ce,aa as Y,bO as Se,a6 as Re,bP as Ee,bQ as Te,bR as Oe,bS as Me,bT as Ne,bU as De,c as F,bt as Ie,B as je}from"./index-mevy0vLr.js";import{u as U}from"./index-Cl161mdg.js";const ke=_({defaultVariants:{color:"default",variant:"secondary"},slots:{base:"chip",label:"chip__label"},variants:{color:{accent:{base:"chip--accent"},danger:{base:"chip--danger"},default:{base:"chip--default"},success:{base:"chip--success"},warning:{base:"chip--warning"}},size:{lg:{base:"chip--lg"},md:{base:"chip--md"},sm:{base:"chip--sm"}},variant:{primary:{base:"chip--primary"},secondary:{base:"chip--secondary"},soft:{base:"chip--soft"},tertiary:{base:"chip--tertiary"}}}}),_e=_({defaultVariants:{size:"md"},slots:{base:"switch",content:"switch__content",control:"switch__control",icon:"switch__icon",thumb:"switch__thumb"},variants:{size:{lg:{base:"switch--lg"},md:{base:"switch--md"},sm:{base:"switch--sm"}}}}),Ae=_({slots:{base:"tooltip",trigger:"tooltip__trigger"}}),Z=r.createContext({}),z=({children:e,className:t,color:a,size:n,variant:o,...s})=>{const i=f.useMemo(()=>ke({color:a,size:n,variant:o}),[a,n,o]),d=f.useMemo(()=>typeof e=="string"||typeof e=="number"?u.jsx(ee,{children:e}):e,[e]);return u.jsx(Z,{value:{slots:i},children:u.jsx(T.span,{...s,className:O(i.base,t),"data-slot":"chip",children:d})})},ee=({children:e,className:t,...a})=>{const{slots:n}=r.use(Z);return u.jsx(T.span,{className:O(n==null?void 0:n.label,t),"data-slot":"chip-label",...a,children:e})},$t=Object.assign(z,{Root:z,Label:ee});function He(e,t,a){let{labelProps:n,inputProps:o,isSelected:s,...i}=ce(e,t,a);return{labelProps:n,inputProps:{...o,role:"switch",checked:s},isSelected:s,...i}}const Be=r.createContext(null),te=r.createContext(null),ae=r.createContext(null),Le=r.forwardRef(function(t,a){let{inputRef:n=null,...o}=t;[t,a]=Q(o,a,Be);let{validationBehavior:s}=de(ue)||{},i=t.validationBehavior??s??"native",d=fe(pe(n,t.inputRef!==void 0?t.inputRef:null)),l=be(t),c=He({...$e(t),children:typeof t.children=="function"?!0:t.children,validationBehavior:i},l,d),{descriptionProps:b,errorMessageProps:h,isSelected:m,isDisabled:$,isReadOnly:x,isInvalid:y,validationDetails:p,validationErrors:C}=c,v=A({...t,defaultClassName:"react-aria-SwitchField",values:{isSelected:m,isDisabled:$,isReadOnly:x,isInvalid:y,isRequired:t.isRequired||!1,state:l}}),w=D(t,{global:!0});return delete w.id,delete w.onClick,f.createElement(H.div,{...P(w,v),ref:a,slot:t.slot||void 0,"data-selected":m||void 0,"data-disabled":$||void 0,"data-readonly":x||void 0,"data-invalid":y||void 0,"data-required":t.isRequired||void 0},f.createElement(X,{values:[[te,l],[ae,{...c,inputRef:d,defaultClassName:"react-aria-SwitchButton",isRequired:t.isRequired}],[he,{slots:{description:b,errorMessage:h}}],[me,{isInvalid:y,validationDetails:p,validationErrors:C}]]},v.children))}),Fe=r.forwardRef(function(t,a){let{labelProps:n,inputProps:o,isSelected:s,isDisabled:i,isReadOnly:d,isPressed:l,isInvalid:c,inputRef:b,defaultClassName:h,isRequired:m}=r.useContext(ae),{isFocused:$,isFocusVisible:x,focusProps:y}=xe(),p=i||d,C=r.useContext(te),{hoverProps:v,isHovered:w}=B({...t,isDisabled:p}),q=A({...t,defaultClassName:h,values:{isSelected:s,isPressed:l,isHovered:w,isFocused:$,isFocusVisible:x,isDisabled:i,isReadOnly:d,isInvalid:c,isRequired:m||!1,state:C}}),I=D(t,{global:!0});return delete I.id,delete I.onClick,f.createElement(H.label,{...P(I,n,v,q),ref:a,slot:t.slot||void 0,"data-selected":s||void 0,"data-pressed":l||void 0,"data-hovered":w||void 0,"data-focused":$||void 0,"data-focus-visible":x||void 0,"data-disabled":i||void 0,"data-readonly":d||void 0,"data-invalid":c||void 0,"data-required":m||void 0},f.createElement(ve,{elementType:"span"},f.createElement("input",{...P(o,y),ref:b})),q.children)}),N=r.createContext({}),j=({children:e,className:t,size:a,...n})=>{const o=f.useMemo(()=>_e({size:a}),[a]);return u.jsx(Le,{"data-slot":"switch",...n,className:L(t,o.base()),children:s=>u.jsx(N,{value:{slots:o,state:s},children:typeof e=="function"?e(s):e})})};j.displayName="HeroUI.Switch";const ne=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(Fe,{"data-slot":"switch-content",...a,className:L(t,n==null?void 0:n.content()),children:e})};ne.displayName="HeroUI.Switch.Content";const oe=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.control,t),"data-slot":"switch-control",...a,children:e})};oe.displayName="HeroUI.Switch.Control";const re=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.thumb,t),"data-slot":"switch-thumb",...a,children:e})};re.displayName="HeroUI.Switch.Thumb";const se=({children:e,className:t,...a})=>{const{slots:n}=r.use(N);return u.jsx(T.span,{className:O(n==null?void 0:n.icon,t),"data-slot":"switch-icon",...a,children:e})};se.displayName="HeroUI.Switch.Icon";const ht=Object.assign(j,{Root:j,Content:ne,Control:oe,Thumb:re,Icon:se}),k=f.createContext(null);function Ve(e){let{children:t}=e,a=r.useContext(k),[n,o]=r.useState(0),s=r.useMemo(()=>({parent:a,modalCount:n,addModal(){o(i=>i+1),a&&a.addModal()},removeModal(){o(i=>i-1),a&&a.removeModal()}}),[a,n]);return f.createElement(k.Provider,{value:s},t)}function qe(){let e=r.useContext(k);return{modalProviderProps:{"aria-hidden":e&&e.modalCount>0?!0:void 0}}}function Ue(e){let{modalProviderProps:t}=qe();return f.createElement("div",{"data-overlay-container":!0,...e,...t})}function ze(e){return f.createElement(Ve,null,f.createElement(Ue,e))}function We(e){let t=ge(),{portalContainer:a=t?null:document.body,...n}=e,{getContainer:o}=ye();if(!e.portalContainer&&o&&(a=o()),f.useEffect(()=>{if(a!=null&&a.closest("[data-overlay-container]"))throw new Error("An OverlayContainer must not be inside another container. Please change the portalContainer prop.")},[a]),!a)return null;let s=f.createElement(ze,n);return we.createPortal(s,a)}const Je=1500,W=500;let S={},Ke=0,E=!1,g=null,R=null;function ie(e={}){let{delay:t=Je,closeDelay:a=W}=e,{isOpen:n,open:o,close:s}=Pe(e),[i,d]=r.useState(!1),l=r.useMemo(()=>`${++Ke}`,[]),c=r.useRef(null),b=r.useRef(s),h=()=>{S[l]=x},m=()=>{for(let p in S)p!==l&&(S[p](!0,!0),delete S[p])},$=p=>{c.current&&clearTimeout(c.current),c.current=null,m(),h(),d(!!p),E=!0,o(),g&&(clearTimeout(g),g=null),R&&(clearTimeout(R),R=null)},x=(p,C)=>{d(!!C),p||a<=0?(c.current&&clearTimeout(c.current),c.current=null,b.current()):c.current||(c.current=setTimeout(()=>{c.current=null,b.current()},a)),g&&(clearTimeout(g),g=null),E&&(R&&clearTimeout(R),R=setTimeout(()=>{delete S[l],R=null,E=!1},Math.max(W,a)))},y=()=>{m(),h(),!n&&!E?(g&&clearTimeout(g),g=setTimeout(()=>{g=null,E=!0,$(!1)},t)):n||$(!0)};return r.useEffect(()=>{b.current=s},[s]),r.useEffect(()=>()=>{c.current&&clearTimeout(c.current),S[l]&&delete S[l]},[l]),{isOpen:n,shouldSkipAnimation:i,open:p=>{!p&&t>0&&!c.current?y():$(E)},close:x}}function Ge(e,t){let a=D(e,{labelable:!0}),{hoverProps:n}=B({onHoverStart:()=>t==null?void 0:t.open(!0),onHoverEnd:()=>t==null?void 0:t.close()});return{tooltipProps:P(a,n,{role:"tooltip"})}}function Qe(e,t,a){let{isDisabled:n,trigger:o,shouldCloseOnPress:s=!0}=e,i=Ce(),d=r.useRef(!1),l=r.useRef(!1),c=()=>{(d.current||l.current)&&t.open(l.current)},b=v=>{!d.current&&!l.current&&t.close(v)};r.useEffect(()=>{let v=w=>{a&&a.current&&w.key==="Escape"&&(w.stopPropagation(),t.close(!0))};if(t.isOpen)return document.addEventListener("keydown",v,!0),()=>{document.removeEventListener("keydown",v,!0)}},[a,t]);let h=()=>{o!=="focus"&&(Se()==="pointer"?d.current=!0:d.current=!1,c())},m=()=>{o!=="focus"&&(l.current=!1,d.current=!1,b())},$=()=>{s&&(l.current=!1,d.current=!1,b(!0))},x=()=>{Re()&&(l.current=!0,c())},y=()=>{l.current=!1,d.current=!1,b(!0)},{hoverProps:p}=B({isDisabled:n,onHoverStart:h,onHoverEnd:m}),{focusableProps:C}=Y({isDisabled:n,onFocus:x,onBlur:y},a);return{triggerProps:{"aria-describedby":t.isOpen?i:void 0,...P(C,p,{onPointerDown:$,onKeyDown:$}),tabIndex:void 0},tooltipProps:{id:i}}}const M=r.createContext(null),le=r.createContext(null);function Xe(e){let t=ie(e),a=r.useRef(null),{triggerProps:n,tooltipProps:o}=Qe(e,t,a);return f.createElement(X,{values:[[M,t],[le,{...o,triggerRef:a}]]},f.createElement(Ee,{...n,ref:a},e.children))}const Ye=r.forwardRef(function({UNSTABLE_portalContainer:t,...a},n){[a,n]=Q(a,n,le);let o=r.useContext(M),s=ie(a),i=a.isOpen!=null||a.defaultOpen!=null||!o?s:o,d=Te(n,i.isOpen),l=a.isExiting||!i.shouldSkipAnimation&&d||!1;return!i.isOpen&&!l?null:f.createElement(We,{portalContainer:t},f.createElement(Ze,{...a,tooltipRef:n,isExiting:l}))});function Ze(e){let t=r.useContext(M),a=r.useRef(null),{overlayProps:n,arrowProps:o,placement:s,triggerAnchorPoint:i}=Oe({placement:e.placement||"top",targetRef:e.triggerRef,overlayRef:e.tooltipRef,arrowRef:a,offset:e.offset,crossOffset:e.crossOffset,isOpen:t.isOpen,arrowBoundaryOffset:e.arrowBoundaryOffset,shouldFlip:e.shouldFlip,containerPadding:e.containerPadding,onClose:()=>t.close(!0)}),d=Me(e.tooltipRef,!!s),l=e.isEntering||!t.shouldSkipAnimation&&d||!1,c=A({...e,defaultClassName:"react-aria-Tooltip",values:{placement:s,isEntering:l,isExiting:e.isExiting,state:t}});e=P(e,n);let{tooltipProps:b}=Ge(e,t),h=D(e,{global:!0});return f.createElement(H.div,{...P(h,c,b),ref:e.tooltipRef,style:{...n.style,"--trigger-anchor-point":i?`${i.x}px ${i.y}px`:void 0,...c.style},"data-placement":s??void 0,"data-entering":l||void 0,"data-exiting":e.isExiting||void 0},f.createElement(Ne.Provider,{value:{...o,placement:s,ref:a}},c.children))}const J=e=>{if(!e)return;const t=e.trim(),a=parseFloat(t);if(!Number.isNaN(a))return t.endsWith("ms")?a:t.endsWith("s")?a*1e3:a},V=r.createContext({}),et=({children:e,shouldSkipAnimation:t})=>{const a=r.use(M);return!a||t?e:u.jsx(M,{value:{...a,shouldSkipAnimation:!1},children:e})},K=({children:e,closeDelay:t,delay:a,shouldSkipAnimation:n=!1,...o})=>{const s=f.useMemo(()=>Ae(),[]),i=U("--tooltip-delay"),d=U("--tooltip-close-delay"),l=a??J(i),c=t??J(d);return u.jsx(V,{value:{slots:s},children:u.jsx(Xe,{closeDelay:c,"data-slot":"tooltip-root",delay:l,...o,children:u.jsx(et,{shouldSkipAnimation:n,children:e})})})},tt=({children:e,className:t,offset:a,showArrow:n=!1,...o})=>{const{slots:s}=r.use(V),i=a||(n?7:3);return u.jsx(Ye,{...o,className:L(t,s==null?void 0:s.base()),offset:i,children:e})},at=({children:e,className:t,...a})=>{const n=u.jsx("svg",{"data-slot":"overlay-arrow",fill:"none",height:"12",viewBox:"0 0 12 12",width:"12",xmlns:"http://www.w3.org/2000/svg",children:u.jsx("path",{d:"M0 0C5.48483 8 6.5 8 12 0Z"})}),o=f.isValidElement(e)?f.cloneElement(e,{"data-slot":"overlay-arrow"}):n;return u.jsx(De,{"data-slot":"tooltip-arrow",...a,className:t,children:o})},nt=({children:e,className:t,...a})=>{const{slots:n}=r.use(V),o=r.useRef(null),{focusableProps:s}=Y({},o);return u.jsx(T.div,{ref:o,className:O(n==null?void 0:n.trigger,t),"data-slot":"tooltip-trigger",role:"button",...P(s,a),children:e})},G=Object.assign(K,{Root:K,Trigger:nt,Content:tt,Arrow:at}),mt=e=>r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",width:16,height:16,fill:"none",viewBox:"0 0 16 16"},e),r.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M10.418 2.489c.9-1.196 2.382-1.724 3.154-1.391.852.367 1.539 2.08 1.054 3.702a4 4 0 0 1-2.616 5.559c.309.471.49 1.035.49 1.641v2.25a.75.75 0 0 1-1.5 0V12a1.5 1.5 0 0 0-3 0v2.25a.75.75 0 0 1-1.5 0v-.75h-.876a2.626 2.626 0 0 1-2.625-2.625c0-.621-.504-1.125-1.125-1.125h-.125a.75.75 0 0 1 0-1.5h.125a2.625 2.625 0 0 1 2.625 2.625c0 .621.504 1.125 1.125 1.125H6.5c0-.606.18-1.17.488-1.641A4 4 0 0 1 4.373 4.8c-.484-1.623.202-3.335 1.054-3.702.772-.333 2.254.195 3.155 1.39zm2.549.02a1.4 1.4 0 0 0-.35.098 2.5 2.5 0 0 0-1 .784l-.451.598H7.834l-.45-.598a2.5 2.5 0 0 0-1.001-.784 1.4 1.4 0 0 0-.352-.099c-.063.088-.14.231-.204.429a2.5 2.5 0 0 0-.016 1.434l.163.546-.242.517c-.13.279-.21.586-.228.913l-.004.142a2.5 2.5 0 0 0 2.5 2.5h3a2.5 2.5 0 0 0 2.267-3.555l-.242-.517.163-.547a2.5 2.5 0 0 0-.016-1.433 1.6 1.6 0 0 0-.205-.429",clipRule:"evenodd"}));/**
|
|
2
2
|
* @license lucide-react v1.24.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="446" height="446" viewBox="0 0 446 446" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M226.665 18.1979H218.375C166.389 18.1979 129.23 18.2366 100.991 22.0332C73.2761 25.7594 56.8935 32.8027 44.8481 44.8481C32.8027 56.8935 25.7594 73.2761 22.0332 100.991C18.2365 129.23 18.1979 166.389 18.1979 218.375V226.665C18.1979 278.651 18.2365 315.809 22.0332 344.048C25.7594 371.764 32.8027 388.146 44.8481 400.192C56.8935 412.237 73.276 419.28 100.991 423.007C129.23 426.803 166.389 426.842 218.375 426.842H226.665C278.651 426.842 315.809 426.803 344.048 423.007C371.764 419.28 388.146 412.237 400.191 400.192C412.237 388.146 419.28 371.764 423.006 344.048C426.803 315.809 426.842 278.651 426.842 226.665V218.375C426.842 166.389 426.803 129.23 423.006 100.991C419.28 73.2761 412.237 56.8935 400.191 44.8481C388.146 32.8027 371.764 25.7594 344.048 22.0332C315.809 18.2366 278.651 18.1979 226.665 18.1979ZM31.9803 31.9803C0 63.9605 0 115.432 0 218.375V226.665C0 329.608 0 381.079 31.9803 413.059C63.9605 445.04 115.432 445.04 218.375 445.04H226.665C329.608 445.04 381.079 445.04 413.059 413.059C445.04 381.079 445.04 329.608 445.04 226.665V218.375C445.04 115.432 445.04 63.9605 413.059 31.9803C381.079 0 329.608 0 226.665 0H218.375C115.432 0 63.9605 0 31.9803 31.9803Z" fill="black"/>
|
|
3
|
+
<path d="M306.202 85.5845C276.837 85.5845 252.95 109.472 252.95 138.837V161.66H192.09V138.837C192.09 109.472 168.202 85.5845 138.837 85.5845C109.472 85.5845 85.5845 109.472 85.5845 138.837C85.5845 168.202 109.472 192.09 138.837 192.09H161.66V252.95H138.837C109.472 252.95 85.5845 276.837 85.5845 306.202C85.5845 335.568 109.472 359.455 138.837 359.455C168.202 359.455 192.09 335.568 192.09 306.202V283.38H252.95V306.202C252.95 335.568 276.837 359.455 306.202 359.455C335.567 359.455 359.455 335.568 359.455 306.202C359.455 276.837 335.567 252.95 306.202 252.95H283.38V192.09H306.202C335.567 192.09 359.455 168.202 359.455 138.837C359.455 109.472 335.567 85.5845 306.202 85.5845ZM283.38 161.66V138.837C283.38 126.209 293.574 116.015 306.202 116.015C318.831 116.015 329.025 126.209 329.025 138.837C329.025 151.466 318.831 161.66 306.202 161.66H283.38ZM138.837 161.66C126.209 161.66 116.015 151.466 116.015 138.837C116.015 126.209 126.209 116.015 138.837 116.015C151.466 116.015 161.66 126.209 161.66 138.837V161.66H138.837ZM192.09 252.95V192.09H252.95V252.95H192.09ZM306.202 329.025C293.574 329.025 283.38 318.831 283.38 306.202V283.38H306.202C318.831 283.38 329.025 293.574 329.025 306.202C329.025 318.831 318.831 329.025 306.202 329.025ZM138.837 329.025C126.209 329.025 116.015 318.831 116.015 306.202C116.015 293.574 126.209 283.38 138.837 283.38H161.66V306.202C161.66 318.831 151.466 329.025 138.837 329.025Z" fill="black"/>
|
|
4
|
+
</svg>
|
|
Binary file
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>AI Usage Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-mevy0vLr.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dt-v3FGI.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/dist/doctor.d.ts
ADDED
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function shouldUseColors() {
|
|
2
|
+
if (process.env.NO_COLOR)
|
|
3
|
+
return false;
|
|
4
|
+
if (process.env.FORCE_COLOR)
|
|
5
|
+
return true;
|
|
6
|
+
return Boolean(process.stdout.isTTY);
|
|
7
|
+
}
|
|
8
|
+
const colors = {
|
|
9
|
+
reset: '\x1b[0m',
|
|
10
|
+
bold: '\x1b[1m',
|
|
11
|
+
dim: '\x1b[2m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
yellow: '\x1b[33m',
|
|
14
|
+
red: '\x1b[31m',
|
|
15
|
+
cyan: '\x1b[36m',
|
|
16
|
+
gray: '\x1b[90m',
|
|
17
|
+
};
|
|
18
|
+
function c(color, text, enabled) {
|
|
19
|
+
if (!enabled)
|
|
20
|
+
return text;
|
|
21
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
22
|
+
}
|
|
23
|
+
export function printDoctorReport(report) {
|
|
24
|
+
const useColor = shouldUseColors();
|
|
25
|
+
console.log();
|
|
26
|
+
console.log(c('bold', `🩺 ${c('cyan', 'JUsage Doctor', useColor)} - 系统环境与数据源全面诊断`, useColor));
|
|
27
|
+
console.log(c('dim', `诊断时间: ${new Date(report.timestamp).toLocaleString()}`, useColor));
|
|
28
|
+
console.log();
|
|
29
|
+
for (const cat of report.categories) {
|
|
30
|
+
let catIcon = c('green', '[✓]', useColor);
|
|
31
|
+
if (cat.status === 'error') {
|
|
32
|
+
catIcon = c('red', '[✗]', useColor);
|
|
33
|
+
}
|
|
34
|
+
else if (cat.status === 'warn') {
|
|
35
|
+
catIcon = c('yellow', '[!]', useColor);
|
|
36
|
+
}
|
|
37
|
+
console.log(`${catIcon} ${c('bold', cat.title, useColor)}`);
|
|
38
|
+
for (const item of cat.items) {
|
|
39
|
+
let itemIcon = c('green', '✓', useColor);
|
|
40
|
+
if (item.status === 'error')
|
|
41
|
+
itemIcon = c('red', '✗', useColor);
|
|
42
|
+
else if (item.status === 'warn')
|
|
43
|
+
itemIcon = c('yellow', '!', useColor);
|
|
44
|
+
else if (item.status === 'info')
|
|
45
|
+
itemIcon = c('gray', '-', useColor);
|
|
46
|
+
console.log(` ${itemIcon} ${item.name}: ${item.message}`);
|
|
47
|
+
if (item.detail) {
|
|
48
|
+
console.log(` ${c('dim', item.detail, useColor)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
console.log();
|
|
52
|
+
}
|
|
53
|
+
// Display collectors breakdown if any
|
|
54
|
+
const detected = report.collectors.items.filter((i) => i.present);
|
|
55
|
+
const undetected = report.collectors.items.filter((i) => !i.present);
|
|
56
|
+
console.log(`${c('cyan', '📊 AI 编程工具探测详情', useColor)} ` +
|
|
57
|
+
`(${c('bold', String(detected.length), useColor)} / ${report.collectors.total} 款已就绪)`);
|
|
58
|
+
if (detected.length > 0) {
|
|
59
|
+
for (const d of detected) {
|
|
60
|
+
const hookText = d.hookStatus ? ` ${c('cyan', `[Hook: ${d.hookStatus}]`, useColor)}` : '';
|
|
61
|
+
console.log(` ${c('green', '✓', useColor)} ${d.displayName}${hookText}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.log(` ${c('yellow', '!', useColor)} 尚未检测到任何支持的 AI 工具`);
|
|
66
|
+
}
|
|
67
|
+
if (undetected.length > 0) {
|
|
68
|
+
const unNames = undetected.map((u) => u.displayName).join(', ');
|
|
69
|
+
console.log(` ${c('dim', `- 未探测到日志的工具 (${undetected.length}): ${unNames}`, useColor)}`);
|
|
70
|
+
}
|
|
71
|
+
console.log();
|
|
72
|
+
// Suggestions block if any warnings/errors
|
|
73
|
+
if (report.summary.suggestions.length > 0) {
|
|
74
|
+
console.log(c('bold', c('yellow', '💡 诊断发现以下建议项:', useColor), useColor));
|
|
75
|
+
for (const suggestion of report.summary.suggestions) {
|
|
76
|
+
console.log(` • ${suggestion}`);
|
|
77
|
+
}
|
|
78
|
+
console.log();
|
|
79
|
+
}
|
|
80
|
+
// Summary conclusion line
|
|
81
|
+
if (report.summary.status === 'ok') {
|
|
82
|
+
console.log(c('green', `🎉 诊断完成: ${report.summary.okCount} 项正常, 0 个错误, 0 个警告。所有核心组件运行良好!`, useColor));
|
|
83
|
+
}
|
|
84
|
+
else if (report.summary.status === 'warn') {
|
|
85
|
+
console.log(c('yellow', `⚠️ 诊断完成: ${report.summary.warnCount} 个提醒事项,请根据上方建议进行调整。`, useColor));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log(c('red', `❌ 诊断完成: 发现 ${report.summary.errorCount} 个异常项,请优先处理上方错误。`, useColor));
|
|
89
|
+
}
|
|
90
|
+
console.log();
|
|
91
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { dirname, join } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { appendJsonLog, BucketStore, createAggregateCache, createApplyAfterSync, createHttpServer, createLocalApiApp, createPollBackoff, DEFAULT_PORT, getHookStatus, getRunningOwner, listenServer, loadConfig, POLL_INTERVAL_MS, pollIntervalLabel, releaseRuntimeOwner, resolveLocalCollectSince, runtimeKindLabel, saveConfig, setupClaudeHook, setupCodexHook, syncAll, collectWrittenBuckets, syncLogPath, touchStatsSince, watchRuntimeSignals, watchSyncSignals, writeSyncDone, maybeUploadAfterSync, uploadToServer, kickBackfillDrain, stopBackfillDrain, drainBackfillUntilIdle, resolvePricingRefreshConfig, DEFAULT_PRICING_FIRST_FETCH_TIMEOUT_MS, startPricingRefresh, } from '@juejin-opensource/jusage-core';
|
|
4
|
-
import { DEFAULT_HOST, formatListenUrl, isWildcardListenHost, parseArgs, printHelp, resolveDaysAgo, } from './args.js';
|
|
3
|
+
import { appendJsonLog, BucketStore, createAggregateCache, createApplyAfterSync, createHttpServer, createLocalApiApp, createPollBackoff, DEFAULT_PORT, getHookStatus, getRunningOwner, listenServer, loadConfig, POLL_INTERVAL_MS, pollIntervalLabel, releaseRuntimeOwner, resolveLocalCollectSince, runtimeKindLabel, saveConfig, setupClaudeHook, setupCodexHook, syncAll, collectWrittenBuckets, syncLogPath, touchStatsSince, watchRuntimeSignals, watchSyncSignals, writeSyncDone, maybeUploadAfterSync, uploadToServer, kickBackfillDrain, stopBackfillDrain, drainBackfillUntilIdle, resolvePricingRefreshConfig, DEFAULT_PRICING_FIRST_FETCH_TIMEOUT_MS, startPricingRefresh, runDoctorDiagnostics, } from '@juejin-opensource/jusage-core';
|
|
4
|
+
import { DEFAULT_HOST, formatListenUrl, isWildcardListenHost, parseArgs, printHelp, resolveDaysAgo, resolveSyncSource, } from './args.js';
|
|
5
5
|
import { writePid } from './daemon.js';
|
|
6
|
+
import { printDoctorReport } from './doctor.js';
|
|
6
7
|
import { cmdServiceStart, cmdServiceStatus, cmdServiceStop } from './service.js';
|
|
7
8
|
export { parseArgs } from './args.js';
|
|
8
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -271,14 +272,17 @@ async function cmdStart(portArg, hostArg, daysAgo) {
|
|
|
271
272
|
console.log(`\n按 Ctrl+C 停止\n`);
|
|
272
273
|
}
|
|
273
274
|
async function cmdSync(source) {
|
|
275
|
+
// Reject unknown sources before touching config/log/lastSync state, so a
|
|
276
|
+
// typo exits non-zero instead of refreshing "上次同步" with zero work done.
|
|
277
|
+
const filter = resolveSyncSource(source);
|
|
274
278
|
const { dir, config } = await loadConfig();
|
|
275
279
|
await touchStatsSince(dir, config);
|
|
276
|
-
const scope =
|
|
280
|
+
const scope = filter ?? 'all';
|
|
277
281
|
const started = Date.now();
|
|
278
282
|
const logPath = syncLogPath(dir);
|
|
279
283
|
await appendJsonLog(logPath, { event: 'start', source: scope });
|
|
280
284
|
try {
|
|
281
|
-
const results = await syncAll(dir, config,
|
|
285
|
+
const results = await syncAll(dir, config, filter);
|
|
282
286
|
await writeSyncDone(dir);
|
|
283
287
|
await maybeUploadAfterSync(dir, config, collectWrittenBuckets(results));
|
|
284
288
|
await appendJsonLog(logPath, {
|
|
@@ -290,9 +294,15 @@ async function cmdSync(source) {
|
|
|
290
294
|
eventsParsed: r.eventsParsed,
|
|
291
295
|
bucketsWritten: r.bucketsWritten,
|
|
292
296
|
filesProcessed: r.filesProcessed,
|
|
297
|
+
...(r.skipped ? { skipped: true } : {}),
|
|
298
|
+
...(r.error ? { error: r.error } : {}),
|
|
293
299
|
})),
|
|
294
300
|
});
|
|
295
301
|
for (const r of results) {
|
|
302
|
+
if (r.skipped) {
|
|
303
|
+
console.log(`${r.source}: 跳过(${r.error ?? '无数据'})`);
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
296
306
|
console.log(`${r.source}: ${r.eventsParsed} 条消息, ${r.bucketsWritten} 个桶写入, ${r.filesProcessed} 个文件`);
|
|
297
307
|
}
|
|
298
308
|
}
|
|
@@ -335,6 +345,10 @@ async function cmdStatus() {
|
|
|
335
345
|
console.log(`上次上报: ${config.lastUploadAt ?? '从未'}`);
|
|
336
346
|
console.log(`调试日志: ${join(dir, 'logs')}`);
|
|
337
347
|
}
|
|
348
|
+
async function cmdDoctor(port) {
|
|
349
|
+
const report = await runDoctorDiagnostics({ port });
|
|
350
|
+
printDoctorReport(report);
|
|
351
|
+
}
|
|
338
352
|
async function cmdUpload(force = false, reconcile = false) {
|
|
339
353
|
const { dir, config } = await loadConfig();
|
|
340
354
|
await touchStatsSince(dir, config);
|
|
@@ -421,6 +435,9 @@ async function main() {
|
|
|
421
435
|
case 'status':
|
|
422
436
|
await cmdStatus();
|
|
423
437
|
break;
|
|
438
|
+
case 'doctor':
|
|
439
|
+
await cmdDoctor(port);
|
|
440
|
+
break;
|
|
424
441
|
case 'upload':
|
|
425
442
|
await cmdUpload(force, reconcile);
|
|
426
443
|
break;
|
package/dist/service-linux.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
|
-
import { dirname, join } from 'node:path';
|
|
3
|
+
import { dirname, join, posix } from 'node:path';
|
|
4
4
|
import { mkdir, unlink, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { daemonLogPath, ensureDaemonLogDir, resolveServiceCommand } from './daemon.js';
|
|
@@ -15,9 +15,11 @@ export function linuxUnitPath() {
|
|
|
15
15
|
}
|
|
16
16
|
function defaultPath(nodePath, home) {
|
|
17
17
|
const parts = [
|
|
18
|
-
|
|
18
|
+
// The unit file is consumed by systemd, so every path in it is POSIX no
|
|
19
|
+
// matter which platform composed the string.
|
|
20
|
+
posix.dirname(nodePath),
|
|
19
21
|
'/usr/local/bin',
|
|
20
|
-
join(home, '.local', 'bin'),
|
|
22
|
+
posix.join(home, '.local', 'bin'),
|
|
21
23
|
'/usr/bin',
|
|
22
24
|
'/bin',
|
|
23
25
|
'/usr/sbin',
|
package/dist/service-windows.js
CHANGED
|
@@ -36,7 +36,11 @@ Start-ScheduledTask -TaskName $taskName
|
|
|
36
36
|
`;
|
|
37
37
|
const result = runPowerShell(script);
|
|
38
38
|
if (!result.ok) {
|
|
39
|
-
|
|
39
|
+
const raw = result.stderr || result.stdout || 'PowerShell 返回非零';
|
|
40
|
+
if (/0x80070005|拒绝访问|Access is denied|PermissionDenied/i.test(raw)) {
|
|
41
|
+
throw new Error('注册 Windows 开机自启需要管理员权限:请右键「以管理员身份运行」终端后重新执行 `jusage service start`(服务已在运行时会自动补注册自启);或改用 `jusage start` 前台运行(无开机自启)');
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`注册 Windows 开机自启失败: ${raw}`);
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
46
|
export async function unregisterWindowsAutostart() {
|
package/dist/service.js
CHANGED
|
@@ -43,6 +43,23 @@ async function unregisterAutostart() {
|
|
|
43
43
|
}
|
|
44
44
|
await unregisterLinuxAutostart();
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Re-register autostart while the service is already running.
|
|
48
|
+
* On failure warn and continue (the running service is unaffected), so a
|
|
49
|
+
* non-elevated Windows terminal does not abort `service start`.
|
|
50
|
+
*/
|
|
51
|
+
async function registerAutostartOrWarn(cliBinPath, dataDir) {
|
|
52
|
+
try {
|
|
53
|
+
await registerAutostart(cliBinPath, dataDir);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
console.warn(` ⚠️ 开机自启注册失败: ${message}`);
|
|
59
|
+
console.warn(' 服务运行不受影响;如需开机自启,请修复上述问题后重新执行 `jusage service start`。');
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
46
63
|
export async function cmdServiceStart(cliBinPath, daysAgo, listen) {
|
|
47
64
|
assertSupportedPlatform();
|
|
48
65
|
const startedAt = Date.now();
|
|
@@ -74,8 +91,10 @@ async function cmdServiceStartBody(cliBinPath, daysAgo, listen) {
|
|
|
74
91
|
const who = runtimeKindLabel(existing.kind);
|
|
75
92
|
const registered = await isAutostartRegistered();
|
|
76
93
|
if (!registered) {
|
|
77
|
-
await
|
|
78
|
-
console.log(
|
|
94
|
+
const autostartRegistered = await registerAutostartOrWarn(cliBinPath, dir);
|
|
95
|
+
console.log(autostartRegistered
|
|
96
|
+
? `服务已在运行(${who} pid ${existing.pid}),已补注册开机自启`
|
|
97
|
+
: `服务已在运行(${who} pid ${existing.pid},开机自启未注册)`);
|
|
79
98
|
}
|
|
80
99
|
else {
|
|
81
100
|
console.log(`服务已在运行(${who} pid ${existing.pid})`);
|