Help
RSS
API
Feed
Maltego
Contact
Domain > mailproxy.at
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2026-02-21
188.40.30.118
(
ClassC
)
Port 80
HTTP/1.1 200 OKDate: Sat, 21 Feb 2026 22:56:43 GMTServer: ApacheUpgrade: h2cConnection: UpgradeLast-Modified: Wed, 03 Sep 2025 15:02:19 GMTETag: bda9-63de6e41ad4c0Accept-Ranges: bytesContent-Length: 48553Content-Type: text/html !DOCTYPE html>html langen>head> meta charsetUTF-8> meta nameviewport contentwidthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalableno> meta nameapple-mobile-web-app-capable contentyes> meta nameapple-mobile-web-app-status-bar-style contentblack-translucent> meta nameapple-mobile-web-app-title contentZulu> meta nametheme-color content#000000> meta namemsapplication-TileColor content#000000> title>Zulu v1.0.0/title> !-- Safari-specific favicon (put first for Safari) --> link relicon typeimage/png href/favicon-96x96.png?v2 sizes16x16 32x32 /> !-- Data URI fallback for Safari --> link relicon hrefdata:image/svg+xml,svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 32 32>rect width32 height32 fillblack/>text x16 y20 text-anchormiddle fillred font-familymonospace font-size20>Z/text>text x16 y20 text-anchormiddle fillnone strokelime stroke-width0.5 font-familymonospace font-size20>Z/text>/svg> /> link relicon typeimage/x-icon href/favicon.ico?v2 /> link relicon typeimage/png href/favicon-96x96.png?v2 sizes96x96 /> link relicon typeimage/png href/favicon-96x96.png?v2 sizes32x32 /> link relicon typeimage/png href/favicon-96x96.png?v2 sizes16x16 /> link relicon typeimage/svg+xml href/favicon.svg?v2 /> link relshortcut icon href/favicon.ico?v2 /> link relicon href/favicon.ico?v2 /> link relicon hreffavicon.ico?v2 /> link relicon typeimage/png hreffavicon-96x96.png?v2 /> link relapple-touch-icon sizes180x180 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes152x152 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes144x144 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes120x120 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes114x114 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes76x76 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes72x72 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes60x60 href/apple-touch-icon.png?v1 /> link relapple-touch-icon sizes57x57 href/apple-touch-icon.png?v1 /> link relapple-touch-icon href/apple-touch-icon.png?v1 /> link relmanifest href/site.webmanifest?v1 /> style> @font-face { font-family: MatrixType Regular; font-style: normal; font-weight: normal; src: local(MatrixType Regular), url(./fonts/Matrixtype-2v3p3.woff) format(woff); } @font-face { font-family: LED Wide; src: url(./fonts/led-wide.otf.woff2) format(woff2); font-weight: normal; font-style: normal; } @font-face { font-family: London Underground; src: url(./fonts/London Underground Regular.ttf) format(truetype); font-weight: normal; font-style: normal; } @font-face { font-family: London Underground; src: url(./fonts/London Underground Medium.ttf) format(truetype); font-weight: 500; font-style: normal; } @font-face { font-family: London Underground; src: url(./fonts/London Underground Bold.ttf) format(truetype); font-weight: bold; font-style: normal; } /style> style> :root { /* Dark mode (default) */ --bg-color: #000000; --text-color: #ffffff; --header-bg: #000000; --header-border: #333333; --header-text: #cccccc; --header-subtitle: #666666; --version-text: #888888; --button-container-bg: #000000; --button-container-border: #333333; --button-bg: rgba(0, 64, 0, 0.5); --button-color: #00ff00; --button-border: #00ff00; --overlap-inactive-color: #cccccc; --overlap-inactive-border: #666666; --overlap-inactive-bg: rgba(102, 102, 102, 0.2); --date-color: #999999; --clock-container-bg: #111111; --clock-container-border: #333333; --market-text: #cccccc; --market-border: #666666; --market-bg: rgba(102, 102, 102, 0.2); } data-themelight { /* Light mode */ --bg-color: #f8f9fa; --text-color: #2c3e50; --header-bg: #ffffff; --header-border: #e9ecef; --header-text: #2c3e50; --header-subtitle: #6c757d; --version-text: #8e9ba8; --button-container-bg: #ffffff; --button-container-border: #e9ecef; --button-bg: rgba(0, 64, 0, 0.08); --button-color: #155724; --button-border: #28a745; --overlap-inactive-color: #6c757d; --overlap-inactive-border: #d1d3d4; --overlap-inactive-bg: rgba(108, 117, 125, 0.1); --date-color: #6c757d; --clock-container-bg: #f1f3f4; --clock-container-border: #d6d8db; --market-text: #6c757d; --market-border: #d1d3d4; --market-bg: rgba(108, 117, 125, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; } /* Prevent double-tap zoom on iOS */ body { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; touch-action: manipulation; } body { background: var(--bg-color); font-family: MatrixType Regular, monospace; color: var(--text-color); min-height: 100vh; display: flex; flex-direction: column; transition: background-color 0.3s ease, color 0.3s ease; } .clock-container { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 10px; gap: 10px; } .clock-display { background: var(--clock-container-bg); border: 1px solid var(--clock-container-border); border-radius: 6px; padding: 15px; text-align: center; transition: background-color 0.3s ease, border-color 0.3s ease; } .led-panel { background: linear-gradient(145deg, #0a0a0a 0%, #1a1a1a 50%, #0a0a0a 100%); border: 2px solid #333333; border-radius: 8px; padding: 16px 24px; margin: 6px auto; max-width: 520px; min-width: 480px; box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 3px 12px rgba(0, 0, 0, 0.4); position: relative; overflow: visible; } .led-panel::before { content: ; position: absolute; top: 2px; left: 2px; right: 2px; height: 1px; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.08), transparent); } .timezone-label { font-size: 14px; color: #00ff00; /* Always green LED color */ text-transform: uppercase; letter-spacing: 1px; margin-top: 6px; margin-bottom: 6px; font-weight: normal; font-family: MatrixType Regular, monospace; background: transparent; /* LED panel provides background */ padding: 0; border-radius: 0; display: block; width: fit-content; margin-left: auto; margin-right: auto; text-shadow: 0 0 12px rgba(0, 255, 0, 0.7); filter: contrast(1.6) brightness(1.4); } /* Timezone label parts */ .tz-label { margin-right: 6px; } .tz-offset { font-size: 0.7em; color: #999999; /* Always gray for LED offset */ padding: 0; border: none; background: transparent; border-radius: 0; text-shadow: none; opacity: 0.8; } .time-display { font-size: 36px; color: #ff0000; /* Always red LED color */ font-family: MatrixType Regular, monospace; font-weight: normal; letter-spacing: 2px; line-height: 1; margin-bottom: 8px; display: inline-block; /* size to core only for centering */ position: relative; /* allow absolute offset placement */ vertical-align: baseline; } .time-core { background: transparent; /* Remove background - LED panel provides it */ padding: 0; border-radius: 0; display: inline-block; } .time-offset { font-size: 0.35em; color: #888888; /* Slightly lighter for better contrast on LED panel */ text-shadow: none !important; position: absolute; /* do not affect centering of core */ left: 100%; bottom: 0; margin-left: 10px; } .colon { font-family: MatrixType Regular, monospace; font-weight: normal; font-size: 0.8em; vertical-align: middle; } .dot { font-family: MatrixType Regular, monospace; font-weight: normal; font-size: 0.8em; vertical-align: bottom; } .slash { font-family: MatrixType Regular, monospace; font-weight: normal; } .header { background: var(--header-bg); border: 1px solid var(--header-border); border-radius: 12px 12px 0 0; padding: 20px 20px 15px 20px; text-align: center; position: relative; margin: 0 10px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease, border-color 0.3s ease; } .header-title { font-size: 20px; color: var(--header-text); text-transform: uppercase; letter-spacing: 6px; font-family: MatrixType Regular, monospace; font-weight: normal; margin: 0; text-shadow: 0 0 10px rgba(204, 204, 204, 0.3); transition: color 0.3s ease; } .version { font-size: 10px; color: var(--version-text); text-transform: uppercase; letter-spacing: 1px; font-family: MatrixType Regular, monospace; font-weight: normal; margin-top: 6px; opacity: 0.8; transition: color 0.3s ease; } .header-subtitle { font-size: 12px; color: var(--header-subtitle); text-transform: uppercase; letter-spacing: 2px; font-family: MatrixType Regular, monospace; font-weight: normal; margin-top: 4px; transition: color 0.3s ease; } .button-container { background: var(--button-container-bg); border: 1px solid var(--button-container-border); border-top: none; border-radius: 0 0 8px 8px; padding: 10px 20px; margin: 0 10px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease, border-color 0.3s ease; } .left-buttons { display: flex; gap: 4px; flex-wrap: wrap; } .right-buttons { display: flex; gap: 4px; } /* Mobile responsive button layout */ @media (max-width: 600px) { .button-container { flex-direction: column; gap: 8px; align-items: stretch; padding: 12px 15px; } .left-buttons { justify-content: center; gap: 6px; } .right-buttons { justify-content: center; } .toggle-button { width: 140px !important; font-size: 10px; height: 24px; } .update-button { width: 140px !important; font-size: 10px; height: 24px; } } .toggle-button { background: var(--button-bg); color: var(--button-color); border: 1px solid var(--button-border); padding: 0 12px; font-family: MatrixType Regular, monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; border-radius: 4px; width: 160px; height: 28px; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top; line-height: 1; flex-shrink: 0; transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; } .update-button { background: var(--button-bg); color: var(--button-color); border: 1px solid var(--button-border); padding: 0 12px; font-family: MatrixType Regular, monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; border-radius: 4px; width: 160px; height: 28px; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top; line-height: 1; flex-shrink: 0; transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; } .milliseconds.hidden { display: none; } .status-display { font-size: 11px; padding: 3px 6px; border: 1px solid #555555; border-radius: 3px; display: inline-block; text-transform: uppercase; letter-spacing: 0.5px; font-family: MatrixType Regular, monospace; font-weight: normal; margin-top: 6px; background: rgba(85, 85, 85, 0.3); opacity: 0.9; } .status-market-open, .status-market-closed { color: #aaaaaa; /* Always gray on LED panel */ border-color: #555555; } .date-display { font-size: 13px; color: #888888; /* Always gray on LED panel */ text-transform: uppercase; letter-spacing: 1px; font-family: MatrixType Regular, monospace; font-weight: normal; margin-bottom: 6px; opacity: 0.9; } .overlap-indicator { display: flex; justify-content: center; padding: 8px 10px; margin: 0 10px; } .overlap-status { font-size: 14px; padding: 0; border: none; border-radius: 0; display: block; text-transform: uppercase; letter-spacing: 1px; font-family: MatrixType Regular, monospace; font-weight: normal; text-align: center; background: transparent; } .overlap-status.active { color: #ff9500; text-shadow: 0 0 12px rgba(255, 149, 0, 0.7); filter: contrast(1.6) brightness(1.4); } .overlap-status.inactive { color: #888888; opacity: 0.9; } /* Enhance LED effect for time display */ .time-display { filter: contrast(1.6) brightness(1.4); text-shadow: 0 0 15px rgba(255, 0, 0, 0.8); } /style>/head>body> div classheader> h1 classheader-title>Zulu/h1> div classversion>v1.0.0/div> /div> div classbutton-container> div classleft-buttons> button classtoggle-button onclicktoggleMilliseconds()>Hide MS/button> button classtoggle-button onclicktogglePresident()>Show President/button> button classtoggle-button onclicktoggleTheme()>Light Mode/button> /div> div classright-buttons> button classupdate-button onclickcheckForUpdates()>Check Updates/button> /div> /div> div classclock-container> div classoverlap-indicator> div classled-panel> div classoverlap-status idoverlap-status>EU+US OPEN IN --:--:--/div> /div> /div> div classclock-display> div classled-panel> div classdate-display idlocal-date>2024-01-01/div> div classtime-display idlocal-time>--span classcolon>:/span>--span classcolon>:/span>--span classmilliseconds>span classdot>./span>---/span>/div> div classtimezone-label idlocal-timezone-label>LOCAL/div> /div> /div> div classclock-display> div classled-panel> div classdate-display idvienna-date>2024-01-01/div> div classtime-display idvienna-time>--span classcolon>:/span>--span classcolon>:/span>--span classmilliseconds>span classdot>./span>---/span>/div> div classtimezone-label idvienna-timezone-label>EUROPE/VIENNA/div> div classstatus-display idvienna-market-status>MARKET CLOSED/div> /div> /div> div classclock-display> div classled-panel> div classdate-display idpresident-date>2024-01-01/div> div classtime-display idpresident-time>--span classcolon>:/span>--span classcolon>:/span>--span classmilliseconds>span classdot>./span>---/span>/div> div classtimezone-label idnyc-timezone-label>AMERICA/NEW_YORK/div> div classstatus-display idmarket-status>MARKET CLOSED/div> /div> /div> div classclock-display> div classled-panel> div classdate-display idla-date>2024-01-01/div> div classtime-display idla-time>--span classcolon>:/span>--span classcolon>:/span>--span classmilliseconds>span classdot>./span>---/span>/div> div classtimezone-label idla-timezone-label>AMERICA/LOS_ANGELES/div> /div> /div> div classclock-display> div classled-panel> div classdate-display idutc-date>2024-01-01/div> div classtime-display idutc-time>--span classcolon>:/span>--span classcolon>:/span>--span classmilliseconds>span classdot>./span>---/span>/div> div classtimezone-label idutc-timezone-label>ZULU/UTC/div> /div> /div> /div> script> // Load preferences from localStorage let showMilliseconds localStorage.getItem(showMilliseconds) ! false; let showPresident localStorage.getItem(showPresident) true; let isDarkMode localStorage.getItem(isDarkMode) ! false; // Performance-conscious clock rendering (Safari-friendly) // - requestAnimationFrame for ~60fps milliseconds // - Update HH:MM:SS and status once per second // - Prebuilt DOM nodes; update textContent only (no innerHTML churn) const zones { key: local, timeId: local-time, dateId: local-date, labelId: local-timezone-label, label: LOCAL, tz: Intl.DateTimeFormat().resolvedOptions().timeZone }, { key: president, timeId: president-time, dateId: president-date, labelId: nyc-timezone-label, label: AMERICA/NEW_YORK, tz: America/New_York }, { key: la, timeId: la-time, dateId: la-date, labelId: la-timezone-label, label: AMERICA/LOS_ANGELES, tz: America/Los_Angeles }, { key: vienna, timeId: vienna-time, dateId: vienna-date, labelId: vienna-timezone-label, label: EUROPE/VIENNA, tz: Europe/Vienna }, { key: utc, timeId: utc-time, dateId: utc-date, labelId: utc-timezone-label, label: ZULU/UTC, tz: UTC }, ; const timeFormatters {}; const dateFormatters {}; zones.forEach(z > { timeFormattersz.key new Intl.DateTimeFormat(en-US, { hour12: false, timeZone: z.tz, hour: 2-digit, minute: 2-digit, second: 2-digit }); dateFormattersz.key new Intl.DateTimeFormat(en-CA, { timeZone: z.tz, year: numeric, month: 2-digit, day: 2-digit }); }); // Formatter to compute UTC offset string like +01:00 for a given timeZone function getUtcOffsetString(now, timeZone) { // Get the local time in the target zone and UTC, then compute offset minutes const utcMs now.getTime(); // Represent now as if in the target zone by formatting parts and reconstructing const parts new Intl.DateTimeFormat(en-CA, { timeZone, year: numeric, month: 2-digit, day: 2-digit, hour: 2-digit, minute: 2-digit, second: 2-digit, hour12: false }).formatToParts(now); const get type > parts.find(p > p.type type)?.value; const year Number(get(year)); const month Number(get(month)); const day Number(get(day)); const hour Number(get(hour)); const minute Number(get(minute)); const second Number(get(second)); const asIfLocal new Date(Date.UTC(year, month - 1, day, hour, minute, second)); const offsetMinutes Math.round((asIfLocal.getTime() - utcMs) / 60000); const sign offsetMinutes > 0 ? + : -; const abs Math.abs(offsetMinutes); const hh String(Math.floor(abs / 60)).padStart(2, 0); const mm String(abs % 60).padStart(2, 0); return `${sign}${hh}:${mm}`; } const timeDisplays {}; // key -> { hhEl, mmEl, ssEl, msEl, msContainer, offsetEl } function buildTimeDisplay(containerEl) { const coreEl document.createElement(span); coreEl.className time-core; const hoursEl document.createElement(span); const colon1El document.createElement(span); colon1El.className colon; colon1El.textContent :; const minutesEl document.createElement(span); const colon2El document.createElement(span); colon2El.className colon; colon2El.textContent :; const secondsEl document.createElement(span); const msContainerEl document.createElement(span); msContainerEl.className milliseconds; const dotEl document.createElement(span); dotEl.className dot; dotEl.textContent .; const msEl document.createElement(span); msContainerEl.appendChild(dotEl); msContainerEl.appendChild(msEl); const offsetEl document.createElement(span); offsetEl.className time-offset; coreEl.replaceChildren(hoursEl, colon1El, minutesEl, colon2El, secondsEl, msContainerEl); containerEl.replaceChildren(coreEl, offsetEl); msContainerEl.style.display showMilliseconds ? : none; return { hhEl: hoursEl, mmEl: minutesEl, ssEl: secondsEl, msEl: msEl, msContainer: msContainerEl, offsetEl }; } function initializeClocks() { zones.forEach(z > { const el document.getElementById(z.timeId); timeDisplaysz.key buildTimeDisplay(el); }); // Initial one-shot fill to avoid blanks updateOncePerSecond(new Date()); updateMilliseconds(new Date()); } function updateMilliseconds(now) { if (!showMilliseconds) return; const msText String(now.getMilliseconds()).padStart(3, 0); for (const key in timeDisplays) { timeDisplayskey.msEl.textContent msText; } } function updateOncePerSecond(now) { // Update HH:MM:SS and dates zones.forEach(z > { const timeText timeFormattersz.key.format(now); // HH:MM:SS const hh, mm, ss timeText.split(:); const nodes timeDisplaysz.key; if (nodes.hhEl.textContent ! hh) nodes.hhEl.textContent hh; if (nodes.mmEl.textContent ! mm) nodes.mmEl.textContent mm; if (nodes.ssEl.textContent ! ss) nodes.ssEl.textContent ss; const dateEl document.getElementById(z.dateId); const dateText dateFormattersz.key.format(now); if (dateEl.textContent ! dateText) dateEl.textContent dateText; }); // Update timezone labels (no offset) and put offset next to time zones.forEach(z > { const labelContainer document.getElementById(z.labelId); if (labelContainer) { let baseLabel z.label; if (z.key president) { baseLabel showPresident ? PRESIDENT : AMERICA/NEW_YORK; } if (labelContainer.textContent ! baseLabel) labelContainer.textContent baseLabel; } const offset getUtcOffsetString(now, z.tz); const nodes timeDisplaysz.key; if (nodes && nodes.offsetEl.textContent ! offset) nodes.offsetEl.textContent offset; }); // Market status (NYSE: 9:30 AM - 4:00 PM ET, Mon-Fri) const nyNow new Date(now.toLocaleString(en-US, { timeZone: America/New_York })); const day nyNow.getDay(); const hours nyNow.getHours(); const minutes nyNow.getMinutes(); const timeInMinutes hours * 60 + minutes; const marketOpen 9 * 60 + 30; const marketClose 16 * 60; const marketStatus document.getElementById(market-status); if (marketStatus) { if (day > 1 && day 5 && timeInMinutes > marketOpen && timeInMinutes marketClose) { const marketCloseTime new Date(nyNow); marketCloseTime.setHours(16, 0, 0, 0); const diff marketCloseTime.getTime() - nyNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); marketStatus.textContent `CLOSES IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; marketStatus.className status-display status-market-open; } else { let nextOpen new Date(nyNow); if (day 0) { nextOpen.setDate(nextOpen.getDate() + 1); } else if (day 6) { nextOpen.setDate(nextOpen.getDate() + 2); } else if (day > 1 && day 5) { if (timeInMinutes > marketClose) { nextOpen.setDate(nextOpen.getDate() + (day 5 ? 3 : 1)); } } nextOpen.setHours(9, 30, 0, 0); const diff nextOpen.getTime() - nyNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); marketStatus.textContent h > 24 ? MARKET CLOSED : `OPENS IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; marketStatus.className status-display status-market-closed; } } // Vienna Stock Exchange status (VSE: 9:04 AM - 5:30 PM CET, Mon-Fri) const viennaNow new Date(now.toLocaleString(en-US, { timeZone: Europe/Vienna })); const viennaDay viennaNow.getDay(); const viennaHours viennaNow.getHours(); const viennaMinutes viennaNow.getMinutes(); const viennaTimeInMinutes viennaHours * 60 + viennaMinutes; const viennaMarketOpen 9 * 60 + 4; const viennaMarketClose 17 * 60 + 30; const viennaMarketStatus document.getElementById(vienna-market-status); if (viennaMarketStatus) { if (viennaDay > 1 && viennaDay 5 && viennaTimeInMinutes > viennaMarketOpen && viennaTimeInMinutes viennaMarketClose) { const closeTime new Date(viennaNow); closeTime.setHours(17, 30, 0, 0); const diff closeTime.getTime() - viennaNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); viennaMarketStatus.textContent `CLOSES IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; viennaMarketStatus.className status-display status-market-open; } else { let nextOpen new Date(viennaNow); if (viennaDay 0) { nextOpen.setDate(nextOpen.getDate() + 1); } else if (viennaDay 6) { nextOpen.setDate(nextOpen.getDate() + 2); } else if (viennaDay > 1 && viennaDay 5) { if (viennaTimeInMinutes > viennaMarketClose) { nextOpen.setDate(nextOpen.getDate() + (viennaDay 5 ? 3 : 1)); } } nextOpen.setHours(9, 4, 0, 0); const diff nextOpen.getTime() - viennaNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); viennaMarketStatus.textContent h > 24 ? MARKET CLOSED : `OPENS IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; viennaMarketStatus.className status-display status-market-closed; } } // EU+US Overlap Status const overlapStatus document.getElementById(overlap-status); if (overlapStatus) { const viennaOverlapStart 15 * 60 + 30; const viennaOverlapEnd 17 * 60 + 30; const isViennaMarketOpen viennaDay > 1 && viennaDay 5 && viennaTimeInMinutes > viennaMarketOpen && viennaTimeInMinutes viennaMarketClose; const isOverlapWindow viennaDay > 1 && viennaDay 5 && viennaTimeInMinutes > viennaOverlapStart && viennaTimeInMinutes viennaOverlapEnd; if (isViennaMarketOpen && isOverlapWindow) { const overlapEndTime new Date(viennaNow); overlapEndTime.setHours(17, 30, 0, 0); const diff overlapEndTime.getTime() - viennaNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); overlapStatus.textContent `EU+US OPEN - CLOSES IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; overlapStatus.className overlap-status active; } else { let nextOverlap new Date(viennaNow); if (viennaDay 0) { nextOverlap.setDate(nextOverlap.getDate() + 1); nextOverlap.setHours(15, 30, 0, 0); } else if (viennaDay 6) { nextOverlap.setDate(nextOverlap.getDate() + 2); nextOverlap.setHours(15, 30, 0, 0); } else if (viennaDay > 1 && viennaDay 5) { if (viennaTimeInMinutes > viennaOverlapEnd) { nextOverlap.setDate(nextOverlap.getDate() + (viennaDay 5 ? 3 : 1)); nextOverlap.setHours(15, 30, 0, 0); } else { nextOverlap.setHours(15, 30, 0, 0); } } const diff nextOverlap.getTime() - viennaNow.getTime(); const h Math.floor(diff / (1000 * 60 * 60)); const m Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const s Math.floor((diff % (1000 * 60)) / 1000); overlapStatus.textContent `EU+US OPEN IN ${String(h).padStart(2, 0)}:${String(m).padStart(2, 0)}:${String(s).padStart(2, 0)}`; overlapStatus.className overlap-status inactive; } } } let rafId null; let lastSecond -1; function startClockLoop() { function tick() { const now new Date(); updateMilliseconds(now); if (now.getSeconds() ! lastSecond) { lastSecond now.getSeconds(); updateOncePerSecond(now); } rafId requestAnimationFrame(tick); } if (rafId) cancelAnimationFrame(rafId); rafId requestAnimationFrame(tick); } // Toggle milliseconds visibility function toggleMilliseconds() { showMilliseconds !showMilliseconds; // Save preference to localStorage localStorage.setItem(showMilliseconds, showMilliseconds); const button document.querySelector(.toggle-button); button.textContent showMilliseconds ? Hide MS : Show MS; button.style.width 160px; // Maintain consistent width // Show/hide ms containers Object.values(timeDisplays).forEach(nodes > { nodes.msContainer.style.display showMilliseconds ? : none; }); } // Toggle president label function togglePresident() { showPresident !showPresident; // Save preference to localStorage localStorage.setItem(showPresident, showPresident); const button document.querySelectorAll(.toggle-button)1; // Second button button.textContent showPresident ? Show IANA : Show President; button.style.width 160px; // Maintain consistent width // Immediately update the timezone label (dont wait for next second update) const labelContainer document.getElementById(nyc-timezone-label); if (labelContainer) { const baseLabel showPresident ? PRESIDENT : AMERICA/NEW_YORK; labelContainer.textContent baseLabel; } } // Toggle theme (light/dark mode) function toggleTheme() { isDarkMode !isDarkMode; // Save preference to localStorage localStorage.setItem(isDarkMode, isDarkMode); const button document.querySelectorAll(.toggle-button)2; // Third button button.textContent isDarkMode ? Light Mode : Dark Mode; button.style.width 160px; // Maintain consistent width // Apply theme applyTheme(); } // Apply the current theme function applyTheme() { if (isDarkMode) { document.documentElement.removeAttribute(data-theme); } else { document.documentElement.setAttribute(data-theme, light); } } // Initialize button text on page load function initializeButtons() { const msButton document.querySelector(.toggle-button); msButton.textContent showMilliseconds ? Hide MS : Show MS; const presButton document.querySelectorAll(.toggle-button)1; presButton.textContent showPresident ? Show IANA : Show President; const themeButton document.querySelectorAll(.toggle-button)2; themeButton.textContent isDarkMode ? Light Mode : Dark Mode; // Set consistent button widths const toggleButtons document.querySelectorAll(.toggle-button); toggleButtons.forEach(button > { button.style.width 160px; }); const updateButton document.querySelector(.update-button); if (updateButton) { updateButton.style.width 160px; } } // Initialize UI and start optimized clock loop applyTheme(); // Apply theme first initializeButtons(); initializeClocks(); startClockLoop(); // iOS PWA update detection (fallback) const isIOSPWA window.navigator.standalone true; if (isIOSPWA) { console.log(iOS PWA detected); // Store current version in localStorage const currentVersion 1.0.0; const storedVersion localStorage.getItem(app-version); if (storedVersion && storedVersion ! currentVersion) { console.log(Version change detected:, storedVersion, ->, currentVersion); alert(New version detected! App has been updated.); } localStorage.setItem(app-version, currentVersion); // Check for updates every 5 minutes for iOS PWA setInterval(() > { console.log(iOS PWA periodic update check...); // Check if version has changed const newVersion 1.0.0; // This would be dynamic in a real app if (localStorage.getItem(app-version) ! newVersion) { console.log(Version update detected, reloading...); window.location.reload(); } }, 5 * 60 * 1000); } // Manual update check function function checkForUpdates() { console.log(Manual update check triggered); // Check if running as PWA const isPWA window.matchMedia((display-mode: standalone)).matches || window.navigator.standalone true; console.log(Is PWA:, isPWA); if (serviceWorker in navigator) { navigator.serviceWorker.getRegistration().then(function(registration) { if (registration && registration.active && registration.active.state ! redundant) { console.log(Service worker found, checking for updates...); registration.update().catch(error > { console.log(Failed to update service worker:, error); }); // Force reload for iOS PWA if (isPWA) { console.log(iOS PWA detected, forcing reload...); setTimeout(() > { window.location.reload(); }, 1000); } } else { console.log(No service worker registration found); // iOS PWA fallback - force reload to check for new version if (isPWA) { console.log(iOS PWA detected without service worker, forcing reload...); if (confirm(Force reload to check for updates?)) { window.location.reload(); } } } }).catch(function(error) { console.log(Service worker error:, error); // Fallback for iOS PWA if (isPWA) { console.log(iOS PWA fallback - forcing reload...); if (confirm(Force reload to check for updates?)) { window.location.reload(); } } }); } else { console.log(Service workers not supported); // For iOS PWA without service worker, just reload if (isPWA) { console.log(Reloading iOS PWA...); if (confirm(Force reload to check for updates?)) { window.location.reload(); } } } console.log(Update check complete. Check console for details.); } // Service Worker Registration with version check if (serviceWorker in navigator) { const version 1.0.0; console.log(Registering service worker with version:, version); navigator.serviceWorker.register(/sw.js?v + version) .then(function(registration) { console.log(SW registered successfully:, registration); // Check for updates immediately console.log(Checking for updates immediately...); if (registration && registration.active) { registration.update().catch(error > { console.log(Failed to update service worker immediately:, error); }); } else { console.log(Skipping immediate update - registration not ready); } // Check for updates every 30 minutes setInterval(() > { console.log(Periodic update check...); if (registration && registration.active && registration.active.state ! redundant) { registration.update().catch(error > { console.log(Failed to update service worker periodically:, error); }); } else { console.log(Skipping periodic update - registration not valid or redundant); } }, 30 * 60 * 1000); // Listen for updates registration.addEventListener(updatefound, function() { console.log(Update found!); const newWorker registration.installing; newWorker.addEventListener(statechange, function() { console.log(Worker state changed:, newWorker.state); if (newWorker.state installed && navigator.serviceWorker.controller) { // New version available console.log(New version available!); if (confirm(New version available! Reload to update?)) { window.location.reload(); } } }); }); // Listen for controller change (when SW takes control) navigator.serviceWorker.addEventListener(controllerchange, function() { console.log(Service worker controller changed!); }); }) .catch(function(error) { console.log(SW registration failed:, error); }); } else { console.log(Service workers not supported in this browser); } // Live reload functionality (only on localhost) (function() { if (window.location.protocol file:) return; // Skip if opened as file if (window.location.hostname ! localhost && window.location.hostname ! 127.0.0.1) return; // Only on localhost const ws new WebSocket(ws://localhost:3000); ws.onmessage function(event) { if (event.data reload) { window.location.reload(); } }; ws.onopen function() { console.log(Live reload connected); }; ws.onclose function() { console.log(Live reload disconnected); // Try to reconnect after 1 second setTimeout(() > { window.location.reload(); }, 1000); }; })(); /script>/body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]