fLausch commited on
Commit
2753306
·
verified ·
1 Parent(s): 1cbed66

Upload 12 files

Browse files
Files changed (12) hide show
  1. .env.local +1 -0
  2. .gitignore +21 -20
  3. App.tsx +472 -0
  4. README.md +13 -75
  5. index.html +66 -0
  6. index.tsx +15 -0
  7. metadata.json +5 -0
  8. package-lock.json +2178 -0
  9. package.json +16 -32
  10. tsconfig.json +29 -0
  11. types.ts +51 -0
  12. vite.config.ts +23 -0
.env.local ADDED
@@ -0,0 +1 @@
 
 
1
+ GEMINI_API_KEY=PLACEHOLDER_API_KEY
.gitignore CHANGED
@@ -1,23 +1,24 @@
1
- # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
-
3
- # dependencies
4
- /node_modules
5
- /.pnp
6
- .pnp.js
7
-
8
- # testing
9
- /coverage
10
-
11
- # production
12
- /build
13
-
14
- # misc
15
- .DS_Store
16
- .env.local
17
- .env.development.local
18
- .env.test.local
19
- .env.production.local
20
-
21
  npm-debug.log*
22
  yarn-debug.log*
23
  yarn-error.log*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  npm-debug.log*
5
  yarn-debug.log*
6
  yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
App.tsx ADDED
@@ -0,0 +1,472 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useMemo, useRef } from 'react';
2
+ import { fetchModels, filterFreeModels, testModelPerformance } from './services/openRouterService';
3
+ import { OpenRouterModel, ModelTestResult, SortOption } from './types';
4
+ import { ModelCard } from './components/ModelCard';
5
+ import { PerformanceChart } from './components/PerformanceChart';
6
+ import { RankingTable } from './components/RankingTable';
7
+ import { Play, RotateCcw, Search, ShieldCheck, CheckCircle, ExternalLink, HelpCircle, X, Key, Pause, Square, Download } from 'lucide-react';
8
+
9
+ // Required for export
10
+ declare global {
11
+ interface Window {
12
+ html2canvas: any;
13
+ }
14
+ }
15
+
16
+ const HelpModal = ({ onClose }: { onClose: () => void }) => (
17
+ <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm animate-fade-in">
18
+ <div className="bg-surface border border-gray-700 rounded-2xl w-full max-w-lg shadow-2xl overflow-hidden relative">
19
+ <button
20
+ onClick={onClose}
21
+ className="absolute top-4 right-4 text-gray-400 hover:text-white transition-colors"
22
+ >
23
+ <X size={20} />
24
+ </button>
25
+
26
+ <div className="p-6">
27
+ <div className="flex items-center gap-3 mb-6">
28
+ <div className="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center text-primary">
29
+ <Key size={20} />
30
+ </div>
31
+ <h2 className="text-xl font-bold text-white">OpenRouter API Key erstellen</h2>
32
+ </div>
33
+
34
+ <div className="space-y-6">
35
+ <div className="flex gap-4">
36
+ <div className="flex-shrink-0 w-8 h-8 rounded-full bg-gray-800 border border-gray-700 flex items-center justify-center font-bold text-sm text-gray-300">1</div>
37
+ <div>
38
+ <h3 className="font-semibold text-white mb-1">Account erstellen</h3>
39
+ <p className="text-sm text-gray-400 leading-relaxed">
40
+ Gehe auf <a href="https://openrouter.ai" target="_blank" rel="noreferrer" className="text-primary hover:underline">openrouter.ai</a>.
41
+ </p>
42
+ </div>
43
+ </div>
44
+
45
+ <div className="flex gap-4">
46
+ <div className="flex-shrink-0 w-8 h-8 rounded-full bg-gray-800 border border-gray-700 flex items-center justify-center font-bold text-sm text-gray-300">2</div>
47
+ <div>
48
+ <h3 className="font-semibold text-white mb-1">Key generieren</h3>
49
+ <p className="text-sm text-gray-400 leading-relaxed">
50
+ Klicke auf "Create Key". Das Limit kann 0 sein (für Free Models).
51
+ </p>
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <div className="mt-8 pt-6 border-t border-gray-800 flex flex-col gap-3">
57
+ <a
58
+ href="https://openrouter.ai/settings/keys"
59
+ target="_blank"
60
+ rel="noreferrer"
61
+ className="w-full py-2.5 bg-primary hover:bg-indigo-500 text-white rounded-lg font-medium text-sm flex items-center justify-center gap-2 transition-colors"
62
+ >
63
+ Jetzt Key erstellen <ExternalLink size={14} />
64
+ </a>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ );
70
+
71
+ const App = () => {
72
+ const [apiKey, setApiKey] = useState('');
73
+ const [allModels, setAllModels] = useState<OpenRouterModel[]>([]);
74
+ const [loadingModels, setLoadingModels] = useState(false);
75
+ const [testResults, setTestResults] = useState<Record<string, ModelTestResult>>({});
76
+
77
+ // Test control states
78
+ const [isTesting, setIsTesting] = useState(false);
79
+ const [isPaused, setIsPaused] = useState(false);
80
+ const [progress, setProgress] = useState(0);
81
+
82
+ // Refs for loop control (vital for async loops)
83
+ const pausedRef = useRef(false);
84
+ const stopRef = useRef(false);
85
+
86
+ const [sortBy, setSortBy] = useState<SortOption>('name');
87
+ const [filterText, setFilterText] = useState('');
88
+ const [showOnlyWorking, setShowOnlyWorking] = useState(false);
89
+ const [showHelp, setShowHelp] = useState(false);
90
+
91
+ const resultsRef = useRef<HTMLDivElement>(null);
92
+
93
+ // Load API Key from LocalStorage
94
+ useEffect(() => {
95
+ const savedKey = localStorage.getItem('openrouter_api_key');
96
+ if (savedKey) setApiKey(savedKey);
97
+ }, []);
98
+
99
+ // Save API Key on change
100
+ useEffect(() => {
101
+ if (apiKey) localStorage.setItem('openrouter_api_key', apiKey);
102
+ }, [apiKey]);
103
+
104
+ // Sync refs with state
105
+ useEffect(() => {
106
+ pausedRef.current = isPaused;
107
+ }, [isPaused]);
108
+
109
+ // Load models on mount
110
+ useEffect(() => {
111
+ const load = async () => {
112
+ setLoadingModels(true);
113
+ try {
114
+ const models = await fetchModels();
115
+ setAllModels(models);
116
+ } catch (e) {
117
+ console.error(e);
118
+ } finally {
119
+ setLoadingModels(false);
120
+ }
121
+ };
122
+ load();
123
+ }, []);
124
+
125
+ const freeModels = useMemo(() => filterFreeModels(allModels), [allModels]);
126
+
127
+ const runTests = async () => {
128
+ if (!apiKey) {
129
+ setShowHelp(true);
130
+ return;
131
+ }
132
+
133
+ setIsTesting(true);
134
+ setIsPaused(false);
135
+ stopRef.current = false;
136
+ pausedRef.current = false;
137
+
138
+ // Only clear if we are starting fresh (optional logic, here we restart fresh)
139
+ setTestResults({});
140
+ setProgress(0);
141
+
142
+ const queue = [...freeModels];
143
+ const total = queue.length;
144
+ let completed = 0;
145
+
146
+ for (const model of queue) {
147
+ // Check Stop
148
+ if (stopRef.current) break;
149
+
150
+ // Check Pause (Loop until unpaused)
151
+ while (pausedRef.current) {
152
+ if (stopRef.current) break;
153
+ await new Promise(r => setTimeout(r, 500));
154
+ }
155
+ if (stopRef.current) break;
156
+
157
+ setTestResults(prev => ({
158
+ ...prev,
159
+ [model.id]: {
160
+ modelId: model.id,
161
+ status: 'running',
162
+ latencyMs: 0,
163
+ tokensPerSecond: 0,
164
+ latencyMs2: 0,
165
+ tokensPerSecond2: 0,
166
+ timestamp: Date.now()
167
+ }
168
+ }));
169
+
170
+ const result = await testModelPerformance(model.id, apiKey);
171
+
172
+ if (stopRef.current) break; // Check again after await
173
+
174
+ setTestResults(prev => ({
175
+ ...prev,
176
+ [model.id]: result
177
+ }));
178
+
179
+ completed++;
180
+ setProgress((completed / total) * 100);
181
+
182
+ await new Promise(r => setTimeout(r, 200));
183
+ }
184
+
185
+ setIsTesting(false);
186
+ setIsPaused(false);
187
+ };
188
+
189
+ const handleStop = () => {
190
+ stopRef.current = true;
191
+ setIsTesting(false);
192
+ setIsPaused(false);
193
+ };
194
+
195
+ const handlePauseToggle = () => {
196
+ setIsPaused(!isPaused);
197
+ };
198
+
199
+ const handleExport = async () => {
200
+ if (!resultsRef.current || !window.html2canvas) return;
201
+
202
+ try {
203
+ const canvas = await window.html2canvas(resultsRef.current, {
204
+ backgroundColor: '#09090b',
205
+ scale: 2 // High resolution
206
+ });
207
+
208
+ const link = document.createElement('a');
209
+ link.download = `OpenRouter_Benchmark_${new Date().toISOString().slice(0,19).replace(/:/g,'-')}.png`;
210
+ link.href = canvas.toDataURL('image/png');
211
+ link.click();
212
+ } catch (err) {
213
+ console.error("Export failed", err);
214
+ alert("Fehler beim Exportieren.");
215
+ }
216
+ };
217
+
218
+ // Filter Logic
219
+ const displayedModels = useMemo(() => {
220
+ let list = [...freeModels];
221
+
222
+ if (filterText) {
223
+ const lower = filterText.toLowerCase();
224
+ list = list.filter(m =>
225
+ m.name.toLowerCase().includes(lower) ||
226
+ m.id.toLowerCase().includes(lower)
227
+ );
228
+ }
229
+
230
+ if (showOnlyWorking) {
231
+ list = list.filter(m => testResults[m.id]?.status === 'success');
232
+ }
233
+
234
+ list.sort((a, b) => {
235
+ const resA = testResults[a.id];
236
+ const resB = testResults[b.id];
237
+
238
+ switch (sortBy) {
239
+ case 'name': return a.name.localeCompare(b.name);
240
+ case 'context': return b.context_length - a.context_length;
241
+ case 'newest': return (b.created || 0) - (a.created || 0);
242
+ case 'latency':
243
+ if (!resA || resA.status !== 'success') return 1;
244
+ if (!resB || resB.status !== 'success') return -1;
245
+ return resA.latencyMs - resB.latencyMs;
246
+ case 'throughput':
247
+ if (!resA || resA.status !== 'success') return 1;
248
+ if (!resB || resB.status !== 'success') return -1;
249
+ return resB.tokensPerSecond - resA.tokensPerSecond;
250
+ default: return 0;
251
+ }
252
+ });
253
+
254
+ return list;
255
+ }, [freeModels, filterText, sortBy, testResults, showOnlyWorking]);
256
+
257
+ const workingCount = (Object.values(testResults) as ModelTestResult[]).filter(r => r.status === 'success').length;
258
+ const testedCount = Object.keys(testResults).length;
259
+
260
+ return (
261
+ <div className="min-h-screen pb-20 font-sans text-gray-200">
262
+ {showHelp && <HelpModal onClose={() => setShowHelp(false)} />}
263
+
264
+ {/* Header */}
265
+ <header className="sticky top-0 z-30 bg-background/95 backdrop-blur-md border-b border-gray-800 shadow-lg shadow-black/20">
266
+ <div className="max-w-7xl mx-auto px-4 py-4">
267
+ <div className="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
268
+ <div className="flex items-center gap-3">
269
+ <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shadow-lg shadow-primary/20">
270
+ <ShieldCheck className="text-white" size={24} />
271
+ </div>
272
+ <div>
273
+ <h1 className="text-xl font-bold text-white tracking-tight">OpenRouter FreeScout</h1>
274
+ <p className="text-xs text-gray-500">Benchmark für kostenlose LLMs</p>
275
+ </div>
276
+ </div>
277
+
278
+ <div className="flex flex-col sm:flex-row gap-2 w-full lg:w-auto items-stretch sm:items-center">
279
+ <div className="flex-1 sm:flex-none flex gap-2">
280
+ <div className="relative group flex-1 sm:w-64">
281
+ <input
282
+ type="password"
283
+ placeholder="API Key (wird gespeichert)"
284
+ value={apiKey}
285
+ onChange={(e) => setApiKey(e.target.value)}
286
+ className="w-full bg-surface border border-gray-700 rounded-lg py-2 pl-3 pr-9 text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all placeholder:text-gray-600 h-10"
287
+ />
288
+ <div className="absolute right-0 top-0 h-full flex items-center pr-2">
289
+ <button
290
+ onClick={() => setShowHelp(true)}
291
+ className="text-gray-500 hover:text-primary transition-colors p-1"
292
+ >
293
+ <HelpCircle size={18} />
294
+ </button>
295
+ </div>
296
+ </div>
297
+ <a
298
+ href="https://openrouter.ai/settings/keys"
299
+ target="_blank"
300
+ rel="noreferrer"
301
+ className="flex items-center justify-center w-10 h-10 bg-gray-800 hover:bg-gray-700 text-gray-400 hover:text-white rounded-lg border border-gray-700 transition-all"
302
+ title="Neuen Key erstellen"
303
+ >
304
+ <Key size={16} />
305
+ </a>
306
+ </div>
307
+
308
+ {/* Controls */}
309
+ <div className="flex gap-2">
310
+ {!isTesting ? (
311
+ <button
312
+ onClick={runTests}
313
+ disabled={loadingModels || !apiKey}
314
+ className={`flex items-center justify-center gap-2 px-6 h-10 rounded-lg text-sm font-semibold transition-all shadow-lg
315
+ ${!apiKey
316
+ ? 'bg-gray-800 text-gray-500 cursor-not-allowed'
317
+ : 'bg-primary hover:bg-indigo-500 text-white shadow-primary/25 hover:shadow-primary/40'
318
+ }`}
319
+ >
320
+ <Play size={16} fill="currentColor" /> Start
321
+ </button>
322
+ ) : (
323
+ <>
324
+ <button
325
+ onClick={handlePauseToggle}
326
+ className={`flex items-center justify-center w-10 h-10 rounded-lg border transition-colors
327
+ ${isPaused
328
+ ? 'bg-yellow-500/20 border-yellow-500 text-yellow-500 animate-pulse'
329
+ : 'bg-gray-800 border-gray-700 text-yellow-500 hover:bg-gray-700'
330
+ }`}
331
+ title={isPaused ? "Fortsetzen" : "Pause"}
332
+ >
333
+ {isPaused ? <Play size={16} /> : <Pause size={16} />}
334
+ </button>
335
+ <button
336
+ onClick={handleStop}
337
+ className="flex items-center justify-center w-10 h-10 rounded-lg bg-red-950/30 border border-red-900 text-red-500 hover:bg-red-900/50 transition-colors"
338
+ title="Abbrechen"
339
+ >
340
+ <Square size={16} fill="currentColor" />
341
+ </button>
342
+ </>
343
+ )}
344
+ </div>
345
+ </div>
346
+ </div>
347
+
348
+ {isTesting && (
349
+ <div className="absolute bottom-0 left-0 w-full h-1 bg-gray-800">
350
+ <div
351
+ className={`h-full bg-gradient-to-r from-primary to-purple-500 transition-all duration-300 ease-out ${isPaused ? 'opacity-50' : ''}`}
352
+ style={{ width: `${progress}%` }}
353
+ ></div>
354
+ </div>
355
+ )}
356
+ </div>
357
+ </header>
358
+
359
+ <main className="max-w-7xl mx-auto px-4 py-8 space-y-8">
360
+
361
+ {/* Stats */}
362
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
363
+ <div className="p-4 rounded-xl bg-surface border border-gray-800">
364
+ <h3 className="text-gray-500 text-xs uppercase font-bold tracking-wider mb-1">Gefundene Modelle</h3>
365
+ <div className="text-2xl font-bold text-white flex items-baseline gap-2">
366
+ {loadingModels ? '...' : freeModels.length}
367
+ <span className="text-xs font-normal text-emerald-500 bg-emerald-950/30 px-2 py-0.5 rounded-full border border-emerald-900">100% Free</span>
368
+ </div>
369
+ </div>
370
+ <div className="p-4 rounded-xl bg-surface border border-gray-800">
371
+ <h3 className="text-gray-500 text-xs uppercase font-bold tracking-wider mb-1">Getestet</h3>
372
+ <div className="text-2xl font-bold text-white">
373
+ {testedCount} <span className="text-sm text-gray-500">/ {freeModels.length}</span>
374
+ </div>
375
+ </div>
376
+ <div className="p-4 rounded-xl bg-surface border border-gray-800">
377
+ <h3 className="text-gray-500 text-xs uppercase font-bold tracking-wider mb-1">Funktioniert</h3>
378
+ <div className={`text-2xl font-bold ${workingCount > 0 ? 'text-emerald-400' : 'text-gray-600'}`}>
379
+ {workingCount}
380
+ </div>
381
+ </div>
382
+ <div className="p-4 rounded-xl bg-surface border border-gray-800 flex flex-col justify-center">
383
+ <p className="text-xs text-gray-400">
384
+ Status: {isTesting ? (isPaused ? <span className="text-yellow-500 font-bold">Pausiert</span> : <span className="text-blue-400 font-bold">Test läuft...</span>) : "Bereit"}
385
+ </p>
386
+ </div>
387
+ </div>
388
+
389
+ {/* Results Section (Printable) */}
390
+ {workingCount > 0 && (
391
+ <div className="animate-fade-in relative">
392
+ <div className="flex justify-end mb-2">
393
+ <button
394
+ onClick={handleExport}
395
+ className="flex items-center gap-2 text-xs font-medium text-gray-400 hover:text-white bg-gray-800 hover:bg-gray-700 px-3 py-1.5 rounded-lg border border-gray-700 transition-colors"
396
+ >
397
+ <Download size={14} /> Report Exportieren (Bild)
398
+ </button>
399
+ </div>
400
+
401
+ <div ref={resultsRef} className="space-y-6 p-4 -m-4 bg-[#09090b]"> {/* Wrapper for screenshot */}
402
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
403
+ <PerformanceChart results={Object.values(testResults)} models={allModels} metric="latency" />
404
+ <PerformanceChart results={Object.values(testResults)} models={allModels} metric="throughput" />
405
+ </div>
406
+ <RankingTable results={testResults} models={allModels} />
407
+
408
+ <div className="text-center text-xs text-gray-600 pt-4 pb-2">
409
+ Generiert mit OpenRouter FreeScout am {new Date().toLocaleString()}
410
+ </div>
411
+ </div>
412
+ </div>
413
+ )}
414
+
415
+ <div className="border-t border-gray-800 my-8"></div>
416
+
417
+ {/* Model Browser */}
418
+ <div className="space-y-4">
419
+ <div className="flex flex-col md:flex-row justify-between items-center gap-4 bg-surface p-4 rounded-xl border border-gray-800 sticky top-20 z-20 shadow-xl">
420
+ <div className="relative w-full md:w-auto md:flex-1 max-w-md">
421
+ <Search className="absolute left-3 top-2.5 text-gray-500" size={16} />
422
+ <input
423
+ type="text"
424
+ placeholder="Modelle durchsuchen..."
425
+ className="w-full bg-black/40 border border-gray-700 rounded-lg pl-9 pr-4 py-2 text-sm focus:outline-none focus:border-primary text-white"
426
+ value={filterText}
427
+ onChange={(e) => setFilterText(e.target.value)}
428
+ />
429
+ </div>
430
+ <div className="flex items-center gap-2 w-full md:w-auto overflow-x-auto pb-2 md:pb-0">
431
+ <button
432
+ onClick={() => setShowOnlyWorking(!showOnlyWorking)}
433
+ className={`flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium border transition-colors whitespace-nowrap
434
+ ${showOnlyWorking
435
+ ? 'bg-emerald-950/30 border-emerald-800 text-emerald-400'
436
+ : 'bg-black/40 border-gray-700 text-gray-400 hover:text-white'}`}
437
+ >
438
+ <CheckCircle size={14} />
439
+ Nur funktionierende
440
+ </button>
441
+ <div className="h-6 w-px bg-gray-700 mx-1"></div>
442
+ <select
443
+ className="bg-black/40 border border-gray-700 text-gray-300 text-xs rounded-lg px-3 py-2 focus:outline-none focus:border-primary"
444
+ value={sortBy}
445
+ onChange={(e) => setSortBy(e.target.value as SortOption)}
446
+ >
447
+ <option value="name">Name (A-Z)</option>
448
+ <option value="latency">Latenz (Beste)</option>
449
+ <option value="throughput">Speed (Max)</option>
450
+ <option value="context">Kontextgröße</option>
451
+ </select>
452
+ </div>
453
+ </div>
454
+
455
+ <div className="grid grid-cols-1 gap-3">
456
+ {loadingModels ? (
457
+ <div className="text-center py-20 text-gray-500 animate-pulse">Lade Modelldaten...</div>
458
+ ) : displayedModels.length === 0 ? (
459
+ <div className="text-center py-20 text-gray-500 border border-dashed border-gray-800 rounded-xl">Keine Modelle gefunden.</div>
460
+ ) : (
461
+ displayedModels.map(model => (
462
+ <ModelCard key={model.id} model={model} result={testResults[model.id]} />
463
+ ))
464
+ )}
465
+ </div>
466
+ </div>
467
+ </main>
468
+ </div>
469
+ );
470
+ };
471
+
472
+ export default App;
README.md CHANGED
@@ -1,82 +1,20 @@
1
- ---
2
- title: Openrouter Freescout
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: red
6
- sdk: static
7
- pinned: false
8
- app_build_command: npm run build
9
- app_file: build/index.html
10
- short_description: test all free models from openrouter and create a ranking
11
- ---
12
 
13
- # Getting Started with Create React App
14
 
15
- This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
16
 
17
- ## Available Scripts
18
 
19
- In the project directory, you can run:
20
 
21
- ### `npm start`
22
 
23
- Runs the app in the development mode.\
24
- Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
25
 
26
- The page will reload when you make changes.\
27
- You may also see any lint errors in the console.
28
-
29
- ### `npm test`
30
-
31
- Launches the test runner in the interactive watch mode.\
32
- See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
33
-
34
- ### `npm run build`
35
-
36
- Builds the app for production to the `build` folder.\
37
- It correctly bundles React in production mode and optimizes the build for the best performance.
38
-
39
- The build is minified and the filenames include the hashes.\
40
- Your app is ready to be deployed!
41
-
42
- See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
43
-
44
- ### `npm run eject`
45
-
46
- **Note: this is a one-way operation. Once you `eject`, you can't go back!**
47
-
48
- If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
49
-
50
- Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
51
-
52
- You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
53
-
54
- ## Learn More
55
-
56
- You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
57
-
58
- To learn React, check out the [React documentation](https://reactjs.org/).
59
-
60
- ### Code Splitting
61
-
62
- This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
63
-
64
- ### Analyzing the Bundle Size
65
-
66
- This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
67
-
68
- ### Making a Progressive Web App
69
-
70
- This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
71
-
72
- ### Advanced Configuration
73
-
74
- This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
75
-
76
- ### Deployment
77
-
78
- This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
79
-
80
- ### `npm run build` fails to minify
81
-
82
- This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
 
1
+ <div align="center">
2
+ <img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
3
+ </div>
 
 
 
 
 
 
 
 
4
 
5
+ # Run and deploy your AI Studio app
6
 
7
+ This contains everything you need to run your app locally.
8
 
9
+ View your app in AI Studio: https://ai.studio/apps/drive/1xLStDU3BdoxhkkcFGqWzFtmCk5l2kjU1
10
 
11
+ ## Run Locally
12
 
13
+ **Prerequisites:** Node.js
14
 
 
 
15
 
16
+ 1. Install dependencies:
17
+ `npm install`
18
+ 2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
19
+ 3. Run the app:
20
+ `npm run dev`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="de" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>OpenRouter FreeScout</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
10
+ <script>
11
+ tailwind.config = {
12
+ darkMode: 'class',
13
+ theme: {
14
+ extend: {
15
+ fontFamily: {
16
+ sans: ['Inter', 'sans-serif'],
17
+ },
18
+ colors: {
19
+ background: '#09090b',
20
+ surface: '#18181b',
21
+ primary: '#6366f1',
22
+ secondary: '#10b981',
23
+ }
24
+ }
25
+ }
26
+ }
27
+ </script>
28
+ <style>
29
+ body {
30
+ background-color: #09090b;
31
+ color: #e4e4e7;
32
+ }
33
+ /* Custom Scrollbar */
34
+ ::-webkit-scrollbar {
35
+ width: 8px;
36
+ height: 8px;
37
+ }
38
+ ::-webkit-scrollbar-track {
39
+ background: #18181b;
40
+ }
41
+ ::-webkit-scrollbar-thumb {
42
+ background: #3f3f46;
43
+ border-radius: 4px;
44
+ }
45
+ ::-webkit-scrollbar-thumb:hover {
46
+ background: #52525b;
47
+ }
48
+ </style>
49
+ <script type="importmap">
50
+ {
51
+ "imports": {
52
+ "react/": "https://aistudiocdn.com/react@^19.2.1/",
53
+ "react": "https://aistudiocdn.com/react@^19.2.1",
54
+ "react-dom/": "https://aistudiocdn.com/react-dom@^19.2.1/",
55
+ "lucide-react": "https://aistudiocdn.com/lucide-react@^0.555.0",
56
+ "recharts": "https://aistudiocdn.com/recharts@^3.5.1"
57
+ }
58
+ }
59
+ </script>
60
+ <link rel="stylesheet" href="/index.css">
61
+ </head>
62
+ <body>
63
+ <div id="root"></div>
64
+ <script type="module" src="/index.tsx"></script>
65
+ </body>
66
+ </html>
index.tsx ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+
5
+ const rootElement = document.getElementById('root');
6
+ if (!rootElement) {
7
+ throw new Error("Could not find root element to mount to");
8
+ }
9
+
10
+ const root = ReactDOM.createRoot(rootElement);
11
+ root.render(
12
+ <React.StrictMode>
13
+ <App />
14
+ </React.StrictMode>
15
+ );
metadata.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "name": "OpenRouter FreeScout",
3
+ "description": "Ein Dashboard zum Testen und Vergleichen von kostenlosen OpenRouter-Modellen. Analysiert Latenz, Geschwindigkeit und Zuverlässigkeit.",
4
+ "requestFramePermissions": []
5
+ }
package-lock.json ADDED
@@ -0,0 +1,2178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "openrouter-freescout",
3
+ "version": "0.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "openrouter-freescout",
9
+ "version": "0.0.0",
10
+ "dependencies": {
11
+ "lucide-react": "^0.555.0",
12
+ "react": "^19.2.1",
13
+ "react-dom": "^19.2.1",
14
+ "recharts": "^3.5.1"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^22.14.0",
18
+ "@vitejs/plugin-react": "^5.0.0",
19
+ "typescript": "~5.8.2",
20
+ "vite": "^6.2.0"
21
+ }
22
+ },
23
+ "node_modules/@babel/code-frame": {
24
+ "version": "7.27.1",
25
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
26
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
27
+ "dev": true,
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@babel/helper-validator-identifier": "^7.27.1",
31
+ "js-tokens": "^4.0.0",
32
+ "picocolors": "^1.1.1"
33
+ },
34
+ "engines": {
35
+ "node": ">=6.9.0"
36
+ }
37
+ },
38
+ "node_modules/@babel/compat-data": {
39
+ "version": "7.28.5",
40
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
41
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
42
+ "dev": true,
43
+ "license": "MIT",
44
+ "engines": {
45
+ "node": ">=6.9.0"
46
+ }
47
+ },
48
+ "node_modules/@babel/core": {
49
+ "version": "7.28.5",
50
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
51
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
52
+ "dev": true,
53
+ "license": "MIT",
54
+ "dependencies": {
55
+ "@babel/code-frame": "^7.27.1",
56
+ "@babel/generator": "^7.28.5",
57
+ "@babel/helper-compilation-targets": "^7.27.2",
58
+ "@babel/helper-module-transforms": "^7.28.3",
59
+ "@babel/helpers": "^7.28.4",
60
+ "@babel/parser": "^7.28.5",
61
+ "@babel/template": "^7.27.2",
62
+ "@babel/traverse": "^7.28.5",
63
+ "@babel/types": "^7.28.5",
64
+ "@jridgewell/remapping": "^2.3.5",
65
+ "convert-source-map": "^2.0.0",
66
+ "debug": "^4.1.0",
67
+ "gensync": "^1.0.0-beta.2",
68
+ "json5": "^2.2.3",
69
+ "semver": "^6.3.1"
70
+ },
71
+ "engines": {
72
+ "node": ">=6.9.0"
73
+ },
74
+ "funding": {
75
+ "type": "opencollective",
76
+ "url": "https://opencollective.com/babel"
77
+ }
78
+ },
79
+ "node_modules/@babel/generator": {
80
+ "version": "7.28.5",
81
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
82
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
83
+ "dev": true,
84
+ "license": "MIT",
85
+ "dependencies": {
86
+ "@babel/parser": "^7.28.5",
87
+ "@babel/types": "^7.28.5",
88
+ "@jridgewell/gen-mapping": "^0.3.12",
89
+ "@jridgewell/trace-mapping": "^0.3.28",
90
+ "jsesc": "^3.0.2"
91
+ },
92
+ "engines": {
93
+ "node": ">=6.9.0"
94
+ }
95
+ },
96
+ "node_modules/@babel/helper-compilation-targets": {
97
+ "version": "7.27.2",
98
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
99
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
100
+ "dev": true,
101
+ "license": "MIT",
102
+ "dependencies": {
103
+ "@babel/compat-data": "^7.27.2",
104
+ "@babel/helper-validator-option": "^7.27.1",
105
+ "browserslist": "^4.24.0",
106
+ "lru-cache": "^5.1.1",
107
+ "semver": "^6.3.1"
108
+ },
109
+ "engines": {
110
+ "node": ">=6.9.0"
111
+ }
112
+ },
113
+ "node_modules/@babel/helper-globals": {
114
+ "version": "7.28.0",
115
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
116
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
117
+ "dev": true,
118
+ "license": "MIT",
119
+ "engines": {
120
+ "node": ">=6.9.0"
121
+ }
122
+ },
123
+ "node_modules/@babel/helper-module-imports": {
124
+ "version": "7.27.1",
125
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
126
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
127
+ "dev": true,
128
+ "license": "MIT",
129
+ "dependencies": {
130
+ "@babel/traverse": "^7.27.1",
131
+ "@babel/types": "^7.27.1"
132
+ },
133
+ "engines": {
134
+ "node": ">=6.9.0"
135
+ }
136
+ },
137
+ "node_modules/@babel/helper-module-transforms": {
138
+ "version": "7.28.3",
139
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
140
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
141
+ "dev": true,
142
+ "license": "MIT",
143
+ "dependencies": {
144
+ "@babel/helper-module-imports": "^7.27.1",
145
+ "@babel/helper-validator-identifier": "^7.27.1",
146
+ "@babel/traverse": "^7.28.3"
147
+ },
148
+ "engines": {
149
+ "node": ">=6.9.0"
150
+ },
151
+ "peerDependencies": {
152
+ "@babel/core": "^7.0.0"
153
+ }
154
+ },
155
+ "node_modules/@babel/helper-plugin-utils": {
156
+ "version": "7.27.1",
157
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
158
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
159
+ "dev": true,
160
+ "license": "MIT",
161
+ "engines": {
162
+ "node": ">=6.9.0"
163
+ }
164
+ },
165
+ "node_modules/@babel/helper-string-parser": {
166
+ "version": "7.27.1",
167
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
168
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
169
+ "dev": true,
170
+ "license": "MIT",
171
+ "engines": {
172
+ "node": ">=6.9.0"
173
+ }
174
+ },
175
+ "node_modules/@babel/helper-validator-identifier": {
176
+ "version": "7.28.5",
177
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
178
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
179
+ "dev": true,
180
+ "license": "MIT",
181
+ "engines": {
182
+ "node": ">=6.9.0"
183
+ }
184
+ },
185
+ "node_modules/@babel/helper-validator-option": {
186
+ "version": "7.27.1",
187
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
188
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
189
+ "dev": true,
190
+ "license": "MIT",
191
+ "engines": {
192
+ "node": ">=6.9.0"
193
+ }
194
+ },
195
+ "node_modules/@babel/helpers": {
196
+ "version": "7.28.4",
197
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
198
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
199
+ "dev": true,
200
+ "license": "MIT",
201
+ "dependencies": {
202
+ "@babel/template": "^7.27.2",
203
+ "@babel/types": "^7.28.4"
204
+ },
205
+ "engines": {
206
+ "node": ">=6.9.0"
207
+ }
208
+ },
209
+ "node_modules/@babel/parser": {
210
+ "version": "7.28.5",
211
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
212
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
213
+ "dev": true,
214
+ "license": "MIT",
215
+ "dependencies": {
216
+ "@babel/types": "^7.28.5"
217
+ },
218
+ "bin": {
219
+ "parser": "bin/babel-parser.js"
220
+ },
221
+ "engines": {
222
+ "node": ">=6.0.0"
223
+ }
224
+ },
225
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
226
+ "version": "7.27.1",
227
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
228
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
229
+ "dev": true,
230
+ "license": "MIT",
231
+ "dependencies": {
232
+ "@babel/helper-plugin-utils": "^7.27.1"
233
+ },
234
+ "engines": {
235
+ "node": ">=6.9.0"
236
+ },
237
+ "peerDependencies": {
238
+ "@babel/core": "^7.0.0-0"
239
+ }
240
+ },
241
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
242
+ "version": "7.27.1",
243
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
244
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
245
+ "dev": true,
246
+ "license": "MIT",
247
+ "dependencies": {
248
+ "@babel/helper-plugin-utils": "^7.27.1"
249
+ },
250
+ "engines": {
251
+ "node": ">=6.9.0"
252
+ },
253
+ "peerDependencies": {
254
+ "@babel/core": "^7.0.0-0"
255
+ }
256
+ },
257
+ "node_modules/@babel/template": {
258
+ "version": "7.27.2",
259
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
260
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
261
+ "dev": true,
262
+ "license": "MIT",
263
+ "dependencies": {
264
+ "@babel/code-frame": "^7.27.1",
265
+ "@babel/parser": "^7.27.2",
266
+ "@babel/types": "^7.27.1"
267
+ },
268
+ "engines": {
269
+ "node": ">=6.9.0"
270
+ }
271
+ },
272
+ "node_modules/@babel/traverse": {
273
+ "version": "7.28.5",
274
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
275
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
276
+ "dev": true,
277
+ "license": "MIT",
278
+ "dependencies": {
279
+ "@babel/code-frame": "^7.27.1",
280
+ "@babel/generator": "^7.28.5",
281
+ "@babel/helper-globals": "^7.28.0",
282
+ "@babel/parser": "^7.28.5",
283
+ "@babel/template": "^7.27.2",
284
+ "@babel/types": "^7.28.5",
285
+ "debug": "^4.3.1"
286
+ },
287
+ "engines": {
288
+ "node": ">=6.9.0"
289
+ }
290
+ },
291
+ "node_modules/@babel/types": {
292
+ "version": "7.28.5",
293
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
294
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
295
+ "dev": true,
296
+ "license": "MIT",
297
+ "dependencies": {
298
+ "@babel/helper-string-parser": "^7.27.1",
299
+ "@babel/helper-validator-identifier": "^7.28.5"
300
+ },
301
+ "engines": {
302
+ "node": ">=6.9.0"
303
+ }
304
+ },
305
+ "node_modules/@esbuild/aix-ppc64": {
306
+ "version": "0.25.12",
307
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
308
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
309
+ "cpu": [
310
+ "ppc64"
311
+ ],
312
+ "dev": true,
313
+ "license": "MIT",
314
+ "optional": true,
315
+ "os": [
316
+ "aix"
317
+ ],
318
+ "engines": {
319
+ "node": ">=18"
320
+ }
321
+ },
322
+ "node_modules/@esbuild/android-arm": {
323
+ "version": "0.25.12",
324
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
325
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
326
+ "cpu": [
327
+ "arm"
328
+ ],
329
+ "dev": true,
330
+ "license": "MIT",
331
+ "optional": true,
332
+ "os": [
333
+ "android"
334
+ ],
335
+ "engines": {
336
+ "node": ">=18"
337
+ }
338
+ },
339
+ "node_modules/@esbuild/android-arm64": {
340
+ "version": "0.25.12",
341
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
342
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
343
+ "cpu": [
344
+ "arm64"
345
+ ],
346
+ "dev": true,
347
+ "license": "MIT",
348
+ "optional": true,
349
+ "os": [
350
+ "android"
351
+ ],
352
+ "engines": {
353
+ "node": ">=18"
354
+ }
355
+ },
356
+ "node_modules/@esbuild/android-x64": {
357
+ "version": "0.25.12",
358
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
359
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
360
+ "cpu": [
361
+ "x64"
362
+ ],
363
+ "dev": true,
364
+ "license": "MIT",
365
+ "optional": true,
366
+ "os": [
367
+ "android"
368
+ ],
369
+ "engines": {
370
+ "node": ">=18"
371
+ }
372
+ },
373
+ "node_modules/@esbuild/darwin-arm64": {
374
+ "version": "0.25.12",
375
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
376
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
377
+ "cpu": [
378
+ "arm64"
379
+ ],
380
+ "dev": true,
381
+ "license": "MIT",
382
+ "optional": true,
383
+ "os": [
384
+ "darwin"
385
+ ],
386
+ "engines": {
387
+ "node": ">=18"
388
+ }
389
+ },
390
+ "node_modules/@esbuild/darwin-x64": {
391
+ "version": "0.25.12",
392
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
393
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
394
+ "cpu": [
395
+ "x64"
396
+ ],
397
+ "dev": true,
398
+ "license": "MIT",
399
+ "optional": true,
400
+ "os": [
401
+ "darwin"
402
+ ],
403
+ "engines": {
404
+ "node": ">=18"
405
+ }
406
+ },
407
+ "node_modules/@esbuild/freebsd-arm64": {
408
+ "version": "0.25.12",
409
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
410
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
411
+ "cpu": [
412
+ "arm64"
413
+ ],
414
+ "dev": true,
415
+ "license": "MIT",
416
+ "optional": true,
417
+ "os": [
418
+ "freebsd"
419
+ ],
420
+ "engines": {
421
+ "node": ">=18"
422
+ }
423
+ },
424
+ "node_modules/@esbuild/freebsd-x64": {
425
+ "version": "0.25.12",
426
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
427
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
428
+ "cpu": [
429
+ "x64"
430
+ ],
431
+ "dev": true,
432
+ "license": "MIT",
433
+ "optional": true,
434
+ "os": [
435
+ "freebsd"
436
+ ],
437
+ "engines": {
438
+ "node": ">=18"
439
+ }
440
+ },
441
+ "node_modules/@esbuild/linux-arm": {
442
+ "version": "0.25.12",
443
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
444
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
445
+ "cpu": [
446
+ "arm"
447
+ ],
448
+ "dev": true,
449
+ "license": "MIT",
450
+ "optional": true,
451
+ "os": [
452
+ "linux"
453
+ ],
454
+ "engines": {
455
+ "node": ">=18"
456
+ }
457
+ },
458
+ "node_modules/@esbuild/linux-arm64": {
459
+ "version": "0.25.12",
460
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
461
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
462
+ "cpu": [
463
+ "arm64"
464
+ ],
465
+ "dev": true,
466
+ "license": "MIT",
467
+ "optional": true,
468
+ "os": [
469
+ "linux"
470
+ ],
471
+ "engines": {
472
+ "node": ">=18"
473
+ }
474
+ },
475
+ "node_modules/@esbuild/linux-ia32": {
476
+ "version": "0.25.12",
477
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
478
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
479
+ "cpu": [
480
+ "ia32"
481
+ ],
482
+ "dev": true,
483
+ "license": "MIT",
484
+ "optional": true,
485
+ "os": [
486
+ "linux"
487
+ ],
488
+ "engines": {
489
+ "node": ">=18"
490
+ }
491
+ },
492
+ "node_modules/@esbuild/linux-loong64": {
493
+ "version": "0.25.12",
494
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
495
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
496
+ "cpu": [
497
+ "loong64"
498
+ ],
499
+ "dev": true,
500
+ "license": "MIT",
501
+ "optional": true,
502
+ "os": [
503
+ "linux"
504
+ ],
505
+ "engines": {
506
+ "node": ">=18"
507
+ }
508
+ },
509
+ "node_modules/@esbuild/linux-mips64el": {
510
+ "version": "0.25.12",
511
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
512
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
513
+ "cpu": [
514
+ "mips64el"
515
+ ],
516
+ "dev": true,
517
+ "license": "MIT",
518
+ "optional": true,
519
+ "os": [
520
+ "linux"
521
+ ],
522
+ "engines": {
523
+ "node": ">=18"
524
+ }
525
+ },
526
+ "node_modules/@esbuild/linux-ppc64": {
527
+ "version": "0.25.12",
528
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
529
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
530
+ "cpu": [
531
+ "ppc64"
532
+ ],
533
+ "dev": true,
534
+ "license": "MIT",
535
+ "optional": true,
536
+ "os": [
537
+ "linux"
538
+ ],
539
+ "engines": {
540
+ "node": ">=18"
541
+ }
542
+ },
543
+ "node_modules/@esbuild/linux-riscv64": {
544
+ "version": "0.25.12",
545
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
546
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
547
+ "cpu": [
548
+ "riscv64"
549
+ ],
550
+ "dev": true,
551
+ "license": "MIT",
552
+ "optional": true,
553
+ "os": [
554
+ "linux"
555
+ ],
556
+ "engines": {
557
+ "node": ">=18"
558
+ }
559
+ },
560
+ "node_modules/@esbuild/linux-s390x": {
561
+ "version": "0.25.12",
562
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
563
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
564
+ "cpu": [
565
+ "s390x"
566
+ ],
567
+ "dev": true,
568
+ "license": "MIT",
569
+ "optional": true,
570
+ "os": [
571
+ "linux"
572
+ ],
573
+ "engines": {
574
+ "node": ">=18"
575
+ }
576
+ },
577
+ "node_modules/@esbuild/linux-x64": {
578
+ "version": "0.25.12",
579
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
580
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
581
+ "cpu": [
582
+ "x64"
583
+ ],
584
+ "dev": true,
585
+ "license": "MIT",
586
+ "optional": true,
587
+ "os": [
588
+ "linux"
589
+ ],
590
+ "engines": {
591
+ "node": ">=18"
592
+ }
593
+ },
594
+ "node_modules/@esbuild/netbsd-arm64": {
595
+ "version": "0.25.12",
596
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
597
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
598
+ "cpu": [
599
+ "arm64"
600
+ ],
601
+ "dev": true,
602
+ "license": "MIT",
603
+ "optional": true,
604
+ "os": [
605
+ "netbsd"
606
+ ],
607
+ "engines": {
608
+ "node": ">=18"
609
+ }
610
+ },
611
+ "node_modules/@esbuild/netbsd-x64": {
612
+ "version": "0.25.12",
613
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
614
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
615
+ "cpu": [
616
+ "x64"
617
+ ],
618
+ "dev": true,
619
+ "license": "MIT",
620
+ "optional": true,
621
+ "os": [
622
+ "netbsd"
623
+ ],
624
+ "engines": {
625
+ "node": ">=18"
626
+ }
627
+ },
628
+ "node_modules/@esbuild/openbsd-arm64": {
629
+ "version": "0.25.12",
630
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
631
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
632
+ "cpu": [
633
+ "arm64"
634
+ ],
635
+ "dev": true,
636
+ "license": "MIT",
637
+ "optional": true,
638
+ "os": [
639
+ "openbsd"
640
+ ],
641
+ "engines": {
642
+ "node": ">=18"
643
+ }
644
+ },
645
+ "node_modules/@esbuild/openbsd-x64": {
646
+ "version": "0.25.12",
647
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
648
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
649
+ "cpu": [
650
+ "x64"
651
+ ],
652
+ "dev": true,
653
+ "license": "MIT",
654
+ "optional": true,
655
+ "os": [
656
+ "openbsd"
657
+ ],
658
+ "engines": {
659
+ "node": ">=18"
660
+ }
661
+ },
662
+ "node_modules/@esbuild/openharmony-arm64": {
663
+ "version": "0.25.12",
664
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
665
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
666
+ "cpu": [
667
+ "arm64"
668
+ ],
669
+ "dev": true,
670
+ "license": "MIT",
671
+ "optional": true,
672
+ "os": [
673
+ "openharmony"
674
+ ],
675
+ "engines": {
676
+ "node": ">=18"
677
+ }
678
+ },
679
+ "node_modules/@esbuild/sunos-x64": {
680
+ "version": "0.25.12",
681
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
682
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
683
+ "cpu": [
684
+ "x64"
685
+ ],
686
+ "dev": true,
687
+ "license": "MIT",
688
+ "optional": true,
689
+ "os": [
690
+ "sunos"
691
+ ],
692
+ "engines": {
693
+ "node": ">=18"
694
+ }
695
+ },
696
+ "node_modules/@esbuild/win32-arm64": {
697
+ "version": "0.25.12",
698
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
699
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
700
+ "cpu": [
701
+ "arm64"
702
+ ],
703
+ "dev": true,
704
+ "license": "MIT",
705
+ "optional": true,
706
+ "os": [
707
+ "win32"
708
+ ],
709
+ "engines": {
710
+ "node": ">=18"
711
+ }
712
+ },
713
+ "node_modules/@esbuild/win32-ia32": {
714
+ "version": "0.25.12",
715
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
716
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
717
+ "cpu": [
718
+ "ia32"
719
+ ],
720
+ "dev": true,
721
+ "license": "MIT",
722
+ "optional": true,
723
+ "os": [
724
+ "win32"
725
+ ],
726
+ "engines": {
727
+ "node": ">=18"
728
+ }
729
+ },
730
+ "node_modules/@esbuild/win32-x64": {
731
+ "version": "0.25.12",
732
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
733
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
734
+ "cpu": [
735
+ "x64"
736
+ ],
737
+ "dev": true,
738
+ "license": "MIT",
739
+ "optional": true,
740
+ "os": [
741
+ "win32"
742
+ ],
743
+ "engines": {
744
+ "node": ">=18"
745
+ }
746
+ },
747
+ "node_modules/@jridgewell/gen-mapping": {
748
+ "version": "0.3.13",
749
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
750
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
751
+ "dev": true,
752
+ "license": "MIT",
753
+ "dependencies": {
754
+ "@jridgewell/sourcemap-codec": "^1.5.0",
755
+ "@jridgewell/trace-mapping": "^0.3.24"
756
+ }
757
+ },
758
+ "node_modules/@jridgewell/remapping": {
759
+ "version": "2.3.5",
760
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
761
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
762
+ "dev": true,
763
+ "license": "MIT",
764
+ "dependencies": {
765
+ "@jridgewell/gen-mapping": "^0.3.5",
766
+ "@jridgewell/trace-mapping": "^0.3.24"
767
+ }
768
+ },
769
+ "node_modules/@jridgewell/resolve-uri": {
770
+ "version": "3.1.2",
771
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
772
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
773
+ "dev": true,
774
+ "license": "MIT",
775
+ "engines": {
776
+ "node": ">=6.0.0"
777
+ }
778
+ },
779
+ "node_modules/@jridgewell/sourcemap-codec": {
780
+ "version": "1.5.5",
781
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
782
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
783
+ "dev": true,
784
+ "license": "MIT"
785
+ },
786
+ "node_modules/@jridgewell/trace-mapping": {
787
+ "version": "0.3.31",
788
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
789
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
790
+ "dev": true,
791
+ "license": "MIT",
792
+ "dependencies": {
793
+ "@jridgewell/resolve-uri": "^3.1.0",
794
+ "@jridgewell/sourcemap-codec": "^1.4.14"
795
+ }
796
+ },
797
+ "node_modules/@reduxjs/toolkit": {
798
+ "version": "2.11.0",
799
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.0.tgz",
800
+ "integrity": "sha512-hBjYg0aaRL1O2Z0IqWhnTLytnjDIxekmRxm1snsHjHaKVmIF1HiImWqsq+PuEbn6zdMlkIj9WofK1vR8jjx+Xw==",
801
+ "license": "MIT",
802
+ "dependencies": {
803
+ "@standard-schema/spec": "^1.0.0",
804
+ "@standard-schema/utils": "^0.3.0",
805
+ "immer": "^11.0.0",
806
+ "redux": "^5.0.1",
807
+ "redux-thunk": "^3.1.0",
808
+ "reselect": "^5.1.0"
809
+ },
810
+ "peerDependencies": {
811
+ "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
812
+ "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
813
+ },
814
+ "peerDependenciesMeta": {
815
+ "react": {
816
+ "optional": true
817
+ },
818
+ "react-redux": {
819
+ "optional": true
820
+ }
821
+ }
822
+ },
823
+ "node_modules/@reduxjs/toolkit/node_modules/immer": {
824
+ "version": "11.0.1",
825
+ "resolved": "https://registry.npmjs.org/immer/-/immer-11.0.1.tgz",
826
+ "integrity": "sha512-naDCyggtcBWANtIrjQEajhhBEuL9b0Zg4zmlWK2CzS6xCWSE39/vvf4LqnMjUAWHBhot4m9MHCM/Z+mfWhUkiA==",
827
+ "license": "MIT",
828
+ "funding": {
829
+ "type": "opencollective",
830
+ "url": "https://opencollective.com/immer"
831
+ }
832
+ },
833
+ "node_modules/@rolldown/pluginutils": {
834
+ "version": "1.0.0-beta.47",
835
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz",
836
+ "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==",
837
+ "dev": true,
838
+ "license": "MIT"
839
+ },
840
+ "node_modules/@rollup/rollup-android-arm-eabi": {
841
+ "version": "4.53.3",
842
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
843
+ "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
844
+ "cpu": [
845
+ "arm"
846
+ ],
847
+ "dev": true,
848
+ "license": "MIT",
849
+ "optional": true,
850
+ "os": [
851
+ "android"
852
+ ]
853
+ },
854
+ "node_modules/@rollup/rollup-android-arm64": {
855
+ "version": "4.53.3",
856
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
857
+ "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
858
+ "cpu": [
859
+ "arm64"
860
+ ],
861
+ "dev": true,
862
+ "license": "MIT",
863
+ "optional": true,
864
+ "os": [
865
+ "android"
866
+ ]
867
+ },
868
+ "node_modules/@rollup/rollup-darwin-arm64": {
869
+ "version": "4.53.3",
870
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
871
+ "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
872
+ "cpu": [
873
+ "arm64"
874
+ ],
875
+ "dev": true,
876
+ "license": "MIT",
877
+ "optional": true,
878
+ "os": [
879
+ "darwin"
880
+ ]
881
+ },
882
+ "node_modules/@rollup/rollup-darwin-x64": {
883
+ "version": "4.53.3",
884
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
885
+ "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
886
+ "cpu": [
887
+ "x64"
888
+ ],
889
+ "dev": true,
890
+ "license": "MIT",
891
+ "optional": true,
892
+ "os": [
893
+ "darwin"
894
+ ]
895
+ },
896
+ "node_modules/@rollup/rollup-freebsd-arm64": {
897
+ "version": "4.53.3",
898
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
899
+ "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
900
+ "cpu": [
901
+ "arm64"
902
+ ],
903
+ "dev": true,
904
+ "license": "MIT",
905
+ "optional": true,
906
+ "os": [
907
+ "freebsd"
908
+ ]
909
+ },
910
+ "node_modules/@rollup/rollup-freebsd-x64": {
911
+ "version": "4.53.3",
912
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
913
+ "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
914
+ "cpu": [
915
+ "x64"
916
+ ],
917
+ "dev": true,
918
+ "license": "MIT",
919
+ "optional": true,
920
+ "os": [
921
+ "freebsd"
922
+ ]
923
+ },
924
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
925
+ "version": "4.53.3",
926
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
927
+ "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
928
+ "cpu": [
929
+ "arm"
930
+ ],
931
+ "dev": true,
932
+ "license": "MIT",
933
+ "optional": true,
934
+ "os": [
935
+ "linux"
936
+ ]
937
+ },
938
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
939
+ "version": "4.53.3",
940
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
941
+ "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
942
+ "cpu": [
943
+ "arm"
944
+ ],
945
+ "dev": true,
946
+ "license": "MIT",
947
+ "optional": true,
948
+ "os": [
949
+ "linux"
950
+ ]
951
+ },
952
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
953
+ "version": "4.53.3",
954
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
955
+ "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
956
+ "cpu": [
957
+ "arm64"
958
+ ],
959
+ "dev": true,
960
+ "license": "MIT",
961
+ "optional": true,
962
+ "os": [
963
+ "linux"
964
+ ]
965
+ },
966
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
967
+ "version": "4.53.3",
968
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
969
+ "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
970
+ "cpu": [
971
+ "arm64"
972
+ ],
973
+ "dev": true,
974
+ "license": "MIT",
975
+ "optional": true,
976
+ "os": [
977
+ "linux"
978
+ ]
979
+ },
980
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
981
+ "version": "4.53.3",
982
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
983
+ "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
984
+ "cpu": [
985
+ "loong64"
986
+ ],
987
+ "dev": true,
988
+ "license": "MIT",
989
+ "optional": true,
990
+ "os": [
991
+ "linux"
992
+ ]
993
+ },
994
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
995
+ "version": "4.53.3",
996
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
997
+ "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
998
+ "cpu": [
999
+ "ppc64"
1000
+ ],
1001
+ "dev": true,
1002
+ "license": "MIT",
1003
+ "optional": true,
1004
+ "os": [
1005
+ "linux"
1006
+ ]
1007
+ },
1008
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1009
+ "version": "4.53.3",
1010
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
1011
+ "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
1012
+ "cpu": [
1013
+ "riscv64"
1014
+ ],
1015
+ "dev": true,
1016
+ "license": "MIT",
1017
+ "optional": true,
1018
+ "os": [
1019
+ "linux"
1020
+ ]
1021
+ },
1022
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
1023
+ "version": "4.53.3",
1024
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
1025
+ "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
1026
+ "cpu": [
1027
+ "riscv64"
1028
+ ],
1029
+ "dev": true,
1030
+ "license": "MIT",
1031
+ "optional": true,
1032
+ "os": [
1033
+ "linux"
1034
+ ]
1035
+ },
1036
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
1037
+ "version": "4.53.3",
1038
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
1039
+ "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
1040
+ "cpu": [
1041
+ "s390x"
1042
+ ],
1043
+ "dev": true,
1044
+ "license": "MIT",
1045
+ "optional": true,
1046
+ "os": [
1047
+ "linux"
1048
+ ]
1049
+ },
1050
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
1051
+ "version": "4.53.3",
1052
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
1053
+ "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
1054
+ "cpu": [
1055
+ "x64"
1056
+ ],
1057
+ "dev": true,
1058
+ "license": "MIT",
1059
+ "optional": true,
1060
+ "os": [
1061
+ "linux"
1062
+ ]
1063
+ },
1064
+ "node_modules/@rollup/rollup-linux-x64-musl": {
1065
+ "version": "4.53.3",
1066
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
1067
+ "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
1068
+ "cpu": [
1069
+ "x64"
1070
+ ],
1071
+ "dev": true,
1072
+ "license": "MIT",
1073
+ "optional": true,
1074
+ "os": [
1075
+ "linux"
1076
+ ]
1077
+ },
1078
+ "node_modules/@rollup/rollup-openharmony-arm64": {
1079
+ "version": "4.53.3",
1080
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
1081
+ "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
1082
+ "cpu": [
1083
+ "arm64"
1084
+ ],
1085
+ "dev": true,
1086
+ "license": "MIT",
1087
+ "optional": true,
1088
+ "os": [
1089
+ "openharmony"
1090
+ ]
1091
+ },
1092
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
1093
+ "version": "4.53.3",
1094
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
1095
+ "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
1096
+ "cpu": [
1097
+ "arm64"
1098
+ ],
1099
+ "dev": true,
1100
+ "license": "MIT",
1101
+ "optional": true,
1102
+ "os": [
1103
+ "win32"
1104
+ ]
1105
+ },
1106
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
1107
+ "version": "4.53.3",
1108
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
1109
+ "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
1110
+ "cpu": [
1111
+ "ia32"
1112
+ ],
1113
+ "dev": true,
1114
+ "license": "MIT",
1115
+ "optional": true,
1116
+ "os": [
1117
+ "win32"
1118
+ ]
1119
+ },
1120
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
1121
+ "version": "4.53.3",
1122
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
1123
+ "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
1124
+ "cpu": [
1125
+ "x64"
1126
+ ],
1127
+ "dev": true,
1128
+ "license": "MIT",
1129
+ "optional": true,
1130
+ "os": [
1131
+ "win32"
1132
+ ]
1133
+ },
1134
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
1135
+ "version": "4.53.3",
1136
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
1137
+ "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
1138
+ "cpu": [
1139
+ "x64"
1140
+ ],
1141
+ "dev": true,
1142
+ "license": "MIT",
1143
+ "optional": true,
1144
+ "os": [
1145
+ "win32"
1146
+ ]
1147
+ },
1148
+ "node_modules/@standard-schema/spec": {
1149
+ "version": "1.0.0",
1150
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
1151
+ "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
1152
+ "license": "MIT"
1153
+ },
1154
+ "node_modules/@standard-schema/utils": {
1155
+ "version": "0.3.0",
1156
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
1157
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
1158
+ "license": "MIT"
1159
+ },
1160
+ "node_modules/@types/babel__core": {
1161
+ "version": "7.20.5",
1162
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
1163
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
1164
+ "dev": true,
1165
+ "license": "MIT",
1166
+ "dependencies": {
1167
+ "@babel/parser": "^7.20.7",
1168
+ "@babel/types": "^7.20.7",
1169
+ "@types/babel__generator": "*",
1170
+ "@types/babel__template": "*",
1171
+ "@types/babel__traverse": "*"
1172
+ }
1173
+ },
1174
+ "node_modules/@types/babel__generator": {
1175
+ "version": "7.27.0",
1176
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
1177
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
1178
+ "dev": true,
1179
+ "license": "MIT",
1180
+ "dependencies": {
1181
+ "@babel/types": "^7.0.0"
1182
+ }
1183
+ },
1184
+ "node_modules/@types/babel__template": {
1185
+ "version": "7.4.4",
1186
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
1187
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
1188
+ "dev": true,
1189
+ "license": "MIT",
1190
+ "dependencies": {
1191
+ "@babel/parser": "^7.1.0",
1192
+ "@babel/types": "^7.0.0"
1193
+ }
1194
+ },
1195
+ "node_modules/@types/babel__traverse": {
1196
+ "version": "7.28.0",
1197
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
1198
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
1199
+ "dev": true,
1200
+ "license": "MIT",
1201
+ "dependencies": {
1202
+ "@babel/types": "^7.28.2"
1203
+ }
1204
+ },
1205
+ "node_modules/@types/d3-array": {
1206
+ "version": "3.2.2",
1207
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
1208
+ "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
1209
+ "license": "MIT"
1210
+ },
1211
+ "node_modules/@types/d3-color": {
1212
+ "version": "3.1.3",
1213
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
1214
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
1215
+ "license": "MIT"
1216
+ },
1217
+ "node_modules/@types/d3-ease": {
1218
+ "version": "3.0.2",
1219
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
1220
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
1221
+ "license": "MIT"
1222
+ },
1223
+ "node_modules/@types/d3-interpolate": {
1224
+ "version": "3.0.4",
1225
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
1226
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
1227
+ "license": "MIT",
1228
+ "dependencies": {
1229
+ "@types/d3-color": "*"
1230
+ }
1231
+ },
1232
+ "node_modules/@types/d3-path": {
1233
+ "version": "3.1.1",
1234
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
1235
+ "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
1236
+ "license": "MIT"
1237
+ },
1238
+ "node_modules/@types/d3-scale": {
1239
+ "version": "4.0.9",
1240
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
1241
+ "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
1242
+ "license": "MIT",
1243
+ "dependencies": {
1244
+ "@types/d3-time": "*"
1245
+ }
1246
+ },
1247
+ "node_modules/@types/d3-shape": {
1248
+ "version": "3.1.7",
1249
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
1250
+ "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
1251
+ "license": "MIT",
1252
+ "dependencies": {
1253
+ "@types/d3-path": "*"
1254
+ }
1255
+ },
1256
+ "node_modules/@types/d3-time": {
1257
+ "version": "3.0.4",
1258
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
1259
+ "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
1260
+ "license": "MIT"
1261
+ },
1262
+ "node_modules/@types/d3-timer": {
1263
+ "version": "3.0.2",
1264
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
1265
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
1266
+ "license": "MIT"
1267
+ },
1268
+ "node_modules/@types/estree": {
1269
+ "version": "1.0.8",
1270
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1271
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
1272
+ "dev": true,
1273
+ "license": "MIT"
1274
+ },
1275
+ "node_modules/@types/node": {
1276
+ "version": "22.19.1",
1277
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
1278
+ "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
1279
+ "dev": true,
1280
+ "license": "MIT",
1281
+ "dependencies": {
1282
+ "undici-types": "~6.21.0"
1283
+ }
1284
+ },
1285
+ "node_modules/@types/use-sync-external-store": {
1286
+ "version": "0.0.6",
1287
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
1288
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
1289
+ "license": "MIT"
1290
+ },
1291
+ "node_modules/@vitejs/plugin-react": {
1292
+ "version": "5.1.1",
1293
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.1.tgz",
1294
+ "integrity": "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==",
1295
+ "dev": true,
1296
+ "license": "MIT",
1297
+ "dependencies": {
1298
+ "@babel/core": "^7.28.5",
1299
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
1300
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
1301
+ "@rolldown/pluginutils": "1.0.0-beta.47",
1302
+ "@types/babel__core": "^7.20.5",
1303
+ "react-refresh": "^0.18.0"
1304
+ },
1305
+ "engines": {
1306
+ "node": "^20.19.0 || >=22.12.0"
1307
+ },
1308
+ "peerDependencies": {
1309
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
1310
+ }
1311
+ },
1312
+ "node_modules/baseline-browser-mapping": {
1313
+ "version": "2.9.2",
1314
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.2.tgz",
1315
+ "integrity": "sha512-PxSsosKQjI38iXkmb3d0Y32efqyA0uW4s41u4IVBsLlWLhCiYNpH/AfNOVWRqCQBlD8TFJTz6OUWNd4DFJCnmw==",
1316
+ "dev": true,
1317
+ "license": "Apache-2.0",
1318
+ "bin": {
1319
+ "baseline-browser-mapping": "dist/cli.js"
1320
+ }
1321
+ },
1322
+ "node_modules/browserslist": {
1323
+ "version": "4.28.1",
1324
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
1325
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
1326
+ "dev": true,
1327
+ "funding": [
1328
+ {
1329
+ "type": "opencollective",
1330
+ "url": "https://opencollective.com/browserslist"
1331
+ },
1332
+ {
1333
+ "type": "tidelift",
1334
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
1335
+ },
1336
+ {
1337
+ "type": "github",
1338
+ "url": "https://github.com/sponsors/ai"
1339
+ }
1340
+ ],
1341
+ "license": "MIT",
1342
+ "dependencies": {
1343
+ "baseline-browser-mapping": "^2.9.0",
1344
+ "caniuse-lite": "^1.0.30001759",
1345
+ "electron-to-chromium": "^1.5.263",
1346
+ "node-releases": "^2.0.27",
1347
+ "update-browserslist-db": "^1.2.0"
1348
+ },
1349
+ "bin": {
1350
+ "browserslist": "cli.js"
1351
+ },
1352
+ "engines": {
1353
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
1354
+ }
1355
+ },
1356
+ "node_modules/caniuse-lite": {
1357
+ "version": "1.0.30001759",
1358
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz",
1359
+ "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==",
1360
+ "dev": true,
1361
+ "funding": [
1362
+ {
1363
+ "type": "opencollective",
1364
+ "url": "https://opencollective.com/browserslist"
1365
+ },
1366
+ {
1367
+ "type": "tidelift",
1368
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1369
+ },
1370
+ {
1371
+ "type": "github",
1372
+ "url": "https://github.com/sponsors/ai"
1373
+ }
1374
+ ],
1375
+ "license": "CC-BY-4.0"
1376
+ },
1377
+ "node_modules/clsx": {
1378
+ "version": "2.1.1",
1379
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
1380
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
1381
+ "license": "MIT",
1382
+ "engines": {
1383
+ "node": ">=6"
1384
+ }
1385
+ },
1386
+ "node_modules/convert-source-map": {
1387
+ "version": "2.0.0",
1388
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
1389
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
1390
+ "dev": true,
1391
+ "license": "MIT"
1392
+ },
1393
+ "node_modules/d3-array": {
1394
+ "version": "3.2.4",
1395
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
1396
+ "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
1397
+ "license": "ISC",
1398
+ "dependencies": {
1399
+ "internmap": "1 - 2"
1400
+ },
1401
+ "engines": {
1402
+ "node": ">=12"
1403
+ }
1404
+ },
1405
+ "node_modules/d3-color": {
1406
+ "version": "3.1.0",
1407
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
1408
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
1409
+ "license": "ISC",
1410
+ "engines": {
1411
+ "node": ">=12"
1412
+ }
1413
+ },
1414
+ "node_modules/d3-ease": {
1415
+ "version": "3.0.1",
1416
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
1417
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
1418
+ "license": "BSD-3-Clause",
1419
+ "engines": {
1420
+ "node": ">=12"
1421
+ }
1422
+ },
1423
+ "node_modules/d3-format": {
1424
+ "version": "3.1.0",
1425
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
1426
+ "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
1427
+ "license": "ISC",
1428
+ "engines": {
1429
+ "node": ">=12"
1430
+ }
1431
+ },
1432
+ "node_modules/d3-interpolate": {
1433
+ "version": "3.0.1",
1434
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
1435
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
1436
+ "license": "ISC",
1437
+ "dependencies": {
1438
+ "d3-color": "1 - 3"
1439
+ },
1440
+ "engines": {
1441
+ "node": ">=12"
1442
+ }
1443
+ },
1444
+ "node_modules/d3-path": {
1445
+ "version": "3.1.0",
1446
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
1447
+ "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
1448
+ "license": "ISC",
1449
+ "engines": {
1450
+ "node": ">=12"
1451
+ }
1452
+ },
1453
+ "node_modules/d3-scale": {
1454
+ "version": "4.0.2",
1455
+ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
1456
+ "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
1457
+ "license": "ISC",
1458
+ "dependencies": {
1459
+ "d3-array": "2.10.0 - 3",
1460
+ "d3-format": "1 - 3",
1461
+ "d3-interpolate": "1.2.0 - 3",
1462
+ "d3-time": "2.1.1 - 3",
1463
+ "d3-time-format": "2 - 4"
1464
+ },
1465
+ "engines": {
1466
+ "node": ">=12"
1467
+ }
1468
+ },
1469
+ "node_modules/d3-shape": {
1470
+ "version": "3.2.0",
1471
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
1472
+ "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
1473
+ "license": "ISC",
1474
+ "dependencies": {
1475
+ "d3-path": "^3.1.0"
1476
+ },
1477
+ "engines": {
1478
+ "node": ">=12"
1479
+ }
1480
+ },
1481
+ "node_modules/d3-time": {
1482
+ "version": "3.1.0",
1483
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
1484
+ "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
1485
+ "license": "ISC",
1486
+ "dependencies": {
1487
+ "d3-array": "2 - 3"
1488
+ },
1489
+ "engines": {
1490
+ "node": ">=12"
1491
+ }
1492
+ },
1493
+ "node_modules/d3-time-format": {
1494
+ "version": "4.1.0",
1495
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
1496
+ "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
1497
+ "license": "ISC",
1498
+ "dependencies": {
1499
+ "d3-time": "1 - 3"
1500
+ },
1501
+ "engines": {
1502
+ "node": ">=12"
1503
+ }
1504
+ },
1505
+ "node_modules/d3-timer": {
1506
+ "version": "3.0.1",
1507
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
1508
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
1509
+ "license": "ISC",
1510
+ "engines": {
1511
+ "node": ">=12"
1512
+ }
1513
+ },
1514
+ "node_modules/debug": {
1515
+ "version": "4.4.3",
1516
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1517
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1518
+ "dev": true,
1519
+ "license": "MIT",
1520
+ "dependencies": {
1521
+ "ms": "^2.1.3"
1522
+ },
1523
+ "engines": {
1524
+ "node": ">=6.0"
1525
+ },
1526
+ "peerDependenciesMeta": {
1527
+ "supports-color": {
1528
+ "optional": true
1529
+ }
1530
+ }
1531
+ },
1532
+ "node_modules/decimal.js-light": {
1533
+ "version": "2.5.1",
1534
+ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
1535
+ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
1536
+ "license": "MIT"
1537
+ },
1538
+ "node_modules/electron-to-chromium": {
1539
+ "version": "1.5.266",
1540
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz",
1541
+ "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==",
1542
+ "dev": true,
1543
+ "license": "ISC"
1544
+ },
1545
+ "node_modules/es-toolkit": {
1546
+ "version": "1.42.0",
1547
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.42.0.tgz",
1548
+ "integrity": "sha512-SLHIyY7VfDJBM8clz4+T2oquwTQxEzu263AyhVK4jREOAwJ+8eebaa4wM3nlvnAqhDrMm2EsA6hWHaQsMPQ1nA==",
1549
+ "license": "MIT",
1550
+ "workspaces": [
1551
+ "docs",
1552
+ "benchmarks"
1553
+ ]
1554
+ },
1555
+ "node_modules/esbuild": {
1556
+ "version": "0.25.12",
1557
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
1558
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
1559
+ "dev": true,
1560
+ "hasInstallScript": true,
1561
+ "license": "MIT",
1562
+ "bin": {
1563
+ "esbuild": "bin/esbuild"
1564
+ },
1565
+ "engines": {
1566
+ "node": ">=18"
1567
+ },
1568
+ "optionalDependencies": {
1569
+ "@esbuild/aix-ppc64": "0.25.12",
1570
+ "@esbuild/android-arm": "0.25.12",
1571
+ "@esbuild/android-arm64": "0.25.12",
1572
+ "@esbuild/android-x64": "0.25.12",
1573
+ "@esbuild/darwin-arm64": "0.25.12",
1574
+ "@esbuild/darwin-x64": "0.25.12",
1575
+ "@esbuild/freebsd-arm64": "0.25.12",
1576
+ "@esbuild/freebsd-x64": "0.25.12",
1577
+ "@esbuild/linux-arm": "0.25.12",
1578
+ "@esbuild/linux-arm64": "0.25.12",
1579
+ "@esbuild/linux-ia32": "0.25.12",
1580
+ "@esbuild/linux-loong64": "0.25.12",
1581
+ "@esbuild/linux-mips64el": "0.25.12",
1582
+ "@esbuild/linux-ppc64": "0.25.12",
1583
+ "@esbuild/linux-riscv64": "0.25.12",
1584
+ "@esbuild/linux-s390x": "0.25.12",
1585
+ "@esbuild/linux-x64": "0.25.12",
1586
+ "@esbuild/netbsd-arm64": "0.25.12",
1587
+ "@esbuild/netbsd-x64": "0.25.12",
1588
+ "@esbuild/openbsd-arm64": "0.25.12",
1589
+ "@esbuild/openbsd-x64": "0.25.12",
1590
+ "@esbuild/openharmony-arm64": "0.25.12",
1591
+ "@esbuild/sunos-x64": "0.25.12",
1592
+ "@esbuild/win32-arm64": "0.25.12",
1593
+ "@esbuild/win32-ia32": "0.25.12",
1594
+ "@esbuild/win32-x64": "0.25.12"
1595
+ }
1596
+ },
1597
+ "node_modules/escalade": {
1598
+ "version": "3.2.0",
1599
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1600
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1601
+ "dev": true,
1602
+ "license": "MIT",
1603
+ "engines": {
1604
+ "node": ">=6"
1605
+ }
1606
+ },
1607
+ "node_modules/eventemitter3": {
1608
+ "version": "5.0.1",
1609
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
1610
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
1611
+ "license": "MIT"
1612
+ },
1613
+ "node_modules/fdir": {
1614
+ "version": "6.5.0",
1615
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
1616
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
1617
+ "dev": true,
1618
+ "license": "MIT",
1619
+ "engines": {
1620
+ "node": ">=12.0.0"
1621
+ },
1622
+ "peerDependencies": {
1623
+ "picomatch": "^3 || ^4"
1624
+ },
1625
+ "peerDependenciesMeta": {
1626
+ "picomatch": {
1627
+ "optional": true
1628
+ }
1629
+ }
1630
+ },
1631
+ "node_modules/fsevents": {
1632
+ "version": "2.3.3",
1633
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1634
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1635
+ "dev": true,
1636
+ "hasInstallScript": true,
1637
+ "license": "MIT",
1638
+ "optional": true,
1639
+ "os": [
1640
+ "darwin"
1641
+ ],
1642
+ "engines": {
1643
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1644
+ }
1645
+ },
1646
+ "node_modules/gensync": {
1647
+ "version": "1.0.0-beta.2",
1648
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
1649
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
1650
+ "dev": true,
1651
+ "license": "MIT",
1652
+ "engines": {
1653
+ "node": ">=6.9.0"
1654
+ }
1655
+ },
1656
+ "node_modules/immer": {
1657
+ "version": "10.2.0",
1658
+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
1659
+ "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
1660
+ "license": "MIT",
1661
+ "funding": {
1662
+ "type": "opencollective",
1663
+ "url": "https://opencollective.com/immer"
1664
+ }
1665
+ },
1666
+ "node_modules/internmap": {
1667
+ "version": "2.0.3",
1668
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
1669
+ "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
1670
+ "license": "ISC",
1671
+ "engines": {
1672
+ "node": ">=12"
1673
+ }
1674
+ },
1675
+ "node_modules/js-tokens": {
1676
+ "version": "4.0.0",
1677
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1678
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1679
+ "dev": true,
1680
+ "license": "MIT"
1681
+ },
1682
+ "node_modules/jsesc": {
1683
+ "version": "3.1.0",
1684
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
1685
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
1686
+ "dev": true,
1687
+ "license": "MIT",
1688
+ "bin": {
1689
+ "jsesc": "bin/jsesc"
1690
+ },
1691
+ "engines": {
1692
+ "node": ">=6"
1693
+ }
1694
+ },
1695
+ "node_modules/json5": {
1696
+ "version": "2.2.3",
1697
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1698
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1699
+ "dev": true,
1700
+ "license": "MIT",
1701
+ "bin": {
1702
+ "json5": "lib/cli.js"
1703
+ },
1704
+ "engines": {
1705
+ "node": ">=6"
1706
+ }
1707
+ },
1708
+ "node_modules/lru-cache": {
1709
+ "version": "5.1.1",
1710
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
1711
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
1712
+ "dev": true,
1713
+ "license": "ISC",
1714
+ "dependencies": {
1715
+ "yallist": "^3.0.2"
1716
+ }
1717
+ },
1718
+ "node_modules/lucide-react": {
1719
+ "version": "0.555.0",
1720
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.555.0.tgz",
1721
+ "integrity": "sha512-D8FvHUGbxWBRQM90NZeIyhAvkFfsh3u9ekrMvJ30Z6gnpBHS6HC6ldLg7tL45hwiIz/u66eKDtdA23gwwGsAHA==",
1722
+ "license": "ISC",
1723
+ "peerDependencies": {
1724
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
1725
+ }
1726
+ },
1727
+ "node_modules/ms": {
1728
+ "version": "2.1.3",
1729
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1730
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1731
+ "dev": true,
1732
+ "license": "MIT"
1733
+ },
1734
+ "node_modules/nanoid": {
1735
+ "version": "3.3.11",
1736
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1737
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1738
+ "dev": true,
1739
+ "funding": [
1740
+ {
1741
+ "type": "github",
1742
+ "url": "https://github.com/sponsors/ai"
1743
+ }
1744
+ ],
1745
+ "license": "MIT",
1746
+ "bin": {
1747
+ "nanoid": "bin/nanoid.cjs"
1748
+ },
1749
+ "engines": {
1750
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1751
+ }
1752
+ },
1753
+ "node_modules/node-releases": {
1754
+ "version": "2.0.27",
1755
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
1756
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
1757
+ "dev": true,
1758
+ "license": "MIT"
1759
+ },
1760
+ "node_modules/picocolors": {
1761
+ "version": "1.1.1",
1762
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1763
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1764
+ "dev": true,
1765
+ "license": "ISC"
1766
+ },
1767
+ "node_modules/picomatch": {
1768
+ "version": "4.0.3",
1769
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
1770
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
1771
+ "dev": true,
1772
+ "license": "MIT",
1773
+ "engines": {
1774
+ "node": ">=12"
1775
+ },
1776
+ "funding": {
1777
+ "url": "https://github.com/sponsors/jonschlinkert"
1778
+ }
1779
+ },
1780
+ "node_modules/postcss": {
1781
+ "version": "8.5.6",
1782
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
1783
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
1784
+ "dev": true,
1785
+ "funding": [
1786
+ {
1787
+ "type": "opencollective",
1788
+ "url": "https://opencollective.com/postcss/"
1789
+ },
1790
+ {
1791
+ "type": "tidelift",
1792
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1793
+ },
1794
+ {
1795
+ "type": "github",
1796
+ "url": "https://github.com/sponsors/ai"
1797
+ }
1798
+ ],
1799
+ "license": "MIT",
1800
+ "dependencies": {
1801
+ "nanoid": "^3.3.11",
1802
+ "picocolors": "^1.1.1",
1803
+ "source-map-js": "^1.2.1"
1804
+ },
1805
+ "engines": {
1806
+ "node": "^10 || ^12 || >=14"
1807
+ }
1808
+ },
1809
+ "node_modules/react": {
1810
+ "version": "19.2.1",
1811
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
1812
+ "integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
1813
+ "license": "MIT",
1814
+ "engines": {
1815
+ "node": ">=0.10.0"
1816
+ }
1817
+ },
1818
+ "node_modules/react-dom": {
1819
+ "version": "19.2.1",
1820
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz",
1821
+ "integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==",
1822
+ "license": "MIT",
1823
+ "dependencies": {
1824
+ "scheduler": "^0.27.0"
1825
+ },
1826
+ "peerDependencies": {
1827
+ "react": "^19.2.1"
1828
+ }
1829
+ },
1830
+ "node_modules/react-is": {
1831
+ "version": "19.2.1",
1832
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.1.tgz",
1833
+ "integrity": "sha512-L7BnWgRbMwzMAubQcS7sXdPdNLmKlucPlopgAzx7FtYbksWZgEWiuYM5x9T6UqS2Ne0rsgQTq5kY2SGqpzUkYA==",
1834
+ "license": "MIT",
1835
+ "peer": true
1836
+ },
1837
+ "node_modules/react-redux": {
1838
+ "version": "9.2.0",
1839
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
1840
+ "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
1841
+ "license": "MIT",
1842
+ "dependencies": {
1843
+ "@types/use-sync-external-store": "^0.0.6",
1844
+ "use-sync-external-store": "^1.4.0"
1845
+ },
1846
+ "peerDependencies": {
1847
+ "@types/react": "^18.2.25 || ^19",
1848
+ "react": "^18.0 || ^19",
1849
+ "redux": "^5.0.0"
1850
+ },
1851
+ "peerDependenciesMeta": {
1852
+ "@types/react": {
1853
+ "optional": true
1854
+ },
1855
+ "redux": {
1856
+ "optional": true
1857
+ }
1858
+ }
1859
+ },
1860
+ "node_modules/react-refresh": {
1861
+ "version": "0.18.0",
1862
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
1863
+ "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
1864
+ "dev": true,
1865
+ "license": "MIT",
1866
+ "engines": {
1867
+ "node": ">=0.10.0"
1868
+ }
1869
+ },
1870
+ "node_modules/recharts": {
1871
+ "version": "3.5.1",
1872
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.5.1.tgz",
1873
+ "integrity": "sha512-+v+HJojK7gnEgG6h+b2u7k8HH7FhyFUzAc4+cPrsjL4Otdgqr/ecXzAnHciqlzV1ko064eNcsdzrYOM78kankA==",
1874
+ "license": "MIT",
1875
+ "workspaces": [
1876
+ "www"
1877
+ ],
1878
+ "dependencies": {
1879
+ "@reduxjs/toolkit": "1.x.x || 2.x.x",
1880
+ "clsx": "^2.1.1",
1881
+ "decimal.js-light": "^2.5.1",
1882
+ "es-toolkit": "^1.39.3",
1883
+ "eventemitter3": "^5.0.1",
1884
+ "immer": "^10.1.1",
1885
+ "react-redux": "8.x.x || 9.x.x",
1886
+ "reselect": "5.1.1",
1887
+ "tiny-invariant": "^1.3.3",
1888
+ "use-sync-external-store": "^1.2.2",
1889
+ "victory-vendor": "^37.0.2"
1890
+ },
1891
+ "engines": {
1892
+ "node": ">=18"
1893
+ },
1894
+ "peerDependencies": {
1895
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
1896
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
1897
+ "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
1898
+ }
1899
+ },
1900
+ "node_modules/redux": {
1901
+ "version": "5.0.1",
1902
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
1903
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
1904
+ "license": "MIT"
1905
+ },
1906
+ "node_modules/redux-thunk": {
1907
+ "version": "3.1.0",
1908
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
1909
+ "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
1910
+ "license": "MIT",
1911
+ "peerDependencies": {
1912
+ "redux": "^5.0.0"
1913
+ }
1914
+ },
1915
+ "node_modules/reselect": {
1916
+ "version": "5.1.1",
1917
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
1918
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
1919
+ "license": "MIT"
1920
+ },
1921
+ "node_modules/rollup": {
1922
+ "version": "4.53.3",
1923
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
1924
+ "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
1925
+ "dev": true,
1926
+ "license": "MIT",
1927
+ "dependencies": {
1928
+ "@types/estree": "1.0.8"
1929
+ },
1930
+ "bin": {
1931
+ "rollup": "dist/bin/rollup"
1932
+ },
1933
+ "engines": {
1934
+ "node": ">=18.0.0",
1935
+ "npm": ">=8.0.0"
1936
+ },
1937
+ "optionalDependencies": {
1938
+ "@rollup/rollup-android-arm-eabi": "4.53.3",
1939
+ "@rollup/rollup-android-arm64": "4.53.3",
1940
+ "@rollup/rollup-darwin-arm64": "4.53.3",
1941
+ "@rollup/rollup-darwin-x64": "4.53.3",
1942
+ "@rollup/rollup-freebsd-arm64": "4.53.3",
1943
+ "@rollup/rollup-freebsd-x64": "4.53.3",
1944
+ "@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
1945
+ "@rollup/rollup-linux-arm-musleabihf": "4.53.3",
1946
+ "@rollup/rollup-linux-arm64-gnu": "4.53.3",
1947
+ "@rollup/rollup-linux-arm64-musl": "4.53.3",
1948
+ "@rollup/rollup-linux-loong64-gnu": "4.53.3",
1949
+ "@rollup/rollup-linux-ppc64-gnu": "4.53.3",
1950
+ "@rollup/rollup-linux-riscv64-gnu": "4.53.3",
1951
+ "@rollup/rollup-linux-riscv64-musl": "4.53.3",
1952
+ "@rollup/rollup-linux-s390x-gnu": "4.53.3",
1953
+ "@rollup/rollup-linux-x64-gnu": "4.53.3",
1954
+ "@rollup/rollup-linux-x64-musl": "4.53.3",
1955
+ "@rollup/rollup-openharmony-arm64": "4.53.3",
1956
+ "@rollup/rollup-win32-arm64-msvc": "4.53.3",
1957
+ "@rollup/rollup-win32-ia32-msvc": "4.53.3",
1958
+ "@rollup/rollup-win32-x64-gnu": "4.53.3",
1959
+ "@rollup/rollup-win32-x64-msvc": "4.53.3",
1960
+ "fsevents": "~2.3.2"
1961
+ }
1962
+ },
1963
+ "node_modules/scheduler": {
1964
+ "version": "0.27.0",
1965
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
1966
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
1967
+ "license": "MIT"
1968
+ },
1969
+ "node_modules/semver": {
1970
+ "version": "6.3.1",
1971
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1972
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1973
+ "dev": true,
1974
+ "license": "ISC",
1975
+ "bin": {
1976
+ "semver": "bin/semver.js"
1977
+ }
1978
+ },
1979
+ "node_modules/source-map-js": {
1980
+ "version": "1.2.1",
1981
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1982
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1983
+ "dev": true,
1984
+ "license": "BSD-3-Clause",
1985
+ "engines": {
1986
+ "node": ">=0.10.0"
1987
+ }
1988
+ },
1989
+ "node_modules/tiny-invariant": {
1990
+ "version": "1.3.3",
1991
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
1992
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
1993
+ "license": "MIT"
1994
+ },
1995
+ "node_modules/tinyglobby": {
1996
+ "version": "0.2.15",
1997
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
1998
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
1999
+ "dev": true,
2000
+ "license": "MIT",
2001
+ "dependencies": {
2002
+ "fdir": "^6.5.0",
2003
+ "picomatch": "^4.0.3"
2004
+ },
2005
+ "engines": {
2006
+ "node": ">=12.0.0"
2007
+ },
2008
+ "funding": {
2009
+ "url": "https://github.com/sponsors/SuperchupuDev"
2010
+ }
2011
+ },
2012
+ "node_modules/typescript": {
2013
+ "version": "5.8.3",
2014
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
2015
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
2016
+ "dev": true,
2017
+ "license": "Apache-2.0",
2018
+ "bin": {
2019
+ "tsc": "bin/tsc",
2020
+ "tsserver": "bin/tsserver"
2021
+ },
2022
+ "engines": {
2023
+ "node": ">=14.17"
2024
+ }
2025
+ },
2026
+ "node_modules/undici-types": {
2027
+ "version": "6.21.0",
2028
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
2029
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
2030
+ "dev": true,
2031
+ "license": "MIT"
2032
+ },
2033
+ "node_modules/update-browserslist-db": {
2034
+ "version": "1.2.2",
2035
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
2036
+ "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
2037
+ "dev": true,
2038
+ "funding": [
2039
+ {
2040
+ "type": "opencollective",
2041
+ "url": "https://opencollective.com/browserslist"
2042
+ },
2043
+ {
2044
+ "type": "tidelift",
2045
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
2046
+ },
2047
+ {
2048
+ "type": "github",
2049
+ "url": "https://github.com/sponsors/ai"
2050
+ }
2051
+ ],
2052
+ "license": "MIT",
2053
+ "dependencies": {
2054
+ "escalade": "^3.2.0",
2055
+ "picocolors": "^1.1.1"
2056
+ },
2057
+ "bin": {
2058
+ "update-browserslist-db": "cli.js"
2059
+ },
2060
+ "peerDependencies": {
2061
+ "browserslist": ">= 4.21.0"
2062
+ }
2063
+ },
2064
+ "node_modules/use-sync-external-store": {
2065
+ "version": "1.6.0",
2066
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
2067
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
2068
+ "license": "MIT",
2069
+ "peerDependencies": {
2070
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2071
+ }
2072
+ },
2073
+ "node_modules/victory-vendor": {
2074
+ "version": "37.3.6",
2075
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
2076
+ "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==",
2077
+ "license": "MIT AND ISC",
2078
+ "dependencies": {
2079
+ "@types/d3-array": "^3.0.3",
2080
+ "@types/d3-ease": "^3.0.0",
2081
+ "@types/d3-interpolate": "^3.0.1",
2082
+ "@types/d3-scale": "^4.0.2",
2083
+ "@types/d3-shape": "^3.1.0",
2084
+ "@types/d3-time": "^3.0.0",
2085
+ "@types/d3-timer": "^3.0.0",
2086
+ "d3-array": "^3.1.6",
2087
+ "d3-ease": "^3.0.1",
2088
+ "d3-interpolate": "^3.0.1",
2089
+ "d3-scale": "^4.0.2",
2090
+ "d3-shape": "^3.1.0",
2091
+ "d3-time": "^3.0.0",
2092
+ "d3-timer": "^3.0.1"
2093
+ }
2094
+ },
2095
+ "node_modules/vite": {
2096
+ "version": "6.4.1",
2097
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
2098
+ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
2099
+ "dev": true,
2100
+ "license": "MIT",
2101
+ "dependencies": {
2102
+ "esbuild": "^0.25.0",
2103
+ "fdir": "^6.4.4",
2104
+ "picomatch": "^4.0.2",
2105
+ "postcss": "^8.5.3",
2106
+ "rollup": "^4.34.9",
2107
+ "tinyglobby": "^0.2.13"
2108
+ },
2109
+ "bin": {
2110
+ "vite": "bin/vite.js"
2111
+ },
2112
+ "engines": {
2113
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
2114
+ },
2115
+ "funding": {
2116
+ "url": "https://github.com/vitejs/vite?sponsor=1"
2117
+ },
2118
+ "optionalDependencies": {
2119
+ "fsevents": "~2.3.3"
2120
+ },
2121
+ "peerDependencies": {
2122
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
2123
+ "jiti": ">=1.21.0",
2124
+ "less": "*",
2125
+ "lightningcss": "^1.21.0",
2126
+ "sass": "*",
2127
+ "sass-embedded": "*",
2128
+ "stylus": "*",
2129
+ "sugarss": "*",
2130
+ "terser": "^5.16.0",
2131
+ "tsx": "^4.8.1",
2132
+ "yaml": "^2.4.2"
2133
+ },
2134
+ "peerDependenciesMeta": {
2135
+ "@types/node": {
2136
+ "optional": true
2137
+ },
2138
+ "jiti": {
2139
+ "optional": true
2140
+ },
2141
+ "less": {
2142
+ "optional": true
2143
+ },
2144
+ "lightningcss": {
2145
+ "optional": true
2146
+ },
2147
+ "sass": {
2148
+ "optional": true
2149
+ },
2150
+ "sass-embedded": {
2151
+ "optional": true
2152
+ },
2153
+ "stylus": {
2154
+ "optional": true
2155
+ },
2156
+ "sugarss": {
2157
+ "optional": true
2158
+ },
2159
+ "terser": {
2160
+ "optional": true
2161
+ },
2162
+ "tsx": {
2163
+ "optional": true
2164
+ },
2165
+ "yaml": {
2166
+ "optional": true
2167
+ }
2168
+ }
2169
+ },
2170
+ "node_modules/yallist": {
2171
+ "version": "3.1.1",
2172
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
2173
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
2174
+ "dev": true,
2175
+ "license": "ISC"
2176
+ }
2177
+ }
2178
+ }
package.json CHANGED
@@ -1,39 +1,23 @@
1
  {
2
- "name": "react-template",
3
- "version": "0.1.0",
4
  "private": true,
5
- "dependencies": {
6
- "@testing-library/dom": "^10.4.0",
7
- "@testing-library/jest-dom": "^6.6.3",
8
- "@testing-library/react": "^16.3.0",
9
- "@testing-library/user-event": "^13.5.0",
10
- "react": "^19.1.0",
11
- "react-dom": "^19.1.0",
12
- "react-scripts": "5.0.1",
13
- "web-vitals": "^2.1.4"
14
- },
15
  "scripts": {
16
- "start": "react-scripts start",
17
- "build": "react-scripts build",
18
- "test": "react-scripts test",
19
- "eject": "react-scripts eject"
20
  },
21
- "eslintConfig": {
22
- "extends": [
23
- "react-app",
24
- "react-app/jest"
25
- ]
26
  },
27
- "browserslist": {
28
- "production": [
29
- ">0.2%",
30
- "not dead",
31
- "not op_mini all"
32
- ],
33
- "development": [
34
- "last 1 chrome version",
35
- "last 1 firefox version",
36
- "last 1 safari version"
37
- ]
38
  }
39
  }
 
1
  {
2
+ "name": "openrouter-freescout",
 
3
  "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
 
 
 
 
 
 
 
 
6
  "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
 
10
  },
11
+ "dependencies": {
12
+ "react": "^19.2.1",
13
+ "react-dom": "^19.2.1",
14
+ "lucide-react": "^0.555.0",
15
+ "recharts": "^3.5.1"
16
  },
17
+ "devDependencies": {
18
+ "@types/node": "^22.14.0",
19
+ "@vitejs/plugin-react": "^5.0.0",
20
+ "typescript": "~5.8.2",
21
+ "vite": "^6.2.0"
 
 
 
 
 
 
22
  }
23
  }
tsconfig.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "experimentalDecorators": true,
5
+ "useDefineForClassFields": false,
6
+ "module": "ESNext",
7
+ "lib": [
8
+ "ES2022",
9
+ "DOM",
10
+ "DOM.Iterable"
11
+ ],
12
+ "skipLibCheck": true,
13
+ "types": [
14
+ "node"
15
+ ],
16
+ "moduleResolution": "bundler",
17
+ "isolatedModules": true,
18
+ "moduleDetection": "force",
19
+ "allowJs": true,
20
+ "jsx": "react-jsx",
21
+ "paths": {
22
+ "@/*": [
23
+ "./*"
24
+ ]
25
+ },
26
+ "allowImportingTsExtensions": true,
27
+ "noEmit": true
28
+ }
29
+ }
types.ts ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface OpenRouterPricing {
2
+ prompt: string;
3
+ completion: string;
4
+ request: string;
5
+ image: string;
6
+ }
7
+
8
+ export interface OpenRouterModel {
9
+ id: string;
10
+ name: string;
11
+ description: string;
12
+ pricing: OpenRouterPricing;
13
+ context_length: number;
14
+ architecture: {
15
+ modality: string;
16
+ tokenizer: string;
17
+ instruct_type: string | null;
18
+ };
19
+ top_provider: {
20
+ context_length: number | null;
21
+ max_completion_tokens: number | null;
22
+ is_moderated: boolean;
23
+ };
24
+ created?: number;
25
+ }
26
+
27
+ export interface ModelTestResult {
28
+ modelId: string;
29
+ status: 'pending' | 'running' | 'success' | 'error';
30
+ // Test 1
31
+ latencyMs: number;
32
+ tokensPerSecond: number;
33
+ // Test 2 (Second answer)
34
+ latencyMs2: number;
35
+ tokensPerSecond2: number;
36
+
37
+ errorMsg?: string;
38
+ timestamp: number;
39
+ }
40
+
41
+ export type SortOption = 'name' | 'latency' | 'throughput' | 'context' | 'newest';
42
+
43
+ export interface AppState {
44
+ apiKey: string;
45
+ allModels: OpenRouterModel[];
46
+ freeModels: OpenRouterModel[];
47
+ testResults: Record<string, ModelTestResult>;
48
+ isTesting: boolean;
49
+ progress: number;
50
+ viewMode: 'list' | 'test';
51
+ }
vite.config.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import path from 'path';
2
+ import { defineConfig, loadEnv } from 'vite';
3
+ import react from '@vitejs/plugin-react';
4
+
5
+ export default defineConfig(({ mode }) => {
6
+ const env = loadEnv(mode, '.', '');
7
+ return {
8
+ server: {
9
+ port: 3000,
10
+ host: '0.0.0.0',
11
+ },
12
+ plugins: [react()],
13
+ define: {
14
+ 'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
15
+ 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
16
+ },
17
+ resolve: {
18
+ alias: {
19
+ '@': path.resolve(__dirname, '.'),
20
+ }
21
+ }
22
+ };
23
+ });