KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.4.62
System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
User : www ( 80)
PHP Version : 8.3.8
Disable Function : NONE
Directory :  /domains/drsuper/CalculusMechanics/images/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /domains/drsuper/CalculusMechanics/images/calc-popup.js_old
/* ===== DrSuper Popup Calculator (Injects UI Automatically) ===== */
document.addEventListener("DOMContentLoaded", () => {
  // Prevent duplicates if included twice
  if (document.getElementById("calcFab") || document.getElementById("calcOverlay")) return;

  // --- Inject HTML ---
  const wrapper = document.createElement("div");
  wrapper.innerHTML = `
    <button id="calcFab" type="button" aria-label="Open calculator">🧮</button>

    <div id="calcOverlay" class="calc-overlay" role="dialog" aria-modal="true" aria-labelledby="calcTitle">
      <div class="calc-modal" role="document">
        <div class="calc-header">
          <div>
            <div id="calcTitle" class="calc-title">Calculator</div>
            <div class="calc-sub">Esc to close • Enter to =</div>
          </div>
          <button id="calcClose" type="button" class="calc-x" aria-label="Close">✕</button>
        </div>

        <input id="calcDisplay" class="calc-display" inputmode="decimal" autocomplete="off"
               placeholder="Type: (3+2)*5  or  sin(0.5)" />

        <div class="calc-grid" aria-label="Calculator buttons">
          <!-- Row 1 -->
          <button class="cb" type="button" data-a="7">7</button>
          <button class="cb" type="button" data-a="8">8</button>
          <button class="cb" type="button" data-a="9">9</button>
          <button class="cb op" type="button" data-a="/">÷</button>
          <button class="cb fn" type="button" data-a="(">(</button>
          <button class="cb fn" type="button" data-a=")">)</button>

          <!-- Row 2 -->
          <button class="cb" type="button" data-a="4">4</button>
          <button class="cb" type="button" data-a="5">5</button>
          <button class="cb" type="button" data-a="6">6</button>
          <button class="cb op" type="button" data-a="*">×</button>
          <button class="cb fn" type="button" data-a="^">^</button>
          <button class="cb fn" type="button" data-a="pi">Ï€</button>

          <!-- Row 3 -->
          <button class="cb" type="button" data-a="1">1</button>
          <button class="cb" type="button" data-a="2">2</button>
          <button class="cb" type="button" data-a="3">3</button>
          <button class="cb op" type="button" data-a="-">−</button>
          <button class="cb fn" type="button" data-a="sqrt(">√</button>
          <button class="cb fn" type="button" data-a="abs(">abs</button>

          <!-- Row 4 -->
          <button class="cb" type="button" data-a="0">0</button>
          <button class="cb" type="button" data-a=".">.</button>
          <button class="cb fn" type="button" data-a="%">%</button>
          <button class="cb op" type="button" data-a="+">+</button>
          <button class="cb danger" type="button" data-a="back">⌫</button>
          <button class="cb danger" type="button" data-a="clear">C</button>

          <!-- Row 5 -->
          <button class="cb fn" type="button" data-a="sin(">sin</button>
          <button class="cb fn" type="button" data-a="cos(">cos</button>
          <button class="cb fn" type="button" data-a="tan(">tan</button>
          <button class="cb fn" type="button" data-a="ln(">ln</button>
          <button class="cb fn" type="button" data-a="log10(">log</button>
          <button class="cb eq" type="button" data-a="=">=</button>
        </div>

        <div class="calc-footer">
          <button id="calcCopy" type="button" class="calc-copy">Copy result</button>
          <span id="calcMsg" class="calc-msg" aria-live="polite"></span>
        </div>
      </div>
    </div>
  `;
  document.body.appendChild(wrapper);

  // --- Wire up behavior ---
  const fab = document.getElementById("calcFab");
  const overlay = document.getElementById("calcOverlay");
  const closeBtn = document.getElementById("calcClose");
  const display = document.getElementById("calcDisplay");
  const copyBtn = document.getElementById("calcCopy");
  const msg = document.getElementById("calcMsg");

  const showMsg = (t) => { msg.textContent = t; setTimeout(() => (msg.textContent = ""), 1400); };

  const setOpen = (open) => {
    overlay.classList.toggle("is-open", !!open);
    if (open) setTimeout(() => display.focus(), 0);
  };
  const toggleOpen = () => setOpen(!overlay.classList.contains("is-open"));

  // Safe-ish evaluator (allowlist + token mapping)
  function evaluateExpr(input){
    let s = (input || "").trim();
    if (!s) return "";

    // Normalize symbols
    s = s.replaceAll("×","*").replaceAll("÷","/").replaceAll("−","-");

    // Allowlist characters (no quotes, no brackets, no semicolons, etc.)
    if (!/^[0-9+\-*/().,^% \tA-Za-z]+$/.test(s)) {
      throw new Error("Invalid characters");
    }

    // Map tokens
    s = s
      .replace(/\bpi\b/gi, "Math.PI")
      .replace(/\be\b/g, "Math.E")
      .replace(/\^/g, "**")
      .replace(/\babs\s*\(/gi, "Math.abs(")
      .replace(/\bsqrt\s*\(/gi, "Math.sqrt(")
      .replace(/\bsin\s*\(/gi, "Math.sin(")
      .replace(/\bcos\s*\(/gi, "Math.cos(")
      .replace(/\btan\s*\(/gi, "Math.tan(")
      .replace(/\bln\s*\(/gi, "Math.log(")
      .replace(/\blog10\s*\(/gi, "Math.log10(");

    // percent: 50% -> (50/100)
    s = s.replace(/(\d+(?:\.\d+)?)\s*%/g, "($1/100)");

    const f = new Function(`"use strict"; return (${s});`);
    const result = f();
    if (typeof result !== "number" || !isFinite(result)) throw new Error("Bad result");
    return result;
  }

  function doEquals(){
    try{
      const r = evaluateExpr(display.value);
      if (r === "") return;
      display.value = String(r);
      showMsg("OK");
    } catch (e){
      showMsg("Error");
    }
  }

  // Events
  fab.addEventListener("click", toggleOpen);
  closeBtn.addEventListener("click", () => setOpen(false));

  // Persistent: NO outside-click close

  document.addEventListener("keydown", (e) => {
    if (!overlay.classList.contains("is-open")) return;

    if (e.key === "Escape") setOpen(false);
    if (e.key === "Enter") { e.preventDefault(); doEquals(); }
  });

  document.querySelectorAll(".cb").forEach(btn => {
    btn.addEventListener("click", () => {
      const a = btn.getAttribute("data-a");

      if (a === "clear") { display.value = ""; display.focus(); return; }
      if (a === "back")  { display.value = display.value.slice(0, -1); display.focus(); return; }
      if (a === "=")     { doEquals(); return; }
      if (a === "pi")    { display.value += "pi"; display.focus(); return; }

      display.value += a;
      display.focus();
    });
  });

  copyBtn.addEventListener("click", async () => {
    try{
      await navigator.clipboard.writeText(display.value || "");
      showMsg("Copied");
    } catch(e){
      showMsg("Copy failed");
    }
  });

  // Start closed
  setOpen(false);
});

Anon7 - 2021