Gemini Pro

增强 Gemini 对话界面

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ 172:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {


// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  A: () => (/* binding */ Options)
});

// EXTERNAL MODULE: ./utils/src/gm/Store.ts
var Store = __webpack_require__(307);
;// ./utils/src/gm/MenuCmd.ts
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * 选项菜单
 */
var MenuCmd = /*#__PURE__*/function () {
  function MenuCmd() {
    _classCallCheck(this, MenuCmd);
  }
  return _createClass(MenuCmd, null, [{
    key: "register",
    value:
    /**
     * 注册
     * @param name 名称
     * @param fn 点击菜单时执行的函数
     */
    function register(name, fn) {
      return GM_registerMenuCommand(name, fn);
    }

    /**
     * 注销
     * @param menuCmdId 注册时返回的 ID
     */
  }, {
    key: "unregister",
    value: function unregister(menuCmdId) {
      GM_unregisterMenuCommand(menuCmdId);
    }
  }]);
}();

;// ./utils/src/CommonOptions.ts
function CommonOptions_typeof(o) { "@babel/helpers - typeof"; return CommonOptions_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, CommonOptions_typeof(o); }
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function CommonOptions_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function CommonOptions_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, CommonOptions_toPropertyKey(o.key), o); } }
function CommonOptions_createClass(e, r, t) { return r && CommonOptions_defineProperties(e.prototype, r), t && CommonOptions_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function CommonOptions_toPropertyKey(t) { var i = CommonOptions_toPrimitive(t, "string"); return "symbol" == CommonOptions_typeof(i) ? i : i + ""; }
function CommonOptions_toPrimitive(t, r) { if ("object" != CommonOptions_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != CommonOptions_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }



/**
 * 选项菜单
 */
var CommonOptions = /*#__PURE__*/function () {
  function CommonOptions() {
    CommonOptions_classCallCheck(this, CommonOptions);
  }
  return CommonOptions_createClass(CommonOptions, null, [{
    key: "registerBoolOption",
    value:
    /**
     * 注册 bool 类型的选项
     *
     * @param option 选项
     */
    function registerBoolOption(option) {
      var _this = this;
      var val = option.value,
        valIsBool = typeof val === 'boolean';
      if (!valIsBool) {
        return;
      }
      // 注册选项和选项点击事件
      var currentMenuCmdId = MenuCmd.register((val ? '✅ ' : '🔲 ') + option.label, function () {
        // 点击后取反
        option.value = !option.value;
        Store/* default */.A.set(option.name, JSON.stringify(option));

        // 重新注册
        MenuCmd.unregister(currentMenuCmdId);
        _this.registerBoolOption(option);
        // 刷新页面
        window.location.reload();
      });

      // 保存选项 ID
      option.menuCmdId = currentMenuCmdId;
      Store/* default */.A.set(option.name, JSON.stringify(option));
    }

    /**
     * 注册字符串/按钮类型的选项 (无状态)
     *
     * @param option 选项
     */
  }, {
    key: "registerStrOption",
    value: function registerStrOption(option) {
      MenuCmd.register(option.label, function () {
        if (typeof option.callback === 'function') {
          option.callback();
        }
      });
    }

    /**
     * 注册所有选项
     *
     * @param options 选项
     * @param moreOptionsUrl 更多设置页面 URL
     * @param useStore 是否使用存储(默认 true)
     */
  }, {
    key: "registerAll",
    value: function registerAll(options, moreOptionsUrl) {
      var useStore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      if (moreOptionsUrl) {
        // 注册“更多设置”选项,点击后打开新页面到更多设置页面
        MenuCmd.register('更多设置', function () {
          window.open(moreOptionsUrl, '_blank');
        });
      }
      var _iterator = _createForOfIteratorHelper(options),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var option = _step.value;
          // TODO 【调试】不保留选项的值,每次都从 Store 中获取
          // Store.set(option.name, null);

          // 声明最终用于注册的选项变量
          var finalOption = option;

          // useStore 为 true 时,才从 Store 读取或更新
          if (useStore) {
            var storeOption = Store/* default */.A.get(option.name) ? JSON.parse(Store/* default */.A.get(option.name)) : null;
            // 如果选项不存在 || 版本不一致 时重置选项
            if (storeOption === null || !storeOption['version'] || storeOption['version'] < option.version) {
              Store/* default */.A.set(option.name, JSON.stringify(option));
              storeOption = option;
            }
            finalOption = storeOption;
          }

          // 根据类型分发注册方法
          if (typeof finalOption.value === 'boolean') {
            this.registerBoolOption(finalOption);
          } else {
            this.registerStrOption(finalOption);
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
    }

    /**
     * 在 Greasy Fork 脚本详情页中加载选项
     *
     * @param scriptId 脚本 ID
     * @param loadOptionContentFn 加载选项内容的函数
     */
  }, {
    key: "loadInGreasyfork",
    value: function loadInGreasyfork(scriptId, loadOptionContentFn) {
      // 非脚本详情页结束
      if (location.host !== 'greasyfork.org' || location.href.indexOf('/scripts/' + scriptId) == -1) {
        return;
      }
      var selector = {
        scriptLinks: '#script-links',
        scriptOptions: '#script-options',
        scriptContent: '#script-content'
      };
      var $body = $(document.body),
        $scriptLinks = $(selector.scriptLinks),
        $scriptContent = $(selector.scriptContent);

      // 添加“脚本设置”选项卡和点击事件
      $scriptLinks.children('li:eq(0)').after("<li><a href=\"javascript:;\" id=\"script-options\">\u811A\u672C\u8BBE\u7F6E</a></li>");
      $body.on('click', selector.scriptOptions, function () {
        // 移除其他已选中选项的样式
        var $currentLi = $scriptLinks.children('li.current');
        $currentLi.html("<a href=\"".concat(location.href, "\">").concat($currentLi.text(), "</a>"));
        $currentLi.removeClass('current');
        // 给“脚本设置”选项卡添加选中选项的样式
        var $scriptOptions = $(selector.scriptOptions);
        $scriptOptions.parent().addClass('current');
        loadOptionContentFn($scriptContent);
      });
    }
  }]);
}();

;// ./gemini-pro/src/Options.ts
var _Options;
function Options_typeof(o) { "@babel/helpers - typeof"; return Options_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, Options_typeof(o); }
function Options_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function Options_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, Options_toPropertyKey(o.key), o); } }
function Options_createClass(e, r, t) { return r && Options_defineProperties(e.prototype, r), t && Options_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _defineProperty(e, r, t) { return (r = Options_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function Options_toPropertyKey(t) { var i = Options_toPrimitive(t, "string"); return "symbol" == Options_typeof(i) ? i : i + ""; }
function Options_toPrimitive(t, r) { if ("object" != Options_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != Options_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }

var Options = /*#__PURE__*/function () {
  function Options() {
    Options_classCallCheck(this, Options);
  }
  return Options_createClass(Options, null, [{
    key: "registerAll",
    value:
    /**
     * 注册所有选项
     * @param settingsCallback 点击“设置”时的回调函数
     */
    function registerAll(settingsCallback) {
      var _this = this;
      // 如果传入了回调,将其绑定到对应的选项上
      if (settingsCallback) {
        var option = this.options.find(function (o) {
          return o.name === _this.Keys.settings;
        });
        if (option) {
          option.callback = settingsCallback;
        }
      }
      CommonOptions.registerAll(this.options, null, false);
    }
  }]);
}();
_Options = Options;
/**
 * 选项 Key
 */
_defineProperty(Options, "Keys", {
  settings: 'settings'
});
/**
 * 选项
 * @private
 */
_defineProperty(Options, "options", [{
  label: '设置',
  name: _Options.Keys.settings,
  version: 1,
  value: '',
  menuCmdId: null
}]);


/***/ }),

/***/ 307:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (/* binding */ Store)
/* harmony export */ });
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * 存储
 */
var Store = /*#__PURE__*/function () {
  function Store() {
    _classCallCheck(this, Store);
  }
  return _createClass(Store, null, [{
    key: "get",
    value:
    /**
     * 获取
     * @param key 键
     */
    function get(key) {
      return GM_getValue(key);
    }

    /**
     * 设置
     * @param key 键
     * @param value 值
     */
  }, {
    key: "set",
    value: function set(key, value) {
      GM_setValue(key, value);
    }
  }]);
}();


/***/ }),

/***/ 490:
/***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => {

/* harmony import */ var _utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(307);
/* harmony import */ var _gemini_pro_src_Options__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172);
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
// ==UserScript==
// @name         Gemini Pro
// @namespace    http://tampermonkey.net/
// @version      0.4.0
// @description  增强 Gemini 对话界面
// @author       duanluan
// @copyright    2025, duanluan (https://github.com/duanluan)
// @license      Apache-2.0; https://www.apache.org/licenses/LICENSE-2.0.txt
// @homepage     https://greasyfork.org/zh-CN/scripts/558517
// @match        https://gemini.google.com/*
// @require      https://update.greasyfork.org/scripts/433051/Trusted%20Types%20Helper.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js
// @resource     layui_css https://cdn.jsdelivr.net/npm/[email protected]/css/layui.css
// @require      https://cdn.jsdelivr.net/npm/[email protected]/layui.js
// @grant        GM_registerMenuCommand
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

// ==OpenUserJS==
// @author       duanluan
// @updateURL    https://raw.kkgithub.com/duanluan/tampermonkey-scripts/main/gemini-pro/dist/gemini-pro.user.js
// ==/OpenUserJS==



(function () {
  'use strict';

  // 加载 Layui CSS
  GM_addStyle(GM_getResourceText('layui_css'));

  // 注入自定义样式
  GM_addStyle("\n    .layui-layer-ico{background:url('https://cdn.jsdelivr.net/npm/[email protected]/dist/theme/default/icon.png') no-repeat}\n    .layui-layer-ico1{background-position:-30px 0}\n    .layui-layer-ico2{background-position:-60px 0}\n    .layui-layer-ico3{background-position:-90px 0}\n    .layui-layer-ico4{background-position:-120px 0}\n    .layui-layer-ico5{background-position:-150px 0}\n    .layui-layer-ico6{background-position:-180px 0}\n\n    /* \u8BBE\u7F6E\u6309\u94AE */\n    #gemini-pro-toolbar-btn {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      box-sizing: border-box;\n      /* \u6807\u51C6 Material Icon Button \u5927\u5C0F */\n      width: 40px;\n      height: 40px;\n      border: none;\n      outline: none;\n      background-color: transparent;\n      fill: currentColor;\n      color: #444746;\n      border-radius: 50%;\n      cursor: pointer;\n      /* \u4E0E\u53F3\u4FA7\u539F\u6709\u56FE\u6807\u4FDD\u6301\u4E00\u70B9\u8DDD\u79BB */\n      margin-right: 4px;\n      transition: background-color 0.15s cubic-bezier(0.4, 0.0, 0.2, 1);\n    }\n    \n    /* \u6697\u9ED1\u6A21\u5F0F\u9002\u914D */\n    @media (prefers-color-scheme: dark) {\n      #gemini-pro-toolbar-btn {\n        color: #e3e3e3;\n      }\n      #gemini-pro-toolbar-btn:hover {\n        background-color: rgba(227, 227, 227, 0.08);\n      }\n    }\n    \n    /* \u666E\u901A\u6A21\u5F0F\u4E0B\u7684 Hover */\n    @media (prefers-color-scheme: light) {\n      #gemini-pro-toolbar-btn:hover {\n        background-color: rgba(68, 71, 70, 0.08);\n      }\n    }\n\n    #gemini-pro-toolbar-btn svg {\n      width: 24px;\n      height: 24px;\n      pointer-events: none;\n    }\n    \n    /* \u6E05\u9664\u9876\u90E8\u7684\u865A\u5316\u906E\u7F69\uFF0C\u8FD9\u662F\u5BFC\u81F4\u957F\u622A\u56FE\u51FA\u73B0\u9634\u5F71\u63A5\u7F1D\u7684\u6839\u6E90 */\n    body.gemini-pro-no-input-shadow .input-gradient,\n    body.gemini-pro-no-input-shadow .input-gradient::before,\n    body.gemini-pro-no-input-shadow .input-gradient::after {\n      background: none !important;\n      background-image: none !important;\n      mask: none !important;\n      -webkit-mask: none !important;\n      box-shadow: none !important;\n    }\n  ");
  var selector = {
    toolbarBtn: '#gemini-pro-toolbar-btn',
    // 我的内容入口按钮
    myContentEntryBtn: '.side-nav-entry-container > side-nav-entry-button',
    // 我的内容预览
    myContentPreview: 'my-stuff-recents-preview',
    // 底部免责声明
    disclaimer: 'hallucination-disclaimer',
    // 样式应用相关
    styleId: '#gemini-pro-page-style',
    chatHistory: '#chat-history > .chat-history',
    botInfoCardContainer: '#chat-history > .chat-history > .bot-info-card-container',
    botInfoCardWrapper: 'bot-info-card > .bot-info-card-container',
    userQuery: 'user-query',
    userQueryContainer: 'user-query-content > .user-query-container',
    conversationContainer: '.conversation-container',
    inputContainer: 'input-container',
    inputAreaContainer: '.input-area-container',
    messageContent: 'message-content .markdown',
    horizontalScrollWrapper: '.horizontal-scroll-wrapper',
    tableBlockComponent: '.horizontal-scroll-wrapper > .table-block-component',
    codeContainer: '.code-container',
    formattedCodeBlock: '.formatted-code-block-internal-container pre',
    // 侧边栏
    sidenavContainer: 'bard-sidenav-container[data-test-id="bard-sidenav-container"]',
    sidenav: 'bard-sidenav',
    sideNavigationContent: 'side-navigation-content',
    // 按钮挂载点
    rightSectionContainer: 'div.right-section .buttons-container',
    // 代码块右上角的复制按钮
    copyButton: 'button.copy-button',
    // 回答底部的复制按钮组件
    copyComponent: 'copy-button',
    pre: 'pre',
    codeBlockComponent: '.code-block-component'
  };
  var defaultConfig = {
    hideMyContentEntryBtn: false,
    hideMyContentPreview: false,
    hideDisclaimer: false,
    hideInputShadow: false,
    // 复制时合并多余换行
    trimCopyNewline: false,
    page: {
      // 聊天对话容器左边距
      chatLeftPadding: '10%',
      // 聊天对话容器右边距
      chatRightPadding: '10%',
      // 聊天输入容器底边距
      chatBottomPadding: '',
      // Markdown 内容底边距
      pBottomSpacing: '',
      // 标题上下间距
      hTopSpacing: '',
      hBottomSpacing: '',
      // UL/OL 列表整体间距
      ulTopSpacing: '',
      ulBottomSpacing: '',
      // LI 列表项间距
      liTopSpacing: '',
      liBottomSpacing: '',
      // 表格下边距
      tableBottomPadding: '0px',
      // 代码块行高
      codeLineHeight: '',
      // 代码块最大高度
      codeMaxHeight: ''
    },
    // 侧边栏宽度
    sidebarWidth: ''
  };
  var STORE_CONF_KEY = 'config';

  // 读取配置
  var savedConfigStr = _utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.get(STORE_CONF_KEY);
  var config = savedConfigStr ? JSON.parse(savedConfigStr) : defaultConfig;
  config.page = _objectSpread(_objectSpread({}, defaultConfig.page), config.page || {});

  /**
   * 将值转换为带 px 的值
   */
  var toPxVal = function toPxVal(val) {
    if (!val) return '0px';
    val = String(val).trim();
    if (/^\d+$/.test(val)) return val + 'px';
    return val;
  };

  /**
   * 应用页面宽度样式
   */
  var applyPageStyle = function applyPageStyle() {
    var $style = $(selector.styleId);
    if ($style.length === 0) {
      $style = $("<style id=\"".concat(selector.styleId.substring(1), "\"></style>"));
      $('head').append($style);
    }
    var leftRaw = config.page.chatLeftPadding;
    var rightRaw = config.page.chatRightPadding;
    var bottomRaw = config.page.chatBottomPadding;

    // 计算并限制总边距不超过 80%
    var winWidth = $(window).width() || window.innerWidth || 0;
    // 最大总边距
    var maxTotalPadding = winWidth * 0.8;

    // 将值转换为像素(支持百分比和数字)
    var convertToPixels = function convertToPixels(val) {
      if (!val) return 0;
      val = String(val).trim();
      // 处理百分比
      if (val.endsWith('%')) {
        return parseFloat(val) / 100 * winWidth;
      }
      // 处理数字或像素值
      return parseFloat(val) || 0;
    };
    var leftPx = convertToPixels(leftRaw);
    var rightPx = convertToPixels(rightRaw);
    var totalPx = leftPx + rightPx;

    // 判断是否超过阈值
    if (winWidth > 0 && totalPx > maxTotalPadding) {
      // 计算缩放系数
      var scale = maxTotalPadding / totalPx;

      // 按比例缩放左右边距
      leftPx = leftPx * scale;
      rightPx = rightPx * scale;

      // 覆盖原始值为计算后的 px 字符串
      leftRaw = leftPx + 'px';
      rightRaw = rightPx + 'px';
      console.warn("Gemini Pro: Chat padding exceeded limit, adjusted to ".concat(leftRaw, " (left) and ").concat(rightRaw, " (right)"));
    } else {
      // 未超限,使用常规格式化
      leftRaw = toPxVal(leftRaw);
      rightRaw = toPxVal(rightRaw);
    }

    // 底边距不需要参与宽度计算逻辑,直接格式化
    bottomRaw = toPxVal(bottomRaw);
    var chatLeftPadding = leftRaw;
    var chatRightPadding = rightRaw;
    var chatBottomPadding = bottomRaw;

    // 处理 Markdown 间距配置
    var pBottom = toPxVal(config.page.pBottomSpacing);
    var hTop = toPxVal(config.page.hTopSpacing);
    var hBottom = toPxVal(config.page.hBottomSpacing);
    var ulTop = toPxVal(config.page.ulTopSpacing);
    var ulBottom = toPxVal(config.page.ulBottomSpacing);
    var liTop = toPxVal(config.page.liTopSpacing);
    var liBottom = toPxVal(config.page.liBottomSpacing);
    var tableBottom = toPxVal(config.page.tableBottomPadding);

    // 代码行高:不使用 toPxVal,允许纯数字作为倍数
    var codeLH = config.page.codeLineHeight ? String(config.page.codeLineHeight).trim() : '';

    // 代码块最大高度 CSS 生成逻辑
    var codeMaxHeightCss = '';
    if (config.page.codeMaxHeight) {
      var maxH = toPxVal(config.page.codeMaxHeight);
      codeMaxHeightCss = "\n        ".concat(selector.formattedCodeBlock, " {\n            max-height: ").concat(maxH, " !important;\n            overflow-y: auto !important;\n            display: block !important;\n        }\n      ");
    }

    // 将显隐逻辑直接转换为 CSS 规则
    var displayNone = 'display: none !important;';
    $style.text("\n      /* \u663E\u9690\u63A7\u5236 */\n      ".concat(selector.myContentEntryBtn, " {\n        ").concat(config.hideMyContentEntryBtn ? displayNone : '', "\n      }\n      ").concat(selector.myContentPreview, " {\n        ").concat(config.hideMyContentPreview ? displayNone : '', "\n      }\n      ").concat(selector.disclaimer, " {\n        ").concat(config.hideDisclaimer ? displayNone : '', "\n      }\n      \n      /* \u804A\u5929\u5BF9\u8BDD\u5BB9\u5668 */\n      ").concat(selector.chatHistory, " {\n        padding: 16px ").concat(chatRightPadding, " 20px ").concat(chatLeftPadding, " !important;\n      }\n      /* \u804A\u5929\u5BF9\u8BDD Gem \u4FE1\u606F */\n      ").concat(selector.botInfoCardContainer, " {\n        padding: 0 !important;\n      }\n      /* \u89E3\u51B3\u4FEE\u6539 Gem \u4FE1\u606F padding \u540E\u4E0D\u5C45\u4E2D\u95EE\u9898 */\n      ").concat(selector.botInfoCardWrapper, " {\n        align-items: center !important;\n      }\n      \n      /* \u7528\u6237\u8BF4 */\n      ").concat(selector.userQuery, " {\n        max-width: 100% !important;\n      }\n      ").concat(selector.userQueryContainer, " {\n        max-width: 50% !important;\n      }\n      /* AI \u8BF4 */\n      ").concat(selector.conversationContainer, " {\n        max-width: 100% !important;\n      }\n      \n      /* \u804A\u5929\u8F93\u5165\u8FB9\u8DDD */\n      ").concat(selector.inputContainer, " {\n        padding: 0 ").concat(chatRightPadding, " ").concat(chatBottomPadding, " ").concat(chatLeftPadding, " !important;\n      }\n      /* \u804A\u5929\u8F93\u5165\u6700\u5927\u5BBD\u5EA6 */\n      ").concat(selector.inputAreaContainer, " {\n        max-width: 100% !important;\n      }\n\n      /* Markdown \u5185\u5BB9\u95F4\u8DDD\u8C03\u6574 */\n      \n      /* \u6BB5\u843D (P)\uFF1A\u53EA\u63A7\u5236\u4E0B\u8FB9\u8DDD */\n      ").concat(config.page.pBottomSpacing ? "\n        ".concat(selector.messageContent, " p {\n          margin-bottom: ").concat(pBottom, " !important;\n        }\n      ") : '', "\n\n      /* \u6807\u9898 (H1-H6)\uFF1A\u63A7\u5236\u4E0A\u4E0B\u8FB9\u8DDD */\n      ").concat(config.page.hTopSpacing || config.page.hBottomSpacing ? "\n        ".concat(selector.messageContent, " h1,\n        ").concat(selector.messageContent, " h2,\n        ").concat(selector.messageContent, " h3,\n        ").concat(selector.messageContent, " h4,\n        ").concat(selector.messageContent, " h5,\n        ").concat(selector.messageContent, " h6 {\n          ").concat(config.page.hTopSpacing ? "margin-top: ".concat(hTop, " !important;") : '', "\n          ").concat(config.page.hBottomSpacing ? "margin-bottom: ".concat(hBottom, " !important;") : '', "\n        }\n      ") : '', "\n\n      /* \u5217\u8868\u6574\u4F53 (UL/OL)\uFF1A\u63A7\u5236\u4E0A\u4E0B\u8FB9\u8DDD */\n      ").concat(config.page.ulTopSpacing || config.page.ulBottomSpacing ? "\n        ".concat(selector.messageContent, " ul,\n        ").concat(selector.messageContent, " ol {\n          ").concat(config.page.ulTopSpacing ? "margin-top: ".concat(ulTop, " !important;") : '', "\n          ").concat(config.page.ulBottomSpacing ? "margin-bottom: ".concat(ulBottom, " !important;") : '', "\n        }\n      ") : '', "\n\n      /* \u5217\u8868\u9879 (LI)\uFF1A\u63A7\u5236\u4E0A\u4E0B\u8FB9\u8DDD */\n      ").concat(config.page.liTopSpacing || config.page.liBottomSpacing ? "\n        ".concat(selector.messageContent, " ul li,\n        ").concat(selector.messageContent, " ol li,\n        ").concat(selector.messageContent, " ul li > p,\n        ").concat(selector.messageContent, " ol li > p {\n          ").concat(config.page.liTopSpacing ? "margin-top: ".concat(liTop, " !important;") : '', "\n          ").concat(config.page.liBottomSpacing ? "margin-bottom: ".concat(liBottom, " !important;") : '', "\n        }\n      ") : '', "\n\n      /* \u8868\u683C (Table) \u95F4\u8DDD\u53CA\u6EDA\u52A8\u63A7\u5236 */\n      ").concat(config.page.tableBottomPadding !== '' ? "\n        ".concat(selector.horizontalScrollWrapper, ",\n        ").concat(selector.tableBlockComponent, " {\n          overflow-x: auto !important;\n          padding-bottom: ").concat(tableBottom, " !important;\n        }\n      ") : '', "\n\n      /* \u4EE3\u7801\u5757\u884C\u9AD8 (\u540C\u65F6\u63A7\u5236\u5916\u5C42\u5BB9\u5668\u548C\u5185\u5C42 span) */\n      ").concat(config.page.codeLineHeight ? "\n        ".concat(selector.codeContainer, ",\n        ").concat(selector.codeContainer, " pre,\n        ").concat(selector.codeContainer, " code,\n        ").concat(selector.codeContainer, " span {\n          line-height: ").concat(codeLH, " !important;\n        }\n      ") : '', "\n      \n      /* \u4EE3\u7801\u5757\u6700\u5927\u9AD8\u5EA6 (\u6EDA\u52A8\u6761) */\n      ").concat(codeMaxHeightCss, "\n    "));

    // 处理侧边栏宽度
    if (config.sidebarWidth) {
      var val = toPxVal(config.sidebarWidth);

      // 需要修改变量的所有目标元素
      var targets = [
      // 侧边栏容器
      document.querySelector(selector.sidenavContainer),
      // 侧边栏
      document.querySelector(selector.sidenav),
      // 侧边栏内容
      document.querySelector(selector.sideNavigationContent)];
      targets.forEach(function (el) {
        if (el) {
          // 设置展开宽度为自定义值
          el.style.setProperty('--bard-sidenav-open-width', val, 'important');
        }
      });
    } else {
      // 如果用户清空了设置,移除所有强制修改
      var _targets = [document.querySelector(selector.sidenavContainer), document.querySelector(selector.sidenav), document.querySelector(selector.sideNavigationContent)];
      _targets.forEach(function (el) {
        if (el) {
          el.style.removeProperty('--bard-sidenav-open-width');
          el.style.removeProperty('--bard-sidenav-closed-width');
        }
      });
    }
  };

  /**
   * 应用配置
   */
  var applyConfig = function applyConfig() {
    // 样式类配置:通过 toggleClass 给 body 加标记
    $('body').toggleClass('gemini-pro-no-input-shadow', config.hideInputShadow);
    applyPageStyle();
  };

  // 初始应用
  applyConfig();

  // 监听窗口大小变化,动态重新计算边距限制
  $(window).on('resize', function () {
    applyPageStyle();
  });

  // 标记是否点击了Gemini原生的复制按钮(代码块按钮 或 底部回答按钮)
  var isNativeCopyBtnClick = false;

  // 监听点击事件,用于检测是否点击了原生复制按钮
  document.addEventListener('click', function (e) {
    var target = e.target;
    var btn =
    // 代码块右上角的复制按钮
    target.closest(selector.copyButton)
    // 回答底部的复制按钮组件
    || target.closest(selector.copyComponent);
    if (btn) {
      isNativeCopyBtnClick = true;
      // 500ms 后重置,防止影响后续操作
      setTimeout(function () {
        isNativeCopyBtnClick = false;
      }, 500);
    }
  }, true);

  // 监听复制事件(使用 { capture: true } 以在页面脚本之前拦截)
  document.addEventListener('copy', function (e) {
    // 全局开关校验
    if (!config.trimCopyNewline) return;

    // 如果是点击了 Gemini 原生的复制按钮,放行
    if (isNativeCopyBtnClick) {
      isNativeCopyBtnClick = false;
      return;
    }
    var selection = window.getSelection();
    if (!selection || selection.isCollapsed || selection.rangeCount === 0) return;

    // 如果选区完全在代码块内部(Code Block),也不做处理
    var commonNode = selection.getRangeAt(0).commonAncestorContainer;
    // 如果是文本节点,取其父元素
    if (commonNode.nodeType === 3) {
      commonNode = commonNode.parentNode;
    }
    var parentEl = commonNode;
    // 检查是否在代码块容器中
    if (parentEl.closest(selector.pre) || parentEl.closest(selector.codeBlockComponent)) {
      // 纯代码块内容复制,不执行空行合并
      return;
    }

    // 执行混合内容的智能处理(保护代码块结构,合并普通文本空行)
    e.preventDefault();
    e.stopImmediatePropagation();

    // 获取 DOM 片段
    var range = selection.getRangeAt(0);
    var fragment = range.cloneContents();
    var tempDiv = document.createElement('div');
    tempDiv.appendChild(fragment);

    // 保护代码块:查找 <pre>
    var codeBlocks = tempDiv.querySelectorAll(selector.pre);
    var placeholders = [];
    codeBlocks.forEach(function (block, index) {
      // 生成唯一占位符
      var placeholder = "__GEMINI_CODE_BLOCK_PROTECTION_".concat(index, "_").concat(Date.now(), "__");
      // 保存原始内容
      placeholders.push({
        id: placeholder,
        content: block.innerText
      });
      // 替换
      block.textContent = placeholder;
    });

    // 获取文本并处理
    tempDiv.style.position = 'absolute';
    tempDiv.style.left = '-9999px';
    tempDiv.style.opacity = '0';
    document.body.appendChild(tempDiv);
    var text = tempDiv.innerText;
    document.body.removeChild(tempDiv);

    // 合并换行逻辑:每两个换行符替换为一个
    text = text.replace(/\n\n/g, '\n');

    // 还原代码块
    placeholders.forEach(function (item) {
      text = text.replace(item.id, item.content);
    });

    // 彻底清空剪贴板数据并设置新的内容
    if (e.clipboardData) {
      e.clipboardData.clearData();
      e.clipboardData.setData('text/plain', text);
    }
  },
  // 表示在捕获阶段执行
  true);

  // 定义点击设置时的回调函数
  var onSettingsClick = function onSettingsClick() {
    // 获取配置值 > 页面实时计算值 > 兜底默认值
    var getVal = function getVal(key, selectorStr, prop, fallback) {
      // 如果有配置值,直接使用(保持用户输入的原样)
      if (config.page[key]) return config.page[key];

      // 尝试从 DOM 获取当前计算样式(浏览器通常返回 px)
      var el = document.querySelector(selectorStr);
      if (el) {
        return getComputedStyle(el)[prop];
      }

      // 使用兜底默认值,如果是 rem 则转换为 px
      if (fallback && fallback.includes('rem')) {
        var rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
        return parseFloat(fallback) * rootFontSize + 'px';
      }
      return fallback || '';
    };

    // 获取用于显示在 Input 框中的值
    // 默认值参考:s=8px, h-top=1.75rem, h-bottom=8px, li=8px
    var pBottom = getVal('pBottomSpacing', "".concat(selector.messageContent, " p"), 'marginBottom', '');
    var hTop = getVal('hTopSpacing', "".concat(selector.messageContent, " h2"), 'marginTop', '1.75rem');
    var hBottom = getVal('hBottomSpacing', "".concat(selector.messageContent, " h2"), 'marginBottom', '8px');

    // UL/OL 默认通常是 1em,这里兜底给 16px(1rem)
    var ulTop = getVal('ulTopSpacing', "".concat(selector.messageContent, " ul"), 'marginTop', '1rem');
    var ulBottom = getVal('ulBottomSpacing', "".concat(selector.messageContent, " ul"), 'marginBottom', '1rem');
    var liTop = getVal('liTopSpacing', "".concat(selector.messageContent, " li"), 'marginTop', '8px');
    var liBottom = getVal('liBottomSpacing', "".concat(selector.messageContent, " li"), 'marginBottom', '8px');

    // 表格下边距
    var tableBottom = getVal('tableBottomPadding', selector.horizontalScrollWrapper, 'paddingBottom', '0px');

    // 代码块行高:优先获取 code 标签的行高,比 span 更能反映块级属性
    var codeLH = getVal('codeLineHeight', "".concat(selector.codeContainer, " code"), 'lineHeight', '1.5');
    // 代码块最大高度
    var codeMaxH = config.page.codeMaxHeight;
    layer.open({
      type: 1,
      area: ['600px', '650px'],
      title: 'Gemini Pro 设置',
      // 点击遮罩关闭
      shadeClose: true,
      content: "\n        <div class=\"layui-tab layui-tab-brief\" lay-filter=\"gemini-settings-tab\" style=\"margin: 0;\">\n          <ul class=\"layui-tab-title\">\n            <li class=\"layui-this\">\u5E38\u89C4\u8BBE\u7F6E</li>\n            <li>\u9875\u9762\u8C03\u6574</li>\n            <li>\u4EE3\u7801\u5757\u589E\u5F3A</li>\n          </ul>\n          <div class=\"layui-tab-content\">\n            <div class=\"layui-tab-item layui-show\">\n              <form class=\"layui-form\" style=\"padding: 10px;\" action=\"\">\n                <div class=\"layui-form-item\">\n                  <label class=\"layui-form-label\" style=\"width: 60px;\">\u9690\u85CF\uFF1A</label>\n                  <div class=\"layui-input-block\" style=\"margin-left: 90px;\">\n                    <input type=\"checkbox\" title=\"\u4FA7\u8FB9\u680F-\u6211\u7684\u5185\u5BB9\" name=\"hideMyContentEntryBtn\" lay-filter=\"item-switch\" ".concat(config.hideMyContentEntryBtn ? 'checked' : '', "/>\n                    <input type=\"checkbox\" title=\"\u4FA7\u8FB9\u680F-\u6211\u7684\u5185\u5BB9\u9884\u89C8\" name=\"hideMyContentPreview\" lay-filter=\"item-switch\" ").concat(config.hideMyContentPreview ? 'checked' : '', "/>\n                    <input type=\"checkbox\" title=\"\u5E95\u90E8\u514D\u8D23\u58F0\u660E\" name=\"hideDisclaimer\" lay-filter=\"item-switch\" ").concat(config.hideDisclaimer ? 'checked' : '', "/>\n                    <input type=\"checkbox\" title=\"\u804A\u5929\u8F93\u5165\u6846\u4E0A\u65B9\u6E10\u53D8\" name=\"hideInputShadow\" lay-filter=\"item-switch\" ").concat(config.hideInputShadow ? 'checked' : '', "/>\n                  </div>\n                </div>\n                \n                <div class=\"layui-form-item\">\n                  <label class=\"layui-form-label\" style=\"width: 60px;\">\u5176\u4ED6\uFF1A</label>\n                  <div class=\"layui-input-block\" style=\"margin-left: 90px;\">\n                    <input type=\"checkbox\" title=\"\u526A\u8D34\u677F-\u5220\u9664\u9519\u8BEF\u7A7A\u884C\" name=\"trimCopyNewline\" lay-filter=\"item-switch\" ").concat(config.trimCopyNewline ? 'checked' : '', "/>\n                  </div>\n                </div>\n              </form>\n            </div>\n\n            <div class=\"layui-tab-item\">\n              <form class=\"layui-form\" lay-filter=\"page-form\" style=\"padding: 10px;\">\n                <fieldset class=\"layui-elem-field layui-field-title\" style=\"margin-top: 10px;\">\n                  <legend style=\"font-size: 14px;\">\u5BB9\u5668\u8FB9\u8DDD</legend>\n                </fieldset>\n                \n                <div class=\"layui-form-item\">\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u804A\u5929\u5DE6</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"chatLeftPadding\" value=\"").concat(config.page.chatLeftPadding, "\" placeholder=\"\u5982 10%\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u804A\u5929\u53F3</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"chatRightPadding\" value=\"").concat(config.page.chatRightPadding, "\" placeholder=\"\u5982 10%\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u804A\u5929\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"chatBottomPadding\" value=\"").concat(config.page.chatBottomPadding, "\" placeholder=\"\u5982 20px\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                </div>\n                <div class=\"layui-form-item\">\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u4FA7\u8FB9\u680F\u5BBD</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"sidebarWidth\" value=\"").concat(config.sidebarWidth, "\" placeholder=\"\u5982 300px\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                </div>\n                \n                <fieldset class=\"layui-elem-field layui-field-title\" style=\"margin-top: 20px;\">\n                  <legend style=\"font-size: 14px;\">\u5185\u5BB9\u95F4\u8DDD</legend>\n                </fieldset>\n\n                <div class=\"layui-form-item\">\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u6BB5\u843D\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"pBottomSpacing\" value=\"").concat(pBottom, "\" placeholder=\"\u5982 10px\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u6807\u9898\u4E0A</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"hTopSpacing\" value=\"").concat(hTop, "\" placeholder=\"\u4E0A\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u6807\u9898\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"hBottomSpacing\" value=\"").concat(hBottom, "\" placeholder=\"\u4E0B\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                </div>\n                \n                <div class=\"layui-form-item\">\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u5217\u8868\u4E0A</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"ulTopSpacing\" value=\"").concat(ulTop, "\" placeholder=\"\u4E0A\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u5217\u8868\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"ulBottomSpacing\" value=\"").concat(ulBottom, "\" placeholder=\"\u4E0B\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                    <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u8868\u683C\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"tableBottomPadding\" value=\"").concat(tableBottom, "\" placeholder=\"\u4E0B\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"layui-form-item\">\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u5217\u8868\u9879\u4E0A</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"liTopSpacing\" value=\"").concat(liTop, "\" placeholder=\"\u4E0A\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                  <div class=\"layui-inline\">\n                    <label class=\"layui-form-label\" style=\"width: 70px; padding-left: 5px; padding-right: 5px;\">\u5217\u8868\u9879\u4E0B</label>\n                    <div class=\"layui-input-inline\" style=\"width: 90px;\">\n                      <input type=\"text\" name=\"liBottomSpacing\" value=\"").concat(liBottom, "\" placeholder=\"\u4E0B\u95F4\u8DDD\" autocomplete=\"off\" class=\"layui-input\">\n                    </div>\n                  </div>\n                </div>\n                \n                <div style=\"padding: 0 20px; color: #999; font-size: 12px; line-height: 1.5;\">\n                  <p>1. \u652F\u6301\u5355\u4F4D\uFF1Apx\uFF08\u50CF\u7D20\uFF09\u6216 %\uFF08\u767E\u5206\u6BD4\uFF09\u3002</p>\n                  <p>2. \u5982\u679C\u53EA\u586B\u6570\u5B57\uFF0C\u9ED8\u8BA4\u4E3A px\u3002</p>\n                  <p>3. \u7559\u7A7A\u5219\u4E0D\u8C03\u6574\uFF0C\u652F\u6301\u9F20\u6807\u6EDA\u8F6E\u8C03\u6574\u6570\u503C\u3002</p>\n                </div>\n              </form>\n            </div>\n\n            <div class=\"layui-tab-item\">\n              <form class=\"layui-form\" style=\"padding: 10px;\">\n                <fieldset class=\"layui-elem-field layui-field-title\" style=\"margin-top: 10px;\">\n                  <legend style=\"font-size: 14px;\">\u663E\u793A\u8BBE\u7F6E</legend>\n                </fieldset>\n                <div class=\"layui-form-item\">\n                  <label class=\"layui-form-label\" style=\"width: 80px;\">\u4EE3\u7801\u884C\u9AD8</label>\n                  <div class=\"layui-input-block\" style=\"margin-left: 110px;\">\n                    <input type=\"text\" name=\"codeLineHeight\" value=\"").concat(codeLH, "\" placeholder=\"\u5982 1.5 \u6216 24px\" autocomplete=\"off\" class=\"layui-input\">\n                  </div>\n                </div>\n                <div class=\"layui-form-item\">\n                  <label class=\"layui-form-label\" style=\"width: 80px;\">\u6700\u5927\u9AD8\u5EA6</label>\n                  <div class=\"layui-input-block\" style=\"margin-left: 110px;\">\n                    <input type=\"text\" name=\"codeMaxHeight\" value=\"").concat(codeMaxH, "\" placeholder=\"\u8D85\u51FA\u5219\u663E\u793A\u6EDA\u52A8\u6761\uFF0C\u5982 600px\" autocomplete=\"off\" class=\"layui-input\">\n                  </div>\n                </div>\n                \n                <div style=\"padding: 0 20px; color: #999; font-size: 12px; line-height: 1.5;\">\n                  <p>1. \u652F\u6301\u5355\u4F4D\uFF1Apx\uFF08\u50CF\u7D20\uFF09\u3002</p>\n                  <p>2. \u884C\u9AD8\u82E5\u65E0\u5355\u4F4D\u5219\u4E3A\u500D\u6570\uFF08\u652F\u6301\u5C0F\u6570\uFF09\u3002</p>\n                  <p>3. \u7559\u7A7A\u5219\u4E0D\u8C03\u6574\uFF0C\u652F\u6301\u9F20\u6807\u6EDA\u8F6E\u8C03\u6574\u6570\u503C\u3002</p>\n                </div>\n              </form>\n            </div>\n          </div>\n        </div>\n      ")
    });

    // layer.open 中 radio、checkbox、select 需要 render 才能显示
    layui.use(['form', 'element'], function () {
      var form = layui.form;

      // 验证并修正侧边栏宽度
      var validateSidebarWidth = function validateSidebarWidth(input) {
        // 如果输入为空,直接返回空(表示使用默认/不修改)
        var strVal = String(input).trim();
        if (strVal === '') return '';
        var winWidth = window.innerWidth;
        var pxVal = 0;

        // 解析数值(支持百分比和 px)
        if (strVal.endsWith('%')) {
          var pct = parseFloat(strVal);
          if (!isNaN(pct)) {
            pxVal = pct / 100 * winWidth;
          }
        } else {
          pxVal = parseFloat(strVal);
        }

        // 如果解析失败(非数字),返回空
        if (isNaN(pxVal)) return '';

        // 边界检查
        var MIN_PX = 200;
        var MAX_PX = winWidth * 0.5;
        if (pxVal < MIN_PX) pxVal = MIN_PX;
        if (pxVal > MAX_PX) pxVal = MAX_PX;

        // 返回修正后的 px 值字符串
        return Math.round(pxVal) + 'px';
      };
      form.render();
      // 监听复选框变更
      form.on('checkbox(item-switch)', function (data) {
        // 更新配置对象
        config[data.elem.name] = data.elem.checked;
        // 保存配置
        _utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.set(STORE_CONF_KEY, JSON.stringify(config));
        applyConfig();
      });

      // 动态监听输入框变化
      var inputSelector = ['input[name="chatLeftPadding"]', 'input[name="chatRightPadding"]', 'input[name="chatBottomPadding"]', 'input[name="pBottomSpacing"]', 'input[name="hTopSpacing"]', 'input[name="hBottomSpacing"]', 'input[name="ulTopSpacing"]', 'input[name="ulBottomSpacing"]', 'input[name="liTopSpacing"]', 'input[name="liBottomSpacing"]', 'input[name="tableBottomPadding"]', 'input[name="codeLineHeight"]', 'input[name="codeMaxHeight"]', 'input[name="sidebarWidth"]'].join(', ');

      // 防抖定时器:将“保存”和“应用样式”打包在一起延迟执行,解决滚轮调整时的卡顿问题
      var saveAndApplyTimer = null;
      var saveAndApply = function saveAndApply() {
        // 持久化保存
        _utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.set(STORE_CONF_KEY, JSON.stringify(config));
        // 实时应用样式
        applyConfig();
      };
      $(inputSelector).on('input', function () {
        var $this = $(this);
        var name = $this.attr('name');
        var val = $this.val();

        // 更新内存中的配置对象
        if (name === 'sidebarWidth') {
          config[name] = validateSidebarWidth(val);
        } else {
          config.page[name] = val;
        }

        // 避免高频 JSON 序列化和 DOM 操作阻塞主线程
        if (saveAndApplyTimer !== null) {
          clearTimeout(saveAndApplyTimer);
        }
        saveAndApplyTimer = window.setTimeout(function () {
          saveAndApply();
        }, 150);
      });

      // 支持鼠标滚轮调整数值
      $(inputSelector).on('wheel', function (e) {
        // 阻止默认滚动行为
        e.preventDefault();
        var $this = $(this);
        // 获取滚动方向:deltaY > 0 为向下滚动(数值减小),deltaY < 0 为向上滚动(数值增加)
        var originalEvent = e.originalEvent;
        var delta = originalEvent.deltaY || -originalEvent.wheelDelta || originalEvent.detail;

        // 获取当前值并分离数值和单位
        var valStr = String($this.val());
        // 正则匹配:开始(可选负号)(数字)(可选单位)
        var match = valStr.match(/^(-?[\d\.]+)(.*)$/);
        var num = 0;
        var unit = ''; // 默认单位为空,由后续逻辑决定

        if (match) {
          num = parseFloat(match[1]);
          unit = match[2];
        } else if (!valStr) {
          // 如果为空,视为 0
          num = 0;
        }

        // 其他字段默认补 px(行高除外)
        var name = $this.attr('name');
        if (!unit && name !== 'codeLineHeight') {
          unit = 'px';
        }

        // 确定步长:如果是代码行高,步长为 0.1,否则为 1
        var step = name === 'codeLineHeight' ? 0.1 : 1;

        // 根据滚动方向增减
        if (delta < 0) {
          num += step;
        } else {
          num -= step;
          if (num < 0) num = 0;
        }

        // 针对小数运算修复精度问题
        if (name === 'codeLineHeight') {
          num = parseFloat(num.toFixed(1));
        }

        // 针对侧边栏宽度的滚轮验证
        var finalValStr = num + unit;
        if (name === 'sidebarWidth') {
          // 将计算出的值传入验证函数,得到修正后的值
          finalValStr = validateSidebarWidth(finalValStr);
        }

        // 更新输入框并手动触发 input 事件以保存和应用
        $this.val(finalValStr);
        $this.trigger('input');
      });

      // 侧边栏输入框失去焦点时,修正显示值
      $('input[name="sidebarWidth"]').on('blur', function () {
        var $this = $(this);
        // 获取最终保存的配置值(一定是合法的,比如 200px)
        var finalVal = config.sidebarWidth;

        // 只有当输入框当前显示的内容与最终保存值不一致时才修正
        if ($this.val() !== finalVal) {
          $this.val(finalVal);
        }
      });
    });
  };

  /**
   * 将设置按钮嵌入到页面顶部导航栏
   */
  var mountToolbarButton = function mountToolbarButton() {
    // 如果按钮已经存在,直接返回
    if ($(selector.toolbarBtn).length > 0) return;

    // 寻找容器:使用 .first() 确保只操作第一个匹配的容器
    var $container = $(selector.rightSectionContainer).first();

    // 如果容器不存在,直接返回
    if ($container.length === 0) return;
    var $btn = $("\n    <button id=\"".concat(selector.toolbarBtn.substring(1), "\" title=\"Gemini Pro \u8BBE\u7F6E\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 -960 960 960\" width=\"24\">\n        <path d=\"M440-120v-240h80v80h320v80H520v80h-80Zm-320-80v-80h240v80H120Zm160-160v-80H120v-80h160v-80h80v240h-80Zm160-80v-80h400v80H440Zm160-160v-240h80v80h160v80H680v80h-80Zm-480-80v-80h400v80H120Z\"/>\n      </svg>\n    </button>\n  "));
    $btn.on('click', function (e) {
      e.stopPropagation();
      onSettingsClick();
    });

    // 插入到容器第一个位置
    $container.prepend($btn);

    // 首次运行时显示设置入口提示
    if (!_utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.get('hasShownButtonHint')) {
      setTimeout(function () {
        layer.tips('Gemini Pro 设置入口在这里', selector.toolbarBtn, {
          tips: [3, '#009688'],
          time: 5000,
          anim: 5
        });
        _utils_gm_Store__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.set('hasShownButtonHint', true);
      }, 4000);
    }
  };

  // 防抖定时器
  var mountTimer = null;

  // 使用 MutationObserver 监听 DOM 变化
  var observer = new MutationObserver(function () {
    // 防抖处理:避免短时间内频繁触发
    if (mountTimer !== null) {
      clearTimeout(mountTimer);
    }
    mountTimer = window.setTimeout(function () {
      mountToolbarButton();
      applyPageStyle();
    }, 100);
  });

  // 直接监听 document.body,简单有效,覆盖所有子树变化
  observer.observe(document.body, {
    childList: true,
    subtree: true
  });

  // 注册 Tampermonkey 菜单选项
  _gemini_pro_src_Options__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.registerAll(onSettingsClick);
  // 初始尝试渲染
  mountToolbarButton();
})();

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	__webpack_require__(172);
/******/ 	var __webpack_exports__ = __webpack_require__(490);
/******/ 	
/******/ })()
;
//# sourceMappingURL=gemini-pro.user.js.map