token-usage-dashboard 1.0.15 → 1.0.17
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/README.md +11 -11
- package/bin/{ai-usage-dashboard.js → token-usage-dashboard.js} +1 -1
- package/build/adapter-node.js +1 -1
- package/build/client/_app/immutable/entry/{app.CRLWmGVY.js → app.CQWyl0kn.js} +2 -2
- package/build/client/_app/immutable/entry/app.CQWyl0kn.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CQWyl0kn.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Cw7ieJWD.js +2 -0
- package/build/client/_app/immutable/nodes/2.Cw7ieJWD.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Cw7ieJWD.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/instance.js +3 -3
- package/build/server/chunks/internal.js +1 -1
- package/build/server/chunks/queries.js +45 -51
- package/build/server/chunks/range.js +10 -4
- package/build/server/entries/pages/_page.svelte.js +32 -13
- package/build/server/manifest-full.js +1 -1
- package/build/server/manifest.js +1 -1
- package/build/server/nodes/2.js +1 -1
- package/build/server/server.js +1 -1
- package/package.json +6 -6
- package/build/client/_app/immutable/entry/app.CRLWmGVY.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CRLWmGVY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CRMPKkcX.js +0 -2
- package/build/client/_app/immutable/nodes/2.CRMPKkcX.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CRMPKkcX.js.gz +0 -0
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<h1 align="center">
|
|
1
|
+
<h1 align="center">Token usage dashboard</h1>
|
|
2
2
|
<p align="center">
|
|
3
3
|
<i>Beautiful dashboard showing a breakdown of where all of your tokens are going</i><br>
|
|
4
4
|
<b><code>npx token-usage-dashboard</code></b>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<img src="https://raw.githubusercontent.com/NotAFlightRisk/
|
|
8
|
+
<img src="https://raw.githubusercontent.com/NotAFlightRisk/token-usage-dashboard/main/.github/screenshot.png" width="800" alt="The dashboard, showing a usage calendar, daily totals and plan windows" />
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
---
|
|
@@ -56,7 +56,7 @@ Most of it lives behind the gear icon: theme, default range, how often to rescan
|
|
|
56
56
|
Anthropic for your plan windows, and price overrides for any model we've got wrong or don't know.
|
|
57
57
|
|
|
58
58
|
Paths are environment variables, since they're needed before the app starts. See
|
|
59
|
-
[`.env.example`](https://github.com/NotAFlightRisk/
|
|
59
|
+
[`.env.example`](https://github.com/NotAFlightRisk/token-usage-dashboard/blob/main/.env.example) for the full list. The ones you'll actually want are
|
|
60
60
|
`AIUSAGE_DB`, `AIUSAGE_CLAUDE_DIR` and `AIUSAGE_CODEX_DIR`.
|
|
61
61
|
|
|
62
62
|
---
|
|
@@ -78,18 +78,18 @@ we can read, it can go in - open an issue with a sample and we'll have a look.
|
|
|
78
78
|
|
|
79
79
|
### Option 1: Docker
|
|
80
80
|
|
|
81
|
-
The image is on DockerHub ([`notaflightrisk/
|
|
81
|
+
The image is on DockerHub ([`notaflightrisk/token-usage-dashboard`](https://hub.docker.com/r/notaflightrisk/token-usage-dashboard))
|
|
82
82
|
and GHCR. Mount the directories you want read, plus somewhere to keep the database:
|
|
83
83
|
|
|
84
84
|
```shell
|
|
85
85
|
docker run -p 127.0.0.1:8080:8080 \
|
|
86
86
|
-v ~/.claude:/home/node/.claude:ro \
|
|
87
87
|
-v ~/.codex:/home/node/.codex:ro \
|
|
88
|
-
-v
|
|
89
|
-
notaflightrisk/
|
|
88
|
+
-v token-usage:/data \
|
|
89
|
+
notaflightrisk/token-usage-dashboard
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
There's a compose file in [`docker/`](https://github.com/NotAFlightRisk/
|
|
92
|
+
There's a compose file in [`docker/`](https://github.com/NotAFlightRisk/token-usage-dashboard/blob/main/docker/compose.yaml) if you'd rather. The container has
|
|
93
93
|
to bind `0.0.0.0` internally, so publish the port to localhost like that unless something in
|
|
94
94
|
front of it is checking who's asking.
|
|
95
95
|
|
|
@@ -104,7 +104,7 @@ so it comes back after a reboot:
|
|
|
104
104
|
|
|
105
105
|
### Option 3: From a release
|
|
106
106
|
|
|
107
|
-
Grab the tarball from [releases](https://github.com/NotAFlightRisk/
|
|
107
|
+
Grab the tarball from [releases](https://github.com/NotAFlightRisk/token-usage-dashboard/releases),
|
|
108
108
|
then `npm ci --omit=dev && npm start`.
|
|
109
109
|
|
|
110
110
|
### Option 4: From source
|
|
@@ -119,8 +119,8 @@ You'll need [Node](https://nodejs.org/) 22.12 or newer, plus [Git](https://git-s
|
|
|
119
119
|
It's a [SvelteKit](https://svelte.dev/docs/kit) app and the build is self-contained so there's no runtime dependencies at all.
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
|
-
git clone git@github.com:NotAFlightRisk/
|
|
123
|
-
cd
|
|
122
|
+
git clone git@github.com:NotAFlightRisk/token-usage-dashboard.git
|
|
123
|
+
cd token-usage-dashboard
|
|
124
124
|
npm install
|
|
125
125
|
npm run dev
|
|
126
126
|
```
|
|
@@ -134,6 +134,6 @@ The other scripts you'll want are `npm run check` (types), `npm test` (tests) an
|
|
|
134
134
|
<p align="center">
|
|
135
135
|
<a href="https://github.com/NotAFlightRisk"><img width="64" src="https://pixelflare.cc/iain/gif/penguin-dance.gif" /></a><br>
|
|
136
136
|
<sup>
|
|
137
|
-
<i>Licensed under <a href="https://github.com/NotAFlightRisk/
|
|
137
|
+
<i>Licensed under <a href="https://github.com/NotAFlightRisk/token-usage-dashboard/blob/main/LICENSE">MIT</a>, © <a href="https://peng.ly">NotAFlightRisk</a> 2026</i>
|
|
138
138
|
</sup>
|
|
139
139
|
</p>
|
|
@@ -78,7 +78,7 @@ process.env.PORT = String(port);
|
|
|
78
78
|
const shown = host === '0.0.0.0' || host === '::' ? 'localhost' : host;
|
|
79
79
|
const url = `http://${shown.includes(':') ? `[${shown}]` : shown}:${port}`;
|
|
80
80
|
await import(resolve(root, 'build', 'index.js'));
|
|
81
|
-
console.log(`\n
|
|
81
|
+
console.log(`\n Token usage dashboard is on ${url}\n`);
|
|
82
82
|
|
|
83
83
|
const wantsBrowser = flag('--open') || (process.stdout.isTTY && !flag('--no-open'));
|
|
84
84
|
if (wantsBrowser) {
|
package/build/adapter-node.js
CHANGED
|
@@ -7,5 +7,5 @@ export const app_path = "_app";
|
|
|
7
7
|
export const origin = undefined;
|
|
8
8
|
export const env_prefix = "";
|
|
9
9
|
export const mime_types = {".svg":"image/svg+xml",".txt":"text/plain",".json":"application/json",".css":"text/css",".js":"text/javascript"};
|
|
10
|
-
export const assets = JSON.parse("{\"entries\":[[\"/_app/immutable/assets/0.CZ6VMqH1.css\",{\"file\":\"_app/immutable/assets/0.CZ6VMqH1.css\",\"size\":6415,\"etag\":\"AmJmtz8-GUP6-pN5uxaZQOmSuoaHq2Sqe__AyVSXstw\",\"gz\":2245,\"br\":1763}],[\"/_app/immutable/assets/2.CZocdpCk.css\",{\"file\":\"_app/immutable/assets/2.CZocdpCk.css\",\"size\":21079,\"etag\":\"zB6NnjGejn-r7_JQS5OeO1uLsY4dTfc-oZgDwtX2PHs\",\"gz\":4049,\"br\":3618}],[\"/_app/immutable/chunks/B0VWrXPj.js\",{\"file\":\"_app/immutable/chunks/B0VWrXPj.js\",\"size\":4346,\"etag\":\"VlDh4E_v-YX1wXJrJufswOtaqXf2nlGvAnp0K5QOPZY\",\"gz\":1958,\"br\":1736}],[\"/_app/immutable/chunks/BaNbYf_w.js\",{\"file\":\"_app/immutable/chunks/BaNbYf_w.js\",\"size\":1398,\"etag\":\"SeMbugghlpNXgqwUu-28Ko58Qin5GLwIarXdCMoBUDQ\",\"gz\":749,\"br\":630}],[\"/_app/immutable/chunks/Bjy-W4x2.js\",{\"file\":\"_app/immutable/chunks/Bjy-W4x2.js\",\"size\":1365,\"etag\":\"8HQkdYMY3WtfMrD-jenS_7jZehfIQXWGJtGLoPqgRWo\",\"gz\":654,\"br\":499}],[\"/_app/immutable/chunks/CbiRHTcG.js\",{\"file\":\"_app/immutable/chunks/CbiRHTcG.js\",\"size\":74,\"etag\":\"V-LMEc5umA_-juDuCBm9StVFZHbFfPFOxc2LAPt2qlg\",\"gz\":84,\"br\":78}],[\"/_app/immutable/chunks/DTingiCe.js\",{\"file\":\"_app/immutable/chunks/DTingiCe.js\",\"size\":49075,\"etag\":\"SEphUN_rkMlSo03zc6D1bY6mlO7ZjFpJ9kuWn5fkZj4\",\"gz\":18639,\"br\":16967}],[\"/_app/immutable/chunks/ssd4Rw-g.js\",{\"file\":\"_app/immutable/chunks/ssd4Rw-g.js\",\"size\":43463,\"etag\":\"ASXguujVvmnB1OQGEpilTjuEC2DMb0VZ3r_z0b5aEpk\",\"gz\":15844,\"br\":14351}],[\"/_app/immutable/entry/app.
|
|
10
|
+
export const assets = JSON.parse("{\"entries\":[[\"/_app/immutable/assets/0.CZ6VMqH1.css\",{\"file\":\"_app/immutable/assets/0.CZ6VMqH1.css\",\"size\":6415,\"etag\":\"AmJmtz8-GUP6-pN5uxaZQOmSuoaHq2Sqe__AyVSXstw\",\"gz\":2245,\"br\":1763}],[\"/_app/immutable/assets/2.CZocdpCk.css\",{\"file\":\"_app/immutable/assets/2.CZocdpCk.css\",\"size\":21079,\"etag\":\"zB6NnjGejn-r7_JQS5OeO1uLsY4dTfc-oZgDwtX2PHs\",\"gz\":4049,\"br\":3618}],[\"/_app/immutable/chunks/B0VWrXPj.js\",{\"file\":\"_app/immutable/chunks/B0VWrXPj.js\",\"size\":4346,\"etag\":\"VlDh4E_v-YX1wXJrJufswOtaqXf2nlGvAnp0K5QOPZY\",\"gz\":1958,\"br\":1736}],[\"/_app/immutable/chunks/BaNbYf_w.js\",{\"file\":\"_app/immutable/chunks/BaNbYf_w.js\",\"size\":1398,\"etag\":\"SeMbugghlpNXgqwUu-28Ko58Qin5GLwIarXdCMoBUDQ\",\"gz\":749,\"br\":630}],[\"/_app/immutable/chunks/Bjy-W4x2.js\",{\"file\":\"_app/immutable/chunks/Bjy-W4x2.js\",\"size\":1365,\"etag\":\"8HQkdYMY3WtfMrD-jenS_7jZehfIQXWGJtGLoPqgRWo\",\"gz\":654,\"br\":499}],[\"/_app/immutable/chunks/CbiRHTcG.js\",{\"file\":\"_app/immutable/chunks/CbiRHTcG.js\",\"size\":74,\"etag\":\"V-LMEc5umA_-juDuCBm9StVFZHbFfPFOxc2LAPt2qlg\",\"gz\":84,\"br\":78}],[\"/_app/immutable/chunks/DTingiCe.js\",{\"file\":\"_app/immutable/chunks/DTingiCe.js\",\"size\":49075,\"etag\":\"SEphUN_rkMlSo03zc6D1bY6mlO7ZjFpJ9kuWn5fkZj4\",\"gz\":18639,\"br\":16967}],[\"/_app/immutable/chunks/ssd4Rw-g.js\",{\"file\":\"_app/immutable/chunks/ssd4Rw-g.js\",\"size\":43463,\"etag\":\"ASXguujVvmnB1OQGEpilTjuEC2DMb0VZ3r_z0b5aEpk\",\"gz\":15844,\"br\":14351}],[\"/_app/immutable/entry/app.CQWyl0kn.js\",{\"file\":\"_app/immutable/entry/app.CQWyl0kn.js\",\"size\":1152,\"etag\":\"YMBtbW_kHWfPMTG7xzmia7q_0PdGqtihqBIUBli9gYQ\",\"gz\":584,\"br\":544}],[\"/_app/immutable/entry/payload.DSmR2FwN.js\",{\"file\":\"_app/immutable/entry/payload.DSmR2FwN.js\",\"size\":65,\"etag\":\"t8untEsjl8fSj320o07HNKmF5k_yfXTd-NlkXPgU8J8\",\"gz\":77,\"br\":60}],[\"/_app/immutable/entry/start.CzGx2BYz.js\",{\"file\":\"_app/immutable/entry/start.CzGx2BYz.js\",\"size\":548,\"etag\":\"_HEmuLQviTm8WWFgGQF1FkudnNzr4eYPqpIyQZvXl0Y\",\"gz\":316,\"br\":297}],[\"/_app/immutable/nodes/0.BBGTwdwd.js\",{\"file\":\"_app/immutable/nodes/0.BBGTwdwd.js\",\"size\":146,\"etag\":\"DPaI0bHB1EG8OS9bO_AdYFYJzBAZS1HUqAUkuA-wg7s\",\"gz\":142,\"br\":113}],[\"/_app/immutable/nodes/1.Cy2JV0fN.js\",{\"file\":\"_app/immutable/nodes/1.Cy2JV0fN.js\",\"size\":322,\"etag\":\"JJb9Y2tEB1OmdqWaFeFvfgEA9KQn054_C4xkGPO2ixo\",\"gz\":245,\"br\":206}],[\"/_app/immutable/nodes/2.Cw7ieJWD.js\",{\"file\":\"_app/immutable/nodes/2.Cw7ieJWD.js\",\"size\":56616,\"etag\":\"9lx3zhxqYh3NKXnBS4PM9kluHJLYorIFTJQUb7VETSM\",\"gz\":21199,\"br\":18113}],[\"/_app/version.json\",{\"file\":\"_app/version.json\",\"size\":27,\"etag\":\"WsbqxEz0byqIwvxVZCFT6N4hlYtmv5rK9xMPrnISt_U\",\"gz\":47,\"br\":31}],[\"/favicon.svg\",{\"file\":\"favicon.svg\",\"size\":1359,\"etag\":\"dwTca4XMwxgmKSW81f8rca-PdcQQ4c06bZv5jlVJpmE\",\"gz\":260,\"br\":211}],[\"/robots.txt\",{\"file\":\"robots.txt\",\"size\":26,\"etag\":\"Mx6pCQ2wyfb1l72YQP1bFxgw9uCzuhyyTfqR8Mla7cE\",\"gz\":46,\"br\":30}]],\"aliases\":[]}");
|
|
11
11
|
export const prerendered_assets = JSON.parse("{\"entries\":[],\"aliases\":[]}");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../nodes/0.BBGTwdwd.js","../chunks/DTingiCe.js","../assets/0.CZ6VMqH1.css","../nodes/1.Cy2JV0fN.js","../chunks/B0VWrXPj.js","./payload.DSmR2FwN.js","../nodes/2.
|
|
2
|
-
import{t as e}from"../chunks/BaNbYf_w.js";var t={},n=[()=>e(()=>import(`../nodes/0.BBGTwdwd.js`),__vite__mapDeps([0,1,2]),import.meta.url),()=>e(()=>import(`../nodes/1.Cy2JV0fN.js`),__vite__mapDeps([3,1,4,5]),import.meta.url),()=>e(()=>import(`../nodes/2.
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../nodes/0.BBGTwdwd.js","../chunks/DTingiCe.js","../assets/0.CZ6VMqH1.css","../nodes/1.Cy2JV0fN.js","../chunks/B0VWrXPj.js","./payload.DSmR2FwN.js","../nodes/2.Cw7ieJWD.js","../chunks/ssd4Rw-g.js","../assets/2.CZocdpCk.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{t as e}from"../chunks/BaNbYf_w.js";var t={},n=[()=>e(()=>import(`../nodes/0.BBGTwdwd.js`),__vite__mapDeps([0,1,2]),import.meta.url),()=>e(()=>import(`../nodes/1.Cy2JV0fN.js`),__vite__mapDeps([3,1,4,5]),import.meta.url),()=>e(()=>import(`../nodes/2.Cw7ieJWD.js`),__vite__mapDeps([6,1,7,5,4,8]),import.meta.url)],r=[],i={"/":[-3]},a={handleError:(({kind:e,error:t})=>{e===`unknown`&&console.error(t)}),reroute:(()=>{}),transport:{}},o=Object.fromEntries(Object.entries(a.transport).map(([e,t])=>[e,t.decode])),s=Object.fromEntries(Object.entries(a.transport).map(([e,t])=>[e,t.encode])),c=!1,l=(e,t)=>o[e](t),u=()=>e(()=>import(`../chunks/Bjy-W4x2.js`).then(e=>e.default),[],import.meta.url);export{l as decode,o as decoders,i as dictionary,s as encoders,u as get_error_template,c as hash,a as hooks,t as matchers,n as nodes,r as server_loads};
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{$ as e,A as t,B as n,D as r,F as i,G as a,H as o,J as s,K as c,M as l,N as u,O as d,P as f,Q as p,R as m,S as h,T as g,U as _,V as v,W as y,X as b,Y as x,Z as S,a as C,b as w,c as T,d as E,et as D,f as O,g as k,h as A,i as j,j as M,k as N,l as P,m as F,n as I,o as L,p as R,q as z,r as B,rt as ee,s as V,t as H,tt as U,u as te,v as W,y as ne,z as re}from"../chunks/DTingiCe.js";import{t as ie}from"../chunks/ssd4Rw-g.js";var G=null;function ae(){return G||(G=document.createElement(`div`),G.className=`app-tooltip`,G.setAttribute(`role`,`tooltip`),document.body.append(G),G)}var K=(e,t)=>{let n=t,r=()=>{G&&G.classList.remove(`is-open`)},i=()=>{if(!n)return;let t=ae();t.textContent=n,t.classList.add(`is-open`);let r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),a=Math.min(Math.max(8,r.left+r.width/2-i.width/2),window.innerWidth-i.width-8),o=r.top>i.height+12;t.style.left=`${a}px`,t.style.top=`${o?r.top-i.height-8:r.bottom+8}px`};return e.addEventListener(`pointerenter`,i),e.addEventListener(`focusin`,i),e.addEventListener(`pointerleave`,r),e.addEventListener(`focusout`,r),window.addEventListener(`scroll`,r,!0),{update:t=>{n=t,t&&e.setAttribute(`aria-label`,e.getAttribute(`aria-label`)??t)},destroy:()=>{r(),e.removeEventListener(`pointerenter`,i),e.removeEventListener(`focusin`,i),e.removeEventListener(`pointerleave`,r),e.removeEventListener(`focusout`,r),window.removeEventListener(`scroll`,r,!0)}}},oe=N(`<div class="actions svelte-hxsa5u"><!></div>`),se=N(`<section class="panel svelte-hxsa5u"><header class="svelte-hxsa5u"><h2 class="svelte-hxsa5u"> </h2> <!></header> <div class="body svelte-hxsa5u"><!></div></section>`);function q(e,t){let i=H(t,`span`,3,12);var a=se(),o=y(a),s=y(o),l=c(s,!0);F(s,(e,t)=>K?.(e,t),()=>t.hint);var u=z(s,2),d=e=>{var n=oe(),i=y(n);h(i,()=>t.actions),U(n),r(e,n)};w(u,e=>{t.actions&&e(d)}),U(o);var f=z(o,2),p=y(f);h(p,()=>t.children),U(f),U(a),n(()=>{O(a,`--span: ${i()??``}`),g(l,t.title)}),r(e,a)}var ce=N(`<button type="button"> </button>`),le=N(`<div role="group"></div>`);function ue(t,a){e(a,!0);let o=H(a,`value`,15),s=H(a,`size`,3,`md`);var l=le();let d;W(l,21,()=>a.options,e=>e.id,(e,t)=>{var a=ce();let s;var l=c(a,!0);F(a,(e,t)=>K?.(e,t),()=>i(t).hint),n(()=>{T(a,`aria-pressed`,o()===i(t).id),s=R(a,1,`svelte-1dkbyok`,null,s,{on:o()===i(t).id}),g(l,i(t).label)}),u(`click`,a,()=>o(i(t).id)),r(e,a)}),U(l),n(()=>{d=R(l,1,`segmented svelte-1dkbyok`,null,d,{sm:s()===`sm`}),T(l,`aria-label`,a.label)}),r(t,l),p()}l([`click`]);var de=N(`<b class="num svelte-vbwhwd"> </b>`),fe=N(`<label class="svelte-vbwhwd"><input type="checkbox" class="svelte-vbwhwd"/> <span class="svelte-vbwhwd"> </span></label>`),pe=N(`<p class="none svelte-vbwhwd">Nothing matches</p>`),me=N(`<button type="button" class="clear svelte-vbwhwd">Clear</button>`),he=N(`<div class="menu svelte-vbwhwd"><input class="search svelte-vbwhwd" type="search"/> <div class="list svelte-vbwhwd"></div> <!></div>`),ge=N(`<div class="select svelte-vbwhwd"><button type="button"> <!> <svg viewBox="0 0 12 12" width="10" height="10" aria-hidden="true"><path d="M2 4.5 6 8.5 10 4.5" fill="none" stroke="currentColor" stroke-width="1.5"></path></svg></button> <!></div>`);function _e(t,a){e(a,!0);let o=H(a,`selected`,15),s=H(a,`format`,3,e=>e),l=b(!1),d=b(``),m,h=S(()=>a.options.filter(e=>s()(e).toLowerCase().includes(i(d).toLowerCase()))),v=e=>{o(o().includes(e)?o().filter(t=>t!==e):[...o(),e])},C=e=>{i(l)&&!m.contains(e.target)&&x(l,!1)};var E=ge();f(`click`,_,C);var O=y(E);let k;var A=y(O),M=z(A),N=e=>{var t=de(),i=c(t,!0);n(()=>g(i,o().length)),r(e,t)};w(M,e=>{o().length&&e(N)}),D(2),U(O);var F=z(O,2),L=e=>{var t=he(),l=y(t);V(l);var f=z(l,2);W(f,20,()=>i(h),e=>e,(e,t)=>{var i=fe(),a=y(i);V(a);var l=z(a,2),d=c(l,!0);U(i),n((e,t)=>{P(a,e),g(d,t)},[()=>o().includes(t),()=>s()(t)]),u(`change`,a,()=>v(t)),r(e,i)},e=>{var t=pe();r(e,t)}),U(f);var p=z(f,2),m=e=>{var t=me();u(`click`,t,()=>o([])),r(e,t)};w(p,e=>{o().length&&e(m)}),U(t),n(e=>T(l,`placeholder`,`Filter ${e??``}`),[()=>a.label.toLowerCase()]),j(l,()=>i(d),e=>x(d,e)),r(e,t)};w(F,e=>{i(l)&&e(L)}),U(E),I(E,e=>m=e,()=>m),n(()=>{k=R(O,1,`trigger svelte-vbwhwd`,null,k,{on:o().length>0}),T(O,`aria-expanded`,i(l)),g(A,`${a.label??``} `)}),u(`click`,O,()=>x(l,!i(l))),r(t,E),p()}l([`click`,`change`]);var ve=[{at:0xe8d4a51000,suffix:`T`},{at:1e9,suffix:`B`},{at:1e6,suffix:`M`},{at:1e3,suffix:`k`}];function J(e){let t=ve.find(t=>Math.abs(e)>=t.at);if(!t)return String(Math.round(e));let n=e/t.at;return`${n.toFixed(+(n<10))}${t.suffix}`}var Y=e=>Math.round(e).toLocaleString(`en-GB`);function X(e){return e===null?`--`:e===0?`$0`:Math.abs(e)<.01?`<$0.01`:`$${e.toLocaleString(`en-GB`,{minimumFractionDigits:2,maximumFractionDigits:2})}`}function ye(e){return e===null?`--`:Math.abs(e)>=1e3?`$${J(e)}`:X(e)}var be=(e,t=0)=>`${e.toFixed(t)}%`,xe=new Intl.RelativeTimeFormat(`en-GB`,{numeric:`auto`}),Se=[[`second`,60],[`minute`,60],[`hour`,24],[`day`,7],[`week`,4.35],[`month`,12]];function Ce(e,t=Date.now()){if(!e)return`never`;let n=(e-t)/1e3;if(Math.abs(n)<45)return n<0?`just now`:`in a moment`;for(let[e,t]of Se){if(Math.abs(n)<t)return xe.format(Math.round(n),e);n/=t}return xe.format(Math.round(n),`year`)}var Z=e=>new Date(`${e}T00:00:00`).toLocaleDateString(`en-GB`,{weekday:`short`,day:`numeric`,month:`short`}),we=e=>new Date(e).toLocaleString(`en-GB`,{day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`});function Te(e){let t=Math.round(e/6e4);return t<1?`under a minute`:t<60?`${t} min`:`${Math.floor(t/60)}h ${t%60}m`}var Ee=e=>e?e.replace(/\/+$/,``).split(`/`).pop()||e:`unknown`,De=e=>(e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e).replace(/-\d{8}$/,``);function Oe(e,t){if(!t)return null;let n=(e-t)/t*100;return!Number.isFinite(n)||Math.abs(n)<1?{text:`flat`,tone:`even`}:{text:`${n>0?`+`:``}${n.toFixed(0)}%`,tone:n>0?`up`:`down`}}var ke=N(`<span class="delta svelte-l3stpt"> </span>`),Ae=N(`<i> </i>`),je=N(`<i class="delta svelte-l3stpt"> <span class="visually-hidden"> </span></i>`),Me=N(`<div class="figures svelte-l3stpt"><div class="lead svelte-l3stpt"><span class="cap svelte-l3stpt"> </span> <strong class="num svelte-l3stpt"> </strong> <!></div> <dl class="svelte-l3stpt"><div class="svelte-l3stpt"><dt class="svelte-l3stpt">Est. cost</dt> <dd class="num svelte-l3stpt"> <!> <!></dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Sessions</dt> <dd class="num svelte-l3stpt"> </dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Active days</dt> <dd class="num svelte-l3stpt"> </dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Daily pace</dt> <dd class="num svelte-l3stpt"> </dd></div></dl></div>`);function Ne(t,a){e(a,!0);let o=S(()=>Oe(a.totals.total,a.previous.total)),s=S(()=>a.unpriced.length?null:Oe(a.totals.cost??0,a.previous.cost??0)),l=S(()=>a.activeDays?a.totals.total/a.activeDays:0);var u=Me(),d=y(u),f=y(d),m=c(f),h=z(f,2),_=c(h,!0);F(h,(e,t)=>K?.(e,t),()=>Y(a.totals.total));var v=z(h,2),b=e=>{var t=ke(),s=c(t,!0);F(t,(e,t)=>K?.(e,t),()=>`on the ${a.rangeLabel.toLowerCase()} before`),n(()=>g(s,i(o).text)),r(e,t)};w(v,e=>{i(o)&&e(b)}),U(d);var x=z(d,2),C=y(x),T=y(C);F(T,(e,t)=>K?.(e,t),()=>`What these tokens would cost at published API rates. A subscription is billed separately.`);var E=z(T,2),D=y(E),O=z(D),k=e=>{var t=Ae(),a=c(t,!0);n(()=>{R(t,1,`delta cost ${i(s).tone??``}`,`svelte-l3stpt`),g(a,i(s).text)}),r(e,t)};w(O,e=>{i(s)&&e(k)});var A=z(O,2),j=e=>{var t=je(),i=y(t),o=z(i),s=c(o);U(t),F(t,(e,t)=>K?.(e,t),()=>`Leaves out ${a.unpriced.join(`, `)} - no price yet. Add one in Settings.`),n(e=>{g(i,`${a.unpriced.length??``} unpriced`),g(s,`: ${e??``}`)},[()=>a.unpriced.join(`, `)]),r(e,t)};w(A,e=>{a.unpriced.length&&e(j)}),U(E),U(C);var M=z(C,2),N=z(y(M),2),P=c(N,!0);U(M);var I=z(M,2),L=y(I);F(L,(e,t)=>K?.(e,t),()=>`Days with at least one request`);var B=z(L,2),ee=c(B,!0);U(I);var V=z(I,2),H=y(V);F(H,(e,t)=>K?.(e,t),()=>`Tokens per active day`);var te=z(H,2),W=c(te,!0);U(V),U(x),U(u),n((e,t,n,r,i,a)=>{g(m,`Tokens, ${e??``}`),g(_,t),g(D,`${n??``} `),g(P,r),g(ee,i),g(W,a)},[()=>a.rangeLabel.toLowerCase(),()=>J(a.totals.total),()=>X(a.totals.cost),()=>Y(a.totals.sessions),()=>Y(a.activeDays),()=>J(i(l))]),r(t,u),p()}var Pe=t(`<text class="axis svelte-1iu5iby" y="10"> </text>`),Fe=t(`<text class="axis svelte-1iu5iby" x="0"> </text>`),Ie=t(`<rect role="img"></rect>`),Le=N(`<i class="svelte-1iu5iby"></i>`),Re=N(`<div class="calendar svelte-1iu5iby"><svg role="img" aria-label="Daily usage calendar" class="svelte-1iu5iby"><!><!><!></svg> <div class="legend svelte-1iu5iby"><span class="span svelte-1iu5iby"> </span> <span>No records</span> <i class="blank svelte-1iu5iby"></i> <span class="spread svelte-1iu5iby">Quieter</span> <!> <span>Busier</span></div></div>`);function ze(t,o){e(o,!0);let s=b(680),l=e=>e.toLocaleDateString(`en-CA`),u=e=>e?o.metric===`cost`?e.cost??0:e.total:0,f=S(()=>new Map(o.days.map(e=>[e.day,e]))),m=S(()=>o.oldest?l(new Date(o.oldest)):o.days[0]?.day??``),h=S(()=>{let e=new Date;e.setHours(0,0,0,0);let t=new Date(o.days.length?`${o.days[0].day}T00:00:00`:e),n=new Date(e);n.setDate(n.getDate()-370);let r=new Date(e);r.setDate(r.getDate()-125);let i=new Date(Math.max(n.getTime(),Math.min(t.getTime(),r.getTime())));i.setDate(i.getDate()-(i.getDay()+6)%7);let a=[],s=new Date(i),c=0;for(;s<=e;){let e=(s.getDay()+6)%7;a.push({day:l(s),date:new Date(s),week:c,weekday:e}),e===6&&(c+=1),s.setDate(s.getDate()+1)}return{cells:a,weeks:c+1}}),_=S(()=>Math.max(9,Math.min(30,Math.floor((i(s)-32)/i(h).weeks)-3))),v=S(()=>i(_)+3),C=S(()=>{let e=o.days.map(e=>u(e)).filter(e=>e>0).sort((e,t)=>e-t);return e.length?[.2,.4,.6,.8].map(t=>e[Math.floor(e.length*t)]):[]}),E=e=>e<=0?0:i(C).filter(t=>e>=t).length+1,k=S(()=>{let e=[];for(let t of i(h).cells){if(t.weekday!==0)continue;let n=t.date.toLocaleDateString(`en-GB`,{month:`short`});(!e.length||t.date.getDate()<=7&&e[e.length-1].label!==n)&&e.push({label:n,week:t.week})}return e}),A=e=>{if(i(m)&&e<i(m))return`${Z(e)} - before your records start`;let t=u(i(f).get(e)),n=o.metric===`cost`?X(t):`${J(t)} tokens`;return`${Z(e)} - ${t?n:`nothing`}`},j=[`Mon`,``,`Wed`,``,`Fri`,``,`Sun`],M=S(()=>o.days.filter(e=>u(e)>0).length),N=S(()=>i(m)?`Since ${Z(i(m))}, ${i(M)} ${i(M)===1?`day`:`days`} with usage`:``);var P=Re(),I=y(P),L=y(I);W(L,17,()=>i(k),e=>e.week+e.label,(e,t)=>{var a=Pe(),o=c(a,!0);n(()=>{T(a,`x`,32+i(t).week*i(v)),g(o,i(t).label)}),r(e,a)});var ee=z(L);W(ee,17,()=>j,ne,(e,t,o)=>{var s=d(),l=a(s),u=e=>{var a=Fe(),s=c(a,!0);n(()=>{T(a,`y`,18+o*i(v)+i(_)/2+3),g(s,i(t))}),r(e,a)};w(l,e=>{i(t)&&e(u)}),r(e,s)});var V=z(ee);W(V,17,()=>i(h).cells,e=>e.day,(e,t)=>{let a=S(()=>!!i(m)&&i(t).day<i(m));var o=Ie();let s;F(o,(e,t)=>K?.(e,t),()=>A(i(t).day)),n((e,n,r)=>{s=R(o,0,`cell svelte-1iu5iby`,null,s,{blank:i(a)}),T(o,`x`,32+i(t).week*i(v)),T(o,`y`,18+i(t).weekday*i(v)),T(o,`width`,i(_)),T(o,`height`,i(_)),T(o,`rx`,e),T(o,`fill`,`var(--ramp-${n??``})`),T(o,`aria-label`,r)},[()=>Math.max(2,i(_)/4),()=>i(a)?0:E(u(i(f).get(i(t).day))),()=>A(i(t).day)]),r(e,o)}),U(I);var H=z(I,2),te=y(H),re=c(te,!0),ie=z(te,8);W(ie,16,()=>[0,1,2,3,4,5],e=>e,(e,t)=>{var i=Le();n(()=>O(i,`background: var(--ramp-${t??``})`)),r(e,i)}),D(2),U(H),U(P),n(()=>{T(I,`width`,i(h).weeks*i(v)+32),T(I,`height`,7*i(v)+18),g(re,i(N))}),B(P,`clientWidth`,e=>x(s,e)),r(t,P),p()}var Be=N(`<div class="tick svelte-118k1un"><span class="svelte-118k1un"> </span></div>`),Ve=N(`<span aria-hidden="true" class="svelte-118k1un"></span>`),He=N(`<div class="column svelte-118k1un"><div class="stack svelte-118k1un"></div></div>`),Ue=N(`<div class="trend svelte-118k1un"><div class="plot svelte-118k1un"><!> <div class="bars svelte-118k1un"></div></div> <div class="axis svelte-118k1un"><span> </span> <span> </span></div></div>`);function We(t,o){e(o,!0);let s=e=>o.metric===`cost`?e.cost??0:e.total,l=e=>o.metric===`cost`?X(e):J(e),u=S(()=>{let e=new Map;for(let t of o.series){let n=e.get(t.day)??{day:t.day,total:0,parts:new Map};n.total+=s(t),n.parts.set(t.key,(n.parts.get(t.key)??0)+s(t)),e.set(t.day,n)}return[...e.values()].sort((e,t)=>e.day.localeCompare(t.day))}),f=S(()=>Math.max(1,...i(u).map(e=>e.total))),m=e=>{let t=o.keys.filter(t=>e.parts.get(t.id)).map(t=>`${t.label} ${l(e.parts.get(t.id)??0)}`).join(`, `);return`${Z(e.day)} - ${l(e.total)}${t?` (${t})`:``}`},h=e=>o.metric===`cost`?ye(e):J(e),_=S(()=>[1,.5,0].map(e=>({at:e,label:h(i(f)*e)})));var v=Ue(),b=y(v),x=y(b);W(x,17,()=>i(_),e=>e.at,(e,t)=>{var a=Be(),o=y(a),s=c(o,!0);U(a),n(()=>{O(a,`bottom: ${i(t).at*100}%`),g(s,i(t).label)}),r(e,a)});var C=z(x,2);W(C,21,()=>i(u),e=>e.day,(e,t)=>{var s=He(),c=y(s);W(c,21,()=>o.keys,e=>e.id,(e,o)=>{let s=S(()=>i(t).parts.get(i(o).id)??0);var c=d(),l=a(c),u=e=>{var t=Ve();n(()=>O(t,`flex: ${i(s)??``}; background: ${i(o).colour??``}`)),r(e,t)};w(l,e=>{i(s)>0&&e(u)}),r(e,c)}),U(c),U(s),F(s,(e,t)=>K?.(e,t),()=>m(i(t))),n(()=>O(c,`height: ${i(t).total/i(f)*100}%`)),r(e,s)}),U(C),U(b);var T=z(b,2),E=y(T),D=c(E,!0),k=z(E,2),A=c(k,!0);U(T),U(v),n((e,t)=>{g(D,e),g(A,t)},[()=>i(u).length?Z(i(u)[0].day):``,()=>i(u).length?Z(i(u)[i(u).length-1].day):``]),r(t,v),p()}var Ge=`M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81`,Ke={anthropic:`M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z`,openai:`M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z`,google:Ge,xai:`M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815`,meta:`M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z`,mistral:`M17.143 3.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z`,deepseek:`M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45`,qwen:`M23.919 14.545 20.817 9.17l1.47-2.544a.56.56 0 0 0 0-.566l-1.633-2.83a.57.57 0 0 0-.49-.283h-6.207L12.487.402a.57.57 0 0 0-.49-.284H8.732a.56.56 0 0 0-.49.284L5.139 5.775h-2.94a.56.56 0 0 0-.49.284L.077 8.887a.56.56 0 0 0 0 .567L3.18 14.83l-1.47 2.545a.56.56 0 0 0 0 .566l1.634 2.83a.57.57 0 0 0 .49.283h6.205l1.47 2.545a.57.57 0 0 0 .49.284h3.266a.57.57 0 0 0 .49-.284l3.104-5.375h2.94a.57.57 0 0 0 .49-.283l1.634-2.828a.55.55 0 0 0-.004-.568M8.733.686l1.634 2.828-1.634 2.828H21.8L20.164 9.17H7.425L5.63 6.06Zm1.306 19.801-6.205-.002 1.634-2.83h3.265L2.201 6.344h3.267q3.182 5.517 6.367 11.032zm10.124-5.66L18.53 12l-6.532 11.315-1.634-2.83c2.129-3.673 4.25-7.351 6.373-11.028h3.592l3.102 5.374z`,"claude-code":`M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z`,codex:`M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z`,opencode:`M22 24H2V0h20zM17 4.8H7v14.4h10z`,"gemini-cli":Ge},qe=t(`<path fill="currentColor"></path>`),Je=t(`<rect x="1.5" y="1.5" width="21" height="21" rx="6" fill="none" stroke="currentColor" stroke-width="1.8"></rect><text x="12" y="12.5" text-anchor="middle" dominant-baseline="central" fill="currentColor" font-weight="600" font-family="var(--sans)"> </text>`,1),Ye=t(`<svg class="mark svelte-jlywqn" viewBox="0 0 24 24" role="img"><!></svg>`);function Xe(t,o){e(o,!0);let s=H(o,`size`,3,16),l=S(()=>Ke[o.id]),u=S(()=>o.label.replace(/[^a-z ]/gi,``).split(` `).map(e=>e[0]).join(``).slice(0,2).toUpperCase());var d=Ye();let f;var m=y(d),h=e=>{var t=qe();n(()=>T(t,`d`,i(l))),r(e,t)},_=e=>{var t=Je(),o=z(a(t)),s=c(o,!0);n(()=>{T(o,`font-size`,i(u).length>1?9:12),g(s,i(u))}),r(e,t)};w(m,e=>{i(l)?e(h):e(_,-1)}),U(d),n(()=>{T(d,`width`,s()),T(d,`height`,s()),T(d,`aria-label`,o.label),f=O(d,``,f,{color:o.colour})}),r(t,d),p()}var Ze=N(`<i class="dot svelte-eh60s9"></i>`),Qe=N(`<em class="svelte-eh60s9"> </em>`),$e=N(`<span class="fill svelte-eh60s9"></span> <span class="label svelte-eh60s9"><!> <b class="svelte-eh60s9"> </b> <!></span> <span class="value num svelte-eh60s9"> </span>`,1),et=N(`<li><!></li>`),tt=N(`<ul class="bars svelte-eh60s9"></ul>`),nt=N(`<p class="empty svelte-eh60s9"> </p>`);function rt(t,o){e(o,!0);let s=H(o,`active`,19,()=>[]),l=H(o,`empty`,3,`Nothing in this range`),u=S(()=>Math.max(1,...o.rows.map(e=>e.value)));var f=d(),m=a(f),h=e=>{var t=tt();W(t,21,()=>o.rows,e=>e.id,(e,t)=>{var l=et(),d=y(l);k(d,()=>o.onpick?`button`:`div`,!1,(e,l)=>{F(e,(e,t)=>K?.(e,t),()=>i(t).hint);var d=()=>o.onpick?.(i(t).id);L(e,e=>({class:`row`,role:o.onpick?`button`:void 0,tabindex:o.onpick?0:void 0,onclick:d,[C]:{on:e}}),[()=>s().includes(i(t).id)],void 0,void 0,`svelte-eh60s9`);var f=$e(),p=a(f),m=z(p,2),h=y(m),_=e=>{Xe(e,{get id(){return i(t).mark},get label(){return i(t).label},get colour(){return i(t).colour},size:15})},v=e=>{var a=Ze();n(()=>O(a,`background: ${i(t).colour??``}`)),r(e,a)};w(h,e=>{i(t).mark?e(_):e(v,-1)});var b=z(h,2),x=c(b,!0),S=z(b,2),T=e=>{var a=Qe(),o=c(a,!0);n(()=>g(o,i(t).detail)),r(e,a)};w(S,e=>{i(t).detail&&e(T)}),U(m);var E=z(m,2),D=c(E,!0);n(()=>{O(p,`width: ${i(t).value/i(u)*100}%; background: ${i(t).colour??``}`),g(x,i(t).label),g(D,i(t).display)}),r(l,f)}),U(l),r(e,l)}),U(t),r(e,t)},_=e=>{var t=nt(),i=c(t,!0);n(()=>g(i,l())),r(e,t)};w(m,e=>{o.rows.length?e(h):e(_,-1)}),r(t,f),p()}var it=t(`<circle cx="70" cy="70" fill="none" stroke-width="18" transform="rotate(-90 70 70)" class="svelte-1o711x0"></circle>`),at=N(`<div class="donut svelte-1o711x0"><svg viewBox="0 0 140 140" role="img" class="svelte-1o711x0"><circle cx="70" cy="70" fill="none" stroke="var(--surface-3)" stroke-width="18" class="svelte-1o711x0"></circle><!><text class="centre num svelte-1o711x0" x="70" y="66" text-anchor="middle"> </text><text class="sub svelte-1o711x0" x="70" y="84" text-anchor="middle"> </text></svg></div>`);function ot(t,a){e(a,!0);let o=2*Math.PI*52,s=S(()=>{let e=a.slices.reduce((e,t)=>e+t.value,0)||1,t=0;return a.slices.map(n=>{let r=n.value/e*o,i={...n,length:r,offset:t,share:n.value/e*100};return t+=r,i})});var l=at(),u=y(l),d=y(u);T(d,`r`,52);var f=z(d);W(f,17,()=>i(s),e=>e.id,(e,t)=>{var a=it();T(a,`r`,52),F(a,(e,t)=>K?.(e,t),()=>`${i(t).label} - ${i(t).display} (${i(t).share.toFixed(1)}%)`),n(e=>{T(a,`stroke`,i(t).colour),T(a,`stroke-dasharray`,`${e??``} 326.7256359733385`),T(a,`stroke-dashoffset`,-i(t).offset)},[()=>Math.max(0,i(t).length-2)]),r(e,a)});var m=z(f),h=c(m,!0),_=z(m),v=c(_,!0);U(u),U(l),n(()=>{T(u,`aria-label`,a.caption),g(h,a.centre),g(v,a.caption)}),r(t,l),p()}var st=N(`<span class="svelte-1qwkpf0"></span>`),ct=N(`<li class="svelte-1qwkpf0"><i class="svelte-1qwkpf0"></i> <span class="name svelte-1qwkpf0"> </span> <span class="value num svelte-1qwkpf0"> </span> <span class="share num svelte-1qwkpf0"> </span></li>`),lt=N(`<div class="split svelte-1qwkpf0"><div class="bar svelte-1qwkpf0"></div> <ul class="svelte-1qwkpf0"></ul></div>`);function ut(t,o){e(o,!0);let s=S(()=>o.parts.reduce((e,t)=>e+t.value,0)||1);var l=lt(),u=y(l);W(u,21,()=>o.parts,e=>e.id,(e,t)=>{var o=d(),c=a(o),l=e=>{var a=st();F(a,(e,t)=>K?.(e,t),()=>`${i(t).label} - ${i(t).display} (${(i(t).value/i(s)*100).toFixed(1)}%)`),n(()=>O(a,`flex: ${i(t).value??``}; background: ${i(t).colour??``}`)),r(e,a)};w(c,e=>{i(t).value>0&&e(l)}),r(e,o)}),U(u);var f=z(u,2);W(f,21,()=>o.parts,e=>e.id,(e,t)=>{var a=ct(),o=y(a),l=z(o,2),u=c(l,!0),d=z(l,2),f=c(d,!0),p=z(d,2),m=c(p);U(a),F(a,(e,t)=>K?.(e,t),()=>i(t).hint),n(e=>{O(o,`background: ${i(t).colour??``}`),g(u,i(t).label),g(f,i(t).display),g(m,`${e??``}%`)},[()=>(i(t).value/i(s)*100).toFixed(1)]),r(e,a)}),U(f),U(l),r(t,l),p()}var dt=N(`<i class="svelte-13d36y"></i>`),ft=N(`<span class="day svelte-13d36y"> </span> <div class="hours svelte-13d36y"></div>`,1),pt=N(`<span> </span>`),mt=N(`<div class="clock svelte-13d36y"><div class="rows svelte-13d36y"></div> <div class="scale svelte-13d36y"><!> <span>23</span></div></div>`);function ht(t,o){e(o,!0);let s=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],l=S(()=>{let e=new Map;for(let t of o.points){let n=(t.day+6)%7;e.set(`${n}-${t.hour}`,(e.get(`${n}-${t.hour}`)??0)+t.total)}return e}),u=S(()=>Math.max(1,...i(l).values())),d=e=>e?.32+.68*Math.sqrt(e/i(u)):0;var f=mt(),m=y(f);W(m,22,()=>s,e=>e,(e,t,o)=>{var s=ft(),u=a(s),f=c(u,!0),p=z(u,2);W(p,20,()=>Array(24),ne,(e,a,s)=>{let c=S(()=>i(l).get(`${i(o)}-${s}`)??0);var u=dt();F(u,(e,t)=>K?.(e,t),()=>`${t} ${String(s).padStart(2,`0`)}:00 - ${i(c)?`${J(i(c))} tokens`:`nothing`}`),n(e=>O(u,`--dot: ${e??``}`),[()=>d(i(c))]),r(e,u)}),U(p),n(()=>g(f,t)),r(e,s)}),U(m);var h=z(m,2),_=y(h);W(_,16,()=>[0,6,12,18],e=>e,(e,t)=>{var i=pt(),a=c(i,!0);n(e=>g(a,e),[()=>String(t).padStart(2,`0`)]),r(e,i)}),D(2),U(h),U(f),r(t,f),p()}var gt=N(`<div><div class="top svelte-tlhxud"><span class="name svelte-tlhxud"> </span> <span class="num pct svelte-tlhxud"> </span></div> <div class="track svelte-tlhxud" role="meter" aria-valuemin="0" aria-valuemax="100"><span class="svelte-tlhxud"></span></div> <span class="reset svelte-tlhxud"><!></span></div>`);function _t(t,a){e(a,!0);let o=S(()=>!!a.window.resets_at&&a.window.resets_at<Date.now()),s=S(()=>i(o)?`text-faint`:a.window.used_percent>=90?`bad`:a.window.used_percent>=70?`warn`:`good`),l=S(()=>[a.window.detail,a.window.resets_at?`resets ${Ce(a.window.resets_at)}`:``,`seen ${Ce(a.window.seen_at)}`].filter(Boolean).join(` - `));var u=gt();let d;var f=y(u),m=y(f),h=c(m,!0),_=z(m,2),v=c(_);U(f);var b=z(f,2),x=c(b),C=z(b,2),E=y(C),D=e=>{var t=M();n(e=>g(t,`window has turned over, last read ${e??``}`),[()=>Ce(a.window.seen_at)]),r(e,t)},k=e=>{var t=M();n(e=>g(t,`resets ${e??``}`),[()=>Ce(a.window.resets_at)]),r(e,t)};w(E,e=>{i(o)?e(D):a.window.resets_at&&e(k,1)}),U(C),U(u),F(u,(e,t)=>K?.(e,t),()=>i(l)),n((e,t,n)=>{d=R(u,1,`meter svelte-tlhxud`,null,d,{stale:i(o)}),g(h,a.window.label),O(_,`color: var(--${i(s)??``})`),g(v,`${e??``}%`),T(b,`aria-valuenow`,t),T(b,`aria-label`,a.window.label),O(x,`width: ${n??``}%; background: var(--${i(s)??``})`)},[()=>Math.round(a.window.used_percent),()=>Math.round(a.window.used_percent),()=>Math.min(100,a.window.used_percent)]),r(t,u),p()}var vt=[{id:`anthropic`,label:`Anthropic`,colour:`#d97757`},{id:`openai`,label:`OpenAI`,colour:`#10a37f`},{id:`google`,label:`Google`,colour:`#4285f4`},{id:`meta`,label:`Meta`,colour:`#0668e1`},{id:`mistral`,label:`Mistral`,colour:`#fa520f`},{id:`xai`,label:`xAI`,colour:`#7c7c8a`},{id:`deepseek`,label:`DeepSeek`,colour:`#4d6bfe`},{id:`qwen`,label:`Qwen`,colour:`#a855f7`},{id:`unknown`,label:`Other`,colour:`#8b93a7`}],yt=[[/^claude/,`anthropic`],[/^(gpt|codex|o[1-4]-|chatgpt|text-embedding)/,`openai`],[/^(gemini|gemma|palm)/,`google`],[/^(llama|code-?llama)/,`meta`],[/^(mistral|mixtral|codestral|magistral|devstral)/,`mistral`],[/^grok/,`xai`],[/^deepseek/,`deepseek`],[/^(qwen|qwq)/,`qwen`]];function bt(e){let t=e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e,n=e.includes(`/`)?e.slice(0,e.indexOf(`/`)).toLowerCase():``;return vt.some(e=>e.id===n)?n:yt.find(([e])=>e.test(t.toLowerCase()))?.[1]??`unknown`}var xt=e=>vt.find(t=>t.id===e)??vt[vt.length-1],St=(e,t)=>t?`color-mix(in oklch, ${e}, ${t%2?`black`:`white`} ${Math.min(Math.ceil(t/2)*18,72)}%)`:e;function Ct(e){let t=new Map;return Object.fromEntries(e.map(e=>{let n=bt(e),r=t.get(n)??0;return t.set(n,r+1),[e,St(xt(n).colour,r)]}))}var wt=[{id:`claude-code`,label:`Claude Code`,colour:`#d97757`,home:`https://claude.com/claude-code`},{id:`codex`,label:`Codex`,colour:`#10a37f`,home:`https://developers.openai.com/codex`},{id:`opencode`,label:`OpenCode`,colour:`#f5a524`,home:`https://opencode.ai`},{id:`gemini-cli`,label:`Gemini CLI`,colour:`#4285f4`,home:`https://github.com/google-gemini/gemini-cli`}],Tt=e=>wt.find(t=>t.id===e)??{id:e,label:e,colour:`#8b93a7`,home:``},Et=e=>e===null?`--`:be(e*100),Dt=[{id:`session`,label:`Session`,hint:`The tool and its session id`,by:e=>e.id},{id:`name`,label:`Session name`,hint:`What the session was called, if it got a name`,by:e=>e.name,show:e=>e.name??``},{id:`project`,label:`Project`,hint:`Where it ran`,by:e=>e.project},{id:`models`,label:`Models`,hint:`Every model the session used`,by:e=>e.models,show:e=>e.models.split(`, `).map(De).join(`, `)},{id:`ran`,label:`Ran`,hint:`When it last did anything`,by:e=>e.ended,show:e=>we(e.ended)},{id:`tokens`,label:`Tokens`,hint:`Everything in and out, cache included`,by:e=>e.total,show:e=>J(e.total),numeric:!0},{id:`cost`,label:`Est. cost`,hint:`Worked out from list prices, not your bill`,by:e=>e.cost,show:e=>X(e.cost),numeric:!0},{id:`peak`,label:`Peak context`,hint:`The biggest prompt the model was handed in one go`,by:e=>e.peak,show:e=>J(e.peak),numeric:!0},{id:`cache`,label:`Cache hits`,hint:`How much of the input came straight from cache`,by:e=>e.cacheHit,show:e=>Et(e.cacheHit),numeric:!0},{id:`subagents`,label:`Subagents`,hint:`Share of the tokens spent by subagents. Claude Code only.`,by:e=>e.subagents,show:e=>Et(e.subagents),numeric:!0},{id:`turns`,label:`Turns`,hint:`Replies from the model, subagents included`,by:e=>e.turns,show:e=>String(e.turns),numeric:!0}],Ot=N(`<th scope="col"><button type="button" class="svelte-1uqtl83"> </button></th>`),kt=N(`<td class="svelte-1uqtl83"><span class="tool svelte-1uqtl83"><!> <span class="id mono svelte-1uqtl83"> </span></span></td>`),At=N(`<td class="svelte-1uqtl83"><button type="button" class="link svelte-1uqtl83"> </button></td>`),jt=N(`<td class="svelte-1uqtl83"> </td>`),Mt=N(`<td> </td>`),Nt=N(`<tr class="svelte-1uqtl83"></tr>`),Pt=N(`<div class="scroll svelte-1uqtl83"><table class="svelte-1uqtl83"><thead><tr></tr></thead><tbody class="svelte-1uqtl83"></tbody></table></div>`),Ft=N(`<p class="empty svelte-1uqtl83">No sessions in this range</p>`);function It(t,o){e(o,!0);let s=b(`ran`),l=b(!0),f=S(()=>Dt.filter(e=>!o.hidden.includes(e.id)&&(e.id!==`name`||o.rows.some(e=>e.name)))),m=S(()=>{let e=(Dt.find(e=>e.id===i(s))??Dt[0]).by;return o.rows.toSorted((t,n)=>{let[r,a]=[e(t),e(n)];if(r===a)return 0;if(r===null)return 1;if(a===null)return-1;let o=r<a?-1:1;return i(l)?-o:o})});function h(e){x(l,i(s)===e.id?!i(l):!!(e.numeric||e.id===`ran`),!0),x(s,e.id,!0)}var _=d(),v=a(_),C=e=>{var t=Pt(),p=y(t),_=y(p),v=y(_);W(v,21,()=>i(f),e=>e.id,(e,t)=>{var a=Ot();let o;var d=y(a),f=c(d,!0);F(d,(e,t)=>K?.(e,t),()=>i(t).hint),U(a),n(()=>{T(a,`aria-sort`,i(s)===i(t).id?i(l)?`descending`:`ascending`:`none`),o=R(a,1,`svelte-1uqtl83`,null,o,{right:i(t).numeric}),g(f,i(t).label)}),u(`click`,d,()=>h(i(t))),r(e,a)}),U(v),U(_);var b=z(_);W(b,21,()=>i(m),e=>`${e.tool}:${e.id}`,(e,t)=>{let s=S(()=>Tt(i(t).tool));var l=Nt();W(l,21,()=>i(f),e=>e.id,(e,l)=>{var f=d(),p=a(f),m=e=>{var a=kt(),o=y(a),l=y(o);Xe(l,{get id(){return i(t).tool},get label(){return i(s).label},get colour(){return i(s).colour},size:14});var u=z(l,2),d=c(u,!0);F(u,(e,t)=>K?.(e,t),()=>i(t).id),U(o),U(a),n(e=>g(d,e),[()=>i(t).id.slice(0,8)]),r(e,a)},h=e=>{var a=At(),s=y(a),l=c(s,!0);F(s,(e,t)=>K?.(e,t),()=>i(t).project||`unknown`),U(a),n(e=>g(l,e),[()=>Ee(i(t).project)]),u(`click`,s,()=>o.onpick?.(i(t).project)),r(e,a)},_=e=>{var a=jt(),o=c(a,!0);F(a,(e,t)=>K?.(e,t),()=>`${we(i(t).started)} for ${Te(i(t).ended-i(t).started)}`),n(e=>g(o,e),[()=>i(l).show?.(i(t))]),r(e,a)},v=e=>{var a=Mt();let o;var s=c(a,!0);n(e=>{o=R(a,1,`svelte-1uqtl83`,null,o,{right:i(l).numeric,num:i(l).numeric,muted:!i(l).numeric}),g(s,e)},[()=>i(l).show?.(i(t))]),r(e,a)};w(p,e=>{i(l).id===`session`?e(m):i(l).id===`project`?e(h,1):i(l).id===`ran`?e(_,2):e(v,-1)}),r(e,f)}),U(l),r(e,l)}),U(b),U(p),U(t),r(e,t)},E=e=>{var t=Ft();r(e,t)};w(v,e=>{o.rows.length?e(C):e(E,-1)}),r(t,_),p()}l([`click`]);var Lt=N(`<label class="svelte-17j4bwj"><input type="checkbox" class="svelte-17j4bwj"/> <span> </span></label>`),Rt=N(`<div class="menu svelte-17j4bwj"></div>`),zt=N(`<div class="fields svelte-17j4bwj"><button type="button" class="trigger svelte-17j4bwj" aria-label="Choose columns"><svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M2.5 4h11M2.5 8h11M2.5 12h11M6 2.5v11M10 2.5v11" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path></svg></button> <!></div>`);function Bt(t,a){e(a,!0);let o=H(a,`hidden`,15),s=b(!1),l,d=e=>{o(o().includes(e)?o().filter(t=>t!==e):[...o(),e]),a.onchange?.(o())},m=e=>{i(s)&&!l.contains(e.target)&&x(s,!1)};var h=zt();f(`click`,_,m);var v=y(h);F(v,(e,t)=>K?.(e,t),()=>`Choose columns`);var S=z(v,2),C=e=>{var t=Rt();W(t,21,()=>a.options,e=>e.id,(e,t)=>{var a=Lt(),s=y(a);V(s);var l=z(s,2),f=c(l,!0);U(a),n(e=>{P(s,e),g(f,i(t).label)},[()=>!o().includes(i(t).id)]),u(`change`,s,()=>d(i(t).id)),r(e,a)}),U(t),r(e,t)};w(S,e=>{i(s)&&e(C)}),U(h),I(h,e=>l=e,()=>l),n(()=>T(v,`aria-expanded`,i(s))),u(`click`,v,()=>x(s,!i(s))),r(t,h),p()}l([`click`,`change`]);var Vt=N(`<span class="hint svelte-1vaf4tg"> </span>`),Ht=N(`<li class="svelte-1vaf4tg"><div class="svelte-1vaf4tg"><b class="svelte-1vaf4tg"> </b> <span class="svelte-1vaf4tg"> </span> <!> <time class="svelte-1vaf4tg"> </time></div> <button type="button" class="close svelte-1vaf4tg" aria-label="Dismiss"><svg viewBox="0 0 16 16" width="13" height="13" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg></button></li>`),Ut=N(`<ul class="svelte-1vaf4tg"></ul>`),Wt=N(`<aside aria-live="polite"><button type="button" class="head svelte-1vaf4tg"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><circle cx="8" cy="8" r="6.6" fill="none" stroke="currentColor" stroke-width="1.5"></circle><path d="M8 4.6v4.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path><circle cx="8" cy="11.4" r="0.9" fill="currentColor"></circle></svg> <span class="svelte-1vaf4tg"> </span> <em class="svelte-1vaf4tg"> </em></button> <!></aside>`);function Gt(t,o){e(o,!0);let l=b(s([])),f=b(!1),m=S(()=>o.problems.filter(e=>!i(l).includes(e.id))),h=S(()=>i(m).some(e=>e.level===`error`)?`error`:i(m).some(e=>e.level===`warn`)?`warn`:`info`);var _=d(),v=a(_),C=e=>{var t=Wt(),a=y(t),o=z(y(a),2),s=c(o,!0),d=z(o,2),p=c(d,!0);U(a);var _=z(a,2),v=e=>{var t=Ut();W(t,21,()=>i(m),e=>e.id,(e,t)=>{var a=Ht(),o=y(a),s=y(o),d=c(s,!0),f=z(s,2),p=c(f,!0),m=z(f,2),h=e=>{var a=Vt(),o=c(a,!0);n(()=>g(o,i(t).hint)),r(e,a)};w(m,e=>{i(t).hint&&e(h)});var _=z(m,2),v=c(_,!0);U(o);var b=z(o,2);U(a),n(e=>{g(d,i(t).scope),g(p,i(t).message),g(v,e)},[()=>Ce(i(t).at)]),u(`click`,b,()=>x(l,[...i(l),i(t).id],!0)),r(e,a)}),U(t),r(e,t)};w(_,e=>{i(f)&&e(v)}),U(t),n(()=>{R(t,1,`problems ${i(h)??``}`,`svelte-1vaf4tg`),T(a,`aria-expanded`,i(f)),g(s,i(m).length===1?i(m)[0].message:`${i(m).length} things need a look`),g(p,i(f)?`Hide`:`Details`)}),u(`click`,a,()=>x(f,!i(f))),r(e,t)};w(v,e=>{i(m).length&&e(C)}),r(t,_),p()}l([`click`]);var Kt=[{id:`today`,label:`Today`,days:1},{id:`7d`,label:`7 days`,days:7},{id:`30d`,label:`30 days`,days:30},{id:`90d`,label:`90 days`,days:90},{id:`1y`,label:`12 months`,days:365},{id:`all`,label:`All time`,days:0}],qt=e=>Kt.find(t=>t.id===e)?.label??`30 days`,Q=(e,t,n=.1)=>({input:e,output:t,cacheRead:e*n,cacheWrite:e*1.25}),$=(e,t)=>({input:e,output:t,cacheRead:e*.1,cacheWrite:0}),Jt={"claude-fable-5-1":Q(10,50,.025),"claude-fable-5":Q(10,50),"claude-opus-5-5":Q(4,20,.05),"claude-opus-5":Q(5,25),"claude-opus-4-8":Q(5,25),"claude-opus-4-7":Q(5,25),"claude-opus-4-6":Q(5,25),"claude-opus-4-5":Q(5,25),"claude-opus-4-1":Q(15,75),"claude-sonnet-5":Q(2,10),"claude-sonnet-4-6":Q(3,15),"claude-sonnet-4-5":Q(3,15),"claude-sonnet-4":Q(3,15),"claude-haiku-5-5":Q(.1,.5),"claude-haiku-4-5":Q(1,5),"claude-3-5-haiku":Q(.8,4),"gpt-5.6-sol-pro":$(2.5,15),"gpt-5.6-sol":$(2.5,15),"gpt-5.6-terra":$(2,12),"gpt-5.6-luna":$(.2,1.2),"gpt-5":$(1.25,10),"gpt-5-mini":$(.25,2),"gpt-5-nano":$(.05,.4),"gpt-4.1":$(2,8),"gpt-4o":$(2.5,10),"gemini-3-pro":$(2,12),"gemini-2.5-pro":$(1.25,10),"gemini-2.5-flash":$(.3,2.5)},Yt=[{id:`auto`,label:`Match the system`},{id:`light`,label:`Light`},{id:`dark`,label:`Dark`},{id:`dracula`,label:`Dracula`},{id:`catppuccin`,label:`Catppuccin Mocha`},{id:`tokyo-night`,label:`Tokyo Night`},{id:`nord`,label:`Nord`},{id:`gruvbox`,label:`Gruvbox dark`},{id:`solarized`,label:`Solarized dark`}],Xt=N(`<option> </option>`),Zt=N(`<li class="svelte-anx9w7"><div><b class="svelte-anx9w7"> </b> <code class="svelte-anx9w7"> </code></div> <span> </span></li>`),Qt=N(`<code class="svelte-anx9w7"> </code> `,1),$t=N(`<li class="svelte-anx9w7"><code class="svelte-anx9w7"> </code> <span class="num"> </span> <button type="button" class="svelte-anx9w7">Remove</button></li>`),en=N(`<ul class="prices svelte-anx9w7"></ul>`),tn=N(`<dialog aria-labelledby="settings-title" class="svelte-anx9w7"><header class="svelte-anx9w7"><h2 id="settings-title" class="svelte-anx9w7">Settings</h2> <button type="button" class="close svelte-anx9w7" aria-label="Close settings"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg></button></header> <div class="body svelte-anx9w7"><section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Appearance</h3> <label class="field svelte-anx9w7"><span>Theme</span> <select class="svelte-anx9w7"></select></label> <label class="field svelte-anx9w7"><span>Range on open</span> <select class="svelte-anx9w7"></select></label> <label class="field svelte-anx9w7"><span>Headline measure</span> <select class="svelte-anx9w7"><option>Tokens</option><option>Estimated cost</option></select></label></section> <section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Data</h3> <ul class="sources svelte-anx9w7"></ul> <p class="note svelte-anx9w7">Point these somewhere else with <!>. History lives in <code class="svelte-anx9w7"> </code> and outlives the transcripts, which most tools prune.</p> <label class="field svelte-anx9w7"><span>Rescan every</span> <select class="svelte-anx9w7"><option>30 seconds</option><option>2 minutes</option><option>10 minutes</option><option>an hour</option></select></label> <label class="check svelte-anx9w7"><input type="checkbox" class="svelte-anx9w7"/> <span>Ask Anthropic for your 5-hour and 7-day windows <em class="svelte-anx9w7">Reads the Claude Code credentials on this machine. Nothing else leaves it.</em></span></label> <div class="row svelte-anx9w7"><button type="button" class="action svelte-anx9w7">Rescan now</button> <span class="note svelte-anx9w7"> </span></div></section> <section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Prices</h3> <p class="note svelte-anx9w7"> </p> <!> <div class="add svelte-anx9w7"><input placeholder="model id" class="svelte-anx9w7"/> <input placeholder="in" inputmode="decimal" class="svelte-anx9w7"/> <input placeholder="out" inputmode="decimal" class="svelte-anx9w7"/> <button type="button" class="action svelte-anx9w7">Add</button></div></section></div></dialog>`);function nn(t,o){e(o,!0);let s=H(o,`open`,15),l,d=b(``),m=b(``),h=b(``);v(()=>{s()&&!l.open&&l.showModal(),!s()&&l.open&&l.close()});let _=S(()=>Object.entries(o.saved.prices));function C(){let e=Number(i(m)),t=Number(i(h));i(d).trim()&&Number.isFinite(e)&&Number.isFinite(t)&&(o.onsave({prices:{...o.saved.prices,[i(d).trim()]:{input:e,output:t,cacheRead:e*.1,cacheWrite:e*1.25}}}),x(d,``),x(m,``),x(h,``))}function T(e){let t={...o.saved.prices};delete t[e],o.onsave({prices:t})}let O={"claude-code":`AIUSAGE_CLAUDE_DIR`,codex:`AIUSAGE_CODEX_DIR`,opencode:`AIUSAGE_OPENCODE_DIR`};var k=tn(),A=y(k),M=z(y(A),2);U(A);var N=z(A,2),F=y(N),L=z(y(F),2),B=z(y(L),2);W(B,21,()=>Yt,e=>e.id,(e,t)=>{var a=Xt(),o=c(a,!0),s={};n(()=>{g(o,i(t).label),s!==(s=i(t).id)&&(a.value=(a.__value=s)??``)}),r(e,a)}),U(B);var ne;te(B),U(L);var re=z(L,2),ie=z(y(re),2);W(ie,21,()=>Kt,e=>e.id,(e,t)=>{var a=Xt(),o=c(a,!0),s={};n(()=>{g(o,i(t).label),s!==(s=i(t).id)&&(a.value=(a.__value=s)??``)}),r(e,a)}),U(ie);var G;te(ie),U(re);var ae=z(re,2),K=z(y(ae),2),oe=y(K);oe.value=oe.__value=`tokens`;var se=z(oe);se.value=se.__value=`cost`,U(K);var q;te(K),U(ae),U(F);var ce=z(F,2),le=z(y(ce),2);W(le,21,()=>o.sources,e=>e.id,(e,t)=>{var a=Zt(),o=y(a),s=y(o),l=c(s,!0),u=z(s,2),d=c(u,!0);U(o);var f=z(o,2);let p;var m=c(f,!0);U(a),n(()=>{g(l,i(t).label),g(d,i(t).root),p=R(f,1,`badge svelte-anx9w7`,null,p,{on:i(t).present}),g(m,i(t).present?`${i(t).files} files`:`not found`)}),r(e,a)}),U(le);var ue=z(le,2),de=z(y(ue));W(de,19,()=>o.sources,e=>e.id,(e,t,s)=>{var l=Qt(),u=a(l),d=c(u,!0),f=z(u,1,!0);n(()=>{g(d,O[i(t).id]??i(t).id),g(f,i(s)<o.sources.length-1?`, `:``)}),r(e,l)});var fe=z(de,2),pe=c(fe,!0);D(),U(ue);var me=z(ue,2),he=z(y(me),2),ge=y(he);ge.value=ge.__value=`30`;var _e=z(ge);_e.value=_e.__value=`120`;var ve=z(_e);ve.value=ve.__value=`600`;var J=z(ve);J.value=J.__value=`3600`,U(he);var Y;te(he),U(me);var X=z(me,2),ye=y(X);V(ye),D(2),U(X);var be=z(X,2),xe=y(be),Se=z(xe,2),Z=c(Se);U(be),U(ce);var we=z(ce,2),Te=z(y(we),2),Ee=c(Te),De=z(Te,2),Oe=e=>{var t=en();W(t,21,()=>i(_),([e,t])=>e,(e,t)=>{var a=S(()=>ee(i(t),2));let o=()=>i(a)[0],s=()=>i(a)[1];var l=$t(),d=y(l),f=c(d,!0),p=z(d,2),m=c(p),h=z(p,2);U(l),n(()=>{g(f,o()),g(m,`in ${s().input??``} / out ${s().output??``}`)}),u(`click`,h,()=>T(o())),r(e,l)}),U(t),r(e,t)};w(De,e=>{i(_).length&&e(Oe)});var ke=z(De,2),Ae=y(ke);V(Ae);var je=z(Ae,2);V(je);var Me=z(je,2);V(Me);var Ne=z(Me,2);U(ke),U(we),U(N),U(k),I(k,e=>l=e,()=>l),n((e,t,n)=>{ne!==(ne=o.saved.theme)&&(B.value=(B.__value=ne)??``,E(B,ne)),G!==(G=o.saved.range)&&(ie.value=(ie.__value=G)??``,E(ie,G)),q!==(q=o.saved.metric)&&(K.value=(K.__value=q)??``,E(K,q)),g(pe,o.dbPath),Y!==(Y=e)&&(he.value=(he.__value=Y)??``,E(he,Y)),P(ye,o.saved.claudeWindows),g(Z,`Last scan ${t??``}`),g(Ee,`Dollars per million tokens. ${n??``} models are priced out of the box; anything
|
|
2
|
+
you add here wins, and an unknown model is reported rather than counted as free.`)},[()=>String(o.saved.scanIntervalSec),()=>Ce(o.scannedAt),()=>Object.keys(Jt).length]),f(`close`,k,()=>s(!1)),u(`pointerdown`,k,e=>{e.target===l&&s(!1)}),u(`click`,M,()=>s(!1)),u(`change`,B,e=>o.onsave({theme:e.currentTarget.value})),u(`change`,ie,e=>o.onsave({range:e.currentTarget.value})),u(`change`,K,e=>o.onsave({metric:e.currentTarget.value})),u(`change`,he,e=>o.onsave({scanIntervalSec:Number(e.currentTarget.value)})),u(`change`,ye,e=>o.onsave({claudeWindows:e.currentTarget.checked})),u(`click`,xe,function(...e){o.onrescan?.apply(this,e)}),j(Ae,()=>i(d),e=>x(d,e)),j(je,()=>i(m),e=>x(m,e)),j(Me,()=>i(h),e=>x(h,e)),u(`click`,Ne,C),r(t,k),p()}l([`pointerdown`,`click`,`change`]);var rn=t(`<rect width="4" height="4" rx="1.2" fill="var(--accent-text)"></rect>`),an=t(`<svg class="logo svelte-nck4wt" viewBox="0 0 32 32" role="img" aria-label="Token usage dashboard"><rect width="32" height="32" rx="8" fill="var(--accent)"></rect><!></svg>`);function on(t,a){e(a,!0);let o=H(a,`size`,3,28),s=[0,1,2,3].flatMap(e=>[0,1,2,3].map(t=>({row:e,column:t,heat:(t+(3-e))/6})));var c=an(),l=z(y(c));W(l,17,()=>s,e=>`${e.row}-${e.column}`,(e,t)=>{var a=rn();n(e=>{T(a,`x`,5+i(t).column*6),T(a,`y`,5+i(t).row*6),T(a,`opacity`,e)},[()=>(.22+i(t).heat*.78).toFixed(2)]),r(e,a)}),U(c),n(()=>{T(c,`width`,o()),T(c,`height`,o())}),r(t,c),p()}var sn=N(`<button type="button" class="reset svelte-1uha8ag">Clear filters</button>`),cn=N(`<div class="meters svelte-1uha8ag"></div>`),ln=N(`<p class="empty svelte-1uha8ag">No plan windows yet. Sign in with Claude Code or run Codex once and they turn up here.</p>`),un=N(`<li class="svelte-1uha8ag"><!> <span class="svelte-1uha8ag"> </span> <b class="num svelte-1uha8ag"> </b></li>`),dn=N(`<div class="share svelte-1uha8ag"><!> <ul class="key svelte-1uha8ag"></ul></div>`),fn=N(`<!> <p class="aside svelte-1uha8ag"> </p>`,1),pn=N(`<header class="bar svelte-1uha8ag"><a class="brand svelte-1uha8ag" href="/"><!> <span>Token usage</span></a> <div class="filters svelte-1uha8ag"><!> <!> <!> <!> <!> <!></div> <div class="tools svelte-1uha8ag"><button type="button" aria-label="Rescan now"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" class="svelte-1uha8ag"><path d="M13.4 7A5.5 5.5 0 1 0 12.6 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path><path d="M13.8 3.4v3.8h-3.8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon svelte-1uha8ag" aria-label="Settings"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="2.3" fill="none" stroke="currentColor" stroke-width="1.5"></circle><path d="M8 1.6v1.8M8 12.6v1.8M14.4 8h-1.8M3.4 8H1.6M12.5 3.5l-1.3 1.3M4.8 11.2l-1.3 1.3M12.5 12.5l-1.3-1.3M4.8 4.8 3.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path></svg></button></div></header> <main class="svelte-1uha8ag"><!> <div class="grid svelte-1uha8ag"><!> <!> <!> <!> <!> <!> <!> <!> <!></div> <footer class="svelte-1uha8ag"><span>Reads the transcripts already on this machine. Nothing is sent anywhere.</span> <span><!> </span></footer></main> <!> <!>`,1);function mn(t,l){e(l,!0);let f=m(()=>l.data),h=b(s(f.usage)),_=b(s(f.settings)),C=b(!1),T=b(!1),E=b(s(f.usage.filters.range)),O=b(s(f.usage.filters.tools)),k=b(s(f.usage.filters.models)),j=b(s(f.usage.filters.projects)),N=b(s(f.settings.metric)),P=b(`tool`),I=b(`share`),L=b(`measure`),B=b(s(f.settings.hiddenColumns)),ee=S(()=>new URLSearchParams({range:i(E),tools:i(O).join(`,`),models:i(k).join(`,`),projects:i(j).join(`,`)}).toString()),V=m(()=>i(ee));async function H(e){x(C,!0);try{let t=await fetch(`/api/usage?${e}`);t.ok&&x(h,await t.json(),!0)}finally{x(C,!1)}}v(()=>{i(ee)!==V&&(V=i(ee),ie(`?${i(ee)}`,{shallow:!0,replace:!0}),H(i(ee)))}),v(()=>{let e=setInterval(()=>void H(V),3e4);return()=>clearInterval(e)}),v(()=>{let e=i(_).theme;document.documentElement.dataset.theme=e===`auto`?``:e});let te=(e,t={})=>fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)});async function ne(e){let t=await te(`/api/settings`,e);t.ok&&x(_,await t.json(),!0)}async function G(){x(C,!0);try{let e=await te(`/api/refresh?${V}`);e.ok&&x(h,await e.json(),!0)}finally{x(C,!1)}}let ae=(e,t)=>e.includes(t)?e.filter(e=>e!==t):[...e,t],oe=e=>i(N)===`cost`?e.cost??0:e.total,se=e=>i(N)===`cost`?X(e.cost):J(e.total),ce=S(()=>new Set(i(h).series.filter(e=>e.total>0).map(e=>e.day)).size),le=S(()=>i(h).byTool.map(e=>({id:e.key,label:Tt(e.key).label,colour:Tt(e.key).colour}))),de=S(()=>Ct(i(h).byModel.map(e=>e.key))),fe=S(()=>i(h).byModel.map(e=>({id:e.key,label:De(e.key),colour:i(de)[e.key]}))),pe=S(()=>i(P)===`tool`?i(le):i(fe)),me=S(()=>i(h).byModel.map(e=>{let t=xt(bt(e.key));return{id:e.key,label:De(e.key),detail:t.label,value:oe(e),display:se(e),colour:i(de)[e.key],mark:t.id,hint:`${e.key} - ${Y(e.total)} tokens over ${Y(e.events)} requests, ${X(e.cost)} estimated`}})),he=S(()=>i(h).byProject.map(e=>({id:e.key,label:Ee(e.key),detail:``,value:i(L)===`sessions`?e.sessions:oe(e),display:i(L)===`sessions`?Y(e.sessions):se(e),colour:`var(--accent)`,hint:`${e.key||`unknown`} - ${Y(e.total)} tokens, ${Y(e.sessions)} sessions`}))),ge=S(()=>i(h).sources.map(e=>{let t=i(h).byTool.find(t=>t.key===e.id),n=Tt(e.id);return{id:e.id,label:n.label,detail:t?`${Y(t.sessions)} sessions`:`not found`,value:t?oe(t):0,display:t?se(t):`--`,colour:n.colour,mark:e.id,hint:e.present?`${Y(e.files)} files under ${e.root}`:`Nothing at ${e.root}`}})),ve=S(()=>[{id:`input`,label:`Input`,value:i(h).totals.tokens.input,display:J(i(h).totals.tokens.input),colour:`var(--ramp-4)`,hint:`Fresh prompt tokens, billed at full rate`},{id:`output`,label:`Output`,value:i(h).totals.tokens.output,display:J(i(h).totals.tokens.output),colour:`var(--ramp-2)`,hint:`Everything the model wrote back, ${J(i(h).totals.reasoning)} of it reasoning`},{id:`cache_read`,label:`Cache read`,value:i(h).totals.tokens.cache_read,display:J(i(h).totals.tokens.cache_read),colour:`var(--ramp-1)`,hint:`Context served from cache, usually a tenth of the input price`},{id:`cache_write`,label:`Cache write`,value:i(h).totals.tokens.cache_write,display:J(i(h).totals.tokens.cache_write),colour:`var(--ramp-3)`,hint:`Putting context into the cache, a premium on the input price`}]),ye=S(()=>i(h).totals.total?i(h).totals.tokens.cache_read/i(h).totals.total*100:0);var be=pn();A(`1uha8ag`,e=>{re(()=>{o.title=`Token usage dashboard`})});var xe=a(be),Se=y(xe);on(y(Se),{}),D(2),U(Se);var Z=z(Se,2),we=y(Z);{let e=S(()=>Kt.map(e=>({id:e.id,label:e.label})));ue(we,{get options(){return i(e)},label:`Date range`,size:`sm`,get value(){return i(E)},set value(e){x(E,e,!0)}})}var Te=z(we,2);ue(Te,{options:[{id:`tokens`,label:`Tokens`},{id:`cost`,label:`Est. cost`,hint:`At published API rates. Your subscription is billed separately.`}],label:`Measure`,size:`sm`,get value(){return i(N)},set value(e){x(N,e,!0)}});var Oe=z(Te,2);_e(Oe,{label:`Tools`,get options(){return i(h).options.tools},format:e=>Tt(e).label,get selected(){return i(O)},set selected(e){x(O,e,!0)}});var ke=z(Oe,2);_e(ke,{label:`Models`,get options(){return i(h).options.models},get format(){return De},get selected(){return i(k)},set selected(e){x(k,e,!0)}});var Ae=z(ke,2);_e(Ae,{label:`Projects`,get options(){return i(h).options.projects},get format(){return Ee},get selected(){return i(j)},set selected(e){x(j,e,!0)}});var je=z(Ae,2),Me=e=>{var t=sn();u(`click`,t,()=>{x(O,[],!0),x(k,[],!0),x(j,[],!0)}),r(e,t)};w(je,e=>{(i(O).length||i(k).length||i(j).length)&&e(Me)}),U(Z);var Pe=z(Z,2),Fe=y(Pe);let Ie;F(Fe,(e,t)=>K?.(e,t),()=>`Last scan ${Ce(i(h).scannedAt)}`);var Le=z(Fe,2);F(Le,(e,t)=>K?.(e,t),()=>`Settings`),U(Pe),U(xe);var Re=z(xe,2),Be=y(Re);{let e=S(()=>qt(i(h).filters.range));Ne(Be,{get totals(){return i(h).totals},get previous(){return i(h).previous},get activeDays(){return i(ce)},get rangeLabel(){return i(e)},get unpriced(){return i(h).unpriced}})}var Ve=z(Be,2),He=y(Ve);q(He,{title:`Every day so far`,span:8,hint:`One square per day, whatever range is picked above. Outlined days are before your records start.`,children:(e,t)=>{ze(e,{get days(){return i(h).calendar},get metric(){return i(N)},get oldest(){return i(h).oldest}})},$$slots:{default:!0}});var Ue=z(He,2);q(Ue,{title:`Plan windows`,span:4,hint:`Straight from each account, not worked out from tokens`,children:(e,t)=>{var n=d(),o=a(n),s=e=>{var t=cn();W(t,21,()=>i(h).windows,e=>e.id,(e,t)=>{_t(e,{get window(){return i(t)}})}),U(t),r(e,t)},c=e=>{var t=ln();r(e,t)};w(o,e=>{i(h).windows.length?e(s):e(c,-1)}),r(e,n)},$$slots:{default:!0}});var Ge=z(Ue,2);q(Ge,{title:`Day by day`,span:12,hint:`Stacked over the range you picked`,actions:e=>{ue(e,{options:[{id:`tool`,label:`By tool`},{id:`model`,label:`By model`}],label:`Trend grouping`,size:`sm`,get value(){return i(P)},set value(e){x(P,e,!0)}})},children:(e,t)=>{{let t=S(()=>i(P)===`tool`?i(h).series:i(h).seriesByModel);We(e,{get series(){return i(t)},get keys(){return i(pe)},get metric(){return i(N)}})}},$$slots:{actions:!0,default:!0}});var Ke=z(Ge,2);q(Ke,{title:`Models`,span:5,hint:`Click one to filter the whole page by it`,actions:e=>{ue(e,{options:[{id:`share`,label:`Share`},{id:`list`,label:`Ranked`}],label:`Model view`,size:`sm`,get value(){return i(I)},set value(e){x(I,e,!0)}})},children:(e,t)=>{var o=d(),s=a(o),l=e=>{var t=dn(),a=y(t);{let e=S(()=>i(me).map(e=>({id:e.id,label:e.label,value:e.value,colour:e.colour,display:e.display}))),t=S(()=>se(i(h).totals)),n=S(()=>i(N)===`cost`?`estimated`:`tokens`);ot(a,{get slices(){return i(e)},get centre(){return i(t)},get caption(){return i(n)}})}var o=z(a,2);W(o,21,()=>i(me),e=>e.id,(e,t)=>{var a=un(),o=y(a);Xe(o,{get id(){return i(t).mark},get label(){return i(t).detail},get colour(){return i(t).colour},size:14});var s=z(o,2),l=c(s,!0),u=z(s,2),d=c(u,!0);U(a),n(()=>{g(l,i(t).label),g(d,i(t).display)}),r(e,a)}),U(o),U(t),r(e,t)},u=e=>{rt(e,{get rows(){return i(me)},get active(){return i(k)},onpick:e=>x(k,ae(i(k),e),!0)})};w(s,e=>{i(I)===`share`?e(l):e(u,-1)}),r(e,o)},$$slots:{actions:!0,default:!0}});var qe=z(Ke,2);q(qe,{title:`Projects`,span:7,hint:`Where the work happened. Click one to filter.`,actions:e=>{{let t=S(()=>[{id:`measure`,label:i(N)===`cost`?`Est. cost`:`Tokens`},{id:`sessions`,label:`Sessions`}]);ue(e,{get options(){return i(t)},label:`Project measure`,size:`sm`,get value(){return i(L)},set value(e){x(L,e,!0)}})}},children:(e,t)=>{{let t=S(()=>i(he).slice(0,8));rt(e,{get rows(){return i(t)},get active(){return i(j)},onpick:e=>x(j,ae(i(j),e),!0)})}},$$slots:{actions:!0,default:!0}});var Je=z(qe,2);q(Je,{title:`Where the tokens go`,span:4,hint:`Cache reads are cheap, cache writes are not. This is the split that decides the bill.`,children:(e,t)=>{var o=fn(),s=a(o);ut(s,{get parts(){return i(ve)}});var l=z(s,2),u=c(l);n(e=>g(u,`${e??``}% of everything counted was served from cache.`),[()=>i(ye).toFixed(0)]),r(e,o)},$$slots:{default:!0}});var Ye=z(Je,2);q(Ye,{title:`When you work`,span:5,hint:`Local time, over the range above`,children:(e,t)=>{ht(e,{get points(){return i(h).clock}})},$$slots:{default:!0}});var Ze=z(Ye,2);q(Ze,{title:`Tools`,span:3,hint:`Click one to filter the whole page by it`,children:(e,t)=>{rt(e,{get rows(){return i(ge)},get active(){return i(O)},onpick:e=>x(O,ae(i(O),e),!0)})},$$slots:{default:!0}}),q(z(Ze,2),{title:`Recent sessions`,span:12,hint:`Click a column heading to sort by it`,actions:e=>{Bt(e,{get options(){return Dt},onchange:e=>ne({hiddenColumns:e}),get hidden(){return i(B)},set hidden(e){x(B,e,!0)}})},children:(e,t)=>{It(e,{get rows(){return i(h).sessions},get hidden(){return i(B)},onpick:e=>x(j,ae(i(j),e),!0)})},$$slots:{actions:!0,default:!0}}),U(Ve);var Qe=z(Ve,2),$e=z(y(Qe),2),et=y($e),tt=e=>{var t=M();n(e=>g(t,`Records from ${e??``} ·`),[()=>new Date(i(h).oldest).toLocaleDateString(`en-GB`)]),r(e,t)};w(et,e=>{i(h).oldest&&e(tt)});var nt=z(et);U($e),U(Qe),U(Re);var it=z(Re,2);Gt(it,{get problems(){return i(h).problems}}),nn(z(it,2),{get saved(){return i(_)},get sources(){return i(h).sources},get dbPath(){return l.data.paths.db},get scannedAt(){return i(h).scannedAt},onsave:ne,onrescan:G,get open(){return i(T)},set open(e){x(T,e,!0)}}),n(e=>{Ie=R(Fe,1,`icon svelte-1uha8ag`,null,Ie,{busy:i(C)}),g(nt,` Scanned ${e??``}`)},[()=>Ce(i(h).scannedAt)]),u(`click`,Fe,G),u(`click`,Le,()=>x(T,!0)),r(t,be),p()}l([`click`]);export{mn as component};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"1792014819768"}
|
|
Binary file
|
|
Binary file
|
|
@@ -206,7 +206,7 @@ function server_data_serializer(event, state) {
|
|
|
206
206
|
let promise_id = 1;
|
|
207
207
|
let max_nodes = -1;
|
|
208
208
|
const iterator = create_async_iterator();
|
|
209
|
-
const global = "
|
|
209
|
+
const global = "__sveltekit_1xoegac";
|
|
210
210
|
/** @param {number} index */
|
|
211
211
|
function get_replacer(index) {
|
|
212
212
|
/** @param {any} thing */
|
|
@@ -1444,7 +1444,7 @@ async function render_response({ branch, fetched, page_config, status, error = n
|
|
|
1444
1444
|
"crossorigin"
|
|
1445
1445
|
]);
|
|
1446
1446
|
}
|
|
1447
|
-
const global = "
|
|
1447
|
+
const global = "__sveltekit_1xoegac";
|
|
1448
1448
|
const { data, chunks } = data_serializer.get_data(csp);
|
|
1449
1449
|
if (page_config.ssr && page_config.csr) body += `\n\t\t\t${fetched.map((item) => serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!(state.prerendering || state.prerender_default === true))).join("\n ")}`;
|
|
1450
1450
|
if (page_config.csr && client) {
|
|
@@ -1468,7 +1468,7 @@ async function render_response({ branch, fetched, page_config, status, error = n
|
|
|
1468
1468
|
}
|
|
1469
1469
|
}
|
|
1470
1470
|
const blocks = [];
|
|
1471
|
-
const properties = [`base: ${base_expression}`, `version: ${s("
|
|
1471
|
+
const properties = [`base: ${base_expression}`, `version: ${s("1792014819768")}`];
|
|
1472
1472
|
if (assets) properties.push(`assets: ${s(assets)}`);
|
|
1473
1473
|
if (client.uses_env_dynamic_public) properties.push(`env: ${load_env_eagerly ? "null" : uneval$1(rendered_env)}`);
|
|
1474
1474
|
if (chunks) {
|
|
@@ -2491,7 +2491,7 @@ function redirect_response(status, location) {
|
|
|
2491
2491
|
* @param {Response} response
|
|
2492
2492
|
*/
|
|
2493
2493
|
function with_version_header(response) {
|
|
2494
|
-
response.headers.set("x-sveltekit-version", "
|
|
2494
|
+
response.headers.set("x-sveltekit-version", "1792014819768");
|
|
2495
2495
|
return response;
|
|
2496
2496
|
}
|
|
2497
2497
|
/**
|
|
@@ -2,14 +2,16 @@ import { a as costOf, o as totalOf, s as THEMES } from "./range.js";
|
|
|
2
2
|
import { readFile, readdir, stat } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, join } from "node:path";
|
|
4
4
|
import { DatabaseSync } from "node:sqlite";
|
|
5
|
-
import { mkdirSync } from "node:fs";
|
|
5
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
//#region src/lib/server/config.ts
|
|
8
8
|
var home = homedir();
|
|
9
9
|
var env = (name, fallback) => (process.env[name] || "").trim() || fallback;
|
|
10
10
|
var dataHome = env("XDG_DATA_HOME", join(home, ".local", "share"));
|
|
11
|
+
var dataDirs = ["token-usage-dashboard", "ai-usage-dashboard"].map((name) => join(dataHome, name));
|
|
12
|
+
var dataDir = dataDirs.find((dir) => existsSync(dir)) ?? dataDirs[0];
|
|
11
13
|
var config = {
|
|
12
|
-
dbPath: env("AIUSAGE_DB", join(
|
|
14
|
+
dbPath: env("AIUSAGE_DB", join(dataDir, "usage.db")),
|
|
13
15
|
claudeDir: env("AIUSAGE_CLAUDE_DIR", join(home, ".claude")),
|
|
14
16
|
codexDir: env("AIUSAGE_CODEX_DIR", join(home, ".codex")),
|
|
15
17
|
openCodeDir: env("AIUSAGE_OPENCODE_DIR", join(dataHome, "opencode")),
|
|
@@ -37,6 +39,7 @@ create table if not exists events (
|
|
|
37
39
|
output integer not null default 0,
|
|
38
40
|
cache_read integer not null default 0,
|
|
39
41
|
cache_write integer not null default 0,
|
|
42
|
+
cache_write_long integer not null default 0,
|
|
40
43
|
reasoning integer not null default 0,
|
|
41
44
|
subagent integer
|
|
42
45
|
);
|
|
@@ -80,14 +83,21 @@ function db() {
|
|
|
80
83
|
writeMeta("schema", String(SCHEMA));
|
|
81
84
|
}
|
|
82
85
|
handle.exec(TABLES);
|
|
83
|
-
|
|
86
|
+
addColumns(handle);
|
|
84
87
|
rebucket(handle);
|
|
85
88
|
return handle;
|
|
86
89
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
var ADDED = {
|
|
91
|
+
subagent: "integer",
|
|
92
|
+
cache_write_long: "integer not null default 0"
|
|
93
|
+
};
|
|
94
|
+
/** Older databases grow columns in place, then every file is read again to fill them in */
|
|
95
|
+
function addColumns(handle) {
|
|
96
|
+
const columns = handle.prepare("pragma table_info(events)").all();
|
|
97
|
+
const missing = Object.keys(ADDED).filter((name) => !columns.some((column) => column.name === name));
|
|
98
|
+
if (!missing.length) return;
|
|
99
|
+
const alters = missing.map((name) => `alter table events add column ${name} ${ADDED[name]};`);
|
|
100
|
+
handle.exec(`begin; ${alters.join(" ")} delete from files; commit;`);
|
|
91
101
|
}
|
|
92
102
|
var REBUCKET = `
|
|
93
103
|
update events set
|
|
@@ -144,6 +154,7 @@ var claudeCode = {
|
|
|
144
154
|
const ts = Date.parse(String(line.timestamp));
|
|
145
155
|
if (Number.isNaN(ts)) continue;
|
|
146
156
|
const details = usage.output_tokens_details;
|
|
157
|
+
const written = usage.cache_creation;
|
|
147
158
|
events.push({
|
|
148
159
|
id: `claude-code:${message.id}`,
|
|
149
160
|
model: message.model,
|
|
@@ -154,6 +165,7 @@ var claudeCode = {
|
|
|
154
165
|
output: num(usage.output_tokens),
|
|
155
166
|
cache_read: num(usage.cache_read_input_tokens),
|
|
156
167
|
cache_write: num(usage.cache_creation_input_tokens),
|
|
168
|
+
cache_write_long: num(written?.ephemeral_1h_input_tokens),
|
|
157
169
|
reasoning: num(details?.thinking_tokens),
|
|
158
170
|
subagent: line.isSidechain === true
|
|
159
171
|
});
|
|
@@ -313,7 +325,7 @@ async function listFiles(source) {
|
|
|
313
325
|
withFileTypes: true
|
|
314
326
|
})).filter((entry) => entry.isFile() && entry.name.endsWith(source.ext)).map((entry) => join(entry.parentPath, entry.name));
|
|
315
327
|
}
|
|
316
|
-
var INSERT = "insert into events (id, tool, model, session, project, ts, day, dow, hour, input, output, cache_read, cache_write, reasoning, subagent) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) on conflict(id) do update set input = max(input, excluded.input), output = max(output, excluded.output), cache_read = max(cache_read, excluded.cache_read), cache_write = max(cache_write, excluded.cache_write), reasoning = max(reasoning, excluded.reasoning), subagent = coalesce(excluded.subagent, subagent)";
|
|
328
|
+
var INSERT = "insert into events (id, tool, model, session, project, ts, day, dow, hour, input, output, cache_read, cache_write, cache_write_long, reasoning, subagent) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) on conflict(id) do update set input = max(input, excluded.input), output = max(output, excluded.output), cache_read = max(cache_read, excluded.cache_read), cache_write = max(cache_write, excluded.cache_write), cache_write_long = max(cache_write_long, excluded.cache_write_long), reasoning = max(reasoning, excluded.reasoning), subagent = coalesce(excluded.subagent, subagent)";
|
|
317
329
|
var INSERT_NAME = "insert into names (tool, session, name) values (?, ?, ?) on conflict(tool, session) do update set name = excluded.name";
|
|
318
330
|
var INSERT_WINDOW = "insert into windows (id, tool, label, used_percent, window_minutes, resets_at, detail, seen_at) values (?, ?, ?, ?, ?, ?, ?, ?) on conflict(id) do update set used_percent = excluded.used_percent, resets_at = excluded.resets_at, detail = excluded.detail, seen_at = excluded.seen_at where excluded.seen_at >= windows.seen_at";
|
|
319
331
|
async function scanSource(source) {
|
|
@@ -361,7 +373,7 @@ async function scanSource(source) {
|
|
|
361
373
|
handle.exec("begin");
|
|
362
374
|
for (const event of parsed.events) {
|
|
363
375
|
const at = new Date(event.ts);
|
|
364
|
-
insert.run(event.id, source.id, event.model, event.session, event.project, event.ts, localDay(at), at.getDay(), at.getHours(), event.input, event.output, event.cache_read, event.cache_write, event.reasoning, event.subagent === void 0 ? null : Number(event.subagent));
|
|
376
|
+
insert.run(event.id, source.id, event.model, event.session, event.project, event.ts, localDay(at), at.getDay(), at.getHours(), event.input, event.output, event.cache_read, event.cache_write, event.cache_write_long ?? 0, event.reasoning, event.subagent === void 0 ? null : Number(event.subagent));
|
|
365
377
|
}
|
|
366
378
|
for (const [session, name] of Object.entries(parsed.names ?? {})) insertName.run(source.id, session, name);
|
|
367
379
|
for (const window of parsed.windows ?? []) insertWindow.run(window.id, source.id, window.label, window.used_percent, window.window_minutes, window.resets_at, window.detail, window.seen_at);
|
|
@@ -469,8 +481,18 @@ var empty = () => ({
|
|
|
469
481
|
input: 0,
|
|
470
482
|
output: 0,
|
|
471
483
|
cache_read: 0,
|
|
472
|
-
cache_write: 0
|
|
484
|
+
cache_write: 0,
|
|
485
|
+
cache_write_long: 0
|
|
486
|
+
});
|
|
487
|
+
var tokensOf = (row) => ({
|
|
488
|
+
input: Number(row.input) || 0,
|
|
489
|
+
output: Number(row.output) || 0,
|
|
490
|
+
cache_read: Number(row.cache_read) || 0,
|
|
491
|
+
cache_write: Number(row.cache_write) || 0,
|
|
492
|
+
cache_write_long: Number(row.cache_write_long) || 0
|
|
473
493
|
});
|
|
494
|
+
/** Adds what can be priced, so one unpriced model doesn't blank out the whole total */
|
|
495
|
+
var plus = (sum, cost) => cost === null ? sum : (sum ?? 0) + cost;
|
|
474
496
|
function where(filters, dated = true) {
|
|
475
497
|
const clauses = [];
|
|
476
498
|
const params = [];
|
|
@@ -492,7 +514,7 @@ function where(filters, dated = true) {
|
|
|
492
514
|
params
|
|
493
515
|
};
|
|
494
516
|
}
|
|
495
|
-
var SUMS = "sum(input) input, sum(output) output, sum(cache_read) cache_read, sum(cache_write) cache_write, sum(reasoning) reasoning, count(*) events, count(distinct tool || ':' || session) sessions";
|
|
517
|
+
var SUMS = "sum(input) input, sum(output) output, sum(cache_read) cache_read, sum(cache_write) cache_write, sum(cache_write_long) cache_write_long, sum(reasoning) reasoning, count(*) events, count(distinct tool || ':' || session) sessions";
|
|
496
518
|
/** Rows arrive split by model so each slice can be priced at its own rate. */
|
|
497
519
|
function fold(rows, overrides) {
|
|
498
520
|
const slices = /* @__PURE__ */ new Map();
|
|
@@ -506,27 +528,20 @@ function fold(rows, overrides) {
|
|
|
506
528
|
tokens: empty(),
|
|
507
529
|
total: 0,
|
|
508
530
|
reasoning: 0,
|
|
509
|
-
cost:
|
|
531
|
+
cost: null,
|
|
510
532
|
events: 0,
|
|
511
533
|
sessions: 0
|
|
512
534
|
};
|
|
513
535
|
slices.set(key, slice);
|
|
514
536
|
sessions.set(key, /* @__PURE__ */ new Set());
|
|
515
537
|
}
|
|
516
|
-
const tokens =
|
|
517
|
-
input: Number(row.input) || 0,
|
|
518
|
-
output: Number(row.output) || 0,
|
|
519
|
-
cache_read: Number(row.cache_read) || 0,
|
|
520
|
-
cache_write: Number(row.cache_write) || 0
|
|
521
|
-
};
|
|
538
|
+
const tokens = tokensOf(row);
|
|
522
539
|
for (const field of Object.keys(tokens)) slice.tokens[field] += tokens[field];
|
|
523
540
|
slice.total += totalOf(tokens);
|
|
524
541
|
slice.reasoning += Number(row.reasoning) || 0;
|
|
525
542
|
slice.events += Number(row.events) || 0;
|
|
526
543
|
slice.sessions += Number(row.sessions) || 0;
|
|
527
|
-
|
|
528
|
-
if (cost === null) slice.cost = null;
|
|
529
|
-
else if (slice.cost !== null) slice.cost += cost;
|
|
544
|
+
slice.cost = plus(slice.cost, costOf(String(row.model ?? ""), tokens, overrides));
|
|
530
545
|
}
|
|
531
546
|
return slices;
|
|
532
547
|
}
|
|
@@ -560,18 +575,11 @@ function series(filters, column, overrides) {
|
|
|
560
575
|
day: String(row.day),
|
|
561
576
|
key: String(row.key ?? ""),
|
|
562
577
|
total: 0,
|
|
563
|
-
cost:
|
|
564
|
-
};
|
|
565
|
-
const tokens = {
|
|
566
|
-
input: Number(row.input) || 0,
|
|
567
|
-
output: Number(row.output) || 0,
|
|
568
|
-
cache_read: Number(row.cache_read) || 0,
|
|
569
|
-
cache_write: Number(row.cache_write) || 0
|
|
578
|
+
cost: null
|
|
570
579
|
};
|
|
580
|
+
const tokens = tokensOf(row);
|
|
571
581
|
point.total += totalOf(tokens);
|
|
572
|
-
|
|
573
|
-
if (cost === null) point.cost = null;
|
|
574
|
-
else if (point.cost !== null) point.cost += cost;
|
|
582
|
+
point.cost = plus(point.cost, costOf(String(row.model ?? ""), tokens, overrides));
|
|
575
583
|
points.set(id, point);
|
|
576
584
|
}
|
|
577
585
|
return [...points.values()];
|
|
@@ -586,20 +594,13 @@ function calendar(filters, overrides) {
|
|
|
586
594
|
const entry = days.get(day) ?? {
|
|
587
595
|
day,
|
|
588
596
|
total: 0,
|
|
589
|
-
cost:
|
|
597
|
+
cost: null,
|
|
590
598
|
events: 0
|
|
591
599
|
};
|
|
592
|
-
const tokens =
|
|
593
|
-
input: Number(row.input) || 0,
|
|
594
|
-
output: Number(row.output) || 0,
|
|
595
|
-
cache_read: Number(row.cache_read) || 0,
|
|
596
|
-
cache_write: Number(row.cache_write) || 0
|
|
597
|
-
};
|
|
600
|
+
const tokens = tokensOf(row);
|
|
598
601
|
entry.total += totalOf(tokens);
|
|
599
602
|
entry.events += Number(row.events) || 0;
|
|
600
|
-
|
|
601
|
-
if (cost === null) entry.cost = null;
|
|
602
|
-
else if (entry.cost !== null) entry.cost += cost;
|
|
603
|
+
entry.cost = plus(entry.cost, costOf(String(row.model ?? ""), tokens, overrides));
|
|
603
604
|
days.set(day, entry);
|
|
604
605
|
}
|
|
605
606
|
return [...days.values()];
|
|
@@ -628,19 +629,14 @@ function sessions(filters, overrides, limit = 60) {
|
|
|
628
629
|
started: Number(row.started),
|
|
629
630
|
ended: Number(row.ended),
|
|
630
631
|
total: 0,
|
|
631
|
-
cost:
|
|
632
|
+
cost: null,
|
|
632
633
|
peak: 0,
|
|
633
634
|
turns: 0,
|
|
634
635
|
read: 0,
|
|
635
636
|
fed: 0,
|
|
636
637
|
side: null
|
|
637
638
|
};
|
|
638
|
-
const tokens =
|
|
639
|
-
input: Number(row.input) || 0,
|
|
640
|
-
output: Number(row.output) || 0,
|
|
641
|
-
cache_read: Number(row.cache_read) || 0,
|
|
642
|
-
cache_write: Number(row.cache_write) || 0
|
|
643
|
-
};
|
|
639
|
+
const tokens = tokensOf(row);
|
|
644
640
|
entry.models.add(String(row.model));
|
|
645
641
|
entry.started = Math.min(entry.started, Number(row.started));
|
|
646
642
|
entry.ended = Math.max(entry.ended, Number(row.ended));
|
|
@@ -650,9 +646,7 @@ function sessions(filters, overrides, limit = 60) {
|
|
|
650
646
|
entry.read += tokens.cache_read;
|
|
651
647
|
entry.fed += tokens.input + tokens.cache_read + tokens.cache_write;
|
|
652
648
|
if (Number(row.flagged)) entry.side = (entry.side ?? 0) + (Number(row.side) || 0);
|
|
653
|
-
|
|
654
|
-
if (cost === null) entry.cost = null;
|
|
655
|
-
else if (entry.cost !== null) entry.cost += cost;
|
|
649
|
+
entry.cost = plus(entry.cost, costOf(String(row.model), tokens, overrides));
|
|
656
650
|
merged.set(at, entry);
|
|
657
651
|
}
|
|
658
652
|
const name = db().prepare("select name from names where tool = ? and session = ?");
|
|
@@ -40,12 +40,14 @@ var THEMES = [
|
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/lib/pricing.ts
|
|
42
42
|
/** Dollars per million. Anthropic bills cache reads at a tenth and 5m writes at 1.25x. */
|
|
43
|
-
var anthropic = (input, output) => ({
|
|
43
|
+
var anthropic = (input, output, read = .1) => ({
|
|
44
44
|
input,
|
|
45
45
|
output,
|
|
46
|
-
cacheRead: input *
|
|
46
|
+
cacheRead: input * read,
|
|
47
47
|
cacheWrite: input * 1.25
|
|
48
48
|
});
|
|
49
|
+
/** An hour in the cache costs 2x input, where five minutes is 1.25x */
|
|
50
|
+
var LONG_WRITE = 2 / 1.25;
|
|
49
51
|
/** OpenAI discounts cached input and charges nothing to put it there. */
|
|
50
52
|
var openai = (input, output) => ({
|
|
51
53
|
input,
|
|
@@ -54,17 +56,20 @@ var openai = (input, output) => ({
|
|
|
54
56
|
cacheWrite: 0
|
|
55
57
|
});
|
|
56
58
|
var RATES = {
|
|
59
|
+
"claude-fable-5-1": anthropic(10, 50, .025),
|
|
57
60
|
"claude-fable-5": anthropic(10, 50),
|
|
61
|
+
"claude-opus-5-5": anthropic(4, 20, .05),
|
|
58
62
|
"claude-opus-5": anthropic(5, 25),
|
|
59
63
|
"claude-opus-4-8": anthropic(5, 25),
|
|
60
64
|
"claude-opus-4-7": anthropic(5, 25),
|
|
61
65
|
"claude-opus-4-6": anthropic(5, 25),
|
|
62
66
|
"claude-opus-4-5": anthropic(5, 25),
|
|
63
67
|
"claude-opus-4-1": anthropic(15, 75),
|
|
64
|
-
"claude-sonnet-5": anthropic(
|
|
68
|
+
"claude-sonnet-5": anthropic(2, 10),
|
|
65
69
|
"claude-sonnet-4-6": anthropic(3, 15),
|
|
66
70
|
"claude-sonnet-4-5": anthropic(3, 15),
|
|
67
71
|
"claude-sonnet-4": anthropic(3, 15),
|
|
72
|
+
"claude-haiku-5-5": anthropic(.1, .5),
|
|
68
73
|
"claude-haiku-4-5": anthropic(1, 5),
|
|
69
74
|
"claude-3-5-haiku": anthropic(.8, 4),
|
|
70
75
|
"gpt-5.6-sol-pro": openai(2.5, 15),
|
|
@@ -96,7 +101,8 @@ function rateFor(model, overrides = {}) {
|
|
|
96
101
|
function costOf(model, tokens, overrides = {}) {
|
|
97
102
|
const rate = rateFor(model, overrides);
|
|
98
103
|
if (!rate) return null;
|
|
99
|
-
|
|
104
|
+
const short = tokens.cache_write - tokens.cache_write_long;
|
|
105
|
+
return (tokens.input * rate.input + tokens.output * rate.output + tokens.cache_read * rate.cacheRead + short * rate.cacheWrite + tokens.cache_write_long * rate.cacheWrite * LONG_WRITE) / 1e6;
|
|
100
106
|
}
|
|
101
107
|
var totalOf = (tokens) => tokens.input + tokens.output + tokens.cache_read + tokens.cache_write;
|
|
102
108
|
//#endregion
|
|
@@ -139,9 +139,9 @@ function delta(now, before) {
|
|
|
139
139
|
//#region src/lib/components/Figures.svelte
|
|
140
140
|
function Figures($$renderer, $$props) {
|
|
141
141
|
$$renderer.component(($$renderer) => {
|
|
142
|
-
let { totals, previous, activeDays, rangeLabel } = $$props;
|
|
142
|
+
let { totals, previous, activeDays, rangeLabel, unpriced } = $$props;
|
|
143
143
|
const change = derived(() => delta(totals.total, previous.total));
|
|
144
|
-
const costChange = derived(() => delta(totals.cost ?? 0, previous.cost ?? 0));
|
|
144
|
+
const costChange = derived(() => unpriced.length ? null : delta(totals.cost ?? 0, previous.cost ?? 0));
|
|
145
145
|
const perDay = derived(() => activeDays ? totals.total / activeDays : 0);
|
|
146
146
|
$$renderer.push(`<div class="figures svelte-l3stpt"><div class="lead svelte-l3stpt"><span class="cap svelte-l3stpt">Tokens, ${escape_html(rangeLabel.toLowerCase())}</span> <strong class="num svelte-l3stpt">${escape_html(compact(totals.total))}</strong> `);
|
|
147
147
|
if (change()) $$renderer.push(`<!--[0--><span class="delta svelte-l3stpt">${escape_html(change().text)}</span>`);
|
|
@@ -149,6 +149,9 @@ function Figures($$renderer, $$props) {
|
|
|
149
149
|
$$renderer.push(`<!--]--></div> <dl class="svelte-l3stpt"><div class="svelte-l3stpt"><dt class="svelte-l3stpt">Est. cost</dt> <dd class="num svelte-l3stpt">${escape_html(money(totals.cost))} `);
|
|
150
150
|
if (costChange()) $$renderer.push(`<!--[0--><i${attr_class(`delta cost ${stringify(costChange().tone)}`, "svelte-l3stpt")}>${escape_html(costChange().text)}</i>`);
|
|
151
151
|
else $$renderer.push("<!--[-1-->");
|
|
152
|
+
$$renderer.push(`<!--]--> `);
|
|
153
|
+
if (unpriced.length) $$renderer.push(`<!--[0--><i class="delta svelte-l3stpt">${escape_html(unpriced.length)} unpriced<span class="visually-hidden">: ${escape_html(unpriced.join(", "))}</span></i>`);
|
|
154
|
+
else $$renderer.push("<!--[-1-->");
|
|
152
155
|
$$renderer.push(`<!--]--></dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Sessions</dt> <dd class="num svelte-l3stpt">${escape_html(full(totals.sessions))}</dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Active days</dt> <dd class="num svelte-l3stpt">${escape_html(full(activeDays))}</dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Daily pace</dt> <dd class="num svelte-l3stpt">${escape_html(compact(perDay()))}</dd></div></dl></div>`);
|
|
153
156
|
});
|
|
154
157
|
}
|
|
@@ -588,6 +591,20 @@ function providerFor(model) {
|
|
|
588
591
|
return MATCHES.find(([pattern]) => pattern.test(name.toLowerCase()))?.[1] ?? "unknown";
|
|
589
592
|
}
|
|
590
593
|
var providerMeta = (id) => PROVIDERS.find((provider) => provider.id === id) ?? PROVIDERS[PROVIDERS.length - 1];
|
|
594
|
+
var shade = (colour, index) => {
|
|
595
|
+
if (!index) return colour;
|
|
596
|
+
return `color-mix(in oklch, ${colour}, ${index % 2 ? "black" : "white"} ${Math.min(Math.ceil(index / 2) * 18, 72)}%)`;
|
|
597
|
+
};
|
|
598
|
+
/** Each model after a provider's first goes alternately darker and lighter, so siblings differ */
|
|
599
|
+
function modelColours(models) {
|
|
600
|
+
const seen = /* @__PURE__ */ new Map();
|
|
601
|
+
return Object.fromEntries(models.map((model) => {
|
|
602
|
+
const provider = providerFor(model);
|
|
603
|
+
const index = seen.get(provider) ?? 0;
|
|
604
|
+
seen.set(provider, index + 1);
|
|
605
|
+
return [model, shade(providerMeta(provider).colour, index)];
|
|
606
|
+
}));
|
|
607
|
+
}
|
|
591
608
|
var TOOLS = [
|
|
592
609
|
{
|
|
593
610
|
id: "claude-code",
|
|
@@ -915,7 +932,7 @@ function Logo($$renderer, $$props) {
|
|
|
915
932
|
column,
|
|
916
933
|
heat: (column + (3 - row)) / 6
|
|
917
934
|
})));
|
|
918
|
-
$$renderer.push(`<svg class="logo svelte-nck4wt" viewBox="0 0 32 32"${attr("width", size)}${attr("height", size)} role="img" aria-label="
|
|
935
|
+
$$renderer.push(`<svg class="logo svelte-nck4wt" viewBox="0 0 32 32"${attr("width", size)}${attr("height", size)} role="img" aria-label="Token usage dashboard"><rect width="32" height="32" rx="8" fill="var(--accent)"></rect><!--[-->`);
|
|
919
936
|
const each_array = ensure_array_like(cells);
|
|
920
937
|
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
921
938
|
let cell = each_array[$$index];
|
|
@@ -970,17 +987,18 @@ function _page($$renderer, $$props) {
|
|
|
970
987
|
}
|
|
971
988
|
const toggle = (list, value) => list.includes(value) ? list.filter((item) => item !== value) : [...list, value];
|
|
972
989
|
const measure = (slice) => metric === "cost" ? slice.cost ?? 0 : slice.total;
|
|
973
|
-
const show = (
|
|
990
|
+
const show = (slice) => metric === "cost" ? money(slice.cost) : compact(slice.total);
|
|
974
991
|
const activeDays = derived(() => new Set(usage.series.filter((point) => point.total > 0).map((point) => point.day)).size);
|
|
975
992
|
const toolKeys = derived(() => usage.byTool.map((slice) => ({
|
|
976
993
|
id: slice.key,
|
|
977
994
|
label: toolMeta(slice.key).label,
|
|
978
995
|
colour: toolMeta(slice.key).colour
|
|
979
996
|
})));
|
|
997
|
+
const colours = derived(() => modelColours(usage.byModel.map((slice) => slice.key)));
|
|
980
998
|
const modelKeys = derived(() => usage.byModel.map((slice) => ({
|
|
981
999
|
id: slice.key,
|
|
982
1000
|
label: modelName(slice.key),
|
|
983
|
-
colour:
|
|
1001
|
+
colour: colours()[slice.key]
|
|
984
1002
|
})));
|
|
985
1003
|
const trendKeys = derived(() => trendBy === "tool" ? toolKeys() : modelKeys());
|
|
986
1004
|
const modelRows = derived(() => usage.byModel.map((slice) => {
|
|
@@ -990,8 +1008,8 @@ function _page($$renderer, $$props) {
|
|
|
990
1008
|
label: modelName(slice.key),
|
|
991
1009
|
detail: provider.label,
|
|
992
1010
|
value: measure(slice),
|
|
993
|
-
display: show(
|
|
994
|
-
colour:
|
|
1011
|
+
display: show(slice),
|
|
1012
|
+
colour: colours()[slice.key],
|
|
995
1013
|
mark: provider.id,
|
|
996
1014
|
hint: `${slice.key} - ${full(slice.total)} tokens over ${full(slice.events)} requests, ${money(slice.cost)} estimated`
|
|
997
1015
|
};
|
|
@@ -1001,7 +1019,7 @@ function _page($$renderer, $$props) {
|
|
|
1001
1019
|
label: projectName(slice.key),
|
|
1002
1020
|
detail: "",
|
|
1003
1021
|
value: projectBy === "sessions" ? slice.sessions : measure(slice),
|
|
1004
|
-
display: projectBy === "sessions" ? full(slice.sessions) : show(
|
|
1022
|
+
display: projectBy === "sessions" ? full(slice.sessions) : show(slice),
|
|
1005
1023
|
colour: "var(--accent)",
|
|
1006
1024
|
hint: `${slice.key || "unknown"} - ${full(slice.total)} tokens, ${full(slice.sessions)} sessions`
|
|
1007
1025
|
})));
|
|
@@ -1014,7 +1032,7 @@ function _page($$renderer, $$props) {
|
|
|
1014
1032
|
label: tool.label,
|
|
1015
1033
|
detail: slice ? `${full(slice.sessions)} sessions` : "not found",
|
|
1016
1034
|
value: slice ? measure(slice) : 0,
|
|
1017
|
-
display: slice ? show(
|
|
1035
|
+
display: slice ? show(slice) : "--",
|
|
1018
1036
|
colour: tool.colour,
|
|
1019
1037
|
mark: source.id,
|
|
1020
1038
|
hint: source.present ? `${full(source.files)} files under ${source.root}` : `Nothing at ${source.root}`
|
|
@@ -1060,12 +1078,12 @@ function _page($$renderer, $$props) {
|
|
|
1060
1078
|
function $$render_inner($$renderer) {
|
|
1061
1079
|
head("1uha8ag", $$renderer, ($$renderer) => {
|
|
1062
1080
|
$$renderer.title(($$renderer) => {
|
|
1063
|
-
$$renderer.push(`<title>
|
|
1081
|
+
$$renderer.push(`<title>Token usage dashboard</title>`);
|
|
1064
1082
|
});
|
|
1065
1083
|
});
|
|
1066
1084
|
$$renderer.push(`<header class="bar svelte-1uha8ag"><a class="brand svelte-1uha8ag" href="/">`);
|
|
1067
1085
|
Logo($$renderer, {});
|
|
1068
|
-
$$renderer.push(`<!----> <span>
|
|
1086
|
+
$$renderer.push(`<!----> <span>Token usage</span></a> <div class="filters svelte-1uha8ag">`);
|
|
1069
1087
|
Segmented($$renderer, {
|
|
1070
1088
|
options: RANGES.map((entry) => ({
|
|
1071
1089
|
id: entry.id,
|
|
@@ -1148,7 +1166,8 @@ function _page($$renderer, $$props) {
|
|
|
1148
1166
|
totals: usage.totals,
|
|
1149
1167
|
previous: usage.previous,
|
|
1150
1168
|
activeDays: activeDays(),
|
|
1151
|
-
rangeLabel: rangeLabel(usage.filters.range)
|
|
1169
|
+
rangeLabel: rangeLabel(usage.filters.range),
|
|
1170
|
+
unpriced: usage.unpriced
|
|
1152
1171
|
});
|
|
1153
1172
|
$$renderer.push(`<!----> <div class="grid svelte-1uha8ag">`);
|
|
1154
1173
|
Panel($$renderer, {
|
|
@@ -1261,7 +1280,7 @@ function _page($$renderer, $$props) {
|
|
|
1261
1280
|
colour: row.colour,
|
|
1262
1281
|
display: row.display
|
|
1263
1282
|
})),
|
|
1264
|
-
centre: show(
|
|
1283
|
+
centre: show(usage.totals),
|
|
1265
1284
|
caption: metric === "cost" ? "estimated" : "tokens"
|
|
1266
1285
|
});
|
|
1267
1286
|
$$renderer.push(`<!----> <ul class="key svelte-1uha8ag"><!--[-->`);
|
|
@@ -9,7 +9,7 @@ return {
|
|
|
9
9
|
app_path: "_app",
|
|
10
10
|
assets: new Set(["favicon.svg","robots.txt"]),
|
|
11
11
|
mime_types: {".svg":"image/svg+xml",".txt":"text/plain"},
|
|
12
|
-
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.
|
|
12
|
+
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.CQWyl0kn.js",imports:["_app/immutable/entry/start.CzGx2BYz.js","_app/immutable/entry/payload.DSmR2FwN.js","_app/immutable/chunks/BaNbYf_w.js","_app/immutable/chunks/CbiRHTcG.js","_app/immutable/chunks/ssd4Rw-g.js","_app/immutable/chunks/DTingiCe.js","_app/immutable/chunks/B0VWrXPj.js","_app/immutable/entry/app.CQWyl0kn.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
|
|
13
13
|
|
|
14
14
|
nodes: [
|
|
15
15
|
__memo(() => import('./nodes/0.js')),
|
package/build/server/manifest.js
CHANGED
|
@@ -9,7 +9,7 @@ return {
|
|
|
9
9
|
app_path: "_app",
|
|
10
10
|
assets: new Set(["favicon.svg","robots.txt"]),
|
|
11
11
|
mime_types: {".svg":"image/svg+xml",".txt":"text/plain"},
|
|
12
|
-
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.
|
|
12
|
+
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.CQWyl0kn.js",imports:["_app/immutable/entry/start.CzGx2BYz.js","_app/immutable/entry/payload.DSmR2FwN.js","_app/immutable/chunks/BaNbYf_w.js","_app/immutable/chunks/CbiRHTcG.js","_app/immutable/chunks/ssd4Rw-g.js","_app/immutable/chunks/DTingiCe.js","_app/immutable/chunks/B0VWrXPj.js","_app/immutable/entry/app.CQWyl0kn.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
|
|
13
13
|
|
|
14
14
|
nodes: [
|
|
15
15
|
__memo(() => import('./nodes/0.js')),
|
package/build/server/nodes/2.js
CHANGED
|
@@ -5,6 +5,6 @@ let component_cache;
|
|
|
5
5
|
export const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js')).default;
|
|
6
6
|
export { server };
|
|
7
7
|
export const server_id = "src/routes/+page.server.ts";
|
|
8
|
-
export const imports = ["_app/immutable/nodes/2.
|
|
8
|
+
export const imports = ["_app/immutable/nodes/2.Cw7ieJWD.js","_app/immutable/chunks/DTingiCe.js","_app/immutable/chunks/ssd4Rw-g.js","_app/immutable/entry/payload.DSmR2FwN.js","_app/immutable/chunks/B0VWrXPj.js"];
|
|
9
9
|
export const stylesheets = ["_app/immutable/assets/2.CZocdpCk.css"];
|
|
10
10
|
export const fonts = [];
|
package/build/server/server.js
CHANGED
|
@@ -10,7 +10,7 @@ return {
|
|
|
10
10
|
app_path: "_app",
|
|
11
11
|
assets: new Set(["favicon.svg","robots.txt"]),
|
|
12
12
|
mime_types: {".svg":"image/svg+xml",".txt":"text/plain"},
|
|
13
|
-
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.
|
|
13
|
+
client: {start:"_app/immutable/entry/start.CzGx2BYz.js",app:"_app/immutable/entry/app.CQWyl0kn.js",imports:["_app/immutable/entry/start.CzGx2BYz.js","_app/immutable/entry/payload.DSmR2FwN.js","_app/immutable/chunks/BaNbYf_w.js","_app/immutable/chunks/CbiRHTcG.js","_app/immutable/chunks/ssd4Rw-g.js","_app/immutable/chunks/DTingiCe.js","_app/immutable/chunks/B0VWrXPj.js","_app/immutable/entry/app.CQWyl0kn.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
|
|
14
14
|
|
|
15
15
|
nodes: [
|
|
16
16
|
__memo(() => import('./nodes/0.js')),
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-usage-dashboard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "vite build",
|
|
8
8
|
"prepublishOnly": "npm run build",
|
|
9
|
-
"start": "node bin/
|
|
9
|
+
"start": "node bin/token-usage-dashboard.js",
|
|
10
10
|
"preview": "vite preview",
|
|
11
11
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
12
12
|
"test": "vitest run",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"cost"
|
|
41
41
|
],
|
|
42
42
|
"license": "MIT",
|
|
43
|
-
"homepage": "https://github.com/NotAFlightRisk/
|
|
44
|
-
"bugs": "https://github.com/NotAFlightRisk/
|
|
43
|
+
"homepage": "https://github.com/NotAFlightRisk/token-usage-dashboard",
|
|
44
|
+
"bugs": "https://github.com/NotAFlightRisk/token-usage-dashboard/issues",
|
|
45
45
|
"bin": {
|
|
46
|
-
"aiusage": "bin/
|
|
46
|
+
"aiusage": "bin/token-usage-dashboard.js"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"bin",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|
|
59
|
-
"url": "git+https://github.com/NotAFlightRisk/
|
|
59
|
+
"url": "git+https://github.com/NotAFlightRisk/token-usage-dashboard.git"
|
|
60
60
|
},
|
|
61
61
|
"imports": {
|
|
62
62
|
"#lib/*": "./src/lib/*"
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{$ as e,A as t,B as n,D as r,F as i,G as a,H as o,J as s,K as c,M as l,N as u,O as d,P as f,Q as p,R as m,S as h,T as g,U as _,V as v,W as y,X as b,Y as x,Z as S,a as C,b as w,c as T,d as E,et as D,f as O,g as k,h as A,i as j,j as ee,k as M,l as N,m as P,n as F,o as I,p as L,q as R,r as z,rt as B,s as V,t as H,tt as U,u as te,v as W,y as ne,z as re}from"../chunks/DTingiCe.js";import{t as ie}from"../chunks/ssd4Rw-g.js";var G=null;function ae(){return G||(G=document.createElement(`div`),G.className=`app-tooltip`,G.setAttribute(`role`,`tooltip`),document.body.append(G),G)}var K=(e,t)=>{let n=t,r=()=>{G&&G.classList.remove(`is-open`)},i=()=>{if(!n)return;let t=ae();t.textContent=n,t.classList.add(`is-open`);let r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),a=Math.min(Math.max(8,r.left+r.width/2-i.width/2),window.innerWidth-i.width-8),o=r.top>i.height+12;t.style.left=`${a}px`,t.style.top=`${o?r.top-i.height-8:r.bottom+8}px`};return e.addEventListener(`pointerenter`,i),e.addEventListener(`focusin`,i),e.addEventListener(`pointerleave`,r),e.addEventListener(`focusout`,r),window.addEventListener(`scroll`,r,!0),{update:t=>{n=t,t&&e.setAttribute(`aria-label`,e.getAttribute(`aria-label`)??t)},destroy:()=>{r(),e.removeEventListener(`pointerenter`,i),e.removeEventListener(`focusin`,i),e.removeEventListener(`pointerleave`,r),e.removeEventListener(`focusout`,r),window.removeEventListener(`scroll`,r,!0)}}},q=M(`<div class="actions svelte-hxsa5u"><!></div>`),oe=M(`<section class="panel svelte-hxsa5u"><header class="svelte-hxsa5u"><h2 class="svelte-hxsa5u"> </h2> <!></header> <div class="body svelte-hxsa5u"><!></div></section>`);function J(e,t){let i=H(t,`span`,3,12);var a=oe(),o=y(a),s=y(o),l=c(s,!0);P(s,(e,t)=>K?.(e,t),()=>t.hint);var u=R(s,2),d=e=>{var n=q(),i=y(n);h(i,()=>t.actions),U(n),r(e,n)};w(u,e=>{t.actions&&e(d)}),U(o);var f=R(o,2),p=y(f);h(p,()=>t.children),U(f),U(a),n(()=>{O(a,`--span: ${i()??``}`),g(l,t.title)}),r(e,a)}var se=M(`<button type="button"> </button>`),ce=M(`<div role="group"></div>`);function le(t,a){e(a,!0);let o=H(a,`value`,15),s=H(a,`size`,3,`md`);var l=ce();let d;W(l,21,()=>a.options,e=>e.id,(e,t)=>{var a=se();let s;var l=c(a,!0);P(a,(e,t)=>K?.(e,t),()=>i(t).hint),n(()=>{T(a,`aria-pressed`,o()===i(t).id),s=L(a,1,`svelte-1dkbyok`,null,s,{on:o()===i(t).id}),g(l,i(t).label)}),u(`click`,a,()=>o(i(t).id)),r(e,a)}),U(l),n(()=>{d=L(l,1,`segmented svelte-1dkbyok`,null,d,{sm:s()===`sm`}),T(l,`aria-label`,a.label)}),r(t,l),p()}l([`click`]);var ue=M(`<b class="num svelte-vbwhwd"> </b>`),de=M(`<label class="svelte-vbwhwd"><input type="checkbox" class="svelte-vbwhwd"/> <span class="svelte-vbwhwd"> </span></label>`),fe=M(`<p class="none svelte-vbwhwd">Nothing matches</p>`),pe=M(`<button type="button" class="clear svelte-vbwhwd">Clear</button>`),me=M(`<div class="menu svelte-vbwhwd"><input class="search svelte-vbwhwd" type="search"/> <div class="list svelte-vbwhwd"></div> <!></div>`),he=M(`<div class="select svelte-vbwhwd"><button type="button"> <!> <svg viewBox="0 0 12 12" width="10" height="10" aria-hidden="true"><path d="M2 4.5 6 8.5 10 4.5" fill="none" stroke="currentColor" stroke-width="1.5"></path></svg></button> <!></div>`);function ge(t,a){e(a,!0);let o=H(a,`selected`,15),s=H(a,`format`,3,e=>e),l=b(!1),d=b(``),m,h=S(()=>a.options.filter(e=>s()(e).toLowerCase().includes(i(d).toLowerCase()))),v=e=>{o(o().includes(e)?o().filter(t=>t!==e):[...o(),e])},C=e=>{i(l)&&!m.contains(e.target)&&x(l,!1)};var E=he();f(`click`,_,C);var O=y(E);let k;var A=y(O),ee=R(A),M=e=>{var t=ue(),i=c(t,!0);n(()=>g(i,o().length)),r(e,t)};w(ee,e=>{o().length&&e(M)}),D(2),U(O);var P=R(O,2),I=e=>{var t=me(),l=y(t);V(l);var f=R(l,2);W(f,20,()=>i(h),e=>e,(e,t)=>{var i=de(),a=y(i);V(a);var l=R(a,2),d=c(l,!0);U(i),n((e,t)=>{N(a,e),g(d,t)},[()=>o().includes(t),()=>s()(t)]),u(`change`,a,()=>v(t)),r(e,i)},e=>{var t=fe();r(e,t)}),U(f);var p=R(f,2),m=e=>{var t=pe();u(`click`,t,()=>o([])),r(e,t)};w(p,e=>{o().length&&e(m)}),U(t),n(e=>T(l,`placeholder`,`Filter ${e??``}`),[()=>a.label.toLowerCase()]),j(l,()=>i(d),e=>x(d,e)),r(e,t)};w(P,e=>{i(l)&&e(I)}),U(E),F(E,e=>m=e,()=>m),n(()=>{k=L(O,1,`trigger svelte-vbwhwd`,null,k,{on:o().length>0}),T(O,`aria-expanded`,i(l)),g(A,`${a.label??``} `)}),u(`click`,O,()=>x(l,!i(l))),r(t,E),p()}l([`click`,`change`]);var _e=[{at:0xe8d4a51000,suffix:`T`},{at:1e9,suffix:`B`},{at:1e6,suffix:`M`},{at:1e3,suffix:`k`}];function Y(e){let t=_e.find(t=>Math.abs(e)>=t.at);if(!t)return String(Math.round(e));let n=e/t.at;return`${n.toFixed(+(n<10))}${t.suffix}`}var X=e=>Math.round(e).toLocaleString(`en-GB`);function Z(e){return e===null?`--`:e===0?`$0`:Math.abs(e)<.01?`<$0.01`:`$${e.toLocaleString(`en-GB`,{minimumFractionDigits:2,maximumFractionDigits:2})}`}function ve(e){return e===null?`--`:Math.abs(e)>=1e3?`$${Y(e)}`:Z(e)}var ye=(e,t=0)=>`${e.toFixed(t)}%`,be=new Intl.RelativeTimeFormat(`en-GB`,{numeric:`auto`}),xe=[[`second`,60],[`minute`,60],[`hour`,24],[`day`,7],[`week`,4.35],[`month`,12]];function Se(e,t=Date.now()){if(!e)return`never`;let n=(e-t)/1e3;if(Math.abs(n)<45)return n<0?`just now`:`in a moment`;for(let[e,t]of xe){if(Math.abs(n)<t)return be.format(Math.round(n),e);n/=t}return be.format(Math.round(n),`year`)}var Ce=e=>new Date(`${e}T00:00:00`).toLocaleDateString(`en-GB`,{weekday:`short`,day:`numeric`,month:`short`}),we=e=>new Date(e).toLocaleString(`en-GB`,{day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`});function Te(e){let t=Math.round(e/6e4);return t<1?`under a minute`:t<60?`${t} min`:`${Math.floor(t/60)}h ${t%60}m`}var Ee=e=>e?e.replace(/\/+$/,``).split(`/`).pop()||e:`unknown`,De=e=>(e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e).replace(/-\d{8}$/,``);function Oe(e,t){if(!t)return null;let n=(e-t)/t*100;return!Number.isFinite(n)||Math.abs(n)<1?{text:`flat`,tone:`even`}:{text:`${n>0?`+`:``}${n.toFixed(0)}%`,tone:n>0?`up`:`down`}}var ke=M(`<span class="delta svelte-l3stpt"> </span>`),Ae=M(`<i> </i>`),je=M(`<div class="figures svelte-l3stpt"><div class="lead svelte-l3stpt"><span class="cap svelte-l3stpt"> </span> <strong class="num svelte-l3stpt"> </strong> <!></div> <dl class="svelte-l3stpt"><div class="svelte-l3stpt"><dt class="svelte-l3stpt">Est. cost</dt> <dd class="num svelte-l3stpt"> <!></dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Sessions</dt> <dd class="num svelte-l3stpt"> </dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Active days</dt> <dd class="num svelte-l3stpt"> </dd></div> <div class="svelte-l3stpt"><dt class="svelte-l3stpt">Daily pace</dt> <dd class="num svelte-l3stpt"> </dd></div></dl></div>`);function Me(t,a){e(a,!0);let o=S(()=>Oe(a.totals.total,a.previous.total)),s=S(()=>Oe(a.totals.cost??0,a.previous.cost??0)),l=S(()=>a.activeDays?a.totals.total/a.activeDays:0);var u=je(),d=y(u),f=y(d),m=c(f),h=R(f,2),_=c(h,!0);P(h,(e,t)=>K?.(e,t),()=>X(a.totals.total));var v=R(h,2),b=e=>{var t=ke(),s=c(t,!0);P(t,(e,t)=>K?.(e,t),()=>`on the ${a.rangeLabel.toLowerCase()} before`),n(()=>g(s,i(o).text)),r(e,t)};w(v,e=>{i(o)&&e(b)}),U(d);var x=R(d,2),C=y(x),T=y(C);P(T,(e,t)=>K?.(e,t),()=>`What these tokens would cost at published API rates. A subscription is billed separately.`);var E=R(T,2),D=y(E),O=R(D),k=e=>{var t=Ae(),a=c(t,!0);n(()=>{L(t,1,`delta cost ${i(s).tone??``}`,`svelte-l3stpt`),g(a,i(s).text)}),r(e,t)};w(O,e=>{i(s)&&e(k)}),U(E),U(C);var A=R(C,2),j=R(y(A),2),ee=c(j,!0);U(A);var M=R(A,2),N=y(M);P(N,(e,t)=>K?.(e,t),()=>`Days with at least one request`);var F=R(N,2),I=c(F,!0);U(M);var z=R(M,2),B=y(z);P(B,(e,t)=>K?.(e,t),()=>`Tokens per active day`);var V=R(B,2),H=c(V,!0);U(z),U(x),U(u),n((e,t,n,r,i,a)=>{g(m,`Tokens, ${e??``}`),g(_,t),g(D,`${n??``} `),g(ee,r),g(I,i),g(H,a)},[()=>a.rangeLabel.toLowerCase(),()=>Y(a.totals.total),()=>Z(a.totals.cost),()=>X(a.totals.sessions),()=>X(a.activeDays),()=>Y(i(l))]),r(t,u),p()}var Ne=t(`<text class="axis svelte-1iu5iby" y="10"> </text>`),Pe=t(`<text class="axis svelte-1iu5iby" x="0"> </text>`),Fe=t(`<rect role="img"></rect>`),Ie=M(`<i class="svelte-1iu5iby"></i>`),Le=M(`<div class="calendar svelte-1iu5iby"><svg role="img" aria-label="Daily usage calendar" class="svelte-1iu5iby"><!><!><!></svg> <div class="legend svelte-1iu5iby"><span class="span svelte-1iu5iby"> </span> <span>No records</span> <i class="blank svelte-1iu5iby"></i> <span class="spread svelte-1iu5iby">Quieter</span> <!> <span>Busier</span></div></div>`);function Re(t,o){e(o,!0);let s=b(680),l=e=>e.toLocaleDateString(`en-CA`),u=e=>e?o.metric===`cost`?e.cost??0:e.total:0,f=S(()=>new Map(o.days.map(e=>[e.day,e]))),m=S(()=>o.oldest?l(new Date(o.oldest)):o.days[0]?.day??``),h=S(()=>{let e=new Date;e.setHours(0,0,0,0);let t=new Date(o.days.length?`${o.days[0].day}T00:00:00`:e),n=new Date(e);n.setDate(n.getDate()-370);let r=new Date(e);r.setDate(r.getDate()-125);let i=new Date(Math.max(n.getTime(),Math.min(t.getTime(),r.getTime())));i.setDate(i.getDate()-(i.getDay()+6)%7);let a=[],s=new Date(i),c=0;for(;s<=e;){let e=(s.getDay()+6)%7;a.push({day:l(s),date:new Date(s),week:c,weekday:e}),e===6&&(c+=1),s.setDate(s.getDate()+1)}return{cells:a,weeks:c+1}}),_=S(()=>Math.max(9,Math.min(30,Math.floor((i(s)-32)/i(h).weeks)-3))),v=S(()=>i(_)+3),C=S(()=>{let e=o.days.map(e=>u(e)).filter(e=>e>0).sort((e,t)=>e-t);return e.length?[.2,.4,.6,.8].map(t=>e[Math.floor(e.length*t)]):[]}),E=e=>e<=0?0:i(C).filter(t=>e>=t).length+1,k=S(()=>{let e=[];for(let t of i(h).cells){if(t.weekday!==0)continue;let n=t.date.toLocaleDateString(`en-GB`,{month:`short`});(!e.length||t.date.getDate()<=7&&e[e.length-1].label!==n)&&e.push({label:n,week:t.week})}return e}),A=e=>{if(i(m)&&e<i(m))return`${Ce(e)} - before your records start`;let t=u(i(f).get(e)),n=o.metric===`cost`?Z(t):`${Y(t)} tokens`;return`${Ce(e)} - ${t?n:`nothing`}`},j=[`Mon`,``,`Wed`,``,`Fri`,``,`Sun`],ee=S(()=>o.days.filter(e=>u(e)>0).length),M=S(()=>i(m)?`Since ${Ce(i(m))}, ${i(ee)} ${i(ee)===1?`day`:`days`} with usage`:``);var N=Le(),F=y(N),I=y(F);W(I,17,()=>i(k),e=>e.week+e.label,(e,t)=>{var a=Ne(),o=c(a,!0);n(()=>{T(a,`x`,32+i(t).week*i(v)),g(o,i(t).label)}),r(e,a)});var B=R(I);W(B,17,()=>j,ne,(e,t,o)=>{var s=d(),l=a(s),u=e=>{var a=Pe(),s=c(a,!0);n(()=>{T(a,`y`,18+o*i(v)+i(_)/2+3),g(s,i(t))}),r(e,a)};w(l,e=>{i(t)&&e(u)}),r(e,s)});var V=R(B);W(V,17,()=>i(h).cells,e=>e.day,(e,t)=>{let a=S(()=>!!i(m)&&i(t).day<i(m));var o=Fe();let s;P(o,(e,t)=>K?.(e,t),()=>A(i(t).day)),n((e,n,r)=>{s=L(o,0,`cell svelte-1iu5iby`,null,s,{blank:i(a)}),T(o,`x`,32+i(t).week*i(v)),T(o,`y`,18+i(t).weekday*i(v)),T(o,`width`,i(_)),T(o,`height`,i(_)),T(o,`rx`,e),T(o,`fill`,`var(--ramp-${n??``})`),T(o,`aria-label`,r)},[()=>Math.max(2,i(_)/4),()=>i(a)?0:E(u(i(f).get(i(t).day))),()=>A(i(t).day)]),r(e,o)}),U(F);var H=R(F,2),te=y(H),re=c(te,!0),ie=R(te,8);W(ie,16,()=>[0,1,2,3,4,5],e=>e,(e,t)=>{var i=Ie();n(()=>O(i,`background: var(--ramp-${t??``})`)),r(e,i)}),D(2),U(H),U(N),n(()=>{T(F,`width`,i(h).weeks*i(v)+32),T(F,`height`,7*i(v)+18),g(re,i(M))}),z(N,`clientWidth`,e=>x(s,e)),r(t,N),p()}var ze=M(`<div class="tick svelte-118k1un"><span class="svelte-118k1un"> </span></div>`),Be=M(`<span aria-hidden="true" class="svelte-118k1un"></span>`),Ve=M(`<div class="column svelte-118k1un"><div class="stack svelte-118k1un"></div></div>`),He=M(`<div class="trend svelte-118k1un"><div class="plot svelte-118k1un"><!> <div class="bars svelte-118k1un"></div></div> <div class="axis svelte-118k1un"><span> </span> <span> </span></div></div>`);function Ue(t,o){e(o,!0);let s=e=>o.metric===`cost`?e.cost??0:e.total,l=e=>o.metric===`cost`?Z(e):Y(e),u=S(()=>{let e=new Map;for(let t of o.series){let n=e.get(t.day)??{day:t.day,total:0,parts:new Map};n.total+=s(t),n.parts.set(t.key,(n.parts.get(t.key)??0)+s(t)),e.set(t.day,n)}return[...e.values()].sort((e,t)=>e.day.localeCompare(t.day))}),f=S(()=>Math.max(1,...i(u).map(e=>e.total))),m=e=>{let t=o.keys.filter(t=>e.parts.get(t.id)).map(t=>`${t.label} ${l(e.parts.get(t.id)??0)}`).join(`, `);return`${Ce(e.day)} - ${l(e.total)}${t?` (${t})`:``}`},h=e=>o.metric===`cost`?ve(e):Y(e),_=S(()=>[1,.5,0].map(e=>({at:e,label:h(i(f)*e)})));var v=He(),b=y(v),x=y(b);W(x,17,()=>i(_),e=>e.at,(e,t)=>{var a=ze(),o=y(a),s=c(o,!0);U(a),n(()=>{O(a,`bottom: ${i(t).at*100}%`),g(s,i(t).label)}),r(e,a)});var C=R(x,2);W(C,21,()=>i(u),e=>e.day,(e,t)=>{var s=Ve(),c=y(s);W(c,21,()=>o.keys,e=>e.id,(e,o)=>{let s=S(()=>i(t).parts.get(i(o).id)??0);var c=d(),l=a(c),u=e=>{var t=Be();n(()=>O(t,`flex: ${i(s)??``}; background: ${i(o).colour??``}`)),r(e,t)};w(l,e=>{i(s)>0&&e(u)}),r(e,c)}),U(c),U(s),P(s,(e,t)=>K?.(e,t),()=>m(i(t))),n(()=>O(c,`height: ${i(t).total/i(f)*100}%`)),r(e,s)}),U(C),U(b);var T=R(b,2),E=y(T),D=c(E,!0),k=R(E,2),A=c(k,!0);U(T),U(v),n((e,t)=>{g(D,e),g(A,t)},[()=>i(u).length?Ce(i(u)[0].day):``,()=>i(u).length?Ce(i(u)[i(u).length-1].day):``]),r(t,v),p()}var We=`M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81`,Ge={anthropic:`M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z`,openai:`M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z`,google:We,xai:`M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815`,meta:`M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z`,mistral:`M17.143 3.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z`,deepseek:`M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45`,qwen:`M23.919 14.545 20.817 9.17l1.47-2.544a.56.56 0 0 0 0-.566l-1.633-2.83a.57.57 0 0 0-.49-.283h-6.207L12.487.402a.57.57 0 0 0-.49-.284H8.732a.56.56 0 0 0-.49.284L5.139 5.775h-2.94a.56.56 0 0 0-.49.284L.077 8.887a.56.56 0 0 0 0 .567L3.18 14.83l-1.47 2.545a.56.56 0 0 0 0 .566l1.634 2.83a.57.57 0 0 0 .49.283h6.205l1.47 2.545a.57.57 0 0 0 .49.284h3.266a.57.57 0 0 0 .49-.284l3.104-5.375h2.94a.57.57 0 0 0 .49-.283l1.634-2.828a.55.55 0 0 0-.004-.568M8.733.686l1.634 2.828-1.634 2.828H21.8L20.164 9.17H7.425L5.63 6.06Zm1.306 19.801-6.205-.002 1.634-2.83h3.265L2.201 6.344h3.267q3.182 5.517 6.367 11.032zm10.124-5.66L18.53 12l-6.532 11.315-1.634-2.83c2.129-3.673 4.25-7.351 6.373-11.028h3.592l3.102 5.374z`,"claude-code":`M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z`,codex:`M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z`,opencode:`M22 24H2V0h20zM17 4.8H7v14.4h10z`,"gemini-cli":We},Ke=t(`<path fill="currentColor"></path>`),qe=t(`<rect x="1.5" y="1.5" width="21" height="21" rx="6" fill="none" stroke="currentColor" stroke-width="1.8"></rect><text x="12" y="12.5" text-anchor="middle" dominant-baseline="central" fill="currentColor" font-weight="600" font-family="var(--sans)"> </text>`,1),Je=t(`<svg class="mark svelte-jlywqn" viewBox="0 0 24 24" role="img"><!></svg>`);function Ye(t,o){e(o,!0);let s=H(o,`size`,3,16),l=S(()=>Ge[o.id]),u=S(()=>o.label.replace(/[^a-z ]/gi,``).split(` `).map(e=>e[0]).join(``).slice(0,2).toUpperCase());var d=Je();let f;var m=y(d),h=e=>{var t=Ke();n(()=>T(t,`d`,i(l))),r(e,t)},_=e=>{var t=qe(),o=R(a(t)),s=c(o,!0);n(()=>{T(o,`font-size`,i(u).length>1?9:12),g(s,i(u))}),r(e,t)};w(m,e=>{i(l)?e(h):e(_,-1)}),U(d),n(()=>{T(d,`width`,s()),T(d,`height`,s()),T(d,`aria-label`,o.label),f=O(d,``,f,{color:o.colour})}),r(t,d),p()}var Xe=M(`<i class="dot svelte-eh60s9"></i>`),Ze=M(`<em class="svelte-eh60s9"> </em>`),Qe=M(`<span class="fill svelte-eh60s9"></span> <span class="label svelte-eh60s9"><!> <b class="svelte-eh60s9"> </b> <!></span> <span class="value num svelte-eh60s9"> </span>`,1),$e=M(`<li><!></li>`),et=M(`<ul class="bars svelte-eh60s9"></ul>`),tt=M(`<p class="empty svelte-eh60s9"> </p>`);function nt(t,o){e(o,!0);let s=H(o,`active`,19,()=>[]),l=H(o,`empty`,3,`Nothing in this range`),u=S(()=>Math.max(1,...o.rows.map(e=>e.value)));var f=d(),m=a(f),h=e=>{var t=et();W(t,21,()=>o.rows,e=>e.id,(e,t)=>{var l=$e(),d=y(l);k(d,()=>o.onpick?`button`:`div`,!1,(e,l)=>{P(e,(e,t)=>K?.(e,t),()=>i(t).hint);var d=()=>o.onpick?.(i(t).id);I(e,e=>({class:`row`,role:o.onpick?`button`:void 0,tabindex:o.onpick?0:void 0,onclick:d,[C]:{on:e}}),[()=>s().includes(i(t).id)],void 0,void 0,`svelte-eh60s9`);var f=Qe(),p=a(f),m=R(p,2),h=y(m),_=e=>{Ye(e,{get id(){return i(t).mark},get label(){return i(t).label},get colour(){return i(t).colour},size:15})},v=e=>{var a=Xe();n(()=>O(a,`background: ${i(t).colour??``}`)),r(e,a)};w(h,e=>{i(t).mark?e(_):e(v,-1)});var b=R(h,2),x=c(b,!0),S=R(b,2),T=e=>{var a=Ze(),o=c(a,!0);n(()=>g(o,i(t).detail)),r(e,a)};w(S,e=>{i(t).detail&&e(T)}),U(m);var E=R(m,2),D=c(E,!0);n(()=>{O(p,`width: ${i(t).value/i(u)*100}%; background: ${i(t).colour??``}`),g(x,i(t).label),g(D,i(t).display)}),r(l,f)}),U(l),r(e,l)}),U(t),r(e,t)},_=e=>{var t=tt(),i=c(t,!0);n(()=>g(i,l())),r(e,t)};w(m,e=>{o.rows.length?e(h):e(_,-1)}),r(t,f),p()}var rt=t(`<circle cx="70" cy="70" fill="none" stroke-width="18" transform="rotate(-90 70 70)" class="svelte-1o711x0"></circle>`),it=M(`<div class="donut svelte-1o711x0"><svg viewBox="0 0 140 140" role="img" class="svelte-1o711x0"><circle cx="70" cy="70" fill="none" stroke="var(--surface-3)" stroke-width="18" class="svelte-1o711x0"></circle><!><text class="centre num svelte-1o711x0" x="70" y="66" text-anchor="middle"> </text><text class="sub svelte-1o711x0" x="70" y="84" text-anchor="middle"> </text></svg></div>`);function at(t,a){e(a,!0);let o=2*Math.PI*52,s=S(()=>{let e=a.slices.reduce((e,t)=>e+t.value,0)||1,t=0;return a.slices.map(n=>{let r=n.value/e*o,i={...n,length:r,offset:t,share:n.value/e*100};return t+=r,i})});var l=it(),u=y(l),d=y(u);T(d,`r`,52);var f=R(d);W(f,17,()=>i(s),e=>e.id,(e,t)=>{var a=rt();T(a,`r`,52),P(a,(e,t)=>K?.(e,t),()=>`${i(t).label} - ${i(t).display} (${i(t).share.toFixed(1)}%)`),n(e=>{T(a,`stroke`,i(t).colour),T(a,`stroke-dasharray`,`${e??``} 326.7256359733385`),T(a,`stroke-dashoffset`,-i(t).offset)},[()=>Math.max(0,i(t).length-2)]),r(e,a)});var m=R(f),h=c(m,!0),_=R(m),v=c(_,!0);U(u),U(l),n(()=>{T(u,`aria-label`,a.caption),g(h,a.centre),g(v,a.caption)}),r(t,l),p()}var ot=M(`<span class="svelte-1qwkpf0"></span>`),st=M(`<li class="svelte-1qwkpf0"><i class="svelte-1qwkpf0"></i> <span class="name svelte-1qwkpf0"> </span> <span class="value num svelte-1qwkpf0"> </span> <span class="share num svelte-1qwkpf0"> </span></li>`),ct=M(`<div class="split svelte-1qwkpf0"><div class="bar svelte-1qwkpf0"></div> <ul class="svelte-1qwkpf0"></ul></div>`);function lt(t,o){e(o,!0);let s=S(()=>o.parts.reduce((e,t)=>e+t.value,0)||1);var l=ct(),u=y(l);W(u,21,()=>o.parts,e=>e.id,(e,t)=>{var o=d(),c=a(o),l=e=>{var a=ot();P(a,(e,t)=>K?.(e,t),()=>`${i(t).label} - ${i(t).display} (${(i(t).value/i(s)*100).toFixed(1)}%)`),n(()=>O(a,`flex: ${i(t).value??``}; background: ${i(t).colour??``}`)),r(e,a)};w(c,e=>{i(t).value>0&&e(l)}),r(e,o)}),U(u);var f=R(u,2);W(f,21,()=>o.parts,e=>e.id,(e,t)=>{var a=st(),o=y(a),l=R(o,2),u=c(l,!0),d=R(l,2),f=c(d,!0),p=R(d,2),m=c(p);U(a),P(a,(e,t)=>K?.(e,t),()=>i(t).hint),n(e=>{O(o,`background: ${i(t).colour??``}`),g(u,i(t).label),g(f,i(t).display),g(m,`${e??``}%`)},[()=>(i(t).value/i(s)*100).toFixed(1)]),r(e,a)}),U(f),U(l),r(t,l),p()}var ut=M(`<i class="svelte-13d36y"></i>`),dt=M(`<span class="day svelte-13d36y"> </span> <div class="hours svelte-13d36y"></div>`,1),ft=M(`<span> </span>`),pt=M(`<div class="clock svelte-13d36y"><div class="rows svelte-13d36y"></div> <div class="scale svelte-13d36y"><!> <span>23</span></div></div>`);function mt(t,o){e(o,!0);let s=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],l=S(()=>{let e=new Map;for(let t of o.points){let n=(t.day+6)%7;e.set(`${n}-${t.hour}`,(e.get(`${n}-${t.hour}`)??0)+t.total)}return e}),u=S(()=>Math.max(1,...i(l).values())),d=e=>e?.32+.68*Math.sqrt(e/i(u)):0;var f=pt(),m=y(f);W(m,22,()=>s,e=>e,(e,t,o)=>{var s=dt(),u=a(s),f=c(u,!0),p=R(u,2);W(p,20,()=>Array(24),ne,(e,a,s)=>{let c=S(()=>i(l).get(`${i(o)}-${s}`)??0);var u=ut();P(u,(e,t)=>K?.(e,t),()=>`${t} ${String(s).padStart(2,`0`)}:00 - ${i(c)?`${Y(i(c))} tokens`:`nothing`}`),n(e=>O(u,`--dot: ${e??``}`),[()=>d(i(c))]),r(e,u)}),U(p),n(()=>g(f,t)),r(e,s)}),U(m);var h=R(m,2),_=y(h);W(_,16,()=>[0,6,12,18],e=>e,(e,t)=>{var i=ft(),a=c(i,!0);n(e=>g(a,e),[()=>String(t).padStart(2,`0`)]),r(e,i)}),D(2),U(h),U(f),r(t,f),p()}var ht=M(`<div><div class="top svelte-tlhxud"><span class="name svelte-tlhxud"> </span> <span class="num pct svelte-tlhxud"> </span></div> <div class="track svelte-tlhxud" role="meter" aria-valuemin="0" aria-valuemax="100"><span class="svelte-tlhxud"></span></div> <span class="reset svelte-tlhxud"><!></span></div>`);function gt(t,a){e(a,!0);let o=S(()=>!!a.window.resets_at&&a.window.resets_at<Date.now()),s=S(()=>i(o)?`text-faint`:a.window.used_percent>=90?`bad`:a.window.used_percent>=70?`warn`:`good`),l=S(()=>[a.window.detail,a.window.resets_at?`resets ${Se(a.window.resets_at)}`:``,`seen ${Se(a.window.seen_at)}`].filter(Boolean).join(` - `));var u=ht();let d;var f=y(u),m=y(f),h=c(m,!0),_=R(m,2),v=c(_);U(f);var b=R(f,2),x=c(b),C=R(b,2),E=y(C),D=e=>{var t=ee();n(e=>g(t,`window has turned over, last read ${e??``}`),[()=>Se(a.window.seen_at)]),r(e,t)},k=e=>{var t=ee();n(e=>g(t,`resets ${e??``}`),[()=>Se(a.window.resets_at)]),r(e,t)};w(E,e=>{i(o)?e(D):a.window.resets_at&&e(k,1)}),U(C),U(u),P(u,(e,t)=>K?.(e,t),()=>i(l)),n((e,t,n)=>{d=L(u,1,`meter svelte-tlhxud`,null,d,{stale:i(o)}),g(h,a.window.label),O(_,`color: var(--${i(s)??``})`),g(v,`${e??``}%`),T(b,`aria-valuenow`,t),T(b,`aria-label`,a.window.label),O(x,`width: ${n??``}%; background: var(--${i(s)??``})`)},[()=>Math.round(a.window.used_percent),()=>Math.round(a.window.used_percent),()=>Math.min(100,a.window.used_percent)]),r(t,u),p()}var _t=[{id:`anthropic`,label:`Anthropic`,colour:`#d97757`},{id:`openai`,label:`OpenAI`,colour:`#10a37f`},{id:`google`,label:`Google`,colour:`#4285f4`},{id:`meta`,label:`Meta`,colour:`#0668e1`},{id:`mistral`,label:`Mistral`,colour:`#fa520f`},{id:`xai`,label:`xAI`,colour:`#7c7c8a`},{id:`deepseek`,label:`DeepSeek`,colour:`#4d6bfe`},{id:`qwen`,label:`Qwen`,colour:`#a855f7`},{id:`unknown`,label:`Other`,colour:`#8b93a7`}],vt=[[/^claude/,`anthropic`],[/^(gpt|codex|o[1-4]-|chatgpt|text-embedding)/,`openai`],[/^(gemini|gemma|palm)/,`google`],[/^(llama|code-?llama)/,`meta`],[/^(mistral|mixtral|codestral|magistral|devstral)/,`mistral`],[/^grok/,`xai`],[/^deepseek/,`deepseek`],[/^(qwen|qwq)/,`qwen`]];function yt(e){let t=e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e,n=e.includes(`/`)?e.slice(0,e.indexOf(`/`)).toLowerCase():``;return _t.some(e=>e.id===n)?n:vt.find(([e])=>e.test(t.toLowerCase()))?.[1]??`unknown`}var bt=e=>_t.find(t=>t.id===e)??_t[_t.length-1],xt=[{id:`claude-code`,label:`Claude Code`,colour:`#d97757`,home:`https://claude.com/claude-code`},{id:`codex`,label:`Codex`,colour:`#10a37f`,home:`https://developers.openai.com/codex`},{id:`opencode`,label:`OpenCode`,colour:`#f5a524`,home:`https://opencode.ai`},{id:`gemini-cli`,label:`Gemini CLI`,colour:`#4285f4`,home:`https://github.com/google-gemini/gemini-cli`}],St=e=>xt.find(t=>t.id===e)??{id:e,label:e,colour:`#8b93a7`,home:``},Ct=e=>e===null?`--`:ye(e*100),wt=[{id:`session`,label:`Session`,hint:`The tool and its session id`,by:e=>e.id},{id:`name`,label:`Session name`,hint:`What the session was called, if it got a name`,by:e=>e.name,show:e=>e.name??``},{id:`project`,label:`Project`,hint:`Where it ran`,by:e=>e.project},{id:`models`,label:`Models`,hint:`Every model the session used`,by:e=>e.models,show:e=>e.models.split(`, `).map(De).join(`, `)},{id:`ran`,label:`Ran`,hint:`When it last did anything`,by:e=>e.ended,show:e=>we(e.ended)},{id:`tokens`,label:`Tokens`,hint:`Everything in and out, cache included`,by:e=>e.total,show:e=>Y(e.total),numeric:!0},{id:`cost`,label:`Est. cost`,hint:`Worked out from list prices, not your bill`,by:e=>e.cost,show:e=>Z(e.cost),numeric:!0},{id:`peak`,label:`Peak context`,hint:`The biggest prompt the model was handed in one go`,by:e=>e.peak,show:e=>Y(e.peak),numeric:!0},{id:`cache`,label:`Cache hits`,hint:`How much of the input came straight from cache`,by:e=>e.cacheHit,show:e=>Ct(e.cacheHit),numeric:!0},{id:`subagents`,label:`Subagents`,hint:`Share of the tokens spent by subagents. Claude Code only.`,by:e=>e.subagents,show:e=>Ct(e.subagents),numeric:!0},{id:`turns`,label:`Turns`,hint:`Replies from the model, subagents included`,by:e=>e.turns,show:e=>String(e.turns),numeric:!0}],Tt=M(`<th scope="col"><button type="button" class="svelte-1uqtl83"> </button></th>`),Et=M(`<td class="svelte-1uqtl83"><span class="tool svelte-1uqtl83"><!> <span class="id mono svelte-1uqtl83"> </span></span></td>`),Dt=M(`<td class="svelte-1uqtl83"><button type="button" class="link svelte-1uqtl83"> </button></td>`),Ot=M(`<td class="svelte-1uqtl83"> </td>`),kt=M(`<td> </td>`),At=M(`<tr class="svelte-1uqtl83"></tr>`),jt=M(`<div class="scroll svelte-1uqtl83"><table class="svelte-1uqtl83"><thead><tr></tr></thead><tbody class="svelte-1uqtl83"></tbody></table></div>`),Mt=M(`<p class="empty svelte-1uqtl83">No sessions in this range</p>`);function Nt(t,o){e(o,!0);let s=b(`ran`),l=b(!0),f=S(()=>wt.filter(e=>!o.hidden.includes(e.id)&&(e.id!==`name`||o.rows.some(e=>e.name)))),m=S(()=>{let e=(wt.find(e=>e.id===i(s))??wt[0]).by;return o.rows.toSorted((t,n)=>{let[r,a]=[e(t),e(n)];if(r===a)return 0;if(r===null)return 1;if(a===null)return-1;let o=r<a?-1:1;return i(l)?-o:o})});function h(e){x(l,i(s)===e.id?!i(l):!!(e.numeric||e.id===`ran`),!0),x(s,e.id,!0)}var _=d(),v=a(_),C=e=>{var t=jt(),p=y(t),_=y(p),v=y(_);W(v,21,()=>i(f),e=>e.id,(e,t)=>{var a=Tt();let o;var d=y(a),f=c(d,!0);P(d,(e,t)=>K?.(e,t),()=>i(t).hint),U(a),n(()=>{T(a,`aria-sort`,i(s)===i(t).id?i(l)?`descending`:`ascending`:`none`),o=L(a,1,`svelte-1uqtl83`,null,o,{right:i(t).numeric}),g(f,i(t).label)}),u(`click`,d,()=>h(i(t))),r(e,a)}),U(v),U(_);var b=R(_);W(b,21,()=>i(m),e=>`${e.tool}:${e.id}`,(e,t)=>{let s=S(()=>St(i(t).tool));var l=At();W(l,21,()=>i(f),e=>e.id,(e,l)=>{var f=d(),p=a(f),m=e=>{var a=Et(),o=y(a),l=y(o);Ye(l,{get id(){return i(t).tool},get label(){return i(s).label},get colour(){return i(s).colour},size:14});var u=R(l,2),d=c(u,!0);P(u,(e,t)=>K?.(e,t),()=>i(t).id),U(o),U(a),n(e=>g(d,e),[()=>i(t).id.slice(0,8)]),r(e,a)},h=e=>{var a=Dt(),s=y(a),l=c(s,!0);P(s,(e,t)=>K?.(e,t),()=>i(t).project||`unknown`),U(a),n(e=>g(l,e),[()=>Ee(i(t).project)]),u(`click`,s,()=>o.onpick?.(i(t).project)),r(e,a)},_=e=>{var a=Ot(),o=c(a,!0);P(a,(e,t)=>K?.(e,t),()=>`${we(i(t).started)} for ${Te(i(t).ended-i(t).started)}`),n(e=>g(o,e),[()=>i(l).show?.(i(t))]),r(e,a)},v=e=>{var a=kt();let o;var s=c(a,!0);n(e=>{o=L(a,1,`svelte-1uqtl83`,null,o,{right:i(l).numeric,num:i(l).numeric,muted:!i(l).numeric}),g(s,e)},[()=>i(l).show?.(i(t))]),r(e,a)};w(p,e=>{i(l).id===`session`?e(m):i(l).id===`project`?e(h,1):i(l).id===`ran`?e(_,2):e(v,-1)}),r(e,f)}),U(l),r(e,l)}),U(b),U(p),U(t),r(e,t)},E=e=>{var t=Mt();r(e,t)};w(v,e=>{o.rows.length?e(C):e(E,-1)}),r(t,_),p()}l([`click`]);var Pt=M(`<label class="svelte-17j4bwj"><input type="checkbox" class="svelte-17j4bwj"/> <span> </span></label>`),Ft=M(`<div class="menu svelte-17j4bwj"></div>`),It=M(`<div class="fields svelte-17j4bwj"><button type="button" class="trigger svelte-17j4bwj" aria-label="Choose columns"><svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M2.5 4h11M2.5 8h11M2.5 12h11M6 2.5v11M10 2.5v11" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path></svg></button> <!></div>`);function Lt(t,a){e(a,!0);let o=H(a,`hidden`,15),s=b(!1),l,d=e=>{o(o().includes(e)?o().filter(t=>t!==e):[...o(),e]),a.onchange?.(o())},m=e=>{i(s)&&!l.contains(e.target)&&x(s,!1)};var h=It();f(`click`,_,m);var v=y(h);P(v,(e,t)=>K?.(e,t),()=>`Choose columns`);var S=R(v,2),C=e=>{var t=Ft();W(t,21,()=>a.options,e=>e.id,(e,t)=>{var a=Pt(),s=y(a);V(s);var l=R(s,2),f=c(l,!0);U(a),n(e=>{N(s,e),g(f,i(t).label)},[()=>!o().includes(i(t).id)]),u(`change`,s,()=>d(i(t).id)),r(e,a)}),U(t),r(e,t)};w(S,e=>{i(s)&&e(C)}),U(h),F(h,e=>l=e,()=>l),n(()=>T(v,`aria-expanded`,i(s))),u(`click`,v,()=>x(s,!i(s))),r(t,h),p()}l([`click`,`change`]);var Rt=M(`<span class="hint svelte-1vaf4tg"> </span>`),zt=M(`<li class="svelte-1vaf4tg"><div class="svelte-1vaf4tg"><b class="svelte-1vaf4tg"> </b> <span class="svelte-1vaf4tg"> </span> <!> <time class="svelte-1vaf4tg"> </time></div> <button type="button" class="close svelte-1vaf4tg" aria-label="Dismiss"><svg viewBox="0 0 16 16" width="13" height="13" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg></button></li>`),Bt=M(`<ul class="svelte-1vaf4tg"></ul>`),Vt=M(`<aside aria-live="polite"><button type="button" class="head svelte-1vaf4tg"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><circle cx="8" cy="8" r="6.6" fill="none" stroke="currentColor" stroke-width="1.5"></circle><path d="M8 4.6v4.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path><circle cx="8" cy="11.4" r="0.9" fill="currentColor"></circle></svg> <span class="svelte-1vaf4tg"> </span> <em class="svelte-1vaf4tg"> </em></button> <!></aside>`);function Ht(t,o){e(o,!0);let l=b(s([])),f=b(!1),m=S(()=>o.problems.filter(e=>!i(l).includes(e.id))),h=S(()=>i(m).some(e=>e.level===`error`)?`error`:i(m).some(e=>e.level===`warn`)?`warn`:`info`);var _=d(),v=a(_),C=e=>{var t=Vt(),a=y(t),o=R(y(a),2),s=c(o,!0),d=R(o,2),p=c(d,!0);U(a);var _=R(a,2),v=e=>{var t=Bt();W(t,21,()=>i(m),e=>e.id,(e,t)=>{var a=zt(),o=y(a),s=y(o),d=c(s,!0),f=R(s,2),p=c(f,!0),m=R(f,2),h=e=>{var a=Rt(),o=c(a,!0);n(()=>g(o,i(t).hint)),r(e,a)};w(m,e=>{i(t).hint&&e(h)});var _=R(m,2),v=c(_,!0);U(o);var b=R(o,2);U(a),n(e=>{g(d,i(t).scope),g(p,i(t).message),g(v,e)},[()=>Se(i(t).at)]),u(`click`,b,()=>x(l,[...i(l),i(t).id],!0)),r(e,a)}),U(t),r(e,t)};w(_,e=>{i(f)&&e(v)}),U(t),n(()=>{L(t,1,`problems ${i(h)??``}`,`svelte-1vaf4tg`),T(a,`aria-expanded`,i(f)),g(s,i(m).length===1?i(m)[0].message:`${i(m).length} things need a look`),g(p,i(f)?`Hide`:`Details`)}),u(`click`,a,()=>x(f,!i(f))),r(e,t)};w(v,e=>{i(m).length&&e(C)}),r(t,_),p()}l([`click`]);var Ut=[{id:`today`,label:`Today`,days:1},{id:`7d`,label:`7 days`,days:7},{id:`30d`,label:`30 days`,days:30},{id:`90d`,label:`90 days`,days:90},{id:`1y`,label:`12 months`,days:365},{id:`all`,label:`All time`,days:0}],Wt=e=>Ut.find(t=>t.id===e)?.label??`30 days`,Q=(e,t)=>({input:e,output:t,cacheRead:e*.1,cacheWrite:e*1.25}),$=(e,t)=>({input:e,output:t,cacheRead:e*.1,cacheWrite:0}),Gt={"claude-fable-5":Q(10,50),"claude-opus-5":Q(5,25),"claude-opus-4-8":Q(5,25),"claude-opus-4-7":Q(5,25),"claude-opus-4-6":Q(5,25),"claude-opus-4-5":Q(5,25),"claude-opus-4-1":Q(15,75),"claude-sonnet-5":Q(3,15),"claude-sonnet-4-6":Q(3,15),"claude-sonnet-4-5":Q(3,15),"claude-sonnet-4":Q(3,15),"claude-haiku-4-5":Q(1,5),"claude-3-5-haiku":Q(.8,4),"gpt-5.6-sol-pro":$(2.5,15),"gpt-5.6-sol":$(2.5,15),"gpt-5.6-terra":$(2,12),"gpt-5.6-luna":$(.2,1.2),"gpt-5":$(1.25,10),"gpt-5-mini":$(.25,2),"gpt-5-nano":$(.05,.4),"gpt-4.1":$(2,8),"gpt-4o":$(2.5,10),"gemini-3-pro":$(2,12),"gemini-2.5-pro":$(1.25,10),"gemini-2.5-flash":$(.3,2.5)},Kt=[{id:`auto`,label:`Match the system`},{id:`light`,label:`Light`},{id:`dark`,label:`Dark`},{id:`dracula`,label:`Dracula`},{id:`catppuccin`,label:`Catppuccin Mocha`},{id:`tokyo-night`,label:`Tokyo Night`},{id:`nord`,label:`Nord`},{id:`gruvbox`,label:`Gruvbox dark`},{id:`solarized`,label:`Solarized dark`}],qt=M(`<option> </option>`),Jt=M(`<li class="svelte-anx9w7"><div><b class="svelte-anx9w7"> </b> <code class="svelte-anx9w7"> </code></div> <span> </span></li>`),Yt=M(`<code class="svelte-anx9w7"> </code> `,1),Xt=M(`<li class="svelte-anx9w7"><code class="svelte-anx9w7"> </code> <span class="num"> </span> <button type="button" class="svelte-anx9w7">Remove</button></li>`),Zt=M(`<ul class="prices svelte-anx9w7"></ul>`),Qt=M(`<dialog aria-labelledby="settings-title" class="svelte-anx9w7"><header class="svelte-anx9w7"><h2 id="settings-title" class="svelte-anx9w7">Settings</h2> <button type="button" class="close svelte-anx9w7" aria-label="Close settings"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg></button></header> <div class="body svelte-anx9w7"><section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Appearance</h3> <label class="field svelte-anx9w7"><span>Theme</span> <select class="svelte-anx9w7"></select></label> <label class="field svelte-anx9w7"><span>Range on open</span> <select class="svelte-anx9w7"></select></label> <label class="field svelte-anx9w7"><span>Headline measure</span> <select class="svelte-anx9w7"><option>Tokens</option><option>Estimated cost</option></select></label></section> <section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Data</h3> <ul class="sources svelte-anx9w7"></ul> <p class="note svelte-anx9w7">Point these somewhere else with <!>. History lives in <code class="svelte-anx9w7"> </code> and outlives the transcripts, which most tools prune.</p> <label class="field svelte-anx9w7"><span>Rescan every</span> <select class="svelte-anx9w7"><option>30 seconds</option><option>2 minutes</option><option>10 minutes</option><option>an hour</option></select></label> <label class="check svelte-anx9w7"><input type="checkbox" class="svelte-anx9w7"/> <span>Ask Anthropic for your 5-hour and 7-day windows <em class="svelte-anx9w7">Reads the Claude Code credentials on this machine. Nothing else leaves it.</em></span></label> <div class="row svelte-anx9w7"><button type="button" class="action svelte-anx9w7">Rescan now</button> <span class="note svelte-anx9w7"> </span></div></section> <section class="svelte-anx9w7"><h3 class="svelte-anx9w7">Prices</h3> <p class="note svelte-anx9w7"> </p> <!> <div class="add svelte-anx9w7"><input placeholder="model id" class="svelte-anx9w7"/> <input placeholder="in" inputmode="decimal" class="svelte-anx9w7"/> <input placeholder="out" inputmode="decimal" class="svelte-anx9w7"/> <button type="button" class="action svelte-anx9w7">Add</button></div></section></div></dialog>`);function $t(t,o){e(o,!0);let s=H(o,`open`,15),l,d=b(``),m=b(``),h=b(``);v(()=>{s()&&!l.open&&l.showModal(),!s()&&l.open&&l.close()});let _=S(()=>Object.entries(o.saved.prices));function C(){let e=Number(i(m)),t=Number(i(h));i(d).trim()&&Number.isFinite(e)&&Number.isFinite(t)&&(o.onsave({prices:{...o.saved.prices,[i(d).trim()]:{input:e,output:t,cacheRead:e*.1,cacheWrite:e*1.25}}}),x(d,``),x(m,``),x(h,``))}function T(e){let t={...o.saved.prices};delete t[e],o.onsave({prices:t})}let O={"claude-code":`AIUSAGE_CLAUDE_DIR`,codex:`AIUSAGE_CODEX_DIR`,opencode:`AIUSAGE_OPENCODE_DIR`};var k=Qt(),A=y(k),ee=R(y(A),2);U(A);var M=R(A,2),P=y(M),I=R(y(P),2),z=R(y(I),2);W(z,21,()=>Kt,e=>e.id,(e,t)=>{var a=qt(),o=c(a,!0),s={};n(()=>{g(o,i(t).label),s!==(s=i(t).id)&&(a.value=(a.__value=s)??``)}),r(e,a)}),U(z);var ne;te(z),U(I);var re=R(I,2),ie=R(y(re),2);W(ie,21,()=>Ut,e=>e.id,(e,t)=>{var a=qt(),o=c(a,!0),s={};n(()=>{g(o,i(t).label),s!==(s=i(t).id)&&(a.value=(a.__value=s)??``)}),r(e,a)}),U(ie);var G;te(ie),U(re);var ae=R(re,2),K=R(y(ae),2),q=y(K);q.value=q.__value=`tokens`;var oe=R(q);oe.value=oe.__value=`cost`,U(K);var J;te(K),U(ae),U(P);var se=R(P,2),ce=R(y(se),2);W(ce,21,()=>o.sources,e=>e.id,(e,t)=>{var a=Jt(),o=y(a),s=y(o),l=c(s,!0),u=R(s,2),d=c(u,!0);U(o);var f=R(o,2);let p;var m=c(f,!0);U(a),n(()=>{g(l,i(t).label),g(d,i(t).root),p=L(f,1,`badge svelte-anx9w7`,null,p,{on:i(t).present}),g(m,i(t).present?`${i(t).files} files`:`not found`)}),r(e,a)}),U(ce);var le=R(ce,2),ue=R(y(le));W(ue,19,()=>o.sources,e=>e.id,(e,t,s)=>{var l=Yt(),u=a(l),d=c(u,!0),f=R(u,1,!0);n(()=>{g(d,O[i(t).id]??i(t).id),g(f,i(s)<o.sources.length-1?`, `:``)}),r(e,l)});var de=R(ue,2),fe=c(de,!0);D(),U(le);var pe=R(le,2),me=R(y(pe),2),he=y(me);he.value=he.__value=`30`;var ge=R(he);ge.value=ge.__value=`120`;var _e=R(ge);_e.value=_e.__value=`600`;var Y=R(_e);Y.value=Y.__value=`3600`,U(me);var X;te(me),U(pe);var Z=R(pe,2),ve=y(Z);V(ve),D(2),U(Z);var ye=R(Z,2),be=y(ye),xe=R(be,2),Ce=c(xe);U(ye),U(se);var we=R(se,2),Te=R(y(we),2),Ee=c(Te),De=R(Te,2),Oe=e=>{var t=Zt();W(t,21,()=>i(_),([e,t])=>e,(e,t)=>{var a=S(()=>B(i(t),2));let o=()=>i(a)[0],s=()=>i(a)[1];var l=Xt(),d=y(l),f=c(d,!0),p=R(d,2),m=c(p),h=R(p,2);U(l),n(()=>{g(f,o()),g(m,`in ${s().input??``} / out ${s().output??``}`)}),u(`click`,h,()=>T(o())),r(e,l)}),U(t),r(e,t)};w(De,e=>{i(_).length&&e(Oe)});var ke=R(De,2),Ae=y(ke);V(Ae);var je=R(Ae,2);V(je);var Me=R(je,2);V(Me);var Ne=R(Me,2);U(ke),U(we),U(M),U(k),F(k,e=>l=e,()=>l),n((e,t,n)=>{ne!==(ne=o.saved.theme)&&(z.value=(z.__value=ne)??``,E(z,ne)),G!==(G=o.saved.range)&&(ie.value=(ie.__value=G)??``,E(ie,G)),J!==(J=o.saved.metric)&&(K.value=(K.__value=J)??``,E(K,J)),g(fe,o.dbPath),X!==(X=e)&&(me.value=(me.__value=X)??``,E(me,X)),N(ve,o.saved.claudeWindows),g(Ce,`Last scan ${t??``}`),g(Ee,`Dollars per million tokens. ${n??``} models are priced out of the box; anything
|
|
2
|
-
you add here wins, and an unknown model is reported rather than counted as free.`)},[()=>String(o.saved.scanIntervalSec),()=>Se(o.scannedAt),()=>Object.keys(Gt).length]),f(`close`,k,()=>s(!1)),u(`pointerdown`,k,e=>{e.target===l&&s(!1)}),u(`click`,ee,()=>s(!1)),u(`change`,z,e=>o.onsave({theme:e.currentTarget.value})),u(`change`,ie,e=>o.onsave({range:e.currentTarget.value})),u(`change`,K,e=>o.onsave({metric:e.currentTarget.value})),u(`change`,me,e=>o.onsave({scanIntervalSec:Number(e.currentTarget.value)})),u(`change`,ve,e=>o.onsave({claudeWindows:e.currentTarget.checked})),u(`click`,be,function(...e){o.onrescan?.apply(this,e)}),j(Ae,()=>i(d),e=>x(d,e)),j(je,()=>i(m),e=>x(m,e)),j(Me,()=>i(h),e=>x(h,e)),u(`click`,Ne,C),r(t,k),p()}l([`pointerdown`,`click`,`change`]);var en=t(`<rect width="4" height="4" rx="1.2" fill="var(--accent-text)"></rect>`),tn=t(`<svg class="logo svelte-nck4wt" viewBox="0 0 32 32" role="img" aria-label="AI usage dashboard"><rect width="32" height="32" rx="8" fill="var(--accent)"></rect><!></svg>`);function nn(t,a){e(a,!0);let o=H(a,`size`,3,28),s=[0,1,2,3].flatMap(e=>[0,1,2,3].map(t=>({row:e,column:t,heat:(t+(3-e))/6})));var c=tn(),l=R(y(c));W(l,17,()=>s,e=>`${e.row}-${e.column}`,(e,t)=>{var a=en();n(e=>{T(a,`x`,5+i(t).column*6),T(a,`y`,5+i(t).row*6),T(a,`opacity`,e)},[()=>(.22+i(t).heat*.78).toFixed(2)]),r(e,a)}),U(c),n(()=>{T(c,`width`,o()),T(c,`height`,o())}),r(t,c),p()}var rn=M(`<button type="button" class="reset svelte-1uha8ag">Clear filters</button>`),an=M(`<div class="meters svelte-1uha8ag"></div>`),on=M(`<p class="empty svelte-1uha8ag">No plan windows yet. Sign in with Claude Code or run Codex once and they turn up here.</p>`),sn=M(`<li class="svelte-1uha8ag"><!> <span class="svelte-1uha8ag"> </span> <b class="num svelte-1uha8ag"> </b></li>`),cn=M(`<div class="share svelte-1uha8ag"><!> <ul class="key svelte-1uha8ag"></ul></div>`),ln=M(`<!> <p class="aside svelte-1uha8ag"> </p>`,1),un=M(`<header class="bar svelte-1uha8ag"><a class="brand svelte-1uha8ag" href="/"><!> <span>AI usage</span></a> <div class="filters svelte-1uha8ag"><!> <!> <!> <!> <!> <!></div> <div class="tools svelte-1uha8ag"><button type="button" aria-label="Rescan now"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" class="svelte-1uha8ag"><path d="M13.4 7A5.5 5.5 0 1 0 12.6 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path><path d="M13.8 3.4v3.8h-3.8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon svelte-1uha8ag" aria-label="Settings"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="2.3" fill="none" stroke="currentColor" stroke-width="1.5"></circle><path d="M8 1.6v1.8M8 12.6v1.8M14.4 8h-1.8M3.4 8H1.6M12.5 3.5l-1.3 1.3M4.8 11.2l-1.3 1.3M12.5 12.5l-1.3-1.3M4.8 4.8 3.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path></svg></button></div></header> <main class="svelte-1uha8ag"><!> <div class="grid svelte-1uha8ag"><!> <!> <!> <!> <!> <!> <!> <!> <!></div> <footer class="svelte-1uha8ag"><span>Reads the transcripts already on this machine. Nothing is sent anywhere.</span> <span><!> </span></footer></main> <!> <!>`,1);function dn(t,l){e(l,!0);let f=m(()=>l.data),h=b(s(f.usage)),_=b(s(f.settings)),C=b(!1),T=b(!1),E=b(s(f.usage.filters.range)),O=b(s(f.usage.filters.tools)),k=b(s(f.usage.filters.models)),j=b(s(f.usage.filters.projects)),M=b(s(f.settings.metric)),N=b(`tool`),F=b(`share`),I=b(`measure`),z=b(s(f.settings.hiddenColumns)),B=S(()=>new URLSearchParams({range:i(E),tools:i(O).join(`,`),models:i(k).join(`,`),projects:i(j).join(`,`)}).toString()),V=m(()=>i(B));async function H(e){x(C,!0);try{let t=await fetch(`/api/usage?${e}`);t.ok&&x(h,await t.json(),!0)}finally{x(C,!1)}}v(()=>{i(B)!==V&&(V=i(B),ie(`?${i(B)}`,{shallow:!0,replace:!0}),H(i(B)))}),v(()=>{let e=setInterval(()=>void H(V),3e4);return()=>clearInterval(e)}),v(()=>{let e=i(_).theme;document.documentElement.dataset.theme=e===`auto`?``:e});let te=(e,t={})=>fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)});async function ne(e){let t=await te(`/api/settings`,e);t.ok&&x(_,await t.json(),!0)}async function G(){x(C,!0);try{let e=await te(`/api/refresh?${V}`);e.ok&&x(h,await e.json(),!0)}finally{x(C,!1)}}let ae=(e,t)=>e.includes(t)?e.filter(e=>e!==t):[...e,t],q=e=>i(M)===`cost`?e.cost??0:e.total,oe=e=>i(M)===`cost`?Z(e):Y(e),se=S(()=>new Set(i(h).series.filter(e=>e.total>0).map(e=>e.day)).size),ce=S(()=>i(h).byTool.map(e=>({id:e.key,label:St(e.key).label,colour:St(e.key).colour}))),ue=S(()=>i(h).byModel.map(e=>({id:e.key,label:De(e.key),colour:bt(yt(e.key)).colour}))),de=S(()=>i(N)===`tool`?i(ce):i(ue)),fe=S(()=>i(h).byModel.map(e=>{let t=bt(yt(e.key));return{id:e.key,label:De(e.key),detail:t.label,value:q(e),display:oe(q(e)),colour:t.colour,mark:t.id,hint:`${e.key} - ${X(e.total)} tokens over ${X(e.events)} requests, ${Z(e.cost)} estimated`}})),pe=S(()=>i(h).byProject.map(e=>({id:e.key,label:Ee(e.key),detail:``,value:i(I)===`sessions`?e.sessions:q(e),display:i(I)===`sessions`?X(e.sessions):oe(q(e)),colour:`var(--accent)`,hint:`${e.key||`unknown`} - ${X(e.total)} tokens, ${X(e.sessions)} sessions`}))),me=S(()=>i(h).sources.map(e=>{let t=i(h).byTool.find(t=>t.key===e.id),n=St(e.id);return{id:e.id,label:n.label,detail:t?`${X(t.sessions)} sessions`:`not found`,value:t?q(t):0,display:t?oe(q(t)):`--`,colour:n.colour,mark:e.id,hint:e.present?`${X(e.files)} files under ${e.root}`:`Nothing at ${e.root}`}})),he=S(()=>[{id:`input`,label:`Input`,value:i(h).totals.tokens.input,display:Y(i(h).totals.tokens.input),colour:`var(--ramp-4)`,hint:`Fresh prompt tokens, billed at full rate`},{id:`output`,label:`Output`,value:i(h).totals.tokens.output,display:Y(i(h).totals.tokens.output),colour:`var(--ramp-2)`,hint:`Everything the model wrote back, ${Y(i(h).totals.reasoning)} of it reasoning`},{id:`cache_read`,label:`Cache read`,value:i(h).totals.tokens.cache_read,display:Y(i(h).totals.tokens.cache_read),colour:`var(--ramp-1)`,hint:`Context served from cache, usually a tenth of the input price`},{id:`cache_write`,label:`Cache write`,value:i(h).totals.tokens.cache_write,display:Y(i(h).totals.tokens.cache_write),colour:`var(--ramp-3)`,hint:`Putting context into the cache, a premium on the input price`}]),_e=S(()=>i(h).totals.total?i(h).totals.tokens.cache_read/i(h).totals.total*100:0);var ve=un();A(`1uha8ag`,e=>{re(()=>{o.title=`AI usage dashboard`})});var ye=a(ve),be=y(ye);nn(y(be),{}),D(2),U(be);var xe=R(be,2),Ce=y(xe);{let e=S(()=>Ut.map(e=>({id:e.id,label:e.label})));le(Ce,{get options(){return i(e)},label:`Date range`,size:`sm`,get value(){return i(E)},set value(e){x(E,e,!0)}})}var we=R(Ce,2);le(we,{options:[{id:`tokens`,label:`Tokens`},{id:`cost`,label:`Est. cost`,hint:`At published API rates. Your subscription is billed separately.`}],label:`Measure`,size:`sm`,get value(){return i(M)},set value(e){x(M,e,!0)}});var Te=R(we,2);ge(Te,{label:`Tools`,get options(){return i(h).options.tools},format:e=>St(e).label,get selected(){return i(O)},set selected(e){x(O,e,!0)}});var Oe=R(Te,2);ge(Oe,{label:`Models`,get options(){return i(h).options.models},get format(){return De},get selected(){return i(k)},set selected(e){x(k,e,!0)}});var ke=R(Oe,2);ge(ke,{label:`Projects`,get options(){return i(h).options.projects},get format(){return Ee},get selected(){return i(j)},set selected(e){x(j,e,!0)}});var Ae=R(ke,2),je=e=>{var t=rn();u(`click`,t,()=>{x(O,[],!0),x(k,[],!0),x(j,[],!0)}),r(e,t)};w(Ae,e=>{(i(O).length||i(k).length||i(j).length)&&e(je)}),U(xe);var Ne=R(xe,2),Pe=y(Ne);let Fe;P(Pe,(e,t)=>K?.(e,t),()=>`Last scan ${Se(i(h).scannedAt)}`);var Ie=R(Pe,2);P(Ie,(e,t)=>K?.(e,t),()=>`Settings`),U(Ne),U(ye);var Le=R(ye,2),ze=y(Le);{let e=S(()=>Wt(i(h).filters.range));Me(ze,{get totals(){return i(h).totals},get previous(){return i(h).previous},get activeDays(){return i(se)},get rangeLabel(){return i(e)}})}var Be=R(ze,2),Ve=y(Be);J(Ve,{title:`Every day so far`,span:8,hint:`One square per day, whatever range is picked above. Outlined days are before your records start.`,children:(e,t)=>{Re(e,{get days(){return i(h).calendar},get metric(){return i(M)},get oldest(){return i(h).oldest}})},$$slots:{default:!0}});var He=R(Ve,2);J(He,{title:`Plan windows`,span:4,hint:`Straight from each account, not worked out from tokens`,children:(e,t)=>{var n=d(),o=a(n),s=e=>{var t=an();W(t,21,()=>i(h).windows,e=>e.id,(e,t)=>{gt(e,{get window(){return i(t)}})}),U(t),r(e,t)},c=e=>{var t=on();r(e,t)};w(o,e=>{i(h).windows.length?e(s):e(c,-1)}),r(e,n)},$$slots:{default:!0}});var We=R(He,2);J(We,{title:`Day by day`,span:12,hint:`Stacked over the range you picked`,actions:e=>{le(e,{options:[{id:`tool`,label:`By tool`},{id:`model`,label:`By model`}],label:`Trend grouping`,size:`sm`,get value(){return i(N)},set value(e){x(N,e,!0)}})},children:(e,t)=>{{let t=S(()=>i(N)===`tool`?i(h).series:i(h).seriesByModel);Ue(e,{get series(){return i(t)},get keys(){return i(de)},get metric(){return i(M)}})}},$$slots:{actions:!0,default:!0}});var Ge=R(We,2);J(Ge,{title:`Models`,span:5,hint:`Click one to filter the whole page by it`,actions:e=>{le(e,{options:[{id:`share`,label:`Share`},{id:`list`,label:`Ranked`}],label:`Model view`,size:`sm`,get value(){return i(F)},set value(e){x(F,e,!0)}})},children:(e,t)=>{var o=d(),s=a(o),l=e=>{var t=cn(),a=y(t);{let e=S(()=>i(fe).map(e=>({id:e.id,label:e.label,value:e.value,colour:e.colour,display:e.display}))),t=S(()=>oe(q(i(h).totals))),n=S(()=>i(M)===`cost`?`estimated`:`tokens`);at(a,{get slices(){return i(e)},get centre(){return i(t)},get caption(){return i(n)}})}var o=R(a,2);W(o,21,()=>i(fe),e=>e.id,(e,t)=>{var a=sn(),o=y(a);Ye(o,{get id(){return i(t).mark},get label(){return i(t).detail},get colour(){return i(t).colour},size:14});var s=R(o,2),l=c(s,!0),u=R(s,2),d=c(u,!0);U(a),n(()=>{g(l,i(t).label),g(d,i(t).display)}),r(e,a)}),U(o),U(t),r(e,t)},u=e=>{nt(e,{get rows(){return i(fe)},get active(){return i(k)},onpick:e=>x(k,ae(i(k),e),!0)})};w(s,e=>{i(F)===`share`?e(l):e(u,-1)}),r(e,o)},$$slots:{actions:!0,default:!0}});var Ke=R(Ge,2);J(Ke,{title:`Projects`,span:7,hint:`Where the work happened. Click one to filter.`,actions:e=>{{let t=S(()=>[{id:`measure`,label:i(M)===`cost`?`Est. cost`:`Tokens`},{id:`sessions`,label:`Sessions`}]);le(e,{get options(){return i(t)},label:`Project measure`,size:`sm`,get value(){return i(I)},set value(e){x(I,e,!0)}})}},children:(e,t)=>{{let t=S(()=>i(pe).slice(0,8));nt(e,{get rows(){return i(t)},get active(){return i(j)},onpick:e=>x(j,ae(i(j),e),!0)})}},$$slots:{actions:!0,default:!0}});var qe=R(Ke,2);J(qe,{title:`Where the tokens go`,span:4,hint:`Cache reads are cheap, cache writes are not. This is the split that decides the bill.`,children:(e,t)=>{var o=ln(),s=a(o);lt(s,{get parts(){return i(he)}});var l=R(s,2),u=c(l);n(e=>g(u,`${e??``}% of everything counted was served from cache.`),[()=>i(_e).toFixed(0)]),r(e,o)},$$slots:{default:!0}});var Je=R(qe,2);J(Je,{title:`When you work`,span:5,hint:`Local time, over the range above`,children:(e,t)=>{mt(e,{get points(){return i(h).clock}})},$$slots:{default:!0}});var Xe=R(Je,2);J(Xe,{title:`Tools`,span:3,hint:`Click one to filter the whole page by it`,children:(e,t)=>{nt(e,{get rows(){return i(me)},get active(){return i(O)},onpick:e=>x(O,ae(i(O),e),!0)})},$$slots:{default:!0}}),J(R(Xe,2),{title:`Recent sessions`,span:12,hint:`Click a column heading to sort by it`,actions:e=>{Lt(e,{get options(){return wt},onchange:e=>ne({hiddenColumns:e}),get hidden(){return i(z)},set hidden(e){x(z,e,!0)}})},children:(e,t)=>{Nt(e,{get rows(){return i(h).sessions},get hidden(){return i(z)},onpick:e=>x(j,ae(i(j),e),!0)})},$$slots:{actions:!0,default:!0}}),U(Be);var Ze=R(Be,2),Qe=R(y(Ze),2),$e=y(Qe),et=e=>{var t=ee();n(e=>g(t,`Records from ${e??``} ·`),[()=>new Date(i(h).oldest).toLocaleDateString(`en-GB`)]),r(e,t)};w($e,e=>{i(h).oldest&&e(et)});var tt=R($e);U(Qe),U(Ze),U(Le);var rt=R(Le,2);Ht(rt,{get problems(){return i(h).problems}}),$t(R(rt,2),{get saved(){return i(_)},get sources(){return i(h).sources},get dbPath(){return l.data.paths.db},get scannedAt(){return i(h).scannedAt},onsave:ne,onrescan:G,get open(){return i(T)},set open(e){x(T,e,!0)}}),n(e=>{Fe=L(Pe,1,`icon svelte-1uha8ag`,null,Fe,{busy:i(C)}),g(tt,` Scanned ${e??``}`)},[()=>Se(i(h).scannedAt)]),u(`click`,Pe,G),u(`click`,Ie,()=>x(T,!0)),r(t,ve),p()}l([`click`]);export{dn as component};
|
|
Binary file
|
|
Binary file
|