`; html += `

TRADEFX

`; html += `

Trade Report: ${fromDate} to ${toDate}

`; html += `
Summary
`; html += `
Total Trades
${s.total_trades}
`; html += `
Gross P&L
\u20B9${s.total_pnl.toLocaleString()}
`; html += `
Brokerage
\u20B9${s.total_brokerage.toLocaleString()}
`; html += `
Net P&L
\u20B9${s.net_pnl.toLocaleString()}
`; html += `
`; html += ``; data.positions.forEach((p) => { const side = p.qty > 0 ? "BUY" : "SELL"; const pnl = parseFloat(p.pnl || 0); const brk = parseFloat(p.brokerage || 0); const net = pnl - brk; const exitDate = p.exit_time ? p.exit_time.split(" ")[0] : p.entry_time ? p.entry_time.split(" ")[0] : ""; html += ``; }); html += `
DateInstrumentSideQtyEntryExitP&LBrokerageNet
${exitDate}${p.name || p.symbol}${side}${Math.abs(p.qty)}\u20B9${parseFloat(p.avg_price || 0).toFixed(2)}\u20B9${parseFloat(p.exit_price || 0).toFixed(2)}\u20B9${pnl.toFixed(2)}\u20B9${brk.toFixed(2)}\u20B9${net.toFixed(2)}
`; html += ``; html += ` `; const win = window.open("", "_blank"); win.document.write(html); win.document.close(); setTimeout(() => { win.print(); }, 500); }; return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: onBack, className: "text-xl px-2" }, "\u2190"), /* @__PURE__ */ React.createElement("h2", { className: "font-bold text-lg" }, "\u{1F4CA} Trade Report")), /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded-lg mb-4 bg-theme-card" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-3 mb-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "text-[10px] text-theme-muted block mb-1" }, "From Date"), /* @__PURE__ */ React.createElement("input", { type: "date", value: fromDate, onChange: (e) => setFromDate(e.target.value), className: "w-full p-2 rounded bg-theme-input text-theme-main border border-theme text-sm" })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "text-[10px] text-theme-muted block mb-1" }, "To Date"), /* @__PURE__ */ React.createElement("input", { type: "date", value: toDate, onChange: (e) => setToDate(e.target.value), className: "w-full p-2 rounded bg-theme-input text-theme-main border border-theme text-sm" }))), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("button", { onClick: () => generate(), className: "flex-1 py-2 bg-[#1c7cd5] text-white rounded font-bold text-sm" }, "\u{1F50D} Generate"), /* @__PURE__ */ React.createElement("button", { onClick: () => setDateRange((/* @__PURE__ */ new Date()).toISOString().split("T")[0], (/* @__PURE__ */ new Date()).toISOString().split("T")[0], "Today"), className: `px-3 py-2 rounded text-xs font-bold ${dateLabel === "Today" ? "bg-[#1c7cd5] text-white" : "bg-theme-input text-theme-muted border border-theme"}` }, "Today"), /* @__PURE__ */ React.createElement("button", { onClick: () => setDateRange(new Date(Date.now() - 7 * 864e5).toISOString().split("T")[0], (/* @__PURE__ */ new Date()).toISOString().split("T")[0], "7D"), className: `px-3 py-2 rounded text-xs font-bold ${dateLabel === "7D" ? "bg-[#1c7cd5] text-white" : "bg-theme-input text-theme-muted border border-theme"}` }, "7D"), /* @__PURE__ */ React.createElement("button", { onClick: () => setDateRange(new Date(Date.now() - 30 * 864e5).toISOString().split("T")[0], (/* @__PURE__ */ new Date()).toISOString().split("T")[0], "30D"), className: `px-3 py-2 rounded text-xs font-bold ${dateLabel === "30D" ? "bg-[#1c7cd5] text-white" : "bg-theme-input text-theme-muted border border-theme"}` }, "30D"))), reportTab === "trades" && data && !loading && /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4" }, /* @__PURE__ */ React.createElement(StatCard, { label: "Trades", value: ((_a = data.summary) == null ? void 0 : _a.total_trades) || 0, valueClass: "text-theme-main" }), /* @__PURE__ */ React.createElement(StatCard, { label: "Gross P&L", value: fmtMoney(((_b = data.summary) == null ? void 0 : _b.total_pnl) || 0), valueClass: (((_c = data.summary) == null ? void 0 : _c.total_pnl) || 0) >= 0 ? "text-green-400" : "text-red-400", compact: true }), /* @__PURE__ */ React.createElement(StatCard, { label: "Brokerage", value: fmtMoney(((_d = data.summary) == null ? void 0 : _d.total_brokerage) || 0), valueClass: "text-orange-400", compact: true }), /* @__PURE__ */ React.createElement(StatCard, { label: "Net P&L", value: fmtMoney(((_e = data.summary) == null ? void 0 : _e.net_pnl) || 0), valueClass: (((_f = data.summary) == null ? void 0 : _f.net_pnl) || 0) >= 0 ? "text-green-400" : "text-red-400", compact: true })), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: () => { setReportTab("trades"); fetchReport(); }, className: `flex-1 py-2 rounded font-bold text-sm ${reportTab === "trades" ? "bg-[#1c7cd5] text-white" : "bg-theme-card text-theme-muted border border-theme"}` }, "\u{1F4CA} Trades"), /* @__PURE__ */ React.createElement("button", { onClick: () => { setReportTab("funds"); fetchFundHistory(); }, className: `flex-1 py-2 rounded font-bold text-sm ${reportTab === "funds" ? "bg-[#1c7cd5] text-white" : "bg-theme-card text-theme-muted border border-theme"}` }, "\u{1F4B0} Deposits & Withdrawals")), loading && /* @__PURE__ */ React.createElement("div", { className: "text-center p-8 text-theme-muted" }, "Loading Report..."), reportTab === "trades" && data && !loading && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: downloadCSV, className: "flex-1 py-2 rounded bg-green-600 text-white font-bold text-sm" }, "\u{1F4E5} Download CSV"), /* @__PURE__ */ React.createElement("button", { onClick: downloadPDF, className: "flex-1 py-2 rounded bg-red-600 text-white font-bold text-sm" }, "\u{1F4C4} Download PDF")), /* @__PURE__ */ React.createElement("div", { className: "text-center text-theme-muted text-xs p-4" }, (data.positions || []).length > 0 ? `${(data.positions || []).length} trades found \u2022 Download CSV or PDF to view details` : "No closed trades in this period")), reportTab === "funds" && !loading && fundData && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded-lg mb-4 bg-theme-card" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-3 gap-3 text-center" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Total Deposits"), /* @__PURE__ */ React.createElement("div", { className: "text-lg font-bold font-mono text-green-400" }, fmtMoney(((_g = fundData == null ? void 0 : fundData.summary) == null ? void 0 : _g.total_deposits) || 0))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Total Withdrawals"), /* @__PURE__ */ React.createElement("div", { className: "text-lg font-bold font-mono text-red-400" }, fmtMoney(((_h = fundData == null ? void 0 : fundData.summary) == null ? void 0 : _h.total_withdrawals) || 0))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Net"), /* @__PURE__ */ React.createElement("div", { className: `text-lg font-bold font-mono ${(((_i = fundData == null ? void 0 : fundData.summary) == null ? void 0 : _i.net) || 0) >= 0 ? "text-green-400" : "text-red-400"}` }, fmtMoney(((_j = fundData == null ? void 0 : fundData.summary) == null ? void 0 : _j.net) || 0))))), (fundData.deposits || []).length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card rounded-lg overflow-hidden bg-theme-card mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "px-4 py-2 bg-green-600/20 border-b border-theme" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-bold text-green-400" }, "\u{1F4B5} Deposits")), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-[var(--border)]" }, (fundData.deposits || []).map((d, i) => /* @__PURE__ */ React.createElement("div", { key: d.id || i, className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start mb-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-green-400" }, "+", fmtMoney(d.amount)), /* @__PURE__ */ React.createElement(FundStatusBadge, { status: d.status })), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, d.created_at), d.utr_number && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mt-1" }, "UTR: ", d.utr_number), d.payment_method && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Method: ", d.payment_method), d.admin_comment && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-yellow-400 mt-1 bg-yellow-500/10 p-1.5 rounded" }, "\u{1F4DD} ", d.admin_comment))))), (fundData.withdrawals || []).length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card rounded-lg overflow-hidden bg-theme-card mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "px-4 py-2 bg-red-600/20 border-b border-theme" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-bold text-red-400" }, "\u{1F4B8} Withdrawals")), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-[var(--border)]" }, (fundData.withdrawals || []).map((w, i) => /* @__PURE__ */ React.createElement("div", { key: w.id || i, className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start mb-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-red-400" }, "-", fmtMoney(w.amount)), /* @__PURE__ */ React.createElement(FundStatusBadge, { status: w.status })), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, w.created_at), w.upi_id && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mt-1" }, "UPI: ", w.upi_id), w.bank_account && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Bank: ", w.bank_account), w.blocked_reason && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-blue-400 mt-1 bg-blue-500/10 p-1.5 rounded" }, "\u{1F4DD} ", w.blocked_reason), w.approved_at && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-green-400 mt-1" }, "Approved: ", w.approved_at))))), fundData.requests && (fundData.requests || []).length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card rounded-lg overflow-hidden bg-theme-card mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "px-4 py-2 bg-purple-600/20 border-b border-theme" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-bold text-purple-400" }, "\u{1F4CB} All Ledger Transactions")), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-[var(--border)]" }, (fundData.requests || []).map((r, i) => /* @__PURE__ */ React.createElement("div", { key: r.id || i, className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start mb-1" }, /* @__PURE__ */ React.createElement("div", { className: `text-sm font-bold ${r.req_type === "DEPOSIT" ? "text-green-400" : "text-red-400"}` }, r.req_type === "DEPOSIT" ? "+" : "-", fmtMoney(r.amount)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: `text-[10px] px-1.5 py-0.5 rounded font-bold ${r.req_type === "DEPOSIT" ? "bg-green-500/20 text-green-400" : "bg-orange-500/20 text-orange-400"}` }, r.req_type), /* @__PURE__ */ React.createElement("span", { className: `text-[10px] px-1.5 py-0.5 rounded font-bold ${r.status === "APPROVE" ? "bg-green-500/20 text-green-400" : r.status === "REJECT" ? "bg-red-500/20 text-red-400" : "bg-yellow-500/20 text-yellow-400"}` }, r.status))), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, r.created_at), r.utr_number && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mt-1" }, "UTR: ", r.utr_number), r.notes && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-blue-400 mt-1 bg-blue-500/10 p-1.5 rounded" }, "\u{1F4DD} ", r.notes))))), (fundData.deposits || []).length === 0 && (fundData.withdrawals || []).length === 0 && (!fundData.requests || (fundData.requests || []).length === 0) && /* @__PURE__ */ React.createElement("div", { className: "text-center py-10 text-theme-muted" }, "No fund transactions in this period")), reportTab === "funds" && !loading && !fundData && /* @__PURE__ */ React.createElement("div", { className: "text-center py-10 text-theme-muted" }, "Click Generate to load fund history")); } function DepositView({ user, onBack }) { const [amount, setAmount] = React.useState(""); const [utr, setUtr] = React.useState(""); const [screenshot, setScreenshot] = React.useState(null); const [methods, setMethods] = React.useState({ banks: [], qrs: [] }); const [loading, setLoading] = React.useState(true); const [deposits, setDeposits] = React.useState([]); const [showHistory2, setShowHistory2] = React.useState(false); React.useEffect(() => { const uid = (user == null ? void 0 : user.user_id) || localStorage.getItem("user_id"); if (!uid) { setLoading(false); return; } api("user_get_payment_methods", { user_id: uid }).then((r) => { if (r.success) setMethods({ banks: r.banks || [], qrs: r.qrs || [] }); setLoading(false); }); }, [user]); const loadHistory = React.useCallback(() => { const uid = (user == null ? void 0 : user.user_id) || localStorage.getItem("user_id"); api("get_deposits", { user_id: uid }).then((r) => { if (r.success) setDeposits(r.deposits || []); }); }, [user]); React.useEffect(() => { if (showHistory2) { loadHistory(); const interval = setInterval(loadHistory, 1e4); return () => clearInterval(interval); } }, [showHistory2, loadHistory]); const handleDeposit = async () => { if (!amount || amount <= 0) return alert("Enter valid amount"); if (!utr) return alert("Enter UTR Number"); const formData = new FormData(); formData.append("action", "user_deposit"); formData.append("session_token", user.session_token || session_token); formData.append("user_id", user.user_id); formData.append("amount", amount); formData.append("utr_number", utr); if (screenshot) formData.append("screenshot", screenshot); try { const res = await fetch("https://tradefx.space/trade_api.php", { method: "POST", body: formData }); const data = await res.json(); if (data.success) { alert(data.message || "Deposit Submitted! Check history for status."); setAmount(""); setUtr(""); setScreenshot(null); loadHistory(); } else { alert(data.error || "Failed"); } } catch (e) { alert("Error submitting deposit"); } }; const getStatusColor = (status) => { if (status === "approved") return "text-green-500 bg-green-500/10 border-green-500"; if (status === "pending") return "text-yellow-500 bg-yellow-500/10 border-yellow-500"; if (status === "rejected") return "text-red-500 bg-red-500/10 border-red-500"; return "text-gray-500 bg-gray-500/10 border-gray-500"; }; const getApprovalBadge = (deposit) => { if (deposit.auto_approved == 1) { return /* @__PURE__ */ React.createElement("span", { className: "text-xs px-2 py-0.5 rounded bg-blue-500/20 text-blue-400 border border-blue-500/30" }, "Auto"); } if (deposit.status === "approved") { return /* @__PURE__ */ React.createElement("span", { className: "text-xs px-2 py-0.5 rounded bg-purple-500/20 text-purple-400 border border-purple-500/30" }, "Manual"); } return null; }; if (showHistory2) { return /* @__PURE__ */ React.createElement("div", { className: "p-4", style: { paddingBottom: "80px" } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setShowHistory2(false), className: "text-xl px-2 text-theme-main" }, "\u2190"), /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-theme-text" }, "Deposit History")), deposits.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "text-center p-8 text-theme-muted" }, "No deposits yet") : /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, deposits.map((d, i) => /* @__PURE__ */ React.createElement("div", { key: i, className: "card p-4 rounded bg-theme-card border border-theme-border" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start mb-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-xl font-bold text-theme-main" }, "\u20B9", parseFloat(d.amount).toFixed(2)), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 items-center" }, getApprovalBadge(d), /* @__PURE__ */ React.createElement("span", { className: `text-xs px-2 py-1 rounded border ${getStatusColor(d.status)} font-bold uppercase` }, d.status))), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-theme-muted space-y-1" }, /* @__PURE__ */ React.createElement("div", null, "UTR: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main font-mono" }, d.utr_number || "N/A")), /* @__PURE__ */ React.createElement("div", null, "ID: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main" }, "#", d.id)), /* @__PURE__ */ React.createElement("div", null, "Date: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main" }, new Date(d.created_at).toLocaleString())), d.approved_at && /* @__PURE__ */ React.createElement("div", null, "Approved: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main" }, new Date(d.approved_at).toLocaleString())), d.approved_by && /* @__PURE__ */ React.createElement("div", null, "By: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main" }, d.approved_by)), d.admin_comment && /* @__PURE__ */ React.createElement("div", { className: "text-yellow-400 mt-1" }, "Note: ", d.admin_comment)))))); } return /* @__PURE__ */ React.createElement("div", { className: "p-4", style: { paddingBottom: "80px" } }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center mb-4" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-bold text-theme-text" }, "Add Funds"), /* @__PURE__ */ React.createElement("button", { onClick: () => setShowHistory2(true), className: "text-sm text-blue-400 hover:text-blue-300" }, "\u{1F4DC} History")), loading ? /* @__PURE__ */ React.createElement("div", { className: "text-center p-4" }, "Loading Payment Details...") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "QR Codes"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-bold text-theme-main" }, methods.qrs.length)), /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "Bank Accounts"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-bold text-theme-main" }, methods.banks.length)), /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "History"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-lg font-bold text-theme-main" }, deposits.length)), /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "Proof"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs font-bold text-theme-main" }, screenshot ? "Attached" : "Optional"))), /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-blue-600/10 border border-blue-500/30" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-blue-300 mb-1" }, "Deposit Steps"), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-theme-muted" }, "1. Pay using QR or bank transfer. 2. Enter amount and UTR. 3. Upload screenshot for faster approval.")), methods.qrs.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-theme-card text-center" }, /* @__PURE__ */ React.createElement("h3", { className: "text-sm text-theme-muted mb-3 font-bold uppercase" }, "Scan to Pay"), /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 overflow-x-auto justify-center" }, methods.qrs.map((q2, i) => /* @__PURE__ */ React.createElement("div", { key: i, className: "flex-shrink-0" }, /* @__PURE__ */ React.createElement("div", { className: "w-32 h-32 bg-white mx-auto mb-2 flex items-center justify-center overflow-hidden rounded" }, /* @__PURE__ */ React.createElement("img", { src: q2.qr_image_path, alt: "QR", className: "max-w-full max-h-full" })), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-white font-bold" }, q2.label), q2.upi_id && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-gray-400" }, q2.upi_id))))) : /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-theme-card text-center text-yellow-500 text-sm" }, "No QR Codes available currently."), methods.banks.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-theme-card" }, /* @__PURE__ */ React.createElement("h3", { className: "text-sm text-theme-muted mb-3 font-bold uppercase" }, "Bank Transfers (NEFT/IMPS)"), methods.banks.map((b, i) => /* @__PURE__ */ React.createElement("div", { key: i, className: "mb-3 p-3 bg-theme-input rounded border border-theme text-sm space-y-1" }, /* @__PURE__ */ React.createElement("div", { className: "font-bold text-theme-main" }, b.bank_name), /* @__PURE__ */ React.createElement("div", { className: "text-theme-muted" }, "Acc No: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main select-all" }, b.account_number)), /* @__PURE__ */ React.createElement("div", { className: "text-theme-muted" }, "IFSC: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main select-all" }, b.ifsc_code)), /* @__PURE__ */ React.createElement("div", { className: "text-theme-muted" }, "Holder: ", b.account_holder), b.upi_id && /* @__PURE__ */ React.createElement("div", { className: "text-theme-muted" }, "UPI: ", b.upi_id))))), /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded bg-theme-card" }, /* @__PURE__ */ React.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm text-theme-muted mb-1" }, "Amount"), /* @__PURE__ */ React.createElement("input", { type: "number", className: "w-full bg-theme-input border border-theme-border p-2 rounded text-theme-main", style: { color: "var(--text-primary)", backgroundColor: "var(--bg-input)" }, value: amount, onChange: (e) => setAmount(e.target.value), placeholder: "0.00" })), /* @__PURE__ */ React.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm text-theme-muted mb-1" }, "UTR / Transaction ID"), /* @__PURE__ */ React.createElement("input", { type: "text", className: "w-full bg-theme-input border border-theme-border p-2 rounded text-theme-main", style: { color: "var(--text-primary)", backgroundColor: "var(--bg-input)" }, value: utr, onChange: (e) => setUtr(e.target.value), placeholder: "Enter 12-digit UTR" })), /* @__PURE__ */ React.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm text-theme-muted mb-1" }, "Screenshot (Recommended for Auto-Approval)"), /* @__PURE__ */ React.createElement("input", { type: "file", className: "w-full bg-theme-bg border border-theme-border p-2 rounded text-gray-400", onChange: (e) => setScreenshot(e.target.files[0]), accept: "image/*" })), /* @__PURE__ */ React.createElement("button", { onClick: handleDeposit, className: "w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 rounded" }, "SUBMIT DEPOSIT"))); } function RulesView({ onBack }) { const [rules, setRules] = React.useState({}); const [loading, setLoading] = React.useState(true); const [userBrk, setUserBrk] = React.useState({}); React.useEffect(() => { api("get_margin_rules").then((r) => { setRules(r.rules || {}); setLoading(false); }); let _uid = null; try { const stored = localStorage.getItem(USER_KEY); if (stored) { const u = JSON.parse(stored); if (u && (u.user_id || u.userid)) { _uid = u.user_id || u.userid; setUserBrk(__spreadProps(__spreadValues({}, u), { user_id: _uid })); } } } catch (e) { } if (_uid) { api("get_user_details", { user_id: _uid }).then((r) => { if (r && r.user) { const fresh = r.user; setUserBrk(__spreadProps(__spreadValues({}, fresh), { user_id: fresh.user_id || fresh.userid || _uid })); try { localStorage.setItem(USER_KEY, JSON.stringify(fresh)); } catch (e) { } } }).catch(() => { }); } }, []); const segmentLabels = { "MCX": "\u{1F7E1} MCX Futures", "NSE_FUT": "\u{1F535} NSE Futures", "NSE_INDEX": "\u{1F535} NSE Index Futures", "BFO": "\u{1F7E2} BSE F&O", "NSE_EQUITY": "\u{1F4CA} NSE Equity", "OPTION_BUY": "\u{1F4D7} Option Buy", "OPTION_SELL": "\u{1F4D5} Option Sell", "CRYPTO": "\u20BF Crypto" }; let _userMargin = {}; try { _userMargin = typeof userBrk.margin_settings === "string" ? JSON.parse(userBrk.margin_settings || "{}") : userBrk.margin_settings || {}; } catch (e) { _userMargin = {}; } const _mergedRules = __spreadValues({}, rules); Object.keys(_userMargin).forEach((k) => { if (_userMargin[k] && (_userMargin[k].intraday != null || _userMargin[k].holding != null)) { _mergedRules[k] = _userMargin[k]; } }); const entries = Object.entries(_mergedRules); return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: onBack, className: "text-xl px-2" }, "\u2190"), /* @__PURE__ */ React.createElement("h2", { className: "font-bold text-lg" }, "\u2696\uFE0F Margin & Exposure Rules")), loading && /* @__PURE__ */ React.createElement("div", { className: "text-center p-8 text-theme-muted" }, "Loading..."), userBrk && (userBrk.user_id || userBrk.userid) && /* @__PURE__ */ React.createElement("div", { className: "mt-4 space-y-2" }, [["mcx", "MCX FUT"], ["equity", "Equity"], ["nfo", "NSE FUT"], ["nse_opt", "NSE OPT"], ["mcx_opt", "MCX OPT"], ["crypto", "Crypto"]].filter(([prefix]) => { var _a; return Number((_a = userBrk[prefix + "_allowed"]) != null ? _a : 1) === 1; }).map(([prefix, label]) => { var _a, _b, _c, _d, _e, _f; const brkType = userBrk[prefix + "_brokerage_type"] || userBrk.brokerage_type || "LOT"; const brkVal = (_b = (_a = userBrk[prefix + "_brokerage"]) != null ? _a : userBrk.brokerage_val) != null ? _b : 0; const minLots = (_c = userBrk[prefix + "_min_lots"]) != null ? _c : 1; const maxLots = (_d = userBrk[prefix + "_max_lots"]) != null ? _d : 0; const brkLabel = brkType === "PER_CR" ? "/Cr" : brkType === "PERCENT" ? "%" : "/Lot"; let _ms = {}; try { _ms = typeof userBrk.margin_settings === "string" ? JSON.parse(userBrk.margin_settings || "{}") : userBrk.margin_settings || {}; } catch (e) { _ms = {}; } const _msMap = { "mcx": "MCX", "equity": "NSE_EQUITY", "nfo": "NSE_FUT", "nse_opt": "OPTION_BUY", "mcx_opt": "BFO", "crypto": "CRYPTO" }; const _seg = _ms[_msMap[prefix]] || {}; const expMode = _seg.mode || "X"; const expIntra = (_e = _seg.intraday) != null ? _e : 0; const expHold = (_f = _seg.holding) != null ? _f : 0; const expSuffix = expMode === "FIXED" ? "" : "x"; return /* @__PURE__ */ React.createElement("div", { key: prefix, className: "card p-3 rounded-lg bg-theme-card" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs font-bold text-theme-main mb-2" }, label), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-5 gap-1 text-xs" }, /* @__PURE__ */ React.createElement("div", { className: "bg-theme-input p-2 rounded text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mb-1" }, "Brokerage"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-yellow-400" }, brkVal, /* @__PURE__ */ React.createElement("span", { className: "text-[9px] text-theme-muted ml-0.5" }, brkLabel))), /* @__PURE__ */ React.createElement("div", { className: "bg-theme-input p-2 rounded text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mb-1" }, "Min Lots"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-blue-400" }, minLots)), /* @__PURE__ */ React.createElement("div", { className: "bg-theme-input p-2 rounded text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mb-1" }, "Max Lots"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-green-400" }, maxLots > 0 ? maxLots : "\u221E")), /* @__PURE__ */ React.createElement("div", { className: "bg-theme-input p-2 rounded text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mb-1" }, "Intraday"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-orange-400" }, expIntra, expSuffix)), /* @__PURE__ */ React.createElement("div", { className: "bg-theme-input p-2 rounded text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mb-1" }, "Holding"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-pink-400" }, expHold, expSuffix)))); }))); } function WithdrawView({ user, onBack }) { var _a, _b; const defaultBankAccount = `${user.bank_name || ""} ${user.account_number || ""} ${user.ifsc_code || ""}`.trim(); const defaultUpiId = user.upi_id || ""; const [amount, setAmount] = React.useState(""); const [bankAccount, setBankAccount] = React.useState(defaultBankAccount); const [upiId, setUpiId] = React.useState(defaultUpiId); const [loading, setLoading] = React.useState(false); const [withdrawals2, setWithdrawals] = React.useState([]); const [editingWithdrawal, setEditingWithdrawal] = React.useState(null); const [showHistory2, setShowHistory2] = React.useState(false); const [rules, setRules] = React.useState({ withdrawal_start_time: "09:00", withdrawal_end_time: "23:50", withdrawal_min_amount: 1, withdrawal_require_no_positions: 1, withdrawal_time_enabled: 1 }); const fetchWithdrawals = async () => { const r = await api("get_withdrawals", { user_id: user.user_id }); if (r == null ? void 0 : r.success) setWithdrawals(r.withdrawals || []); }; React.useEffect(() => { api("get_payment_settings").then((r) => { if (r == null ? void 0 : r.settings) setRules((prev) => __spreadValues(__spreadValues({}, prev), r.settings)); }); fetchWithdrawals(); }, [user.user_id]); const pendingWithdrawals = (withdrawals2 || []).filter((w) => String(w.status || "pending").toLowerCase() === "pending" && !Number(w.legacy_request || 0)); const withdrawalHistory = (withdrawals2 || []).filter((w) => String(w.status || "pending").toLowerCase() !== "pending"); const startEdit = (w) => { setEditingWithdrawal(w); setAmount(String(w.amount || "")); setBankAccount(w.bank_account || defaultBankAccount); setUpiId(w.upi_id || defaultUpiId); }; const cancelEdit = () => { setEditingWithdrawal(null); setAmount(""); setBankAccount(defaultBankAccount); setUpiId(defaultUpiId); }; const deleteWithdrawal = async (w) => { if (!confirm("Delete this pending payout request? Amount will be returned to your wallet.")) return; setLoading(true); const r = await api("user_delete_withdrawal", { user_id: user.user_id, withdrawal_id: w.id }); setLoading(false); if (r.success) { if ((editingWithdrawal == null ? void 0 : editingWithdrawal.id) === w.id) cancelEdit(); alert("Payout request deleted. Amount refunded to wallet."); fetchWithdrawals(); } else { alert(r.error || "Delete failed"); } }; const submit = async () => { const minAmount = Number(rules.withdrawal_min_amount || 1); if (!amount || amount <= 0) return alert("Enter valid amount"); if (Number(amount) < minAmount) return alert("Minimum withdrawal: Rs " + minAmount.toFixed(2)); if (!bankAccount && !upiId) return alert("Enter Bank Account or UPI ID"); setLoading(true); const payload = { user_id: user.user_id, amount, bank_account: bankAccount, upi_id: upiId }; if (editingWithdrawal) payload.withdrawal_id = editingWithdrawal.id; const r = await api(editingWithdrawal ? "user_update_withdrawal" : "user_withdraw", payload); setLoading(false); if (r.success) { if (editingWithdrawal) { alert("Payout request updated."); cancelEdit(); fetchWithdrawals(); } else { alert("Withdrawal request submitted. Pending admin approval."); onBack(); } } else { alert(r.error || "Withdrawal failed"); fetchWithdrawals(); } }; return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: onBack, className: "text-xl px-2" }, "\u2190"), /* @__PURE__ */ React.createElement("h2", { className: "font-bold text-lg" }, "Withdraw Funds")), /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-yellow-900/20 border border-yellow-500/30" }, String((_a = rules.withdrawal_time_enabled) != null ? _a : "1") !== "0" && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-yellow-400" }, "Withdrawal allowed: ", rules.withdrawal_start_time || "09:00", " - ", rules.withdrawal_end_time || "23:50", " IST"), String((_b = rules.withdrawal_require_no_positions) != null ? _b : "1") !== "0" && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-yellow-400 mt-1" }, "Close all active positions before withdrawal"), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-yellow-400 mt-1" }, "Minimum withdrawal: Rs ", Number(rules.withdrawal_min_amount || 1).toFixed(2))), /* @__PURE__ */ React.createElement("div", { className: "card p-4 rounded mb-4 bg-theme-card" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs text-theme-muted" }, "Available to Withdraw"), /* @__PURE__ */ React.createElement("div", { className: "text-2xl font-bold text-green-400" }, fmtMoney(user.funds || 0))), pendingWithdrawals.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card rounded-lg overflow-hidden bg-theme-card mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "px-4 py-2 border-b border-theme flex items-center justify-between gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-bold text-theme-main" }, "Pending Payout Requests"), /* @__PURE__ */ React.createElement("span", { className: "text-[10px] text-theme-muted" }, pendingWithdrawals.length)), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-[var(--border)]" }, pendingWithdrawals.map((w) => /* @__PURE__ */ React.createElement("div", { key: w.id, className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-red-400" }, "-", fmtMoney(w.amount)), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, w.created_at)), /* @__PURE__ */ React.createElement(FundStatusBadge, { status: w.status })), w.upi_id && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mt-1 break-words" }, "UPI: ", w.upi_id), w.bank_account && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted break-words" }, "Bank: ", w.bank_account), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-2 mt-3" }, /* @__PURE__ */ React.createElement( "button", { onClick: () => startEdit(w), disabled: loading, className: "py-2 rounded bg-blue-600/20 text-blue-300 text-xs font-bold border border-blue-500/30 disabled:opacity-50" }, "EDIT" ), /* @__PURE__ */ React.createElement( "button", { onClick: () => deleteWithdrawal(w), disabled: loading, className: "py-2 rounded bg-red-600/20 text-red-300 text-xs font-bold border border-red-500/30 disabled:opacity-50" }, "DELETE" )))))), withdrawalHistory.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "card rounded-lg overflow-hidden bg-theme-card mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "px-4 py-2 border-b border-theme flex items-center justify-between gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-bold text-theme-main" }, "Payout History"), /* @__PURE__ */ React.createElement("span", { className: "text-[10px] text-theme-muted" }, withdrawalHistory.length)), /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-[var(--border)]" }, withdrawalHistory.map((w) => /* @__PURE__ */ React.createElement("div", { key: `history-${w.id}`, className: "p-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-red-400" }, "-", fmtMoney(w.amount)), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, w.created_at)), /* @__PURE__ */ React.createElement(FundStatusBadge, { status: w.status })), w.bank_account && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted mt-1 break-words" }, "Bank: ", w.bank_account), w.upi_id && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted break-words" }, "UPI: ", w.upi_id), w.admin_comment && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-yellow-400 break-words" }, "Note: ", w.admin_comment), w.approved_by && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "By: ", w.approved_by), w.approved_at && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Done: ", w.approved_at), Number(w.legacy_request || 0) === 1 && /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-blue-300 mt-1" }, "Legacy record"))))), editingWithdrawal && /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded mb-4 bg-blue-600/10 border border-blue-500/30 flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-xs font-bold text-blue-300" }, "Editing payout #", editingWithdrawal.id), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "Submit will update only this pending request.")), /* @__PURE__ */ React.createElement( "button", { onClick: cancelEdit, disabled: loading, className: "px-3 py-2 rounded border border-theme text-xs font-bold text-theme-main disabled:opacity-50" }, "Cancel" )), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-3 mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "Bank Route"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs font-bold text-theme-main break-words" }, bankAccount || "Not added")), /* @__PURE__ */ React.createElement("div", { className: "card p-3 rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] uppercase tracking-wide text-theme-muted" }, "UPI Route"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs font-bold text-theme-main break-words" }, upiId || "Not added"))), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "text-xs text-theme-muted" }, "Amount"), /* @__PURE__ */ React.createElement( "input", { type: "number", className: "w-full bg-theme-card border border-theme p-3 rounded text-theme-main", value: amount, onChange: (e) => setAmount(e.target.value), placeholder: `Minimum: Rs ${Number(rules.withdrawal_min_amount || 1).toFixed(2)}` } )), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "text-xs text-theme-muted" }, "Bank Account / IFSC"), /* @__PURE__ */ React.createElement( "input", { type: "text", className: "w-full bg-theme-card border border-theme p-3 rounded text-theme-main", value: bankAccount, onChange: (e) => setBankAccount(e.target.value), placeholder: "Account Number / IFSC" } )), /* @__PURE__ */ React.createElement("div", { className: "text-center text-xs text-theme-muted" }, "OR"), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "text-xs text-theme-muted" }, "UPI ID"), /* @__PURE__ */ React.createElement( "input", { type: "text", className: "w-full bg-theme-card border border-theme p-3 rounded text-theme-main", value: upiId, onChange: (e) => setUpiId(e.target.value), placeholder: "yourname@upi" } )), /* @__PURE__ */ React.createElement( "button", { onClick: submit, disabled: loading, className: "w-full btn-primary py-3 rounded font-bold bg-[#d9534f] disabled:opacity-50" }, loading ? "Processing..." : editingWithdrawal ? "UPDATE REQUEST" : "REQUEST WITHDRAWAL" ))); } function OrderPadChart({ item, ticks, onSubscribe, onCloseChart }) { const chartKey = (item == null ? void 0 : item.key) || (item == null ? void 0 : item.instrument_key) || (item == null ? void 0 : item.fyers_symbol) || (item == null ? void 0 : item.symbol); const [tf, setTf] = React.useState("1m"); const [points, setPoints] = React.useState([]); const [historyCandles, setHistoryCandles] = React.useState([]); const [historyStatus, setHistoryStatus] = React.useState("LOADING"); const chartEl = React.useRef(null); const chartRef = React.useRef(null); const candleRef = React.useRef(null); const priceLineRef = React.useRef(null); const tick = getTickForItem(ticks, item); const bid = Number((tick == null ? void 0 : tick.bid) || (tick == null ? void 0 : tick.best_bid) || (tick == null ? void 0 : tick.bestBid) || (item == null ? void 0 : item.bid) || 0); const ask2 = Number((tick == null ? void 0 : tick.ask) || (tick == null ? void 0 : tick.best_ask) || (tick == null ? void 0 : tick.bestAsk) || (item == null ? void 0 : item.ask) || 0); const ltp = Number((tick == null ? void 0 : tick.ltp) || (tick == null ? void 0 : tick.last_traded_price) || (item == null ? void 0 : item.ltp) || (tick == null ? void 0 : tick.close) || 0); const last = ltp || bid || ask2 || 0; React.useEffect(() => { if (onSubscribe) onSubscribe(getSubscriptionKeysForItem(item)); }, [chartKey, onSubscribe]); React.useEffect(() => { setPoints([]); setHistoryCandles([]); setHistoryStatus("LOADING"); }, [chartKey]); React.useEffect(() => { let cancelled = false; setHistoryStatus("LOADING"); api("chart_candles", { instrument_key: chartKey, symbol: (item == null ? void 0 : item.symbol) || (item == null ? void 0 : item.name) || "", interval: tf }).then((res) => { if (cancelled) return; const rows = Array.isArray(res == null ? void 0 : res.candles) ? res.candles : []; const clean = rows.map((c) => ({ time: Number(c.time), open: Number(c.open), high: Number(c.high), low: Number(c.low), close: Number(c.close) })).filter((c) => c.time > 0 && c.open > 0 && c.high > 0 && c.low > 0 && c.close > 0); setHistoryCandles(clean.slice(-220)); setHistoryStatus(clean.length ? "READY" : "EMPTY"); }).catch(() => { if (!cancelled) { setHistoryCandles([]); setHistoryStatus("EMPTY"); } }); return () => { cancelled = true; }; }, [chartKey, tf]); React.useEffect(() => { if (!chartEl.current || !window.LightweightCharts) return; const LW = window.LightweightCharts; const chart = LW.createChart(chartEl.current, { autoSize: true, height: 310, layout: { background: { color: "#050914" }, textColor: "#cbd5e1" }, grid: { vertLines: { color: "rgba(148,163,184,.08)" }, horzLines: { color: "rgba(148,163,184,.10)" } }, rightPriceScale: { borderColor: "rgba(148,163,184,.20)", scaleMargins: { top: 0.12, bottom: 0.12 } }, timeScale: { borderColor: "rgba(148,163,184,.20)", timeVisible: true, secondsVisible: false }, crosshair: { mode: LW.CrosshairMode.Normal }, localization: { priceFormatter: (p) => Number(p).toFixed(2) } }); const candleOptions = { upColor: "#22c55e", downColor: "#ef4444", borderUpColor: "#22c55e", borderDownColor: "#ef4444", wickUpColor: "#22c55e", wickDownColor: "#ef4444", priceFormat: { type: "price", precision: 2, minMove: 0.01 } }; const candle = chart.addSeries ? chart.addSeries(LW.CandlestickSeries, candleOptions) : chart.addCandlestickSeries(candleOptions); chartRef.current = chart; candleRef.current = candle; return () => { chart.remove(); chartRef.current = null; candleRef.current = null; priceLineRef.current = null; }; }, [chartKey]); React.useEffect(() => { if (!last || last <= 0) return; setPoints((prev) => { const next = [...prev, { t: Date.now(), p: last }]; return next.slice(-700); }); }, [chartKey, last]); const tfMs = { "1m": 6e4, "3m": 18e4, "5m": 3e5, "15m": 9e5, "30m": 18e5, "1h": 36e5 }[tf] || 6e4; const lastHistoryMs = historyCandles.length ? historyCandles[historyCandles.length - 1].time * 1e3 : 0; const buckets = []; points.filter((pt) => !lastHistoryMs || pt.t >= lastHistoryMs).forEach((pt) => { const bucketTime = Math.floor(pt.t / tfMs) * tfMs; let c = buckets[buckets.length - 1]; if (!c || c.t !== bucketTime) { c = { t: bucketTime, o: pt.p, h: pt.p, l: pt.p, c: pt.p }; buckets.push(c); } else { c.h = Math.max(c.h, pt.p); c.l = Math.min(c.l, pt.p); c.c = pt.p; } }); const liveCandles = buckets.map((c) => ({ time: Math.floor(c.t / 1e3), open: c.o, high: c.h, low: c.l, close: c.c })); const mergedMap = /* @__PURE__ */ new Map(); historyCandles.forEach((c) => mergedMap.set(c.time, __spreadValues({}, c))); liveCandles.forEach((c) => { const old = mergedMap.get(c.time); if (old) { mergedMap.set(c.time, { time: c.time, open: old.open, high: Math.max(old.high, c.high), low: Math.min(old.low, c.low), close: c.close }); } else { mergedMap.set(c.time, c); } }); const candles = Array.from(mergedMap.values()).sort((a, b) => a.time - b.time).slice(-220); React.useEffect(() => { if (!candleRef.current) return; const data = candles.map((c) => ({ time: c.time, open: c.open, high: c.high, low: c.low, close: c.close })); candleRef.current.setData(data); if (last > 0) { if (priceLineRef.current) candleRef.current.removePriceLine(priceLineRef.current); priceLineRef.current = candleRef.current.createPriceLine({ price: last, color: ask2 > bid ? "#22c55e" : "#ef4444", lineWidth: 1, lineStyle: 2, axisLabelVisible: true, title: "TradeFX" }); } if (chartRef.current && data.length > 1) chartRef.current.timeScale().fitContent(); }, [candles.length, historyCandles.length, tf, last, bid, ask2]); return /* @__PURE__ */ React.createElement("div", { className: "border-y border-theme/60 bg-[#07101d] px-3 py-3" }, /* @__PURE__ */ React.createElement("div", { className: "sticky top-0 z-20 -mx-3 -mt-3 mb-3 border-b border-theme/60 bg-[#07101d]/95 px-3 py-2 backdrop-blur" }, /* @__PURE__ */ React.createElement("button", { onClick: onCloseChart, className: "rounded-lg border border-theme bg-black/30 px-3 py-2 text-xs font-black text-theme-main shadow-lg" }, "BACK TO ORDER")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 mb-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted uppercase tracking-[0.18em]" }, "Chart"), /* @__PURE__ */ React.createElement("div", { className: "text-xs font-black text-theme-main truncate max-w-[260px]" }, (item == null ? void 0 : item.symbol) || (item == null ? void 0 : item.name) || chartKey)), /* @__PURE__ */ React.createElement("div", { className: "flex gap-1" }, ["1m", "3m", "5m", "15m", "30m", "1h"].map((x) => /* @__PURE__ */ React.createElement("button", { key: x, onClick: () => setTf(x), className: `px-2 py-1 rounded text-[10px] font-bold border ${tf === x ? "bg-[#1c7cd5] border-[#1c7cd5] text-white" : "bg-black/20 border-theme text-theme-muted"}` }, x)))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-3 gap-2 mb-3" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-red-500/30 bg-red-500/10 p-2 text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[9px] text-theme-muted" }, "BID"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-black text-red-300" }, bid > 0 ? bid.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-theme bg-black/20 p-2 text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[9px] text-theme-muted" }, "LTP"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-black text-theme-main" }, last > 0 ? last.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-green-500/30 bg-green-500/10 p-2 text-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-[9px] text-theme-muted" }, "ASK"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-black text-green-300" }, ask2 > 0 ? ask2.toFixed(2) : "-"))), /* @__PURE__ */ React.createElement("div", { ref: chartEl, className: "w-full h-[310px] rounded-xl bg-[#050914] border border-theme overflow-hidden" }), historyStatus === "LOADING" && /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-[10px] text-theme-muted" }, "Loading previous candles..."), historyStatus === "EMPTY" && candles.length < 2 && /* @__PURE__ */ React.createElement("div", { className: "mt-2 text-[10px] text-theme-muted" }, "Historical candles unavailable for this script right now.")); } function LiveChartModal({ item, ticks, onClose, onSubscribe }) { var _a, _b; const chartKey = (item == null ? void 0 : item.key) || (item == null ? void 0 : item.instrument_key) || (item == null ? void 0 : item.fyers_symbol) || (item == null ? void 0 : item.symbol); const chartName = (item == null ? void 0 : item.symbol) || (item == null ? void 0 : item.name) || chartKey || "Chart"; const [points, setPoints] = React.useState([]); React.useEffect(() => { if (item && onSubscribe) onSubscribe(getSubscriptionKeysForItem(item)); }, [chartKey, onSubscribe]); const tick = getTickForItem(ticks, item || {}); const bid = Number((tick == null ? void 0 : tick.bid) || (tick == null ? void 0 : tick.best_bid) || (tick == null ? void 0 : tick.bestBid) || 0); const ask2 = Number((tick == null ? void 0 : tick.ask) || (tick == null ? void 0 : tick.best_ask) || (tick == null ? void 0 : tick.bestAsk) || 0); const ltp = Number((tick == null ? void 0 : tick.ltp) || (tick == null ? void 0 : tick.last_traded_price) || (tick == null ? void 0 : tick.close) || bid || ask2 || 0); React.useEffect(() => { if (!ltp || !Number.isFinite(ltp)) return; setPoints((prev) => [...prev, { t: Date.now(), p: ltp, bid, ask: ask2 }].slice(-90)); }, [ltp, bid, ask2, chartKey]); const prices = points.map((p) => p.p); const min = prices.length ? Math.min(...prices) : ltp; const max = prices.length ? Math.max(...prices) : ltp; const spread = Math.max(max - min, 0.01); const width = 680; const height = 260; const pad = 18; const path = points.map((p, i) => { const x = pad + (points.length <= 1 ? 0 : i * ((width - pad * 2) / (points.length - 1))); const y = height - pad - (p.p - min) / spread * (height - pad * 2); return `${i === 0 ? "M" : "L"}${x.toFixed(1)} ${y.toFixed(1)}`; }).join(" "); const last = ((_a = points[points.length - 1]) == null ? void 0 : _a.p) || ltp || 0; const first = ((_b = points[0]) == null ? void 0 : _b.p) || last; const up = last >= first; return /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 bg-black/80 z-[70] flex items-center justify-center p-3", onClick: onClose }, /* @__PURE__ */ React.createElement("div", { className: "w-full max-w-3xl rounded-2xl border border-theme bg-theme-card shadow-2xl overflow-hidden", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3 px-4 py-3 border-b border-theme" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "text-theme-main font-black text-sm" }, chartName), /* @__PURE__ */ React.createElement("div", { className: "text-[11px] text-theme-muted font-mono" }, "Live tick chart")), /* @__PURE__ */ React.createElement("button", { onClick: onClose, className: "w-8 h-8 rounded-full border border-theme bg-black/20 text-white text-base font-bold leading-none shrink-0 flex items-center justify-center" }, "\u2715")), /* @__PURE__ */ React.createElement("div", { className: "p-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-3 gap-2 mb-3 text-center" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-theme bg-black/20 p-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "BID"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-black text-red-300" }, bid > 0 ? bid.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-theme bg-black/20 p-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "LTP"), /* @__PURE__ */ React.createElement("div", { className: `font-mono font-black ${up ? "text-green-300" : "text-red-300"}` }, last > 0 ? last.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-theme bg-black/20 p-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-[10px] text-theme-muted" }, "ASK"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-black text-green-300" }, ask2 > 0 ? ask2.toFixed(2) : "-"))), /* @__PURE__ */ React.createElement("svg", { viewBox: `0 0 ${width} ${height}`, className: "w-full h-[280px] rounded-xl bg-[#070b12] border border-theme" }, /* @__PURE__ */ React.createElement("line", { x1: pad, y1: height - pad, x2: width - pad, y2: height - pad, stroke: "rgba(148,163,184,.25)" }), /* @__PURE__ */ React.createElement("line", { x1: pad, y1: pad, x2: pad, y2: height - pad, stroke: "rgba(148,163,184,.25)" }), [0.25, 0.5, 0.75].map((g, i) => /* @__PURE__ */ React.createElement("line", { key: i, x1: pad, y1: pad + g * (height - pad * 2), x2: width - pad, y2: pad + g * (height - pad * 2), stroke: "rgba(148,163,184,.12)" })), path && /* @__PURE__ */ React.createElement("path", { d: path, fill: "none", stroke: up ? "#22c55e" : "#ef4444", strokeWidth: "3", strokeLinejoin: "round", strokeLinecap: "round" }), points.length < 2 && /* @__PURE__ */ React.createElement("text", { x: width / 2, y: height / 2, textAnchor: "middle", fill: "#94a3b8", fontSize: "16" }, "Waiting for live ticks..."), /* @__PURE__ */ React.createElement("text", { x: width - pad - 4, y: pad + 10, textAnchor: "end", fill: "#94a3b8", fontSize: "12" }, max ? max.toFixed(2) : "-"), /* @__PURE__ */ React.createElement("text", { x: width - pad - 4, y: height - pad - 6, textAnchor: "end", fill: "#94a3b8", fontSize: "12" }, min ? min.toFixed(2) : "-"))))); } function OrderPad({ item, ticks, onClose, rules = {}, isStale = false, onSubscribe }) { const instrumentKey = item.key || item.instrument_key || item.fyers_symbol || item.symbol; const instrumentSymbol = item.symbol || item.name || item.displayName || instrumentKey || ""; const instrumentName = item.name || item.displayName || item.symbol || instrumentKey || ""; const instrumentExch = (item.exch || item.exchange || "").toUpperCase(); React.useEffect(() => { if (onSubscribe) onSubscribe(getSubscriptionKeysForItem(item)); }, [instrumentKey, onSubscribe]); const tick = getTickForItem(ticks, item); let lotSize = 1; if (tick.lot) lotSize = parseInt(tick.lot); else if (item.lot) lotSize = parseInt(item.lot); else if (item.lot_size) lotSize = parseInt(item.lot_size); else if (item.lotsize) lotSize = parseInt(item.lotsize); const upperInstrumentSymbol = String(instrumentSymbol || "").toUpperCase(); const staleIndexFutureLots = { NIFTY: { stale: [25], current: 65 }, BANKNIFTY: { stale: [15], current: 30 }, FINNIFTY: { stale: [25], current: 60 }, MIDCPNIFTY: { stale: [50], current: 120 } }; for (const [prefix, config] of Object.entries(staleIndexFutureLots)) { if (upperInstrumentSymbol.startsWith(prefix) && upperInstrumentSymbol.endsWith("FUT") && config.stale.includes(lotSize)) { lotSize = config.current; break; } } if (isNaN(lotSize) || lotSize < 1 || lotSize === 1) { const mcxLotFallback = { GOLD: 100, GOLDM: 10, SILVER: 30, SILVERM: 5, CRUDEOIL: 100, NATURALGAS: 1250, COPPER: 2500, ZINC: 5e3, ALUMINIUM: 5e3, LEAD: 5e3 }; const lotKey = String(instrumentName || instrumentSymbol || "").toUpperCase(); for (const [prefix, fallbackLot] of Object.entries(mcxLotFallback)) { if (lotKey.startsWith(prefix)) { lotSize = fallbackLot; break; } } } if (isNaN(lotSize) || lotSize < 1) lotSize = 1; const isIndexOrOpt = lotSize > 1; const [mode, setMode] = React.useState(isIndexOrOpt ? "LOT" : "QTY"); const [inputValue, setInputValue] = React.useState(1); const [side, setSide] = React.useState(item.side || "BUY"); const [product, setProduct] = React.useState("INTRADAY"); const [slPrice, setSlPrice] = React.useState(""); const [tgPrice, setTgPrice] = React.useState(""); const [priceType, setPriceType] = React.useState("MARKET"); const [status, setStatus] = React.useState(""); const [showSL, setShowSL] = React.useState(false); const [showTG, setShowTG] = React.useState(false); const [showDetails, setShowDetails] = React.useState(false); const [showChart, setShowChart] = React.useState(false); React.useEffect(() => { if (!showChart) return; const onPopState = () => setShowChart(false); window.history.pushState({ tradefx_chart_open: true, instrumentKey }, ""); window.addEventListener("popstate", onPopState); return () => window.removeEventListener("popstate", onPopState); }, [showChart, instrumentKey]); React.useEffect(() => { const nextSide = item.side || "BUY"; setMode(lotSize > 1 ? "LOT" : "QTY"); setInputValue(1); setSide(nextSide); setProduct("INTRADAY"); setSlPrice(""); setTgPrice(""); setPriceType("MARKET"); setStatus(""); setShowSL(false); setShowTG(false); setShowDetails(false); setShowChart(false); }, [instrumentKey]); const ltp = (tick == null ? void 0 : tick.ltp) && (tick == null ? void 0 : tick.ltp) > 0 ? tick.ltp : (tick == null ? void 0 : tick.close) && (tick == null ? void 0 : tick.close) > 0 ? tick.close : item.ltp || 0; const { bid: bidPrice, ask: askPrice } = getQuoteDisplay(tick); const getMarketQuotePrice = (s) => s === "BUY" ? askPrice : bidPrice; const getDefaultPrice = (s) => { return getMarketQuotePrice(s) || ltp; }; const [limitPrice, setLimitPrice] = React.useState(getDefaultPrice(item.side || "BUY")); React.useEffect(() => { setLimitPrice(getDefaultPrice(side)); }, [instrumentKey]); React.useEffect(() => { if (priceType === "LIMIT") { setLimitPrice(getDefaultPrice(side)); } }, [side, priceType, instrumentKey]); const isBuy = side === "BUY"; const finalQty = mode === "LOT" ? inputValue * lotSize : inputValue; const submit = async () => { if (isStale) { alert("\u26A0\uFE0F SAFE MODE: Data update delayed!"); return; } if (priceType === "MARKET" && getMarketQuotePrice(side) <= 0) { alert("Wait for Bid/Ask Update"); return; } if (finalQty < 1) { alert("\u26A0\uFE0F Error: Minimum Qty is 1"); return; } const marketPrice = getMarketQuotePrice(side); const execPrice = priceType === "LIMIT" ? limitPrice : marketPrice; setStatus("EXECUTING..."); let _curUser = {}; try { _curUser = JSON.parse(localStorage.getItem(USER_KEY) || "{}"); } catch (e) { } const _callerRole = _curUser.role || "CLIENT"; const orderRes = await api("place_order", { symbol: instrumentKey, name: instrumentName, side, qty: finalQty, price: execPrice, bid: bidPrice, ask: askPrice, lot_size: lotSize, exch: instrumentExch || "NSE", option_type: item.option_type || "XX", type: priceType, limitPrice: execPrice, caller_role: _callerRole, sl_price: showSL && slPrice ? parseFloat(slPrice) : 0, tg_price: showTG && tgPrice ? parseFloat(tgPrice) : 0 }); if (orderRes && orderRes.error) { notify("\u274C " + (orderRes.message || orderRes.error), "error"); setStatus("FAILED"); return; } notify("\u2705 " + (orderRes.message || "Order Placed"), "success"); setStatus("SUCCESS"); setTimeout(onClose, 1200); }; const getMarginConfig = () => { var _a; const sym = (item.symbol || "").toUpperCase(); const isOpt = item.type === "OPT" || item.option_type === "CE" || item.option_type === "PE" || sym.endsWith("CE") || sym.endsWith("PE"); const isBuy2 = side === "BUY"; let cat = "NSE_FUT"; if (isOpt) { cat = isBuy2 ? "OPTION_BUY" : "OPTION_SELL"; } else { if (instrumentExch === "BINANCE" || instrumentExch === "CRYPTO") cat = "CRYPTO"; else if (sym.includes("GOLDM")) cat = "GOLDM"; else if (sym.includes("SILVERMIC")) cat = "SILVERMIC"; else if (sym.includes("CRUDEM") || sym.includes("CRUDEOILM")) cat = "CRUDEM"; else if (instrumentExch === "MCX" || instrumentExch === "MCX_FO") cat = "MCX"; else if (instrumentExch === "BFO" || instrumentExch === "BSE_FO") cat = "BFO"; else if ((_a = item.symbol) == null ? void 0 : _a.includes("-EQ")) cat = "NSE_EQUITY"; else { const n = (item.symbol || "").toUpperCase(); if (n.includes("NIFTY") || n.includes("BANKNIFTY") || n.includes("FINNIFTY") || n.includes("SENSEX")) cat = "NSE_INDEX"; else cat = "NSE_FUT"; } } const defaultRules = { "NSE_FUT": { mode: "X", intraday: 1e3, holding: 100 }, "NSE_INDEX": { mode: "X", intraday: 1e3, holding: 100 }, "MCX": { mode: "X", intraday: 1e3, holding: 100 }, "GOLDM": { mode: "X", intraday: 1e3, holding: 100 }, "SILVERMIC": { mode: "X", intraday: 1e3, holding: 100 }, "CRUDEM": { mode: "X", intraday: 1e3, holding: 100 }, "BFO": { mode: "X", intraday: 1e3, holding: 100 }, "NSE_EQUITY": { mode: "X", intraday: 1, holding: 1 }, "OPTION_BUY": { mode: "X", intraday: 20, holding: 10 }, "OPTION_SELL": { mode: "FIXED", intraday: 5e3, holding: 1e4 }, "CRYPTO": { mode: "X", intraday: 100, holding: 100 } }; return rules[cat] || defaultRules[cat] || { mode: "X", intraday: 1, holding: 1 }; }; const mConfig = getMarginConfig(); const mVal = (product === "INTRADAY" ? mConfig.intraday : mConfig.holding) || 1; const displayPrice = priceType === "LIMIT" ? limitPrice : getMarketQuotePrice(side); let reqMargin = 0; if (mConfig.mode === "FIXED") { reqMargin = finalQty / lotSize * mVal; } else { reqMargin = displayPrice * finalQty / mVal; } return /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 z-[100] bg-theme-main/80 flex items-center justify-center p-4", onClick: onClose }, /* @__PURE__ */ React.createElement("div", { className: `w-full ${showChart ? "max-w-4xl" : "max-w-sm"} bg-theme-main rounded-lg overflow-hidden border border-theme shadow-2xl`, onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement("div", { className: `h-1.5 ${isBuy ? "bg-[#1c7cd5]" : "bg-[#d9534f]"}` }), /* @__PURE__ */ React.createElement("div", { className: `p-3 bg-theme-card flex justify-between items-center bg-gradient-to-r ${isBuy ? "from-blue-900/40" : "from-red-900/40"} to-theme-panel relative` }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xs font-black text-theme-main tracking-tight uppercase leading-none" }, instrumentSymbol), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React.createElement("span", { className: `text-[9px] px-1 rounded border font-bold ${isBuy ? "bg-blue-500/20 border-blue-500/30 text-blue-400" : "bg-red-500/20 border-red-500/30 text-red-400"}` }, formatExch(instrumentExch)), /* @__PURE__ */ React.createElement("span", { className: "text-[8px] text-theme-muted font-mono" }, "LTP: ", ltp.toFixed(2), " | ", isBuy ? "ASK" : "BID", ": ", getMarketQuotePrice(side) > 0 ? getMarketQuotePrice(side).toFixed(2) : "-"))), /* @__PURE__ */ React.createElement("div", { className: "text-right pr-6" }, /* @__PURE__ */ React.createElement("div", { className: `text-xl font-mono font-black ${isBuy ? "text-green-400" : "text-red-400"} leading-none` }, priceType === "MARKET" ? getMarketQuotePrice(side) > 0 ? getMarketQuotePrice(side).toFixed(2) : "-" : displayPrice.toFixed(2)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-end gap-2 mt-1" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setShowChart(!showChart), className: `text-[9px] font-bold transition-opacity ${showChart ? "text-green-400" : "text-[#1c7cd5] hover:opacity-70"}` }, "CHART"), /* @__PURE__ */ React.createElement("button", { onClick: () => setShowDetails(!showDetails), className: "text-[9px] font-bold text-[#1c7cd5] hover:opacity-70 transition-opacity" }, showDetails ? "HIDE INFO" : "MARKET INFO"))), /* @__PURE__ */ React.createElement("button", { onClick: onClose, className: "absolute top-2 right-2 text-theme-muted hover:text-theme-main transition-colors p-1" }, /* @__PURE__ */ React.createElement("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" })))), showDetails && /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-3 gap-y-2 gap-x-1.5 bg-theme-panel border-y border-theme/50 py-3 px-3 text-[10px] animate-in slide-in-from-top-1 duration-200" }, /* @__PURE__ */ React.createElement("div", { className: "p-1.5 rounded bg-black/10 relative" }, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5 flex justify-between" }, /* @__PURE__ */ React.createElement("span", null, "Bid"), tick.q_ts && Date.now() - tick.q_ts > 1e4 && /* @__PURE__ */ React.createElement("span", { className: "text-orange-500 font-bold px-1 bg-orange-500/10 rounded" }, "STALE")), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-main" }, bidPrice > 0 ? bidPrice.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "p-1.5 rounded bg-black/10 relative" }, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5 flex justify-between" }, /* @__PURE__ */ React.createElement("span", null, "Ask"), tick.q_ts && Date.now() - tick.q_ts > 1e4 && /* @__PURE__ */ React.createElement("span", { className: "text-orange-500 font-bold px-1 bg-orange-500/10 rounded" }, "STALE")), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-main" }, askPrice > 0 ? askPrice.toFixed(2) : "-")), /* @__PURE__ */ React.createElement("div", { className: "p-1.5 rounded bg-black/10" }, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "Last"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-main" }, ltp.toFixed(2))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "High / Low"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold" }, /* @__PURE__ */ React.createElement("span", { className: "text-green-400" }, (tick.high || 0).toFixed(1)), /* @__PURE__ */ React.createElement("span", { className: "text-theme-muted mx-1" }, "/"), /* @__PURE__ */ React.createElement("span", { className: "text-red-400" }, (tick.low || 0).toFixed(1)))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "Open / Close"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-muted" }, (tick.open || 0).toFixed(1), " / ", (tick.close || 0).toFixed(1))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "Change"), /* @__PURE__ */ React.createElement("div", { className: `font-mono font-bold ${tick.change >= 0 ? "text-green-400" : "text-red-400"}` }, tick.change > 0 ? "+" : "", (tick.change || 0).toFixed(2), "%")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "Volume / LTQ"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-main" }, fmtNum(tick.volume), " / ", tick.ltq || 1)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "ATP / OI"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-theme-main" }, (tick.atp || 0).toFixed(1), " / ", fmtNum(tick.oi))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px] mb-0.5" }, "Lot Size"), /* @__PURE__ */ React.createElement("div", { className: "font-mono font-bold text-[#1c7cd5]" }, lotSize)), (tick.uc > 0 || tick.lc > 0) && /* @__PURE__ */ React.createElement("div", { className: "col-span-3 border-t border-theme/20 pt-2 flex gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px]" }, "Upper Circ."), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] font-mono font-bold text-green-500" }, (tick.uc || 0).toFixed(2))), /* @__PURE__ */ React.createElement("div", { className: "flex-1 text-right" }, /* @__PURE__ */ React.createElement("div", { className: "text-[#666] uppercase text-[8px]" }, "Lower Circ."), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] font-mono font-bold text-red-500" }, (tick.lc || 0).toFixed(2))))), showChart && /* @__PURE__ */ React.createElement(OrderPadChart, { item, ticks, onSubscribe, onCloseChart: () => { if (window.history.state && window.history.state.tradefx_chart_open) window.history.back(); else setShowChart(false); } }), /* @__PURE__ */ React.createElement("div", { className: "flex bg-theme-panel border-b border-theme p-1 gap-1" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setSide("BUY"), className: `flex-1 py-1.5 rounded font-black text-[11px] uppercase transition-all ${isBuy ? "bg-[#1c7cd5] text-white shadow-lg" : "text-theme-muted opacity-40 hover:opacity-60"}` }, "BUY"), /* @__PURE__ */ React.createElement("button", { onClick: () => setSide("SELL"), className: `flex-1 py-1.5 rounded font-black text-[11px] uppercase transition-all ${!isBuy ? "bg-[#d9534f] text-white shadow-lg" : "text-theme-muted opacity-40 hover:opacity-60"}` }, "SELL")), /* @__PURE__ */ React.createElement("div", { className: `p-4 pt-3 ${isBuy ? "bg-green-500/5" : "bg-red-500/5"} transition-colors duration-300` }, isStale && /* @__PURE__ */ React.createElement("div", { className: "mb-4 rounded-lg border border-yellow-500/30 bg-yellow-500/10 px-3 py-2 text-xs text-yellow-200" }, "Live feed is delayed."), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1 flex bg-theme-panel p-1 rounded border border-theme/50 text-[10px] font-bold" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setProduct("INTRADAY"), className: `flex-1 py-1 rounded ${product === "INTRADAY" ? "bg-theme-input text-theme-main" : "text-theme-muted"}` }, "INTRADAY"), /* @__PURE__ */ React.createElement("button", { onClick: () => setProduct("DELIVERY"), className: `flex-1 py-1 rounded ${product === "DELIVERY" ? "bg-theme-input text-theme-main" : "text-theme-muted"}` }, "DELIVERY")), /* @__PURE__ */ React.createElement("div", { className: "flex-1 flex bg-theme-panel p-1 rounded border border-theme/50 text-[10px] font-bold" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setPriceType("MARKET"), className: `flex-1 py-1 rounded ${priceType === "MARKET" ? "bg-theme-input text-[#1c7cd5]" : "text-theme-muted"}` }, "MARKET"), /* @__PURE__ */ React.createElement("button", { onClick: () => setPriceType("LIMIT"), className: `flex-1 py-1 rounded ${priceType === "LIMIT" ? "bg-theme-input text-[#1c7cd5]" : "text-theme-muted"}` }, "LIMIT"))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col sm:flex-row gap-x-4 gap-y-3 mb-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-end mb-1" }, /* @__PURE__ */ React.createElement("label", { className: "text-[10px] text-theme-muted font-bold uppercase tracking-wider" }, mode === "LOT" ? "lots" : "qty", " (Lot:", lotSize, ")"), /* @__PURE__ */ React.createElement("div", { className: "flex bg-theme-panel p-0.5 rounded border border-theme/30 text-[9px] font-bold h-6" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setMode("LOT"), className: `px-2 rounded ${mode === "LOT" ? "bg-[#1c7cd5] text-white" : "text-theme-muted"}` }, "LOT"), /* @__PURE__ */ React.createElement("button", { onClick: () => setMode("QTY"), className: `px-2 rounded ${mode === "QTY" ? "bg-[#1c7cd5] text-white" : "text-theme-muted"}` }, "QTY"))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setInputValue(Math.max(1, inputValue - 1)), className: "w-8 h-9 bg-theme-panel border border-theme rounded text-theme-main font-bold" }, "-"), /* @__PURE__ */ React.createElement("input", { type: "number", value: inputValue, onChange: (e) => setInputValue(Number(e.target.value)), className: "flex-1 bg-theme-input border border-theme text-theme-main h-9 rounded font-mono text-center text-sm outline-none focus:border-[#1c7cd5]" }), /* @__PURE__ */ React.createElement("button", { onClick: () => setInputValue(inputValue + 1), className: "w-8 h-9 bg-theme-panel border border-theme rounded text-theme-main font-bold" }, "+")), mode === "LOT" && /* @__PURE__ */ React.createElement("div", { className: "text-[9px] text-green-400 mt-1 font-bold" }, "Total Qty: ", finalQty)), /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("label", { className: "block text-[10px] text-theme-muted font-bold mb-1 uppercase tracking-wider" }, "price"), /* @__PURE__ */ React.createElement("input", { type: "number", step: "0.05", value: priceType === "MARKET" ? "" : limitPrice, disabled: priceType === "MARKET", onChange: (e) => setLimitPrice(Number(e.target.value)), className: "w-full bg-theme-input border border-theme text-theme-main h-9 px-3 rounded font-mono text-sm outline-none focus:border-[#1c7cd5]", placeholder: "Market" }))), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center mb-4 text-[11px] font-mono bg-theme-panel/30 p-2 rounded border border-theme/20" }, /* @__PURE__ */ React.createElement("span", { className: "text-theme-muted" }, "Value: ", /* @__PURE__ */ React.createElement("span", { className: "text-theme-main font-bold" }, fmtMoney(displayPrice * finalQty))), /* @__PURE__ */ React.createElement("span", { className: "text-theme-muted" }, "Margin: ", /* @__PURE__ */ React.createElement("span", { className: "text-orange-500 font-bold" }, fmtMoney(reqMargin)))), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 mb-4" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setShowSL(!showSL), className: `flex-1 py-1.5 rounded text-[10px] font-bold border transition-all ${showSL ? "bg-red-500/10 border-red-500/50 text-red-400" : "bg-theme-panel border-theme text-theme-muted"}` }, showSL ? "\u2713 SL ACTIVE" : "+ ADD STOPLOSS"), /* @__PURE__ */ React.createElement("button", { onClick: () => setShowTG(!showTG), className: `flex-1 py-1.5 rounded text-[10px] font-bold border transition-all ${showTG ? "bg-green-500/10 border-green-500/50 text-green-400" : "bg-theme-panel border-theme text-theme-muted"}` }, showTG ? "\u2713 TG ACTIVE" : "+ ADD TARGET")), (showSL || showTG) && /* @__PURE__ */ React.createElement("div", { className: "flex gap-3 mb-5 animate-in fade-in slide-in-from-top-2 duration-300" }, showSL && /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("label", { className: "block text-[9px] text-theme-muted font-bold mb-1 uppercase" }, "Stoploss"), /* @__PURE__ */ React.createElement("input", { type: "number", step: "0.05", value: slPrice, onChange: (e) => setSlPrice(e.target.value), placeholder: "0.00", className: "w-full bg-theme-input border border-red-500/30 text-theme-main p-2 rounded text-center text-xs outline-none focus:border-red-500" })), showTG && /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("label", { className: "block text-[9px] text-theme-muted font-bold mb-1 uppercase" }, "Target"), /* @__PURE__ */ React.createElement("input", { type: "number", step: "0.05", value: tgPrice, onChange: (e) => setTgPrice(e.target.value), placeholder: "0.00", className: "w-full bg-theme-input border border-green-500/30 text-theme-main p-2 rounded text-center text-xs outline-none focus:border-green-500" }))), /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React.createElement( "button", { onClick: submit, disabled: status === "EXECUTING...", className: `w-full py-3 rounded-lg font-black text-white text-sm uppercase tracking-widest transition-all active:scale-95 disabled:opacity-50 ${isBuy ? "bg-gradient-to-r from-green-600 to-green-500 shadow-lg shadow-green-900/30" : "bg-gradient-to-r from-red-600 to-red-500 shadow-lg shadow-red-900/30"}` }, status || (isBuy ? "Execute Buy" : "Execute Sell") ))))); } function App() { const [user, setUser] = React.useState(localStorage.getItem(TOKEN_KEY)); const [nav, setNav] = React.useState("Market"); const [ticks, setTicks] = React.useState({}); const [connected, setConnected] = React.useState(false); const [dataStale, setDataStale] = React.useState(false); const lastTickTime = React.useRef(Date.now()); const [retryCount, setRetryCount] = React.useState(0); const [padItem, setPadItem] = React.useState(null); const [chartModalItem, setChartModalItem] = React.useState(null); const [indices, setIndices] = React.useState({}); const [rules, setRules] = React.useState({}); const [searchResults, setSearchResults] = React.useState([]); const [refreshConfig, setRefreshConfig] = React.useState(0); const [pendingOrdersForTrigger, setPendingOrdersForTrigger] = React.useState([]); const wsRef = React.useRef(null); const executingPendingOrdersRef = React.useRef(/* @__PURE__ */ new Set()); const [theme, setTheme] = React.useState(localStorage.getItem("theme") || "dark"); const doSearch = (q2) => { const uid = localStorage.getItem(TOKEN_KEY) || "demo"; if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) { wsRef.current.send(JSON.stringify({ type: "search", query: q2, user_id: uid })); } }; React.useEffect(() => { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("theme", theme); }, [theme]); React.useEffect(() => { const i = setInterval(() => { const diff = Date.now() - lastTickTime.current; const isStale = diff > STALE_TIMEOUT_MS; if (isStale !== dataStale) setDataStale(isStale); }, 1e3); return () => clearInterval(i); }, [dataStale]); React.useEffect(() => { if (!user) return; let alive = true; const loadPendingOrders = () => { api("get_orders").then((data) => { if (!alive) return; const list = data.orders || data || []; const pending = Array.isArray(list) ? list.filter((o) => String(o.status || "").toUpperCase() === "PENDING") : []; setPendingOrdersForTrigger(pending); }).catch(() => { }); }; loadPendingOrders(); const timer = setInterval(loadPendingOrders, 2500); return () => { alive = false; clearInterval(timer); }; }, [user, refreshConfig]); React.useEffect(() => { if (!user || !pendingOrdersForTrigger.length) return; if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) return; const symbols = []; pendingOrdersForTrigger.forEach((order) => { symbols.push(...getSubscriptionKeysForItem({ key: order.symbol, instrument_key: order.symbol, symbol: order.name || order.symbol, name: order.name || order.symbol, exch: order.segment || order.exch || order.exchange })); }); const uniqueSymbols = [...new Set(symbols.filter(Boolean))]; if (uniqueSymbols.length) { wsRef.current.send(JSON.stringify({ type: "subscribe", symbols: uniqueSymbols })); } }, [user, pendingOrdersForTrigger]); React.useEffect(() => { if (!user || !pendingOrdersForTrigger.length) return; const getQuote = (order) => { const tick = getTickForItem(ticks, { key: order.symbol, instrument_key: order.symbol, symbol: order.name || order.symbol, name: order.name || order.symbol, exch: order.segment || order.exch || order.exchange }); const bid = Number(tick.bid || tick.best_bid || tick.bestBid || tick.b || 0); const ask2 = Number(tick.ask || tick.best_ask || tick.bestAsk || tick.a || 0); const ltp = Number(tick.ltp || tick.last_traded_price || tick.close || 0); return { bid, ask: ask2, ltp }; }; const shouldTrigger = (order) => { const target = Number(order.price) || 0; if (!target) return false; const side = String(order.type || "").toUpperCase(); const orderType = String(order.ordertype || "LIMIT").toUpperCase(); const { bid, ask: ask2, ltp } = getQuote(order); if (orderType === "LIMIT") { const triggerAbove = Number(order.trigger_above || 0); if (triggerAbove) { if (side === "BUY") { const buyQuote = ask2 > 0 ? ask2 : ltp; return buyQuote > 0 && buyQuote >= target; } if (side === "SELL") { const sellQuote = bid > 0 ? bid : ltp; return sellQuote > 0 && sellQuote >= target; } } else { if (side === "BUY") { const buyQuote = ask2 > 0 ? ask2 : ltp; return buyQuote > 0 && buyQuote <= target; } if (side === "SELL") { const sellQuote = bid > 0 ? bid : ltp; return sellQuote > 0 && sellQuote >= target; } } } if (orderType === "SL") { if (side === "SELL") { const sellQuote = bid > 0 ? bid : ltp; return sellQuote > 0 && sellQuote <= target; } if (side === "BUY") { const buyQuote = ask2 > 0 ? ask2 : ltp; return buyQuote > 0 && buyQuote >= target; } } if (orderType === "TG") { if (side === "SELL") { const sellQuote = bid > 0 ? bid : ltp; return sellQuote > 0 && sellQuote >= target; } if (side === "BUY") { const buyQuote = ask2 > 0 ? ask2 : ltp; return buyQuote > 0 && buyQuote <= target; } } return false; }; pendingOrdersForTrigger.forEach((order) => { const orderId = String(order.id || ""); if (!orderId || executingPendingOrdersRef.current.has(orderId)) return; if (!shouldTrigger(order)) return; executingPendingOrdersRef.current.add(orderId); api("execute_pending_order", { order_id: order.id, execution_price: Number(order.price) || 0 }).then((res) => { if (res && res.success) { setRefreshConfig((prev) => prev + 1); setPendingOrdersForTrigger((prev) => prev.filter((o) => String(o.id) !== orderId)); } }).finally(() => { executingPendingOrdersRef.current.delete(orderId); }); }); }, [user, ticks, pendingOrdersForTrigger]); React.useEffect(() => { if (!user) return; const wsUrl = location.protocol === "file:" ? "ws://localhost:8766" : `${location.protocol === "https:" ? "wss:" : "ws:"}//${location.host}/ws`; const ws = new WebSocket(wsUrl); ws.onopen = () => { setConnected(true); wsRef.current = ws; const wl = JSON.parse(localStorage.getItem("bt_wl_v11") || "[]"); const indexKeys = ["NSE|26000", "NSE|26009", "NSE|26037", "BSE|1"]; const k = [...indexKeys, ...wl.flatMap(getSubscriptionKeysForItem)].filter(Boolean); if (k.length > 0) { ws.send(JSON.stringify({ type: "subscribe", symbols: k })); } api("get_positions").then((data) => { const rawPositions = data.positions || data || []; const positions = Array.isArray(rawPositions) ? rawPositions : []; const posSymbols = positions.filter((p) => p.status === "OPEN" || p.status === "ACTIVE").map((p) => p.symbol).filter(Boolean); if (posSymbols.length > 0 && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: "subscribe", symbols: posSymbols })); } }); api("get_margin_rules").then((r) => { let finalRules = r.rules || {}; try { const stored = localStorage.getItem(USER_KEY); if (stored) { const u = JSON.parse(stored); if (u.margin_config) finalRules = __spreadValues(__spreadValues({}, finalRules), u.margin_config); } } catch (e) { } setRules(finalRules); }); }; ws.onmessage = (e) => { lastTickTime.current = Date.now(); try { const m = JSON.parse(e.data); if ((m.type === "ticks" || m.type === "snapshot" || m.type === "update") && m.data) { setTicks((prev) => { const nextTicks = __spreadValues({}, prev); m.data.forEach((t) => { const tk = t.key; const prevTick = prev[tk] || {}; const merged = __spreadValues({}, prevTick); for (let k in t) { if (t[k] !== void 0 && t[k] !== null && (t[k] !== 0 || !prevTick[k])) { merged[k] = t[k]; } } if (t.ltp && t.ltp > 0) { merged.ltp = t.ltp; } else if (t.last_traded_price && t.last_traded_price > 0) { merged.ltp = t.last_traded_price; } else if ((t.bid || t.ask) && (!merged.ltp || merged.ltp <= 0)) { merged.ltp = t.bid || t.ask || merged.close || 0; } else if (!merged.ltp || merged.ltp <= 0) { merged.ltp = merged.close || 0; } nextTicks[tk] = merged; if (merged.symbol) { nextTicks[merged.symbol] = merged; const upperSymbol = String(merged.symbol).toUpperCase(); nextTicks[upperSymbol] = merged; if (String(merged.exch || "").toUpperCase() === "CRYPTO") { nextTicks[`CRYPTO|${upperSymbol}`] = merged; nextTicks[`BINANCE|${upperSymbol}`] = merged; } if (String(merged.exch || "").toUpperCase() === "FOREX") { nextTicks[`FOREX|${upperSymbol}`] = merged; } } if (tk === "NSE|26000") setIndices((i) => __spreadProps(__spreadValues({}, i), { nifty: merged })); if (tk === "NSE|26009") setIndices((i) => __spreadProps(__spreadValues({}, i), { banknifty: merged })); }); return nextTicks; }); } if (m.type === "search_result") { let effSegs = {}; try { const u = JSON.parse(localStorage.getItem(USER_KEY) || "{}"); effSegs = u.effective_segments || {}; } catch (e2) { } const filtered = (m.results || []).filter((item) => { if (!Object.keys(effSegs).length) return true; const exch = String(item.exch || item.e || item.exchange || "").toUpperCase(); const sym = String(item.s || item.symbol || "").toUpperCase(); const isOpt = /CE$|PE$/.test(sym); if (exch === "MCX") return isOpt ? effSegs.mcx_opt !== 0 : effSegs.mcx !== 0; if (exch === "MCX_FO") return effSegs.mcx_fo !== 0; if (exch === "NFO") return isOpt ? effSegs.nse_opt !== 0 : effSegs.nfo !== 0; if (exch === "BFO") return isOpt ? effSegs.bse_opt !== 0 : effSegs.bse_fut !== 0; if (exch === "CRYPTO" || exch === "BINANCE") return effSegs.crypto !== 0; if (exch === "FOREX") return effSegs.forex !== 0; if (exch === "COMEX") return effSegs.comex !== 0; if (exch === "USA" || exch === "USA_STOCK") return effSegs.usa_stock !== 0; if (exch === "NSE") { if (sym.endsWith("-EQ")) return effSegs.nse_eq !== 0; if (/NIFTY|BANKNIFTY|FINNIFTY/.test(sym)) return effSegs.nse_index !== 0; return effSegs.nse_fut !== 0; } if (exch === "BSE") { if (sym.endsWith("-EQ")) return effSegs.bse_eq !== 0; if (/SENSEX/.test(sym)) return effSegs.bse_index !== 0; return effSegs.bse_eq !== 0; } return effSegs.equity !== 0; }); setSearchResults(filtered); } if (m.type === "order_update" || m.type === "user_update") setRefreshConfig((prev) => prev + 1); } catch (e2) { } }; ws.onclose = () => { setConnected(false); setTimeout(() => setRetryCount((r) => r + 1), 2e3); }; return () => ws.close(); }, [user, retryCount]); const subscribe = (syms) => { if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) { wsRef.current.send(JSON.stringify({ type: "subscribe", symbols: Array.isArray(syms) ? syms : [syms] })); } }; const logout = () => { localStorage.removeItem(TOKEN_KEY); setUser(null); }; const livePadItem = padItem ? __spreadValues(__spreadValues({}, padItem), getTickForItem(ticks, padItem)) : null; if (!user) return /* @__PURE__ */ React.createElement(Login, { onLogin: setUser, theme, setTheme }); return /* @__PURE__ */ React.createElement(Layout, { nav, setNav, connected, indices, dataStale }, nav === "Market" && /* @__PURE__ */ React.createElement(Watchlist, { ticks, indices, onSelect: setPadItem, searchResults, onSearch: doSearch, onSubscribe: subscribe, onChart: setChartModalItem }), nav === "Orders" && /* @__PURE__ */ React.createElement(Orders, { refresh: refreshConfig }), nav === "Position" && /* @__PURE__ */ React.createElement(Positions, { ticks, refresh: refreshConfig, onSubscribe: subscribe }), nav === "Profile" && /* @__PURE__ */ React.createElement(Profile, { onLogout: logout, theme, setTheme, refresh: refreshConfig, onUpdateRules: (r) => setRules((prev) => __spreadValues(__spreadValues({}, prev), r)) }), livePadItem && nav !== "Profile" && /* @__PURE__ */ React.createElement(OrderPad, { key: livePadItem.key || livePadItem.instrument_key || livePadItem.fyers_symbol || livePadItem.symbol, item: livePadItem, ticks, onClose: () => setPadItem(null), rules, isStale: dataStale, onSubscribe: subscribe }), chartModalItem && /* @__PURE__ */ React.createElement(LiveChartModal, { item: chartModalItem, ticks, onClose: () => setChartModalItem(null), onSubscribe: subscribe })); } ReactDOM.createRoot(document.getElementById("root")).render(/* @__PURE__ */ React.createElement(App, null)); })();