// ==UserScript==
// @name XButtonx
// @namespace http://tampermonkey.net/
// @version 1.6
// @description calc umur, auto reload, hapus Ads, darkmode
// @author xkhd
// @match *://*/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
// --- Floating main button ---
const floatingBtn = document.createElement('div');
floatingBtn.style.cssText = `
position: fixed; bottom: 60px; right: 60px;
width: 60px; height: 60px; border-radius: 50%;
overflow: hidden; z-index: 9999; cursor: pointer;
border: 3px solid #007bff; background: #fff;
display: flex; align-items: center; justify-content: center;
transition: transform 0.3s ease; box-shadow: 0 4px 8px rgba(0,0,0,0.3);
`;
const iconImg = document.createElement('img');
iconImg.src = 'https://lh3.googleusercontent.com/a/AGNmyxaEnKjzfKogUt2-V-11G5OAQMl0OZKBz7562IzJ=s96-c';
iconImg.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
floatingBtn.appendChild(iconImg);
document.body.appendChild(floatingBtn);
// --- Button container (positioned relative to floating button center) ---
const btnContainer = document.createElement('div');
// offset to align with floatingBtn center (floatingBtn bottom/right are 60px)
btnContainer.style.cssText = `
position: fixed; bottom: 90px; right: 90px;
width: 0; height: 0; z-index: 9998; pointer-events: none;
`;
document.body.appendChild(btnContainer);
const menuButtons = [];
// --- Helper: create tooltip element for a button ---
function makeTooltip(text) {
const tip = document.createElement('div');
tip.textContent = text;
tip.style.cssText = `
position: absolute;
bottom: 130%;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
padding: 6px 8px;
background: rgba(0,0,0,0.85);
color: #fff;
font-size: 12px;
border-radius: 6px;
box-shadow: 0 4px 10px rgba(0,0,0,0.25);
pointer-events: none;
opacity: 0;
transition: opacity 0.18s ease, transform 0.18s ease;
transform-origin: bottom center;
z-index: 10001;
`;
return tip;
}
// --- SVG icons (inline) ---
const SVG = {
calc: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<rect x="3" y="3" width="18" height="18" rx="2" stroke="lime" stroke-width="1.6" fill="#ffffff"/>
<path d="M7 7h10M7 11h10M7 15h10" stroke="lime" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`,
reload: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M21 12a9 9 0 10-2.6 6.1L21 21v-4.1" stroke="blue" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`,
removeAds: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<circle cx="12" cy="12" r="8" stroke="red" stroke-width="1.6" fill="#ffffff"/>
<path d="M8 8l8 8M16 8l-8 8" stroke="red" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`,
dark: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" stroke="orange" stroke-width="1.4" fill="#ffffff"/>
</svg>`
};
// --- Create a menu button with SVG and tooltip text ---
function createIconButton(svgHTML, tooltipText, callback) {
const btn = document.createElement('button');
btn.innerHTML = svgHTML;
btn.setAttribute('aria-label', tooltipText);
btn.style.cssText = `
position: absolute;
width: 36px; height: 36px; /* rectangle-ish for nicer alignment */
display:flex; align-items:center; justify-content:center;
transform: translate(0px, 0px);
opacity: 0;
transition: transform 0.38s cubic-bezier(.2,.9,.2,1), opacity 0.28s ease;
pointer-events: auto;
background: transparent;
border: 2px solid #007bff;
border-radius: 8px;
padding: 6px;
font-size: 13px;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0,0,0,0.18);
`;
// tooltip
const tip = makeTooltip(tooltipText);
btn.appendChild(tip);
// mouse handlers (use dataset tx,ty that will be set later)
btn.addEventListener('mouseenter', () => {
const tx = parseFloat(btn.dataset.tx || 0);
const ty = parseFloat(btn.dataset.ty || 0);
btn.style.transform = `translate(${tx}px, ${ty}px) scale(1.08)`;
btn.style.boxShadow = '0 6px 18px rgba(0,0,0,0.28)';
tip.style.opacity = '1';
tip.style.transform = 'translateX(-50%) translateY(-6px)';
});
btn.addEventListener('mouseleave', () => {
const tx = parseFloat(btn.dataset.tx || 0);
const ty = parseFloat(btn.dataset.ty || 0);
btn.style.transform = `translate(${tx}px, ${ty}px) scale(1)`;
btn.style.boxShadow = '0 2px 6px rgba(0,0,0,0.18)';
tip.style.opacity = '0';
tip.style.transform = 'translateX(-50%) translateY(0)';
});
btn.addEventListener('click', (e) => {
e.stopPropagation(); // avoid closing menu if needed
callback && callback(e);
});
btnContainer.appendChild(btn);
menuButtons.push(btn);
return btn;
}
// --- Kalkulator Umur (statis) ---
function showAgeCalculator() {
const container = document.createElement('div');
container.style.cssText = `
all: initial;
font-family: Arial, sans-serif;
font-size: 14px;
position: fixed; top: 50%; left: 50%;
transform: translate(-50%, -50%);
background: #ffffff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 8px 30px rgba(0,0,0,0.25);
z-index: 10000; min-width: 300px;
color: #000000;
`;
container.innerHTML = `
<h3 style="margin:0 0 10px 0; font-size:16px; font-weight:700; color:#222;">Kalkulator Umur</h3>
<label style="display:block; margin-bottom:6px; color:#333;">Tanggal Lahir:</label>
<input type="date" id="birthDate" style="padding:8px; width:100%; margin-bottom:12px; border:1px solid #ddd; border-radius:6px;">
<label style="display:block; margin-bottom:6px; color:#333;">Tanggal Acuan:</label>
<input type="date" id="refDate" value="${new Date().toISOString().split('T')[0]}" style="padding:8px; width:100%; margin-bottom:12px; border:1px solid #ddd; border-radius:6px;">
<div style="display:flex; gap:10px; justify-content:space-between; margin-top:8px;">
<button id="calcBtn" style="flex:1; background:#007bff; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Hitung</button>
<button id="closeBtn" style="flex:1; background:#6c757d; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Tutup</button>
</div>
<div id="result" style="margin-top:14px; font-weight:700; color:#222;"></div>
`;
document.body.appendChild(container);
container.querySelector('#closeBtn').onclick = () => container.remove();
container.querySelector('#calcBtn').onclick = () => {
const birthVal = container.querySelector('#birthDate').value;
const refVal = container.querySelector('#refDate').value;
const birth = birthVal ? new Date(birthVal) : NaN;
const ref = refVal ? new Date(refVal) : NaN;
if (isNaN(birth) || isNaN(ref)) {
alert("Mohon masukkan kedua tanggal.");
return;
}
if (ref < birth) {
alert("Tanggal acuan tidak boleh sebelum tanggal lahir.");
return;
}
const age = calcAge(birth, ref);
container.querySelector('#result').textContent =
`${age.years} tahun, ${age.months} bulan, ${age.days} hari`;
};
}
function calcAge(birth, ref) {
let years = ref.getFullYear() - birth.getFullYear();
let months = ref.getMonth() - birth.getMonth();
let days = ref.getDate() - birth.getDate();
if (days < 0) {
months--;
const prevMonth = new Date(ref.getFullYear(), ref.getMonth(), 0);
days += prevMonth.getDate();
}
if (months < 0) {
years--;
months += 12;
}
return { years, months, days };
}
// --- Placeholder Auto Reload ---
function showAutoReloadPopup() {
// Example implementation: simple popup with interval in minutes (you can extend)
const container = document.createElement('div');
container.style.cssText = `
all: initial;
font-family: Arial, sans-serif;
font-size: 14px;
position: fixed; top: 50%; left: 50%;
transform: translate(-50%, -50%);
background: #fff;
padding: 16px;
border-radius: 10px;
box-shadow: 0 8px 30px rgba(0,0,0,0.25);
z-index: 10000; min-width: 280px;
color: #000;
`;
container.innerHTML = `
<h3 style="margin:0 0 10px 0; font-size:16px; color:#222;">Auto Reload</h3>
<label style="display:block; margin-bottom:6px;">Interval (menit)</label>
<input id="reloadMin" type="number" min="1" placeholder="Menit" style="width:100%; padding:8px; border:1px solid #ddd; border-radius:6px;">
<div style="display:flex; gap:8px; margin-top:10px;">
<button id="startReload" style="flex:1; background:#007bff; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Mulai</button>
<button id="stopReload" style="flex:1; background:#6c757d; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Berhenti</button>
</div>
<div style="display:flex; justify-content:flex-end; margin-top:10px;">
<button id="closeReload" style="background:transparent; border:none; color:#007bff; cursor:pointer;">Tutup</button>
</div>
`;
document.body.appendChild(container);
let intervalRef = null;
container.querySelector('#startReload').onclick = () => {
const m = parseInt(container.querySelector('#reloadMin').value, 10);
if (isNaN(m) || m <= 0) {
alert('Masukkan interval (menit) yang valid.');
return;
}
if (intervalRef) clearInterval(intervalRef);
intervalRef = setInterval(() => location.reload(), m * 60 * 1000);
alert(`Auto reload setiap ${m} menit diaktifkan.`);
};
container.querySelector('#stopReload').onclick = () => {
if (intervalRef) {
clearInterval(intervalRef);
intervalRef = null;
alert('Auto reload dihentikan.');
} else alert('Auto reload belum aktif.');
};
container.querySelector('#closeReload').onclick = () => container.remove();
}
// --- Remove Ads ---
function removeAds() {
const selectors = [
'[id^="ad"]','[class*="ad"]','[id*="banner"]','[class*="banner"]',
'[class*="promo"]','[class*="sponsored"]','[class*="ads"]',
'[id*="popup"]','[class*="popup"]','[class*="overlay"]'
];
selectors.forEach(sel => document.querySelectorAll(sel).forEach(el => el.style.display = 'none'));
alert('Berhasil menyembunyikan elemen yang berlabel iklan (metode heuristik).');
}
// --- Dark Mode toggle (kept global) ---
const darkStyle = document.createElement('style');
darkStyle.textContent = `
body.dark-mode, body.dark-mode * {
background-color: #111 !important;
color: #ddd !important;
border-color: #333 !important;
}
`;
document.head.appendChild(darkStyle);
if (localStorage.getItem('darkModeEnabled') === 'true') {
document.body.classList.add('dark-mode');
}
function toggleDarkMode() {
document.body.classList.toggle('dark-mode');
localStorage.setItem('darkModeEnabled', document.body.classList.contains('dark-mode'));
}
// --- Add icon buttons (SVG icons + tooltip text + callbacks) ---
createIconButton(SVG.calc, 'Kalkulator Umur', showAgeCalculator);
createIconButton(SVG.reload, 'Auto Reload', showAutoReloadPopup);
createIconButton(SVG.removeAds, 'Hapus Iklan', removeAds);
createIconButton(SVG.dark, 'Dark Mode', toggleDarkMode);
// --- Quarter-circle animation logic ---
let menuOpen = false;
floatingBtn.addEventListener('click', () => {
menuOpen = !menuOpen;
const total = menuButtons.length;
const radius = 120; // jarak tombol dari pusat
const startAngle = -90; // degrees (top)
const endAngle = -180; // degrees (left)
const step = (endAngle - startAngle) / Math.max(1, (total - 1));
menuButtons.forEach((btn, i) => {
if (menuOpen) {
const angleDeg = startAngle + step * i;
const angle = angleDeg * (Math.PI / 180);
const x = Math.cos(angle) * radius;
const y = Math.sin(angle) * radius;
// store translation so hover can reapply scale without losing coords
btn.dataset.tx = x.toFixed(2);
btn.dataset.ty = y.toFixed(2);
// small staggered delay for nicer effect
btn.style.transitionDelay = `${i * 0.03}s`;
// move and show
btn.style.transform = `translate(${x}px, ${y}px) scale(1)`;
btn.style.opacity = '1';
} else {
btn.style.transitionDelay = `${(menuButtons.length - 1 - i) * 0.02}s`;
btn.dataset.tx = 0;
btn.dataset.ty = 0;
btn.style.transform = `translate(0px, 0px) scale(1)`;
btn.style.opacity = '0';
}
});
floatingBtn.style.transform = menuOpen ? 'rotate(45deg)' : 'rotate(0deg)';
});
// --- Close menu when clicking outside ---
document.addEventListener('click', (e) => {
if (!menuOpen) return;
if (floatingBtn.contains(e.target)) return;
// if clicked a menu button, keep menu open (optional). We'll close for simplicity.
menuOpen = false;
menuButtons.forEach((btn, i) => {
btn.style.transitionDelay = `${(menuButtons.length - 1 - i) * 0.02}s`;
btn.dataset.tx = 0;
btn.dataset.ty = 0;
btn.style.transform = `translate(0px, 0px) scale(1)`;
btn.style.opacity = '0';
});
floatingBtn.style.transform = 'rotate(0deg)';
});
// --- Prevent accidental selection when double-clicking ---
floatingBtn.addEventListener('mousedown', (e) => e.preventDefault());
})();