tokentracker-cli 0.63.1 → 0.64.1

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.
Files changed (50) hide show
  1. package/dashboard/dist/assets/{ActivityHeatmap-3rWViAnK.js → ActivityHeatmap-WJZDXbwS.js} +1 -1
  2. package/dashboard/dist/assets/{Card-CjtoUN-V.js → Card-BLMSo0Yk.js} +1 -1
  3. package/dashboard/dist/assets/DashboardPage-B6riL6Zc.js +19 -0
  4. package/dashboard/dist/assets/{DevicePage-DWgc0ITo.js → DevicePage-DB89vSmn.js} +1 -1
  5. package/dashboard/dist/assets/{DialogTitle-BOWoDnVq.js → DialogTitle-B1RHm8WW.js} +1 -1
  6. package/dashboard/dist/assets/{FadeIn-CK1EopuS.js → FadeIn-7JSzFnw8.js} +1 -1
  7. package/dashboard/dist/assets/{HeaderGithubStar-C1CldHWg.js → HeaderGithubStar-BLtS5CM-.js} +1 -1
  8. package/dashboard/dist/assets/{IpCheckPage-DKiEo4LO.js → IpCheckPage-Bd-0YOCq.js} +1 -1
  9. package/dashboard/dist/assets/{LandingPage-BCzXJP9I.js → LandingPage-2EhY8k2J.js} +1 -1
  10. package/dashboard/dist/assets/{LeaderboardAvatar-Dw-KfosP.js → LeaderboardAvatar-CsPY9Amf.js} +1 -1
  11. package/dashboard/dist/assets/{LeaderboardPage-XQBrmlgA.js → LeaderboardPage-DC76VQpf.js} +3 -3
  12. package/dashboard/dist/assets/{LeaderboardProfileModal-8xPG0MRj.js → LeaderboardProfileModal-C6fllhU2.js} +1 -1
  13. package/dashboard/dist/assets/{LeaderboardProfilePage-DHa73U-g.js → LeaderboardProfilePage-C42UiGkG.js} +3 -3
  14. package/dashboard/dist/assets/{LimitsPage-BTF8cZ-P.js → LimitsPage-CwxWe18U.js} +1 -1
  15. package/dashboard/dist/assets/{LocalOnlyNotice-BqLH4XMA.js → LocalOnlyNotice-CWBhqZ0X.js} +1 -1
  16. package/dashboard/dist/assets/{LoginPage-OZf1-OnV.js → LoginPage-Dw0rFhaO.js} +1 -1
  17. package/dashboard/dist/assets/{PopoverPopup-BQ03eBHT.js → PopoverPopup-D5d98dJF.js} +1 -1
  18. package/dashboard/dist/assets/{ResetPasswordPage-CqSU4VnK.js → ResetPasswordPage-Ca1vYCmL.js} +1 -1
  19. package/dashboard/dist/assets/{Select-C2miulxl.js → Select-TG8sTI5Z.js} +1 -1
  20. package/dashboard/dist/assets/{SelectItemText-CvU6qFNt.js → SelectItemText-ChAwxrlu.js} +1 -1
  21. package/dashboard/dist/assets/SettingsPage-CHO9pTCC.js +1 -0
  22. package/dashboard/dist/assets/{SkillsPage-DKHdur0w.js → SkillsPage-D4gqRDz5.js} +1 -1
  23. package/dashboard/dist/assets/{WidgetsPage-Dh_FKo1H.js → WidgetsPage-B4hDqpOL.js} +1 -1
  24. package/dashboard/dist/assets/{WrappedPage-BIdXJTOA.js → WrappedPage-_5A_J24M.js} +1 -1
  25. package/dashboard/dist/assets/{agent-logos-CWBw3t4a.js → agent-logos-BxXu3XPn.js} +1 -1
  26. package/dashboard/dist/assets/{arrow-up-right-D1Qv9-hJ.js → arrow-up-right-B1VUIoVh.js} +1 -1
  27. package/dashboard/dist/assets/{download-9hc1LZwP.js → download-D6ma9Qrl.js} +1 -1
  28. package/dashboard/dist/assets/{info-Bw9sw3vW.js → info-K9Ps997U.js} +1 -1
  29. package/dashboard/dist/assets/{main-BN1NzjX3.js → main-CnThe5nE.js} +30 -13
  30. package/dashboard/dist/assets/main-DEU_X1Ba.css +1 -0
  31. package/dashboard/dist/assets/{use-limits-display-prefs-CpHg_a82.js → use-limits-display-prefs-lH7AACmv.js} +1 -1
  32. package/dashboard/dist/assets/{use-native-settings-BCMRmnLD.js → use-native-settings-C43_rEQP.js} +1 -1
  33. package/dashboard/dist/assets/use-quality-per-dollar-pref-DsVwHWvg.js +1 -0
  34. package/dashboard/dist/assets/{use-usage-limits-CVu3Jff0.js → use-usage-limits-D6QquT0m.js} +1 -1
  35. package/dashboard/dist/assets/{useCurrency-3hjYtt-n.js → useCurrency-CCGK2Rdz.js} +1 -1
  36. package/dashboard/dist/assets/{useScrollLock-BNfQujzc.js → useScrollLock-BtA-ptIe.js} +1 -1
  37. package/dashboard/dist/index.html +2 -2
  38. package/dashboard/dist/share.html +2 -2
  39. package/package.json +4 -2
  40. package/src/lib/local-api.js +25 -0
  41. package/src/lib/opencode-go-limits.js +253 -20
  42. package/src/lib/outcomes-engine.js +230 -0
  43. package/src/lib/pricing/curated-overrides.json +4 -0
  44. package/src/lib/pricing/seed-snapshot.json +1 -1
  45. package/src/lib/sqlite-reader.js +59 -0
  46. package/src/lib/usage-limits.js +4 -4
  47. package/dashboard/dist/assets/DashboardPage-C8Zm5caR.js +0 -19
  48. package/dashboard/dist/assets/SettingsPage-DYiO30s5.js +0 -1
  49. package/dashboard/dist/assets/main-iuBgdxqX.css +0 -1
  50. package/dashboard/dist/assets/pencil-C8mN_ljR.js +0 -1
@@ -1 +1 @@
1
- import{c as _t,cM as Xe,cG as Dt,b7 as Ot,b5 as H,b8 as wt,bE as U,cN as Ct,ch as je,j as Se,cm as ze,r as g,bC as V,co as ot,cO as Gt,b9 as it,bB as Le,c6 as Kt,cn as ct,cP as xt,bG as x,bF as ke,c1 as he,cQ as Ve,cR as le,cs as ae,bK as C,bL as Ut,cF as It,cJ as Je,c7 as Xt,bY as ut,bT as lt,bV as Vt,cS as qt,bH as be,bX as $t,cA as jt,b as Pe,bQ as zt,cT as Qe,bc as Ye,cU as Jt,cV as He,bN as Qt,bA as We,bO as Zt,bD as Ie,cd as _e,cc as en,cW as tn,ca as nn,bM as rn,bR as Te,cX as me,bf as sn,bg as on,bb as De,cY as cn,cZ as at,cD as un,ci as Ze}from"./main-BN1NzjX3.js";const ln=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],zn=_t("check",ln);function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function an(e){e.preventDefault(),e.stopPropagation()}function fn(e){return"nativeEvent"in e}function dn(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function pn(e){return Dt?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function Jn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function gn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(hn,e).current;return t.next=e,H(t.effect),t}function hn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Ne=0;function Ge(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Ne);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Ne=i,()=>{Ne===i&&(cancelAnimationFrame(i),Ne=0)}}const Ke={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ue=0;function mn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{je(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function bn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],W=[];if(o){const b=Ke[o],T=mn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),Q=E!==null&&E!=="false",B=(b.get(y)||0)+1;b.set(y,B),k.push(y),B===1&&Q&&T.add(y),Q||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),W.push(b),T===1&&b.setAttribute(dt,"")}),Ue+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&W.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ue-=1,Ue||(Ke.inert=new WeakMap,Ke["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=U(e[0]).body;return bn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class En{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function Qn(e){const t=ze(),n=tt(e),r=et();return H(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function Zn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function er(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new En).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function yn(e,t){const n=Ye(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&je(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function Rn(e){return e?Qe(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=Jt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Qe(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function tr(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:W,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:Q,dataRef:B}=P.context,q=V(()=>B.current.floatingContext?.nodeId),J=s===!1,D=ot(y)&&J,se=Ae(s),F=Ae(o),$=Ae(f),ve=Ae(_),N=tt(T),R=Gt(),Y=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),j=it(ye,R?.afterInsideRef),ie=Le(),ce=Le(),Oe=Kt(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Z=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(L){L.key==="Tab"&&C(p,ae(U(p)))&&ne().length===0&&!D&&an(L)}const I=U(p);return x(I,"keydown",m)},[r,p,u,D,ne]),g.useEffect(()=>{if(r||!_)return;const m=U(p);function I(){ee.current=!1}function L(z){const a=be(z),O=Z(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${$t}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function G(){de.current="keyboard"}return ke(x(m,"pointerdown",L,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",G,!0),I)},[r,E,y,p,_,R,ce,Z]),g.useEffect(()=>{if(r||!h)return;const m=U(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function L(O){const d=be(O);Qe(d)&&(te.current=d)}function G(O){const d=O.relatedTarget,M=O.currentTarget,K=be(O);u&&d==null&&K!=null&&C(E,K)&&Et(K),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Z(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(W),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||N&&(Fe(N.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(N.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!jt(K)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(B.current.insideReactTree){B.current.insideReactTree=!1;return}(D||!u)&&d&&X&&!oe.current&&(D||d!==yt())&&(Y.current=!0,P.setOpen(!1,Pe(zt,O)))})}function z(){ee.current||(B.current.insideReactTree=!0,ie.start(0,()=>{B.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",G),a&&x(a,"pointerdown",I),E&&x(E,"focusin",L),E&&x(E,"focusout",G),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,N,R,P,h,i,ne,D,q,B,ie,ce,Oe,k,W,Z]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),L=(N?ft(N.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Z()],L,le(W),le(k),D?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||D,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,D,N,q,k,W,Z]),H(()=>{if(!_||r||!he(p))return;const m=U(p),I=ae(m);queueMicrotask(()=>{const L=se.current,G=typeof L=="function"?L($.current||""):L;if(G===void 0||G===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;G===!0||G===null?d=O():d=le(G),d=d||O();const M=C(p,ae(m));Ge(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const K=ae(m);return!(K!==d&&C(p,K))}})})},[r,_,p,ne,se,$,ve]),H(()=>{if(r||!p)return;const m=U(p),I=ae(m),L=$.current==null;Et(I);function G(a){if(a.open||(Ee.current=yn(a.nativeEvent,de.current)),a.reason===Ut&&a.nativeEvent.type==="mouseleave"&&(Y.current=!0),a.reason===It)if(a.nested)Y.current=!1;else if(dn(a.nativeEvent)||pn(a.nativeEvent))Y.current=!1;else{let O=!1;U(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?Y.current=!1:Y.current=!0}}Q.on("openchange",G);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&je(I)!=="body"?I:null;let K=L?M||d:d||M;return K||(K=yt()||null),typeof O=="boolean"?K:le(O)||K||null}return()=>{Q.off("openchange",G);const a=ae(m),O=Z(),d=C(E,a)||O.some(w=>w===a||C(w,a))||N&&Fe(N.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,K=z();queueMicrotask(()=>{const w=Rn(K),Re=typeof M!="boolean";M&&!Y.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),Y.current=!1})}},[r,E,p,F,$,Q,N,y,q,Z]),H(()=>{if(!Je||_||!E)return;const m=ae(U(E));!he(m)||!Xt(m)||C(E,m)&&m.blur()},[_,E]),H(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),H(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!D:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();Ge(I[I.length-1])}else R?.portalNode&&(Y.current=!1,lt(m,R.portalNode)?Vt(y)?.focus():le(W??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:j,onFocus:m=>{u?Ge(ne()[0]):R?.portalNode&&(h&&(Y.current=!0),lt(m,R.portalNode)?qt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function Tn(){return!1}function Sn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function nr(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=Tn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),W=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:Q}=Sn(u),B=g.useRef(!1),q=g.useRef(!1),J=g.useRef(!1),D=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),$=Le(),ve=Le(),N=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const j=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,j):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),Y=V(S=>He(S,f.select("floatingElement"))||He(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Qt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||D.current||!E&&R("__escapeKeyBubbles"))return;const j=fn(S)?S.nativeEvent:S,ie=Pe(Zt,j);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,N)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const j=be(S.nativeEvent);C(f.select("floatingElement"),j)&&(B.current||(B.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&B.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=Q;const S=new We,j=new We;function ie(){S.clear(),D.current=!0}function ce(){S.start(Je?5:0,()=>{D.current=!1})}function Oe(){J.current=!0,j.start(0,()=>{J.current=!1})}function Me(){B.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Z(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>He(c,v.context?.elements.floating));return Y(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!Y(c)&&(j.clear(),J.current=!1),N();return}if(b.current.insideReactTree){N();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:U(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=en(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!tn(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),Be=nn(l),st=/auto|scroll/,At=re||st.test(Be.overflowX),Nt=re||st.test(Be.overflowY),Lt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Wt=Nt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Yt=Be.direction==="rtl",Bt=Wt&&(Yt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Ht=Lt&&c.offsetY>l.clientHeight;if(Bt||Ht)return}if(!Z(c)){if(p()==="intentional"&&J.current){j.clear(),J.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),N())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||Y(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||Y(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},$.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function L(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function G(c){se.current="touch",L(c,I)}function z(c){$.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&L(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!B.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Z(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||(j.clear(),J.current=!0,N())}}}function O(c){if(p()!=="sloppy"||!F.current||Y(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),$.clear(),F.current=null)}function d(c){L(c,O)}function M(c){p()!=="sloppy"||!F.current||Y(c)||(F.current.dismissOnTouchEnd&&ge(c),$.clear(),F.current=null)}function K(c){L(c,M)}const w=U(W),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",G,!0),x(w,"touchmove",d,!0),x(w,"touchend",K,!0)));return()=>{Re(),S.clear(),j.clear(),Me(),J.current=!1}},[b,W,r,_,P,k,n,E,Q,ee,N,y,R,Y,T,f,$]),g.useEffect(N,[P,N]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function vn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const On={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class wn extends rn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},On),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&gn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function Cn(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,W=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new wn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:W,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),H(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=W,T.context.nested=o,T}function xn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),H(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),H(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),H(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const rr={tabIndex:-1,[cn]:""};function sr(e){return t=>t==="touch"?e.current:!0}function or(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return Cn({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function In(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function ir(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function cr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function ur(e,t,n,r){vn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function lr(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=In(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return H(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function ar(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");H(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,W]=f.value;i.activeTriggerId=k,i.activeTriggerElement=W}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function fr(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=xn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function dr(e,t){e.useSyncedValues(t),H(()=>()=>{e.update({activeTriggerProps:De,inactiveTriggerProps:De,popupProps:De})},[e])}function pr(e,t){H(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),H(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class gr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),$e=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const kn={[$e.popupOpen]:""},Pn={[$e.popupOpen]:"",[$e.pressed]:""},Fn={[rt.open]:""},Mn={[rt.closed]:""},An={[rt.anchorHidden]:""},hr={open(e){return e?kn:null}},mr={open(e){return e?Pn:null}},br={open(e){return e?Fn:Mn},anchorHidden(e){return e?An:null}};function Er(e){return ze(e,"base-ui")}const Nn="ArrowUp",Ln="ArrowDown",Wn="ArrowLeft",Yn="ArrowRight",Bn="Home",Hn="End",_n=new Set([Wn,Yn]),Dn=new Set([Nn,Ln]),Gn=new Set([..._n,...Dn]),yr=new Set([...Gn,Bn,Hn]),Rr=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Kn(e){if(typeof document>"u")return!1;const t=U(e);return Ye(t).innerWidth-t.documentElement.clientWidth>0}function Un(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=U(e),r=n.documentElement,s=n.body,o=Ze(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Xn(e){const t=U(e),n=t.documentElement,r=t.body,s=Ze(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Vn(e){const t=U(e),n=t.documentElement,r=t.body,s=Ye(n);let o=0,i=0,u=!1;const h=me.create();if(Je&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,Q=n.scrollWidth>n.clientWidth,B=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",J=Math.max(0,s.innerWidth-r.clientWidth),D=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),$=Ze(n)?n:r;if(u=Un(e),u){n.style.scrollbarGutter=y,$.style.overflowY="hidden",$.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||B)&&(n.style.overflowY="scroll"),(Q||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||D?`calc(100dvh - ${se+D}px)`:"100dvh",width:F||J?`calc(100vw - ${F+J}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function W(){k(),h.request(f)}f();const b=x(s,"resize",W);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class qn{lockCount=0;restore=null;timeoutLock=We.create();timeoutUnlock=We.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=U(t).documentElement,s=Ye(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=un||!Kn(t);this.restore=o?Xn(t):Vn(t)}}const $n=new qn;function Tr(e=!0,t=null){H(()=>{if(e)return $n.acquire(t)},[e,t])}export{wn as A,Ge as B,zn as C,an as D,dn as E,er as F,pn as G,vn as H,Rr as I,Tr as J,rt as K,gr as P,xn as a,tt as b,et as c,Ae as d,cr as e,or as f,Fe as g,ur as h,Jn as i,pr as j,ar as k,fr as l,nr as m,rr as n,dr as o,lr as p,mr as q,Qn as r,ir as s,hr as t,Er as u,Zn as v,sr as w,tr as x,yr as y,br as z};
1
+ import{c as _t,cN as Xe,cH as Gt,b8 as Ot,b6 as H,b9 as wt,bF as K,cO as Ct,ci as $e,j as Se,cn as ze,r as g,bD as V,cp as ot,cP as Dt,ba as it,bC as We,c7 as Ut,co as ct,cQ as xt,bH as x,bG as ke,c2 as he,cR as Ve,cS as le,ct as ae,bL as C,bM as Kt,cG as It,cK as Ze,c8 as Xt,bZ as ut,bU as lt,bW as Vt,cT as qt,bI as be,bY as jt,cB as $t,b as Pe,bR as zt,cU as Je,bd as Be,cV as Zt,cW as He,bO as Jt,bB as Le,bP as Qt,bE as Ie,ce as _e,cd as en,cX as tn,cb as nn,bN as rn,bS as Te,cY as me,bg as sn,bh as on,bc as Ge,cZ as cn,c_ as at,cE as un,cj as Qe}from"./main-CnThe5nE.js";const ln=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],zn=_t("check",ln);function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function an(e){e.preventDefault(),e.stopPropagation()}function fn(e){return"nativeEvent"in e}function dn(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function pn(e){return Gt?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function Zn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function gn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(hn,e).current;return t.next=e,H(t.effect),t}function hn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Ne=0;function De(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Ne);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Ne=i,()=>{Ne===i&&(cancelAnimationFrame(i),Ne=0)}}const Ue={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ke=0;function mn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{$e(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function bn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],L=[];if(o){const b=Ue[o],T=mn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),J=E!==null&&E!=="false",Y=(b.get(y)||0)+1;b.set(y,Y),k.push(y),Y===1&&J&&T.add(y),J||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),L.push(b),T===1&&b.setAttribute(dt,"")}),Ke+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&L.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ke-=1,Ke||(Ue.inert=new WeakMap,Ue["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=K(e[0]).body;return bn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class En{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function Jn(e){const t=ze(),n=tt(e),r=et();return H(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function Qn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function er(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new En).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function yn(e,t){const n=Be(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&$e(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function Rn(e){return e?Je(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=Zt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Je(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function tr(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:L,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:J,dataRef:Y}=P.context,q=V(()=>Y.current.floatingContext?.nodeId),Z=s===!1,G=ot(y)&&Z,se=Ae(s),F=Ae(o),j=Ae(f),ve=Ae(_),N=tt(T),R=Dt(),B=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),$=it(ye,R?.afterInsideRef),ie=We(),ce=We(),Oe=Ut(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Q=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(W){W.key==="Tab"&&C(p,ae(K(p)))&&ne().length===0&&!G&&an(W)}const I=K(p);return x(I,"keydown",m)},[r,p,u,G,ne]),g.useEffect(()=>{if(r||!_)return;const m=K(p);function I(){ee.current=!1}function W(z){const a=be(z),O=Q(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${jt}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function D(){de.current="keyboard"}return ke(x(m,"pointerdown",W,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",D,!0),I)},[r,E,y,p,_,R,ce,Q]),g.useEffect(()=>{if(r||!h)return;const m=K(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function W(O){const d=be(O);Je(d)&&(te.current=d)}function D(O){const d=O.relatedTarget,M=O.currentTarget,U=be(O);u&&d==null&&U!=null&&C(E,U)&&Et(U),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Q(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(L),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||N&&(Fe(N.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(N.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!$t(U)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(Y.current.insideReactTree){Y.current.insideReactTree=!1;return}(G||!u)&&d&&X&&!oe.current&&(G||d!==yt())&&(B.current=!0,P.setOpen(!1,Pe(zt,O)))})}function z(){ee.current||(Y.current.insideReactTree=!0,ie.start(0,()=>{Y.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",D),a&&x(a,"pointerdown",I),E&&x(E,"focusin",W),E&&x(E,"focusout",D),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,N,R,P,h,i,ne,G,q,Y,ie,ce,Oe,k,L,Q]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),W=(N?ft(N.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Q()],W,le(L),le(k),G?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||G,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,G,N,q,k,L,Q]),H(()=>{if(!_||r||!he(p))return;const m=K(p),I=ae(m);queueMicrotask(()=>{const W=se.current,D=typeof W=="function"?W(j.current||""):W;if(D===void 0||D===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;D===!0||D===null?d=O():d=le(D),d=d||O();const M=C(p,ae(m));De(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const U=ae(m);return!(U!==d&&C(p,U))}})})},[r,_,p,ne,se,j,ve]),H(()=>{if(r||!p)return;const m=K(p),I=ae(m),W=j.current==null;Et(I);function D(a){if(a.open||(Ee.current=yn(a.nativeEvent,de.current)),a.reason===Kt&&a.nativeEvent.type==="mouseleave"&&(B.current=!0),a.reason===It)if(a.nested)B.current=!1;else if(dn(a.nativeEvent)||pn(a.nativeEvent))B.current=!1;else{let O=!1;K(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?B.current=!1:B.current=!0}}J.on("openchange",D);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&$e(I)!=="body"?I:null;let U=W?M||d:d||M;return U||(U=yt()||null),typeof O=="boolean"?U:le(O)||U||null}return()=>{J.off("openchange",D);const a=ae(m),O=Q(),d=C(E,a)||O.some(w=>w===a||C(w,a))||N&&Fe(N.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,U=z();queueMicrotask(()=>{const w=Rn(U),Re=typeof M!="boolean";M&&!B.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),B.current=!1})}},[r,E,p,F,j,J,N,y,q,Q]),H(()=>{if(!Ze||_||!E)return;const m=ae(K(E));!he(m)||!Xt(m)||C(E,m)&&m.blur()},[_,E]),H(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),H(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!G:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();De(I[I.length-1])}else R?.portalNode&&(B.current=!1,lt(m,R.portalNode)?Vt(y)?.focus():le(L??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:$,onFocus:m=>{u?De(ne()[0]):R?.portalNode&&(h&&(B.current=!0),lt(m,R.portalNode)?qt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function Tn(){return!1}function Sn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function nr(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=Tn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),L=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:J}=Sn(u),Y=g.useRef(!1),q=g.useRef(!1),Z=g.useRef(!1),G=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),j=We(),ve=We(),N=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const $=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,$):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),B=V(S=>He(S,f.select("floatingElement"))||He(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Jt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||G.current||!E&&R("__escapeKeyBubbles"))return;const $=fn(S)?S.nativeEvent:S,ie=Pe(Qt,$);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,N)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const $=be(S.nativeEvent);C(f.select("floatingElement"),$)&&(Y.current||(Y.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&Y.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=J;const S=new Le,$=new Le;function ie(){S.clear(),G.current=!0}function ce(){S.start(Ze?5:0,()=>{G.current=!1})}function Oe(){Z.current=!0,$.start(0,()=>{Z.current=!1})}function Me(){Y.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Q(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>He(c,v.context?.elements.floating));return B(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!B(c)&&($.clear(),Z.current=!1),N();return}if(b.current.insideReactTree){N();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:K(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=en(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!tn(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),Ye=nn(l),st=/auto|scroll/,At=re||st.test(Ye.overflowX),Nt=re||st.test(Ye.overflowY),Wt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Lt=Nt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Bt=Ye.direction==="rtl",Yt=Lt&&(Bt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Ht=Wt&&c.offsetY>l.clientHeight;if(Yt||Ht)return}if(!Q(c)){if(p()==="intentional"&&Z.current){$.clear(),Z.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),N())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||B(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||B(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},j.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function W(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function D(c){se.current="touch",W(c,I)}function z(c){j.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&W(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!Y.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Q(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||($.clear(),Z.current=!0,N())}}}function O(c){if(p()!=="sloppy"||!F.current||B(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),j.clear(),F.current=null)}function d(c){W(c,O)}function M(c){p()!=="sloppy"||!F.current||B(c)||(F.current.dismissOnTouchEnd&&ge(c),j.clear(),F.current=null)}function U(c){W(c,M)}const w=K(L),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",D,!0),x(w,"touchmove",d,!0),x(w,"touchend",U,!0)));return()=>{Re(),S.clear(),$.clear(),Me(),Z.current=!1}},[b,L,r,_,P,k,n,E,J,ee,N,y,R,B,T,f,j]),g.useEffect(N,[P,N]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function vn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const On={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class wn extends rn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},On),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&gn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function Cn(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,L=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new wn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:L,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),H(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=L,T.context.nested=o,T}function xn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),H(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),H(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),H(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const rr={tabIndex:-1,[cn]:""};function sr(e){return t=>t==="touch"?e.current:!0}function or(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return Cn({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function In(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function ir(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function cr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function ur(e,t,n,r){vn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function lr(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=In(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return H(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function ar(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");H(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,L]=f.value;i.activeTriggerId=k,i.activeTriggerElement=L}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function fr(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=xn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function dr(e,t){e.useSyncedValues(t),H(()=>()=>{e.update({activeTriggerProps:Ge,inactiveTriggerProps:Ge,popupProps:Ge})},[e])}function pr(e,t){H(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),H(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class gr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),je=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const kn={[je.popupOpen]:""},Pn={[je.popupOpen]:"",[je.pressed]:""},Fn={[rt.open]:""},Mn={[rt.closed]:""},An={[rt.anchorHidden]:""},hr={open(e){return e?kn:null}},mr={open(e){return e?Pn:null}},br={open(e){return e?Fn:Mn},anchorHidden(e){return e?An:null}};function Er(e){return ze(e,"base-ui")}const Nn="ArrowUp",Wn="ArrowDown",Ln="ArrowLeft",Bn="ArrowRight",Yn="Home",Hn="End",_n=new Set([Ln,Bn]),Gn=new Set([Nn,Wn]),Dn=new Set([..._n,...Gn]),yr=new Set([...Dn,Yn,Hn]),Rr=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Un(e){if(typeof document>"u")return!1;const t=K(e);return Be(t).innerWidth-t.documentElement.clientWidth>0}function Kn(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=K(e),r=n.documentElement,s=n.body,o=Qe(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Xn(e){const t=K(e),n=t.documentElement,r=t.body,s=Qe(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Vn(e){const t=K(e),n=t.documentElement,r=t.body,s=Be(n);let o=0,i=0,u=!1;const h=me.create();if(Ze&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,J=n.scrollWidth>n.clientWidth,Y=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",Z=Math.max(0,s.innerWidth-r.clientWidth),G=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),j=Qe(n)?n:r;if(u=Kn(e),u){n.style.scrollbarGutter=y,j.style.overflowY="hidden",j.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||Y)&&(n.style.overflowY="scroll"),(J||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||G?`calc(100dvh - ${se+G}px)`:"100dvh",width:F||Z?`calc(100vw - ${F+Z}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function L(){k(),h.request(f)}f();const b=x(s,"resize",L);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class qn{lockCount=0;restore=null;timeoutLock=Le.create();timeoutUnlock=Le.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=K(t).documentElement,s=Be(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=un||!Un(t);this.restore=o?Xn(t):Vn(t)}}const jn=new qn;function Tr(e=!0,t=null){H(()=>{if(e)return jn.acquire(t)},[e,t])}export{wn as A,De as B,zn as C,an as D,dn as E,er as F,pn as G,vn as H,Rr as I,Tr as J,rt as K,gr as P,xn as a,tt as b,et as c,Ae as d,cr as e,or as f,Fe as g,ur as h,Zn as i,pr as j,ar as k,fr as l,nr as m,rr as n,dr as o,lr as p,mr as q,Jn as r,ir as s,hr as t,Er as u,Qn as v,sr as w,tr as x,yr as y,br as z};
@@ -235,8 +235,8 @@
235
235
  ]
236
236
  }
237
237
  </script>
238
- <script type="module" crossorigin src="/assets/main-BN1NzjX3.js"></script>
239
- <link rel="stylesheet" crossorigin href="/assets/main-iuBgdxqX.css">
238
+ <script type="module" crossorigin src="/assets/main-CnThe5nE.js"></script>
239
+ <link rel="stylesheet" crossorigin href="/assets/main-DEU_X1Ba.css">
240
240
  </head>
241
241
  <body>
242
242
  <main class="aeo-seed-content" aria-label="Token Tracker AI-readable summary">
@@ -75,8 +75,8 @@
75
75
  "description": "Shareable Token Tracker dashboard snapshot."
76
76
  }
77
77
  </script>
78
- <script type="module" crossorigin src="/assets/main-BN1NzjX3.js"></script>
79
- <link rel="stylesheet" crossorigin href="/assets/main-iuBgdxqX.css">
78
+ <script type="module" crossorigin src="/assets/main-CnThe5nE.js"></script>
79
+ <link rel="stylesheet" crossorigin href="/assets/main-DEU_X1Ba.css">
80
80
  </head>
81
81
  <body>
82
82
  <main class="aeo-seed-content" aria-label="Token Tracker share page summary">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokentracker-cli",
3
- "version": "0.63.1",
3
+ "version": "0.64.1",
4
4
  "description": "Token usage tracker for AI agent CLIs (Claude Code, Codex, Cursor, Gemini, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, pi, Craft Agents, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Mimo, ZCode)",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
@@ -38,7 +38,9 @@
38
38
  "validate:copy": "node scripts/validate-copy-registry.cjs",
39
39
  "validate:guardrails": "node scripts/validate-architecture-guardrails.cjs",
40
40
  "validate:retros": "node scripts/validate-retros.cjs",
41
- "validate:ui-hardcode": "node scripts/ops/validate-ui-hardcode.cjs"
41
+ "validate:ui-hardcode": "node scripts/ops/validate-ui-hardcode.cjs",
42
+ "sync-versions": "node scripts/sync-versions.cjs",
43
+ "version": "node scripts/sync-versions.cjs && git add TokenTrackerBar/project.yml TokenTrackerWin/TokenTrackerWin.csproj"
42
44
  },
43
45
  "dependencies": {
44
46
  "@mongodb-js/zstd": "^2.0.1",
@@ -1595,6 +1595,31 @@ function createLocalApiHandler({ queuePath }) {
1595
1595
  return true;
1596
1596
  }
1597
1597
 
1598
+ // --- outcomes (opt-in quality-per-dollar / Effective Tokens; sidecar) ---
1599
+ // Reads the optional ~/.tokentracker/tracker/outcomes.jsonl sidecar and
1600
+ // joins it to the existing token/$ rows at READ time. Returns
1601
+ // available:false with empty arrays when the user hasn't opted in, so the
1602
+ // dashboard renders exactly as before. This path NEVER reads or writes
1603
+ // queue.jsonl's schema or the sync path (see GitHub #229).
1604
+ if (p === "/functions/tokentracker-outcomes") {
1605
+ const from = url.searchParams.get("from") || "";
1606
+ const to = url.searchParams.get("to") || "";
1607
+ const {
1608
+ readOutcomesData,
1609
+ resolveOutcomesPath,
1610
+ computeQualityPerDollar,
1611
+ } = require("./outcomes-engine");
1612
+ const outcomes = readOutcomesData(resolveOutcomesPath());
1613
+ if (!outcomes.length) {
1614
+ json(res, { available: false, from, to, by_model: [], by_tool: [], totals: null });
1615
+ return true;
1616
+ }
1617
+ const { rows, scope, excludedSources } = scopedQueueRows(qp, url);
1618
+ const result = computeQualityPerDollar(rows, outcomes, { from, to });
1619
+ json(res, { from, to, scope, excluded_sources: excludedSources, ...result });
1620
+ return true;
1621
+ }
1622
+
1598
1623
  // --- usage-heatmap ---
1599
1624
  if (p === "/functions/tokentracker-usage-heatmap") {
1600
1625
  const weeks = parseInt(url.searchParams.get("weeks") || "52", 10);
@@ -1,20 +1,36 @@
1
1
  const crypto = require("node:crypto");
2
+ const fssync = require("node:fs");
3
+ const path = require("node:path");
4
+ const { readSqliteJsonRowsAsync } = require("./sqlite-reader");
2
5
 
3
6
  // OpenCode Go usage limits.
4
7
  //
5
- // Scrapes the OpenCode Go workspace dashboard
6
- // (https://opencode.ai/workspace/<id>/go) for rolling (5h) / weekly / monthly
7
- // usage. The opencode web console has no public REST API for quota today
8
- // (tracked at anomalyco/opencode#16017, anomalyco/opencode#16513), so we
9
- // read the same data the React app uses by parsing the SSR hydration output
10
- // (SolidStart `queryLiteSubscription` serializes the result as
11
- // `rollingUsage:$R[N]={...usagePercent:N...resetInSec:N...}`) with a
12
- // `data-slot="usage-item"` HTML fallback.
8
+ // Two data sources, in priority order:
13
9
  //
14
- // Approach ported from slkiser/opencode-quota PR #41 (MIT, Apr 12 2026,
15
- // 430 tests passing) that project independently arrived at the same
16
- // scrape with the same env-var names. The cookie is sent verbatim as
17
- // `Cookie: auth=<OPENCODE_GO_AUTH_COOKIE>` per that reference.
10
+ // 1. Local opencode.db (auth-free, the default / zero-config path). The
11
+ // `opencode` CLI records every Go turn's USD `cost` in its SQLite
12
+ // `message` table. OpenCode Go's limits are themselves dollar caps
13
+ // ($12/5h, $30/week, $60/month https://opencode.ai/docs/go), so summing
14
+ // local cost per window ÷ the dollar cap is dimensionally exact, not a
15
+ // heuristic. Its only blind spot is usage that did NOT go through the
16
+ // local CLI (e.g. the web console, or another machine). This is what
17
+ // token-monitor (Javis603/token-monitor) falls back to, and the only
18
+ // source that survives opencode's OAuth changes (see #225).
19
+ //
20
+ // 2. Web scrape of the workspace dashboard
21
+ // (https://opencode.ai/workspace/<id>/go) for the server's EXACT
22
+ // rolling (5h) / weekly / monthly usagePercent. Used only when a cookie
23
+ // is configured AND the scrape succeeds — it carries the precise
24
+ // server-side number but is fragile: opencode moved auth to OAuth
25
+ // (auth.opencode.ai), so a bare `auth` cookie now often 302s to the login
26
+ // page (the #225 saga). The cookie is sent verbatim as
27
+ // `Cookie: auth=<OPENCODE_GO_AUTH_COOKIE>` per slkiser/opencode-quota#41.
28
+ //
29
+ // The opencode web console has no public REST API for quota
30
+ // (anomalyco/opencode#16017, #16513) and the CLI's `sk-` API key authenticates
31
+ // only the inference gateway (/zen/go/v1), not the usage windows — so the local
32
+ // DB is the only accurate auth-free option. The returned shape is identical for
33
+ // both sources; `source` is `'local'` or `'web'`.
18
34
 
19
35
  const SCRAPED_NUMBER_PATTERN = "([0-9]+(?:\\.[0-9]+)?)";
20
36
 
@@ -271,15 +287,195 @@ function looksSignedOut(text) {
271
287
  || l.includes("not associated with an account") || l.includes('actor of type "public"');
272
288
  }
273
289
 
274
- async function fetchOpencodeGoLimits({
275
- env = process.env,
276
- fetchImpl = fetch,
277
- nowMs = Date.now(),
278
- timeoutMs = DEFAULT_SCRAPE_TIMEOUT_MS,
279
- } = {}) {
280
- const cfg = readConfig(env);
281
- if (!cfg) return { configured: false };
290
+ // --- Local opencode.db cost aggregation (auth-free source) ------------------
291
+
292
+ const SESSION_MS = 5 * 60 * 60 * 1000;
293
+ const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
294
+ // OpenCode Go's official dollar caps — https://opencode.ai/docs/go
295
+ // ($12 per 5h, $30 per week, $60 per month). The limits are not stored in the
296
+ // local DB, so they are hardcoded; env-overridable in case opencode changes
297
+ // them (TOKENTRACKER_OPENCODE_GO_LIMITS="12,30,60").
298
+ const DEFAULT_GO_LIMITS = { session: 12, weekly: 30, monthly: 60 };
299
+
300
+ function goDollarLimits(env = process.env) {
301
+ const raw = String((env && env.TOKENTRACKER_OPENCODE_GO_LIMITS) || "").trim();
302
+ if (!raw) return { ...DEFAULT_GO_LIMITS };
303
+ const parts = raw.split(",").map((s) => Number(s.trim()));
304
+ if (parts.length === 3 && parts.every((n) => Number.isFinite(n) && n > 0)) {
305
+ return { session: parts[0], weekly: parts[1], monthly: parts[2] };
306
+ }
307
+ return { ...DEFAULT_GO_LIMITS };
308
+ }
282
309
 
310
+ // Mirror sync.js's opencode home resolution (OPENCODE_HOME / XDG_DATA_HOME /
311
+ // <home>/.local/share/opencode) so we read the SAME DB the parser reads. The
312
+ // user home comes from the `home` arg getUsageLimits already threads to every
313
+ // other home-based provider (cf. resolveZcodeHome). NOTE: we deliberately do
314
+ // NOT fall back to os.homedir() — only an explicit `home`/env HOME — so a
315
+ // synthetic test env (no home, no HOME) discovers nothing and the web-scrape
316
+ // tests stay isolated from the developer's real opencode.db.
317
+ function resolveOpencodeDataDir({ home, env = process.env } = {}) {
318
+ if (env.OPENCODE_HOME) return env.OPENCODE_HOME;
319
+ if (env.XDG_DATA_HOME) return path.join(env.XDG_DATA_HOME, "opencode");
320
+ const base = home || env.HOME || env.USERPROFILE;
321
+ if (!base) return null;
322
+ return path.join(base, ".local", "share", "opencode");
323
+ }
324
+
325
+ // Matches `opencode.db` or `opencode-<channel>.db`; excludes WAL/SHM side-files.
326
+ function isOpencodeDbFilename(name) {
327
+ if (!name.endsWith(".db")) return false;
328
+ const stem = name.slice(0, -3);
329
+ if (stem === "opencode") return true;
330
+ if (!stem.startsWith("opencode-")) return false;
331
+ const channel = stem.slice("opencode-".length);
332
+ return channel.length > 0 && /^[A-Za-z0-9._-]+$/.test(channel);
333
+ }
334
+
335
+ function discoverOpencodeDbPaths({ home, env = process.env } = {}) {
336
+ const override = String((env && env.OPENCODE_DB) || "").trim();
337
+ if (override) {
338
+ try {
339
+ if (fssync.statSync(override).isFile()) return [override];
340
+ } catch (_e) {
341
+ /* fall through to directory scan */
342
+ }
343
+ }
344
+ const dir = resolveOpencodeDataDir({ home, env });
345
+ if (!dir) return [];
346
+ let entries;
347
+ try {
348
+ entries = fssync.readdirSync(dir);
349
+ } catch (_e) {
350
+ return [];
351
+ }
352
+ return entries.filter(isOpencodeDbFilename).sort().map((n) => path.join(dir, n));
353
+ }
354
+
355
+ function weekStartMs(nowMs) {
356
+ const d = new Date(nowMs);
357
+ const day = d.getUTCDay(); // 0=Sun..6=Sat
358
+ const sinceMonday = day === 0 ? 6 : day - 1;
359
+ return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() - sinceMonday);
360
+ }
361
+
362
+ // Calendar-month bounds (UTC). OpenCode Go's true monthly reset is the
363
+ // subscription anniversary, which the local DB does not record; the calendar
364
+ // month is a stable, defensible approximation for the auth-free estimate.
365
+ function monthBoundsMs(nowMs) {
366
+ const now = new Date(nowMs);
367
+ return {
368
+ startMs: Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1),
369
+ endMs: Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1),
370
+ };
371
+ }
372
+
373
+ // Percentage clamp for the local estimate. Unlike clampPercent() (which scales
374
+ // a 0–1 fraction from the web payload), this treats its input as an already-
375
+ // computed percentage and must NOT rescale values below 1 (e.g. 0.5%).
376
+ function clampLocalPercent(n) {
377
+ if (!Number.isFinite(n)) return null;
378
+ if (n <= 0) return 0;
379
+ if (n >= 100) return 100;
380
+ return n;
381
+ }
382
+
383
+ function buildLocalWindow({ used, limit, resetMs }) {
384
+ if (!(limit > 0)) return null;
385
+ const pct = clampLocalPercent((Number(used) / limit) * 100);
386
+ if (pct === null) return null;
387
+ return { used_percent: pct, reset_at: new Date(resetMs).toISOString() };
388
+ }
389
+
390
+ // One full-table aggregate (the message table has no index on the JSON fields,
391
+ // so we sum in SQLite and return a single row rather than streaming every
392
+ // opencode-go turn into JS — keeps the limits poll cheap, cf. the spawnSync
393
+ // freeze lesson).
394
+ function buildGoAggregateSql({ sessionStart, weekStart, weekEnd, monthStart, monthEnd }) {
395
+ return (
396
+ "SELECT " +
397
+ `COALESCE(SUM(CASE WHEN createdMs >= ${sessionStart} THEN cost ELSE 0 END), 0) AS sessionCost, ` +
398
+ `MIN(CASE WHEN createdMs >= ${sessionStart} THEN createdMs END) AS sessionOldest, ` +
399
+ `COALESCE(SUM(CASE WHEN createdMs >= ${weekStart} AND createdMs < ${weekEnd} THEN cost ELSE 0 END), 0) AS weeklyCost, ` +
400
+ `COALESCE(SUM(CASE WHEN createdMs >= ${monthStart} AND createdMs < ${monthEnd} THEN cost ELSE 0 END), 0) AS monthlyCost, ` +
401
+ "COUNT(*) AS rowCount " +
402
+ "FROM (" +
403
+ "SELECT CAST(COALESCE(json_extract(data,'$.time.created'), time_created) AS INTEGER) AS createdMs, " +
404
+ "CAST(json_extract(data,'$.cost') AS REAL) AS cost " +
405
+ "FROM message " +
406
+ "WHERE json_valid(data) " +
407
+ "AND json_extract(data,'$.providerID') = 'opencode-go' " +
408
+ "AND json_extract(data,'$.role') = 'assistant' " +
409
+ "AND json_type(data,'$.cost') IN ('integer','real')" +
410
+ ")"
411
+ );
412
+ }
413
+
414
+ // Returns { source:'local', primary/secondary/tertiary_window } or null when no
415
+ // opencode.db / no opencode-go rows are found.
416
+ async function collectOpencodeGoLocal({ home, env = process.env, nowMs = Date.now(), sqliteOptions = {} } = {}) {
417
+ const paths = discoverOpencodeDbPaths({ home, env });
418
+ if (paths.length === 0) return null;
419
+
420
+ const sessionStart = Math.floor(nowMs - SESSION_MS);
421
+ const weekStart = weekStartMs(nowMs);
422
+ const weekEnd = weekStart + WEEK_MS;
423
+ const { startMs: monthStart, endMs: monthEnd } = monthBoundsMs(nowMs);
424
+ const sql = buildGoAggregateSql({ sessionStart, weekStart, weekEnd, monthStart, monthEnd });
425
+
426
+ let agg = null;
427
+ for (const dbPath of paths) {
428
+ let rows;
429
+ try {
430
+ rows = await readSqliteJsonRowsAsync(dbPath, sql, {
431
+ label: "OpenCode Go",
432
+ timeout: 5_000,
433
+ ...sqliteOptions,
434
+ });
435
+ } catch (_e) {
436
+ continue;
437
+ }
438
+ const row = rows && rows[0];
439
+ if (!row) continue;
440
+ const rowCount = Number(row.rowCount) || 0;
441
+ if (rowCount <= 0) continue;
442
+ if (!agg) agg = { sessionCost: 0, weeklyCost: 0, monthlyCost: 0, sessionOldest: null, rowCount: 0 };
443
+ agg.sessionCost += Number(row.sessionCost) || 0;
444
+ agg.weeklyCost += Number(row.weeklyCost) || 0;
445
+ agg.monthlyCost += Number(row.monthlyCost) || 0;
446
+ agg.rowCount += rowCount;
447
+ const oldest = row.sessionOldest == null ? null : Number(row.sessionOldest);
448
+ if (oldest != null && Number.isFinite(oldest)) {
449
+ agg.sessionOldest = agg.sessionOldest == null ? oldest : Math.min(agg.sessionOldest, oldest);
450
+ }
451
+ }
452
+ if (!agg || agg.rowCount <= 0) return null;
453
+
454
+ const limits = goDollarLimits(env);
455
+ const sessionReset = (agg.sessionOldest != null ? agg.sessionOldest : nowMs) + SESSION_MS;
456
+ return {
457
+ source: "local",
458
+ primary_window: buildLocalWindow({ used: agg.sessionCost, limit: limits.session, resetMs: sessionReset }),
459
+ secondary_window: buildLocalWindow({ used: agg.weeklyCost, limit: limits.weekly, resetMs: weekEnd }),
460
+ tertiary_window: buildLocalWindow({ used: agg.monthlyCost, limit: limits.monthly, resetMs: monthEnd }),
461
+ };
462
+ }
463
+
464
+ function localGoResult(local) {
465
+ return {
466
+ configured: true,
467
+ error: null,
468
+ source: "local",
469
+ // No `plan_label` — the brand name "OpenCode Go" is the row title.
470
+ primary_window: local.primary_window || null,
471
+ secondary_window: local.secondary_window || null,
472
+ tertiary_window: local.tertiary_window || null,
473
+ };
474
+ }
475
+
476
+ // --- Web scrape (exact server-side usage, cookie-gated) ---------------------
477
+
478
+ async function scrapeOpencodeGoWeb({ cfg, fetchImpl, nowMs, timeoutMs }) {
283
479
  let workspaceId = cfg.workspaceId;
284
480
  if (!workspaceId) {
285
481
  try {
@@ -349,6 +545,34 @@ async function fetchOpencodeGoLimits({
349
545
  };
350
546
  }
351
547
 
548
+ async function fetchOpencodeGoLimits({
549
+ home,
550
+ env = process.env,
551
+ fetchImpl = fetch,
552
+ nowMs = Date.now(),
553
+ timeoutMs = DEFAULT_SCRAPE_TIMEOUT_MS,
554
+ sqliteOptions = {},
555
+ } = {}) {
556
+ const cfg = readConfig(env);
557
+
558
+ // Cookie configured → prefer the exact server-side scrape; fall back to the
559
+ // local DB estimate when the scrape can't authenticate/parse (the #225 case).
560
+ if (cfg) {
561
+ const web = await scrapeOpencodeGoWeb({ cfg, fetchImpl, nowMs, timeoutMs });
562
+ if (web && !web.error && (web.primary_window || web.secondary_window || web.tertiary_window)) {
563
+ return { ...web, source: "web" };
564
+ }
565
+ const local = await collectOpencodeGoLocal({ home, env, nowMs, sqliteOptions });
566
+ if (local) return localGoResult(local);
567
+ return web || { configured: true, error: "OpenCode Go unavailable" };
568
+ }
569
+
570
+ // No cookie → the local opencode.db is the zero-config source.
571
+ const local = await collectOpencodeGoLocal({ home, env, nowMs, sqliteOptions });
572
+ if (local) return localGoResult(local);
573
+ return { configured: false };
574
+ }
575
+
352
576
  module.exports = {
353
577
  fetchOpencodeGoLimits,
354
578
  readConfig,
@@ -360,4 +584,13 @@ module.exports = {
360
584
  resolveWorkspaceId,
361
585
  parseWorkspaceIds,
362
586
  looksSignedOut,
587
+ // Local opencode.db cost-based estimate (auth-free source).
588
+ collectOpencodeGoLocal,
589
+ discoverOpencodeDbPaths,
590
+ resolveOpencodeDataDir,
591
+ isOpencodeDbFilename,
592
+ goDollarLimits,
593
+ weekStartMs,
594
+ monthBoundsMs,
595
+ buildLocalWindow,
363
596
  };