text injector

24/5/2023, 19:07:21

// ==UserScript==
// @name        text injector
// @namespace   Violentmonkey Scripts
// @match       https://beta.character.ai/*
// @grant       none
// @version     1.20
// @author      -
// @description 24/5/2023, 19:07:21
// @license MIT
// ==/UserScript==
const originalFetch = window.fetch;
let customPrepend = ""
function createPrependWindow() {
    //create a floating div which can be resized, dragged, minimized, and closed (like a window) to change the custom prepend
    let customPrependDiv = document.createElement("div")
    customPrependDiv.style.position = "fixed"
    customPrependDiv.style.top = "0px"
    customPrependDiv.style.left = "0px"
    customPrependDiv.style.width = "235px"
    customPrependDiv.style.height = "200px"
    customPrependDiv.style.backgroundColor = "white"
    customPrependDiv.style.border = "1px solid black"
    customPrependDiv.style.zIndex
    customPrependDiv.style.resize = "both"
    customPrependDiv.style.overflow = "auto"
    customPrependDiv.style.display = "none"
    customPrependDiv.style.padding = "5px"
    customPrependDiv.style.fontFamily = "monospace"
    customPrependDiv.style.fontSize = "12px"
    customPrependDiv.style.userSelect = "none"
    customPrependDiv.style.cursor = "move"
    customPrependDiv.style.boxShadow = "0px 0px 10px 0px rgba(0,0,0,0.75)"
    customPrependDiv.style.borderRadius = "5px"
    customPrependDiv.style.transition = "height 0.2s ease-in-out"
    customPrependDiv.style.zIndex = 213098123

    let customPrependDivHeader = document.createElement("div")
    customPrependDivHeader.style.width = "100%"
    customPrependDivHeader.style.height = "20px"
    customPrependDivHeader.style.backgroundColor = "lightgray"
    customPrependDivHeader.style.borderBottom = "1px solid black"
    customPrependDivHeader.style.borderTopLeftRadius = "5px"
    customPrependDivHeader.style.borderTopRightRadius = "5px"
    customPrependDivHeader.style.userSelect = "none"
    customPrependDivHeader.style.cursor = "move"
    customPrependDivHeader.style.display = "flex"
    customPrependDivHeader.style.alignItems = "center"
    customPrependDivHeader.style.justifyContent = "center"

    let customPrependDivHeaderText = document.createElement("span")
    customPrependDivHeaderText.innerText = "Custom Prepend"
    customPrependDivHeaderText.style.fontWeight = "bold"
    customPrependDivHeaderText.style.fontSize = "14px"

    let customPrependDivCloseButton = document.createElement("button")
    customPrependDivCloseButton.innerText = "X"
    customPrependDivCloseButton.style.position = "absolute"
    customPrependDivCloseButton.style.right = "5px"
    customPrependDivCloseButton.style.top = "5px"
    customPrependDivCloseButton.style.width = "20px"
    customPrependDivCloseButton.style.height = "20px"
    customPrependDivCloseButton.style.backgroundColor = "transparent"
    customPrependDivCloseButton.style.border = "none"
    customPrependDivCloseButton.style.outline = "none"
    customPrependDivCloseButton.style.cursor = "pointer"
    customPrependDivCloseButton.style.userSelect = "none"
    customPrependDivCloseButton.style.fontWeight = "bold"
    customPrependDivCloseButton.style.fontSize = "14px"
    customPrependDivCloseButton.style.transition = "height 0.2s ease-in-out"

    let customPrependDivMinimizeButton = document.createElement("button")
    customPrependDivMinimizeButton.innerText = "-"
    customPrependDivMinimizeButton.style.position = "absolute"
    customPrependDivMinimizeButton.style.right = "30px"
    customPrependDivMinimizeButton.style.top = "5px"
    customPrependDivMinimizeButton.style.width = "20px"
    customPrependDivMinimizeButton.style.height = "20px"
    customPrependDivMinimizeButton.style.backgroundColor = "transparent"
    customPrependDivMinimizeButton.style.border = "none"
    customPrependDivMinimizeButton.style.outline = "none"
    customPrependDivMinimizeButton.style.cursor = "pointer"
    customPrependDivMinimizeButton.style.userSelect = "none"
    customPrependDivMinimizeButton.style.fontWeight = "bold"
    customPrependDivMinimizeButton.style.fontSize = "14px"
    customPrependDivMinimizeButton.style.transition = "height 0.2s ease-in-out"

    let customPrependDivContent = document.createElement("div")
    customPrependDivContent.style.width = "100%"
    customPrependDivContent.style.height = "100%"
    customPrependDivContent.style.padding = "5px"
    customPrependDivContent.style.boxSizing = "border-box"

    let customPrependDivTextarea = document.createElement("textarea")
    customPrependDivTextarea.style.width = "100%"
    customPrependDivTextarea.style.height = "100%"
    customPrependDivTextarea.style.resize = "none"
    customPrependDivTextarea.style.outline = "none"
    customPrependDivTextarea.style.border = "none"
    customPrependDivTextarea.style.fontFamily = "monospace"
    customPrependDivTextarea.style.fontSize = "12px"
    customPrependDivTextarea.style.userSelect = "none"
    customPrependDivTextarea.style.cursor = "text"
    customPrependDivTextarea.style.boxShadow = "none"
    customPrependDivTextarea.style.borderRadius = "0px"
    customPrependDivTextarea.style.transition = "height 0.2s ease-in-out"

    customPrependDivHeader.appendChild(customPrependDivHeaderText)
    customPrependDivHeader.appendChild(customPrependDivCloseButton)
    customPrependDivHeader.appendChild(customPrependDivMinimizeButton)
    customPrependDivContent.appendChild(customPrependDivTextarea)
    customPrependDiv.appendChild(customPrependDivHeader)
    customPrependDiv.appendChild(customPrependDivContent)
    document.body.appendChild(customPrependDiv)

    //create a buttton in the top left corner of the screen to open the custom prepend div, with a little animation and margin
    let customPrependDivOpenButton = document.createElement("button")
    customPrependDivOpenButton.innerText = "Custom Prepend"
    customPrependDivOpenButton.style.position = "fixed"
    customPrependDivOpenButton.style.top = "5px"
    customPrependDivOpenButton.style.left = "5px"
    customPrependDivOpenButton.style.border = "1px solid black"
    customPrependDivOpenButton.style.outline = "none"
    customPrependDivOpenButton.style.cursor = "pointer"
    customPrependDivOpenButton.style.userSelect = "none"
    customPrependDivOpenButton.style.fontWeight = "bold"
    customPrependDivOpenButton.style.fontSize = "12px"
    customPrependDivOpenButton.style.transition = "backgroundColor 0.2s ease-in-out"
    customPrependDivOpenButton.style.zIndex = 213098123

    document.body.appendChild(customPrependDivOpenButton)

    customPrependDivOpenButton.addEventListener("click", function () {
        if (customPrependDiv.style.display == "none") {
            customPrependDiv.style.display = "block"
            customPrependDivOpenButton.style.backgroundColor = "lightgray"
            customPrependDiv.style.top = "80px"
        } else {
            customPrependDiv.style.display = "none"
            customPrependDivOpenButton.style.backgroundColor = "transparent"
        }
    })

    customPrependDivCloseButton.addEventListener("click", function () {
        customPrependDiv.style.display = "none"
        customPrependDivOpenButton.style.backgroundColor = "transparent"
    })

    customPrependDivMinimizeButton.addEventListener("click", function () {
        if (customPrependDivMinimizeButton.innerText == "-") {
            customPrependDiv.style.height = "30px"
            customPrependDivMinimizeButton.innerText = "+"
        } else {
            customPrependDiv.style.height = "200px"
            customPrependDivMinimizeButton.innerText = "-"
        }
    })

    //remove transition while being resized
    customPrependDiv.addEventListener("mousedown", function () {
        customPrependDiv.style.transition = "none"
    })
    customPrependDiv.addEventListener("mouseup", function () {
        customPrependDiv.style.transition = "height 0.2s ease-in-out"
    })

    customPrependDivHeader.addEventListener("mousedown", function (e) {
        e.preventDefault()
        let x = e.clientX
        let y = e.clientY
        let top = customPrependDiv.offsetTop
        let left = customPrependDiv.offsetLeft
        console.log("mousedown triggered")
        document.addEventListener("mousemove", drag)
        document.addEventListener("mouseup", stopDrag)
        function drag(e) {
            let newX = e.clientX
            let newY = e.clientY
            let newTop = newY - (y - top)
            let newLeft = newX - (x - left)
            customPrependDiv.style.top = newTop + "px"
            customPrependDiv.style.left = newLeft + "px"
        }
        function stopDrag() {
            document.removeEventListener("mousemove", drag)
            document.removeEventListener("mouseup", stopDrag)
        }
    })

    customPrependDivTextarea.addEventListener("input", function () {
        customPrepend = customPrependDivTextarea.value
    })
}
/**
 * Creates a floating readonly textarea that can be dragged around the screen and resized hidden like the custom prepend div and closed, as well as having a button to open it like the custom prepend div
 */
function createResponsePreviewWindow() {
    let responsePreviewDiv = document.createElement("div")
    responsePreviewDiv.style.position = "fixed"
    responsePreviewDiv.style.top = "0px"
    responsePreviewDiv.style.left = "0px"
    responsePreviewDiv.style.width = "235px"
    responsePreviewDiv.style.height = "200px"
    responsePreviewDiv.style.backgroundColor = "white"
    responsePreviewDiv.style.border = "1px solid black"
    responsePreviewDiv.style.zIndex
    responsePreviewDiv.style.resize = "both"
    responsePreviewDiv.style.overflow = "auto"
    responsePreviewDiv.style.display = "none"
    responsePreviewDiv.style.padding = "5px"
    responsePreviewDiv.style.fontFamily = "monospace"
    responsePreviewDiv.style.fontSize = "12px"
    responsePreviewDiv.style.userSelect = "none"
    responsePreviewDiv.style.cursor = "move"
    responsePreviewDiv.style.boxShadow = "0px 0px 10px 0px rgba(0,0,0,0.75)"
    responsePreviewDiv.style.borderRadius = "5px"
    responsePreviewDiv.style.transition = "height 0.2s ease-in-out"
    responsePreviewDiv.style.zIndex = 213098123

    let responsePreviewDivHeader = document.createElement("div")
    responsePreviewDivHeader.style.width = "100%"
    responsePreviewDivHeader.style.height = "20px"
    responsePreviewDivHeader.style.backgroundColor = "lightgray"
    responsePreviewDivHeader.style.borderBottom = "1px solid black"
    responsePreviewDivHeader.style.borderTopLeftRadius = "5px"
    responsePreviewDivHeader.style.borderTopRightRadius = "5px"
    responsePreviewDivHeader.style.userSelect = "none"
    responsePreviewDivHeader.style.cursor = "move"
    responsePreviewDivHeader.style.display = "flex"
    responsePreviewDivHeader.style.alignItems = "center"
    responsePreviewDivHeader.style.justifyContent = "center"

    let responsePreviewDivHeaderText = document.createElement("span")
    responsePreviewDivHeaderText.innerText = "Response Preview"
    responsePreviewDivHeaderText.style.fontWeight = "bold"
    responsePreviewDivHeaderText.style.fontSize = "14px"

    let responsePreviewDivCloseButton = document.createElement("button")
    responsePreviewDivCloseButton.innerText = "X"
    responsePreviewDivCloseButton.style.position = "absolute"
    responsePreviewDivCloseButton.style.right = "5px"
    responsePreviewDivCloseButton.style.top = "5px"
    responsePreviewDivCloseButton.style.width = "20px"
    responsePreviewDivCloseButton.style.height = "20px"
    responsePreviewDivCloseButton.style.backgroundColor = "transparent"
    responsePreviewDivCloseButton.style.border = "none"
    responsePreviewDivCloseButton.style.outline = "none"
    responsePreviewDivCloseButton.style.cursor = "pointer"
    responsePreviewDivCloseButton.style.userSelect = "none"
    responsePreviewDivCloseButton.style.fontWeight = "bold"
    responsePreviewDivCloseButton.style.fontSize = "14px"
    responsePreviewDivCloseButton.style.transition = "height 0.2s ease-in-out"

    let responsePreviewDivMinimizeButton = document.createElement("button")
    responsePreviewDivMinimizeButton.innerText = "-"
    responsePreviewDivMinimizeButton.style.position = "absolute"
    responsePreviewDivMinimizeButton.style.right = "30px"
    responsePreviewDivMinimizeButton.style.top = "5px"
    responsePreviewDivMinimizeButton.style.width = "20px"
    responsePreviewDivMinimizeButton.style.height = "20px"
    responsePreviewDivMinimizeButton.style.backgroundColor = "transparent"
    responsePreviewDivMinimizeButton.style.border = "none"
    responsePreviewDivMinimizeButton.style.outline = "none"
    responsePreviewDivMinimizeButton.style.cursor = "pointer"
    responsePreviewDivMinimizeButton.style.userSelect = "none"
    responsePreviewDivMinimizeButton.style.fontWeight = "bold"
    responsePreviewDivMinimizeButton.style.fontSize = "14px"
    responsePreviewDivMinimizeButton.style.transition = "height 0.2s ease-in-out"

    let responsePreviewDivContent = document.createElement("div")
    responsePreviewDivContent.style.width = "100%"
    responsePreviewDivContent.style.height = "85%"
    responsePreviewDivContent.style.padding = "5px"
    responsePreviewDivContent.style.boxSizing = "border-box"

    //a colored bar which shows the status of the response preview, green for success, yellow for loading
    let responsePreviewStatusBar = document.createElement("div")
    responsePreviewStatusBar.style.width = "100%"
    responsePreviewStatusBar.style.height = "10px"
    responsePreviewStatusBar.style.backgroundColor = "yellow"
    responsePreviewStatusBar.style.borderRadius = "5px"
    responsePreviewStatusBar.style.transition = "height 0.2s ease-in-out"
    responsePreviewStatusBar.style.display = "none"
    responsePreviewStatusBar.style["--darkreader-inline-bgcolor"] = "#ffff00"

    let responsePreviewDivTextarea = document.createElement("textarea")
    responsePreviewDivTextarea.style.width = "100%"
    responsePreviewDivTextarea.style.height = "100%"
    responsePreviewDivTextarea.style.resize = "none"
    responsePreviewDivTextarea.style.outline = "none"
    responsePreviewDivTextarea.style.border = "none"
    responsePreviewDivTextarea.style.fontFamily = "monospace"
    responsePreviewDivTextarea.style.fontSize = "12px"
    responsePreviewDivTextarea.style.userSelect = "none"
    responsePreviewDivTextarea.style.cursor = "text"
    responsePreviewDivTextarea.style.boxShadow = "none"
    responsePreviewDivTextarea.style.borderRadius = "0px"
    responsePreviewDivTextarea.style.transition = "height 0.2s ease-in-out"
    responsePreviewDivTextarea.disabled = true
    responsePreviewDivTextarea.style.color = "white"

    responsePreviewDivHeader.appendChild(responsePreviewDivHeaderText)
    responsePreviewDivHeader.appendChild(responsePreviewDivCloseButton)
    responsePreviewDivHeader.appendChild(responsePreviewDivMinimizeButton)
    responsePreviewDivContent.appendChild(responsePreviewDivTextarea)
    responsePreviewDiv.appendChild(responsePreviewDivHeader)
    responsePreviewDiv.appendChild(responsePreviewDivContent)
    responsePreviewDiv.appendChild(responsePreviewStatusBar)
    document.body.appendChild(responsePreviewDiv)

    //create a buttton in the top left corner of the screen to open the custom prepend div, with a little animation and margin
    let responsePreviewDivOpenButton = document.createElement("button")
    responsePreviewDivOpenButton.innerText = "Response Preview"
    responsePreviewDivOpenButton.style.position = "fixed"
    responsePreviewDivOpenButton.style.top = "35px"
    responsePreviewDivOpenButton.style.left = "5px"
    responsePreviewDivOpenButton.style.border = "1px solid black"
    responsePreviewDivOpenButton.style.outline = "none"
    responsePreviewDivOpenButton.style.cursor = "pointer"
    responsePreviewDivOpenButton.style.userSelect = "none"
    responsePreviewDivOpenButton.style.fontWeight = "bold"
    responsePreviewDivOpenButton.style.fontSize = "12px"
    responsePreviewDivOpenButton.style.transition = "backgroundColor 0.2s ease-in-out"
    responsePreviewDivOpenButton.style.zIndex = 213098123

    document.body.appendChild(responsePreviewDivOpenButton)

    responsePreviewDivOpenButton.addEventListener("click", function () {
        if (responsePreviewDiv.style.display == "none") {
            responsePreviewDiv.style.display = "block"
            responsePreviewDivOpenButton.style.backgroundColor = "lightgray"
            responsePreviewDiv.style.top = "80px"
        } else {
            responsePreviewDiv.style.display = "none"
            responsePreviewDivOpenButton.style.backgroundColor = "transparent"
        }
    })

    responsePreviewDivCloseButton.addEventListener("click", function () {
        responsePreviewDiv.style.display = "none"
        responsePreviewDivOpenButton.style.backgroundColor = "transparent"
    })

    responsePreviewDivMinimizeButton.addEventListener("click", function () {
        if (responsePreviewDivMinimizeButton.innerText == "-") {
            responsePreviewDiv.style.height = "30px"
            responsePreviewDivMinimizeButton.innerText = "+"
        } else {
            responsePreviewDiv.style.height = "200px"
            responsePreviewDivMinimizeButton.innerText = "-"
        }
    })

    //remove transition while being resized
    responsePreviewDiv.addEventListener("mousedown", function () {
        responsePreviewDiv.style.transition = "none"
    })
    responsePreviewDiv.addEventListener("mouseup", function () {
        responsePreviewDiv.style.transition = "height 0.2s ease-in-out"
    })

    responsePreviewDivHeader.addEventListener("mousedown", function (e) {
        e.preventDefault()
        let x = e.clientX
        let y = e.clientY
        let top = responsePreviewDiv.offsetTop
        let left = responsePreviewDiv.offsetLeft
        console.log("mousedown triggered")
        document.addEventListener("mousemove", drag)
        document.addEventListener("mouseup", stopDrag)
        function drag(e) {
            let newX = e.clientX
            let newY = e.clientY
            let newTop = newY - (y - top)
            let newLeft = newX - (x - left)
            responsePreviewDiv.style.top = newTop + "px"
            responsePreviewDiv.style.left = newLeft + "px"
        }
        function stopDrag() {
            document.removeEventListener("mousemove", drag)
            document.removeEventListener("mouseup", stopDrag)
        }
    })
    let displayResponsePreviewStatusBar = function (boolean) {
        if (boolean) {
            responsePreviewStatusBar.style.display = "block"
            responsePreviewStatusBar.style.backgroundColor = "lightgray"
        } else {
            responsePreviewStatusBar.style.display = "none"
        }
    }
    let responsePreviewSetResponseFinished = function (boolean) {
        if (boolean) {
            responsePreviewStatusBar.style.backgroundColor = "lightgreen"
            responsePreviewStatusBar.style["--darkreader-inline-bgcolor"] = "#00ff00"
        } else {
            responsePreviewStatusBar.style.backgroundColor = "yellow"
            responsePreviewStatusBar.style["--darkreader-inline-bgcolor"] = "#ffff00"
        }
    }
    return { displayResponsePreviewStatusBar, responsePreviewSetResponseFinished, responsePreviewDivTextarea }
}

function createColorPickerWindow() {
    let colorPickerDiv = document.createElement("div")
    colorPickerDiv.style.position = "fixed"
    colorPickerDiv.style.top = "0px"
    colorPickerDiv.style.left = "0px"
    colorPickerDiv.style.width = "235px"
    colorPickerDiv.style.height = "200px"
    colorPickerDiv.style.backgroundColor = "white"
    colorPickerDiv.style.border = "1px solid black"
    colorPickerDiv.style.zIndex
    colorPickerDiv.style.resize = "both"
    colorPickerDiv.style.overflow = "auto"
    colorPickerDiv.style.display = "none"
    colorPickerDiv.style.padding = "5px"
    colorPickerDiv.style.fontFamily = "monospace"
    colorPickerDiv.style.fontSize = "12px"
    colorPickerDiv.style.userSelect = "none"
    colorPickerDiv.style.cursor = "move"
    colorPickerDiv.style.boxShadow = "0px 0px 10px 0px rgba(0,0,0,0.75)"
    colorPickerDiv.style.borderRadius = "5px"
    colorPickerDiv.style.transition = "height 0.2s ease-in-out"
    colorPickerDiv.style.zIndex = 213098123

    let colorPickerDivHeader = document.createElement("div")
    colorPickerDivHeader.style.width = "100%"
    colorPickerDivHeader.style.height = "20px"
    colorPickerDivHeader.style.backgroundColor = "lightgray"
    colorPickerDivHeader.style.borderBottom = "1px solid black"
    colorPickerDivHeader.style.borderTopLeftRadius = "5px"
    colorPickerDivHeader.style.borderTopRightRadius = "5px"
    colorPickerDivHeader.style.userSelect = "none"
    colorPickerDivHeader.style.cursor = "move"
    colorPickerDivHeader.style.display = "flex"
    colorPickerDivHeader.style.alignItems = "center"
    colorPickerDivHeader.style.justifyContent = "center"

    let colorPickerDivHeaderText = document.createElement("span")
    colorPickerDivHeaderText.innerText = "Color Picker"
    colorPickerDivHeaderText.style.fontWeight = "bold"
    colorPickerDivHeaderText.style.fontSize = "14px"

    let colorPickerDivCloseButton = document.createElement("button")
    colorPickerDivCloseButton.innerText = "X"
    colorPickerDivCloseButton.style.position = "absolute"
    colorPickerDivCloseButton.style.right = "5px"
    colorPickerDivCloseButton.style.top = "5px"
    colorPickerDivCloseButton.style.width = "20px"
    colorPickerDivCloseButton.style.height = "20px"
    colorPickerDivCloseButton.style.backgroundColor = "transparent"
    colorPickerDivCloseButton.style.border = "none"
    colorPickerDivCloseButton.style.outline = "none"
    colorPickerDivCloseButton.style.cursor = "pointer"
    colorPickerDivCloseButton.style.userSelect = "none"
    colorPickerDivCloseButton.style.fontWeight = "bold"
    colorPickerDivCloseButton.style.fontSize = "14px"
    colorPickerDivCloseButton.style.transition = "height 0.2s ease-in-out"

    let colorPickerDivMinimizeButton = document.createElement("button")
    colorPickerDivMinimizeButton.innerText = "-"
    colorPickerDivMinimizeButton.style.position = "absolute"
    colorPickerDivMinimizeButton.style.right = "30px"
    colorPickerDivMinimizeButton.style.top = "5px"
    colorPickerDivMinimizeButton.style.width = "20px"
    colorPickerDivMinimizeButton.style.height = "20px"
    colorPickerDivMinimizeButton.style.backgroundColor = "transparent"
    colorPickerDivMinimizeButton.style.border = "none"
    colorPickerDivMinimizeButton.style.outline = "none"
    colorPickerDivMinimizeButton.style.cursor = "pointer"
    colorPickerDivMinimizeButton.style.userSelect = "none"
    colorPickerDivMinimizeButton.style.fontWeight = "bold"
    colorPickerDivMinimizeButton.style.fontSize = "14px"
    colorPickerDivMinimizeButton.style.transition = "height 0.2s ease-in-out"

    let colorPickerDivContent = document.createElement("div")
    colorPickerDivContent.style.width = "100%"
    colorPickerDivContent.style.height = "85%"
    colorPickerDivContent.style.padding = "5px"
    colorPickerDivContent.style.boxSizing = "border-box"

    //pickers are to be shown one under the other, with labels on top, little margin between them
    let colorPickerDivContainer = document.createElement("div")
    colorPickerDivContainer.style.width = "100%"
    colorPickerDivContainer.style.height = "100%"
    colorPickerDivContainer.style.display = "flex"
    colorPickerDivContainer.style.flexDirection = "column"
    colorPickerDivContainer.style.alignItems = "center"
    colorPickerDivContainer.style.justifyContent = "center"
    
    //pickers are color pickers input type color, with a label on top
    let colorPickerDivColorPickerUser = document.createElement("input")
    colorPickerDivColorPickerUser.type = "color"
    colorPickerDivColorPickerUser.style.width = "100%"
    colorPickerDivColorPickerUser.style.height = "100%"
    colorPickerDivColorPickerUser.style.margin = "5px"
    colorPickerDivColorPickerUser.style.boxSizing = "border-box"
    colorPickerDivColorPickerUser.style.border = "1px solid black"
    colorPickerDivColorPickerUser.style.borderRadius = "5px"
    colorPickerDivColorPickerUser.style.outline = "none"
    colorPickerDivColorPickerUser.style.cursor = "pointer"
    colorPickerDivColorPickerUser.style.transition = "height 0.2s ease-in-out"

    //to be show on top of the picker
    let colorPickerDivColorPickerLaberUser = document.createElement("span")
    colorPickerDivColorPickerLaberUser.innerText = "User Color"
    colorPickerDivColorPickerLaberUser.style.fontWeight = "bold"
    colorPickerDivColorPickerLaberUser.style.fontSize = "14px"

    let colorPickerDivColorPickerBot = document.createElement("input")
    colorPickerDivColorPickerBot.type = "color"
    colorPickerDivColorPickerBot.style.width = "100%"
    colorPickerDivColorPickerBot.style.height = "100%"
    colorPickerDivColorPickerBot.style.margin = "5px"
    colorPickerDivColorPickerBot.style.boxSizing = "border-box"
    colorPickerDivColorPickerBot.style.border = "1px solid black"
    colorPickerDivColorPickerBot.style.borderRadius = "5px"
    colorPickerDivColorPickerBot.style.outline = "none"
    colorPickerDivColorPickerBot.style.cursor = "pointer"
    colorPickerDivColorPickerBot.style.transition = "height 0.2s ease-in-out"

    //to be show on top of the picker
    let colorPickerDivColorPickerLaberBot = document.createElement("span")
    colorPickerDivColorPickerLaberBot.innerText = "Bot Color"
    colorPickerDivColorPickerLaberBot.style.fontWeight = "bold"
    colorPickerDivColorPickerLaberBot.style.fontSize = "14px"


    colorPickerDivHeader.appendChild(colorPickerDivHeaderText)
    colorPickerDivHeader.appendChild(colorPickerDivCloseButton)
    colorPickerDivHeader.appendChild(colorPickerDivMinimizeButton)
    colorPickerDivContent.appendChild(colorPickerDivContainer)
    colorPickerDivContainer.appendChild(colorPickerDivColorPickerLaberUser)
    colorPickerDivContainer.appendChild(colorPickerDivColorPickerUser)
    colorPickerDivContainer.appendChild(colorPickerDivColorPickerLaberBot)
    colorPickerDivContainer.appendChild(colorPickerDivColorPickerBot)
    colorPickerDiv.appendChild(colorPickerDivHeader)
    colorPickerDiv.appendChild(colorPickerDivContent)
    document.body.appendChild(colorPickerDiv)

    //create a buttton in the top left corner of the screen to open the custom prepend div, with a little animation and margin
    let colorPickerDivOpenButton = document.createElement("button")
    colorPickerDivOpenButton.innerText = "Color Picker"
    colorPickerDivOpenButton.style.position = "fixed"
    colorPickerDivOpenButton.style.top = "65px"
    colorPickerDivOpenButton.style.left = "5px"
    colorPickerDivOpenButton.style.border = "1px solid black"
    colorPickerDivOpenButton.style.outline = "none"
    colorPickerDivOpenButton.style.cursor = "pointer"
    colorPickerDivOpenButton.style.userSelect = "none"
    colorPickerDivOpenButton.style.fontWeight = "bold"
    colorPickerDivOpenButton.style.fontSize = "12px"
    colorPickerDivOpenButton.style.transition = "backgroundColor 0.2s ease-in-out"
    colorPickerDivOpenButton.style.zIndex = 213098123

    document.body.appendChild(colorPickerDivOpenButton)

    colorPickerDivOpenButton.addEventListener("click", function () {
        if (colorPickerDiv.style.display == "none") {
            colorPickerDiv.style.display = "block"
            colorPickerDivOpenButton.style.backgroundColor = "lightgray"
            colorPickerDiv.style.top = "120px"
        } else {
            colorPickerDiv.style.display = "none"
            colorPickerDivOpenButton.style.backgroundColor = "transparent"
        }
    })

    colorPickerDivCloseButton.addEventListener("click", function () {
        colorPickerDiv.style.display = "none"
        colorPickerDivOpenButton.style.backgroundColor = "transparent"
    })

    colorPickerDivMinimizeButton.addEventListener("click", function () {
        if (colorPickerDivMinimizeButton.innerText == "-") {
            colorPickerDiv.style.height = "30px"
            colorPickerDivMinimizeButton.innerText = "+"
            //hide the color Picker Div Container if it is minimized
            colorPickerDivContainer.style.display = "none"

        } else {
            colorPickerDiv.style.height = "200px"
            colorPickerDivMinimizeButton.innerText = "-"
            //show the color Picker Div Container if it is maximized
            colorPickerDivContainer.style.display = "flex"
        }
    })

    //remove transition while being resized
    colorPickerDiv.addEventListener("mousedown", function () {
        colorPickerDiv.style.transition = "none"
    })
    colorPickerDiv.addEventListener("mouseup", function () {
        colorPickerDiv.style.transition = "height 0.2s ease-in-out"
    })

    colorPickerDivHeader.addEventListener("mousedown", function (e) {
        e.preventDefault()
        let x = e.clientX
        let y = e.clientY
        let top = colorPickerDiv.offsetTop
        let left = colorPickerDiv.offsetLeft
        console.log("mousedown triggered")
        document.addEventListener("mousemove", drag)
        document.addEventListener("mouseup", stopDrag)
        function drag(e) {
            let newX = e.clientX
            let newY = e.clientY
            let newTop = newY - (y - top)
            let newLeft = newX - (x - left)
            colorPickerDiv.style.top = newTop + "px"
            colorPickerDiv.style.left = newLeft + "px"
        }
        function stopDrag() {
            document.removeEventListener("mousemove", drag)
            document.removeEventListener("mouseup", stopDrag)
        }
    })

    colorPickerDivColorPickerUser.addEventListener("input", function () {
        document.querySelectorAll(".user-msg").forEach(function (msg) {
            msg.style.color = colorPickerDivColorPickerUser.value
            //dark reader fix
            msg.style["--darkreader-inline-color"] = colorPickerDivColorPickerUser.value
        })
    })
    colorPickerDivColorPickerBot.addEventListener("input", function () {
        document.querySelectorAll(".char-msg").forEach(function (msg) {
            msg.style.color = colorPickerDivColorPickerBot.value
            //dark reader fix
            msg.style["--darkreader-inline-color"] = colorPickerDivColorPickerBot.value
        })
    })

    let updateColors = function () {
        let currentUserColor = colorPickerDivColorPickerUser.value
        let currentBotColor = colorPickerDivColorPickerBot.value

        document.querySelectorAll(".user-msg").forEach(function (msg) {
            msg.style.color = currentUserColor
            //dark reader fix
            msg.style["--darkreader-inline-color"] = currentUserColor
        })
        document.querySelectorAll(".char-msg").forEach(function (msg) {
            msg.style.color = currentBotColor
            //dark reader fix
            msg.style["--darkreader-inline-color"] = currentBotColor
        })
    }

    return updateColors
}

createPrependWindow()

let { displayResponsePreviewStatusBar, responsePreviewSetResponseFinished, responsePreviewDivTextarea } = createResponsePreviewWindow()

let updateColors = createColorPickerWindow()

function processResponse(response) {
    if (response.body) {
        const reader = response.body.getReader();

        const workerURL = URL.createObjectURL(
            new Blob([`(${workerCode.toString()})()`], { type: 'application/javascript' })
        );

        const worker = new Worker(workerURL);

        worker.onmessage = event => {
            const { data } = event;
            updateColors()
            responsePreviewDivTextarea.value = data.text;
        };

        const processChunks = () => {
            reader.read().then(({ done, value }) => {
                if (done) {
                    // Terminate the web worker after sending the last message
                    worker.onmessage = event => {
                        const { data } = event;
                        updateColors()
                        responsePreviewDivTextarea.value = data.text;
                        if (data.is_final_chunk === true) {
                            responsePreviewSetResponseFinished(true)
                            worker.terminate();
                            updateColors()
                            //asyncronously wait 3 seconds and then hide the response preview div
                            setTimeout(function () {
                                displayResponsePreviewStatusBar(false)
                            }, 8000)
                        }
                    };
                    return;
                }
                // Send each chunk of data to the web worker for processing
                worker.postMessage(value);

                processChunks(); // Continue reading the next chunk of data
            }).catch(error => {
                console.log(error);
                worker.terminate(); // Terminate the web worker in case of error
            });
        };
        processChunks(); // Start reading the chunks of data
    }
}

window.fetch = function (url, options) {
    if (url == "https://beta.character.ai/chat/streaming/") {
        let optionsCopy = JSON.parse(options.body)
        optionsCopy.text = optionsCopy.text
        if (customPrepend != "") optionsCopy.text = customPrepend + "\n\n" + optionsCopy.text
        options.body = JSON.stringify(optionsCopy)
        const fetchPromise = originalFetch(url, options);

        fetchPromise.then(response => {
            const cloneResponse = response.clone(); // Create a clone of the response
            displayResponsePreviewStatusBar(true)
            responsePreviewSetResponseFinished(false)
            processResponse(cloneResponse); // Process the clone in the background
        }).catch(error => {
            console.log(error);
        });

        return fetchPromise;
    } else {
        return originalFetch(url, options);
    }
};

function workerCode() {
    self.onmessage = event => {
        const data = event.data;
        const decodedData = new TextDecoder().decode(data);
        let structuredData = { text: JSON.parse(decodedData).replies[0].text, is_final_chunk: JSON.parse(decodedData).is_final_chunk }
        self.postMessage(structuredData);
    };
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址