<?php
require_once '../config/config.php';
// Installation check removed
require_once '../config/database.php';
require_once '../includes/functions.php';
if (!isset($_SESSION['user_id'])) { header('Location: login.php'); exit; }
$userId = $_SESSION['user_id'];
$user = dbFetch("SELECT * FROM users WHERE id = ?", [$userId]);
if (!$user || $user['status'] !== 'active') { session_destroy(); header('Location: login.php'); exit; }
$userName = trim(($user['first_name'] ?? '') . ' ' . ($user['last_name'] ?? ''));
if (empty($userName)) $userName = 'User';
$userInitials = strtoupper(substr($user['first_name'] ?? 'U', 0, 1) . substr($user['last_name'] ?? '', 0, 1));
$siteSettings = [];
try { $rows = dbFetchAll("SELECT setting_key, setting_value FROM settings"); foreach ($rows as $row) $siteSettings[$row['setting_key']] = $row['setting_value']; } catch (Exception $e) {}
$siteName = $siteSettings['site_name'] ?? 'BinaryPro';
$minTradeAmount = (int)($siteSettings['min_trade_amount'] ?? $siteSettings['min_trade'] ?? 10);
$maxTradeAmount = (int)($siteSettings['max_trade_amount'] ?? $siteSettings['max_trade'] ?? 50000);
$maxSimTrades = (int)($siteSettings['max_simultaneous_trades'] ?? 10);
$minCfdMul = (int)($siteSettings['min_cfd_multiplier'] ?? 1);
$maxCfdMul = (int)($siteSettings['max_cfd_multiplier'] ?? 1000);
$defaultCfdMul = (int)($siteSettings['default_cfd_multiplier'] ?? 1);
$accountType = $_GET['account'] ?? ($_SESSION['account_type'] ?? 'demo');
$_SESSION['account_type'] = $accountType;
$isDemo = ($accountType === 'demo') ? 1 : 0;
$currency = $siteSettings['currency_symbol'] ?? '₹';
$wallet = dbFetch("SELECT * FROM user_wallets WHERE user_id = ?", [$userId]);
if (!$wallet) {
    $demoBalance = (float)($siteSettings['demo_balance'] ?? 10000);
    dbQuery("INSERT INTO user_wallets (user_id, balance, demo_balance) VALUES (?, 0, ?)", [$userId, $demoBalance]);
    $wallet = ['balance' => 0, 'demo_balance' => $demoBalance];
}
$pendingData = dbFetch("SELECT COALESCE(SUM(amount), 0) as total FROM withdrawals WHERE user_id = ? AND status = 'pending'", [$userId]);
$pendingAmount = (float)($pendingData['total'] ?? 0);
$userBalance = max(0, (float)($wallet['balance'] ?? 0) + (float)($wallet['bonus_balance'] ?? 0) - $pendingAmount);
$userDemoBalance = (float)($wallet['demo_balance'] ?? 10000);
$assets = [];
try { $assets = dbFetchAll("SELECT * FROM assets WHERE is_active = 1 ORDER BY sort_order"); } catch (Exception $e) {}
if (empty($assets)) {
    $assets = [
        ['id'=>1,'symbol'=>'BTCUSDT','name'=>'Bitcoin','payout_percent'=>85,'icon_color'=>'#f7931a','asset_type'=>'crypto'],
        ['id'=>2,'symbol'=>'ETHUSDT','name'=>'Ethereum','payout_percent'=>82,'icon_color'=>'#627eea','asset_type'=>'crypto'],
        ['id'=>3,'symbol'=>'CRYPTO_IDX','name'=>'Crypto IDX','payout_percent'=>84,'icon_color'=>'#8b5cf6','asset_type'=>'crypto']
    ];
}
$assetsJson = json_encode($assets);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>Trade - <?php echo htmlspecialchars($siteName); ?></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root{--bg:#0d1117;--bg2:#161b22;--bg3:#21262d;--bg4:#30363d;--text:#f0f6fc;--text2:#8b949e;--border:#30363d;--green:#26a69a;--red:#ef5350;--yellow:#ffc107;--blue:#2196f3}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden;font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text)}
.app{display:flex;flex-direction:column;height:100vh;height:100dvh}
.main-row{display:flex;flex:1;overflow:hidden}
.chart-col{flex:1;display:flex;flex-direction:column;min-width:0}
.right-col{width:320px;display:flex;flex-direction:column;border-left:1px solid var(--border);background:var(--bg2);overflow-y:auto}
.hdr{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:linear-gradient(90deg,#1a1a2e,#16213e);border-bottom:1px solid var(--border);flex-shrink:0;min-height:50px}
.hdr-left{display:flex;align-items:center;gap:8px}
.hbtn{width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,.1);border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1rem}
.hbtn.yel{background:#ffc107;color:#000}
.acc-box{padding:6px 14px;background:rgba(255,255,255,.08);border-radius:10px;cursor:pointer;text-align:center;position:relative;transition:background .2s}
.acc-box:hover{background:rgba(255,255,255,.14)}
.acc-type{font-size:.65rem;color:rgba(255,255,255,.6);letter-spacing:.5px;display:flex;align-items:center;justify-content:center;gap:4px}
.acc-type .arrow{font-size:.5rem;transition:transform .2s}
.acc-dd.show ~ .acc-type .arrow,.acc-box.open .acc-type .arrow{transform:rotate(180deg)}
.acc-bal{font-size:1.05rem;font-weight:700}
.acc-dd{position:absolute;top:calc(100% + 10px);right:-10px;background:var(--bg2);border:1px solid var(--border);border-radius:12px;width:240px;z-index:1100;display:none;box-shadow:0 12px 40px rgba(0,0,0,.6);overflow:hidden;animation:ddFadeIn .15s ease}
@keyframes ddFadeIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
.acc-dd::before{content:'';position:absolute;top:-6px;right:24px;width:12px;height:12px;background:var(--bg2);border-left:1px solid var(--border);border-top:1px solid var(--border);transform:rotate(45deg);z-index:1}
.acc-dd.show{display:block}
.acc-opt{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;color:#fff;text-decoration:none;border-bottom:1px solid var(--border);transition:background .15s;gap:10px}
.acc-opt:last-child{border-bottom:none}
.acc-opt:hover{background:rgba(255,255,255,.06)}
.acc-opt.active{background:rgba(38,166,154,.1);border-left:3px solid var(--green)}
.acc-badge{padding:4px 12px;border-radius:6px;font-size:.7rem;font-weight:700;letter-spacing:.5px;min-width:50px;text-align:center}
.acc-badge.d{background:var(--green);color:#000}.acc-badge.l{background:var(--red);color:#fff}
.acc-opt span:last-child{font-weight:600;font-size:.9rem}
.hdr-right{display:flex;gap:6px}
.pbtn{width:36px;height:36px;border-radius:50%;background:#6b4423;border:2px solid #ffc107;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:.7rem;font-weight:700}
.asel-tabs{display:flex; gap:6px; align-items:center; overflow-x:auto; transition: max-height 0.3s ease; position:relative;}
.asel-tabs::-webkit-scrollbar{display:none;}
.asel-tab{display:flex; align-items:center; gap:8px; padding:6px 12px; background:var(--bg3); border:1px solid var(--border); border-radius:8px; cursor:pointer; color:var(--text2); min-width:120px; position:relative; user-select:none;}
.asel-tab.on{background:var(--bg4); border-color:var(--yellow); color:#fff;}
.asel-tab:hover{background:var(--bg4);}
.asel-tab .aicon{width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:.6rem; font-weight:700; color:#fff;}
.asel-tab .aname{font-weight:600; font-size:.8rem; flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.asel-tab .cls-tab{width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:rgba(0,0,0,0.2); color:var(--text2); border:none; cursor:pointer;}
.asel-tab .cls-tab:hover{background:var(--red); color:#fff;}
.asel-dd-icon{display:none; margin-left: auto; font-size: 0.8rem;}

@media(max-width:768px) and (orientation:portrait){
    .hdr-left {
        flex-wrap: nowrap; 
        overflow: visible !important; 
        justify-content: flex-start; /* Align everything to the left */
        align-items: center;
        gap: 6px; /* Reduced gap */
    }
    .hbtn#menuBtn {
        order: 1 !important;
        margin-right: 0 !important;
        flex-shrink: 0 !important;
        min-width: 32px !important;
    }
    .hbtn#addChartBtn {
        order: 3 !important;
        margin-left: 2px !important;
        flex-shrink: 0 !important;
        min-width: 32px !important;
    } 
    
    .asel-tabs {
        order: 2 !important;
        margin: 0 4px !important; 
        flex-direction: column !important; 
        align-items: flex-start; /* Align dropdown items to the left */
        gap: 2px;
        background: transparent;
        border: none;
        padding: 0;
        position: relative;
        overflow: visible;
        flex: 1 1 auto; /* Take all available space and allow shrinking */
        min-width: 0; /* Allow the flex item to shrink smaller than content */
    }
    
    /* When open, show dropdown style */
    .asel-tabs.open {
        background: var(--bg2);
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 4px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.5);
        position: absolute;
        top: 100%;
        left: 44px; /* Align it roughly under the tab itself, avoiding the menu button */
        z-index: 1050;
        width: 200px;
    }
    
    .mobile-asel-active { display: none !important; } 
    
    /* The tabs themselves */
    .asel-tab {
        width: auto;
        display: none; 
        border-color: transparent; 
        background: transparent;
        padding: 4px 10px; 
        min-width: 0;
    }
    
    .asel-tabs.open .asel-tab {
        display: flex; 
        width: 100%; /* Full width of dropdown */
    }
    
    /* The active tab */
    .asel-tab.on {
        display: flex; 
        background: var(--bg3); 
        border: 1px solid var(--border);
        border-radius: 20px;
        color: #fff;
    }
    
    .asel-tabs.open .asel-tab.on {
        background: rgba(255,193,7,0.1); 
        border-color: transparent;
        border-radius: 8px;
    }
    
    /* Compact name inside active tab when not expanded */
    .asel-tab.on:not(.open-view) .aname {
        max-width: 100px; 
        font-size: 0.8rem;
    }
    
    .asel-tab.on:not(.open-view) .asel-dd-icon {
        display: block; 
        margin-left: 6px;
    }
    
    .asel-tabs.open .asel-tab .asel-dd-icon {
        display: none; 
    }
    
    .hdr { padding: 6px 4px; }
    .hdr-right { gap: 4px; flex-shrink: 0; }
    .acc-box { padding: 4px 6px; }
    .acc-type { display: none !important; }
    .acc-bal { font-size: 0.9rem; }
    .hbtn { width: 32px; height: 32px; font-size: 0.9rem; min-width: 32px; }
    .pbtn { width: 32px; height: 32px; font-size: 0.65rem; min-width: 32px; flex-shrink: 0; }
}
.chart-wrap{flex:1;position:relative;min-height:200px;background:var(--bg)}
#tv_chart{position:absolute;inset:0}
#drawCanvas{position:absolute;top:0;left:0;z-index:90;pointer-events:none}
#drawCanvas.on{pointer-events:auto;cursor:crosshair}
.dline{position:absolute;left:0;right:60px;height:28px;display:none;align-items:center;z-index:100;user-select:none}
.dline.on{display:flex}
.dline .tag{padding:3px 8px;font-size:.7rem;font-weight:700;border-radius:4px;white-space:nowrap;display:flex;align-items:center;gap:4px}
.dline .dsh{flex:1;height:2px;margin:0 6px}
.dline .hnd{font-size:.6rem;padding:2px 6px;background:rgba(0,0,0,.6);border-radius:3px;color:#fff;cursor:ns-resize}
.dline.tp .tag{background:var(--green);color:#fff}
.dline.tp .dsh{background:repeating-linear-gradient(90deg,var(--green),var(--green) 6px,transparent 6px,transparent 12px)}
.dline.sl .tag{background:var(--red);color:#fff}
.dline.sl .dsh{background:repeating-linear-gradient(90deg,var(--red),var(--red) 6px,transparent 6px,transparent 12px)}
.dline.en .tag{background:var(--yellow);color:#000}
.dline.en .dsh{background:repeating-linear-gradient(90deg,var(--yellow),var(--yellow) 8px,transparent 8px,transparent 14px)}
.dline.en .hnd{display:none}
.atrades{position:absolute;top:8px;right:68px;z-index:100;display:flex;flex-direction:column;gap:4px}
.at-item{display:flex;align-items:center;gap:6px;padding:4px 8px;background:rgba(0,0,0,.85);border-radius:6px;font-size:.7rem;border:1px solid var(--border)}
.ainds{position:absolute;top:8px;left:8px;z-index:100;display:flex;flex-direction:column;gap:4px;pointer-events:none}
.ai-item{display:flex;align-items:center;gap:6px;padding:4px 8px;background:rgba(0,0,0,.6);border-radius:6px;font-size:.75rem;border:1px solid var(--border);pointer-events:auto;backdrop-filter:blur(4px)}
.ai-name{color:#fff;font-weight:600;cursor:pointer}
.ai-btn{background:none;border:none;color:var(--text2);cursor:pointer;display:flex;align-items:center;justify-content:center}
.ai-btn:hover{color:var(--red)}
.tools{display:flex;align-items:center;gap:6px;padding:6px 12px;background:var(--bg2);border-top:1px solid var(--border);flex-shrink:0}
.tbtn{height:32px;padding:0 10px;background:var(--bg3);border:1px solid var(--border);border-radius:8px;color:var(--text2);cursor:pointer;display:flex;align-items:center;gap:4px;font-size:.8rem}
.tbtn:hover,.tbtn.on{background:var(--bg4);color:var(--text);border-color:var(--yellow)}
.zbtns{display:flex;gap:4px;margin-left:auto}
.zbtn{width:30px;height:30px;border-radius:8px;background:var(--bg3);border:1px solid var(--border);color:var(--text2);cursor:pointer;display:flex;align-items:center;justify-content:center}
.tabs{display:flex;border-bottom:2px solid var(--border);background:var(--bg2);flex-shrink:0}
.tab{flex:1;padding:10px;text-align:center;font-weight:600;font-size:.9rem;color:var(--text2);cursor:pointer;border:none;background:none;border-bottom:2px solid transparent;margin-bottom:-2px}
.tab.on{color:var(--blue);border-bottom-color:var(--blue)}
.panel{padding:12px}
.bin-panel{display:block}.bin-panel.off{display:none}
.trow{display:flex;gap:8px;margin-bottom:10px}
.tinput{flex:1;display:flex;align-items:center;background:var(--bg3);border:1px solid var(--border);border-radius:10px;overflow:hidden}
.tinput .ab{width:42px;height:48px;background:var(--bg4);border:none;color:var(--text2);font-size:1.2rem;cursor:pointer}
.tinput .ic{flex:1;text-align:center;padding:6px}
.tinput .lb{font-size:.6rem;color:var(--text2);text-transform:uppercase}
.tinput .vl{font-size:1rem;font-weight:700}
.earn{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;padding:10px;background:var(--bg3);border-radius:8px;font-size:.85rem}
.earn .pct{color:var(--green);font-weight:700}
.earn .amt{font-size:1.1rem;font-weight:700;color:var(--yellow)}
.bbtns{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.bbtn{display:flex;align-items:center;justify-content:center;gap:8px;padding:16px;border:none;border-radius:12px;font-size:1.1rem;font-weight:700;cursor:pointer;color:#fff}
.bbtn.up{background:linear-gradient(135deg,#26a69a,#00897b)}
.bbtn.dn{background:linear-gradient(135deg,#ef5350,#e53935)}
.cfd-panel{display:none}.cfd-panel.on{display:block}
.cfd-row{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
.cfd-inp{background:var(--bg3);border:1px solid var(--border);border-radius:10px;padding:10px}
.cfd-inp .lb{font-size:.6rem;color:var(--text2);text-transform:uppercase}
.cfd-inp input{width:100%;background:none;border:none;color:#fff;font-size:1rem;font-weight:600;outline:none}
.cfd-msg{text-align:center;font-size:.8rem;color:var(--yellow);margin-bottom:10px;padding:8px;background:rgba(255,193,7,.1);border-radius:8px}
.cfd-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.cbtn{padding:14px;border:none;border-radius:10px;font-size:.9rem;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px;flex-direction:column;color:#fff}
.cbtn.buy{background:linear-gradient(135deg,#26a69a,#00897b)}
.cbtn.sell{background:linear-gradient(135deg,#ef5350,#e53935)}
.cbtn .ptag{font-size:.75rem;opacity:.8;font-weight:400}
.cbtn.tnow{background:var(--yellow);color:#000;grid-column:span 2;display:none;flex-direction:row}
.cbtn.tnow.on{display:flex}
.cbtn.exit{background:var(--red);grid-column:span 2;display:none;flex-direction:row}
.cbtn.exit.on{display:flex}
.cfd-stat{margin-top:10px;padding:10px;background:var(--bg3);border-radius:10px;display:none}
.cfd-stat.on{display:block}
.cfd-sr{display:flex;justify-content:space-between;padding:4px 0;font-size:.8rem;border-bottom:1px solid var(--border)}
.cfd-sr:last-child{border-bottom:none}
.cfd-sr .lb{color:var(--text2)}.cfd-sr .vl{font-weight:600}
.cfd-sr .vl.win{color:var(--green)}.cfd-sr .vl.lose{color:var(--red)}
.modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:1500;align-items:flex-end;justify-content:center}
.modal.show{display:flex}
.modal.as-modal.show{align-items:stretch;justify-content:stretch}
.modal.as-modal .mcont{max-width:100%;max-height:100%;height:100%;border-radius:0;display:flex;flex-direction:column}
.mcont{background:var(--bg2);width:100%;max-width:500px;max-height:60vh;border-radius:16px 16px 0 0}
.mhdr{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;border-bottom:1px solid var(--border)}
.mttl{font-weight:600;font-size:.95rem}
.mcls{width:32px;height:32px;border-radius:50%;background:var(--bg3);border:none;color:var(--text);cursor:pointer;font-size:1rem}
.mbody{padding:8px 16px;max-height:calc(60vh - 46px);overflow-y:auto}
.ogrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.oitem{padding:12px;background:var(--bg3);border:2px solid transparent;border-radius:10px;cursor:pointer;text-align:center;font-size:.85rem}
.oitem.on{border-color:var(--yellow)}
.litem{display:flex;align-items:center;justify-content:space-between;padding:5px 8px;background:var(--bg3);border-radius:6px;margin-bottom:3px;cursor:pointer;font-size:.78rem}
.as-cats{display:flex;gap:6px;padding:12px 16px 8px;flex-wrap:wrap}
.as-cat{padding:6px 16px;border-radius:20px;border:1px solid var(--border);background:var(--bg3);color:#fff;cursor:pointer;font-size:.8rem;font-weight:500}
.as-cat.on{background:var(--green);border-color:var(--green);color:#000}
.as-search{padding:0 16px 8px}
.as-search input{width:100%;background:var(--bg3);border:1px solid var(--border);border-radius:10px;padding:10px 14px 10px 36px;color:#fff;font-size:.85rem;outline:none}
.as-search i{position:absolute;left:28px;top:50%;transform:translateY(-50%);color:var(--text2);font-size:.85rem}
.as-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:0 16px 16px}
.as-item{display:flex;align-items:center;gap:10px;padding:12px;background:var(--bg3);border:2px solid transparent;border-radius:12px;cursor:pointer;color:#fff;transition:border-color .2s}
.as-item:hover{border-color:var(--border)}
.as-item.sel{border-color:var(--yellow)}
.as-icon{width:36px;height:36px;min-width:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;color:#fff}
.as-info{flex:1;min-width:0;overflow:hidden}
.as-sym{font-weight:600;font-size:.8rem;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.as-name{font-size:.65rem;color:rgba(255,255,255,.6);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.as-pay{font-weight:700;font-size:.85rem;color:#fff;white-space:nowrap}
@media(max-width:600px){.as-grid{grid-template-columns:repeat(2,1fr)}}
.litem:hover{background:var(--bg4)}
.litem.app{border-left:3px solid var(--green)}
.sgrp{margin-bottom:12px}
.slbl{font-size:.8rem;color:var(--text2);margin-bottom:4px}
.srow{display:flex;align-items:center;background:var(--bg3);border:1px solid var(--border);border-radius:8px}
.srow input{flex:1;background:none;border:none;color:#fff;font-size:1rem;padding:10px;text-align:center;outline:none}
.srow .adj{width:40px;height:40px;background:var(--bg4);border:none;color:var(--text2);cursor:pointer;font-size:1.1rem}
.cswatches{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px}
.csw{width:32px;height:32px;border-radius:50%;cursor:pointer;border:3px solid transparent}
.csw.on{border-color:#fff;transform:scale(1.1)}
.abtn{width:100%;padding:10px;background:var(--green);color:#fff;border:none;border-radius:8px;font-weight:600;cursor:pointer;margin-top:10px;font-size:.85rem;position:relative;z-index:20;}
.rbtn{width:100%;padding:8px;background:var(--red);color:#fff;border:none;border-radius:8px;font-weight:600;cursor:pointer;margin-top:6px;font-size:.8rem;position:relative;z-index:10;}
.itabs{display:flex;gap:6px;margin-bottom:10px}
.itab{padding:6px 14px;border:1px solid var(--border);border-radius:20px;background:var(--bg3);color:var(--text2);cursor:pointer;font-size:.8rem}
.itab.on{background:var(--blue);color:#fff;border-color:var(--blue)}
.smenu{position:fixed;top:0;left:-280px;width:260px;height:100%;background:var(--bg2);z-index:2000;transition:left .3s}
.smenu.open{left:0}
.sover{position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:1999;display:none}
.sover.show{display:block}
.smhdr{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--border)}
.smcls{background:none;border:none;color:#fff;font-size:1.3rem;cursor:pointer}
.smi{display:flex;align-items:center;gap:14px;padding:14px 18px;color:#fff;text-decoration:none;border-bottom:1px solid var(--border)}
.toast{position:fixed;bottom:100px;left:50%;transform:translateX(-50%) translateY(100px);background:var(--bg3);padding:12px 24px;border-radius:10px;z-index:3000;opacity:0;transition:.3s;font-weight:600;white-space:nowrap;font-size:.85rem;pointer-events:none}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.ok{border:1px solid var(--green);color:var(--green)}
.toast.err{border:1px solid var(--red);color:var(--red)}
@media(max-width:768px){
.right-col{width:100%;border-left:none;border-top:1px solid var(--border);max-height:none}
.main-row{flex-direction:column}
.chart-wrap{min-height:45vh}
}
@media(orientation:landscape) and (max-height:500px){
.main-row{flex-direction:row}
.chart-col{flex:1}
.right-col{width:240px;max-height:none;flex-shrink:0}
.chart-wrap{min-height:auto}
.bbtn{padding:10px;font-size:.85rem}
.cbtn{padding:10px;font-size:.8rem}
}
.candle-timer{position:absolute;right:55px;background:rgba(0,0,0,0.7);color:#fff;padding:2px 6px;border-radius:4px;font-size:0.8rem;font-weight:700;z-index:95;pointer-events:none;border:1px solid rgba(255,255,255,0.1);display:none;white-space:nowrap}
.candle-timer.show{display:block}
</style>
</head>
<body>
<div class="app">
<header class="hdr">
<div class="hdr-left" style="overflow:-moz-hidden-unscrollable; position: relative; flex:1; align-items: center; display: flex;">
<button class="hbtn" id="menuBtn" style="min-width:36px;"><i class="fas fa-bars"></i></button>

<div id="mobileAselActive" class="mobile-asel-active" style="display:none;">
    <!-- Filled via JS in portrait mode -->
</div>

<div class="asel-tabs" id="aselTabs" style="display:flex; gap:6px; align-items:center; margin-left: 8px;">
    <!-- Tabs will be rendered here dynamically via JS -->
</div>
<button class="hbtn" id="addChartBtn" style="min-width:32px; height:32px; margin-left:8px;" onclick="addChartTab()"><i class="fas fa-plus"></i></button>
</div>
<div class="hdr-right">
<div class="acc-box" id="accBox">
<div class="acc-type"><?php echo $accountType==='demo'?'Demo':'Real'; ?> account <i class="fas fa-caret-down" style="font-size:.55rem;opacity:.7"></i></div>
<div class="acc-bal"><?php echo $currency; ?><span id="balDisp"><?php echo number_format($accountType==='demo'?$userDemoBalance:$userBalance,2); ?></span></div>
<div class="acc-dd" id="accDD">
<a href="?account=demo" class="acc-opt<?php echo $accountType==='demo'?' active':''; ?>"><span class="acc-badge d">DEMO</span><span id="demoBal"><?php echo $currency.number_format($userDemoBalance,2); ?></span></a>
<a href="?account=live" class="acc-opt<?php echo $accountType==='live'?' active':''; ?>"><span class="acc-badge l">LIVE</span><span id="liveBal"><?php echo $currency.number_format($userBalance,2); ?></span></a>

</div>
</div>

<button class="hbtn" onclick="location.href='deposit.php'"><i class="fas fa-wallet"></i></button>
<button class="pbtn" onclick="location.href='profile.php'"><?php echo htmlspecialchars($userInitials); ?></button>
</div>
</header>
<div class="sover" id="menuOv"></div>
<div class="smenu" id="sideMenu">
<div class="smhdr"><span style="font-weight:700;color:#ffc107"><?php echo htmlspecialchars($siteName); ?></span><button class="smcls" id="menuCls"><i class="fas fa-times"></i></button></div>
<a href="dashboard.php" class="smi"><i class="fas fa-th-large"></i>Dashboard</a>
<a href="trade.php" class="smi"><i class="fas fa-chart-line"></i>Trade</a>
<a href="history.php" class="smi"><i class="fas fa-history"></i>History</a>
<a href="deposit.php" class="smi"><i class="fas fa-plus-circle"></i>Deposit</a>
<a href="withdraw.php" class="smi"><i class="fas fa-minus-circle"></i>Withdraw</a>
<a href="profile.php" class="smi"><i class="fas fa-user"></i>Profile</a>
<a href="logout.php" class="smi"><i class="fas fa-sign-out-alt"></i>Logout</a>
</div>
<!-- abar removed, asset selector moved to header tab -->
<div class="main-row">
<div class="chart-col">
<div class="chart-wrap" id="chartWrap">
<div id="tv_chart"></div>
<div class="candle-timer" id="candleTimer">00:00</div>
<canvas id="drawCanvas"></canvas>
<div class="dline tp" id="dlTP"><div class="tag"><i class="fas fa-bullseye"></i> TP: <span class="v">0</span></div><div class="dsh"></div><div class="hnd">↕ DRAG</div></div>
<div class="dline en" id="dlEN"><div class="tag"><i class="fas fa-circle"></i> Entry: <span class="v">0</span></div><div class="dsh"></div></div>
<div class="dline sl" id="dlSL"><div class="tag"><i class="fas fa-shield-alt"></i> SL: <span class="v">0</span></div><div class="dsh"></div><div class="hnd">↕ DRAG</div></div>
<div class="atrades" id="aTrades"></div>
<div class="ainds" id="aInds"></div>
</div>
<div class="tools">
<button class="tbtn" id="ctBtn"><i class="fas fa-chart-area"></i> <span id="ctLbl">Area</span></button>
<button class="tbtn" id="tfBtn"><span id="tfLbl">5s</span></button>
<button class="tbtn" id="indBtn"><i class="fas fa-chart-line"></i></button>
<button class="tbtn" id="drwBtn"><i class="fas fa-pencil-alt"></i></button>
<div class="zbtns"><button class="zbtn" id="zOut"><i class="fas fa-minus"></i></button><button class="zbtn" id="zIn"><i class="fas fa-plus"></i></button></div>
</div>
</div>
<div class="right-col">
<div class="tabs">
<button class="tab on" data-t="binary">Options</button>
<button class="tab" data-t="cfd">Stocks</button>
</div>
<div class="panel">
<div class="bin-panel" id="binP">
<div class="trow">
<div class="tinput"><button class="ab" id="tDn">−</button><div class="ic"><div class="lb">Time</div><div class="vl" id="tVal">1m</div></div><button class="ab" id="tUp">+</button></div>
<div class="tinput"><button class="ab" id="aDn">−</button><div class="ic"><div class="lb">Amount</div><input type="number" id="aInput" value="<?php echo $minTradeAmount; ?>" style="background:none;border:none;color:#fff;font-size:1.2rem;font-weight:700;width:80px;text-align:center;outline:none;"></div><button class="ab" id="aUp">+</button></div>
</div>
<div class="earn"><span>Earnings</span><span class="pct">+<span id="payPct">85</span>%</span><span class="amt"><?php echo $currency; ?><span id="potEarn"><?php echo number_format($minTradeAmount * 1.85, 2, '.', ''); ?></span></span></div>
<div class="bbtns">
<button class="bbtn up" id="upBtn"><i class="fas fa-arrow-up"></i> UP</button>
<button class="bbtn dn" id="dnBtn"><i class="fas fa-arrow-down"></i> DOWN</button>
</div>
</div>
<div class="cfd-panel" id="cfdP">
<div class="trow">
<div class="tinput"><button class="ab" id="cAmtDn">−</button><div class="ic"><div class="lb">Amount</div><div class="vl" style="display:flex;align-items:center;justify-content:center"><?php echo $currency; ?><input type="number" id="cAmtInput" value="100" style="background:none;border:none;color:#fff;font-size:1rem;font-weight:700;width:60px;text-align:center;outline:none;-moz-appearance:textfield;margin-left:2px;"></div></div><button class="ab" id="cAmtUp">+</button></div>
<div class="tinput"><button class="ab" id="cMulDn">−</button><div class="ic"><div class="lb">Multiplier</div><div class="vl" style="display:flex;align-items:center;justify-content:center">×<input type="number" id="cMulInput" value="<?php echo $defaultCfdMul; ?>" style="background:none;border:none;color:#fff;font-size:1rem;font-weight:700;width:50px;text-align:center;outline:none;-moz-appearance:textfield;margin-left:2px;"></div></div><button class="ab" id="cMulUp">+</button></div>
</div>
<div class="bbtns">
<button class="bbtn up" id="cUpBtn"><i class="fas fa-arrow-up"></i></button>
<button class="bbtn dn" id="cDnBtn"><i class="fas fa-arrow-down"></i></button>
</div>
<div style="display:flex;justify-content:space-between;padding:8px 12px;background:var(--bg3);border-radius:8px;margin-bottom:10px;font-size:0.85rem;color:var(--text2)">
    <span>Total Volume:</span>
    <span style="color:#fff;font-weight:700"><?php echo $currency; ?><span id="cVol">100</span></span>
</div>
<button class="abtn" id="cTradeBtn" style="display:none;margin-top:0;height:48px;font-size:1.1rem;background:var(--bg4);color:var(--text2)">Trade</button>
<div class="cfd-stat" id="cfdStat">
<div class="cfd-sr"><span class="lb">Direction:</span><span class="vl" id="csDir">BUY</span></div>
<div class="cfd-sr"><span class="lb">Entry:</span><span class="vl" id="csEntry">0</span></div>
<div class="cfd-sr"><span class="lb">Current:</span><span class="vl" id="csCurr">0</span></div>
<div class="cfd-sr"><span class="lb">P/L:</span><span class="vl" id="csPL"><?php echo $currency; ?>0</span></div>
<button class="rbtn" id="cExit" style="margin-top:8px">CLOSE TRADE</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="ctModal"><div class="mcont"><div class="mhdr"><span class="mttl">Chart Type</span><button class="mcls" onclick="cModal('ctModal')">×</button></div><div class="mbody"><div class="ogrid" id="ctGrid"></div></div></div></div>
<div class="modal" id="tfModal"><div class="mcont"><div class="mhdr"><span class="mttl">Timeframe</span><button class="mcls" onclick="cModal('tfModal')">×</button></div><div class="mbody"><div class="ogrid" id="tfGrid"></div></div></div></div>
<div class="modal as-modal" id="asModal"><div class="mcont"><div class="mhdr"><span class="mttl">Assets</span><button class="mcls" onclick="cModal('asModal')">×</button></div><div class="as-cats" id="asCats"></div><div class="as-search" style="position:relative"><i class="fas fa-search"></i><input type="text" id="asSearch" placeholder="Search" oninput="renderAssets()"></div><div style="overflow-y:auto;flex:1"><div class="as-grid" id="asList"></div></div></div></div>
<div class="modal" id="indModal"><div class="mcont"><div class="mhdr"><span class="mttl">Indicators</span><button class="mcls" onclick="cModal('indModal')">×</button></div><div class="mbody"><div class="itabs" id="iTabs"></div><div id="iList"></div></div></div></div>
<div class="modal" id="isModal"><div class="mcont"><div class="mhdr"><span class="mttl" id="iTitle">Settings</span><button class="mcls" onclick="cModal('isModal')">×</button></div><div class="mbody" id="iSet"></div></div></div>
<div class="modal" id="drModal"><div class="mcont"><div class="mhdr"><span class="mttl">Drawing Tools</span><button class="mcls" onclick="cModal('drModal')">×</button></div><div class="mbody" id="drList"></div></div></div>
<div class="toast" id="toast"></div>

<script>console.log("STEP 1: Page HTML loaded");</script>
<script src="../assets/js/lightweight-charts.standalone.production.js" onerror="console.error('Local chart library failed to load, trying unpkg');var s=document.createElement('script');s.src='https://unpkg.com/lightweight-charts@4.1.0/dist/lightweight-charts.standalone.production.js';s.onerror=function(){console.error('unpkg FAILED, trying jsdelivr');var s2=document.createElement('script');s2.src='https://cdn.jsdelivr.net/npm/lightweight-charts@4.1.0/dist/lightweight-charts.standalone.production.js';s2.onerror=function(){document.body.innerHTML='<div style=color:red;padding:20px;font-size:18px><h2>Library Load Error</h2><p>Chart library load nahi thay. Internet connection check karo.</p></div>';};document.head.appendChild(s2);};document.head.appendChild(s);"></script>
<script>
console.log("STEP 2: Script block start, LightweightCharts=", typeof LightweightCharts);
if(typeof LightweightCharts==="undefined"){
    console.error("FATAL: LightweightCharts not loaded!");
    document.addEventListener("DOMContentLoaded",function(){
        document.body.innerHTML="<div style='color:red;padding:20px;font-size:18px'><h2>Library Load Error</h2><p>LightweightCharts library load nahi thay. Page refresh karo (Ctrl+Shift+R).</p><button onclick='location.reload(true)' style='padding:10px 20px;background:#ffc107;border:none;border-radius:8px;font-size:16px;cursor:pointer;margin-top:10px'>Refresh Page</button></div>";
    });
}else{
console.log("STEP 3: LightweightCharts loaded OK, version check passed");
// === CONFIG ===
var ASSETS=<?php echo $assetsJson; ?>;
var UID=<?php echo $userId; ?>,IS_DEMO=<?php echo $isDemo; ?>,ACCT="<?php echo $accountType; ?>",CUR="<?php echo $currency; ?>";
var MIN_AMT=<?php echo $minTradeAmount; ?>,MAX_AMT=<?php echo $maxTradeAmount; ?>,MAX_TR=<?php echo $maxSimTrades; ?>;
var MIN_CFD_MUL=<?php echo $minCfdMul; ?>,MAX_CFD_MUL=<?php echo $maxCfdMul; ?>,DEF_CFD_MUL=<?php echo $defaultCfdMul; ?>;
var bal=<?php echo $accountType==='demo'?$userDemoBalance:$userBalance; ?>,demoBal=<?php echo $userDemoBalance; ?>,liveBal=<?php echo $userBalance; ?>;
// Override IS_DEMO based on URL to ensure sync
var urlParams = new URLSearchParams(window.location.search);
if(urlParams.get('account') === 'live') IS_DEMO = 0;
if(urlParams.get('account') === 'demo') IS_DEMO = 1;
var asset=ASSETS.find(function(a){return a.symbol==="BTCUSDT"})||ASSETS[0];
var price=0,tMode="binary",dur=60,amt=MIN_AMT,cType="area",tf=5;
// Chart Multi-Tab State
var activeCharts = [];
var activeChartIndex = 0;
// We store one data history set for each tab so we can instantly switch
var chartDataStore = {};

var chart,series,candles=[],hkData=[],price=0,tf=60,dur=60,amt=MIN_AMT,cType="candlestick";
var cfdAmt=100,cfdMul=DEF_CFD_MUL;
var binTrades=[],cfdTrade=null,cfdLine=null,slLine=null,tpLine=null,cfdDir=null,cfdSetup=false;
var slP=0,tpP=0,entP=0;
var actInds={},indSeries={},curInd=null,curSet={},indCat="overlay"; // actInds: { id: {type, settings} }
var draws=[],drawMode=null,drawPts=[],dCanvas,dCtx,mPos={x:0,y:0};
var oscScaleSet=false;

var BP={BTCUSDT:97500,ETHUSDT:3400,CRYPTO_IDX:641,EURUSD:1.085,XAUUSD:2650,BNBUSDT:620,XRPUSDT:2.3,SOLUSDT:190,ADAUSDT:0.95,DOGEUSDT:0.32,DOTUSDT:7.5,MATICUSDT:0.85,LTCUSDT:105,GBPUSD:1.27,USDJPY:149.5,AUDUSD:0.66,USDCAD:1.36,USDCHF:0.88,NZDUSD:0.62,USDINR:83.2,RELIANCE:2450,TCS:3850,INFY:1680,HDFCBANK:1620,ICICIBANK:1050,SBIN:780,TATAMOTORS:720,AAPL:185,GOOGL:148,MSFT:415,TSLA:245,AMZN:186,META:520,NVDA:870,XAGUSD:31,XPTUSD:960,CRUDE:73,NATGAS:2.8,NIFTY50:22300,BANKNIFTY:47500,SENSEX:73500,SPX500:5100,NASDAQ:18200,DJI:38900,XTIUSD:73,ABTC:45000};
var asCatFilter="all";
var CTYPES=[{id:"area",n:"Area",i:"fa-mountain"},{id:"line",n:"Line",i:"fa-chart-line"},{id:"candlestick",n:"Candle",i:"fa-signal"},{id:"bars",n:"Bar",i:"fa-chart-bar"},{id:"heikin",n:"Heikin Ashi",i:"fa-chart-area"}];
var TFS=[{id:1,n:"1s"},{id:3,n:"3s"},{id:5,n:"5s"},{id:10,n:"10s"},{id:15,n:"15s"},{id:30,n:"30s"},{id:60,n:"1m"},{id:120,n:"2m"},{id:180,n:"3m"},{id:300,n:"5m"},{id:600,n:"10m"},{id:900,n:"15m"},{id:1800,n:"30m"},{id:3600,n:"1h"},{id:7200,n:"2h"},{id:14400,n:"4h"},{id:86400,n:"1D"},{id:604800,n:"1W"}];
var COLS=["#ffc107","#26a69a","#2196f3","#9c27b0","#e91e63","#ef5350","#00bcd4","#ff9800","#4caf50","#795548"];
var INDS={
sma:{n:"SMA",c:"overlay",s:{period:14,color:"#ffc107"}},ema:{n:"EMA",c:"overlay",s:{period:14,color:"#2196f3"}},wma:{n:"WMA",c:"overlay",s:{period:14,color:"#9c27b0"}},
dema:{n:"DEMA",c:"overlay",s:{period:14,color:"#00bcd4"}},tema:{n:"TEMA",c:"overlay",s:{period:14,color:"#e91e63"}},smma:{n:"SMMA",c:"overlay",s:{period:14,color:"#ff9800"}},
hull:{n:"Hull MA",c:"overlay",s:{period:14,color:"#26a69a"}},vwma:{n:"VWMA",c:"overlay",s:{period:20,color:"#8bc34a"}},
bb:{n:"Bollinger Bands",c:"overlay",s:{period:20,deviation:2,color:["#00bcd4","#ffc107","#00bcd4"]}},keltner:{n:"Keltner Channel",c:"overlay",s:{period:20,mult:1.5,color:["#ff5722","#ff5722"]}},
envelopes:{n:"Envelopes",c:"overlay",s:{period:20,percent:2.5,color:["#607d8b","#607d8b"]}},psar:{n:"Parabolic SAR",c:"overlay",s:{step:0.02,max:0.2,color:"#ffc107"}},
ichimoku:{n:"Ichimoku Cloud",c:"overlay",s:{tenkan:9,kijun:26,color:["#e91e63","#2196f3"]}},alligator:{n:"Alligator",c:"overlay",s:{jaw:13,teeth:8,lips:5,color:["#2196f3","#ef5350","#26a69a"]}},
supertrend:{n:"SuperTrend",c:"overlay",s:{period:10,mult:3,color:"#ff9800"}},pivots:{n:"Pivot Points",c:"overlay",s:{color:["#9c27b0","#26a69a","#ef5350"]}},
rsi:{n:"RSI",c:"oscillator",s:{period:14,overbought:70,oversold:30,color:"#e91e63"}},macd:{n:"MACD",c:"oscillator",s:{fast:12,slow:26,signal:9,color:["#ff9800","#e91e63"]}},
stoch:{n:"Stochastic",c:"oscillator",s:{kPeriod:14,dPeriod:3,color:["#26a69a","#e91e63"]}},stochrsi:{n:"Stoch RSI",c:"oscillator",s:{period:14,kPeriod:3,dPeriod:3,color:["#2196f3","#e91e63"]}},
adx:{n:"ADX",c:"oscillator",s:{period:14,color:"#ffc107"}},atr:{n:"ATR",c:"oscillator",s:{period:14,color:"#ef5350"}},cci:{n:"CCI",c:"oscillator",s:{period:20,color:"#2196f3"}},
momentum:{n:"Momentum",c:"oscillator",s:{period:10,color:"#9c27b0"}},roc:{n:"ROC",c:"oscillator",s:{period:12,color:"#00bcd4"}},
williams:{n:"Williams %R",c:"oscillator",s:{period:14,color:"#607d8b"}},mfi:{n:"MFI",c:"oscillator",s:{period:14,color:"#ff5722"}},
awesome:{n:"Awesome Osc",c:"oscillator",s:{fast:5,slow:34,color:"#4caf50"}},dpo:{n:"DPO",c:"oscillator",s:{period:20,color:"#795548"}},
trix:{n:"TRIX",c:"oscillator",s:{period:18,color:"#009688"}},vortex:{n:"Vortex",c:"oscillator",s:{period:14,color:"#3f51b5"}}
};
var DRAWS=[{id:"hline",n:"Horizontal Line",i:"fa-minus"},{id:"vline",n:"Vertical Line",i:"fa-grip-lines-vertical"},{id:"trendline",n:"Trend Line",i:"fa-chart-line"},{id:"ray",n:"Ray",i:"fa-long-arrow-alt-right"},{id:"fib",n:"Fibonacci",i:"fa-project-diagram"},{id:"rect",n:"Rectangle",i:"fa-square"},{id:"channel",n:"Channel",i:"fa-bars"},{id:"clear",n:"Clear All",i:"fa-trash"}];

function G(id){return document.getElementById(id);}

// === PRICE<->COORDINATE HELPERS (LightweightCharts v4.1 API) ===
function priceToY(p){
    if(!series)return null;
    try{var y=series.priceToCoordinate(p);return(y!==null&&y!==undefined)?y:null;}catch(e){return null;}
}
function yToPrice(y){
    if(!series)return null;
    try{return series.coordinateToPrice(y);}catch(e){return null;}
}
function timeToX(t){
    if(!chart)return null;
    try{var x=chart.timeScale().timeToCoordinate(t);return(x!==null&&x!==undefined)?x:null;}catch(e){return null;}
}
function xToTime(x){
    if(!chart)return null;
    try{return chart.timeScale().coordinateToTime(x);}catch(e){return null;}
}

// === CHART ===
function initChart(){
    var el=G("tv_chart");if(!el)return;
    chart=LightweightCharts.createChart(el,{
        width:el.clientWidth,height:el.clientHeight,
        layout:{background:{color:"#0d1117"},textColor:"#8b949e"},
        grid:{vertLines:{color:"#21262d"},horzLines:{color:"#21262d"}},
        rightPriceScale:{borderColor:"#30363d"},
        timeScale:{borderColor:"#30363d",timeVisible:true,secondsVisible:true},
        crosshair:{mode:LightweightCharts.CrosshairMode.Normal}
    });
    mkSeries();genData();series.setData(cType==="heikin"?hkData:candles);chart.timeScale().fitContent();
    new ResizeObserver(function(){chart.applyOptions({width:el.clientWidth,height:el.clientHeight});resizeDC();}).observe(el);
    initDC();
}
function mkSeries(){
    if(series){try{chart.removeSeries(series);}catch(e){}}
    if(cType==="candlestick"||cType==="heikin") series=chart.addCandlestickSeries({upColor:"#26a69a",downColor:"#ef5350",borderUpColor:"#26a69a",borderDownColor:"#ef5350",wickUpColor:"#26a69a",wickDownColor:"#ef5350"});
    else if(cType==="line") series=chart.addLineSeries({color:"#2196f3",lineWidth:2});
    else if(cType==="bars") series=chart.addBarSeries({upColor:"#26a69a",downColor:"#ef5350"});
    else series=chart.addAreaSeries({topColor:"rgba(33,150,243,0.4)",bottomColor:"rgba(33,150,243,0)",lineColor:"#2196f3",lineWidth:2});
}
function genData(){
    candles=[];hkData=[];var base=BP[asset.symbol]||100;var rawNow=Math.floor(Date.now()/1000);var now=rawNow-(rawNow%tf);var p=base,prev=null;
    for(var i=300;i>=0;i--){var t=now-i*tf;var ch=(Math.random()-0.5)*base*0.002;var o=p;p+=ch;var c=p;var h=Math.max(o,c)+Math.random()*base*0.0005;var l=Math.min(o,c)-Math.random()*base*0.0005;
    candles.push({time:t,open:o,high:h,low:l,close:c,value:c});
    var hc=(o+h+l+c)/4,ho=prev?(prev.open+prev.close)/2:(o+c)/2;
    hkData.push({time:t,open:ho,high:Math.max(h,ho,hc),low:Math.min(l,ho,hc),close:hc});prev={open:ho,close:hc};}
    price=p;
}
function tick(){
    var base=BP[asset.symbol]||100;
    
    // Apply forced result manipulation if there are active binary trades
    var forceAction = null; 
    var rawNow=Math.floor(Date.now()/1000);
    var now=rawNow-(rawNow%tf);
    
    // Check if any binary trade is close to expiring (last 4 seconds)
    if (binTrades.length > 0) {
        // Find the trade that expires soonest
        var closestTrade = null;
        var minTimeLeft = Infinity;
        for (var i = 0; i < binTrades.length; i++) {
            var timeLeft = (binTrades[i].endTime - Date.now()) / 1000;
            if (timeLeft > 0 && timeLeft < minTimeLeft) {
                minTimeLeft = timeLeft;
                closestTrade = binTrades[i];
            }
        }
        
        if (closestTrade && minTimeLeft <= 4 && closestTrade.forced_result) {
            // Determine required price relationship to ENTRY
            // If forced to WIN:
            //   If UP: price must be > entry
            //   If DOWN: price must be < entry
            // If forced to LOSE:
            //   If UP: price must be < entry
            //   If DOWN: price must be > entry
            
            var mustBeAbove = (closestTrade.dir === "up" && closestTrade.forced_result === "won") || (closestTrade.dir === "down" && closestTrade.forced_result === "lost");
            var mustBeBelow = (closestTrade.dir === "down" && closestTrade.forced_result === "won") || (closestTrade.dir === "up" && closestTrade.forced_result === "lost");
            
            var diffAmount = base * 0.005; // Force a distinct visible jump
            
            if (mustBeAbove && price <= closestTrade.entry) {
                forceAction = "pump";
                price = closestTrade.entry + diffAmount + (Math.random() * base * 0.001);
            } else if (mustBeBelow && price >= closestTrade.entry) {
                forceAction = "dump";
                price = closestTrade.entry - diffAmount - (Math.random() * base * 0.001);
            }
        }
    }
    
    // Standard random tick if not forced
    if (!forceAction) {
        price+=(Math.random()-0.5)*base*0.002;
    }
    
    var last=candles[candles.length-1];
    if(now-last.time>=tf){
        candles.push({time:now,open:price,high:price,low:price,close:price,value:price});
        var ph=hkData[hkData.length-1];var hc2=price,ho2=(ph.open+ph.close)/2;
        hkData.push({time:now,open:ho2,high:Math.max(price,ho2,hc2),low:Math.min(price,ho2,hc2),close:hc2});
        if(candles.length>500){candles.shift();hkData.shift();}
    }else{
        last.close=price;last.high=Math.max(last.high,price);last.low=Math.min(last.low,price);last.value=price;
        var lh=hkData[hkData.length-1];lh.close=(last.open+last.high+last.low+last.close)/4;lh.high=Math.max(last.high,lh.open,lh.close);lh.low=Math.min(last.low,lh.open,lh.close);
    }
    if(cType==="heikin") series.update(hkData[hkData.length-1]);
    else if(cType==="candlestick"||cType==="bars") series.update({time:last.time,open:last.open,high:last.high,low:last.low,close:last.close});
    else series.update({time:last.time,value:last.value});
    
    // Update live indicators
    Object.keys(actInds).forEach(function(uid){
        var ind=actInds[uid];
        var s=ind.settings;
        var c=cls();
        try{
            var val=null;
            // Recalculate last value. Optimization: could be better, but this ensures correctness
            if(ind.type==="sma"){ val=calcSMA(c,s.period); }
            else if(ind.type==="ema"){ val=calcEMA(c,s.period); }
            else if(ind.type==="wma"){ val=calcWMA(c,s.period); }
            else if(ind.type==="dema"){ val=calcDEMA(c,s.period); }
            else if(ind.type==="tema"){ val=calcTEMA(c,s.period); }
            else if(ind.type==="smma"){ val=calcSMMA(c,s.period); }
            else if(ind.type==="hull"){ val=calcHull(c,s.period); }
            else if(ind.type==="vwma"){ val=calcSMA(c,s.period); } // VWMA currently uses SMA logic in original code
            else if(ind.type==="bb"){ 
                var bb=calcBB(c,s.period,s.deviation); 
                var i=bb.mid.length-1;
                if(indSeries[uid] && Array.isArray(indSeries[uid])){
                    indSeries[uid][0].update(bb.upper[i]);
                    indSeries[uid][1].update(bb.mid[i]);
                    indSeries[uid][2].update(bb.lower[i]);
                }
                return;
            }
            else if(ind.type==="keltner"){ 
                var ek=calcEMA(c,s.period),ak=calcATR(s.period);
                var i=ak.length-1;
                if(indSeries[uid] && Array.isArray(indSeries[uid])){
                     indSeries[uid][0].update({time:ak[i].time,value:ek[ek.length-1].value+s.mult*ak[i].value});
                     indSeries[uid][1].update({time:ak[i].time,value:ek[ek.length-1].value-s.mult*ak[i].value});
                }
                return;
            }
             else if(ind.type==="envelopes"){
                var sma=calcSMA(c,s.period),p2=s.percent/100;
                var i=sma.length-1;
                if(indSeries[uid] && Array.isArray(indSeries[uid])){
                     indSeries[uid][0].update({time:sma[i].time,value:sma[i].value*(1+p2)});
                     indSeries[uid][1].update({time:sma[i].time,value:sma[i].value*(1-p2)});
                }
                return;
             }
             else if(ind.type==="psar"){
                 var ps=calcPSAR(s.step,s.max);
                 if(indSeries[uid]) indSeries[uid].update(ps[ps.length-1]);
                 return;
             }
             else if(ind.type==="ichimoku"){
                 var ti=calcSMA(c,s.tenkan),ki=calcSMA(c,s.kijun);
                 if(indSeries[uid] && Array.isArray(indSeries[uid])){
                     indSeries[uid][0].update(ti[ti.length-1]);
                     indSeries[uid][1].update(ki[ki.length-1]);
                 }
                 return;
             }
             else if(ind.type==="alligator"){
                 var j=calcSMMA(c,s.jaw),t=calcSMMA(c,s.teeth),l=calcSMMA(c,s.lips);
                 if(indSeries[uid] && Array.isArray(indSeries[uid])){
                     indSeries[uid][0].update(j[j.length-1]);
                     indSeries[uid][1].update(t[t.length-1]);
                     indSeries[uid][2].update(l[l.length-1]);
                 }
                 return;
             }
             // Simple Lines
             if(val && Array.isArray(val) && indSeries[uid] && !Array.isArray(indSeries[uid])){
                 indSeries[uid].update(val[val.length-1]);
             }
             else if(ind.type==="supertrend"){
                 val=calcST(s.period,s.mult);
                 if(indSeries[uid]) indSeries[uid].update(val[val.length-1]);
             }
             // Oscillators
             else if(ind.type==="rsi"){ val=calcRSI(c,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="macd"){ 
                 var m=calcMACD(c,s.fast,s.slow,s.signal);
                 if(indSeries[uid] && Array.isArray(indSeries[uid])){
                     indSeries[uid][0].update(m.macd[m.macd.length-1]);
                     indSeries[uid][1].update(m.signal[m.signal.length-1]);
                     indSeries[uid][2].update(m.hist[m.hist.length-1]);
                 }
             }
             else if(ind.type==="stoch"){
                 var st=calcStoch(s.kPeriod,s.dPeriod);
                    if(indSeries[uid] && Array.isArray(indSeries[uid])){
                        indSeries[uid][0].update(st.k[st.k.length-1]);
                        indSeries[uid][1].update(st.d[st.d.length-1]);
                    }
             }
             else if(ind.type==="stochrsi"){
                    var sr3=calcStochRSI(c,s.period,s.kPeriod,s.dPeriod);
                    if(indSeries[uid] && Array.isArray(indSeries[uid])){
                         indSeries[uid][0].update(sr3.k[sr3.k.length-1]);
                         indSeries[uid][1].update(sr3.d[sr3.d.length-1]);
                    }
             }
             else if(ind.type==="adx"){ val=calcADX(s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="atr"){ val=calcATR(s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="cci"){
                 var tp=candles.map(function(d){return((d.high||d.value)+(d.low||d.value)+(d.close||d.value))/3;});
                 val=calcCCI(tp,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]);
             }
             else if(ind.type==="momentum"){ val=calcMom(c,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="roc"){ val=calcROC(c,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="williams"){ val=calcWR(s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="mfi"){ val=calcMFI(s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="awesome"){ var ao=calcAO(s.fast,s.slow); if(indSeries[uid]) indSeries[uid].update(ao[ao.length-1]); }
             else if(ind.type==="dpo"){ val=calcDPO(c,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="trix"){ val=calcTRIX(c,s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             else if(ind.type==="vortex"){ val=calcVortex(s.period); if(indSeries[uid]) indSeries[uid].update(val[val.length-1]); }
             
        }catch(e){console.error("Ind update err:", uid, e);}
    });

    for(var i=binTrades.length-1;i>=0;i--){if(binTrades[i].endTime<=Date.now())closeBin(binTrades[i],i);}
    if(cfdTrade){updCFD();chkSLTP();}
    if(cfdSetup&&!cfdTrade){entP=price;G("dlEN").querySelector(".v").textContent=price.toFixed(2);updLines();}
    
    // Update Candle Timer
    var remains = tf - (rawNow % tf);
    if(remains < 0) remains = 0;
    var m = Math.floor(remains / 60);
    var s = remains % 60;
    G("candleTimer").textContent = (m<10?"0"+m:m) + ":" + (s<10?"0"+s:s);
    
    // Update Timer Position
    var y = priceToY(price);
    var lx = null;
    if(candles && candles.length > 0) {
        lx = timeToX(candles[candles.length-1].time);
    }
    
    if(y !== null && lx !== null) {
        G("candleTimer").style.top = (y - 12) + "px"; // Offset to center (approx half height)
        G("candleTimer").style.left = (lx + 15) + "px"; // Exact right of the live candle
        G("candleTimer").style.right = "auto";
        G("candleTimer").classList.add("show");
    } else if(y !== null) {
        G("candleTimer").style.top = (y - 12) + "px";
        G("candleTimer").style.right = "55px";
        G("candleTimer").style.left = "auto";
        G("candleTimer").classList.add("show");
    } else {
        G("candleTimer").classList.remove("show");
    }

    // Process offline chart ticks for the other tabs so they stay realistic
    for(var i=0; i<activeCharts.length; i++){
        if(i === activeChartIndex) continue;
        var store = chartDataStore[i];
        if(!store || store.candles.length === 0) continue;
        
        var baseB = BP[store.asset.symbol] || 100;
        store.price += (Math.random()-0.5)*baseB*0.002;
        var sLast = store.candles[store.candles.length-1];
        
        if(now-sLast.time >= tf){
            store.candles.push({time:now, open:store.price, high:store.price, low:store.price, close:store.price, value:store.price});
            var sPh = store.hkData[store.hkData.length-1];
            var sHo2 = (sPh.open+sPh.close)/2;
            store.hkData.push({time:now, open:sHo2, high:Math.max(store.price,sHo2,store.price), low:Math.min(store.price,sHo2,store.price), close:store.price});
            if(store.candles.length > 500){ store.candles.shift(); store.hkData.shift(); }
        } else {
            sLast.close=store.price; sLast.high=Math.max(sLast.high,store.price); sLast.low=Math.min(sLast.low,store.price); sLast.value=store.price;
            var sLh = store.hkData[store.hkData.length-1];
            sLh.close = (sLast.open+sLast.high+sLast.low+sLast.close)/4; 
            sLh.high = Math.max(sLast.high,sLh.open,sLh.close); 
            sLh.low = Math.min(sLast.low,sLh.open,sLh.close);
        }
    }

    requestAnimationFrame(redrawDC); // Ensure valid state for drawing
}

// === BINARY ===
function placeBin(dir){
    if(binTrades.length>=MAX_TR){toast("Max "+MAX_TR+" trades!","err");return;}
    if(cfdTrade||cfdSetup){toast("CFD active!","err");return;}
    if(amt>bal){toast("Insufficient balance!","err");return;}
    if(amt<MIN_AMT||amt>MAX_AMT){toast("Invalid amount","err");return;}
    bal-=amt;syncBal();updUI();
    var pay=parseFloat(asset.payout_percent)||85;
    var nowSec = candles[candles.length-1].time;
    var endSec = nowSec + dur;
    var trColor = dir==="up" ? "#26a69a" : "#ef5350";
    var ts = chart.addLineSeries({
        color: trColor,
        lineWidth: 3,
        lineStyle: 1, // Dotted
        lastValueVisible: false,
        priceLineVisible: false,
        crosshairMarkerVisible: false
    });
    ts.setData([
        { time: nowSec, value: price },
        { time: endSec, value: price }
    ]);
    ts.setMarkers([
        { time: nowSec, position: dir==="up"?'belowBar':'aboveBar', color: trColor, shape: dir==="up"?'arrowUp':'arrowDown', text: 'Entry '+CUR+amt },
        { time: endSec, position: 'inBar', color: '#ffc107', shape: 'circle', text: 'End' }
    ]);
    var t={id:Date.now(),dir:dir,amount:amt,entry:price,pay:pay,start:Date.now(),endTime:Date.now()+dur*1000, ts:ts};
    binTrades.push(t);renderBin();
    dbPlace("binary",dir,amt,price,t);toast(dir.toUpperCase()+" "+CUR+amt,"ok");
}
function closeBin(t,i){
    var finalPrice = price;
    if(t.forced){
        if(t.forced==="won"){
            finalPrice = t.dir==="up" ? t.entry+0.5 : t.entry-0.5;
        } else {
            finalPrice = t.dir==="up" ? t.entry-0.5 : t.entry+0.5;
        }
    }
    var w=(t.dir==="up"&&finalPrice>t.entry)||(t.dir==="down"&&finalPrice<t.entry);
    var p=w ? t.amount*(t.pay/100) : 0;
    
    if(w){bal+=t.amount+p; syncBal();}
    updUI();
    
    if(t.ts){try{chart.removeSeries(t.ts);}catch(e){}}
    dbClose(t.db_id, finalPrice, w?"won":"lost", w?p:-t.amount);
    toast((w?"Won +":"Lost -")+CUR+(w?p:t.amount).toFixed(2), w?"ok":"err");
    
    binTrades.splice(i,1);renderBin();
}
function renderBin(){
    var c=G("aTrades");var h="";
    binTrades.forEach(function(t){var r=Math.max(0,Math.ceil((t.endTime-Date.now())/1000));
        h+="<div class=\"at-item\"><span style=\"color:"+(t.dir==="up"?"var(--green)":"var(--red)")+"\">"+(t.dir==="up"?"\u2191":"\u2193")+"</span><span>"+CUR+t.amount+"</span><span>"+r+"s</span></div>";});
    c.innerHTML=h;
}

// === CFD ===

// === CFD ===
function selCFDDir(dir){
    if(cfdTrade){toast("Trade active!","err");return;}
    if(cfdDir===dir)return; // Already selected
    
    // STRICT check for price
    if(!price || price<=0 || isNaN(price)){
        toast("Waiting for price data...","err");
        return;
    }
    
    cfdDir=dir;cfdSetup=true;
    
    // UI Feedback
    G("cUpBtn").className="bbtn up"+(dir==="buy"?" sel-up":"");
    G("cDnBtn").className="bbtn dn"+(dir==="sell"?" sel-dn":"");
    
    // Optional: Add some visual feedback for selection if 'sel-up' logic is missing in CSS
    // Since .sel-up is missing, let's just use opacity or border here manually or rely on 'active' class if preferred
    // But sticking to user request: "Make color like binary buttons". They are now permanently colored.
    // Selection state might need border:
    G("cUpBtn").style.border = dir==="buy" ? "2px solid #fff" : "none";
    G("cDnBtn").style.border = dir==="sell" ? "2px solid #fff" : "none";
    
    // Show Trade Button
    var tb=G("cTradeBtn");
    tb.innerHTML = "TRADE NOW <i class='fas fa-paper-plane'></i>";
    tb.className="abtn"+(dir==="buy"?" sel-up":dir==="sell"?" sel-dn":"");
    tb.style.background=dir==="buy"?"#26a69a":dir==="sell"?"#ef5350":"var(--bg4)";
    tb.style.color="#fff";
    tb.style.display="block"; 
    
    // Initial SL/TP Calculation
    entP=price;
    
    // Set closer initial spread (0.5%) to ensure visibility
    if(dir==="buy"){
        // Initial defaults - user can adjust
        slP=price * 0.995; 
        tpP=price * 1.005;
    }else{
        slP=price * 1.005;
        tpP=price * 0.995;
    }
    
    console.log("CFD Setup Init:", {dir, price, slP, tpP}); // DEBUG
    
    showLines();updLines();
}

function showLines(){
    ["dlTP","dlEN","dlSL"].forEach(function(id){
        var el=G(id);el.classList.add("on");
        // Enable dragging handles
        var hnd = el.querySelector(".hnd");
        if(hnd) hnd.style.display="block"; 
    });
    // Entry handle always hidden
    G("dlEN").querySelector(".hnd").style.display="none";
    
    updValLabels();
}

function updValLabels(){
    if(slP>0) {
        var pl = calcProjPL(slP);
        var txt = slP.toFixed(2);
        if(cfdSetup || cfdTrade) txt += " (" + (pl>=0?"+":"") + CUR + pl.toFixed(2) + ")";
        G("dlSL").querySelector(".v").textContent=txt;
    }
    if(tpP>0) {
        var pl = calcProjPL(tpP);
        var txt = tpP.toFixed(2);
        if(cfdSetup || cfdTrade) txt += " (" + (pl>=0?"+":"") + CUR + pl.toFixed(2) + ")";
        G("dlTP").querySelector(".v").textContent=txt;
    }
    if(entP>0) G("dlEN").querySelector(".v").textContent=entP.toFixed(2);
}

function calcProjPL(targetPrice){
    // Calculate P/L if trade was closed at targetPrice
    // Formula: (PriceDiff / Entry) * Amount * Levarge
    var dir = cfdTrade ? cfdTrade.dir : cfdDir;
    var entry = cfdTrade ? cfdTrade.entry : entP;
    if(!dir || !entry) return 0;
    
    var diff = (dir==="buy") ? (targetPrice - entry) : (entry - targetPrice);
    return (diff / entry) * cfdAmt * cfdMul;
}

function updCFDCalc(){
    var vol = cfdAmt * cfdMul;
    G("cVol").textContent = vol.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
    // Also update P/L projections if setting up
    if(cfdSetup) updValLabels();
}



function hideLines(){
    ["dlTP","dlEN","dlSL"].forEach(function(id){G(id).classList.remove("on");});
}

function updLines(){
    var wrap=G("chartWrap");if(!wrap||!series)return;var h=wrap.clientHeight;
    // During setup, Entry follows current price
    if(cfdSetup && !cfdTrade) entP = price;
    
    try{
        var enY=priceToY(cfdTrade?cfdTrade.entry:entP);
        var slY=priceToY(cfdTrade?cfdTrade.sl:slP); // Use trade SL or setup SL
        var tpY=priceToY(cfdTrade?cfdTrade.tp:tpP);
        
        if(enY!==null) G("dlEN").style.top=Math.max(0,Math.min(h-28,enY-14))+"px";
        if(slY!==null) G("dlSL").style.top=Math.max(0,Math.min(h-28,slY-14))+"px";
        if(tpY!==null) G("dlTP").style.top=Math.max(0,Math.min(h-28,tpY-14))+"px";
        
        if(cfdSetup && !cfdTrade) updValLabels();
        
    }catch(e){}
}

function execCFD(){
    if(!cfdDir){toast("Select direction first","err");return;}
    if(cfdTrade){toast("Trade active!","err");return;}
    var margin=cfdAmt;
    if(margin>bal){toast("Insufficient balance!","err");return;}
    
    // Final Entry Price is market price at execution
    entP=price; 
    
    // Validate SL Constraint again at execution time
    if(cfdDir==="buy" && slP > entP*0.98){
         // If current SL is invalid (too close), force it or error? user said "dragdrop", implies manual.
         // Let's just warn or clamp? 
         // Constraint: "SL live price thi 2% vadhare... niche lai shakay" -> SL <= Price - 2%
         if(slP > entP*0.98) { toast("SL must be at least 2% below Entry","err"); return; }
    } else if(cfdDir==="sell" && slP < entP*1.02){
         if(slP < entP*1.02) { toast("SL must be at least 2% above Entry","err"); return; }
    }
    
    // Lot calculation
    var lot = (cfdAmt * cfdMul) / price;
    
    bal-=margin;syncBal();updUI();
    
    cfdTrade={dir:cfdDir,amount:margin,lot:lot,lev:cfdMul,entry:entP,sl:slP,tp:tpP};
    
    // Create Chart Lines
    // (cfdLine removed per user request)
    cfdLine=null;
    
    // Re-create SL/TP lines using chart API (cleaner than HTML overlays for active trade?)
    // User requested lines "like photo". Photo shows Drag/Drop overlays.
    // AND user said "pachi te na batave" (don't show drag lines after trade? Or show fixed lines?)
    // User: "trade purna thaya pachi te na batave" (Hide lines AFTER trade completes).
    // User: "CFD mode ma live chart ma... ek trade line batave" (Show ONE trade line at entry price).
    // User also says "SL/ST drag&drop line trading pehla batave" (Show drag lines BEFORE trading).
    // So: BEFORE trade -> HTML Drag Lines. AFTER trade -> Chart Lines (Fixed) OR HTML Lines (Non-draggable).
    // Implementation: Hide HTML lines, Create Chart API lines for Entry, SL, TP.
    
    hideLines(); // Hide HTML drag lines
    cfdSetup=false; // Exit setup mode
    
    // Create Chart API Lines
    if(slLine) series.removePriceLine(slLine);
    if(tpLine) series.removePriceLine(tpLine);
    
    slLine=series.createPriceLine({price:slP,color:"#ef5350",lineWidth:1,lineStyle:2,axisLabelVisible:true,title:"SL"});
    tpLine=series.createPriceLine({price:tpP,color:"#26a69a",lineWidth:1,lineStyle:2,axisLabelVisible:true,title:"TP"});
    
    G("cTradeBtn").style.display="none";
    G("cfdStat").classList.add("on");G("csDir").textContent=cfdDir.toUpperCase();
    G("csEntry").textContent=entP.toFixed(2);
    
    dbPlace("cfd",cfdDir,margin,entP,cfdTrade);toast(cfdDir.toUpperCase()+" @"+entP.toFixed(2),"ok");
}

function updCFD(){G("csCurr").textContent=price.toFixed(2);var p=cfdPnL();var el=G("csPL");el.textContent=(p>=0?"+":"")+CUR+p.toFixed(0);el.className="vl "+(p>=0?"win":"lose");updLines();}
function cfdPnL(){if(!cfdTrade)return 0;var d=cfdTrade.dir==="buy"?price-cfdTrade.entry:cfdTrade.entry-price;return(d/cfdTrade.entry)*cfdTrade.amount*cfdTrade.lev;}
function chkSLTP(){if(!cfdTrade)return;if(cfdTrade.dir==="buy"){if(price<=cfdTrade.sl)exitCFD("sl");else if(price>=cfdTrade.tp)exitCFD("tp");}else{if(price>=cfdTrade.sl)exitCFD("sl");else if(price<=cfdTrade.tp)exitCFD("tp");}}
function exitCFD(reason){
    var p=cfdPnL();bal+=cfdTrade.amount+p;syncBal();updUI();hideLines();
    toast((reason==="sl"?"SL HIT ":reason==="tp"?"TP HIT ":"Closed ")+(p>=0?"+":"")+CUR+p.toFixed(0),p>=0?"ok":"err");
    dbClose(cfdTrade.db_id,price,p>=0?"won":"lost",p);
    
    // Remove Chart Lines
    if(cfdLine) try{series.removePriceLine(cfdLine);}catch(e){}
    if(slLine) try{series.removePriceLine(slLine);}catch(e){}
    if(tpLine) try{series.removePriceLine(tpLine);}catch(e){}
    cfdLine=null;slLine=null;tpLine=null;
    
    G("cTradeBtn").style.display="";
    selCFDDir(null); // Reset selection
    G("cUpBtn").style.border = "none";
    G("cDnBtn").style.border = "none";
    
    G("cfdStat").classList.remove("on");
    cfdTrade=null;cfdDir=null;
}

// === DRAG SL/TP (using coordinateToPrice) ===
function initDrag(){
    ["dlSL","dlTP"].forEach(function(id){
        var el=G(id);var dragging=false;
        function start(e){
            if(!el.classList.contains("on"))return;
            if(cfdTrade)return; // Disable drag if trade active
            dragging=true;e.preventDefault();document.addEventListener("mousemove",mv);document.addEventListener("mouseup",end);document.addEventListener("touchmove",mv,{passive:false});document.addEventListener("touchend",end);
        }
        function mv(e){if(!dragging)return;e.preventDefault();
            var wrap=G("chartWrap");var rect=wrap.getBoundingClientRect();
            var y=(e.touches?e.touches[0].clientY:e.clientY)-rect.top;
            var np=yToPrice(y);
            if(np===null)return;
            if(id==="dlSL"){
                var ref=cfdTrade?cfdTrade.entry:entP;
                // Enforce 2% constraint relative to Entry Price (ref)
                if(cfdDir==="buy"){
                    // SL must be BELOW entry by at least 2%? User said "2% vyahare... niche".
                    // "Live price thi 2% vadhare... niche" -> Distance > 2%.
                    // So SL <= Ref * 0.98.
                    // But if dragging, we want to LIMIT it.
                    // Max valid SL = Ref * 0.98.
                    np=Math.min(np, ref*0.98); 
                }
                else{
                    // Sell: SL must be ABOVE entry by at least 2%.
                    // Min valid SL = Ref * 1.02.
                    np=Math.max(np, ref*1.02);
                }
                slP=np;el.querySelector(".v").textContent=slP.toFixed(2);if(cfdTrade)cfdTrade.sl=slP;
            }else{
                // TP Constraint: User said "Take Profit ne dragdrop karine game tya lai shakay" (TP can be dragged anywhere).
                // So no constraint on TP.
                tpP=np;el.querySelector(".v").textContent=tpP.toFixed(2);if(cfdTrade)cfdTrade.tp=tpP;
            }
            if(!cfdTrade) updValLabels(); // Update text setup
            updLines();
        }
        function end(){dragging=false;document.removeEventListener("mousemove",mv);document.removeEventListener("mouseup",end);document.removeEventListener("touchmove",mv);document.removeEventListener("touchend",end);}
        el.addEventListener("mousedown",start);el.addEventListener("touchstart",start,{passive:false});
    });
}

// === INDICATOR CALCULATIONS ===
function cls(){return candles.map(function(d){return d.close||d.value;});}
function calcSMA(s,p){var r=[];for(var i=p-1;i<s.length;i++){var sum=0;for(var j=0;j<p;j++)sum+=s[i-j];r.push({time:candles[i].time,value:sum/p});}return r;}
function calcEMA(s,p){var r=[],m=2/(p+1);var e=s[0];r.push({time:candles[0].time,value:e});for(var i=1;i<s.length;i++){e=(s[i]-e)*m+e;r.push({time:candles[i].time,value:e});}return r;}
function calcWMA(s,p){var r=[];for(var i=p-1;i<s.length;i++){var sum=0,w=0;for(var j=0;j<p;j++){sum+=s[i-j]*(p-j);w+=(p-j);}r.push({time:candles[i].time,value:sum/w});}return r;}
function calcDEMA(s,p){var e1=calcEMA(s,p),e1v=e1.map(function(x){return x.value;}),e2=calcEMA(e1v,p),r=[],o=e1.length-e2.length;for(var i=0;i<e2.length;i++)r.push({time:e2[i].time,value:2*e1[i+o].value-e2[i].value});return r;}
function calcTEMA(s,p){var e1=calcEMA(s,p),e1v=e1.map(function(x){return x.value;}),e2=calcEMA(e1v,p),e2v=e2.map(function(x){return x.value;}),e3=calcEMA(e2v,p),r=[],o1=e1.length-e2.length,o2=e2.length-e3.length;for(var i=0;i<e3.length;i++)r.push({time:e3[i].time,value:3*e1[i+o1+o2].value-3*e2[i+o2].value+e3[i].value});return r;}
function calcSMMA(s,p){var r=[];var v=0;for(var i=0;i<p;i++)v+=s[i];v/=p;r.push({time:candles[p-1].time,value:v});for(var i2=p;i2<s.length;i2++){v=(v*(p-1)+s[i2])/p;r.push({time:candles[i2].time,value:v});}return r;}
function calcHull(s,p){var h=Math.floor(p/2),sq=Math.floor(Math.sqrt(p));var w1=calcWMA(s,h),w2=calcWMA(s,p),d=[],o=w1.length-w2.length;for(var i=0;i<w2.length;i++)d.push(2*w1[i+o].value-w2[i].value);if(d.length<sq)return calcSMA(s,p);var hull=calcWMA(d,sq),to=s.length-hull.length;return hull.map(function(v,i){return{time:candles[i+to].time,value:v.value};});}
function calcBB(s,p,dev){var sma=calcSMA(s,p),u=[],l=[];for(var i=0;i<sma.length;i++){var idx=i+p-1;var v=0;for(var j=0;j<p;j++)v+=Math.pow(s[idx-j]-sma[i].value,2);var std=Math.sqrt(v/p);u.push({time:sma[i].time,value:sma[i].value+dev*std});l.push({time:sma[i].time,value:sma[i].value-dev*std});}return{mid:sma,upper:u,lower:l};}
function calcRSI(s,p){var r=[];var ag=0,al=0;for(var i=1;i<=p;i++){var c=s[i]-s[i-1];if(c>0)ag+=c;else al+=Math.abs(c);}ag/=p;al/=p;r.push({time:candles[p].time,value:al===0?100:100-100/(1+ag/al)});for(var i2=p+1;i2<s.length;i2++){var c2=s[i2]-s[i2-1];ag=(ag*(p-1)+(c2>0?c2:0))/p;al=(al*(p-1)+(c2<0?Math.abs(c2):0))/p;r.push({time:candles[i2].time,value:al===0?100:100-100/(1+ag/al)});}return r;}
function calcMACD(s,f,sl,sg){var ef=calcEMA(s,f),es=calcEMA(s,sl),ml=[],o=ef.length-es.length;for(var i=0;i<es.length;i++)ml.push({time:es[i].time,value:ef[i+o].value-es[i].value});var mv=ml.map(function(m){return m.value;}),sgl=calcEMA(mv,sg),hist=[],so=ml.length-sgl.length;for(var i2=0;i2<sgl.length;i2++){var v=ml[i2+so].value-sgl[i2].value;hist.push({time:sgl[i2].time,value:v,color:v>=0?"#26a69a":"#ef5350"});}return{macd:ml,signal:sgl,hist:hist};}
function calcStoch(kp,dp){var c=cls(),k=[];for(var i=kp-1;i<candles.length;i++){var h=-Infinity,l=Infinity;for(var j=0;j<kp;j++){h=Math.max(h,candles[i-j].high||candles[i-j].value);l=Math.min(l,candles[i-j].low||candles[i-j].value);}k.push({time:candles[i].time,value:h===l?50:((c[i]-l)/(h-l))*100});}var kv=k.map(function(x){return x.value;}),d=[];for(var i2=dp-1;i2<kv.length;i2++){var s=0;for(var j2=0;j2<dp;j2++)s+=kv[i2-j2];d.push({time:k[i2].time,value:s/dp});}return{k:k,d:d};}
function calcATR(p){var r=[];var a=0;for(var i=1;i<candles.length;i++){var h=candles[i].high||candles[i].value,l=candles[i].low||candles[i].value,pc=candles[i-1].close||candles[i-1].value;var tr=Math.max(h-l,Math.abs(h-pc),Math.abs(l-pc));if(i<p)a+=tr;else if(i===p){a=(a+tr)/p;r.push({time:candles[i].time,value:a});}else{a=(a*(p-1)+tr)/p;r.push({time:candles[i].time,value:a});}}return r;}
function calcADX(p){var r=[];var sTR=0,sPDI=0,sNDI=0,adx=0;for(var i=1;i<candles.length;i++){var h=candles[i].high||candles[i].value,l=candles[i].low||candles[i].value,ph=candles[i-1].high||candles[i-1].value,pl=candles[i-1].low||candles[i-1].value,pc=candles[i-1].close||candles[i-1].value;var tr=Math.max(h-l,Math.abs(h-pc),Math.abs(l-pc));var pDM=h-ph>pl-l?Math.max(h-ph,0):0,nDM=pl-l>h-ph?Math.max(pl-l,0):0;if(i<=p){sTR+=tr;sPDI+=pDM;sNDI+=nDM;}else{sTR=sTR-sTR/p+tr;sPDI=sPDI-sPDI/p+pDM;sNDI=sNDI-sNDI/p+nDM;}if(i>=p){var pv=sTR===0?0:(sPDI/sTR)*100,nv=sTR===0?0:(sNDI/sTR)*100,dx=pv+nv===0?0:Math.abs(pv-nv)/(pv+nv)*100;if(i<p*2)adx+=dx;else if(i===p*2){adx=(adx+dx)/p;r.push({time:candles[i].time,value:adx});}else{adx=(adx*(p-1)+dx)/p;r.push({time:candles[i].time,value:adx});}}}return r;}
function calcCCI(s,p){var r=[];for(var i=p-1;i<s.length;i++){var sum=0;for(var j=0;j<p;j++)sum+=s[i-j];var mean=sum/p;var md=0;for(var j2=0;j2<p;j2++)md+=Math.abs(s[i-j2]-mean);md/=p;r.push({time:candles[i].time,value:md===0?0:(s[i]-mean)/(0.015*md)});}return r;}
function calcMom(s,p){var r=[];for(var i=p;i<s.length;i++)r.push({time:candles[i].time,value:s[i]-s[i-p]});return r;}
function calcROC(s,p){var r=[];for(var i=p;i<s.length;i++)r.push({time:candles[i].time,value:s[i-p]===0?0:((s[i]-s[i-p])/s[i-p])*100});return r;}
function calcWR(p){var c=cls(),r=[];for(var i=p-1;i<candles.length;i++){var h=-Infinity,l=Infinity;for(var j=0;j<p;j++){h=Math.max(h,candles[i-j].high||candles[i-j].value);l=Math.min(l,candles[i-j].low||candles[i-j].value);}r.push({time:candles[i].time,value:h===l?-50:((h-c[i])/(h-l))*-100});}return r;}
function calcMFI(p){var r=[];for(var i=p;i<candles.length;i++){var pf=0,nf=0;for(var j=0;j<p;j++){var tp1=((candles[i-j].high||candles[i-j].value)+(candles[i-j].low||candles[i-j].value)+(candles[i-j].close||candles[i-j].value))/3;var tp0=i-j-1>=0?((candles[i-j-1].high||candles[i-j-1].value)+(candles[i-j-1].low||candles[i-j-1].value)+(candles[i-j-1].close||candles[i-j-1].value))/3:tp1;if(tp1>tp0)pf+=tp1*1000;else nf+=tp1*1000;}r.push({time:candles[i].time,value:nf===0?100:100-100/(1+pf/nf)});}return r;}
function calcAO(f,sl){var c=cls(),r=[];for(var i=sl-1;i<c.length;i++){var fs=0,ss=0;for(var j=0;j<f;j++)fs+=c[i-j];for(var j2=0;j2<sl;j2++)ss+=c[i-j2];var v=fs/f-ss/sl;r.push({time:candles[i].time,value:v,color:v>=0?"#26a69a":"#ef5350"});}return r;}
function calcDPO(s,p){var sma=calcSMA(s,p),sh=Math.floor(p/2)+1,r=[];if(sma.length<=sh)return calcSMA(s,p);for(var i=0;i<sma.length-sh;i++)r.push({time:sma[i].time,value:s[i+p-1]-sma[i+sh].value});return r.length?r:calcSMA(s,p);}
function calcTRIX(s,p){var e1=calcEMA(s,p),e1v=e1.map(function(x){return x.value;}),e2=calcEMA(e1v,p),e2v=e2.map(function(x){return x.value;}),e3=calcEMA(e2v,p),r=[];for(var i=1;i<e3.length;i++)r.push({time:e3[i].time,value:e3[i-1].value===0?0:((e3[i].value-e3[i-1].value)/e3[i-1].value)*10000});return r;}
function calcStochRSI(s,p,kp,dp){var rsi=calcRSI(s,p),rv=rsi.map(function(x){return x.value;}),k=[];for(var i=p-1;i<rv.length;i++){var h=-Infinity,l=Infinity;for(var j=0;j<p;j++){h=Math.max(h,rv[i-j]);l=Math.min(l,rv[i-j]);}k.push({time:rsi[i].time,value:h===l?50:((rv[i]-l)/(h-l))*100});}var kv=k.map(function(x){return x.value;}),d=[];for(var i2=dp-1;i2<kv.length;i2++){var sum=0;for(var j2=0;j2<dp;j2++)sum+=kv[i2-j2];d.push({time:k[i2].time,value:sum/dp});}return{k:k,d:d};}
function calcVortex(p){var r=[];for(var i=p;i<candles.length;i++){var vp=0,vn=0,tr=0;for(var j=0;j<p;j++){var h=candles[i-j].high||candles[i-j].value,l=candles[i-j].low||candles[i-j].value,ph2=i-j-1>=0?candles[i-j-1].high||candles[i-j-1].value:h,pl2=i-j-1>=0?candles[i-j-1].low||candles[i-j-1].value:l,pc2=i-j-1>=0?candles[i-j-1].close||candles[i-j-1].value:candles[i-j].value;vp+=Math.abs(h-pl2);vn+=Math.abs(l-ph2);tr+=Math.max(h-l,Math.abs(h-pc2),Math.abs(l-pc2));}r.push({time:candles[i].time,value:tr===0?0:(vp/tr)-(vn/tr)});}return r;}
function calcPSAR(step,max){var r=[];var af=step,ep=candles[0].high||candles[0].value,sar=candles[0].low||candles[0].value,isL=true;for(var i=1;i<candles.length;i++){var h=candles[i].high||candles[i].value,l=candles[i].low||candles[i].value;sar+=af*(ep-sar);if(isL){if(l<sar){isL=false;sar=ep;ep=l;af=step;}else{if(h>ep){ep=h;af=Math.min(af+step,max);}sar=Math.min(sar,candles[i-1].low||candles[i-1].value);}}else{if(h>sar){isL=true;sar=ep;ep=h;af=step;}else{if(l<ep){ep=l;af=Math.min(af+step,max);}sar=Math.max(sar,candles[i-1].high||candles[i-1].value);}}r.push({time:candles[i].time,value:sar});}return r;}
function calcST(p,m){var atr=calcATR(p),r=[];var st=0,pst=0,pc=0;var o=candles.length-atr.length;for(var i=0;i<atr.length;i++){var di=i+o,hl2=((candles[di].high||candles[di].value)+(candles[di].low||candles[di].value))/2,ub=hl2+m*atr[i].value,lb=hl2-m*atr[i].value,cl2=candles[di].close||candles[di].value;st=i===0?(cl2>hl2?lb:ub):(pst===pc||cl2>pst?lb:ub);pst=st;pc=cl2;r.push({time:candles[di].time,value:st});}return r;}

// === APPLY/REMOVE INDICATORS (FIXED: scaleMargins on priceScale) ===
function recalcOscScales() {
    var oscs = [];
    var uids = Object.keys(actInds);
    for(var i=0; i<uids.length; i++){
        var type = actInds[uids[i]].type;
        if(INDS[type] && INDS[type].c === "oscillator") {
            oscs.push(uids[i]);
        }
    }
    
    var n = oscs.length;
    if(n === 0) {
        try{ chart.priceScale("right").applyOptions({scaleMargins:{top:0.1,bottom:0.1}}); }catch(e){}
        oscScaleSet = false;
        return;
    }
    
    oscScaleSet = true;
    var oscHeight = 0.2;
    var mainBottom = Math.min(0.8, n * oscHeight);
    
    try{ chart.priceScale("right").applyOptions({scaleMargins:{top:0.05, bottom: mainBottom + 0.05}}); }catch(e){}
    
    for(var i=0; i<n; i++){
        var topMargin = 1 - mainBottom + (i * oscHeight);
        var botMargin = mainBottom - ((i + 1) * oscHeight);
        
        topMargin = Math.max(0, topMargin);
        botMargin = Math.max(0, botMargin);
        try{ chart.priceScale(oscs[i]).applyOptions({scaleMargins:{top:topMargin + 0.01, bottom: botMargin}}); }catch(e){}
    }
}
function applyInd(){
    var id=curInd; // curInd is just the TYPE for new ones, or UID for existing
    var s=curSet;
    var c=cls();
    var isNew = !actInds[id]; // If it's a UID, it exists. If it's a type, it might not.
    // Wait, reusing applyInd logic carefully.
    
    // Logic: if curInd is a known type Key (e.g. "sma"), create NEW UID.
    // If curInd is a UID (e.g. "sma_123"), update existing.
    
    var uid, type;
    if(INDS[id]) { // It is a type name (new indicator)
        type = id;
        uid = type + "_" + Date.now();
    } else { // It is an existing UID
        uid = id;
        type = actInds[uid].type;
    }

    // Remove old series if updating existing (to re-add with new settings)
    if(indSeries[uid]){
        if(Array.isArray(indSeries[uid])) indSeries[uid].forEach(function(x){try{chart.removeSeries(x);}catch(e){}});
        else try{chart.removeSeries(indSeries[uid]);}catch(e){}
        delete indSeries[uid];
    }
    
    try{
    function addL(d,col,w){var sr=chart.addLineSeries({color:col,lineWidth:w||2,priceLineVisible:false});sr.setData(d);return sr;}
    function addO(d,col){var sr=chart.addLineSeries({color:col,lineWidth:2,priceLineVisible:false,priceScaleId:uid});sr.setData(d);return sr;}
    function addHO(d){var sr=chart.addHistogramSeries({priceScaleId:uid});sr.setData(d);return sr;}
    
    // Use 'type' instead of 'id' for switching logic
    if(type==="sma")indSeries[uid]=addL(calcSMA(c,s.period),s.color);
    else if(type==="ema")indSeries[uid]=addL(calcEMA(c,s.period),s.color);
    else if(type==="wma")indSeries[uid]=addL(calcWMA(c,s.period),s.color);
    else if(type==="dema")indSeries[uid]=addL(calcDEMA(c,s.period),s.color);
    else if(type==="tema")indSeries[uid]=addL(calcTEMA(c,s.period),s.color);
    else if(type==="smma")indSeries[uid]=addL(calcSMMA(c,s.period),s.color);
    else if(type==="hull")indSeries[uid]=addL(calcHull(c,s.period),s.color);
    else if(type==="vwma")indSeries[uid]=addL(calcSMA(c,s.period),s.color);
    else if(type==="bb"){var bb=calcBB(c,s.period,s.deviation);indSeries[uid]=[addL(bb.upper,s.color[0],1),addL(bb.mid,s.color[1],1),addL(bb.lower,s.color[2],1)];}
    else if(type==="keltner"){var ek=calcEMA(c,s.period),ak=calcATR(s.period),uk=[],lk=[],ok=ek.length-ak.length;for(var ik=0;ik<ak.length;ik++){uk.push({time:ak[ik].time,value:ek[ik+ok].value+s.mult*ak[ik].value});lk.push({time:ak[ik].time,value:ek[ik+ok].value-s.mult*ak[ik].value});}indSeries[uid]=[addL(uk,s.color[0],1),addL(lk,s.color[1],1)];}
    else if(type==="envelopes"){var sma=calcSMA(c,s.period),p2=s.percent/100;indSeries[uid]=[addL(sma.map(function(x){return{time:x.time,value:x.value*(1+p2)};}),s.color[0],1),addL(sma.map(function(x){return{time:x.time,value:x.value*(1-p2)};}),s.color[1],1)];}
    else if(type==="psar"){var sr2=chart.addLineSeries({color:s.color,lineWidth:0,priceLineVisible:false,pointMarkersVisible:true,pointMarkersRadius:2});sr2.setData(calcPSAR(s.step,s.max));indSeries[uid]=sr2;}
    else if(type==="ichimoku"){var ti=calcSMA(c,s.tenkan),ki=calcSMA(c,s.kijun);indSeries[uid]=[addL(ti,s.color[0],1),addL(ki,s.color[1],1)];}
    else if(type==="alligator"){indSeries[uid]=[addL(calcSMMA(c,s.jaw),s.color[0],1),addL(calcSMMA(c,s.teeth),s.color[1],1),addL(calcSMMA(c,s.lips),s.color[2],1)];}
    else if(type==="supertrend")indSeries[uid]=addL(calcST(s.period,s.mult),s.color);
    else if(type==="pivots"){var la=candles[candles.length-1],hh=la.high||la.value,ll=la.low||la.value,cc=la.close||la.value,piv=(hh+ll+cc)/3;indSeries[uid]=[series.createPriceLine({price:piv,color:s.color[0],lineWidth:1,lineStyle:2,title:"P"}),series.createPriceLine({price:2*piv-ll,color:s.color[1],lineWidth:1,lineStyle:2,title:"R1"}),series.createPriceLine({price:2*piv-hh,color:s.color[2],lineWidth:1,lineStyle:2,title:"S1"})];}
    else if(type==="rsi")indSeries[uid]=addO(calcRSI(c,s.period),s.color);
    else if(type==="macd"){var m=calcMACD(c,s.fast,s.slow,s.signal);indSeries[uid]=[addO(m.macd,s.color[0]),addO(m.signal,s.color[1]),addHO(m.hist)];}
    else if(type==="stoch"){var st=calcStoch(s.kPeriod,s.dPeriod);indSeries[uid]=[addO(st.k,s.color[0]),addO(st.d,s.color[1])];}
    else if(type==="stochrsi"){var sr3=calcStochRSI(c,s.period,s.kPeriod,s.dPeriod);indSeries[uid]=[addO(sr3.k,s.color[0]),addO(sr3.d,s.color[1])];}
    else if(type==="adx")indSeries[uid]=addO(calcADX(s.period),s.color);
    else if(type==="atr")indSeries[uid]=addO(calcATR(s.period),s.color);
    else if(type==="cci"){var tp=candles.map(function(d){return((d.high||d.value)+(d.low||d.value)+(d.close||d.value))/3;});indSeries[uid]=addO(calcCCI(tp,s.period),s.color);}
    else if(type==="momentum")indSeries[uid]=addO(calcMom(c,s.period),s.color);
    else if(type==="roc")indSeries[uid]=addO(calcROC(c,s.period),s.color);
    else if(type==="williams")indSeries[uid]=addO(calcWR(s.period),s.color);
    else if(type==="mfi")indSeries[uid]=addO(calcMFI(s.period),s.color);
    else if(type==="awesome")indSeries[uid]=addHO(calcAO(s.fast,s.slow));
    else if(type==="dpo")indSeries[uid]=addO(calcDPO(c,s.period),s.color);
    else if(type==="trix")indSeries[uid]=addO(calcTRIX(c,s.period),s.color);
    else if(type==="vortex")indSeries[uid]=addO(calcVortex(s.period),s.color);
    }catch(e){console.error("Ind err:",id,e);toast("Error: "+id,"err");return;}
    
    actInds[uid] = { type: type, settings: JSON.parse(JSON.stringify(s)) };
    recalcOscScales();
    toast(INDS[type].n+" applied","ok");
    cModal("isModal");
    renderInds();
    renderChartInds();
}

function removeInd(uid){
    if(!uid) uid=curInd;
    if(!actInds[uid]) return;
    
    if(indSeries[uid]){
        if(actInds[uid].type==="pivots"){indSeries[uid].forEach(function(l){try{series.removePriceLine(l);}catch(e){}});}
        else if(Array.isArray(indSeries[uid]))indSeries[uid].forEach(function(x){try{chart.removeSeries(x);}catch(e){}});
        else try{chart.removeSeries(indSeries[uid]);}catch(e){}
        delete indSeries[uid];
    }
    delete actInds[uid];
    recalcOscScales();
    toast("Removed","ok");
    cModal("isModal");
    renderInds();
    renderChartInds();
}

function openIS(id, forceNew){
    // If forceNew is true, we want to create a new indicator of type 'id'
    // If id is a UID, we just edit it (forceNew doesn't apply)
    
    var type = id;
    var uid = null;
    var instances = [];
    
    // Check if id is a known type
    if(INDS[id]){
        type = id;
        // Find existing instances of this type
        var auids=Object.keys(actInds);
        for(var ai=0;ai<auids.length;ai++){
            if(actInds[auids[ai]].type===type) instances.push({uid:auids[ai], s:actInds[auids[ai]].settings});
        }
    } else {
        // It's a UID
        if(actInds[id]){
            uid = id;
            type = actInds[id].type;
        } else {
            return; // invalid
        }
    }

    // Logic:
    // 1. If it's a UID -> Edit Mode
    // 2. If it's a Type AND forceNew -> Create Mode
    // 3. If it's a Type AND NO instances -> Create Mode
    // 4. If it's a Type AND instances exist -> Manage Mode (List instances + Add New button)

    if(uid){
        // Edit Mode
        renderEdit(uid);
    } else if(forceNew || instances.length===0){
        // Create Mode
        renderCreate(type);
    } else {
        // Manage Mode
        renderManage(type, instances);
    }
}

function renderManage(type, instances){
    var ind = INDS[type];
    G("iTitle").textContent="Manage "+ind.n;
    var h="";
    h+="<div style=\"margin-bottom:10px\"><button type=\"button\" class=\"abtn\" onclick=\"openIS('"+type+"', true)\"><i class=\"fas fa-plus\"></i> Add New "+ind.n+"</button></div>";
    h+="<div style=\"font-size:.8rem;color:var(--text2);margin-bottom:6px\">Active Indices:</div>";
    
    for(var i=0;i<instances.length;i++){
        var inst=instances[i];
        // Create a label based on key settings (e.g. Period)
        var lbl = ind.n;
        if(inst.s.period) lbl += " ("+inst.s.period+")";
        else if(inst.s.fast && inst.s.slow) lbl += " ("+inst.s.fast+","+inst.s.slow+")";
        
        h+="<div class=\"litem\" style=\"cursor:default\">";
        h+="<span style=\"flex:1\">"+lbl+"</span>";
        h+="<div style=\"display:flex;gap:8px\">";
        h+="<button style=\"background:none;border:none;color:var(--yellow);cursor:pointer\" onclick=\"openIS('"+inst.uid+"')\"><i class=\"fas fa-pen\"></i></button>";
        h+="<button style=\"background:none;border:none;color:var(--red);cursor:pointer\" onclick=\"removeInd('"+inst.uid+"');openIS('"+type+"')\"><i class=\"fas fa-trash\"></i></button>";
        h+="</div></div>";
    }
    G("iSet").innerHTML=h;cModal("indModal");oModal("isModal");
}

function renderCreate(type){
    curInd = type; // Type
    var ind = INDS[type];
    curSet = JSON.parse(JSON.stringify(ind.s));
    renderForm(ind.n, false);
}

function renderEdit(uid){
    curInd = uid; // UID
    var type = actInds[uid].type;
    var ind = INDS[type];
    curSet = JSON.parse(JSON.stringify(actInds[uid].settings));
    renderForm(ind.n, true);
}

function renderForm(name, applied){
   var html="";
    G("iTitle").textContent=name + (applied ? " (Edit)" : "");
    var keys=Object.keys(curSet);
    for(var ki=0;ki<keys.length;ki++){
        var key=keys[ki];if(key==="color")continue;var val=curSet[key];var step=val<1?0.01:val<10?0.5:1;
        html+="<div class=\"sgrp\"><div class=\"slbl\">"+key+"</div><div class=\"srow\"><button class=\"adj\" onclick=\"adjS('"+key+"',-"+step+")\">-</button><input type=\"number\" id=\"set_"+key+"\" value=\""+val+"\" step=\""+step+"\" onchange=\"curSet['"+key+"']=parseFloat(this.value)\"><button class=\"adj\" onclick=\"adjS('"+key+"',"+step+")\">+</button></div></div>";
    }
    if(Array.isArray(curSet.color)){
        for(var ci=0;ci<curSet.color.length;ci++){
            var cVal=curSet.color[ci];
            var lbl="Line "+(ci+1)+" Color";
            if(name==="Bollinger Bands") lbl=["Upper","Mid","Lower"][ci]+" Band";
            if(name==="Keltner Channel" || name==="Envelopes") lbl=["Upper","Lower"][ci]+" Line";
            if(name==="Ichimoku Cloud") lbl=["Tenkan","Kijun"][ci]+" Line";
            if(name==="Alligator") lbl=["Jaw","Teeth","Lips"][ci]+" Line";
            if(name==="Pivot Points") lbl=["P","R1","S1"][ci];
            if(name==="MACD") lbl=["MACD","Signal"][ci];
            if(name==="Stochastic" || name==="Stoch RSI") lbl=["K","D"][ci];
            
            html+="<div class=\"sgrp\"><div class=\"slbl\">"+lbl+"</div><div class=\"cswatches\">";
            for(var cci=0;cci<COLS.length;cci++){
                var cv=COLS[cci];
                html+="<div class=\"csw"+(cVal===cv?" on":"")+"\" data-idx=\""+ci+"\" style=\"background:"+cv+"\" onclick=\"pickCol('"+cv+"',"+ci+")\"></div>";
            }
            html+="</div></div>";
        }
    }else if(curSet.color){
        html+="<div class=\"sgrp\"><div class=\"slbl\">Color</div><div class=\"cswatches\">";
        for(var cci=0;cci<COLS.length;cci++){
            var cv=COLS[cci];
            html+="<div class=\"csw"+(curSet.color===cv?" on":"")+"\" style=\"background:"+cv+"\" onclick=\"pickCol('"+cv+"',-1)\"></div>";
        }
        html+="</div></div>";
    }
    if(applied){
        html+="<div style=\"display:flex;gap:10px;margin-top:10px\"><button type=\"button\" class=\"abtn\" style=\"margin-top:0;flex:1\" onclick=\"applyInd()\">Update</button><button type=\"button\" class=\"rbtn\" style=\"margin-top:0;flex:1\" onclick=\"removeInd('"+curInd+"')\"><i class=\"fas fa-trash-alt\"></i> Remove</button></div>";
    }else{
        html+="<button type=\"button\" class=\"abtn\" style=\"margin-top:10px\" onclick=\"applyInd()\">Apply</button>";
    }
    
    G("iSet").innerHTML=html;cModal("indModal");oModal("isModal");
}
function adjS(k,d){var e=G("set_"+k);if(e){var v=parseFloat(e.value)+d;e.value=v;curSet[k]=v;}}
function pickCol(c, idx){
    if(idx>=0 && Array.isArray(curSet.color)){
         curSet.color[idx]=c;
         var sws=G("iSet").querySelectorAll(".csw[data-idx='"+idx+"']");
         sws.forEach(function(e){e.classList.remove("on");});
         sws.forEach(function(e){if(e.style.background===c||e.style.backgroundColor===c)e.classList.add("on");});
    } else {
         curSet.color=c;
         var sws=G("iSet").querySelectorAll(".csw");
         sws.forEach(function(e){e.classList.remove("on");});
         sws.forEach(function(e){if(e.style.background===c||e.style.backgroundColor===c)e.classList.add("on");});
    }
}

function renderInds(){
    var cats={overlay:[],oscillator:[]};var ids=Object.keys(INDS);
    for(var i=0;i<ids.length;i++){var id=ids[i],ind=INDS[id];(cats[ind.c]||cats.overlay).push({id:id,n:ind.n});}
    
    var h = "";

    h += "<div class=\"itabs\" id=\"iTabs\"><div class=\"itab"+(indCat==="overlay"?" on":"")+"\" onclick=\"indCat='overlay';renderInds()\">Overlay ("+cats.overlay.length+")</div><div class=\"itab"+(indCat==="oscillator"?" on":"")+"\" onclick=\"indCat='oscillator';renderInds()\">Oscillator ("+cats.oscillator.length+")</div></div>";
    
    var list=cats[indCat]||[];
    for(var j=0;j<list.length;j++){var it=list[j];
        h+="<div class=\"litem\" onclick=\"openIS('"+it.id+"')\"><span>"+it.n+"</span><i class=\"fas fa-cog\" style=\"color:var(--text2)\"></i></div>";}
    G("iList").innerHTML=h;
}

function renderChartInds() {
    var c = G("aInds");
    if(!c) return;
    var h = "";
    var uids = Object.keys(actInds);
    uids.forEach(function(uid) {
        var ind = actInds[uid];
        var config = INDS[ind.type];
        if(!config) return;
        var name = config.n;
        if(ind.settings.period) name += " ("+ind.settings.period+")";
        else if(ind.settings.fast && ind.settings.slow) name += " ("+ind.settings.fast+","+ind.settings.slow+")";
        h += "<div class=\"ai-item\">";
        h += "<span class=\"ai-name\" onclick=\"openIS('"+uid+"')\">"+name+"</span>";
        h += "<button class=\"ai-btn\" onclick=\"removeInd('"+uid+"')\"><i class=\"fas fa-times\"></i></button>";
        h += "</div>";
    });
    c.innerHTML = h;
}

// === DRAWING (FIXED: use priceToCoordinate/timeToCoordinate) ===
function initDC(){dCanvas=G("drawCanvas");if(!dCanvas)return;dCtx=dCanvas.getContext("2d");resizeDC();
    dCanvas.addEventListener("click",onDC);
    dCanvas.addEventListener("mousemove",function(e){var r=dCanvas.getBoundingClientRect();mPos.x=e.clientX-r.left;mPos.y=e.clientY-r.top;if(drawMode&&drawPts.length)redrawDC();});
    dCanvas.addEventListener("touchend",function(e){e.preventDefault();var t=e.changedTouches[0];onDC({clientX:t.clientX,clientY:t.clientY});});
    dCanvas.addEventListener("touchmove",function(e){var r=dCanvas.getBoundingClientRect();var t=e.touches[0];mPos.x=t.clientX-r.left;mPos.y=t.clientY-r.top;if(drawMode&&drawPts.length)redrawDC();},{passive:false});
}
function resizeDC(){if(!dCanvas)return;var c=G("chartWrap");if(!c)return;var r=c.getBoundingClientRect();dCanvas.width=Math.max(1,r.width-60);dCanvas.height=Math.max(1,r.height-30);dCanvas.style.width=(r.width-60)+"px";dCanvas.style.height=(r.height-30)+"px";}
function p2y(p){var y=priceToY(p);return y!==null?y:0;}
function t2x(t){var x=timeToX(t);return x!==null?x:0;}
function onDC(e){
    if(!drawMode)return;var rect=dCanvas.getBoundingClientRect();var x=e.clientX-rect.left,y=e.clientY-rect.top;
    var pv=yToPrice(y);var tv=xToTime(x);
    if(pv===null||tv===null){toast("Click on chart area","err");return;}
    drawPts.push({price:pv,time:tv});
    if(drawMode==="hline"){draws.push({t:"hline",price:pv});endDraw("H-Line at "+pv.toFixed(2));}
    else if(drawMode==="vline"){draws.push({t:"vline",time:tv});endDraw("V-Line placed");}
    else if(["trendline","ray","fib","rect"].indexOf(drawMode)>=0&&drawPts.length>=2){draws.push({t:drawMode,p1:drawPts[0],p2:{price:pv,time:tv}});endDraw("Drawn");}
    else if(drawMode==="channel"&&drawPts.length>=3){draws.push({t:"channel",p1:drawPts[0],p2:drawPts[1],p3:{price:pv,time:tv}});endDraw("Channel drawn");}
    else toast("Click next point","ok");
    redrawDC();
}
function endDraw(msg){drawMode=null;drawPts=[];dCanvas.classList.remove("on");if(chart)chart.applyOptions({handleScroll:true,handleScale:true});var db=G("drwBtn");if(db)db.classList.remove("on");toast(msg,"ok");}
function selDraw(id){
    if(id==="clear"){draws=[];drawMode=null;drawPts=[];dCanvas.classList.remove("on");if(chart)chart.applyOptions({handleScroll:true,handleScale:true});var db=G("drwBtn");if(db)db.classList.remove("on");redrawDC();toast("Cleared","ok");cModal("drModal");return;}
    drawMode=id;drawPts=[];dCanvas.classList.add("on");if(chart)chart.applyOptions({handleScroll:false,handleScale:false});var db2=G("drwBtn");if(db2)db2.classList.add("on");
    var msgs={hline:"Click for H-Line",vline:"Click for V-Line",trendline:"Click 2 points",ray:"Click 2 points",fib:"Click 2 points",rect:"Click 2 corners",channel:"Click 3 points"};
    toast(msgs[id]||"Select","ok");cModal("drModal");
}
function redrawDC(){
    if(!dCtx||!dCanvas||!dCanvas.width)return;dCtx.clearRect(0,0,dCanvas.width,dCanvas.height);
    draws.forEach(function(d){dCtx.strokeStyle="#ffc107";dCtx.lineWidth=1.5;dCtx.setLineDash([]);
        if(d.t==="hline"){var y=p2y(d.price);dCtx.setLineDash([6,4]);dCtx.beginPath();dCtx.moveTo(0,y);dCtx.lineTo(dCanvas.width,y);dCtx.stroke();dCtx.fillStyle="#ffc107";dCtx.font="11px sans-serif";dCtx.fillText(d.price.toFixed(2),4,y-4);}
        else if(d.t==="vline"){var x=t2x(d.time);dCtx.setLineDash([6,4]);dCtx.beginPath();dCtx.moveTo(x,0);dCtx.lineTo(x,dCanvas.height);dCtx.stroke();}
        else if(d.t==="trendline"||d.t==="ray"){var x1=t2x(d.p1.time),y1=p2y(d.p1.price),x2=t2x(d.p2.time),y2=p2y(d.p2.price);dCtx.beginPath();dCtx.moveTo(x1,y1);if(d.t==="ray"){var dx=x2-x1,dy=y2-y1,len=Math.sqrt(dx*dx+dy*dy)||1;dCtx.lineTo(x2+dx/len*3000,y2+dy/len*3000);}else dCtx.lineTo(x2,y2);dCtx.stroke();}
        else if(d.t==="fib"){var yy1=p2y(d.p1.price),yy2=p2y(d.p2.price),xx1=t2x(d.p1.time),xx2=t2x(d.p2.time);var lvls=[0,.236,.382,.5,.618,.786,1],cols2=["#ef5350","#ff9800","#ffc107","#26a69a","#2196f3","#9c27b0","#e91e63"];for(var fi=0;fi<lvls.length;fi++){var fy=yy1+(yy2-yy1)*lvls[fi];dCtx.strokeStyle=cols2[fi];dCtx.setLineDash([4,3]);dCtx.beginPath();dCtx.moveTo(Math.min(xx1,xx2),fy);dCtx.lineTo(Math.max(xx1,xx2,dCanvas.width),fy);dCtx.stroke();dCtx.fillStyle=cols2[fi];dCtx.font="10px sans-serif";dCtx.fillText((lvls[fi]*100).toFixed(1)+"%",4,fy-3);}}
        else if(d.t==="rect"){var rx1=t2x(d.p1.time),ry1=p2y(d.p1.price),rx2=t2x(d.p2.time),ry2=p2y(d.p2.price);dCtx.fillStyle="rgba(255,193,7,0.15)";dCtx.fillRect(Math.min(rx1,rx2),Math.min(ry1,ry2),Math.abs(rx2-rx1),Math.abs(ry2-ry1));dCtx.strokeRect(Math.min(rx1,rx2),Math.min(ry1,ry2),Math.abs(rx2-rx1),Math.abs(ry2-ry1));}
        else if(d.t==="channel"){var cx1=t2x(d.p1.time),cy1=p2y(d.p1.price),cx2=t2x(d.p2.time),cy2=p2y(d.p2.price),cy3=p2y(d.p3.price),cdy=cy3-cy1;dCtx.beginPath();dCtx.moveTo(cx1,cy1);dCtx.lineTo(cx2,cy2);dCtx.stroke();dCtx.beginPath();dCtx.moveTo(cx1,cy1+cdy);dCtx.lineTo(cx2,cy2+cdy);dCtx.stroke();dCtx.fillStyle="rgba(255,193,7,0.08)";dCtx.beginPath();dCtx.moveTo(cx1,cy1);dCtx.lineTo(cx2,cy2);dCtx.lineTo(cx2,cy2+cdy);dCtx.lineTo(cx1,cy1+cdy);dCtx.closePath();dCtx.fill();}
    });

    // Draw Preview
    if(drawMode&&drawPts.length>0){
        var p1=drawPts[0];
        var x1=t2x(p1.time),y1=p2y(p1.price);
        var x2=mPos.x,y2=mPos.y; // Current mouse pos
        
        dCtx.strokeStyle="rgba(255, 193, 7, 0.5)";dCtx.lineWidth=1;dCtx.setLineDash([4,4]);
        
        if(drawMode==="trendline"||drawMode==="ray"){
            dCtx.beginPath();dCtx.moveTo(x1,y1);dCtx.lineTo(x2,y2);dCtx.stroke();
        } else if(drawMode==="rect"){
             dCtx.strokeRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
        } else if(drawMode==="fib"){
             var yy1=y1,yy2=y2;
             var lvls=[0,.236,.382,.5,.618,.786,1];
             for(var fi=0;fi<lvls.length;fi++){var fy=yy1+(yy2-yy1)*lvls[fi];dCtx.beginPath();dCtx.moveTo(Math.min(x1,x2),fy);dCtx.lineTo(Math.max(x1,x2,dCanvas.width),fy);dCtx.stroke();}
        } else if(drawMode==="channel"){
             if(drawPts.length===1){
                 dCtx.beginPath();dCtx.moveTo(x1,y1);dCtx.lineTo(x2,y2);dCtx.stroke();
             } else if(drawPts.length===2){
                 var p2=drawPts[1];
                 var x2f=t2x(p2.time),y2f=p2y(p2.price); // fixed 2nd point
                 // Draw base line
                 dCtx.beginPath();dCtx.moveTo(x1,y1);dCtx.lineTo(x2f,y2f);dCtx.stroke();
                 var cdy=y2-y1; // Simple offset
                 dCtx.beginPath();dCtx.moveTo(x1,y1+cdy);dCtx.lineTo(x2f,y2f+cdy);dCtx.stroke();
             }
        }
    }
}
function renderDraws(){var h="";DRAWS.forEach(function(d){h+="<div class=\"litem\" onclick=\"selDraw('"+d.id+"')\"><i class=\"fas "+d.i+"\" style=\"width:24px;color:var(--yellow)\"></i><span>"+d.n+"</span></div>";});G("drList").innerHTML=h;}

// === DB ===
function dbPlace(type,dir,a,entry,obj){
    var payload = {
        asset_id:asset.id,
        direction:dir,
        amount:a,
        entry_price:entry,
        payout_percent:asset.payout_percent||85,
        duration:type==="binary"?dur:0,
        is_demo:IS_DEMO,
        trade_type:type,
        lot_size: obj && obj.lot ? obj.lot : null,
        leverage: obj && obj.lev ? obj.lev : 1,
        sl: obj && obj.sl ? obj.sl : null,
        tp: obj && obj.tp ? obj.tp : null
    };
    fetch("../api/trade/place.php",{
        method:"POST",
        headers:{"Content-Type":"application/json"},
        body:JSON.stringify(payload)
    })
    .then(function(r){return r.json();})
    .then(function(d){
        if(d.success){
            if(obj) {
                obj.db_id=d.trade_id;
                obj.forced_result=d.forced_result;
            }
        } else {
            // Revert balance on failure
            toast("Trade failed: " + (d.error || "Unknown error"), "err");
            bal += a; 
            syncBal(); 
            updUI();
            // Remove the trade from UI if it was binary
            if(type === "binary" && obj) {
                var idx = binTrades.indexOf(obj);
                if(idx !== -1) {
                    binTrades.splice(idx, 1);
                    renderBin();
                    try{if(obj.ts) chart.removeSeries(obj.ts);}catch(e){}
                }
            } else if(type === "cfd" && obj) {
                // CFD Revert logic
                exitCFD("error"); // This might be too complex, better just reset variables
                cfdTrade = null;
                G("cTradeBtn").style.display="";
                G("cfdStat").classList.remove("on");
                if(cfdLine) try{series.removePriceLine(cfdLine);}catch(e){}
                if(slLine) try{series.removePriceLine(slLine);}catch(e){}
                if(tpLine) try{series.removePriceLine(tpLine);}catch(e){}
                cfdLine=null;slLine=null;tpLine=null;
            }
        }
    })
    .catch(function(e){
        // Revert on network error
        console.error(e);
        toast("Network error", "err");
        bal += a; 
        syncBal(); 
        updUI();
         if(type === "binary" && obj) {
            var idx = binTrades.indexOf(obj);
            if(idx !== -1) {
                binTrades.splice(idx, 1);
                renderBin();
                 try{if(obj.ts) chart.removeSeries(obj.ts);}catch(e){}
            }
        }
    });
}
function loadActiveTrades(){
    fetch("../api/trade/active.php?is_demo="+(IS_DEMO?"1":"0"))
    .then(function(r){return r.json();})
    .then(function(d){
        if(d.status==="success" && d.data && d.data.trades) {
            d.data.trades.forEach(function(t){
                if(t.trade_type === "cfd" && !cfdTrade && t.asset_id == asset.id) {
                    // Restore CFD trade for current asset
                    cfdDir = t.direction;
                    cfdAmt = parseFloat(t.amount);
                    cfdMul = parseInt(t.leverage || 1);
                    entP = parseFloat(t.entry_price);
                    slP = parseFloat(t.stop_loss || 0);
                    tpP = parseFloat(t.take_profit || 0);
                    
                    cfdTrade = {
                        db_id: t.id,
                        dir: cfdDir,
                        amount: cfdAmt,
                        lot: parseFloat(t.lot_size || 0),
                        lev: cfdMul,
                        entry: entP,
                        sl: slP,
                        tp: tpP
                    };
                    
                    if(slP > 0) slLine=series.createPriceLine({price:slP,color:"#ef5350",lineWidth:1,lineStyle:2,axisLabelVisible:true,title:"SL"});
                    if(tpP > 0) tpLine=series.createPriceLine({price:tpP,color:"#26a69a",lineWidth:1,lineStyle:2,axisLabelVisible:true,title:"TP"});
                    
                    cfdSetup = false;
                    hideLines();
                    G("cTradeBtn").style.display="none";
                    G("cfdStat").classList.add("on");
                    G("csDir").textContent=cfdDir.toUpperCase();
                    G("csEntry").textContent=entP.toFixed(2);
                    if(G("cAmtInput")) G("cAmtInput").value=cfdAmt;
                    if(G("cMulInput")) G("cMulInput").value=cfdMul;
                    updCFDCalc();
                }
            });
        }
    })
    .catch(function(e){});
}
function dbClose(id,exit,result,profit){
    if(!id)return;
    fetch("../api/trade/close.php",{
        method:"POST",
        headers:{"Content-Type":"application/json"},
        body:JSON.stringify({trade_id:id,exit_price:exit,result:result,profit:profit})
    })
    .then(function(r){return r.json();})
    .then(function(d){
        if(d.success){
            demoBal=parseFloat(d.demo_balance||demoBal);
            
            // Only update live balance if it wasn't a demo trade
            if(ACCT!=="demo" && d.balance !== undefined) {
                 var newBal = parseFloat(d.balance||0) + parseFloat(d.bonus_balance||0);
                 var pen = parseFloat(d.pending_withdrawals||0);
                 liveBal = Math.max(0, newBal - pen);
            }
            
            bal=ACCT==="demo"?demoBal:liveBal;
            updUI();
        }
    })
    .catch(function(e){});
}
function refreshBal(){
    fetch("../api/user/balance.php")
    .then(function(r){return r.json();})
    .then(function(d){
        if(d.success){
            demoBal=parseFloat(d.demo_balance);
            var actualBalance = parseFloat(d.balance)+parseFloat(d.bonus_balance||0);
            var pendingAmt = parseFloat(d.pending_withdrawals||0);
            liveBal=Math.max(0, actualBalance - pendingAmt);
            
            if(!binTrades.length&&!cfdTrade){
                bal=ACCT==="demo"?demoBal:liveBal;
                updUI();
            }
        }
    })
    .catch(function(){});
}
function syncBal(){if(ACCT==="demo")demoBal=bal;else liveBal=bal;}

// === UI ===
function updUI(){
    var fmt = function(v){return v.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});};
    if(G("balDisp")) G("balDisp").textContent=fmt(bal);
    if(G("demoBal")) G("demoBal").textContent=CUR+fmt(demoBal);
    if(G("liveBal")) G("liveBal").textContent=CUR+fmt(liveBal);

    
    if(G("aName")) G("aName").textContent=asset.name;
    if(G("aPay")) G("aPay").textContent=(asset.payout_percent||85)+"%";
    if(G("payPct")) G("payPct").textContent=asset.payout_percent||85;
    if(G("potEarn")) G("potEarn").textContent=(amt*(1+(parseFloat(asset.payout_percent)||85)/100)).toFixed(2);
    if(document.activeElement !== G("aInput") && G("aInput")) G("aInput").value=amt;
    var fmt = function(s){ return s<60?s+"s":s<3600?Math.floor(s/60)+"m":s<86400?Math.floor(s/3600)+"h":s<604800?Math.floor(s/86400)+"D":Math.floor(s/604800)+"W"; };
    G("tVal").textContent=fmt(dur);
    G("tfLbl").textContent=fmt(tf);
}
function renderAssetCats(){
    var cats=["all","crypto","forex","stock","commodity","index"];
    var labels={all:"All",crypto:"Crypto",forex:"Forex",stock:"Stocks",commodity:"Commodities",index:"Indices"};
    var h="";cats.forEach(function(c){h+="<div class=\"as-cat"+(asCatFilter===c?" on":"")+"\" onclick=\"asCatFilter='"+c+"';renderAssetCats();renderAssets()\">"+labels[c]+"</div>";});
    G("asCats").innerHTML=h;
}
function renderAssets(){
    var q=(G("asSearch")?G("asSearch").value:"").toLowerCase();
    var h="";ASSETS.forEach(function(a){
        var cat=a.asset_type||a.category||"crypto";
        if(asCatFilter!=="all"&&cat!==asCatFilter)return;
        if(q&&a.name.toLowerCase().indexOf(q)<0&&a.symbol.toLowerCase().indexOf(q)<0)return;
        var ic=a.icon_color||"#f7931a";
        var letter=(a.symbol||"X").charAt(0);
        var isSel=asset&&asset.id===a.id;
        h+="<div class=\"as-item"+(isSel?" sel":"")+"\" data-id=\""+a.id+"\">";
        h+="<div class=\"as-icon\" style=\"background:"+ic+"\">"+letter+"</div>";
        h+="<div class=\"as-info\"><div class=\"as-sym\">"+a.symbol+"</div><div class=\"as-name\">"+a.name+"</div></div>";
        h+="<div class=\"as-pay\">"+(a.payout_percent||85)+"%</div></div>";
    });
    if(!h)h="<div style=\"grid-column:span 3;text-align:center;padding:20px;color:var(--text2)\">No assets found</div>";
    G("asList").innerHTML=h;
}
function renderModals(){
    var h="";CTYPES.forEach(function(t){h+="<div class=\"oitem"+(t.id===cType?" on":"")+"\" data-id=\""+t.id+"\"><i class=\"fas "+t.i+"\"></i><div>"+t.n+"</div></div>";});G("ctGrid").innerHTML=h;
    h="";TFS.forEach(function(t){h+="<div class=\"oitem"+(t.id===tf?" on":"")+"\" data-id=\""+t.id+"\">"+t.n+"</div>";});G("tfGrid").innerHTML=h;
    renderAssetCats();renderAssets();
    renderInds();renderDraws();
}
function oModal(id){G(id).classList.add("show");}

function toast(msg,type){var e=G("toast");e.textContent=msg;e.className="toast "+type+" show";setTimeout(function(){e.classList.remove("show");},3000);}

// === EVENTS ===
// === EVENTS ===
function initUIEvents(){
    // Navigation & UI calls (Safe to run even if chart fails)
    if(G("menuBtn")) G("menuBtn").onclick=function(){G("sideMenu").classList.add("open");G("menuOv").classList.add("show");};
    if(G("menuCls")) G("menuCls").onclick=G("menuOv").onclick=function(){G("sideMenu").classList.remove("open");G("menuOv").classList.remove("show");};
    
    if(G("accBox")) G("accBox").onclick=function(e){e.stopPropagation();G("accDD").classList.toggle("show");};
    
    // Bind click to the tabs container or individual tabs to toggle dropdown in portrait
    if(G("aselTabs")) {
        G("aselTabs").onclick = function(e){
            var isPortrait = window.innerWidth <= 768 && window.matchMedia("(orientation: portrait)").matches;
            
            // Allow close tab to work natively
            if(e.target.closest('.cls-tab')) return;
            
            var clickedTab = e.target.closest('.asel-tab');
            
            if(isPortrait) {
                // In portrait, the main container acts as a toggle dropdown
                e.stopPropagation();
                
                if(clickedTab && !clickedTab.classList.contains('on')) {
                     // If they clicked an inactive tab in the dropdown, let normal 'switchChartTab' trigger via HTML onclick attribute on the tab itself
                     // We just ensure the dropdown closes automatically
                     this.classList.remove("open");
                     var activeTab = this.querySelector('.asel-tab.on');
                     if(activeTab) activeTab.classList.remove("open-view");
                     return; 
                }
                
                // Toggle Dropdown
                this.classList.toggle("open");
                var activeTab = this.querySelector('.asel-tab.on');
                if(activeTab) {
                    if(this.classList.contains("open")) {
                        activeTab.classList.add("open-view");
                    } else {
                        activeTab.classList.remove("open-view");
                    }
                }
            } else {
                // In Landscape
                if(clickedTab && clickedTab.classList.contains('on')) {
                     // Clicking the active tab in landscape should open the asset modal
                     e.stopPropagation();
                     oModal("asModal");
                }
            }
        };
    }
    
    document.addEventListener("click",function(){
        if(G("accDD")) G("accDD").classList.remove("show");
        if(G("aselTabs") && window.innerWidth <= 768) {
            G("aselTabs").classList.remove("open");
            var activeTab = G("aselTabs").querySelector('.asel-tab.on');
            if(activeTab) activeTab.classList.remove("open-view");
        }
    });
    
    document.querySelectorAll(".tab").forEach(function(b){b.onclick=function(){document.querySelectorAll(".tab").forEach(function(x){x.classList.remove("on");});b.classList.add("on");setMode(b.getAttribute("data-t"));};});
    
    if(G("aselBtn")) G("aselBtn").onclick=function(){oModal("asModal");};
    if(G("asList")) G("asList").onclick=function(e){
        var i=e.target.closest(".as-item");
        if(i&&i.getAttribute("data-id")){
            var selectedAsset = ASSETS.find(function(a){return a.id===parseInt(i.getAttribute("data-id"));})||asset;
            if (isAddingNewTab) {
                // Add new tab
                activeCharts.push(selectedAsset);
                chartDataStore[activeCharts.length-1] = { candles:[], hkData:[], price:0, asset:selectedAsset };
                switchChartTab(activeCharts.length-1);
            } else {
                // Replace current tab
                activeCharts[activeChartIndex] = selectedAsset;
                chartDataStore[activeChartIndex].asset = selectedAsset;
                asset = selectedAsset;
                switchAsset(); // Recalculates indicators and calls updUI
                renderAssetTabs(); // Update header
            }
            cModal("asModal");
            isAddingNewTab = false; // reset
        }
    };
    
    if(G("ctBtn")) G("ctBtn").onclick=function(){oModal("ctModal");};
    if(G("ctGrid")) G("ctGrid").onclick=function(e){var i=e.target.closest(".oitem");if(i){cType=i.getAttribute("data-id");switchChart();renderModals();cModal("ctModal");}};
    
    if(G("tfBtn")) G("tfBtn").onclick=function(){oModal("tfModal");};
    if(G("tfGrid")) G("tfGrid").onclick=function(e){var i=e.target.closest(".oitem");if(i){tf=parseInt(i.getAttribute("data-id"));switchAsset();renderModals();cModal("tfModal");}};
    
    if(G("indBtn")) G("indBtn").onclick=function(){oModal("indModal");};
    if(G("drwBtn")) G("drwBtn").onclick=function(){oModal("drModal");};
    
    // Modal backdrop click to close
    document.querySelectorAll(".modal").forEach(function(m){m.addEventListener("click",function(e){if(e.target===m)m.classList.remove("show");});});
}

function initTradingEvents(){
    // Trading Logic (Depends on chart/variables)
    var times=[5,10,15,30,60,120,180,300,600,900,1800,3600,7200,14400,86400,604800];
    if(G("tUp")) G("tUp").onclick=function(){var i=times.indexOf(dur);if(i<times.length-1)dur=times[i+1];updUI();};
    if(G("tDn")) G("tDn").onclick=function(){var i=times.indexOf(dur);if(i>0)dur=times[i-1];updUI();};
    if(G("aUp")) G("aUp").onclick=function(){amt=Math.min(MAX_AMT,amt+100);updUI();};
    if(G("aDn")) G("aDn").onclick=function(){amt=Math.max(MIN_AMT,amt-100);updUI();};
    
    // Amount Input Event
    if(G("aInput")){
        G("aInput").onchange=function(){
            var val = parseInt(this.value);
            if(isNaN(val) || val < MIN_AMT) val = MIN_AMT;
            if(val > MAX_AMT) val = MAX_AMT;
            amt = val;
            updUI();
        };
        G("aInput").oninput=function(){
             var val = parseInt(this.value);
             if(!isNaN(val)) {
                 amt = val;
                 G("potEarn").textContent=(val*(1+(parseFloat(asset.payout_percent)||85)/100)).toFixed(2);
             }
        };
    }
    
    if(G("upBtn")) G("upBtn").onclick=function(){placeBin("up");};
    if(G("dnBtn")) G("dnBtn").onclick=function(){placeBin("down");};
    
    if(G("cUpBtn")) G("cUpBtn").onclick=function(){selCFDDir("buy");};
    if(G("cDnBtn")) G("cDnBtn").onclick=function(){selCFDDir("sell");};
    if(G("cTradeBtn")) G("cTradeBtn").onclick=function(){execCFD();};
    if(G("cExit")) G("cExit").onclick=function(){exitCFD("manual");};
    
    if(G("cAmtUp")) G("cAmtUp").onclick=function(){cfdAmt=Math.min(MAX_AMT,cfdAmt+10);if(G("cAmtInput"))G("cAmtInput").value=cfdAmt;updCFDCalc();};
    if(G("cAmtDn")) G("cAmtDn").onclick=function(){cfdAmt=Math.max(10,cfdAmt-10);if(G("cAmtInput"))G("cAmtInput").value=cfdAmt;updCFDCalc();};
    if(G("cMulUp")) G("cMulUp").onclick=function(){cfdMul=Math.min(MAX_CFD_MUL,cfdMul+1);if(G("cMulInput"))G("cMulInput").value=cfdMul;updCFDCalc();};
    if(G("cMulDn")) G("cMulDn").onclick=function(){cfdMul=Math.max(MIN_CFD_MUL,cfdMul-1);if(G("cMulInput"))G("cMulInput").value=cfdMul;updCFDCalc();};
    
    if(G("cAmtInput")){
        G("cAmtInput").onchange=function(){
            var val=parseInt(this.value);
            if(isNaN(val)||val<10) val=10;
            if(val>MAX_AMT) val=MAX_AMT;
            cfdAmt=val; this.value=val; updCFDCalc();
        };
        G("cAmtInput").oninput=function(){
             var val=parseInt(this.value);
             if(!isNaN(val)) {cfdAmt=val; updCFDCalc();}
        };
    }
    
    if(G("cMulInput")){
        G("cMulInput").onchange=function(){
            var val=parseInt(this.value);
            if(isNaN(val)||val<MIN_CFD_MUL) val=MIN_CFD_MUL;
            if(val>MAX_CFD_MUL) val=MAX_CFD_MUL;
            cfdMul=val; this.value=val; updCFDCalc();
        };
        G("cMulInput").oninput=function(){
             var val=parseInt(this.value);
             if(!isNaN(val)) {cfdMul=val; updCFDCalc();}
        };
    }
    
    if(G("zIn")) G("zIn").onclick=function(){
        console.log("Zoom In clicked. Chart API present?", !!chart);
        if(chart) {
            var r = chart.timeScale().getVisibleLogicalRange();
            console.log("Current Range:", r);
            if(r && (r.to - r.from) > 4) {
                var d = (r.to - r.from) * 0.2;
                chart.timeScale().setVisibleLogicalRange({from: r.from + d, to: r.to - d});
                console.log("Zoom In applied");
            }
        }
    };
    if(G("zOut")) G("zOut").onclick=function(){
        console.log("Zoom Out clicked. Chart API present?", !!chart);
        if(chart) {
            var r = chart.timeScale().getVisibleLogicalRange();
            console.log("Current Range:", r);
            if(r) {
                var d = (r.to - r.from) * 0.2;
                chart.timeScale().setVisibleLogicalRange({from: r.from - d, to: r.to + d});
                console.log("Zoom Out applied");
            }
        }
    };
    
    initDrag(); // Initialize drag events for SL/TP
    
    // Initial calculation for CFD
    updCFDCalc();
    
    setInterval(function(){
        // Fallback checks just in case trigger missed
        if(cfdTrade) chkSLTP();
    }, 1000);
    
    setInterval(renderBin,1000);setInterval(refreshBal,30000);
    try{if(chart)chart.timeScale().subscribeVisibleTimeRangeChange(function(){redrawDC();});}catch(e){}
}

function setMode(m){
    tMode=m;
    G("binP").classList.toggle("off",m!=="binary");
    G("cfdP").classList.toggle("on",m==="cfd");
    if(m==="cfd"){
        updCFDCalc();
    }
    if(m==="binary"){
        if(!cfdTrade){
            cfdSetup=false;cfdDir=null;
            var tb=G("cTradeBtn");if(tb)tb.style.display="none";
            var cu=G("cUpBtn"),cd=G("cDnBtn");
            if(cu)cu.style.border="none";
            if(cd)cd.style.border="none";
        }
        hideLines();
    }
}
function switchAsset(){clearIndSeries();genData();series.setData(cType==="heikin"?hkData:candles);chart.timeScale().fitContent();reapplyInds();updUI();}
function switchChart(){clearIndSeries();mkSeries();series.setData(cType==="heikin"?hkData:candles);G("ctLbl").textContent=(CTYPES.find(function(c){return c.id===cType;})||{n:"Area"}).n;reapplyInds();}
function clearIndSeries(){var ids=Object.keys(indSeries);for(var i=0;i<ids.length;i++){var id=ids[i];if(id==="pivots"){if(indSeries[id])indSeries[id].forEach(function(l){try{series.removePriceLine(l);}catch(e){}});}else if(Array.isArray(indSeries[id]))indSeries[id].forEach(function(x){try{chart.removeSeries(x);}catch(e){}});else try{chart.removeSeries(indSeries[id]);}catch(e){}}indSeries={};oscScaleSet=false;}
function reapplyInds(){var uids=Object.keys(actInds);for(var i=0;i<uids.length;i++){curInd=uids[i];curSet=JSON.parse(JSON.stringify(actInds[uids[i]].settings));applyInd();}}

// === MODAL ===
function cModal(id){
    var el=G(id);
    if(el.classList.contains("show")) el.classList.remove("show");
    else {
        // Close others
        document.querySelectorAll(".modal").forEach(function(m){m.classList.remove("show");});
        el.classList.add("show");
        if(id==="asModal"){ renderAssetCats(); renderAssets(); }
    }
}

// === MULTI-TAB LOGIC ===
function renderAssetTabs(){
    var h="";
    activeCharts.forEach(function(a, i){
        var ic=a.icon_color||"#f7931a";
        var letter=(a.symbol||"X").charAt(0);
        var isOn = (i === activeChartIndex) ? " on" : "";
        
        // Let's ensure the dropdown state isn't reset improperly on render, but start closed.
        // We add the chevron icon inside every tab, but CSS controls its visibility (only shows on active tab in portrait)
        h+="<div class=\"asel-tab"+isOn+"\" onclick=\"switchChartTab("+i+")\">";
        h+="<div class=\"aicon\" style=\"background:"+ic+"\">"+letter+"</div>";
        h+="<div class=\"aname\">"+a.name+"</div>";
        h+="<i class=\"fas fa-chevron-down asel-dd-icon\"></i>";
        if (activeCharts.length > 1) {
            h+="<button class=\"cls-tab\" onclick=\"event.stopPropagation();closeChartTab("+i+")\"><i class=\"fas fa-times\"></i></button>";
        }
        h+="</div>";
    });
    var tabsEl = G("aselTabs");
    if(tabsEl) {
        // preserve open state
        var wasOpen = tabsEl.classList.contains("open");
        tabsEl.innerHTML=h;
        if(wasOpen) {
            var activeTab = tabsEl.querySelector('.asel-tab.on');
            if(activeTab) activeTab.classList.add("open-view");
        }
    }
    
    chkMobileAsel();
    
    // Update active asset variable
    asset = activeCharts[activeChartIndex];
    updUI();
}

function chkMobileAsel(){
    var isPortrait = window.matchMedia("(max-width: 768px) and (orientation: portrait)").matches;
    var mobileActiveEl = G("mobileAselActive");
    
    if(mobileActiveEl) {
        mobileActiveEl.style.display = "none"; // Hard hide, no longer used
    }
}

window.addEventListener("resize", chkMobileAsel);

function switchChartTab(index){
    if(index === activeChartIndex || index < 0 || index >= activeCharts.length) return;
    
    // Save current chart state
    var oldStore = chartDataStore[activeChartIndex];
    if(oldStore){
        oldStore.candles = candles.slice();
        oldStore.hkData = hkData.slice();
        oldStore.price = price;
    }
    
    // Switch active index
    activeChartIndex = index;
    asset = activeCharts[index]; // Refresh global asset
    
    // Restore new chart state
    var newStore = chartDataStore[index];
    if(!newStore){
        chartDataStore[index] = { candles:[], hkData:[], price:0, asset:asset };
        newStore = chartDataStore[index];
    }
    
    candles = newStore.candles.slice();
    hkData = newStore.hkData.slice();
    price = newStore.price;
    
    renderAssetTabs();
    
    // If we have no data, generate it
    if(candles.length === 0){
        genData();
        chartDataStore[index].candles = candles;
        chartDataStore[index].hkData = hkData;
        chartDataStore[index].price = price;
    }
    
    // Apply dataset to Lightweight Charts
    if(series){
        series.setData(cType==="heikin" ? hkData : candles);
    }
}

var isAddingNewTab = false;
function addChartTab(){
    if(activeCharts.length >= 4){
        showToast("Maximum 4 charts allowed","error");
        return;
    }
    isAddingNewTab = true; 
    cModal('asModal');
}

function closeChartTab(index){
    if(activeCharts.length <= 1) return; // Must have at least one tab
    
    activeCharts.splice(index, 1);
    
    // Shift data store indices
    for(var i=parseInt(index); i<activeCharts.length; i++){
        chartDataStore[i] = chartDataStore[i+1];
    }
    delete chartDataStore[activeCharts.length];
    
    // Adjust active index if necessary
    if(activeChartIndex >= index && activeChartIndex > 0){
        activeChartIndex--;
    } else if (activeChartIndex >= activeCharts.length) {
        activeChartIndex = activeCharts.length - 1;
    }
    
    // Force a fresh render without early return bailout
    var tempIdx = activeChartIndex;
    activeChartIndex = -1; 
    switchChartTab(tempIdx);
}

// === INIT ===
console.log("STEP 4: All functions defined, setting up DOMContentLoaded");
document.addEventListener("DOMContentLoaded",function(){
    console.log("STEP 5: DOMContentLoaded fired");
    
    // Setup initial multi-chart tab
    if(ASSETS.length) {
        var startA = ASSETS.find(function(a){return a.symbol==="BTCUSDT"})||ASSETS[0];
        activeCharts.push(startA);
        chartDataStore[0] = { candles:[], hkData:[], price:0, asset:startA };
    }
    
    // SAFE UI INIT FIRST
    try {
        renderModals(); // Safe to run
        initUIEvents(); // Safe to run
        renderAssetTabs(); // Renders the header tabs initially
        console.log("STEP 5b: UI Events & Modals initialized");
    } catch(e) {
        console.error("UI INIT ERROR:", e);
    }

    try{
        console.log("STEP 6: Calling initChart()...");
        initChart();
        console.log("STEP 7: Chart created OK");
        
        initTradingEvents(); // Run only if chart ok
        console.log("STEP 9: Trading Events bound");
        
        initDrag();
        console.log("STEP 10: Drag initialized");
        
        setInterval(tick,100);
        updUI();
        refreshBal();
        console.log("STEP 11: ALL INITIALIZED SUCCESSFULLY!");
    }
    catch(e){
        console.error("INIT CRASH:",e);
        document.body.innerHTML="<div style='color:red;padding:20px'><h2>Init Error</h2><p>"+e.message+"</p><pre>"+e.stack+"</pre><button onclick='location.reload(true)' style='padding:10px 20px;background:#ffc107;border:none;border-radius:8px;font-size:16px;cursor:pointer;margin-top:10px'>Refresh</button></div>";
    }
});
} // end else (LightweightCharts loaded)

// Fullscreen Logic for trade.php
document.addEventListener("DOMContentLoaded", function () {
    var fsBtn = document.getElementById('fullScreenBtn');
    if (fsBtn) {
        fsBtn.addEventListener('click', function(e) {
            e.preventDefault();
            toggleFullscreen();
        });
    }

    // Check if we arrived with ?fullscreen=1 from another page (e.g. profile.php)
    var urlParams = new URLSearchParams(window.location.search);
    if (urlParams.get('fullscreen') === '1') {
        // Clean the URL parameter without reloading
        var cleanUrl = window.location.pathname + window.location.hash;
        history.replaceState(null, '', cleanUrl);

        // Show a fullscreen overlay prompt (browser requires user gesture on THIS page)
        var overlay = document.createElement('div');
        overlay.id = 'fsOverlay';
        overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:99999;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;-webkit-tap-highlight-color:transparent;';
        overlay.innerHTML = '<div style="text-align:center;color:#fff;pointer-events:none;">' +
            '<i class="fas fa-expand" style="font-size:3rem;color:#00d09c;margin-bottom:1rem;display:block;"></i>' +
            '<div style="font-size:1.4rem;font-weight:600;margin-bottom:0.5rem;">Tap to Enter Full Display</div>' +
            '<div style="font-size:0.85rem;color:#8b92a8;">Tap anywhere to start trading in fullscreen</div>' +
            '</div>';

        overlay.addEventListener('click', function() {
            toggleFullscreen();
            overlay.remove();
        });

        document.body.appendChild(overlay);
    }
});

function toggleFullscreen() {
    if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
        var docElm = document.documentElement;
        if (docElm.requestFullscreen) {
            docElm.requestFullscreen();
        } else if (docElm.webkitRequestFullscreen) {
            docElm.webkitRequestFullscreen();
        } else if (docElm.msRequestFullscreen) {
            docElm.msRequestFullscreen();
        }
    } else {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }
    }
}
</script>
</body>
</html>
