Waiting for torrents...
';\n }\n function renderTrackerFilters(force=false){\n const box=$('trackerFilters');\n if(!box) return;\n const trackers=trackerSummary.trackers || [];\n // Note: Keep the selected tracker while the async summary is loading or temporarily incomplete; otherwise sorting can reset mobile scope to All trackers.\n if(activeTrackerFilter && trackerSummaryStatus==='ready' && trackers.length && !trackers.some(t=>t.domain===activeTrackerFilter)) activeTrackerFilter='';\n const sig=[\n trackerSummaryStatus,\n trackerFaviconsEnabled ? 1 : 0,\n trackerSummary.pending || 0,\n trackerSummary.cached || 0,\n trackerSummary.scanned || 0,\n trackers.map(t=>`${t.domain}:${t.count||0}:${t.favicon_url||''}`).join('|')\n ].join('::');\n if(!force && sig===lastTrackerFiltersSignature){ syncFilterButtons(); return; }\n lastTrackerFiltersSignature=sig;\n // Note: Tracker filter section is always visible, so an empty or failed tracker scan does not look like a missing feature.\n const rows=trackers.length\n ? ``+\n ` | `+\n `${warn?' ':''}${torrentNameIcon(t)} ${esc(t.name)} | `+\n `${statusBadge(t)} | `+\n `${esc(t.size_h)} | `+\n `${progress(t)} | `+\n `${esc(t.down_rate_h)} | `+\n `${esc(t.up_rate_h)} | `+\n `${esc(t.eta_h||\"-\")} | `+\n `${esc(t.seeds)} | `+\n `${esc(t.peers)} | `+\n `${esc(t.ratio)} | `+\n `${esc(t.path)} | `+\n `${labels||'-'} | `+\n `${esc(t.ratio_group||'')} | `+\n `${esc(t.down_total_h||'-')} | `+\n `${esc(t.to_download_h||'-')} | `+\n `${esc(t.up_total_h||'-')} | `+\n `${esc(formatDateTime(t.created))} | `+\n `${esc(t.priority ?? '-')} | `+\n `${boolCell(t.state)} | `+\n `${boolCell(t.active)} | `+\n `${boolCell(t.complete)} | `+\n `${esc(t.hashing ?? 0)} | `+\n `${compactCell(t.message||'', 80)} | `+\n `${esc(t.hash||'')} | `+\n `
`;\n }\n\n\n\n\n function renderMobile(){\n const list=$('mobileList');\n if(!list) return;\n const src=mobileVisibleRows();\n const rows=src.slice(0,250);\n renderMobileFilters(src);\n list.innerHTML=rows.map(t=>{\n const warn=torrentWarning(t);\n const op=activeOperationFor(t);\n const classes=[selected.has(t.hash)?'selected':'', op?'torrent-operating':'', warn?'torrent-warning':''].filter(Boolean).join(' ');\n const lines=mobileInfoLines(t);\n // Note: Mobile details use a separate corner button so user-configurable action buttons keep their current order.\n return `No torrents.
` : loadingMarkup('Loading torrents...'));\n }\n function renderTable(){ updateBulkBar(); syncActiveFilterSelection(); renderCounts(); renderLabelFilters(); if(typeof renderHealthDashboard==='function') renderHealthDashboard(); if(typeof renderSmartViewsManager==='function') renderSmartViewsManager(); updateSortHeaders(); buildVisibleRows(); renderMobile(); const body=$('torrentBody'); if(!visibleRows.length){ body.innerHTML=hasTorrentSnapshot?`