Best School Cheat

Drag OCR → send to SambaNova API → show answer in floating panel (even if OCR empty)

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Best School Cheat
// @namespace    http://tampermonkey.net/
// @version      V12
// @description  Drag OCR → send to SambaNova API → show answer in floating panel (even if OCR empty)
// @match        *://*/*
// @grant        GM_setClipboard
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js
// @require      https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js
// ==/UserScript==

/* 🔑 YOUR SAMBANOVA API KEY — paste it here */
const SN_API_KEY = "24ae777f-31a3-43ba-85a0-e10a7469581b";

/* 🌐 SambaNova API endpoint */
const SN_URL = "https://api.sambanova.ai/v1/chat/completions";

(function () {

let armed = false;
let startX, startY, box;
let zoomLevel = 2;
let promptType = "solve";

/* ---------- BUTTON ---------- */

function makeBtn(txt){
  let b = document.createElement("button");
  b.textContent = txt;
  Object.assign(b.style,{
    padding:"6px 8px",
    background:"#007bff",
    color:"#fff",
    border:"none",
    borderRadius:"6px",
    cursor:"pointer",
    fontSize:"12px"
  });
  return b;
}

/* ---------- COLLAPSE REOPEN BUTTON ---------- */

const reopenBtn = makeBtn("+");
Object.assign(reopenBtn.style,{
  position:"fixed",
  bottom:"20px",
  right:"20px",
  zIndex:999999,
  display:"none"
});
document.body.appendChild(reopenBtn);

/* ---------- CONTROL BAR ---------- */

const bar = document.createElement("div");
Object.assign(bar.style,{
  position:"fixed",
  bottom:"20px",
  right:"20px",
  zIndex:999998,
  padding:"8px",
  background:"rgba(20,20,20,0.9)",
  borderRadius:"8px",
  display:"flex",
  gap:"6px",
  alignItems:"center",
  color:"#fff",
  fontFamily:"system-ui, sans-serif",
  fontSize:"12px"
});

/* OCR BUTTON */

const ocrBtn = makeBtn("OCR-Drag");
ocrBtn.onclick = () => {
  armed = !armed;
  ocrBtn.style.background = armed ? "#28a745" : "#007bff";
};
bar.appendChild(ocrBtn);

/* PROMPT SELECT */

const select = document.createElement("select");
["solve","explain","summarize"].forEach(v=>{
  let o = document.createElement("option");
  o.value = v;
  o.textContent = v;
  select.appendChild(o);
});
select.onchange = () => promptType = select.value;
bar.appendChild(select);

/* ZOOM CONTROLS */

const zoomMinus = makeBtn("−");
const zoomPlus = makeBtn("+");
const zoomLabel = document.createElement("span");

function updateZoom(){
  zoomLabel.textContent = `Zoom:${zoomLevel}x`;
}
updateZoom();

zoomPlus.onclick = () => {
  zoomLevel = Math.min(5, zoomLevel + 0.5);
  updateZoom();
};

/* ---------- FULL COLLAPSE ---------- */

zoomMinus.onclick = () => {
  bar.style.display = "none";
  panel.style.display = "none";
  reopenBtn.style.display = "block";
};

reopenBtn.onclick = () => {
  bar.style.display = "flex";
  reopenBtn.style.display = "none";
};

bar.append(zoomMinus, zoomLabel, zoomPlus);
document.body.appendChild(bar);

/* ---------- ANSWER PANEL ---------- */

const panel = document.createElement("div");
Object.assign(panel.style,{
  position:"fixed",
  bottom:"70px",
  right:"20px",
  width:"360px",
  maxHeight:"60vh",
  background:"#111",
  color:"#eee",
  borderRadius:"10px",
  padding:"12px",
  display:"none",
  zIndex:999997,
  fontFamily:"system-ui, sans-serif",
  fontSize:"12px",
  overflow:"auto",
  boxShadow:"0 2px 10px rgba(0,0,0,0.5)"
});

const body = document.createElement("div");
body.style.whiteSpace = "pre-wrap";
panel.appendChild(body);
document.body.appendChild(panel);

function showPanel(text){
  body.textContent = text;
  panel.style.display = "block";
}

/* ---------- SCREENSHOT (lab() color fix) ---------- */

async function screenshot(rect){
  return await html2canvas(document.body,{
    x:rect.left,
    y:rect.top,
    width:rect.width,
    height:rect.height,
    scale:zoomLevel,
    onclone:(doc)=>{
      doc.querySelectorAll("[style*='lab(']").forEach(el=>{
        el.style.cssText = el.style.cssText.replace(/lab\([^)]*\)/g,"rgb(0,0,0)");
      });
    }
  });
}

/* ---------- PROMPT BUILDER ---------- */

function buildPrompt(text){
  if(promptType === "explain")
    return `Explain this clearly:\n\n${text}`;
  if(promptType === "summarize")
    return `Summarize this:\n\n${text}`;
  return `Solve this step-by-step:\n\n${text}`;
}

/* ---------- SAMBANOVA CALL ---------- */

async function askSambaNova(text){
  const prompt = buildPrompt(text);

  const res = await fetch(SN_URL, {
    method: "POST",
    headers: {
      "Authorization": "Bearer " + SN_API_KEY,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      stream: false,
      model: "ALLaM-7B-Instruct-preview",
      messages: [
        {
          role: "system",
          content: "You are a helpful assistant"
        },
        {
          role: "user",
          content: prompt
        }
      ]
    })
  });

  const data = await res.json();
  const answer =
    data?.choices?.[0]?.message?.content ||
    "[No answer returned]";

  return { prompt, answer };
}

/* ---------- DRAG ---------- */

document.addEventListener("mousedown", e => {
  if(!armed) return;

  startX = e.clientX;
  startY = e.clientY;

  box = document.createElement("div");
  Object.assign(box.style,{
    position:"fixed",
    border:"2px dashed red",
    background:"rgba(255,0,0,0.15)",
    left:startX+"px",
    top:startY+"px",
    zIndex:999996
  });

  document.body.appendChild(box);
});

document.addEventListener("mousemove", e => {
  if(!armed || !box) return;

  let w = e.clientX - startX;
  let h = e.clientY - startY;

  box.style.width = Math.abs(w) + "px";
  box.style.height = Math.abs(h) + "px";
  box.style.left = (w < 0 ? e.clientX : startX) + "px";
  box.style.top = (h < 0 ? e.clientY : startY) + "px";
});

document.addEventListener("mouseup", async () => {

  if(!armed || !box) return;

  const rect = box.getBoundingClientRect();
  box.remove();
  box = null;
  armed = false;
  ocrBtn.style.background = "#007bff";

  try{

    /* ---------- OCR ---------- */

    const canvas = await screenshot(rect);
    const img = canvas.toDataURL("image/png");

    const result = await Tesseract.recognize(img,"eng",{logger:()=>{}});
    let text = (result.data.text || "").trim();

    if(!text){
      text = "[No OCR text found – sending anyway]";
    }

    showPanel(
`⏳ OCR done. Sending to SambaNova...

--- OCR TEXT ---
${text}`
    );

    /* ---------- SAMBANOVA ---------- */

    const { prompt, answer } = await askSambaNova(text);

    GM_setClipboard(prompt);

    showPanel(
`✅ OCR Copied
✅ Prompt Copied
✅ SambaNova Answer Received

--- OCR TEXT ---
${text}

--- PROMPT SENT TO SAMBANOVA ---
${prompt}

--- SAMBANOVA ANSWER ---
${answer}`
    );

  } catch(err){
    showPanel("[ERROR] " + String(err));
  }

});

})();