Coze Better

🤖用于优化 扣子(coze)的功能体验,具体包括:⚡1. 对话中增加了导出Markdown功能(仅文本),方便用户保存和分享对话记录。⚡2. 为个人空间中的Bots添加了以用户模式启动的按钮(需先发布),方便直接使用自己的bot。⚡3. 优化了开发模式下窗口排布,使宽度可自行调节,并合并了提示词和功能配置为一列,节省界面空间。⚡4. 插件数据中的成功率和耗时数据增加彩色高亮,使其更直观的了解插件的情况。⚡5. 优化对话框输入框宽度和高度,使其更易于编辑长文本,以及其它细节调整。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Coze Better
// @name:en      Coze Better
// @name:zh      Coze Better
// @namespace    http://tampermonkey.net/
// @version      0.4.3
// @description  🤖用于优化 扣子(coze)的功能体验,具体包括:⚡1. 对话中增加了导出Markdown功能(仅文本),方便用户保存和分享对话记录。⚡2. 为个人空间中的Bots添加了以用户模式启动的按钮(需先发布),方便直接使用自己的bot。⚡3. 优化了开发模式下窗口排布,使宽度可自行调节,并合并了提示词和功能配置为一列,节省界面空间。⚡4. 插件数据中的成功率和耗时数据增加彩色高亮,使其更直观的了解插件的情况。⚡5. 优化对话框输入框宽度和高度,使其更易于编辑长文本,以及其它细节调整。
// @description:en  🤖Optimize experience for Coze, including: ⚡1. Added the export Markdown feature (text only) in the conversation. ⚡2. Added buttons to start Bots in user mode (require published). ⚡3. Optimized layout in development mode, make width adjustable, and merged prompt and configuration into one column. ⚡4. Added highlighting to success rate and time-consuming in plugin data for a more intuitive display. ⚡5. Optimized the width/height of the input box, and other detailed adjustments.
// @author       Yearly
// @match        https://www.coze.com/*
// @match        https://www.coze.cn/*
// @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzMiIGhlaWdodD0iMzMiIHZpZXdCb3g9IjAgMCAzMyAzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjNEQ1M0U4IiBkPSJNMCAwaDMzdjMzSDB6Ii8+PHBhdGggZD0iTTE2LjcgNS4xYTguNCA4LjQgMCAwIDAtOC4zIDguNFYxN0g2LjNjLTIuMyAwLTIuOCAzLjItLjYgMy45bDIuNi44djEuNWMwIDEuNSAxLjUgMi40IDIuOSAxLjhsMS40LS43aC4xYzEuMSAzLjcgNi40IDMuNyA3LjYgMGEuMS4xIDAgMCAxIC4xIDBsMS40LjdjMS4zLjYgMi45LS4zIDIuOS0xLjh2LTEuNWwyLjYtLjhjMi4xLS43IDEuNi0zLjktLjYtMy45aC0ydi0zLjVhOC40IDguNCAwIDAgMC04LjMtOC40IiBmaWxsPSIjRjlGOUY5Ii8+PC9zdmc+
// @grant        GM_addStyle
// @grant        window.onurlchange
// @license      AGPL-v3.0
// @homepage     https://greasyfork.org/zh-CN/scripts/497002-coze-better
// ==/UserScript==

(function() {

    GM_addStyle(`
    .bot-user-mode-div {
        margin: -10px 10px;
        direction: rtl;
        position: relative;
    }
    .bot-user-mode-btn {
        box-shadow: 1px 1px 3px 1px #0005;
        text-decoration: none;
    }
    .semi-button-primary.bot-need-publish-btn {
        background: #08B;
    }
    `);

    function addUserModeButtons() {
        function addButtonLoop() {
            const bots = document.querySelectorAll("#root section > section > main div.semi-spin-children > div > a[data-testid]");
            if (bots.length > 0) {
                bots.forEach(function(item) {
                    const bot_ele = item;
                    let bots_id = null;
                    let space_id = null;
                    Object.keys(bot_ele).forEach(function(attr) {
                        if (bot_ele[attr].return){
                            bots_id = bot_ele[attr].return.key
                        }
                    })
                    const sp_match = location.href.match(/\/space\/(\d+)\/bot/);
                    if (sp_match && sp_match[1]) {
                        space_id = sp_match[1];
                    }

                    if (!bots_id || !space_id || item.querySelector("div.bot-user-mode-div")) return;

                    if(item.href == null || item.href == '') {
                        item.href = `/space/${space_id}/bot/${bots_id}`;
                    }
                    item.target = "_blank";

                    const editLink = item.href;
                    const btnUser = document.createElement('div');
                    btnUser.className = "bot-user-mode-div";
                    item.append(btnUser);

                    if (item.querySelector("svg.icon-icon.coz-fg-hglt-green")) {
                        const userLink = editLink.replace(/\/space\/(.*)(\/bot\/.*)/, "/store$2?bot_id=true&space=$1");
                        btnUser.innerHTML = `<a class="semi-button semi-button-primary bot-user-mode-btn" href="${userLink}" target="_blank">Open in User Mode</a>`;
                    } else {
                        const publLink = editLink + "/publish";
                        btnUser.innerHTML = `<a class="semi-button semi-button-primary bot-user-mode-btn bot-need-publish-btn" href="${publLink}" target="_blank">Publish</a>`;
                    }

                    const disabledDiv = item.querySelector("div.PXJ4853Z3IeA21PJ0ygy  > div > div.q_zCj8QLjekm7_4bnIZU > div:first-child");
                    if (disabledDiv && disabledDiv.textContent === 'Disabled') {
                        btnUser.innerHTML = `<a class="semi-button bot-user-mode-btn semi-button-secondary-disabled" style="cursor:not-allowed; color:#666;" href="none" >Disabled</a>`;
                    }

                    item.addEventListener('click', function(event) {
                        event.stopPropagation();
                    });
                });
                setTimeout(addButtonLoop, 1000);
            } else {
                setTimeout(addButtonLoop, 800);
            }
        }
        addButtonLoop();
    }

    function exportMarkdown() {
        function convertToMarkdown(html) {
            let markdown = html
            .replace(/<b>(.*?)<\/b>/gi, '**$1**')
            .replace(/<i>(.*?)<\/i>/gi, '*$1*')
            .replace(/<strong>(.*?)<\/strong>/gi, '**$1**')
            .replace(/<em>(.*?)<\/em>/gi, '*$1*')
            .replace(/<h1.*?>(.*?)<\/h1>/gi, '# $1\n')
            .replace(/<h2.*?>(.*?)<\/h2>/gi, '## $1\n')
            .replace(/<h3.*?>(.*?)<\/h3>/gi, '### $1\n')
            .replace(/<h4.*?>(.*?)<\/h3>/gi, '#### $1\n')
            .replace(/<h5.*?>(.*?)<\/h3>/gi, '##### $1\n')
            .replace(/<p>(.*?)<\/p>/gi, '$1\n\n')
            .replace(/<br\s*\/?>/gi, '\n')
            .replace(/<a href="(.*?)">(.*?)<\/a>/gi, '[$2]($1)')
            .replace(/<code>(.*?)<\/code>/gi, '`$1`');

            const parser = new DOMParser();
            const doc = parser.parseFromString(markdown, 'text/html');

            function countParents(node) {
                let depth = 0;
                while (node.parentNode) {
                    node = node.parentNode;
                    if (node.tagName && (node.tagName.toUpperCase() === 'UL' || node.tagName.toUpperCase() === 'OL')) {
                        depth++;
                    }
                }
                return depth;
            }

            function processList(element) {
                let md = '';
                const depth = countParents(element);
                let index = element.tagName.toUpperCase() === 'OL' ? 1 : null;

                element.childNodes.forEach(node => {
                    if (node.tagName && node.tagName.toLowerCase() === 'li') {
                        if (index != null) {
                            md += '<span> </span>'.repeat(depth*2) + `${index++}\. ${node.textContent.trim()}\n`;
                        } else {
                            md += '<span> </span>'.repeat(depth*2) + `- ${node.textContent.trim()}\n`;
                        }
                    }
                });
                return md;
            }

            Array.from(doc.querySelectorAll('ol, ul')).reverse().forEach(list => {
                list.outerHTML = processList(list);
            });

            doc.querySelectorAll("div.chat-uikit-multi-modal-file-image-content").forEach(multifile => {
                multifile.innerHTML = multifile.innerHTML.replace(/<span class="chat-uikit-file-card__info__size">(.*?)<\/span>/gi, '\n$1');
                multifile.innerHTML = `\n\`\`\`file\n${multifile.textContent}\n\`\`\`\n`;
            });

            doc.querySelectorAll("div[class^=code-block] > div[class^=code-area]").forEach(codearea => {
                const header = codearea.querySelector("div[class^=header] > div[class^=text]");
                const language = header.textContent;
                header.remove();
                codearea.outerHTML = `\n\`\`\`${language}\n${codearea.textContent}\n\`\`\`\n`;
            });

            return (doc.body.innerText || doc.body.textContent) //.replaceAll(":", "\\:");
        }

        function GetDialogContent() {
            const chats = document.querySelectorAll('div[data-scroll-element="scrollable"] div.chat-uikit-message-box-container__message__message-box div.chat-uikit-message-box-container__message__message-box__content');
            let markdownContent = '';

            Array.from(chats).reverse().forEach(chat => {
                const htmlContent = chat.innerHTML;
                const chatMarkdown = convertToMarkdown(htmlContent);
                const isAsk = chat.querySelector("div.chat-uikit-message-box-inner--primary");
                if (isAsk) {
                    markdownContent += "\n******\n## Ask: \n"+ chatMarkdown + '\n\n';
                } else {
                    markdownContent += "## Anser: \n"+ chatMarkdown + '\n\n';
                }
            });

            return markdownContent;
        }

        const succ_svg = `<svg width="32" height="32" viewBox="0 0 24 24" data-name="Flat Line" xmlns="http://www.w3.org/2000/svg" class="icon flat-line"><rect x="3" y="3" width="14" height="14" rx="1" style="fill:#2ca9bc;stroke-width:2"/><path style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2" d="m7 9.63 2.25 2.25L13 8.13"/><rect data-name="primary" x="3" y="3" width="14" height="14" rx="1" style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2"/><path data-name="primary" d="M7 21h13a1 1 0 0 0 1-1V5" style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2"/></svg>`
        const svgDataUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(succ_svg);

        function CopyDialogContent(){
            const mdContent = GetDialogContent();
            navigator.clipboard.writeText(mdContent).then(() => {
                this.style.cursor = 'url(' + svgDataUrl + '), auto';
                setTimeout(() => {
                    this.style.cursor = 'pointer';
                }, 500);
            }).catch(err => {
                console.error('Could not copy text: ', err);
            });
        }

        function ExportDialogContent() {
            let fileContent = GetDialogContent();

            let blob = new Blob([fileContent], {type: 'text/plain;charset=utf-8'});
            let fileUrl = URL.createObjectURL(blob);
            let tempLink = document.createElement('a');
            tempLink.href = fileUrl;

            let fileTitle = document.title + "_DialogExport.md";
            tempLink.setAttribute('download', fileTitle);
            tempLink.style.display = 'none';
            document.body.appendChild(tempLink);
            tempLink.click();
            document.body.removeChild(tempLink);
            URL.revokeObjectURL(fileUrl);
        }

        function MDaddBtnLoop() {
            if( document.querySelector("#copy_dialog_to_md_button") == null ) {

                var lhead = document.querySelector("div[class*=semi-col]:last-child > div[class*=semi-space]") ||
                    document.querySelector("div.flex.items-center.gap-5.h-6") ||
                    document.querySelector("div.sidesheet-container > :last-child .semi-sidesheet-body > div > div > div >div > div:last-child> div:last-child")||
                    document.querySelector("div.sidesheet-container > :last-child > :first-child > :first-child > :first-child > :last-child");

                const md_icon = `
                <svg xmlns="http://www.w3.org/2000/svg" style="height:15px; fill:#fff; display:inline;" viewBox="0 0 800 512">
                    <path d="M593.8 59.1H46.2C20.7 59.1 0 79.8 0 105.2v301.5c0 25.5 20.7 46.2 46.2 46.2h547.7c25.5 0 46.2-20.7 46.1-46.1V105.2c0-25.4-20.7-46.1-46.2-46.1zM338.5 360.6H277v-120l-61.5 76.9-61.5-76.9v120H92.3V151.4h61.5l61.5 76.9 61.5-76.9h61.5v209.2zm135.3 3.1L381.5 256H443V151.4h61.5V256H566z"/>
                </svg>`;

                if (lhead) {
                    var btn_cp = document.createElement('button');
                    lhead.insertBefore(btn_cp, lhead.firstChild);
                    btn_cp.className ="semi-button semi-button-primary";
                    btn_cp.id = 'copy_dialog_to_md_button';
                    btn_cp.onclick = CopyDialogContent;
                    btn_cp.style = "margin: 0px 5px;";
                    btn_cp.innerHTML = md_icon + 'Copy';

                    var btn_dl = document.createElement('button');
                    lhead.insertBefore(btn_dl, lhead.firstChild);
                    btn_dl.className ="semi-button semi-button-primary";
                    btn_dl.id = 'export_dialog_to_md_button';
                    btn_dl.onclick = ExportDialogContent;
                    btn_dl.style = "margin: 0px 5px;";
                    btn_dl.innerHTML = md_icon + 'Export';

                    setTimeout(MDaddBtnLoop, 5000);
                }
            }
            setTimeout(MDaddBtnLoop, 2000);
        }

        function CheckPublish() {
            if (/bot_id=true.*?space=(\d+)/.test(location.href)) {
                let not_exist = document.querySelector("div.semi-empty.semi-empty-vertical");
                if (not_exist) {
                    let warn_info = not_exist.querySelector("div.semi-empty-content > h4");

                    if (warn_info && !warn_info.querySelector("hr")) {
                        console.log("warnning=");
                        warn_info.textContent = warn_info.textContent.replace("not exist", "not exist or need update")
                            .replace("不存在", "不存在或需要更新发布");
                        warn_info.innerHTML += "<hr><p style='font-size:large;'>Please publish first to open in user mode!</p>";
                    }

                    let back_div = not_exist.querySelector('div.semi-empty-footer[x-semi-prop="children"] button.semi-button')

                    if (back_div && !not_exist.querySelector("div.semi-empty-footer[x-semi-prop='children'] a[href]")) {
                        const publHref = location.href.replace(/\/store\/bot\/(\d+).*?space=(\d+)/, "/space/$2/bot/$1/publish");
                        const deveHref = location.href.replace(/\/store\/bot\/(\d+).*?space=(\d+)/, "/space/$2/bot/$1");
                        back_div.insertAdjacentHTML('beforebegin', `
                        <a class="semi-button semi-button-primary" href="${publHref}" style="text-decoration:none; margin:0 18px; width:100px;">Publish</a>
                         `);
                        back_div.insertAdjacentHTML('afterend', `
                        <a class="semi-button semi-button-primary" href="${deveHref}" style="text-decoration:none; margin:0 18px; width:100px;">Develop</a>
                         `);
                        back_div.classList.remove("semi-button-primary");
                    }
                } else {
                    setTimeout(CheckPublish, 350);
                }
            }
        }

        CheckPublish();

        MDaddBtnLoop();
    }

    function colorfulPluginsTotal() {
        function convert2ms(timeStr) {
            const value = parseFloat(timeStr);
            return timeStr.endsWith('ms') ? value : value * 1000;
        }
        function xK2number(numStr) {
            let value = parseFloat(numStr);
            if (/[\d\.]+K/.test(numStr)) {
                value = value * 1024;
            } else if (/[\d\.]+M/.test(numStr)) {
                value = value * 1024 * 1024;
            }
            return parseInt(value);
        }

        const plugins = document.querySelectorAll("#semi-modal-body div.flex.justify-between > div:last-child");

        if (plugins.length > 0) {
            if (!document.querySelector("#semi-modal-body > style.qwertyuiop")) {
                let modalCss = document.createElement("style");
                modalCss.className = "qwertyuiop";
                modalCss.innerHTML =
                    `#semi-modal-body div.flex.justify-between > div:last-child > div::after {
                        display: none;
                     }
                     #semi-modal-body div.flex.justify-between > div:last-child > div {
                        border-radius: 5px;
                        padding: 0px 5px;
                        background-color: #EEE;
                        min-width: 70px;
                        justify-content: space-evenly;
                     }`;
                document.querySelector("#semi-modal-body").append(modalCss);
            }

            plugins.forEach(function(plugin) {
                if(plugin.style.color !== `#000`) {
                    plugin.style.color = `#000`;
                    let hue = 180;

                    const botsUsed = plugin.querySelector("div:nth-child(1)");
                    hue = xK2number(botsUsed.innerText).toString(4).length*10;
                    botsUsed.style.backgroundColor = `hsl(${hue}, 50%, 60%)`;

                    const InvoCnts = plugin.querySelector("div:nth-child(2)");
                    hue = xK2number(InvoCnts.innerText).toString(4).length*10;
                    InvoCnts.style.backgroundColor = `hsl(${hue}, 50%, 60%)`;

                    const timeAver = plugin.querySelector("div:nth-child(3)");
                    hue = Math.min(10000, convert2ms(timeAver.innerText));
                    hue = 140 - hue / 10000 * 120;
                    timeAver.style.backgroundColor = `hsl(${hue}, 50%, 60%)`;

                    const succRate = plugin.querySelector("div:nth-child(4)");
                    hue = Math.max(10, parseInt(succRate.innerText)) * 1.3 - 10;
                    succRate.style.backgroundColor = `hsl(${hue}, 50%, 60%)`;
                }
            });
        }
        setTimeout(colorfulPluginsTotal, 1800);
    }

    var win_resize_addEventListener=0;

    function resizeDialogInputDiv() {

        function heigherTextarea() {
            const tArea = event.target;
            if(tArea.scrollHeight > 120) {
                const scroll = tArea.scrollTop;
                tArea.style.height = "auto"
                tArea.style.height = ((tArea.scrollHeight < 600) ? tArea.scrollHeight : 600) + "px";
                tArea.style.maxHeight = "40vh";
                tArea.scrollTop = scroll;
            }
        }

        const inputTextarea = document.querySelector("textarea[data-testid*='chat_input']");
        if (inputTextarea) {
            if (inputTextarea.closest("div[style='width: 640px;']")) {
                inputTextarea.closest("div[style='width: 640px;']").style.width = 'calc(100% - 44px)';
            }
            inputTextarea.addEventListener('input', heigherTextarea);

        } else {
            setTimeout(resizeDialogInputDiv, 700);
        }

        if(win_resize_addEventListener ==0){
            window.addEventListener('resize', function() {
                resizeDialogInputDiv();
            });
            win_resize_addEventListener = 1;
        }

        GM_addStyle(`
            div[data-scroll-element="scrollable"]{
                scrollbar-width: thin!important;
            }
            div[data-scroll-element="scrollable"] ::-webkit-scrollbar {
                width: 8px !important;
                height: 8px !important;
            }
            div[class^=code-area_] > div[class^=content]  {
                max-height: 50vh !important;
                overflow: auto !important;
            }
            div[class^=code-area_] > div[class^=content] > pre {
                overflow: visible !important;
            }
            div[class^=code-area_] ::-webkit-scrollbar-track {
                background: #5558 !important;
            }
            div[class^=code-area_] ::-webkit-scrollbar-thumb {
                background: #9998 !important;
            }
            div[class^=code-area_] ::-webkit-scrollbar-thumb:hover {
                background: #ccc8 !important;
            }
            div[class^=code-area_] ::-webkit-scrollbar {
                width: 8px !important;
                height: 8px !important;
            }
        `);
    }

    function WiderDialog() {
        GM_addStyle(`
       div[data-scroll-element="scrollable"] > div.message-group-wrapper  >div {
         width: 95% !important;
       }
       div.w-full.h-full.flex > div:first-child {
         width: 75% !important;
       }
       div[data-scroll-element="scrollable"] .common-wrapper> div[style="width: 640px;"]{
         width: 90% !important;
       }
    `);
    }

    function DevelopUI_2Cols() {
        GM_addStyle(`
            .sidesheet-container > :first-child > :last-child {
                display: flex !important;
                flex-direction: column !important;
            }
            .sidesheet-container > :first-child > :last-child > :first-child {
                height: 30% !important;
            }
            .sidesheet-container > :first-child > :last-child > :first-child.semi-sidesheet-left {
                height: 100% !important;
            }
            .sidesheet-container > :first-child > :last-child > :first-child > :first-child {
                padding-bottom: 5px !important;
            }
            .sidesheet-container > div.IoQhh3vVUhwDTJi9EIDK > div.arQAab07X2IRwAe6dqHV > div.ZdYiacTEhcgSnacFo_ah > div > div.S6fvSlBc5DwOx925HTh1 {
                padding: 1px 0px 0px 20px;
            }
            textarea[data-testid="prompt-text-area"] {
                background: #FFFE;
            }
        `);

        function makeResizable(target) {
            console.log("makeResizable");
            const handle = document.createElement('div');
            handle.style = 'z-index:1000; position:absolute; left:0px; top:0px; bottom:0px; height:100%; width:8px; cursor:ew-resize; background:#aaa; border:3px outset;';
            handle.id = "Resizable-Handle";
            target.appendChild(handle);

            handle.addEventListener('mousedown', (evt) => {
                evt.preventDefault();
                const startX = evt.clientX;
                const startWidth = target.getBoundingClientRect().width;
                const maxWidth = target.closest('.sidesheet-container').clientWidth - 420;

                function onMouseMove(evt) {
                    let newWidth = startWidth - (evt.clientX - startX);
                    if (newWidth > maxWidth) { newWidth = maxWidth; } // limit max
                    if (newWidth < 200) { newWidth = 200; } // limit min
                    target.style.width = `${newWidth}px`;
                    const semiSideSheet = target.querySelector(".semi-sidesheet");
                    if (semiSideSheet) {
                        semiSideSheet.style.width = `${newWidth}px`;
                    }
                    const sideContainer = target.closest('.sidesheet-container');
                    if (sideContainer) {
                        const percentage = (newWidth / sideContainer.clientWidth) * 100;
                        sideContainer.style.gridTemplateColumns = `auto ${percentage}%`;
                    }
                }

                function onMouseUp() {
                    document.removeEventListener('mousemove', onMouseMove);
                    document.removeEventListener('mouseup', onMouseUp);
                    localStorage.setItem('resizable_width_percentage', (target.offsetWidth / window.innerWidth).toFixed(3));
                }

                document.addEventListener('mousemove', onMouseMove);
                document.addEventListener('mouseup', onMouseUp);
            });
        }

        function makeResizableLoop() {
            const dialogDiv = document.querySelector('div.sidesheet-container > :last-child'); // document.querySelector('div.sidesheet-container > :last-child .semi-sidesheet');
            if (dialogDiv) {
                const resizable_width_percentage = localStorage.getItem('resizable_width_percentage') || 0.5;
                const resizable_width = `${window.innerWidth * resizable_width_percentage}px`;
                dialogDiv.style.width = resizable_width;
                const semiSideSheet = dialogDiv.querySelector(".semi-sidesheet");
                if (semiSideSheet) {
                    semiSideSheet.style.width = `${resizable_width}px`;
                }
                const sideContainer = dialogDiv.closest('.sidesheet-container');
                if (sideContainer) {
                    const percentage = resizable_width_percentage * 100;
                    sideContainer.style.gridTemplateColumns = `auto ${percentage}%`;
                }
                makeResizable(dialogDiv);

                dialogDiv.querySelector("span.semi-icon").parentElement.addEventListener('click', (event) => {
                    dialogDiv.querySelector("#Resizable-Handle").style.display = "none";
                    setTimeout(function(){
                        if (semiSideSheet) {
                            dialogDiv.style.width = semiSideSheet.style.width;
                        }
                        dialogDiv.querySelector("#Resizable-Handle").style.display = "";
                    }, 150);
                });
                window.addEventListener('resize', () => {
                    const resizable_width_percentage = localStorage.getItem('resizable_width_percentage') || 0.5;
                    const newWidth = `${window.innerWidth * resizable_width_percentage}px`;
                    dialogDiv.style.width = newWidth;
                    if(dialogDiv.querySelector(".semi-sidesheet")){
                        dialogDiv.querySelector(".semi-sidesheet").style.width = newWidth;
                    }
                });
                document.documentElement.style.minWidth="768px";
                document.body.style.minWidth="768px";
            } else {
                setTimeout(makeResizableLoop, 800);
            }
        }
        makeResizableLoop();
    }

    const urlPatterns = {
        space: /https:\/\/www\.coze\.c.*\/space\/.+\/bot$/,
        bot: /https:\/\/www\.coze\.c.*\/store\/bot\/.+/,
        dev: /https:\/\/www\.coze\.c.*\/space\/.+\/bot\/.+/
    };

    let lastUrl = "";

    function checkUrlChange() {
        if (lastUrl !== location.href) {
            lastUrl = location.href;
            if (urlPatterns.space.test(location.href)) {
                console.log(">match: space_url");
                addUserModeButtons();
            } else if (urlPatterns.bot.test(location.href)) {
                console.log(">match: user_url");
                exportMarkdown();
                WiderDialog();
                resizeDialogInputDiv();
            } else if (urlPatterns.dev.test(location.href)) {
                console.log(">match: dev_url");
                DevelopUI_2Cols();
                exportMarkdown();
                resizeDialogInputDiv();
                colorfulPluginsTotal();
            }
        }
    }

    checkUrlChange();
    if (window.onurlchange === null) {
        console.log("add onurlchange");
        window.addEventListener('urlchange', (info) => checkUrlChange());
    }

})();