// ==UserScript==
// @name ⚒ BETA Wizardebop 3.00 ⚒
// @author Type Stuff
// @description The Best Acellus.com Mod Menu
// @version 0.2
// @match https://admin192a.acellus.com/student/*
// @match https://admin192c.acellus.com/student/*
// @run-at document-start
// @grant none
// @namespace https://greasyfork.dpdns.org/users/1394549
// @icon https://img.freepik.com/free-vector/halloween-witch-hat-isolated-illustration_18591-83719.jpg
// @license Proprietary — see below
// ==/UserScript==
/*
© 2025 TypeStuff. All Rights Reserved.
You are free to:
• Install and run this script.
• Modify the code for your own, personal, non-commercial use.
You MAY NOT:
• Redistribute, re-host, repost, or re-upload this script in any form.
• Sell, license, or otherwise make available this script (original or modified).
*/
(function() {
'use strict';
/* -------------------
0) AI CHATBOT INTEGRATION
------------------- */
function setupAIChatbot() {
const aiTab = document.querySelector('.category-menu#ai');
const container = document.createElement('div');
container.id = 'ai-chatbot';
container.style = 'padding:8px;';
container.innerHTML = `
<div id="chat-container" style="display:flex;flex-direction:column;height:300px;">
<div id="chat-messages" style="flex:1;overflow:auto;border:1px solid #ccc;padding:8px;background:#fff;border-radius:4px;margin-bottom:8px;"></div>
<div style="display:flex;align-items:center;">
<select id="template-select" class="wm-input" style="margin-right:8px;">
<option value="">No template</option>
<option value="essay">Essay Writer</option>
</select>
<input id="chat-input" type="text" class="wm-input" placeholder="Type your message..." style="flex:1;margin-right:8px;"/>
<button id="chat-send" class="wm-button">Send</button>
</div>
<div id="chat-error" style="color:red;font-size:12px;margin-top:4px;display:none;"></div>
</div>
`;
aiTab.appendChild(container);
const AI_MAX = 15;
const AI_PROMPTS_KEY = 'wizardebop-ai-prompts';
const AI_TEMPLATE_KEY = 'wizardebop-ai-template';
function getPromptTimestamps(){
let arr = [];
try { arr = JSON.parse(localStorage.getItem(AI_PROMPTS_KEY) || '[]'); }
catch { arr = []; }
return Array.isArray(arr) ? arr : [];
}
function savePromptTimestamps(arr){
localStorage.setItem(AI_PROMPTS_KEY, JSON.stringify(arr));
}
function recordPrompt(){
const now = Date.now();
const oneHour = 60*60*1000;
let arr = getPromptTimestamps().filter(ts => now - ts < oneHour);
arr.push(now);
savePromptTimestamps(arr);
return arr.length;
}
function canSendPrompt(){
const now = Date.now();
const oneHour = 60*60*1000;
return getPromptTimestamps().filter(ts => now - ts < oneHour).length < AI_MAX;
}
async function fetchAI(messages) {
const res = await fetch('http://localhost:11434', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gemm3:1b',
messages
})
});
if (!res.ok) {
throw new Error(`AI request failed: ${res.status} ${res.statusText}`);
}
const data = await res.json();
return data.choices[0].message.content.trim();
}
const tplSelect = document.getElementById('template-select');
const inputEl = document.getElementById('chat-input');
const sendBtn = document.getElementById('chat-send');
const msgsDiv = document.getElementById('chat-messages');
const errDiv = document.getElementById('chat-error');
tplSelect.value = localStorage.getItem(AI_TEMPLATE_KEY) || '';
sendBtn.addEventListener('click', async () => {
errDiv.style.display = 'none';
if (!canSendPrompt()) {
errDiv.textContent = `Rate limit reached: ${AI_MAX} prompts per hour.`;
errDiv.style.display = 'block';
return;
}
const raw = inputEl.value.trim();
if (!raw) return;
const template = tplSelect.value;
localStorage.setItem(AI_TEMPLATE_KEY, template);
let messages = [];
if (template === 'essay') {
messages.push({
role: 'system',
content: 'Make a detailed 200-word essay that gets a 100%, and grammar is perfect and punctuation is also perfect, about:'
});
}
messages.push({ role: 'user', content: raw });
recordPrompt();
if (!canSendPrompt()) sendBtn.disabled = true;
msgsDiv.innerHTML += `<div><strong>You:</strong> ${raw}</div>`;
msgsDiv.scrollTop = msgsDiv.scrollHeight;
inputEl.value = '';
try {
const aiResp = await fetchAI(messages);
msgsDiv.innerHTML += `<div><strong>AI:</strong> ${aiResp}</div>`;
msgsDiv.scrollTop = msgsDiv.scrollHeight;
if (template === 'essay') {
const summary = await fetchAI([
{ role: 'assistant', content: aiResp },
{ role: 'user', content: 'Describe what the above essay is about in one sentence.' }
]);
msgsDiv.innerHTML += `<div><em>Summary:</em> ${summary}</div>`;
msgsDiv.scrollTop = msgsDiv.scrollHeight;
}
} catch (err) {
errDiv.textContent = 'Error: ' + err.message;
errDiv.style.display = 'block';
}
});
}
/* ------------------
1) SETTINGS & STATE
------------------ */
const STORAGE = {
wallpaper: 'wizardebop-wallpaper',
unpause: 'wizardebop-unpause',
pasteFast: 'wizardebop-paste',
autoSpeed: 'wizardebop-autoSpeed',
btnBg: 'wizardebop-btn-bg',
btnHover: 'wizardebop-btn-hover',
btnRadius: 'wizardebop-btn-radius',
btnFont: 'wizardebop-btn-font',
btnPad: 'wizardebop-btn-pad',
animDur: 'wizardebop-anim-duration',
password: 'wizardebop-password',
keybind: 'wizardebop-keybind',
notes: 'wizardebop-notes',
todos: 'wizardebop-todos',
showTimer: 'wizardebop-show-timer'
};
let autoUnpause = localStorage.getItem(STORAGE.unpause) === 'true';
let pasteFast = localStorage.getItem(STORAGE.pasteFast) === 'true';
let autoSpeed = localStorage.getItem(STORAGE.autoSpeed) === 'true';
let userPass = localStorage.getItem(STORAGE.password) || '';
let toggleKey = localStorage.getItem(STORAGE.keybind) || 'F2';
let savedNotes = localStorage.getItem(STORAGE.notes) || '';
let todoList = JSON.parse(localStorage.getItem(STORAGE.todos) || '[]');
let showTimerOnScreen = localStorage.getItem(STORAGE.showTimer) === 'true';
const BTN = {
bg: localStorage.getItem(STORAGE.btnBg) || 'rgba(128,128,128,0.5)',
hover: localStorage.getItem(STORAGE.btnHover) || 'rgba(255,255,255,0.3)',
radius: localStorage.getItem(STORAGE.btnRadius) || '6px',
font: localStorage.getItem(STORAGE.btnFont) || '14px',
pad: localStorage.getItem(STORAGE.btnPad) || '6px 12px'
};
const ANIM = {
gradDur: +localStorage.getItem(STORAGE.animDur) || 12
};
let timerInterval = null,
timerElapsed = 0;
let pomoInterval = null,
pomoRemaining = 25 * 60,
pomoPhase = 'work',
pomoCycleCount = 0;
function save(k,v){ localStorage.setItem(k,v); }
function saveTodos(){ save(STORAGE.todos, JSON.stringify(todoList)); }
/* -------------------
2) AUTO-UNPAUSE
------------------- */
function enableUnpause(){
Object.defineProperty(document,'hidden',{get:()=>false});
Object.defineProperty(document,'visibilityState',{get:()=> 'visible'});
document.addEventListener('visibilitychange',e=>e.stopImmediatePropagation(),true);
}
if(autoUnpause) enableUnpause();
new MutationObserver(()=>{ if(autoUnpause) enableUnpause(); })
.observe(document,{childList:true,subtree:true});
/* -------------------
3) WALLPAPER HELPERS
------------------- */
function loadWP(){
try{ return JSON.parse(localStorage.getItem(STORAGE.wallpaper)); }
catch{ return null; }
}
function saveWP(type,val){
localStorage.setItem(STORAGE.wallpaper, JSON.stringify({type,val}));
}
function createWP(){
let el = document.getElementById('global-wallpaper');
if(!el){
el = document.createElement('div');
el.id = 'global-wallpaper';
document.body.prepend(el);
}
return el;
}
function changeWP(type,val,saveFlag=true){
const w = createWP();
Object.assign(w.style,{
position:'fixed', top:'0', left:'0',
width:'100vw', height:'100vh',
zIndex:'-1', pointerEvents:'none', animation:''
});
if(type==='gradient'){
w.style.background = 'linear-gradient(135deg,rgba(255,182,193,0.6),rgba(176,224,230,0.6),rgba(221,160,221,0.6),rgba(255,228,181,0.6))';
w.style.backgroundSize = '200% 200%';
w.style.animation = `pastelGradient ${ANIM.gradDur}s ease infinite`;
} else if(type.startsWith('ai_')){
const topic = type.split('_')[1];
w.style.background = `url('https://source.unsplash.com/1600x900/?ai-art,${topic}') no-repeat center/cover`;
} else if(type==='custom'){
w.style.background = val;
} else if(type==='upload'){
w.style.background = `url('${val}') no-repeat center/cover`;
}
if(saveFlag) saveWP(type,val);
}
/* -------------------
4) ESSAY PASTER GUI
------------------- */
function setupPaste(){
let last = null;
const overlay = document.createElement('div');
overlay.id = 'pasteOverlay';
overlay.style.cssText =
'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);' +
'background:rgba(0,0,0,0.7);padding:20px;border-radius:8px;z-index:10003;display:none';
overlay.innerHTML =
`<div style="display:flex;flex-direction:column;gap:10px;">
<h3 style="margin:0;color:#000">✎ Paste Anything</h3>
<textarea id="pasteText"
style="width:300px;height:100px;padding:8px;border-radius:4px;border:none;color:#000">
</textarea>
</div>
<div style="display:flex;gap:8px;margin-top:10px;">
<button id="pasteNow"
style="padding:6px;border:none;border-radius:4px;cursor:pointer;background:${BTN.bg};transition:background 0.3s;">
Paste
</button>
<button id="closePaste"
style="padding:6px;border:none;border-radius:4px;cursor:pointer;background:${BTN.bg};transition:background 0.3s;">
Close
</button>
<button id="speedButton"
style="padding:6px;border:none;border-radius:4px;cursor:pointer;background:${BTN.bg};transition:background 0.3s;">
${autoSpeed ? '1.5× Auto ON' : '1.5× Now'}
</button>
</div>`;
document.body.appendChild(overlay);
overlay.querySelector('#pasteNow').addEventListener('click', ()=>{
const txt = overlay.querySelector('#pasteText').value;
if(last){
last.focus();
let i=0;
const ev = new Event('input',{bubbles:true});
const iv = setInterval(()=>{
if(last.isContentEditable) last.textContent += txt[i];
else last.value += txt[i];
last.dispatchEvent(ev);
if(++i >= txt.length) clearInterval(iv);
},5);
}
overlay.style.display = 'none';
});
overlay.querySelector('#closePaste').addEventListener('click', ()=>{
overlay.style.display = 'none';
});
const speedBtn = overlay.querySelector('#speedButton');
speedBtn.addEventListener('click', ()=>{
document.querySelectorAll('video').forEach(v=> v.playbackRate = 1.5);
});
speedBtn.addEventListener('contextmenu', e=>{
e.preventDefault();
autoSpeed = !autoSpeed;
save(STORAGE.autoSpeed, autoSpeed);
speedBtn.textContent = autoSpeed ? '1.5× Auto ON' : '1.5× Now';
if(autoSpeed) applyAutoSpeed();
});
document.addEventListener('click', e=>{
if(!pasteFast) return;
const t = e.target;
if(document.getElementById('settings-menu')?.contains(t)) return;
if(overlay.contains(t)) return;
if(t.isContentEditable || t.nodeName==='TEXTAREA' || (t.nodeName==='INPUT'&&t.type==='text')){
last = t;
overlay.style.display = 'block';
}
}, true);
}
/* -------------------
5) STYLE INJECTION
------------------- */
const styleEl = document.createElement('style');
styleEl.textContent = `
@keyframes pastelGradient {
0% { background-position:0% 0% }
50% { background-position:100% 100% }
100% { background-position:0% 0% }
}
#settings-overlay {
position:fixed;top:0;left:0;width:100vw;height:100vh;
background:rgba(0,0,0,0.2);backdrop-filter:blur(4px);z-index:10000;
display:none;
}
#settings-menu {
position:fixed;top:50%;left:50%;
transform:translate(-50%,-50%) scale(0.8);
width:760px;height:420px;
background:rgba(255,255,255,0.8);
backdrop-filter:blur(6px);
border-radius:12px;
box-shadow:0 0 20px rgba(0,0,0,0.5);
display:none;flex-direction:row;
z-index:10001;opacity:0;
transition:opacity 0.3s ease,transform 0.3s ease;
}
#settings-menu.visible {
display:flex;opacity:1;
transform:translate(-50%,-50%) scale(1);
}
#settings-button {
position:fixed;bottom:20px;right:20px;
background:rgba(128,128,128,0.5);
color:#000;border:none;border-radius:6px;
padding:6px;font-size:18px;cursor:pointer;
z-index:10002;backdrop-filter:blur(4px);
transition:transform 0.2s;
}
#settings-button:hover { transform:scale(1.1) }
.settings-categories {
width:20%;background:rgba(0,0,0,0.1);
display:flex;flex-direction:column;
padding:10px;overflow-y:auto;
}
.settings-categories button {
background:rgba(255,255,255,0.5);
color:#000;border:none;margin:4px 0;
padding:6px;border-radius:6px;
cursor:pointer;transition:background 0.3s,transform 0.2s;
text-align:left;font-size:14px;
}
.settings-categories button:hover {
background:rgba(200,200,200,0.6);
transform:translateX(4px);
}
.settings-categories button.active {
background:rgba(200,200,200,0.8);color:#000;
}
.settings-details {
width:80%;padding:20px;overflow-y:auto;color:#000;
position:relative;
}
.category-menu { display:none }
.category-menu.active { display:block }
.category-menu#timer {
background:rgba(200,200,200,0.1);
border-radius:6px; padding:10px;
}
.category-menu h3 { margin-top:0;font-size:18px }
.category-menu h4 { margin:12px 0 4px;font-size:16px }
.category-menu label { display:block;margin:8px 0;font-size:14px }
.category-menu input.wm-input {
width:90%;margin:4px 0;padding:4px;
border-radius:4px;border:1px solid #ccc;
}
button.wm-button {
margin:6px 4px;padding:${BTN.pad};
background:${BTN.bg};border:none;
border-radius:${BTN.radius};
font-size:${BTN.font};cursor:pointer;
transition:background 0.3s;
}
button.wm-button:hover { background:${BTN.hover} }
#close-x {
position:absolute;top:8px;right:8px;
background:transparent;border:none;
font-size:20px;cursor:pointer;
}
#screen-timer {
position:absolute;top:100px;left:100px;
background:rgba(0,0,0,0.7);color:#fff;
padding:8px 12px;border-radius:4px;
font-size:16px;cursor:move;
z-index:10005;display:none;user-select:none;
}
`;
document.head.appendChild(styleEl);
/* -------------------
6) CREATE ON-SCREEN TIMER
-------------------
*/
let screenTimerEl;
function createScreenTimer(){
if(screenTimerEl) return;
screenTimerEl = document.createElement('div');
screenTimerEl.id = 'screen-timer';
screenTimerEl.textContent = '00:00:00';
document.body.appendChild(screenTimerEl);
let dragging=false, ox=0, oy=0;
screenTimerEl.addEventListener('mousedown', e=>{
dragging=true;
ox = e.clientX - screenTimerEl.offsetLeft;
oy = e.clientY - screenTimerEl.offsetTop;
e.preventDefault();
});
document.addEventListener('mousemove', e=>{
if(dragging){
screenTimerEl.style.left = `${e.clientX - ox}px`;
screenTimerEl.style.top = `${e.clientY - oy}px`;
}
});
document.addEventListener('mouseup', ()=>dragging=false);
screenTimerEl.style.display = showTimerOnScreen ? 'block' : 'none';
}
/* -------------------
7) AUTO-SPEED LOGIC
-------------------
*/
function applyAutoSpeed(){
const setAll = ()=> document.querySelectorAll('video').forEach(v=> v.playbackRate = 1.5);
setAll();
new MutationObserver(setAll)
.observe(document.body, { childList: true, subtree: true });
document.addEventListener('play', e=>{
if(e.target.tagName === 'VIDEO')
e.target.playbackRate = 1.5;
}, true);
}
/* -------------------
8) BUILD SETTINGS MENU
-------------------
*/
function buildMenu(){
const overlay = document.createElement('div');
overlay.id = 'settings-overlay';
document.body.appendChild(overlay);
const btn = document.createElement('button');
btn.id = 'settings-button';
btn.textContent = '⚙️';
document.body.appendChild(btn);
const menu = document.createElement('div');
menu.id = 'settings-menu';
menu.innerHTML =
`<button id='close-x'>×</button>` +
`<div class='settings-categories'>` +
`<button class='cat-btn active' data-cat='general'>General</button>` +
`<button class='cat-btn' data-cat='ai'>AI</button>` +
`<button class='cat-btn' data-cat='wallpaper'>Wallpaper</button>` +
`<button class='cat-btn' data-cat='buttons'>Buttons</button>` +
`<button class='cat-btn' data-cat='animations'>Animations</button>` +
`<button class='cat-btn' data-cat='notes'>Notes</button>` +
`<button class='cat-btn' data-cat='todo'>To-Do</button>` +
`<button class='cat-btn' data-cat='timer'>Timer</button>` +
`<button class='cat-btn' data-cat='extras'>Extras</button>` +
`</div>` +
`<div class='settings-details'>` +
`<div class='category-menu active' id='general'>` +
`<h3>General</h3>` +
`<label><input type='checkbox' id='chk-unpause' ${autoUnpause?'checked':''}/> Auto-Unpause</label>` +
`<label><input type='checkbox' id='chk-paste' ${pasteFast?'checked':''}/> Essay Paster</label>` +
`<label><input type='checkbox' id='chk-speed' ${autoSpeed?'checked':''}/> Auto 1.5× Video</label>` +
`<label>Password: <input type='password' id='menu-pass' class='wm-input' value='${userPass}'></label>` +
`<label>Keybind: <button id='keybind-btn' class='wm-button'>${toggleKey===' ' ? 'Space' : toggleKey}</button></label>` +
`<button id='apply-general' class='wm-button'>Apply</button>` +
`</div>` +
`<div class='category-menu' id='ai'>` +
`<h3>AI</h3>` +
`<div id='ai-settings' style='padding:4px 0;color:#555;'></div>` +
`</div>` +
`<div class='category-menu' id='wallpaper'>` +
`<h3>Wallpaper</h3>` +
`<button class='wm-button' data-wallpaper='gradient'>Gradient</button>` +
`<button class='wm-button' data-wallpaper='ai_nature'>AI Nature</button>` +
`<button class='wm-button' data-wallpaper='ai_cityscape'>AI Cityscape</button>` +
`<button class='wm-button' data-wallpaper='ai_abstract'>AI Abstract</button>` +
`<button class='wm-button' data-wallpaper='custom'>Custom Color</button>` +
`<button class='wm-button' id='upload-wallpaper'>Upload</button>` +
`<input type='file' id='upload-input' accept='image/*'>` +
`</div>` +
`<div class='category-menu' id='buttons'>` +
`<h3>Buttons</h3>` +
`<label>BG:<br><input id='btn-bg' class='wm-input' value='${BTN.bg}'></label>` +
`<label>Hover BG:<br><input id='btn-hover' class='wm-input' value='${BTN.hover}'></label>` +
`<label>Radius:<br><input id='btn-radius' class='wm-input' value='${BTN.radius}'></label>` +
`<label>Font Size:<br><input id='btn-font' class='wm-input' value='${BTN.font}'></label>` +
`<label>Padding:<br><input id='btn-pad' class='wm-input' value='${BTN.pad}'></label>` +
`<button class='wm-button' id='apply-buttons'>Apply</button>` +
`</div>` +
`<div class='category-menu' id='animations'>` +
`<h3>Animations</h3>` +
`<label>Gradient Duration (s):<br><input type='number' id='anim-duration' class='wm-input' value='${ANIM.gradDur}' min='1'></label>` +
`<button class='wm-button' id='apply-animations'>Apply</button>` +
`</div>` +
`<div class='category-menu' id='notes'>` +
`<h3>Notes</h3>` +
`<textarea id='notes-text' style='width:100%;height:200px;padding:8px;border:1px solid #ccc;border-radius:4px;'>${savedNotes}</textarea>` +
`<button id='save-notes' class='wm-button'>Save Notes</button>` +
`</div>` +
`<div class='category-menu' id='todo'>` +
`<h3>To-Do List</h3>` +
`<input id='todo-input' placeholder='New task...'><button id='add-todo' class='wm-button'>Add</button>` +
`<ul id='todo-list'></ul>` +
`</div>` +
`<div class='category-menu' id='timer'>` +
`<h3>Timer</h3>` +
`<span id='timer-display-general'>00:00:00</span>` +
`<label><input type='checkbox' id='chk-show-screen' ${showTimerOnScreen?'checked':''}/> Show timer on screen</label><br>` +
`<button id='timer-toggle-general' class='wm-button'>Start</button>` +
`<button id='timer-reset-general' class='wm-button'>Reset</button>` +
`</div>` +
`<div class='category-menu' id='extras'><h3>Extras</h3><p>More coming soon…</p></div>` +
`</div>`;
document.body.appendChild(menu);
menu.querySelectorAll('.cat-btn').forEach(b=>{
b.addEventListener('click',()=>{
menu.querySelectorAll('.cat-btn').forEach(x=>x.classList.remove('active'));
menu.querySelectorAll('.category-menu').forEach(x=>x.classList.remove('active'));
b.classList.add('active');
menu.querySelector('#'+b.dataset.cat).classList.add('active');
});
});
const showM = ()=>{ overlay.style.display='block'; menu.classList.add('visible'); };
const hideM = ()=>{ menu.classList.remove('visible'); overlay.style.display='none'; };
btn.addEventListener('click',()=>{
if(userPass){
const p = prompt('Enter password:');
if(p !== userPass) return;
}
showM();
});
document.addEventListener('keydown', e=>{
if(e.key === toggleKey){
if(menu.classList.contains('visible')) hideM();
else {
if(userPass){
const p = prompt('Enter password:');
if(p !== userPass) return;
}
showM();
}
}
});
menu.querySelector('#close-x').addEventListener('click', hideM);
overlay.addEventListener('click', hideM);
menu.querySelector('#apply-general').addEventListener('click', ()=>{
autoUnpause = menu.querySelector('#chk-unpause').checked;
pasteFast = menu.querySelector('#chk-paste').checked;
autoSpeed = menu.querySelector('#chk-speed').checked;
userPass = menu.querySelector('#menu-pass').value;
save(STORAGE.unpause, autoUnpause);
save(STORAGE.pasteFast, pasteFast);
save(STORAGE.autoSpeed, autoSpeed);
save(STORAGE.password, userPass);
save(STORAGE.keybind, toggleKey);
if(autoUnpause) enableUnpause();
if(autoSpeed) applyAutoSpeed();
hideM();
});
const disp = menu.querySelector('#timer-display-general'),
btnT = menu.querySelector('#timer-toggle-general'),
btnR = menu.querySelector('#timer-reset-general'),
chkS = menu.querySelector('#chk-show-screen');
function updateTimer(){
const h = Math.floor(timerElapsed/3600).toString().padStart(2,'0'),
m = Math.floor((timerElapsed%3600)/60).toString().padStart(2,'0'),
s = (timerElapsed%60).toString().padStart(2,'0');
disp.textContent = `${h}:${m}:${s}`;
if(showTimerOnScreen && screenTimerEl) screenTimerEl.textContent = disp.textContent;
}
btnT.addEventListener('click', ()=>{
if(timerInterval){
clearInterval(timerInterval);
timerInterval = null;
btnT.textContent = 'Start';
} else {
createScreenTimer();
if(showTimerOnScreen) screenTimerEl.style.display = 'block';
timerInterval = setInterval(()=>{
timerElapsed++;
updateTimer();
}, 1000);
btnT.textContent = 'Stop';
}
});
btnR.addEventListener('click', ()=>{
clearInterval(timerInterval);
timerInterval = null;
timerElapsed = 0;
updateTimer();
btnT.textContent = 'Start';
});
chkS.addEventListener('change', e=>{
showTimerOnScreen = e.target.checked;
save(STORAGE.showTimer, showTimerOnScreen);
if(screenTimerEl) screenTimerEl.style.display = showTimerOnScreen ? 'block' : 'none';
});
}
/* -------------------
9) INIT
------------------- */
function wireUpWallpaperButtons(){
const uploadInput = document.querySelector('#upload-input');
document.body.addEventListener('click', e => {
const btn = e.target;
if (btn.matches('#wallpaper button[data-wallpaper]')) {
const type = btn.getAttribute('data-wallpaper');
if (type === 'custom') {
const val = prompt('Enter a CSS background (color, gradient, etc):');
if (val) changeWP(type, val);
} else {
changeWP(type, null);
}
}
if (btn.id === 'upload-wallpaper') {
uploadInput.click();
}
});
uploadInput.addEventListener('change', e => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = () => changeWP('upload', reader.result);
reader.readAsDataURL(file);
});
}
function init(){
setupPaste();
buildMenu();
setupAIChatbot(); // ← initialize AI after menu exists
createScreenTimer();
wireUpWallpaperButtons();
if(autoSpeed) applyAutoSpeed();
}
if(document.readyState==='loading')
document.addEventListener('DOMContentLoaded', init);
else
init();
// Restore wallpaper
const wp = loadWP();
if(wp) window.addEventListener('DOMContentLoaded', ()=>changeWP(wp.type, wp.val, false));
})();