- Scan-ID:
- d1f561ac-c1e5-49e9-aa8b-7f5708af295cBeendet
- Eingereichte URL:
- https://tracker.qu.ax/
- Bericht beendet:
Links · 3 gefunden
Die von der Seite ausgehenden identifizierten Links
Link | Text |
---|---|
https://qu.ax/donate.html | Support this Tracker |
https://qu.ax/ | qu.ax |
https://erdgeist.org/arts/software/opentracker/ | Opentracker |
JavaScript-Variablen · 9 gefunden
Globale JavaScript-Variablen, die in das Window Object einer Seite geladen werden, sind Variablen, die außerhalb von Funktionen deklariert werden und von jeder Stelle des Codes innerhalb des aktuellen Bereichs zugänglich sind
Name | Typ |
---|---|
onbeforetoggle | object |
documentPictureInPicture | object |
onscrollend | object |
tailwind | object |
/template.html | string |
animateValue | function |
updateStats | function |
fetchStats | function |
copyTrackerAddress | function |
Konsolenprotokoll-Meldungen · 1 gefunden
In der Web-Konsole protokollierte Meldungen
Typ | Kategorie | Protokoll |
---|---|---|
warning | other |
|
HTML
Der HTML-Rohtext der Seite
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>qu.ax Tracker Statistics</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600&display=swap" rel="stylesheet">
<style>
/* Previous styles remain the same */
body {
font-family: 'Open Sans', sans-serif;
background-color: #151515;
}
.gradient-text {
background: linear-gradient(90deg, #E555A6 0%, #e80860 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1rem;
}
.stats-card {
background: rgba(24, 24, 27, 0.6);
backdrop-filter: blur(10px);
border: 1px solid #27272a;
}
/* Chart container styles */
.stats-chart-container {
width: 100%;
height: 0;
padding-bottom: 50%;
position: relative;
overflow: hidden;
}
.stats-chart-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
/* Loading animation styles */
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.loading {
animation: pulse 1.5s ease-in-out infinite;
}
/* Spinner animation */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
@media (max-width: 768px) {
.stats-chart-container {
padding-bottom: 70%;
}
}
</style>
<style>*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.14 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.mx-auto{margin-left:auto;margin-right:auto}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:0.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:0.5rem}.inline-block{display:inline-block}.flex{display:flex}.h-6{height:1.5rem}.min-h-screen{min-height:100vh}.w-6{width:1.5rem}.w-full{width:100%}.max-w-6xl{max-width:72rem}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-between{justify-content:space-between}.gap-2{gap:0.5rem}.gap-3{gap:0.75rem}.gap-4{gap:1rem}.space-y-6 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.rounded-lg{border-radius:0.5rem}.border-2{border-width:2px}.border-\[\#dc0060\]{--tw-border-opacity:1;border-color:rgb(220 0 96 / var(--tw-border-opacity))}.bg-\[\#dc0060\]{--tw-bg-opacity:1;background-color:rgb(220 0 96 / var(--tw-bg-opacity))}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-8{padding-bottom:2rem}.pt-8{padding-top:2rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-6xl{font-size:3.75rem;line-height:1}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.font-normal{font-weight:400}.font-semibold{font-weight:600}.text-\[\#e80860\]{--tw-text-opacity:1;color:rgb(232 8 96 / var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219 / var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.opacity-25{opacity:0.25}.opacity-75{opacity:0.75}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.transition-colors{transition-property:color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;transition-property:color, background-color, border-color, text-decoration-color, fill, stroke;transition-property:color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.duration-300{transition-duration:300ms}.hover\:bg-\[\#a20140\]:hover{--tw-bg-opacity:1;background-color:rgb(162 1 64 / var(--tw-bg-opacity))}.hover\:bg-\[\#dc0060\]:hover{--tw-bg-opacity:1;background-color:rgb(220 0 96 / var(--tw-bg-opacity))}.hover\:text-\[\#a20140\]:hover{--tw-text-opacity:1;color:rgb(162 1 64 / var(--tw-text-opacity))}@media (min-width: 640px){.sm\:flex-row{flex-direction:row}}</style></head>
<body class="min-h-screen text-gray-300">
<div class="min-h-screen flex flex-col items-center justify-start p-4">
<main class="w-full max-w-6xl mx-auto">
<!-- Header Section -->
<header class="text-center mb-12 pt-8">
<h1 class="text-6xl font-normal mb-2">
<span class="gradient-text">qu.ax</span>
</h1>
<h2 class="text-2xl text-gray-400 mb-8">Tracker Statistics</h2>
</header>
<!-- Stats Cards -->
<div class="stats-grid mb-8">
<div class="stats-card rounded-lg p-6">
<h3 class="text-lg text-gray-400 mb-2">Total Torrents</h3>
<div class="flex items-center gap-2">
<p class="text-3xl font-semibold" id="torrent-total">1,454,577</p>
</div>
</div>
<div class="stats-card rounded-lg p-6">
<h3 class="text-lg text-gray-400 mb-2">Connected Peers</h3>
<div class="flex items-center gap-2">
<p class="text-3xl font-semibold" id="peer-total">3,970,458</p>
</div>
</div>
<div class="stats-card rounded-lg p-6">
<h3 class="text-lg text-gray-400 mb-2">Connections/sec</h3>
<div class="flex items-center gap-2">
<p class="text-3xl font-semibold" id="conn-sec">71,304</p>
</div>
</div>
</div>
<!-- Tracker Address -->
<div class="stats-card rounded-lg p-6 mb-8 border-[#dc0060] border-2">
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
<div class="text-lg">
<span class="text-gray-400">Tracker Address:</span>
<span class="font-mono ml-2 text-white" id="tracker-address">udp://tracker.qu.ax:6969</span>
</div>
<button onclick="copyTrackerAddress()" class="bg-[#dc0060] hover:bg-[#a20140] text-white px-6 py-2 rounded-lg transition-colors duration-300">
Copy Address
</button>
</div>
</div>
<!-- Statistics Charts -->
<div class="stats-card rounded-lg p-6 mb-8">
<div class="stats-chart-container">
<img src="tracker_stats_chart.png" alt="Tracker Statistics Charts">
</div>
</div>
<!-- Footer with integrated donation button -->
<footer class="text-center pb-8 space-y-6">
<a href="https://qu.ax/donate.html" class="stats-card inline-block px-8 py-4 rounded-lg border-2 border-[#dc0060] hover:bg-[#dc0060] transition-all duration-300 group">
<div class="flex items-center gap-3">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
<span class="text-lg">Support this Tracker</span>
</div>
</a>
<div class="text-sm text-gray-400">
Powered by <a href="https://qu.ax/" class="text-[#e80860] hover:text-[#a20140]">qu.ax</a> & <a href="https://erdgeist.org/arts/software/opentracker/" class="text-[#e80860] hover:text-[#a20140]">Opentracker</a>
</div>
</footer>
</main>
</div>
<script>
// Constants
const trackerBaseUrl = 'https://tracker.qu.ax/stats';
const updateInterval = 30000; // 30 seconds
// Current values store
let currentValues = {
torrents: 0,
peers: 0,
conns: 0
};
// Animated counter function
function animateValue(element, start, end, duration) {
// Remove loading state
element.innerHTML = '0';
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
const current = Math.floor(start + (end - start) * easeOutQuart);
element.textContent = current.toLocaleString();
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
// Update stats with animation
function updateStats(newValues, animate = true) {
const duration = animate ? 2000 : 0;
if (animate) {
animateValue(document.getElementById('torrent-total'), currentValues.torrents, newValues.torrents, duration);
animateValue(document.getElementById('peer-total'), currentValues.peers, newValues.peers, duration);
animateValue(document.getElementById('conn-sec'), currentValues.conns, newValues.conns, duration);
} else {
document.getElementById('torrent-total').textContent = newValues.torrents.toLocaleString();
document.getElementById('peer-total').textContent = newValues.peers.toLocaleString();
document.getElementById('conn-sec').textContent = newValues.conns.toLocaleString();
}
currentValues = { ...newValues };
}
// Fetch data function
async function fetchStats(animate = true) {
try {
const [torrentResponse, peerResponse, connResponse] = await Promise.all([
fetch(`${trackerBaseUrl}?mode=torr`),
fetch(`${trackerBaseUrl}?mode=peer`),
fetch(`${trackerBaseUrl}?mode=conn`),
]);
if (!torrentResponse.ok || !peerResponse.ok || !connResponse.ok) {
throw new Error('Failed to fetch data');
}
const torrentCount = parseInt(await torrentResponse.text());
const peerCount = parseInt(await peerResponse.text());
const connText = await connResponse.text();
const connMatch = connText.match(/(\d+) conns\/s/);
const connCount = connMatch ? parseInt(connMatch[1]) : 0;
updateStats({
torrents: torrentCount,
peers: peerCount,
conns: connCount
}, animate);
} catch (error) {
console.error('Error fetching stats:', error);
// Show error state if needed
['torrent-total', 'peer-total', 'conn-sec'].forEach(id => {
document.getElementById(id).textContent = 'Error';
});
}
}
// Copy tracker address function
function copyTrackerAddress() {
const address = document.getElementById('tracker-address').textContent;
navigator.clipboard.writeText(address)
.then(() => {
const button = document.querySelector('button');
button.textContent = 'Copied!';
setTimeout(() => {
button.textContent = 'Copy Address';
}, 2000);
})
.catch(err => console.error('Failed to copy:', err));
}
// Initial fetch and set up interval
fetchStats(true);
setInterval(() => fetchStats(true), updateInterval);
</script>
</body></html>