idgmatrix commited on
Commit
830f840
·
verified ·
1 Parent(s): e81263e

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +540 -19
index.html CHANGED
@@ -1,19 +1,540 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ko">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>DEX AMM Visualizer | Crypto Math</title>
7
+
8
+ <!-- External Libraries -->
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
11
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
12
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
13
+
14
+ <style>
15
+ :root {
16
+ --bg-color: #0f172a;
17
+ --card-bg: #1e293b;
18
+ --accent-primary: #6366f1;
19
+ --accent-secondary: #ec4899;
20
+ --text-primary: #f8fafc;
21
+ --text-secondary: #94a3b8;
22
+ --success: #10b981;
23
+ --danger: #ef4444;
24
+ }
25
+
26
+ body {
27
+ font-family: 'Inter', sans-serif;
28
+ background-color: var(--bg-color);
29
+ color: var(--text-primary);
30
+ overflow-x: hidden;
31
+ }
32
+
33
+ /* Custom Scrollbar */
34
+ ::-webkit-scrollbar {
35
+ width: 8px;
36
+ }
37
+ ::-webkit-scrollbar-track {
38
+ background: var(--bg-color);
39
+ }
40
+ ::-webkit-scrollbar-thumb {
41
+ background: var(--card-bg);
42
+ border-radius: 4px;
43
+ }
44
+ ::-webkit-scrollbar-thumb:hover {
45
+ background: var(--accent-primary);
46
+ }
47
+
48
+ /* Glassmorphism Cards */
49
+ .glass-card {
50
+ background: rgba(30, 41, 59, 0.7);
51
+ backdrop-filter: blur(12px);
52
+ -webkit-backdrop-filter: blur(12px);
53
+ border: 1px solid rgba(255, 255, 255, 0.05);
54
+ border-radius: 16px;
55
+ box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3);
56
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
57
+ }
58
+
59
+ .glass-card:hover {
60
+ box-shadow: 0 10px 40px rgba(99, 102, 241, 0.1);
61
+ }
62
+
63
+ /* Inputs */
64
+ .custom-input {
65
+ background: rgba(15, 23, 42, 0.6);
66
+ border: 1px solid rgba(148, 163, 184, 0.2);
67
+ color: var(--text-primary);
68
+ transition: all 0.3s ease;
69
+ }
70
+ .custom-input:focus {
71
+ outline: none;
72
+ border-color: var(--accent-primary);
73
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
74
+ }
75
+
76
+ /* Range Slider */
77
+ input[type=range] {
78
+ -webkit-appearance: none;
79
+ background: transparent;
80
+ }
81
+ input[type=range]::-webkit-slider-thumb {
82
+ -webkit-appearance: none;
83
+ height: 20px;
84
+ width: 20px;
85
+ border-radius: 50%;
86
+ background: var(--accent-primary);
87
+ cursor: pointer;
88
+ margin-top: -8px;
89
+ box-shadow: 0 0 10px rgba(99, 102, 241, 0.5);
90
+ }
91
+ input[type=range]::-webkit-slider-runnable-track {
92
+ width: 100%;
93
+ height: 4px;
94
+ cursor: pointer;
95
+ background: var(--card-bg);
96
+ border-radius: 2px;
97
+ }
98
+
99
+ /* Animations */
100
+ @keyframes pulse-glow {
101
+ 0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.4); }
102
+ 70% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
103
+ 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
104
+ }
105
+ .animate-swap {
106
+ animation: pulse-glow 1s infinite;
107
+ }
108
+
109
+ .formula-text {
110
+ font-family: 'Courier New', monospace;
111
+ }
112
+
113
+ .gradient-text {
114
+ background: linear-gradient(135deg, #6366f1 0%, #ec4899 100%);
115
+ -webkit-background-clip: text;
116
+ -webkit-text-fill-color: transparent;
117
+ }
118
+ </style>
119
+ </head>
120
+ <body class="min-h-screen flex flex-col">
121
+
122
+ <!-- Header -->
123
+ <header class="w-full py-4 px-6 border-b border-slate-800 flex justify-between items-center bg-slate-900/80 backdrop-blur-md sticky top-0 z-50">
124
+ <div class="flex items-center gap-3">
125
+ <div class="w-10 h-10 rounded-lg bg-gradient-to-br from-indigo-500 to-pink-500 flex items-center justify-center text-white font-bold text-xl">
126
+ <i class="fa-solid fa-shuffle"></i>
127
+ </div>
128
+ <h1 class="text-xl font-bold tracking-tight">DEX <span class="font-light text-slate-400">Simulator</span></h1>
129
+ </div>
130
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-sm font-medium text-slate-400 hover:text-indigo-400 transition-colors flex items-center gap-2">
131
+ Built with anycoder <i class="fa-solid fa-arrow-up-right-from-square text-xs"></i>
132
+ </a>
133
+ </header>
134
+
135
+ <!-- Main Content -->
136
+ <main class="flex-grow container mx-auto px-4 py-8 grid grid-cols-1 lg:grid-cols-12 gap-8">
137
+
138
+ <!-- Left Column: Controls & Swap -->
139
+ <div class="lg:col-span-4 flex flex-col gap-6">
140
+
141
+ <!-- Pool Configuration -->
142
+ <section class="glass-card p-6 relative overflow-hidden group">
143
+ <div class="absolute top-0 right-0 w-32 h-32 bg-indigo-500/10 rounded-full blur-3xl -mr-16 -mt-16 pointer-events-none"></div>
144
+
145
+ <h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
146
+ <i class="fa-solid fa-database text-indigo-400"></i> 유동성 풀 설정 (Liquidity Pool)
147
+ </h2>
148
+
149
+ <div class="space-y-4">
150
+ <div>
151
+ <label class="block text-xs uppercase font-bold text-slate-500 mb-1 tracking-wider">Token A (Reserve X)</label>
152
+ <div class="flex items-center gap-2">
153
+ <span class="text-2xl">🍎</span>
154
+ <input type="number" id="reserveA" value="1000" class="custom-input w-full p-3 rounded-lg font-mono text-lg" oninput="updateSimulation()">
155
+ </div>
156
+ </div>
157
+
158
+ <div>
159
+ <label class="block text-xs uppercase font-bold text-slate-500 mb-1 tracking-wider">Token B (Reserve Y)</label>
160
+ <div class="flex items-center gap-2">
161
+ <span class="text-2xl">🍌</span>
162
+ <input type="number" id="reserveB" value="4000" class="custom-input w-full p-3 rounded-lg font-mono text-lg" oninput="updateSimulation()">
163
+ </div>
164
+ </div>
165
+ </div>
166
+
167
+ <div class="mt-6 p-4 bg-slate-900/50 rounded-lg border border-slate-700/50">
168
+ <div class="flex justify-between text-sm mb-1">
169
+ <span class="text-slate-400">Constant Product (k):</span>
170
+ <span id="constantK" class="font-mono text-indigo-300">4,000,000</span>
171
+ </div>
172
+ <div class="flex justify-between text-sm">
173
+ <span class="text-slate-400">Current Price (A/B):</span>
174
+ <span id="spotPrice" class="font-mono text-emerald-400">1 A = 4.00 B</span>
175
+ </div>
176
+ </div>
177
+ </section>
178
+
179
+ <!-- Swap Interface -->
180
+ <section class="glass-card p-6 border-t-4 border-t-pink-500">
181
+ <h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
182
+ <i class="fa-solid fa-right-left text-pink-500"></i> 토큰 교환 (Swap)
183
+ </h2>
184
+
185
+ <div class="relative">
186
+ <div class="bg-slate-800/50 p-4 rounded-xl border border-slate-700 transition-colors focus-within:border-pink-500/50">
187
+ <div class="flex justify-between mb-2">
188
+ <label class="text-xs text-slate-400">지불할 금액 (You Pay)</label>
189
+ <span class="text-xs text-slate-500">Token A</span>
190
+ </div>
191
+ <div class="flex items-center gap-3">
192
+ <input type="number" id="swapInput" value="0" class="bg-transparent text-2xl font-bold w-full outline-none text-white placeholder-slate-600" placeholder="0.0">
193
+ <div class="bg-slate-700 px-2 py-1 rounded text-sm font-bold flex items-center gap-1">
194
+ 🍎 A
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <div class="absolute left-1/2 -translate-x-1/2 -translate-y-1/2 z-10">
200
+ <div class="bg-slate-800 border border-slate-700 p-2 rounded-full shadow-xl text-slate-400">
201
+ <i class="fa-solid fa-arrow-down"></i>
202
+ </div>
203
+ </div>
204
+
205
+ <div class="bg-slate-800/50 p-4 rounded-xl border border-slate-700 mt-2">
206
+ <div class="flex justify-between mb-2">
207
+ <label class="text-xs text-slate-400">받을 금액 (You Receive)</label>
208
+ <span class="text-xs text-slate-500">Token B</span>
209
+ </div>
210
+ <div class="flex items-center gap-3">
211
+ <input type="text" id="swapOutput" readonly class="bg-transparent text-2xl font-bold w-full outline-none text-emerald-400" value="0.00">
212
+ <div class="bg-slate-700 px-2 py-1 rounded text-sm font-bold flex items-center gap-1">
213
+ 🍌 B
214
+ </div>
215
+ </div>
216
+ </div>
217
+ </div>
218
+
219
+ <div class="mt-4 space-y-2">
220
+ <label class="text-xs text-slate-400">빠른 입력 (Slider)</label>
221
+ <input type="range" id="swapSlider" min="0" max="500" value="0" class="w-full" oninput="syncSlider()">
222
+ </div>
223
+ </section>
224
+
225
+ </div>
226
+
227
+ <!-- Right Column: Visualization & Stats -->
228
+ <div class="lg:col-span-8 flex flex-col gap-6">
229
+
230
+ <!-- Chart Section -->
231
+ <section class="glass-card p-6 h-[400px] flex flex-col relative">
232
+ <div class="flex justify-between items-center mb-4">
233
+ <h2 class="text-lg font-semibold flex items-center gap-2">
234
+ <i class="fa-solid fa-chart-line text-emerald-400"></i> AMM Curve (x * y = k)
235
+ </h2>
236
+ <div class="text-xs bg-slate-800 px-3 py-1 rounded-full text-slate-400 border border-slate-700">
237
+ Interactive Visualization
238
+ </div>
239
+ </div>
240
+ <div class="flex-grow relative w-full h-full">
241
+ <canvas id="ammChart"></canvas>
242
+ </div>
243
+ </section>
244
+
245
+ <!-- Formula & Impact Details -->
246
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
247
+
248
+ <!-- Mathematical Breakdown -->
249
+ <section class="glass-card p-6">
250
+ <h3 class="text-sm font-bold text-slate-400 uppercase mb-4 tracking-wider">수학적 공식 (The Math)</h3>
251
+
252
+ <div class="space-y-4 text-sm">
253
+ <div class="flex items-center gap-3 p-3 bg-slate-900/50 rounded-lg">
254
+ <div class="w-8 h-8 rounded-full bg-indigo-500/20 flex items-center justify-center text-indigo-400 font-serif font-bold">1</div>
255
+ <div>
256
+ <div class="text-slate-400 text-xs">불변 상수 (Constant Product)</div>
257
+ <div class="font-mono text-white"><span id="mathX">1000</span> × <span id="mathY">4000</span> = <span id="mathK">4M</span></div>
258
+ </div>
259
+ </div>
260
+
261
+ <div class="flex items-center gap-3 p-3 bg-slate-900/50 rounded-lg">
262
+ <div class="w-8 h-8 rounded-full bg-pink-500/20 flex items-center justify-center text-pink-400 font-serif font-bold">2</div>
263
+ <div>
264
+ <div class="text-slate-400 text-xs">새로운 Reserve X (New X)</div>
265
+ <div class="font-mono text-white"><span id="mathOldX">1000</span> + <span id="mathDeltaX" class="text-indigo-400">0</span> = <span id="mathNewX">1000</span></div>
266
+ </div>
267
+ </div>
268
+
269
+ <div class="flex items-center gap-3 p-3 bg-slate-900/50 rounded-lg">
270
+ <div class="w-8 h-8 rounded-full bg-emerald-500/20 flex items-center justify-center text-emerald-400 font-serif font-bold">3</div>
271
+ <div>
272
+ <div class="text-slate-400 text-xs">받게 될 Token B (Output)</div>
273
+ <div class="font-mono text-white">dy = Y - (k / NewX)</div>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </section>
278
+
279
+ <!-- Trade Statistics -->
280
+ <section class="glass-card p-6">
281
+ <h3 class="text-sm font-bold text-slate-400 uppercase mb-4 tracking-wider">거래 분석 (Analysis)</h3>
282
+
283
+ <div class="space-y-4">
284
+ <div class="flex justify-between items-center border-b border-slate-700 pb-3">
285
+ <span class="text-slate-400 text-sm">실행 가격 (Execution Price)</span>
286
+ <div class="text-right">
287
+ <div id="execPrice" class="font-bold text-white">0.00</div>
288
+ <div class="text-xs text-slate-500">B per A</div>
289
+ </div>
290
+ </div>
291
+
292
+ <div class="flex justify-between items-center border-b border-slate-700 pb-3">
293
+ <span class="text-slate-400 text-sm flex items-center gap-1">
294
+ 가격 영향 (Price Impact)
295
+ <i class="fa-solid fa-circle-info text-[10px] text-slate-600"></i>
296
+ </span>
297
+ <div class="text-right">
298
+ <div id="priceImpact" class="font-bold text-emerald-400">0.00%</div>
299
+ </div>
300
+ </div>
301
+
302
+ <div class="flex justify-between items-center">
303
+ <span class="text-slate-400 text-sm">풀 상태 변화 (Pool Share)</span>
304
+ <div class="w-24 h-2 bg-slate-700 rounded-full overflow-hidden">
305
+ <div id="poolBar" class="h-full bg-indigo-500 transition-all duration-300" style="width: 50%"></div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+
310
+ <div id="warningMsg" class="hidden mt-4 p-3 bg-red-500/10 border border-red-500/20 rounded text-red-400 text-xs flex items-start gap-2">
311
+ <i class="fa-solid fa-triangle-exclamation mt-0.5"></i>
312
+ <span>유동성에 비해 주문 금액이 너무 큽니다. 슬리피지가 매우 높습니다.</span>
313
+ </div>
314
+ </section>
315
+ </div>
316
+
317
+ </div>
318
+ </main>
319
+
320
+ <!-- JavaScript Logic -->
321
+ <script>
322
+ // Global Variables
323
+ let chartInstance = null;
324
+
325
+ // DOM Elements
326
+ const els = {
327
+ resA: document.getElementById('reserveA'),
328
+ resB: document.getElementById('reserveB'),
329
+ inp: document.getElementById('swapInput'),
330
+ out: document.getElementById('swapOutput'),
331
+ slider: document.getElementById('swapSlider'),
332
+ constK: document.getElementById('constantK'),
333
+ spotPrice: document.getElementById('spotPrice'),
334
+ mathX: document.getElementById('mathX'),
335
+ mathY: document.getElementById('mathY'),
336
+ mathK: document.getElementById('mathK'),
337
+ mathOldX: document.getElementById('mathOldX'),
338
+ mathDeltaX: document.getElementById('mathDeltaX'),
339
+ mathNewX: document.getElementById('mathNewX'),
340
+ execPrice: document.getElementById('execPrice'),
341
+ priceImpact: document.getElementById('priceImpact'),
342
+ warning: document.getElementById('warningMsg'),
343
+ poolBar: document.getElementById('poolBar')
344
+ };
345
+
346
+ // Initialization
347
+ window.onload = () => {
348
+ initChart();
349
+ updateSimulation();
350
+
351
+ // Event Listeners
352
+ els.inp.addEventListener('input', () => {
353
+ els.slider.value = els.inp.value;
354
+ updateSimulation();
355
+ });
356
+ };
357
+
358
+ function syncSlider() {
359
+ els.inp.value = els.slider.value;
360
+ updateSimulation();
361
+ }
362
+
363
+ function formatNum(num, decimals = 2) {
364
+ return parseFloat(num).toLocaleString('en-US', {
365
+ minimumFractionDigits: decimals,
366
+ maximumFractionDigits: decimals
367
+ });
368
+ }
369
+
370
+ function initChart() {
371
+ const ctx = document.getElementById('ammChart').getContext('2d');
372
+
373
+ // Chart.js Configuration
374
+ chartInstance = new Chart(ctx, {
375
+ type: 'line',
376
+ data: {
377
+ datasets: [
378
+ {
379
+ label: 'Bonding Curve (k=const)',
380
+ data: [],
381
+ borderColor: '#6366f1',
382
+ borderWidth: 2,
383
+ pointRadius: 0,
384
+ fill: false,
385
+ tension: 0.4
386
+ },
387
+ {
388
+ label: 'Current State',
389
+ data: [],
390
+ backgroundColor: '#10b981',
391
+ borderColor: '#fff',
392
+ borderWidth: 2,
393
+ pointRadius: 6,
394
+ pointHoverRadius: 8
395
+ },
396
+ {
397
+ label: 'New State',
398
+ data: [],
399
+ backgroundColor: '#ec4899',
400
+ borderColor: '#fff',
401
+ borderWidth: 2,
402
+ pointRadius: 6,
403
+ pointHoverRadius: 8
404
+ }
405
+ ]
406
+ },
407
+ options: {
408
+ responsive: true,
409
+ maintainAspectRatio: false,
410
+ interaction: {
411
+ intersect: false,
412
+ mode: 'index',
413
+ },
414
+ plugins: {
415
+ legend: {
416
+ labels: { color: '#94a3b8' }
417
+ },
418
+ tooltip: {
419
+ backgroundColor: 'rgba(15, 23, 42, 0.9)',
420
+ titleColor: '#fff',
421
+ bodyColor: '#cbd5e1',
422
+ borderColor: 'rgba(255,255,255,0.1)',
423
+ borderWidth: 1
424
+ }
425
+ },
426
+ scales: {
427
+ x: {
428
+ type: 'linear',
429
+ title: { display: true, text: 'Reserve A (🍎)', color: '#64748b' },
430
+ grid: { color: 'rgba(255, 255, 255, 0.05)' },
431
+ ticks: { color: '#64748b' }
432
+ },
433
+ y: {
434
+ title: { display: true, text: 'Reserve B (🍌)', color: '#64748b' },
435
+ grid: { color: 'rgba(255, 255, 255, 0.05)' },
436
+ ticks: { color: '#64748b' }
437
+ }
438
+ }
439
+ }
440
+ });
441
+ }
442
+
443
+ function updateSimulation() {
444
+ // 1. Get Values
445
+ const x = parseFloat(els.resA.value) || 1;
446
+ const y = parseFloat(els.resB.value) || 1;
447
+ const dx = parseFloat(els.inp.value) || 0;
448
+
449
+ // 2. Calculate Constant Product
450
+ const k = x * y;
451
+
452
+ // 3. Calculate Swap
453
+ // Formula: (x + dx)(y - dy) = k
454
+ // y - dy = k / (x + dx)
455
+ // dy = y - k / (x + dx)
456
+
457
+ const newX = x + dx;
458
+ const newY = k / newX;
459
+ const dy = y - newY;
460
+
461
+ // 4. Update UI Texts
462
+ els.constK.innerText = formatNum(k, 0);
463
+ els.out.value = dx > 0 ? formatNum(dy, 4) : "0.00";
464
+
465
+ // Spot Price (Current Market Price) = y / x
466
+ const spotPrice = y / x;
467
+ els.spotPrice.innerText = `1 A = ${formatNum(spotPrice, 4)} B`;
468
+
469
+ // Execution Price = dy / dx
470
+ const execPrice = dx > 0 ? dy / dx : 0;
471
+ els.execPrice.innerText = dx > 0 ? formatNum(execPrice, 4) : "0.00";
472
+
473
+ // Price Impact = (Spot Price - Execution Price) / Spot Price * 100
474
+ let impact = 0;
475
+ if (dx > 0) {
476
+ impact = ((spotPrice - execPrice) / spotPrice) * 100;
477
+ }
478
+
479
+ // Color code impact
480
+ const impactEl = els.priceImpact;
481
+ impactEl.innerText = `${formatNum(impact, 2)}%`;
482
+ if(impact < 1) impactEl.className = "font-bold text-emerald-400";
483
+ else if(impact < 5) impactEl.className = "font-bold text-yellow-400";
484
+ else impactEl.className = "font-bold text-red-500";
485
+
486
+ // Warning
487
+ if(impact > 15) els.warning.classList.remove('hidden');
488
+ else els.warning.classList.add('hidden');
489
+
490
+ // Math Breakdown Update
491
+ els.mathX.innerText = formatNum(x, 0);
492
+ els.mathY.innerText = formatNum(y, 0);
493
+ els.mathK.innerText = formatNum(k, 0);
494
+ els.mathOldX.innerText = formatNum(x, 0);
495
+ els.mathDeltaX.innerText = formatNum(dx, 2);
496
+ els.mathNewX.innerText = formatNum(newX, 2);
497
+
498
+ // Pool Bar Visual
499
+ const totalVal = newX + newY; // Simplistic visualization
500
+ const percent = (newX / (newX + newY)) * 100; // Just showing ratio shift
501
+ // Actually, let's show price impact severity on bar
502
+ els.poolBar.style.width = `${Math.min(impact * 5, 100)}%`;
503
+ els.poolBar.className = `h-full transition-all duration-300 ${impact > 5 ? 'bg-red-500' : 'bg-indigo-500'}`;
504
+
505
+
506
+ // 5. Update Chart
507
+ updateChartData(x, y, newX, newY, k);
508
+ }
509
+
510
+ function updateChartData(x, y, newX, newY, k) {
511
+ const dataPoints = [];
512
+
513
+ // Determine range for chart (zoom out slightly based on trade)
514
+ const startX = x * 0.5;
515
+ const endX = Math.max(x * 1.5, newX * 1.2);
516
+ const steps = 50;
517
+
518
+ for (let i = 0; i <= steps; i++) {
519
+ const curX = startX + (endX - startX) * (i / steps);
520
+ const curY = k / curX;
521
+ dataPoints.push({ x: curX, y: curY });
522
+ }
523
+
524
+ chartInstance.data.datasets[0].data = dataPoints;
525
+
526
+ // Current Point (Start)
527
+ chartInstance.data.datasets[1].data = [{ x: x, y: y }];
528
+
529
+ // New Point (End) - Only if swapping
530
+ if (Math.abs(newX - x) > 0.001) {
531
+ chartInstance.data.datasets[2].data = [{ x: newX, y: newY }];
532
+ } else {
533
+ chartInstance.data.datasets[2].data = [];
534
+ }
535
+
536
+ chartInstance.update('none'); // 'none' for performance
537
+ }
538
+ </script>
539
+ </body>
540
+ </html>