General Calculator

Calculator that should work on every page :p

目前為 2024-06-09 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         General Calculator
// @namespace    https://greasyfork.org/en/users/1291009
// @version      1.9.1
// @description  Calculator that should work on every page :p
// @author       BadOrBest
// @license      MIT
// @icon         https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcSITQfCUO2ak5KcOYOskQl6nrLCyC7v73kkB0eIUyu5rsErnN45
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @run-at       document-end
// ==/UserScript==
(function() {
    'use strict';

    var chatBox = document.createElement('div');
    chatBox.id = 'calculator-chat-box';
    chatBox.style.position = 'fixed';
    chatBox.style.bottom = '20px';
    chatBox.style.right = '20px';
    chatBox.style.width = 'calc(100% - 40px)'; // Adjusted to fit within the viewport
    chatBox.style.maxWidth = '300px'; // Added maximum width for responsiveness
    chatBox.style.overflowY = 'hidden';
    chatBox.style.backgroundColor = '#222';
    chatBox.style.borderRadius = '20px';
    chatBox.style.padding = '0';
    chatBox.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.1)';
    chatBox.style.zIndex = '9999';
    chatBox.style.display = 'flex'; // Flexbox layout
    chatBox.style.flexDirection = 'column'; // Column layout

// Draggable functionality
var isDragging = false;
var initialX, initialY;
var offsetX = 0;
var offsetY = 0;
var chatBox = document.getElementById('chatBox');

// Mouse events
chatBox.addEventListener('mousedown', startDragging);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDragging);

// Touch events
chatBox.addEventListener('touchstart', startDragging);
document.addEventListener('touchmove', drag);
document.addEventListener('touchend', stopDragging);

// Pen events
chatBox.addEventListener('pointerdown', startDragging);
document.addEventListener('pointermove', drag);
document.addEventListener('pointerup', stopDragging);

// Arrow key events
document.addEventListener('keydown', function(event) {
    if (isDragging) return;
    const arrowKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
    if (arrowKeys.includes(event.key)) {
        event.preventDefault();
        const step = 10;
        let currentX = offsetX;
        let currentY = offsetY;

        switch (event.key) {
            case 'ArrowUp':
                currentY -= step;
                break;
            case 'ArrowDown':
                currentY += step;
                break;
            case 'ArrowLeft':
                currentX -= step;
                break;
            case 'ArrowRight':
                currentX += step;
                break;
        }

        var maxX = window.innerWidth - chatBox.offsetWidth;
        var maxY = window.innerHeight - chatBox.offsetHeight;
        currentX = Math.max(0, Math.min(currentX, maxX));
        currentY = Math.max(0, Math.min(currentY, maxY));

        offsetX = currentX;
        offsetY = currentY;

        chatBox.style.transform = `translate(${currentX}px, ${currentY}px)`;
    }
});

function startDragging(event) {
    isDragging = true;
    if (event.type === 'mousedown' || event.type === 'pointerdown') {
        initialX = event.clientX - offsetX;
        initialY = event.clientY - offsetY;
    } else if (event.type === 'touchstart') {
        var touch = event.touches[0];
        initialX = touch.clientX - offsetX;
        initialY = touch.clientY - offsetY;
    }
}

function drag(event) {
    if (isDragging) {
        var currentX, currentY;
        if (event.type === 'mousemove' || event.type === 'pointermove') {
            currentX = event.clientX - initialX;
            currentY = event.clientY - initialY;
        } else if (event.type === 'touchmove') {
            var touch = event.touches[0];
            currentX = touch.clientX - initialX;
            currentY = touch.clientY - initialY;
        } else if (event.type === 'pointermove') {
            currentX = event.clientX - initialX;
            currentY = event.clientY - initialY;
        }

        var maxX = window.innerWidth - chatBox.offsetWidth;
        var maxY = window.innerHeight - chatBox.offsetHeight;
        currentX = Math.max(0, Math.min(currentX, maxX));
        currentY = Math.max(0, Math.min(currentY, maxY));

        offsetX = currentX;
        offsetY = currentY;

        chatBox.style.transform = `translate(${currentX}px, ${currentY}px)`;
    }
}

function stopDragging() {
    isDragging = false;
}

    // Title
    var chatTitle = document.createElement('div');
    chatTitle.style.background = '#444';
    chatTitle.style.color = 'white';
    chatTitle.style.padding = '10px';
    chatTitle.style.textAlign = 'center';
    chatTitle.style.fontWeight = 'bold';
    chatTitle.textContent = 'Calculator';
    chatBox.appendChild(chatTitle);

    // Collapse Button
    var collapseButton = document.createElement('button');
    collapseButton.textContent = '▼';
    collapseButton.style.position = 'absolute';
    collapseButton.style.top = '0';
    collapseButton.style.right = '0';
    collapseButton.style.margin = '10px';
    collapseButton.style.width = '30px';
    collapseButton.style.height = '30px';
    collapseButton.style.fontSize = '20px';
    collapseButton.style.border = 'none';
    collapseButton.style.backgroundColor = '#444';
    collapseButton.style.color = 'white';
    collapseButton.style.cursor = 'pointer';
    collapseButton.style.borderRadius = '50%';
    collapseButton.addEventListener('click', function() {
        toggleChatBox();
    });
    chatBox.appendChild(collapseButton);

    // Toggle chat box visibility
    function toggleChatBox() {
        if (chatBox.style.height === 'auto' || chatBox.style.height === '') {
            chatBox.style.height = '70px'; // Set to a fixed height
            collapseButton.textContent = '▲';
            chatInput.style.display = 'none'; // Hide the input field
        } else {
            chatBox.style.height = 'auto';
            collapseButton.textContent = '▼';
            chatInput.style.display = 'block'; // Show the input field
        }
    }

    // Chat history container
    var chatHistory = document.createElement('div');
    chatHistory.id = 'chat-history';
    chatHistory.style.height = 'calc(50vh - 110px)';
    chatHistory.style.overflowY = 'auto';
    chatHistory.style.backgroundColor = '#333';
    chatBox.appendChild(chatHistory);

    // Function to add message to conversation
    function addMessage(message, isInput) {
        var messageElement = document.createElement('div');
        messageElement.className = 'message ' + (isInput ? 'input' : 'output');
        messageElement.innerHTML = message;
        chatHistory.appendChild(messageElement);

        if (!isInput) {
            var line = document.createElement('hr');
            line.style.borderTop = '1px solid white';
            line.style.margin = '5px 0';
            chatHistory.appendChild(line);
        }

        chatHistory.scrollTop = chatHistory.scrollHeight;
    }

    // Function to evaluate and display the result
    function evaluateExpression(expression) {
        try {
            // Replace 'x' with '*' for mathematical operations
            expression = expression.replace(/(x)/g, '*');
            // Handling algebraic expressions
            var result;
            if (/\b[A-Za-z]+\b/.test(expression)) {
                // If expression contains letters
                var match = expression.match(/\b[A-Za-z]+\b/);
                var letter = match[0];
                var equation = expression.replace(/\b[A-Za-z]+\b/g, '0'); // Replace letters with '0' for evaluation
                result = solveEquation(equation, letter);
            } else {
                // If expression is purely mathematical
                result = eval(expression);
            }
            addMessage('<span class="bot-label">(Computer):</span> ' + result, false);
        } catch (error) {
            addMessage('<span class="bot-label">(Computer):</span> Error: ' + error.message, false);
        }
    }

    // Function to solve algebraic equation
    function solveEquation(equation, letter) {
        // For simplicity, let's assume linear equations of the form 'ax = b'
        var sides = equation.split('=');
        var a = eval(sides[0]);
        var b = eval(sides[1]);
        var result = b / a;
        return letter + ' = ' + result;
    }

    // Function to send message
    function sendMessage() {
        var expression = chatInput.value.trim();
        if (expression !== '') {
            addMessage('<span class="user-label">(User):</span> ' + expression, true);
            evaluateExpression(expression);
            chatInput.value = '';
        }
    }

    // Input field
    var chatInput = document.createElement('input');
    chatInput.type = 'text';
    chatInput.placeholder = 'Type here...';
    chatInput.style.width = 'calc(100% - 20px)';
    chatInput.style.padding = '10px';
    chatInput.style.margin = '10px auto'; // Centered horizontally
    chatInput.style.borderRadius = '10px';
    chatInput.style.border = 'none';
    chatInput.style.backgroundColor = '#444';
    chatInput.style.color = 'white';
    chatBox.appendChild(chatInput);

    // Listen for Enter key press to send message
    chatInput.addEventListener('keydown', function(event) {
        if (event.key === 'Enter') {
            event.preventDefault();
            sendMessage();
        }
    });

    // CSS style for user and bot messages
    var style = document.createElement('style');
    style.innerHTML = `
        .message {
            clear: both;
            padding: 5px 10px;
            color: white;
        }
        .input {
            text-align: left;
        }
        .bot-label {
            float: left;
            margin-left: 5px;
            background-color: blue;
            color: white;
            border-radius: 10px;
            padding: 3px 6px;
        }
        .user-label {
            float: left;
            margin-left: 5px;
            background-color: green;
            color: white;
            border-radius: 10px;
            padding: 3px 6px;
        }
        hr {
            border-top: 1px solid white;
            margin: 5px 0;
        }
        .chat-dragging * {
            user-select: none;
        }
    `;
    document.head.appendChild(style);

})();

// Mathematical functions
Math.sinh = function(x) { return (Math.exp(x) - Math.exp(-x)) / 2; };
Math.cosh = function(x) { return (Math.exp(x) + Math.exp(-x)) / 2; };
Math.tanh = function(x) { return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x)); };
Math.asinh = function(x) { return Math.log(x + Math.sqrt(x * x + 1)); };
Math.acosh = function(x) { return Math.log(x + Math.sqrt(x * x - 1)); };
Math.atanh = function(x) { return Math.log((1 + x) / (1 - x)) / 2; };

// Mathematical constants
var E = Math.E; // Euler's number
var PI = Math.PI; // Pi
var SQRT2 = Math.SQRT2; // Square root of 2
var SQRT1_2 = Math.SQRT1_2; // Square root of 1/2

// Additional mathematical operations
Math.factorial = function(n) {
    if (n === 0 || n === 1)
        return 1;
    for (var i = n - 1; i >= 1; i--) {
        n *= i;
    }
    return n;
};

Math.permutation = function(n, r) {
    return Math.factorial(n) / Math.factorial(n - r);
};

Math.combination = function(n, r) {
    return Math.factorial(n) / (Math.factorial(r) * Math.factorial(n - r));
};

Math.roundTo = function(value, decimalPlaces) {
    var multiplier = Math.pow(10, decimalPlaces);
    return Math.round(value * multiplier) / multiplier;
};

// Trigonometric functions
Math.degToRad = function(degrees) {
    return degrees * (Math.PI / 180);
};

Math.radToDeg = function(radians) {
    return radians * (180 / Math.PI);
};

// Logarithmic functions
Math.log10 = function(x) {
    return Math.log(x) / Math.log(10);
};

Math.log2 = function(x) {
    return Math.log(x) / Math.log(2);
};

// Exponential functions
Math.exp10 = function(x) {
    return Math.pow(10, x);
};

Math.exp2 = function(x) {
    return Math.pow(2, x);
};

// Additional mathematical functions
Math.abs = function(x) { return Math.abs(x); };
Math.ceil = function(x) { return Math.ceil(x); };
Math.floor = function(x) { return Math.floor(x); };
Math.max = function(...args) { return Math.max(...args); };
Math.min = function(...args) { return Math.min(...args); };
Math.pow = function(x, y) { return Math.pow(x, y); };
Math.sqrt = function(x) { return Math.sqrt(x); };
Math.sign = function(x) { return Math.sign(x); };
Math.randomInt = function(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; };
Math.clamp = function(x, min, max) { return Math.max(min, Math.min(max, x)); };
Math.hypot = function(...args) { return Math.hypot(...args); };

// Constants
var LN2 = Math.LN2; // Natural logarithm of 2
var LN10 = Math.LN10; // Natural logarithm of 10
var LOG2E = Math.LOG2E; // Base 2 logarithm of E
var LOG10E = Math.LOG10E; // Base 10 logarithm of E
var SQRT3 = Math.SQRT3; // Square root of 3

// Exponential constants
var EXP = Math.exp(1); // Euler's number

// Trigonometric constants
var DEG_PER_RAD = 180 / Math.PI; // Degrees per radian
var RAD_PER_DEG = Math.PI / 180; // Radians per degree
var TWO_PI = 2 * Math.PI; // 2 * Pi

// Logarithmic constants
var LN_2 = Math.LN2; // Natural logarithm of 2
var LN_10 = Math.LN10; // Natural logarithm of 10
var LOG2_E = Math.LOG2E; // Base 2 logarithm of E
var LOG10_E = Math.LOG10E; // Base 10 logarithm of E

// Exponential constants
var SQRT_2 = Math.SQRT2; // Square root of 2
var SQRT_1_2 = Math.SQRT1_2; // Square root of 1/2

// Additional mathematical operations
Math.lcm = function(a, b) { return (!a || !b) ? 0 : Math.abs((a * b) / Math.gcd(a, b)); };
Math.gcd = function(a, b) { return (!b) ? a : Math.gcd(b, a % b); };
Math.factorial = function(n) { return (n !== 1 && n !== 0) ? n * Math.factorial(n - 1) : 1; };
Math.toDegrees = function(radians) { return radians * DEG_PER_RAD; };
Math.toRadians = function(degrees) { return degrees * RAD_PER_DEG; };
Math.isPrime = function(n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 === 0 || n % 3 === 0) return false;
    let i = 5;
    while (i * i <= n) {
        if (n % i === 0 || n % (i + 2) === 0) return false;
        i += 6;
    }
    return true;
};