/* Any JavaScript here will be loaded for all users on every page load. */
// stolen from Lajos Mészáros on this post https://stackoverflow.com/questions/13358292/capture-tap-event-with-pure-javascript
const onClickOrTap = (element, handler) => {
let touchMoveHappened = false;
element.addEventListener('touchstart', () => {
// on mobile this is the 1st event that happens
touchMoveHappened = false;
});
element.addEventListener('touchmove', () => {
// on mobile this might get triggered in which case the
// click or tap will get cancelled
// we'll keep a track of it
touchMoveHappened = true;
});
element.addEventListener('touchend', (e) => {
// happens after touchstart, but before click
// if touch happened then we'll exit
if (touchMoveHappened) {
return;
}
// calling preventDefault() will make sure the
// subsequent click will not get triggered
e.preventDefault();
// at this point we are ready to call our original handler
handler(e);
});
element.addEventListener('click', (e) => {
// this will only get triggered on desktopg
// because we call preventDefault for the "touchend" event
handler(e);
});
}
/* Create Page */
const createPageTargetIdDataSetString = "[data-create-page-target-id]";
if (document.querySelector(createPageTargetIdDataSetString)) {
/**
* @type {HTMLElement[]}
*/
let itemsCreateInputPageGrid = [];
let itemsCreatePageGrid = [];
const createPageTargetId = "createPageTargetId";
const createPageInputHiddenClass = "hidden";
const createPageInputActiveClass = "pageInputActive";
/**
* @param {HTMLElement} element
*/
function getGridTarget(element) {
const targetId = element.dataset[createPageTargetId];
return document.getElementById(targetId);
}
/**
* @this {HTMLDivElement}
*/
function toggleGridTarget(element, targetElement) {
for (let index = 0; index < itemsCreateInputPageGrid.length; index += 1) {
const target = itemsCreateInputPageGrid[index];
target.classList.add(createPageInputHiddenClass);
if (target === targetElement) {
target.classList.remove(createPageInputHiddenClass);
}
const clickedElement = itemsCreatePageGrid[index];
clickedElement.classList.remove(createPageInputActiveClass);
if (clickedElement === element) {
clickedElement.classList.add(createPageInputActiveClass);
}
}
}
/**
* @param {HTMLElement} element
* @param {HTMLElement} targetElement
*/
function addToggleGridTargetEvent(element, targetElement) {
itemsCreatePageGrid.push(element);
itemsCreateInputPageGrid.push(targetElement);
onClickOrTap(element, (e) => {
toggleGridTarget(element, targetElement)
});
//element.addEventListener("click", () =>
// toggleGridTarget(element, targetElement)
//);
}
const createPageTargetElements = document.querySelectorAll(
createPageTargetIdDataSetString
);
for (let index = 0; index < createPageTargetElements.length; index += 1) {
const element = createPageTargetElements[index];
const targetElement = getGridTarget(element);
if (targetElement) {
addToggleGridTargetEvent(element, targetElement);
}
}
}
/* Jakes Recent Changes Portlet */
(function () {
function jakeTimeAgo(date) {
var s = Math.floor((Date.now() - date.getTime()) / 1000);
if (s < 60) return s + "s ago";
var m = Math.floor(s / 60);
if (m < 60) return m + "m ago";
var h = Math.floor(m / 60);
if (h < 24) return h + "h ago";
var d = Math.floor(h / 24);
return d + "d ago";
}
function jakeInjectStyles() {
if (document.getElementById("jake-rc-style")) return;
var style = document.createElement("style");
style.id = "jake-rc-style";
style.textContent =
"#p-jake-recentchanges .vector-menu-heading{display:flex;align-items:center;justify-content:space-between;}" +
"#p-jake-recentchanges .jake-rc-dot{width:8px;height:8px;border-radius:50%;background:#2da44e;box-shadow:0 0 0 2px rgba(45,164,78,.18);flex:0 0 auto;}" +
"#p-jake-recentchanges .vector-menu-heading{font-size:.95em;}" +
"#p-jake-recentchanges .vector-menu-content{font-size:.92em;}" +
"#p-jake-recentchanges .jake-rc-meta{font-size:.85em;opacity:.85;}";
document.head.appendChild(style);
}
function jakeBuildPortlet() {
var menu =
document.getElementById("vector-main-menu") ||
document.getElementById("mw-panel");
if (!menu) return null;
if (document.getElementById("p-jake-recentchanges")) return null;
jakeInjectStyles();
var portlet = document.createElement("div");
portlet.id = "p-jake-recentchanges";
portlet.className = "vector-menu mw-portlet";
var heading = document.createElement("div");
heading.className = "vector-menu-heading";
var headingText = document.createElement("span");
headingText.textContent = "Recent changes";
var dot = document.createElement("span");
dot.className = "jake-rc-dot";
dot.setAttribute("aria-hidden", "true");
dot.title = "Live";
heading.appendChild(headingText);
heading.appendChild(dot);
var content = document.createElement("div");
content.className = "vector-menu-content";
var ul = document.createElement("ul");
ul.className = "vector-menu-content-list";
ul.id = "jake-rc-list";
var moreWrap = document.createElement("div");
moreWrap.className = "jake-rc-more";
var moreLink = document.createElement("a");
moreLink.href = mw.util.getUrl("Special:RecentChanges");
moreLink.textContent = "Show more…";
moreWrap.appendChild(moreLink);
content.appendChild(ul);
content.appendChild(moreWrap);
portlet.appendChild(heading);
portlet.appendChild(content);
var discordPortlet = menu.querySelector("#p-Community");
if (discordPortlet && discordPortlet.parentNode) {
discordPortlet.parentNode.insertBefore(portlet, discordPortlet.nextSibling);
} else {
var navPortlet = menu.querySelector("#p-navigation");
if (navPortlet && navPortlet.parentNode) {
navPortlet.parentNode.insertBefore(portlet, navPortlet.nextSibling);
} else {
menu.appendChild(portlet);
}
}
return ul;
}
function jakeLoadRecentChanges(ul) {
if (!ul) return;
var api = new mw.Api();
api
.get({
action: "query",
list: "recentchanges",
rcnamespace: "0", /* 4 */
rclimit: 5,
rcprop: "title|timestamp|user",
rcshow: "!bot",
formatversion: 2
})
.then(function (data) {
var items =
data && data.query && data.query.recentchanges
? data.query.recentchanges
: [];
ul.textContent = "";
for (var i = 0; i < items.length; i++) {
var rc = items[i];
var li = document.createElement("li");
li.className = "mw-list-item jake-rc-item";
var a = document.createElement("a");
a.href = mw.util.getUrl(rc.title);
a.textContent = rc.title;
var meta = document.createElement("div");
meta.className = "jake-rc-meta";
meta.textContent = jakeTimeAgo(new Date(rc.timestamp)) + " · " + (rc.user || "");
li.appendChild(a);
li.appendChild(meta);
ul.appendChild(li);
}
})
.catch(function () {
ul.textContent = "";
var li = document.createElement("li");
li.className = "mw-list-item jake-rc-item";
var a = document.createElement("a");
a.href = mw.util.getUrl("Special:RecentChanges");
a.textContent = "View recent changes";
li.appendChild(a);
ul.appendChild(li);
});
}
function jakeInitRecentChanges() {
if (!window.mw || !mw.util || !mw.Api) return;
var ul = jakeBuildPortlet();
if (!ul) ul = document.getElementById("jake-rc-list");
if (!ul) return;
jakeLoadRecentChanges(ul);
setInterval(function () {
jakeLoadRecentChanges(ul);
}, 60000);
}
function jakeWaitForMenu() {
var tries = 0;
var timer = setInterval(function () {
var menu =
document.getElementById("vector-main-menu") ||
document.getElementById("mw-panel");
if (menu) {
clearInterval(timer);
jakeInitRecentChanges();
return;
}
tries++;
if (tries > 50) clearInterval(timer);
}, 200);
}
jakeWaitForMenu();
})();
/* */
/*
(function () {
function jakeAddFeedbackToNamespaces() {
var list = document.querySelector("#p-associated-pages .vector-menu-content-list");
if (!list) return;
var existing = document.getElementById("jake-feedback-btn");
if (existing && !existing.closest("#p-associated-pages")) {
var oldLi = existing.closest("li");
if (oldLi) oldLi.remove();
else existing.remove();
}
if (document.getElementById("ca-jake-feedback")) return;
var li = document.createElement("li");
li.id = "ca-jake-feedback";
li.className = "vector-tab-noicon mw-list-item";
var a = document.createElement("a");
a.id = "jake-feedback-btn";
a.className = "jake-feedback-btn";
a.href = mw.util.getUrl("Consumer_Rights_Wiki:Feedback", {
from: mw.config.get("wgPageName")
});
a.title = "Give feedback";
var span = document.createElement("span");
span.textContent = "Give feedback";
a.appendChild(span);
li.appendChild(a);
list.appendChild(li);
}
function jakeInit() {
if (!window.mw || !mw.util || !mw.config) return;
jakeAddFeedbackToNamespaces();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", jakeInit);
} else {
jakeInit();
}
})();
*/
/* */
(function () {
function jakeAddFooterSocialRow() {
var footer = document.getElementById("footer");
if (!footer) return;
var places = document.getElementById("footer-places");
if (!places) return;
if (document.getElementById("footer-social")) return;
var ul = document.createElement("ul");
ul.id = "footer-social";
ul.className = "noprint crw-footer-social";
function add(href, label) {
var li = document.createElement("li");
var a = document.createElement("a");
a.href = href;
a.textContent = label;
a.setAttribute("aria-label", label);
a.title = label;
li.appendChild(a);
ul.appendChild(li);
}
// add("https://discord.gg/8w5rSNAXRf", "Discord");
add("https://www.linkedin.com/company/consumer-rights-wiki/", "LinkedIn");
add("https://www.reddit.com/user/ConsumerRightsWiki/", "Reddit");
places.parentNode.insertBefore(ul, places.nextSibling);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", jakeAddFooterSocialRow);
} else {
jakeAddFooterSocialRow();
}
})();
/* AF 01/03/26 */
mw.loader.using('mediawiki.util', function() {
const now = new Date();
const isAprilFools = now.getMonth() === 3 && now.getDate() === 1;
if (!isAprilFools) return;
if (!mw.config.get('wgIsMainPage')) return;
const btn = document.createElement('button');
btn.textContent = 'Try the new experience →';
btn.id = 'enshittify-btn';
btn.onclick = enshittify;
document.querySelector('.mw-body').prepend(btn);
let popupQueue = [];
let queueRunning = false;
function queuePopup(fn, delay) {
popupQueue.push({ fn, delay });
if (!queueRunning) runQueue();
}
function runQueue() {
if (!popupQueue.length) { queueRunning = false; return; }
queueRunning = true;
const { fn, delay } = popupQueue.shift();
setTimeout(() => { fn(); runQueue(); }, delay);
}
function enshittify() {
btn.disabled = true;
btn.textContent = 'Loading new experience...';
showCookieBanner();
injectBreakingNewsTicker();
degradePrivacyPolicy();
degradeCursor();
addFakeProgressBar();
addViewerCounter();
addTabHijack();
addBeforeUnloadNag();
queuePopup(showNewsletterPopup, 400);
queuePopup(injectAds, 300);
queuePopup(addNotificationPrompt, 600);
queuePopup(addAutoplayVideo, 400);
queuePopup(addSubscriptionNag, 700);
queuePopup(addSurveyPopup, 500);
queuePopup(addFakeSecurityAlert, 600);
queuePopup(addFloatingCountdown, 300);
queuePopup(addLiveChatBubble, 400);
queuePopup(addScrollBlocker, 200);
queuePopup(addConfetti, 100);
}
function showCookieBanner() {
const el = document.createElement('div');
el.id = 'cookie-banner';
el.innerHTML = `
<div id="cookie-inner">
<div id="cookie-text">
<strong>We value your privacy</strong><br/>
<span style="font-size:12px;color:#aaa">We and our <span id="partner-count">847</span> partners store and/or access information on your device and process personal data to personalise content and ads, provide social media features and analyse our traffic. Click Accept to consent or <span id="reject-link" style="font-size:10px;color:#555;cursor:pointer;text-decoration:underline">manage your preferences</span>.</span>
</div>
<div id="cookie-btns">
<button id="cookie-accept" onclick="acceptAllCookies()">✓ Accept All</button>
</div>
</div>`;
document.body.appendChild(el);
let count = 847;
const iv = setInterval(() => {
count += Math.floor(Math.random() * 3);
const el = document.getElementById('partner-count');
if (el) el.textContent = count; else clearInterval(iv);
}, 800);
document.getElementById('reject-link').onclick = showPreferenceCentre;
}
window.acceptAllCookies = function() {
const banner = document.getElementById('cookie-banner');
if (banner) {
banner.innerHTML = `<div style="padding:10px 24px;font-size:13px;color:#aaa">✅ Preferences saved. You have consented to <strong style="color:white">all processing activities</strong> across <strong style="color:white">1,204 partners</strong>. <span style="font-size:10px">This cannot be undone for 13 months.</span></div>`;
setTimeout(() => banner.remove(), 4000);
}
setTimeout(showSecondCookieBanner, 30000);
};
function showPreferenceCentre() {
document.getElementById('cookie-banner').remove();
const steps = [
{ title: 'Strictly Necessary', desc: 'These cookies are required for the website to function.', locked: true },
{ title: 'Performance & Analytics', desc: 'Help us understand how visitors interact with our website.' },
{ title: 'Functional Cookies', desc: 'Enable enhanced functionality and personalisation.' },
{ title: 'Targeting & Advertising', desc: 'Used to deliver relevant advertisements to you.' },
{ title: 'Social Media Cookies', desc: 'Enable sharing content on social media platforms.' },
{ title: 'Measurement Cookies', desc: 'Used to measure the effectiveness of advertising campaigns.' },
{ title: 'Content Personalisation', desc: 'Allow us to tailor content specifically to your interests.' },
{ title: 'Data Enrichment', desc: 'Allow partners to enrich your profile with additional data.' },
{ title: 'Cross-Device Tracking', desc: 'Connect your activity across multiple devices.' },
{ title: 'Partner Data Sharing', desc: 'Share your data with our trusted partner network.' },
{ title: 'Legitimate Interests', desc: 'Processing based on our legitimate business interests.' },
{ title: 'Special Category Data', desc: 'Processing of sensitive personal information.' },
];
let step = 0;
const el = document.createElement('div');
el.id = 'pref-centre';
function renderStep() {
const s = steps[step];
el.innerHTML = `
<div class="modal-box" style="max-width:460px">
<div style="font-size:11px;color:#999;margin-bottom:12px">Step ${step + 1} of ${steps.length} — Cookie Preference Centre</div>
<div style="background:#f5f5f5;border-radius:6px;height:4px;margin-bottom:16px;overflow:hidden">
<div style="background:#4d96ff;height:100%;width:${((step+1)/steps.length)*100}%;transition:width 0.3s"></div>
</div>
<h3 style="margin:0 0 8px">${s.title}</h3>
<p style="font-size:13px;color:#666;margin-bottom:16px">${s.desc}</p>
${s.locked
? `<div style="display:flex;align-items:center;gap:8px;margin-bottom:16px"><span style="background:#4d96ff;color:white;font-size:11px;padding:3px 8px;border-radius:99px">Always Active</span><small style="color:#999">This cannot be disabled</small></div>`
: `<div style="display:flex;gap:12px;margin-bottom:16px">
<label style="display:flex;align-items:center;gap:6px;cursor:pointer"><input type="radio" name="pref_${step}" value="yes" checked> Accept</label>
<label style="display:flex;align-items:center;gap:6px;cursor:pointer"><input type="radio" name="pref_${step}" value="no"> Reject</label>
</div>`
}
<button onclick="nextPrefStep()" style="background:#4d96ff;color:white;border:none;padding:10px 24px;border-radius:6px;cursor:pointer;font-weight:bold">
${step < steps.length - 1 ? 'Next →' : 'Save Preferences'}
</button>
${step > 0 ? `<button onclick="prevPrefStep()" style="background:none;border:none;color:#999;cursor:pointer;margin-left:8px">← Back</button>` : ''}
</div>`;
}
window.nextPrefStep = function() {
step++;
if (step >= steps.length) {
el.remove();
const notice = document.createElement('div');
notice.id = 'cookie-banner';
notice.innerHTML = `<div style="padding:12px 24px;font-size:13px;color:#aaa">
ℹ️ Your preferences have been saved. Note: <strong style="color:white">11 of 12 categories</strong> are required under our Legitimate Interests basis and cannot be disabled by users in your region. <span id="pref-close" style="cursor:pointer;float:right;color:#666">✕</span>
</div>`;
document.body.appendChild(notice);
document.getElementById('pref-close').onclick = () => notice.remove();
} else {
renderStep();
}
};
window.prevPrefStep = function() { step--; renderStep(); };
document.body.appendChild(el);
renderStep();
}
function showSecondCookieBanner() {
const el = document.createElement('div');
el.id = 'cookie-banner';
el.innerHTML = `
<div id="cookie-inner">
<div id="cookie-text">
<strong>Consent refresh required</strong><br/>
<span style="font-size:12px;color:#aaa">Our consent records show your previous consent may have expired. Please reconfirm your preferences to continue.</span>
</div>
<div id="cookie-btns">
<button id="cookie-accept" onclick="acceptAllCookies()">✓ Reconfirm Consent</button>
</div>
</div>`;
document.body.appendChild(el);
}
function showNewsletterPopup() {
const el = document.createElement('div');
el.id = 'newsletter-modal';
el.innerHTML = `
<div class="modal-box">
<div class="modal-close" id="newsletter-close" style="position:absolute;top:12px;right:16px;cursor:pointer;font-size:18px;color:#999;transition:all 0.1s">✕</div>
<div class="modal-badge">YOU QUALIFY</div>
<h2>🎁 Claim your free access</h2>
<p>Enter your email to unlock full wiki access. No credit card required.*</p>
<input type="email" id="nl-email" placeholder="your@email.com" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0;font-size:14px" />
<button onclick="submitNewsletter()">Unlock Free Access →</button>
<p class="fine-print">*Free access includes all articles with ads. Premium access from $9.99/mo. By submitting you agree to receive marketing communications from us and 214 partners.</p>
</div>`;
document.body.appendChild(el);
const closeBtn = document.getElementById('newsletter-close');
closeBtn.addEventListener('mouseover', () => {
const box = el.querySelector('.modal-box');
const maxX = Math.max(20, box.offsetWidth - 60);
const maxY = Math.max(20, box.offsetHeight - 60);
closeBtn.style.top = (10 + Math.random() * maxY) + 'px';
closeBtn.style.right = 'auto';
closeBtn.style.left = (10 + Math.random() * maxX) + 'px';
});
setTimeout(() => {
closeBtn.style.cssText = 'position:absolute;top:12px;right:16px;cursor:pointer;font-size:18px;color:#999';
closeBtn.onclick = () => { el.remove(); setTimeout(showWaitDontGo, 500); };
}, 8000);
}
window.submitNewsletter = function() {
const email = document.getElementById('nl-email').value;
if (!email) { alert('Please enter a valid email address.'); return; }
document.getElementById('newsletter-modal').innerHTML = `
<div class="modal-box">
<h2>✅ Almost there!</h2>
<p>We've sent a confirmation email to <strong>${email}</strong>.</p>
<p style="margin-top:8px;font-size:12px;color:#999">Didn't receive it? Check your spam folder. Email may take up to 48 hours.</p>
<button onclick="document.getElementById('newsletter-modal').remove()">OK</button>
<p class="fine-print">You are now subscribed to our newsletter, partner newsletters, and 47 automated drip campaigns.</p>
</div>`;
};
function showWaitDontGo() {
const el = document.createElement('div');
el.id = 'exit-modal';
el.innerHTML = `
<div class="modal-box">
<h2>⏳ Wait — special offer just for you</h2>
<p>Since you didn't sign up, we're offering you <strong>30 days free</strong> of Premium access.</p>
<p style="margin-top:8px;font-size:13px;color:#666">No commitment. Cancel anytime.*</p>
<button onclick="claimSpecialOffer()">Claim 30 Days Free →</button>
<br/><small onclick="document.getElementById('exit-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:12px">
No thanks, I prefer the limited experience
</small>
<p class="fine-print">*Free trial requires credit card. Cancellation must be completed at least 24 hours before renewal via written notice sent by post.</p>
</div>`;
document.body.appendChild(el);
}
window.claimSpecialOffer = function() {
document.getElementById('exit-modal').innerHTML = `
<div class="modal-box">
<h2>🎉 Great choice!</h2>
<p>To activate your free trial, please create an account first.</p>
<input type="text" placeholder="Full name" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
<input type="email" placeholder="Email address" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
<input type="password" placeholder="Password (min. 16 chars, 2 symbols, 1 emoji)" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
<input type="text" placeholder="Date of birth (DD/MM/YYYY)" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
<button onclick="alert('Account created! Please check your email to verify before adding payment details to activate your free trial.')">Create Account →</button>
<br/><small onclick="document.getElementById('exit-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Cancel</small>
</div>`;
};
function injectAds() {
const imageAds = [
{
eyebrow: 'Limited Time',
headline: 'The Internet You Deserve',
subline: 'Starting from £4.99/mo',
brand: 'TurboNet Broadband',
desc: 'Ultrafast fibre. No contracts. Cancel anytime.*',
cta: 'Get Started',
},
{
eyebrow: 'New Launch',
headline: 'Invest Smarter Today',
subline: 'AI-powered portfolio management',
brand: 'WealthStream Pro',
desc: 'Your money, working harder. Capital at risk.',
cta: 'Learn More',
},
{
eyebrow: 'Flash Sale',
headline: 'Up to 70% Off',
subline: 'Premium software, student prices',
brand: 'SoftBundle',
desc: '4.8★ rated · 2.4 million downloads · Today only',
cta: 'Claim Deal',
},
{
eyebrow: 'Partner Content',
headline: 'Your Data. Their Profit.',
subline: 'Take back control with VaultVPN',
brand: 'VaultVPN',
desc: 'Military-grade encryption. Zero logs. $2.49/mo.',
cta: 'Try Free',
},
{
eyebrow: 'Sponsored',
headline: 'Read More. Pay Less.',
subline: 'All the news, none of the paywalls',
brand: 'PressPass',
desc: '800+ publications in one subscription.',
cta: 'Start Trial',
},
];
const videoAds = [
{
title: 'Why 3 Million People Switched to ClearBank',
channel: 'ClearBank',
channelInitial: 'C',
views: '3.2M views · Promoted',
duration: '0:32',
},
{
title: 'This $12 Trick Cuts Your Energy Bill in Half',
channel: 'EcoHome Tips',
channelInitial: 'E',
views: '847K views · Sponsored',
duration: '1:14',
},
{
title: 'Doctors Hate This One Simple Supplement',
channel: 'VitaCore Health',
channelInitial: 'V',
views: '12M views · Ad',
duration: '2:01',
},
{
title: 'The Investment Strategy Banks Don\'t Want You to Know',
channel: 'WealthWatch',
channelInitial: 'W',
views: '5.4M views · Promoted',
duration: '4:47',
},
];
const paras = document.querySelectorAll('.mw-body p');
paras.forEach((p, i) => {
if (i % 2 !== 0) return;
const ad = document.createElement('div');
ad.className = 'fake-ad';
if (i % 4 === 0) {
const data = imageAds[(i / 4) % imageAds.length];
ad.innerHTML = `
<div class="fake-ad-image">
<div class="fake-ad-image-text">
<span class="ad-eyebrow">${data.eyebrow}</span>
<span class="ad-headline">${data.headline}</span>
<span class="ad-subline">${data.subline}</span>
</div>
</div>
<div class="fake-ad-body">
<div class="fake-ad-body-text">
<span class="fake-ad-brand">${data.brand}</span>
<span class="fake-ad-desc">${data.desc}</span>
</div>
<button class="fake-ad-cta" onclick="closeAd(this,${i})">${data.cta} →</button>
</div>`;
} else {
const data = videoAds[((i - 2) / 4) % videoAds.length];
ad.innerHTML = `
<div class="fake-ad-video">
<div class="fake-ad-video-badge">AD</div>
<div class="fake-ad-play" onclick="closeAd(this,${i})"></div>
<div class="fake-ad-video-overlay">
<span class="fake-ad-video-title">${data.title}</span>
<span class="fake-ad-video-duration">${data.duration}</span>
</div>
</div>
<div class="fake-ad-video-body">
<div class="fake-ad-channel-icon">${data.channelInitial}</div>
<div class="fake-ad-video-meta">
<span class="fake-ad-video-channel">${data.channel}</span>
<span class="fake-ad-video-views">${data.views}</span>
</div>
<button class="fake-ad-cta" onclick="closeAd(this,${i})">Watch →</button>
</div>`;
}
p.after(ad);
});
}
window.closeAd = function(btn, i) {
const ad = btn.closest('.fake-ad');
ad.style.transition = 'opacity 0.2s';
ad.innerHTML = `<div style="padding:12px 14px;font-size:12px;color:#9ca3af;font-family:Inter,sans-serif">Ad closed. Another will appear shortly.</div>`;
setTimeout(() => {
if (!ad.parentNode) return;
const returnMsgs = ['We noticed you closed our last ad. Here\'s one we think you\'ll prefer.', 'Thanks for your feedback. Here\'s a more relevant ad for you.', 'Ad refreshed based on your preferences.'];
ad.innerHTML = `<div style="padding:12px 14px;font-size:12px;color:#6b7280;font-family:Inter,sans-serif;border-top:3px solid #3b82f6">
<div style="font-size:10px;color:#9ca3af;margin-bottom:4px">${returnMsgs[i % returnMsgs.length]}</div>
<strong style="color:#374151;font-size:13px">Upgrade to Premium to remove ads</strong> — from $9.99/mo
<button onclick="choosePremium()" style="display:inline-block;margin-left:10px;background:#3b82f6;color:white;border:none;padding:5px 12px;border-radius:4px;font-size:12px;cursor:pointer;font-family:Inter,sans-serif">Subscribe</button>
</div>`;
}, 30000);
};
function degradePrivacyPolicy() {
const el = document.createElement('div');
el.id = 'privacy-notice';
el.innerHTML = `
<span style="float:right;cursor:pointer;padding:0 12px" id="privacy-close-btn">✕</span>
<marquee scrollamount="3" id="privacy-marquee">
⚠️ PRIVACY UPDATE: By reading this wiki you grant us a perpetual, irrevocable, royalty-free worldwide licence to your data.
Your device fingerprint has been recorded and shared with 214 partners.
We have updated our terms 47 times this week. Continued use constitutes acceptance.
Your right to erasure is subject to our retention policy (minimum 7 years).
</marquee>`;
document.body.prepend(el);
document.getElementById('privacy-close-btn').onclick = () => {
el.style.height = '0';
el.style.overflow = 'hidden';
el.style.transition = 'height 0.3s';
setTimeout(() => {
el.style.cssText = '';
const m = el.querySelector('marquee');
if (m) m.textContent = '📋 IMPORTANT: A new privacy policy update requires your attention. ' + m.textContent;
}, 15000);
};
}
function addSubscriptionNag() {
const el = document.createElement('div');
el.id = 'sub-nag';
el.innerHTML = `
<div class="modal-box">
<div style="font-size:11px;color:#999;margin-bottom:4px">You've read 1 article this month</div>
<h2>Get unlimited access</h2>
<p style="color:#666;font-size:14px">Join millions of readers who enjoy unrestricted access to knowledge.</p>
<div class="pricing-grid" style="margin:20px 0">
<div class="price-card">
<h3 style="font-size:14px">Basic</h3>
<div style="font-size:24px;font-weight:bold;margin:8px 0">Free</div>
<small style="color:#999;display:block;margin-bottom:12px">With limitations</small>
<button onclick="chooseFree()" style="width:100%;background:#f5f5f5;color:#333;border:1px solid #ddd;padding:8px;border-radius:6px;cursor:pointer">Continue free</button>
</div>
<div class="price-card featured" style="transform:scale(1.05)">
<div class="best-value">MOST POPULAR</div>
<h3 style="font-size:14px">Premium</h3>
<div style="font-size:24px;font-weight:bold;margin:8px 0">$9.99<span style="font-size:14px;font-weight:normal">/mo</span></div>
<small style="color:#4d96ff;display:block;margin-bottom:12px">No ads · Full access</small>
<button onclick="choosePremium()" style="width:100%;background:#4d96ff;color:white;border:none;padding:8px;border-radius:6px;cursor:pointer;font-weight:bold">Start free trial</button>
</div>
</div>
<div style="font-size:11px;color:#bbb;text-align:center">🔒 Secure checkout · Cancel anytime*</div>
<p class="fine-print">*Cancellation requires 30 days notice. Annual plan billed upfront. Prices exclude VAT.</p>
</div>`;
document.body.appendChild(el);
}
window.chooseFree = function() {
document.getElementById('sub-nag').innerHTML = `
<div class="modal-box">
<h2>Continue for free</h2>
<p style="color:#666">To continue with free access, please create an account so we can manage your usage limits.</p>
<input type="email" placeholder="Email address" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0" />
<button onclick="freeStep2()" style="background:#333;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%">Continue →</button>
<br/><small onclick="document.getElementById('sub-nag').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Maybe later</small>
</div>`;
};
window.freeStep2 = function() {
document.getElementById('sub-nag').innerHTML = `
<div class="modal-box">
<div style="font-size:11px;color:#999;margin-bottom:8px">Step 2 of 3</div>
<h2>Verify your email</h2>
<p style="color:#666">We've sent a 6-digit code to your email. Enter it below.</p>
<input type="text" placeholder="000000" maxlength="6" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0;text-align:center;font-size:24px;letter-spacing:8px" />
<button onclick="freeStep3()" style="background:#333;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%">Verify →</button>
<small style="color:#999;display:block;margin-top:8px;text-align:center">Didn't receive it? <a href="#" onclick="alert('Resent! Check your spam folder.');return false" style="color:#4d96ff">Resend</a></small>
</div>`;
};
window.freeStep3 = function() {
document.getElementById('sub-nag').innerHTML = `
<div class="modal-box">
<div style="font-size:11px;color:#999;margin-bottom:8px">Step 3 of 3</div>
<h2>Almost there!</h2>
<p style="color:#666">To prevent abuse of our free tier, please add a payment method. <strong>You will not be charged.</strong></p>
<input type="text" placeholder="Card number" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0" />
<div style="display:flex;gap:8px">
<input type="text" placeholder="MM/YY" style="flex:1;padding:10px;border:1px solid #ddd;border-radius:6px" />
<input type="text" placeholder="CVV" style="flex:1;padding:10px;border:1px solid #ddd;border-radius:6px" />
</div>
<button onclick="alert('Free account activated! Note: Your card will be charged $9.99/mo after your 7-day free trial unless cancelled.');document.getElementById('sub-nag').remove();" style="background:#4d96ff;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%;margin-top:12px;font-weight:bold">Activate Free Access →</button>
<div style="display:flex;align-items:center;gap:6px;justify-content:center;margin-top:10px">
<span style="font-size:11px;color:#bbb">🔒 256-bit SSL · Verified by Visa · PCI Compliant</span>
</div>
</div>`;
};
window.choosePremium = function() {
document.getElementById('sub-nag').innerHTML = `
<div class="modal-box">
<h2>✅ Great choice!</h2>
<p>Starting your free trial...</p>
<div style="background:#eee;border-radius:4px;height:6px;overflow:hidden;margin:16px 0">
<div style="background:#4d96ff;height:100%;width:0%;transition:width 2s" id="trial-bar"></div>
</div>
<p style="font-size:12px;color:#999">Setting up your account...</p>
</div>`;
setTimeout(() => { document.getElementById('trial-bar').style.width = '100%'; }, 100);
setTimeout(() => chooseFree(), 2200);
};
function addAutoplayVideo() {
spawnVideoAd('right');
}
function spawnVideoAd(side) {
const existing = document.getElementById('autoplay-video');
if (existing) existing.remove();
const el = document.createElement('div');
el.id = 'autoplay-video';
el.style.cssText = side === 'right' ? 'bottom:80px;right:16px' : 'bottom:80px;left:16px';
let count = 15;
el.innerHTML = `
<div id="video-close" onclick="closeVideoAd('${side}')">✕ Close Ad</div>
<div id="fake-video"><div id="video-placeholder">▶ Ad plays in <span id="ad-countdown">${count}</span>s</div></div>
<div id="video-label">AD · SOUND ON 🔊</div>`;
document.body.appendChild(el);
const iv = setInterval(() => {
count--;
const c = document.getElementById('ad-countdown');
if (c) c.textContent = count;
if (count <= 0) {
clearInterval(iv);
const p = document.getElementById('video-placeholder');
if (p) p.textContent = 'Thanks for watching! Next ad in 3s...';
setTimeout(() => spawnVideoAd(side === 'right' ? 'left' : 'right'), 3000);
}
}, 1000);
}
window.closeVideoAd = function(side) {
const el = document.getElementById('autoplay-video');
if (el) el.remove();
setTimeout(() => spawnVideoAd(side === 'right' ? 'left' : 'right'), 8000);
};
function addNotificationPrompt() {
const el = document.createElement('div');
el.id = 'notif-prompt';
el.innerHTML = `
<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">
<span style="font-size:20px">🔔</span>
<div>
<strong style="font-size:13px">consumerrights.wiki wants to send you notifications</strong><br/>
<span style="font-size:12px;color:#666">Get the latest updates, breaking news, and partner offers</span>
</div>
</div>
<div style="display:flex;gap:8px;justify-content:flex-end">
<button id="notif-block" onclick="blockNotif()">Block</button>
<button id="notif-allow" onclick="allowNotif()">Allow</button>
</div>`;
document.body.appendChild(el);
}
window.allowNotif = function() {
document.getElementById('notif-prompt').innerHTML = `<span style="font-size:13px">✅ Notifications enabled. You'll receive up to 47 per day.</span>`;
setTimeout(() => document.getElementById('notif-prompt').remove(), 3000);
};
window.blockNotif = function() {
const el = document.getElementById('notif-prompt');
el.innerHTML = `<span style="font-size:13px;color:#666">Saving preferences...</span>`;
setTimeout(() => {
el.innerHTML = `
<span style="font-size:13px;color:#c00">⚠️ Unable to save notification preference in your region.</span><br/>
<small style="color:#999">Notifications have been enabled by default. <a href="#" onclick="blockNotif2();return false" style="color:#4d96ff">Try again</a></small>`;
}, 1500);
};
window.blockNotif2 = function() {
document.getElementById('notif-prompt').innerHTML = `
<span style="font-size:13px;color:#666">Please confirm you want to block notifications:</span>
<div style="margin-top:8px;display:flex;gap:8px">
<button onclick="document.getElementById('notif-prompt').remove()">Yes, block</button>
<button onclick="allowNotif()">Actually, allow</button>
</div>`;
};
function addSurveyPopup() {
let q = 0;
const questions = [
{ q: 'How would you rate your experience today?', opts: ['Excellent', 'Good', 'Fair', 'Poor'] },
{ q: 'How likely are you to recommend us to a friend?', opts: ['Very likely', 'Likely', 'Unlikely', 'Never'] },
{ q: 'Which best describes you?', opts: ['Student', 'Professional', 'Researcher', 'Other'] },
{ q: 'How often do you visit this wiki?', opts: ['Daily', 'Weekly', 'Monthly', 'First time'] },
{ q: 'What is your household income?', opts: ['Under £20k', '£20-50k', '£50-100k', 'Over £100k'] },
{ q: 'Do you have any outstanding debts?', opts: ['None', 'Some', 'Significant', 'Prefer not to say'] },
{ q: 'Are you currently employed?', opts: ['Full time', 'Part time', 'Unemployed', 'Retired'] },
];
const el = document.createElement('div');
el.id = 'survey-modal';
function renderQ() {
const qObj = questions[q];
el.innerHTML = `
<div class="modal-box">
<div style="font-size:11px;color:#999;margin-bottom:8px">Quick survey · Question ${q+1} of ${questions.length}</div>
<div style="background:#f0f0f0;border-radius:4px;height:4px;margin-bottom:16px;overflow:hidden">
<div style="background:#4d96ff;height:100%;width:${(q/questions.length)*100}%;transition:width 0.3s"></div>
</div>
<h3 style="margin:0 0 16px;font-size:16px">${qObj.q}</h3>
<div style="display:flex;flex-direction:column;gap:8px">
${qObj.opts.map(o => `<button onclick="answerSurvey()" style="background:#f5f5f5;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;text-align:left">${o}</button>`).join('')}
</div>
<br/><small id="survey-skip" style="cursor:pointer;color:#bbb;font-size:11px" onclick="skipSurvey()">Skip question</small>
</div>`;
}
window.answerSurvey = function() {
q++;
if (q >= questions.length) {
el.innerHTML = `
<div class="modal-box">
<h2>✅ Thank you!</h2>
<p>Your responses help us improve. You've been entered into our prize draw.*</p>
<button onclick="document.getElementById('survey-modal').remove()">Done</button>
<p class="fine-print">*Prize: one additional free article per month for 3 months.</p>
</div>`;
} else { renderQ(); }
};
window.skipSurvey = function() {
q = 0;
setTimeout(() => {
el.innerHTML = `
<div class="modal-box">
<h2>😔 Survey reset</h2>
<p>To ensure data quality, skipping a question restarts the survey from the beginning.</p>
<button onclick="restartSurvey()">Start again</button>
<br/><small onclick="document.getElementById('survey-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Exit survey (results discarded)</small>
</div>`;
}, 200);
};
window.restartSurvey = function() { q = 0; renderQ(); };
document.body.appendChild(el);
renderQ();
}
function addLiveChatBubble() {
const el = document.createElement('div');
el.id = 'live-chat';
el.innerHTML = `
<div id="chat-bubble" onclick="toggleChat()">💬<span id="chat-badge">1</span></div>
<div id="chat-window" style="display:none">
<div id="chat-header">
Support <small style="opacity:0.8">· Typically replies instantly</small>
<span style="float:right;cursor:pointer" onclick="toggleChat()">✕</span>
</div>
<div id="chat-messages">
<div class="chat-msg" style="background:#f0f7ff"><strong>Sarah (Support)</strong><br/>Hi there! I noticed you've been reading for a while. Can I help you find what you're looking for? 😊</div>
</div>
<input id="chat-input" type="text" placeholder="Type a message..." onkeydown="sendChat(event)" />
</div>`;
document.body.appendChild(el);
setTimeout(() => {
document.getElementById('chat-window').style.display = 'block';
document.getElementById('chat-badge').style.display = 'none';
}, 5000);
}
window.toggleChat = function() {
const w = document.getElementById('chat-window');
w.style.display = w.style.display !== 'none' ? 'none' : 'block';
};
const chatResponses = [
'I understand! Have you considered upgrading to Premium for an ad-free experience?',
'Great question! That feature is available on our Premium plan from $9.99/mo.',
'I\'m sorry to hear that. I\'ve escalated your concern to our billing team.',
'I\'d love to help! Could you first verify your account email?',
'That\'s outside my scope. I can connect you to our sales team?',
'Your query has been logged as ticket #84721. Response time: 5-7 business days.',
'I completely understand your frustration. Our Premium plan resolves this issue.',
'Let me check... ⏳ still checking... I\'ll need to transfer you to another agent.',
];
window.sendChat = function(e) {
if (e.key !== 'Enter') return;
const input = document.getElementById('chat-input');
const msgs = document.getElementById('chat-messages');
if (!input.value.trim()) return;
const userMsg = document.createElement('div');
userMsg.className = 'chat-msg user-msg';
userMsg.textContent = input.value;
msgs.appendChild(userMsg);
input.value = '';
const typing = document.createElement('div');
typing.className = 'chat-msg';
typing.innerHTML = '<em style="color:#aaa">Sarah is typing...</em>';
msgs.appendChild(typing);
msgs.scrollTop = msgs.scrollHeight;
setTimeout(() => {
typing.remove();
const botMsg = document.createElement('div');
botMsg.className = 'chat-msg';
botMsg.innerHTML = `<strong>Sarah (Support)</strong><br/>${chatResponses[Math.floor(Math.random() * chatResponses.length)]}`;
msgs.appendChild(botMsg);
msgs.scrollTop = msgs.scrollHeight;
}, 1500 + Math.random() * 1000);
};
function injectBreakingNewsTicker() {
const el = document.createElement('div');
el.id = 'news-ticker';
el.innerHTML = `
<span class="ticker-label">LIVE</span>
<marquee scrollamount="4">
1,204 users currently reading this article •
Your free article limit resets in 29 days •
SPONSORED: Top 10 things you didn't know about subscribing •
Data brokers have accessed your profile 47 times today •
Our terms of service were updated 3 minutes ago •
Premium users are reading 3x more articles than you right now •
⚠️ Your session will expire in 10 minutes without an account •
</marquee>`;
document.body.prepend(el);
}
function degradeCursor() {
document.addEventListener('mousemove', function(e) {
if (Math.random() > 0.25) return;
const spark = document.createElement('div');
spark.className = 'cursor-spark';
spark.textContent = ['💰','📢','🍪','👁️','💊','📧','💳','📊'][Math.floor(Math.random()*8)];
spark.style.left = e.pageX + 'px';
spark.style.top = e.pageY + 'px';
document.body.appendChild(spark);
setTimeout(() => spark.remove(), 800);
});
}
function addConfetti() {
for (let i = 0; i < 40; i++) {
setTimeout(() => {
const el = document.createElement('div');
el.className = 'confetti-piece';
el.textContent = ['💰','📊','🍪','📧','💳','👁️','📱','🎯'][Math.floor(Math.random()*8)];
el.style.left = Math.random() * 100 + 'vw';
el.style.animationDuration = (Math.random() * 2 + 1.5) + 's';
document.body.appendChild(el);
setTimeout(() => el.remove(), 3500);
}, i * 80);
}
}
function addFakeSecurityAlert() {
const el = document.createElement('div');
el.id = 'security-alert';
el.innerHTML = `
<div class="modal-box" style="border-top:4px solid #e53e3e;max-width:460px">
<div class="modal-badge" style="background:#e53e3e">SECURITY NOTICE</div>
<h2 style="color:#e53e3e;margin-top:8px">Unusual activity detected</h2>
<p style="color:#555">We detected a sign-in attempt to your account from:</p>
<div style="background:#fff5f5;border:1px solid #fed7d7;border-radius:6px;padding:12px;margin:12px 0;font-size:13px">
<strong>Location:</strong> ${Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'}<br/>
<strong>Device:</strong> ${navigator.platform || 'Unknown device'}<br/>
<strong>Time:</strong> ${new Date().toLocaleTimeString()}
</div>
<p style="font-size:13px;color:#555">If this was you, no action is needed. If not, secure your account immediately.</p>
<div style="display:flex;gap:8px;margin-top:16px">
<button onclick="document.getElementById('security-alert').remove()" style="flex:1;background:#e53e3e;color:white;border:none;padding:10px;border-radius:6px;cursor:pointer;font-weight:bold">Secure My Account</button>
<button onclick="dismissSecurityAlert()" style="flex:1;background:#f5f5f5;color:#333;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer">This was me</button>
</div>
</div>`;
document.body.appendChild(el);
}
window.dismissSecurityAlert = function() {
document.getElementById('security-alert').innerHTML = `
<div class="modal-box">
<h2>✅ Got it</h2>
<p>We've marked this activity as safe.</p>
<p style="margin-top:8px;font-size:13px;color:#666">To prevent future alerts, <strong>create a free account</strong> and enable two-factor authentication.</p>
<button onclick="chooseFree();document.getElementById('security-alert').remove()">Create Account</button>
<br/><small onclick="document.getElementById('security-alert').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Dismiss</small>
</div>`;
};
function addTabHijack() {
const original = document.title;
let awayCount = 0;
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
awayCount++;
const msgs = ['😢 Come back! We miss you...', '🔴 URGENT: Your session expires soon', '💸 OFFER: 50% off Premium — today only', `⚠️ ${awayCount * 3} notifications while you were away`, '🍪 Cookie consent expires when you leave'];
document.title = msgs[awayCount % msgs.length];
} else {
document.title = original;
if (awayCount > 0) showTabReturnPopup(awayCount);
}
});
}
function showTabReturnPopup(count) {
const existing = document.getElementById('tab-return-popup');
if (existing) existing.remove();
const el = document.createElement('div');
el.id = 'tab-return-popup';
el.innerHTML = `
<strong>👋 Welcome back!</strong><br/>
<span style="font-size:13px;color:#666">You missed <strong>${count * 3} personalised updates</strong> while away. ${count} new ads have been queued for you.</span>
<div style="margin-top:10px"><button onclick="document.getElementById('tab-return-popup').remove()">OK</button></div>`;
document.body.appendChild(el);
setTimeout(() => { if (el.parentNode) el.remove(); }, 6000);
}
function addScrollBlocker() {
let triggered = false;
window.addEventListener('scroll', () => {
if (triggered) return;
if (window.scrollY > 400) {
triggered = true;
const overlay = document.createElement('div');
overlay.id = 'scroll-overlay';
document.body.appendChild(overlay);
const el = document.createElement('div');
el.id = 'scroll-block';
el.innerHTML = `
<div class="modal-box">
<div class="modal-badge">MEMBER CONTENT</div>
<h2>You're reading a member article</h2>
<p style="color:#555">This article is freely available to members. Create a free account to continue reading.</p>
<div style="background:#f9f9f9;border-radius:6px;padding:12px;margin:12px 0;font-size:13px;color:#666">
✓ Unlimited articles ✓ Save to reading list<br/>
✓ Comment on articles ✓ Personalised feed
</div>
<button onclick="chooseFree();document.getElementById('scroll-block').remove();document.getElementById('scroll-overlay').remove();" style="width:100%;background:#4d96ff;color:white;border:none;padding:12px;border-radius:6px;cursor:pointer;font-weight:bold;font-size:15px">Create free account →</button>
<br/><small onclick="continueReading()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Continue without account (limited access)</small>
</div>`;
document.body.appendChild(el);
}
});
}
window.continueReading = function() {
const sb = document.getElementById('scroll-block');
const so = document.getElementById('scroll-overlay');
if (sb) sb.remove();
if (so) so.remove();
setTimeout(() => {
let retrigger = false;
window.addEventListener('scroll', function handler() {
if (retrigger) return;
if (window.scrollY > 800) {
retrigger = true;
window.removeEventListener('scroll', handler);
const el = document.createElement('div');
el.id = 'scroll-block';
el.innerHTML = `
<div class="modal-box">
<h2>You've reached your limit</h2>
<p style="color:#555">You can read <strong>2 articles per month</strong> without an account. You've used both.</p>
<button onclick="chooseFree();document.getElementById('scroll-block').remove();" style="width:100%;background:#4d96ff;color:white;border:none;padding:12px;border-radius:6px;cursor:pointer;font-weight:bold">Create free account →</button>
<br/><small style="color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Resets in 29 days</small>
</div>`;
document.body.appendChild(el);
}
});
}, 500);
};
function addBeforeUnloadNag() {
window.addEventListener('beforeunload', (e) => { e.preventDefault(); e.returnValue = ''; });
}
function addFloatingCountdown() {
const el = document.createElement('div');
el.id = 'urgency-countdown';
el.innerHTML = `
<div id="urgency-inner">
<div style="font-size:10px;color:#999;margin-bottom:4px">LIMITED TIME OFFER</div>
<strong style="font-size:13px">Get 3 months free</strong>
<div id="countdown-timer">14:59</div>
<small style="font-size:11px;color:#999">Then $9.99/mo. Cancel anytime.*</small>
<button onclick="choosePremium()">Claim offer →</button>
<div id="countdown-close" onclick="closeCountdown()">✕</div>
</div>`;
document.body.appendChild(el);
let seconds = 899;
const iv = setInterval(() => {
seconds--;
if (seconds <= 0) {
clearInterval(iv);
const t = document.getElementById('countdown-timer');
if (t) { t.textContent = 'EXPIRED'; t.style.color = '#999'; }
return;
}
const t = document.getElementById('countdown-timer');
if (t) t.textContent = Math.floor(seconds/60) + ':' + String(seconds%60).padStart(2,'0');
}, 1000);
}
window.closeCountdown = function() {
const el = document.getElementById('urgency-countdown');
if (!el) return;
el.style.transform = 'translateX(120%)';
el.style.transition = 'transform 0.3s ease';
setTimeout(() => {
if (!el.parentNode) return;
el.style.transform = '';
el.style.transition = '';
const inner = document.getElementById('urgency-inner');
if (inner) inner.insertAdjacentHTML('afterbegin', '<div style="font-size:10px;background:#fff3cd;color:#856404;padding:4px 8px;border-radius:4px;margin-bottom:8px">⚠️ Closing this resets the offer timer</div>');
}, 5000);
};
function addFakeProgressBar() {
const el = document.createElement('div');
el.id = 'fake-progress-bar';
el.innerHTML = `<div id="fake-progress-fill"></div>`;
document.body.prepend(el);
let pct = 0;
let goingDown = false;
setInterval(() => {
if (goingDown) { pct -= 5; if (pct <= 10) goingDown = false; }
else { pct += Math.random() * 4; if (pct > 89) goingDown = true; }
const fill = document.getElementById('fake-progress-fill');
if (fill) fill.style.width = pct + '%';
}, 400);
}
function addViewerCounter() {
const el = document.createElement('div');
el.id = 'viewer-counter';
el.innerHTML = `<span id="viewer-dot">●</span> <span id="viewer-num">847</span> people reading this now`;
const body = document.querySelector('.mw-body');
if (body) body.prepend(el);
let count = 847;
setInterval(() => {
count += Math.floor(Math.random() * 5) - 1;
if (count < 800) count = 800;
const n = document.getElementById('viewer-num');
if (n) n.textContent = count.toLocaleString();
}, 2000);
}
});