// ==UserScript==
// @name ⚒ BETA Wizardebop 3.00 ⚒
// @author Type Stuff
// @description Acellus.com Adding final things slowly, but almost done!
// @version 0.1
// @match https://admin192a.acellus.com/student/*
// @match https://admin192c.acellus.com/student/*
// @run-at document-start
// @license GNU GPLv3
// @grant none
// @namespace https://greasyfork.org/users/1394549
// @icon https://img.freepik.com/free-vector/halloween-witch-hat-isolated-illustration_18591-83719.jpg
// ==/UserScript==
(function() {
'use strict';
/* ------------------
1) SETTINGS & STATE
------------------ */
const STORAGE = {
wallpaper: 'wizardebop-wallpaper',
unpause: 'wizardebop-unpause',
pasteFast: 'wizardebop-paste',
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 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
};
// Timer state for General tab
let timerInterval = null;
let timerElapsed = 0;
// Pomodoro state
let pomoInterval = null;
let pomoRemaining = 25 * 60;
let pomoPhase = 'work'; // 'work' or 'break'
let 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) PASTE-ESSAYS 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 style='display:flex;justify-content:space-between;'>
<button id='pasteNow' style='padding:6px 12px;border:none;border-radius:4px;cursor:pointer;background:${BTN.bg};color:#000;transition:background 0.3s;'>Paste</button>
<button id='closePaste' style='padding:6px 12px;border:none;border-radius:4px;cursor:pointer;background:${BTN.bg};color:#000;transition:background 0.3s;'>Close</button>
</div>
</div>`;
document.body.appendChild(overlay);
overlay.querySelector('#pasteNow').addEventListener('click',()=>{
const txt = overlay.querySelector('#pasteText').value;
if(last){
last.focus();
let i=0, 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');
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 h3 {margin-top:0;color:#000;font-size:18px}
.category-menu h4 {margin:12px 0 4px;color:#000;font-size:16px}
.category-menu label {display:block;margin:8px 0;font-size:14px;color:#000}
.category-menu input.wm-input {width:90%;margin:4px 0;padding:4px;border-radius:4px;border:1px solid #ccc;color:#000}
button.wm-button {margin:6px 4px;padding:${BTN.pad};background:${BTN.bg};border:none;border-radius:${BTN.radius};color:#000;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}
/* On-screen timer */
#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, offsetX = 0, offsetY = 0;
screenTimerEl.addEventListener('mousedown', e => {
dragging = true;
offsetX = e.clientX - screenTimerEl.offsetLeft;
offsetY = e.clientY - screenTimerEl.offsetTop;
e.preventDefault();
});
document.addEventListener('mousemove', e => {
if (dragging) {
screenTimerEl.style.left = `${e.clientX - offsetX}px`;
screenTimerEl.style.top = `${e.clientY - offsetY}px`;
}
});
document.addEventListener('mouseup', () => {
dragging = false;
});
// initial visibility
screenTimerEl.style.display = showTimerOnScreen ? 'block' : 'none';
}
/* -------------------
7) 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='wallpaper'>Wallpaper</button>` +
`<button class='cat-btn' data-cat='general'>General</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='pomodoro'>Pomodoro</button>` +
`<button class='cat-btn' data-cat='extras'>Extras</button>` +
`</div>` +
`<div class='settings-details'>` +
// Wallpaper
`<div class='category-menu active' 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>` +
// General w/ Timer and on-screen toggle
`<div class='category-menu' 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':''}/> Paste Fast</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>` +
`<h4>Timer</h4>` +
`<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>` +
`<button class='wm-button' id='apply-general'>Apply</button>` +
`</div>` +
// Buttons
`<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>` +
// Animations
`<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>` +
// Notes
`<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>` +
// To-Do
`<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>` +
// Pomodoro
`<div class='category-menu' id='pomodoro'>` +
`<h3>Pomodoro Timer</h3>` +
`<div id='pomodoro-cycle'>Cycle: ${pomoCycleCount}</div>` +
`<div id='pomodoro-display'>25:00</div>` +
`<button id='pomodoro-start' class='wm-button'>Start</button>` +
`<button id='pomodoro-stop' class='wm-button'>Stop</button>` +
`<button id='pomodoro-reset' class='wm-button'>Reset</button>` +
`</div>` +
// Extras
`<div class='category-menu' id='extras'><h3>Extras</h3><p>More coming soon…</p></div>` +
`</div>`;
document.body.appendChild(menu);
// Category tabs
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 showMenu = ()=>{ overlay.style.display='block'; menu.classList.add('visible'); };
const hideMenu = ()=>{
menu.classList.remove('visible');
overlay.style.display='none';
};
// Open/Close handlers
btn.addEventListener('click', ()=>{
if(userPass){
const p=prompt('Enter password:');
if(p!==userPass) return;
}
showMenu();
});
document.addEventListener('keydown',e=>{
if(e.key===toggleKey){
if(menu.classList.contains('visible')) hideMenu();
else {
if(userPass){
const p=prompt('Enter password:');
if(p!==userPass) return;
}
showMenu();
}
}
});
menu.querySelector('#close-x').addEventListener('click', hideMenu);
overlay.addEventListener('click', hideMenu);
/* Wallpaper handlers */
menu.querySelectorAll('[data-wallpaper]').forEach(b=>{
b.addEventListener('click', ()=>{
const t = b.dataset.wallpaper;
if(t==='custom'){
const c = prompt('Enter CSS color:', '#000000');
if(c) changeWP('custom',c);
} else changeWP(t,null);
});
});
menu.querySelector('#upload-wallpaper').addEventListener('click', ()=> menu.querySelector('#upload-input').click());
menu.querySelector('#upload-input').addEventListener('change',e=>{
const f=e.target.files[0];
if(f){
const r=new FileReader();
r.onload=ev=>changeWP('upload',ev.target.result);
r.readAsDataURL(f);
}
e.target.value='';
});
/* General Apply & Timer */
menu.querySelector('#apply-general').addEventListener('click', ()=>{
autoUnpause = menu.querySelector('#chk-unpause').checked;
pasteFast = menu.querySelector('#chk-paste').checked;
userPass = menu.querySelector('#menu-pass').value;
showTimerOnScreen = menu.querySelector('#chk-show-screen').checked;
save(STORAGE.unpause,autoUnpause);
save(STORAGE.pasteFast,pasteFast);
save(STORAGE.password,userPass);
save(STORAGE.keybind,toggleKey);
save(STORAGE.showTimer, showTimerOnScreen);
if(autoUnpause) enableUnpause();
// toggle on-screen timer visibility
if(screenTimerEl) screenTimerEl.style.display = showTimerOnScreen ? 'block' : 'none';
hideMenu();
});
// General timer controls
const dispG = menu.querySelector('#timer-display-general');
const btnTG = menu.querySelector('#timer-toggle-general');
const btnRG = menu.querySelector('#timer-reset-general');
function updateGeneral(){
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');
dispG.textContent = `${h}:${m}:${s}`;
if(showTimerOnScreen && screenTimerEl){
screenTimerEl.textContent = dispG.textContent;
}
}
btnTG.addEventListener('click', ()=>{
if(timerInterval){
clearInterval(timerInterval);
timerInterval = null;
btnTG.textContent = 'Start';
} else {
createScreenTimer();
if(showTimerOnScreen) screenTimerEl.style.display = 'block';
timerInterval = setInterval(()=>{
timerElapsed++;
updateGeneral();
},1000);
btnTG.textContent = 'Stop';
}
});
btnRG.addEventListener('click', ()=>{
clearInterval(timerInterval);
timerInterval = null;
timerElapsed = 0;
updateGeneral();
btnTG.textContent = 'Start';
});
/* Buttons Apply */
menu.querySelector('#apply-buttons').addEventListener('click', ()=>{
const bg=menu.querySelector('#btn-bg').value,
ho=menu.querySelector('#btn-hover').value,
rd=menu.querySelector('#btn-radius').value,
fn=menu.querySelector('#btn-font').value,
pd=menu.querySelector('#btn-pad').value;
save(STORAGE.btnBg,bg);
save(STORAGE.btnHover,ho);
save(STORAGE.btnRadius,rd);
save(STORAGE.btnFont,fn);
save(STORAGE.btnPad,pd);
document.querySelectorAll('.wm-button').forEach(bc=>{
Object.assign(bc.style,{background:bg,borderRadius:rd,fontSize:fn,padding:pd});
bc.onmouseover=()=>bc.style.background=ho;
bc.onmouseout =()=>bc.style.background=bg;
});
});
/* Animations Apply */
menu.querySelector('#apply-animations').addEventListener('click', ()=>{
const d=+menu.querySelector('#anim-duration').value||12;
ANIM.gradDur=d; save(STORAGE.animDur,d);
const cur=loadWP();
if(cur&&cur.type==='gradient') changeWP('gradient',null,false);
});
/* Notes Save */
menu.querySelector('#save-notes').addEventListener('click', ()=>{
const txt=menu.querySelector('#notes-text').value;
save(STORAGE.notes,txt);
alert('Notes saved');
});
/* To-Do List Logic */
const todoInput = menu.querySelector('#todo-input');
const todoUl = menu.querySelector('#todo-list');
function renderTodos(){
todoUl.innerHTML='';
todoList.forEach((t,i)=>{
const li = document.createElement('li');
li.className = 'todo-item'+(t.done?' completed':'');
li.innerHTML =
`<label><input type='checkbox' data-i='${i}' ${t.done?'checked':''}> <span>${t.text}</span></label>`+
`<button data-i='${i}' class='wm-button'>✕</button>`;
todoUl.appendChild(li);
});
}
menu.querySelector('#add-todo').addEventListener('click', ()=>{
const txt=todoInput.value.trim();
if(!txt) return;
todoList.push({ text:txt, done:false });
todoInput.value=''; saveTodos(); renderTodos();
});
todoUl.addEventListener('click', e=>{
const i=+e.target.dataset.i;
if(e.target.tagName==='INPUT'){
todoList[i].done=e.target.checked; saveTodos(); renderTodos();
} else if(e.target.textContent==='✕'){
todoList.splice(i,1); saveTodos(); renderTodos();
}
});
renderTodos();
/* Pomodoro Logic */
const dispP = menu.querySelector('#pomodoro-display');
const cycleP = menu.querySelector('#pomodoro-cycle');
const btnPS = menu.querySelector('#pomodoro-start');
const btnPP = menu.querySelector('#pomodoro-stop');
const btnPR = menu.querySelector('#pomodoro-reset');
function updatePomodoro(){
const m=Math.floor(pomoRemaining/60).toString().padStart(2,'0'),
s=(pomoRemaining%60).toString().padStart(2,'0');
dispP.textContent=`${m}:${s}`;
cycleP.textContent=`Cycle: ${pomoCycleCount}`;
}
btnPS.addEventListener('click', ()=>{
if(pomoInterval) return;
pomoInterval=setInterval(()=>{
if(pomoRemaining>0){
pomoRemaining--; updatePomodoro();
} else {
clearInterval(pomoInterval); pomoInterval=null;
if(pomoPhase==='work'){
pomoPhase='break'; pomoRemaining=5*60;
alert('Work session done! Time for a 5-minute break.');
} else {
pomoPhase='work'; pomoRemaining=25*60; pomoCycleCount++;
alert('Break over! Back to work.');
}
updatePomodoro();
}
},1000);
});
btnPP.addEventListener('click', ()=>{
clearInterval(pomoInterval); pomoInterval=null;
});
btnPR.addEventListener('click', ()=>{
clearInterval(pomoInterval); pomoInterval=null;
pomoPhase='work'; pomoRemaining=25*60; pomoCycleCount=0; updatePomodoro();
});
updatePomodoro();
/* Keybind Capture */
const bindBtn = menu.querySelector('#keybind-btn');
bindBtn.addEventListener('click', e=>{
e.stopPropagation();
bindBtn.textContent='Press any key…';
const handler=ev=>{
ev.preventDefault();
toggleKey=ev.key; save(STORAGE.keybind,toggleKey);
bindBtn.textContent=toggleKey===' ' ? 'Space' : toggleKey;
document.removeEventListener('keydown', handler, true);
};
document.addEventListener('keydown', handler, true);
});
}
/* -------------------
8) INIT
------------------- */
function init(){
setupPaste();
buildMenu();
createScreenTimer();
}
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));
})();