(() => {
  var __create = Object.create;
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __getProtoOf = Object.getPrototypeOf;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __commonJS = (cb, mod) => function __require() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
    // If the importer is in node compatibility mode or this is not an ESM
    // file that has been converted to a CommonJS file using a Babel-
    // compatible transform (i.e. "__esModule" has not been set), then set
    // "default" to the CommonJS "module.exports" for node compatibility.
    isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
    mod
  ));

  // src/shared/version.js
  var require_version = __commonJS({
    "src/shared/version.js"(exports, module) {
      (function attachBuildIdentity(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaBuildIdentity = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createBuildIdentity() {
        "use strict";
        const EXTENSION_VERSION = "1.25.34";
        const injectedFingerprint = true ? "ad6e691b8aca11ed33afdee80003f6267e631e774c668aa45122b2917e7c7890" : "";
        const fingerprint = injectedFingerprint || `source:${EXTENSION_VERSION}`;
        return Object.freeze({ version: EXTENSION_VERSION, fingerprint });
      });
    }
  });

  // src/shared/shortcut-logic.js
  var require_shortcut_logic = __commonJS({
    "src/shared/shortcut-logic.js"(exports, module) {
      (function(global) {
        const MOD_KEYS = ["Alt", "Control", "Shift", "Meta"];
        const KEY_TO_CODE = {
          q: "KeyQ",
          w: "KeyW",
          e: "KeyE",
          r: "KeyR",
          t: "KeyT",
          y: "KeyY",
          u: "KeyU",
          i: "KeyI",
          o: "KeyO",
          p: "KeyP",
          a: "KeyA",
          s: "KeyS",
          d: "KeyD",
          f: "KeyF",
          g: "KeyG",
          h: "KeyH",
          j: "KeyJ",
          k: "KeyK",
          l: "KeyL",
          z: "KeyZ",
          x: "KeyX",
          c: "KeyC",
          v: "KeyV",
          b: "KeyB",
          n: "KeyN",
          m: "KeyM",
          " ": "Space",
          "`": "Backquote",
          "1": "Digit1",
          "2": "Digit2",
          "3": "Digit3",
          "4": "Digit4",
          "5": "Digit5",
          "6": "Digit6",
          "7": "Digit7",
          "8": "Digit8",
          "9": "Digit9",
          "0": "Digit0",
          "-": "Minus",
          "=": "Equal",
          "[": "BracketLeft",
          "]": "BracketRight",
          "\\": "Backslash",
          ";": "Semicolon",
          "'": "Quote",
          ",": "Comma",
          ".": "Period",
          "/": "Slash",
          Tab: "Tab",
          Escape: "Escape"
        };
        function keyLabel(key) {
          if (key === " ") return "Space";
          if (key === "Control") return "Ctrl";
          if (key === "Meta") return "Meta";
          if (key === "`") return "`";
          if (key === "-") return "-";
          if (key === "=") return "=";
          return key && key.length === 1 ? key.toUpperCase() : key;
        }
        function makeLabel(config) {
          if (config.type === "combo") {
            return (config.modifiers || []).map(keyLabel).join("+") + "+" + keyLabel(config.key);
          }
          return keyLabel(config.key);
        }
        function normalizeTriggerConfig(value) {
          if (value.type === "combo") {
            return {
              type: "combo",
              key: value.key,
              modifiers: value.modifiers || [],
              label: value.label || makeLabel(value),
              code: value.code || KEY_TO_CODE[(value.key || "").toLowerCase()] || ""
            };
          }
          return {
            type: "single",
            key: value.key,
            modifiers: [],
            label: value.label || keyLabel(value.key),
            code: value.code || KEY_TO_CODE[(value.key || "").toLowerCase()] || ""
          };
        }
        function buildTriggerConfigFromPreset(preset) {
          if (typeof preset !== "string") return null;
          if (preset.startsWith("combo:")) {
            const parts = preset.slice(6).split("+");
            const mainKey = parts.pop();
            if (!mainKey) return null;
            return normalizeTriggerConfig({ type: "combo", key: mainKey, modifiers: parts });
          }
          if (preset.startsWith("single:")) {
            return normalizeTriggerConfig({ type: "single", key: preset.slice(7) });
          }
          return null;
        }
        function matchesTriggerPreset(config, preset) {
          if (!config || !config.type || typeof config.key === "undefined") return false;
          const presetConfig = buildTriggerConfigFromPreset(preset);
          if (!presetConfig) return false;
          const cfg = normalizeTriggerConfig(config);
          if (cfg.type !== presetConfig.type) return false;
          if (String(cfg.key).toLowerCase() !== String(presetConfig.key).toLowerCase()) return false;
          const cfgMods = [...cfg.modifiers || []].sort().join(",");
          const presetMods = [...presetConfig.modifiers || []].sort().join(",");
          return cfgMods === presetMods;
        }
        function isModifier(key) {
          return MOD_KEYS.includes(key);
        }
        function hasExactModifiers(config, payload) {
          const configuredModifiers = config.modifiers || [];
          const mainModifier = config.type === "single" && isModifier(config.key) ? config.key : null;
          const modifierFlags = {
            Alt: payload.altKey,
            Control: payload.ctrlKey,
            Shift: payload.shiftKey,
            Meta: payload.metaKey
          };
          for (const mod of MOD_KEYS) {
            const expected = mod === mainModifier || configuredModifiers.includes(mod);
            if (Boolean(modifierFlags[mod]) !== expected) return false;
          }
          return true;
        }
        function matchesConfiguredMainKey(config, eventLike) {
          const cfg = normalizeTriggerConfig(config);
          const isIme = eventLike.key === "Process" || eventLike.keyCode === 229;
          const expectedCode = cfg.code || KEY_TO_CODE[(cfg.key || "").toLowerCase()];
          if (expectedCode && eventLike.code === expectedCode) return true;
          return !isIme && String(eventLike.key).toLowerCase() === String(cfg.key).toLowerCase();
        }
        function isEventPartOfTrigger(config, eventLike) {
          const cfg = normalizeTriggerConfig(config);
          if (matchesConfiguredMainKey(cfg, eventLike)) return true;
          return cfg.type === "combo" && (cfg.modifiers || []).includes(eventLike.key);
        }
        function matchesTriggerFromKeyboardEvent(config, eventLike, toggles) {
          const cfg = normalizeTriggerConfig(config);
          const singleEnabled = toggles.singleEnabled !== false;
          const comboEnabled = toggles.comboEnabled !== false;
          if (cfg.type === "combo") {
            return comboEnabled && hasExactModifiers(cfg, eventLike) && matchesConfiguredMainKey(cfg, eventLike);
          }
          return singleEnabled && hasExactModifiers(cfg, eventLike) && matchesConfiguredMainKey(cfg, eventLike);
        }
        function matchesTriggerFromForwardedEvent(config, payload, toggles) {
          return matchesTriggerFromKeyboardEvent(config, payload, toggles);
        }
        function createShortcutSession() {
          const pressed = /* @__PURE__ */ new Map();
          const triggerTokens = /* @__PURE__ */ new Set();
          let active = false;
          let canceled = false;
          let activeConfig = null;
          function physicalKeyToken(eventLike) {
            return eventLike.code || `${eventLike.key}:${eventLike.location || 0}`;
          }
          function keyDown(config, eventLike, toggles) {
            if (eventLike.repeat === true) {
              return { trigger: false, cancel: false };
            }
            const token = physicalKeyToken(eventLike);
            pressed.set(token, eventLike);
            if (active) {
              if (!canceled && !isEventPartOfTrigger(activeConfig, eventLike)) {
                canceled = true;
                return { trigger: false, cancel: true };
              }
              return { trigger: false, cancel: false };
            }
            const cfg = normalizeTriggerConfig(config);
            const expectedCount = cfg.type === "combo" ? new Set(cfg.modifiers || []).size + 1 : 1;
            const exactPressedKeys = pressed.size === expectedCount && [...pressed.values()].every((pressedEvent) => isEventPartOfTrigger(cfg, pressedEvent));
            if (exactPressedKeys && matchesTriggerFromKeyboardEvent(cfg, eventLike, toggles)) {
              active = true;
              activeConfig = cfg;
              for (const pressedToken of pressed.keys()) triggerTokens.add(pressedToken);
              return { trigger: true, cancel: false };
            }
            return { trigger: false, cancel: false };
          }
          function keyUp(eventLike) {
            const token = physicalKeyToken(eventLike);
            const triggerReleased = triggerTokens.delete(token);
            pressed.delete(token);
            const ended = active && triggerTokens.size === 0;
            const wasCanceled = canceled;
            if (ended) {
              active = false;
              canceled = false;
              activeConfig = null;
            }
            return {
              triggerReleased,
              ended,
              canceled: ended ? wasCanceled : canceled
            };
          }
          function reset() {
            pressed.clear();
            triggerTokens.clear();
            active = false;
            canceled = false;
            activeConfig = null;
          }
          function getState() {
            return {
              active,
              canceled,
              pressedCount: pressed.size,
              triggerCount: triggerTokens.size
            };
          }
          return { keyDown, keyUp, reset, getState };
        }
        function buildFullKey(config) {
          const cfg = normalizeTriggerConfig(config);
          const modifiers = (cfg.modifiers || []).map(keyLabel).sort().join("+");
          return modifiers ? `${modifiers}+${keyLabel(cfg.key)}` : keyLabel(cfg.key);
        }
        function checkShortcutConflict(config, platform) {
          const cfg = normalizeTriggerConfig(config);
          const fullKey = buildFullKey(cfg);
          const warnings = [];
          const errors = [];
          if (platform.isMac && cfg.key === "Meta") {
            errors.push("Mac \u4E0A Command \u952E\u4F1A\u88AB\u7CFB\u7EDF\u5360\u7528\uFF0C\u4E0D\u80FD\u53EF\u9760\u5730\u7528\u4F5C\u5355\u952E\u89E6\u53D1\u3002");
          }
          if (platform.isMac && cfg.modifiers && cfg.modifiers.includes("Meta")) {
            warnings.push("Mac \u4E0A Cmd \u7EC4\u5408\u952E\u5E38\u88AB\u7CFB\u7EDF\u6216\u6D4F\u89C8\u5668\u62E6\u622A\u3002");
          }
          if (cfg.type === "single" && cfg.key === "Shift") {
            warnings.push("Shift \u5355\u952E\u5E38\u4E0E\u8F93\u5165\u6CD5\u5207\u6362\u51B2\u7A81\u3002");
          }
          if (cfg.type === "single" && cfg.key === " ") {
            warnings.push("Space \u5355\u952E\u4F1A\u5F71\u54CD\u9875\u9762\u6EDA\u52A8\u3002");
          }
          if (cfg.type === "single" && cfg.key === "Control") {
            warnings.push("Ctrl \u5355\u952E\u5728\u90E8\u5206\u573A\u666F\u4E0B\u4F1A\u88AB\u6D4F\u89C8\u5668\u6216\u7CFB\u7EDF\u62E6\u622A\u3002");
          }
          if (cfg.type === "single" && cfg.key === "Alt") {
            warnings.push("Alt \u5355\u952E\u53EF\u80FD\u89E6\u53D1\u6D4F\u89C8\u5668\u83DC\u5355\u6216\u6743\u9650\u6C14\u6CE1\uFF0C\u7A33\u5B9A\u6027\u901A\u5E38\u4E0D\u5982 Alt+Q\u3002");
          }
          if (platform.browserShortcuts && platform.browserShortcuts[fullKey]) {
            warnings.push(`\u4E0E\u6D4F\u89C8\u5668\u5FEB\u6377\u952E\u51B2\u7A81\uFF1A${platform.browserShortcuts[fullKey]}\uFF08${fullKey}\uFF09`);
          }
          if (platform.winShortcuts && platform.isWin && platform.winShortcuts[fullKey]) {
            warnings.push(`\u4E0E Windows \u7CFB\u7EDF\u70ED\u952E\u51B2\u7A81\uFF1A${platform.winShortcuts[fullKey]}\uFF08${fullKey}\uFF09`);
          }
          if (platform.macShortcuts && platform.isMac && platform.macShortcuts[fullKey]) {
            warnings.push(`\u4E0E macOS \u7CFB\u7EDF\u70ED\u952E\u51B2\u7A81\uFF1A${platform.macShortcuts[fullKey]}\uFF08${fullKey}\uFF09`);
          }
          if (platform.imeShortcuts) {
            const singleKey = keyLabel(cfg.key);
            if (cfg.type === "single" && platform.imeShortcuts[singleKey]) {
              warnings.push(`\u4E0E\u8F93\u5165\u6CD5\u70ED\u952E\u51B2\u7A81\uFF1A${platform.imeShortcuts[singleKey]}`);
            }
            if (platform.imeShortcuts[fullKey]) {
              warnings.push(`\u4E0E\u8F93\u5165\u6CD5\u70ED\u952E\u51B2\u7A81\uFF1A${platform.imeShortcuts[fullKey]}`);
            }
          }
          return { warnings, errors, fullKey };
        }
        const api = {
          MOD_KEYS,
          KEY_TO_CODE,
          keyLabel,
          makeLabel,
          normalizeTriggerConfig,
          buildTriggerConfigFromPreset,
          matchesTriggerPreset,
          isModifier,
          matchesConfiguredMainKey,
          isEventPartOfTrigger,
          matchesTriggerFromKeyboardEvent,
          matchesTriggerFromForwardedEvent,
          createShortcutSession,
          checkShortcutConflict
        };
        if (typeof module !== "undefined" && module.exports) module.exports = api;
        global.TfaShortcutLogic = api;
      })(typeof globalThis !== "undefined" ? globalThis : exports);
    }
  });

  // src/shared/runtime-contract.js
  var require_runtime_contract = __commonJS({
    "src/shared/runtime-contract.js"(exports, module) {
      (function(global) {
        const FRAME_BRIDGE_FILES = ["frame_bridge.js"];
        const TOP_FRAME_BOOTSTRAP_FILES = ["content_bootstrap.js"];
        const TOP_FRAME_FEATURE_FILES = Object.freeze({
          web_dock: Object.freeze(["web_dock.js"]),
          workspace: Object.freeze(["workspace.js"]),
          guidance: Object.freeze(["guidance.js"])
        });
        const TOP_FRAME_FILES = TOP_FRAME_BOOTSTRAP_FILES;
        const CONTENT_SCRIPT_FILES = TOP_FRAME_BOOTSTRAP_FILES;
        const MANIFEST_LOAD_PHASES = Object.freeze({
          frameBridge: "document_start",
          topFrame: "document_start",
          pageWorld: "document_start"
        });
        const api = {
          FRAME_BRIDGE_FILES,
          TOP_FRAME_BOOTSTRAP_FILES,
          TOP_FRAME_FEATURE_FILES,
          TOP_FRAME_FILES,
          CONTENT_SCRIPT_FILES,
          MANIFEST_LOAD_PHASES
        };
        if (typeof module !== "undefined" && module.exports) module.exports = api;
        global.TfaRuntimeContract = api;
      })(typeof globalThis !== "undefined" ? globalThis : exports);
    }
  });

  // src/popup/popup.js
  var require_popup = __commonJS({
    "src/popup/popup.js"() {
      var STORE_KEY = "tfa_settings";
      var MIDDLE_KEY = "tfa_middle_trigger";
      var HOLD_KEY = "tfa_hold_threshold";
      var LANGUAGE_KEY = "tfa_language";
      var THEME_KEY = "tfa_theme";
      var DEFAULTS = { type: "single", key: "Alt", modifiers: [], label: "Alt" };
      var ShortcutLogic = globalThis.TfaShortcutLogic;
      var {
        KEY_TO_CODE,
        keyLabel,
        isModifier,
        makeLabel,
        normalizeTriggerConfig,
        buildTriggerConfigFromPreset,
        matchesTriggerPreset,
        checkShortcutConflict
      } = ShortcutLogic;
      var POPUP_COPY = {
        zh: {
          documentTitle: "TabFlow \u5FEB\u6377\u952E\u8BBE\u7F6E",
          appTitle: "\u6D6E\u5C42\u9875\u7B7E\u7BA1\u7406\u5668",
          settingsChip: "\u6269\u5C55\u8BBE\u7F6E",
          appSubtitle: "\u8BBE\u7F6E\u5524\u8D77\u65B9\u5F0F\uFF0C\u7BA1\u7406\u5355\u952E\u4E0E\u7EC4\u5408\u952E\u89E6\u53D1\u3002",
          recommendedShortcut: "\u63A8\u8350\u5FEB\u6377\u952E",
          browserLevelTrigger: "\u6D4F\u89C8\u5668\u7EA7\u89E6\u53D1",
          currentShortcut: "\u5F53\u524D\u5FEB\u6377\u952E",
          currentShortcutHint: "\u70B9\u51FB\u6309\u952E\u6846\uFF0C\u6309\u4E0B\u4EFB\u610F\u952E\u6216\u7EC4\u5408\u952E",
          keycapStart: "\u70B9\u51FB\u5F00\u59CB\u8BBE\u7F6E",
          keycapTitle: "\u8BBE\u7F6E\u5F53\u524D\u5FEB\u6377\u952E",
          keycapAria: "\u8BBE\u7F6E\u5F53\u524D\u5FEB\u6377\u952E",
          singleTrigger: "\u5355\u952E\u89E6\u53D1",
          singleTriggerHint: "\u6309\u4F4F\u8FBE\u5230\u8BBE\u5B9A\u65F6\u957F\u540E\uFF0C\u677E\u5F00\u5373\u53EF\u4FDD\u6301\u5F00\u542F",
          enableSingle: "\u542F\u7528\u5355\u952E\u89E6\u53D1",
          comboTrigger: "\u7EC4\u5408\u952E\u89E6\u53D1",
          comboTriggerHint: "\u70B9\u6309\u4E00\u6B21\u5524\u8D77\uFF0C\u518D\u6309\u4E00\u6B21\u6216\u6309 Esc \u5173\u95ED",
          enableCombo: "\u542F\u7528\u7EC4\u5408\u952E\u89E6\u53D1",
          holdDuration: "\u6309\u4F4F\u65F6\u957F",
          holdSlider: "\u5355\u952E\u6309\u4F4F\u65F6\u957F",
          holdHint: "\u5355\u952E\u6309\u4F4F {seconds} \u79D2\u677E\u5F00\u4FDD\u6301\uFF0C\u5426\u5219\u677E\u5F00\u5373\u5173",
          holdValue: "{seconds} \u79D2",
          middleTrigger: "\u9F20\u6807\u4E2D\u952E\u89E6\u53D1",
          middleTriggerHint: "\u6309\u4E0B\u4E2D\u952E\u76F4\u63A5\u56FA\u5B9A\u6D6E\u5C42\uFF0C\u518D\u6309\u4E00\u6B21\u5173\u95ED",
          enableMiddle: "\u542F\u7528\u4E2D\u952E\u89E6\u53D1",
          guidanceTest: "\u5F15\u5BFC\u6D6E\u5C42\u6D4B\u8BD5",
          guidanceTestHint: "\u624B\u52A8\u663E\u793A\u4E09\u7C7B\u4E3B\u52A8\u63D0\u9192\uFF0C\u6216\u5FEB\u901F\u521B\u5EFA\u9875\u7B7E\u6570\u91CF\u6D4B\u8BD5\u7A97\u53E3",
          frequentSwitchPrompt: "\u9891\u7E41\u5207\u6362\u63D0\u9192",
          startupPrompt: "\u6D4F\u89C8\u5668\u542F\u52A8\u63D0\u9192",
          overloadPrompt: "\u9875\u7B7E\u8FC7\u591A\u63D0\u9192",
          open19Pages: "\u65B0\u7A97\u53E3\u6253\u5F00 19 \u9875",
          open20Pages: "\u65B0\u7A97\u53E3\u6253\u5F00 20 \u9875",
          singleNote: "\u6309\u4F4F\u5524\u8D77\uFF0C\u8FBE\u5230\u8BBE\u5B9A\u65F6\u957F\u540E\u677E\u5F00\uFF0C\u6D6E\u5C42\u4F1A\u4FDD\u6301\u5F00\u542F\u3002",
          comboNote: "\u70B9\u6309\u4E00\u6B21\u5524\u8D77\uFF0C\u518D\u6309\u4E00\u6B21\u6216\u6309 Esc \u5173\u95ED\u3002",
          stableMethod: "\u66F4\u7A33\u5B9A\u7684\u65B9\u5F0F",
          stableMethodNote: "\u6D4F\u89C8\u5668\u7EA7\u5FEB\u6377\u952E\u66F4\u7A33\uFF0C\u53EF\u5728 chrome://extensions/shortcuts \u4E2D\u8BBE\u7F6E Alt + Q\u3002",
          statusIdle: "\u64CD\u4F5C\u7ED3\u679C\u4F1A\u663E\u793A\u5728\u8FD9\u91CC",
          save: "\u4FDD\u5B58",
          saveTitle: "\u4FDD\u5B58\u5FEB\u6377\u952E\u8BBE\u7F6E",
          saving: "\u4FDD\u5B58\u4E2D...",
          testNow: "\u7ACB\u5373\u6D4B\u8BD5",
          conflictUnavailable: "\u26A0 \u4E0D\u53EF\u7528",
          conflictCaution: "\u26A0 \u6CE8\u610F",
          conflictClear: "\u2713 \u65E0\u51B2\u7A81",
          conflictClearDetail: "\u8BE5\u5FEB\u6377\u952E\u65E0\u5DF2\u77E5\u51B2\u7A81",
          conflictMacMetaSingle: "Mac \u4E0A Command \u952E\u4F1A\u88AB\u7CFB\u7EDF\u5360\u7528\uFF0C\u4E0D\u80FD\u53EF\u9760\u5730\u7528\u4F5C\u5355\u952E\u89E6\u53D1\u3002",
          conflictMacMetaCombo: "Mac \u4E0A Cmd \u7EC4\u5408\u952E\u5E38\u88AB\u7CFB\u7EDF\u6216\u6D4F\u89C8\u5668\u62E6\u622A\u3002",
          conflictShift: "Shift \u5355\u952E\u5E38\u4E0E\u8F93\u5165\u6CD5\u5207\u6362\u51B2\u7A81\u3002",
          conflictSpace: "Space \u5355\u952E\u4F1A\u5F71\u54CD\u9875\u9762\u6EDA\u52A8\u3002",
          conflictControl: "Ctrl \u5355\u952E\u5728\u90E8\u5206\u573A\u666F\u4E0B\u4F1A\u88AB\u6D4F\u89C8\u5668\u6216\u7CFB\u7EDF\u62E6\u622A\u3002",
          conflictAlt: "Alt \u5355\u952E\u53EF\u80FD\u89E6\u53D1\u6D4F\u89C8\u5668\u83DC\u5355\u6216\u6743\u9650\u6C14\u6CE1\uFF0C\u7A33\u5B9A\u6027\u901A\u5E38\u4E0D\u5982 Alt+Q\u3002",
          listeningWithModifier: "+ \u6309\u4E00\u4E2A\u952E\u2026\uFF08\u677E\u5F00=\u5355\u4FEE\u9970\u952E\uFF09",
          listening: "\u6309\u4E0B\u4EFB\u610F\u952E\u6216\u7EC4\u5408\u952E\u2026",
          keycapListeningAria: "\u6B63\u5728\u5F55\u5236\u5FEB\u6377\u952E\uFF0C\u6309\u4E0B\u4EFB\u610F\u952E\u6216\u7EC4\u5408\u952E",
          reservedKey: "\u8BE5\u952E\u4E0D\u53EF\u7528\uFF0C\u8BF7\u6309\u5176\u4ED6\u952E\u2026",
          singleSummary: "\u5355\u952E {key}\uFF08\u6309\u4F4F{seconds}\u79D2\uFF09",
          comboSummary: "\u7EC4\u5408\u952E Alt+Q\uFF08\u70B9\u6309\u5207\u6362\uFF09",
          noShortcut: "\u65E0\u5FEB\u6377\u952E",
          middleSummary: " \xB7 \u4E2D\u952E\u89E6\u53D1\u5DF2\u5F00\u542F",
          savedApplied: "\u5DF2\u4FDD\u5B58\uFF1A{summary}{middle}\uFF08\u5DF2\u5E94\u7528\u5230\u6240\u6709\u7F51\u9875\uFF09",
          saveSuccess: "\u4FDD\u5B58\u6210\u529F",
          unknownReason: "\u672A\u77E5\u539F\u56E0",
          saveFailed: "\u4FDD\u5B58\u5931\u8D25\uFF1A{reason}",
          guidanceFailed: "\u5F15\u5BFC\u6D6E\u5C42\u89E6\u53D1\u5931\u8D25",
          guidanceFailedReason: "\u5F15\u5BFC\u6D6E\u5C42\u89E6\u53D1\u5931\u8D25\uFF1A{reason}",
          openedTestPages: "\u5DF2\u5728\u65B0\u7A97\u53E3\u6253\u5F00 {count} \u4E2A\u767E\u5EA6\u9875\u9762",
          testWindowFailed: "\u6D4B\u8BD5\u7A97\u53E3\u521B\u5EFA\u5931\u8D25",
          testWindowFailedReason: "\u6D4B\u8BD5\u7A97\u53E3\u521B\u5EFA\u5931\u8D25\uFF1A{reason}",
          noActiveTab: "\u627E\u4E0D\u5230\u5F53\u524D\u9875\u7B7E",
          restrictedPage: "\u8BE5\u9875\u9762\u4E0D\u652F\u6301\u6CE8\u5165\uFF0C\u8BF7\u5207\u5230\u666E\u901A\u7F51\u9875",
          toggleFailed: "\u6D6E\u5C42\u5524\u8D77\u5931\u8D25",
          toggleFailedReason: "\u6D6E\u5C42\u5524\u8D77\u5931\u8D25\uFF1A{reason}"
        },
        en: {
          documentTitle: "TabFlow shortcut settings",
          appTitle: "TabFlow shortcut manager",
          settingsChip: "Extension settings",
          appSubtitle: "Choose how to open TabFlow with a single key or key combination.",
          recommendedShortcut: "Recommended shortcut",
          browserLevelTrigger: "Browser-level trigger",
          currentShortcut: "Current shortcut",
          currentShortcutHint: "Select the key field, then press any key or key combination",
          keycapStart: "Select to set a shortcut",
          keycapTitle: "Set current shortcut",
          keycapAria: "Set current shortcut",
          singleTrigger: "Single-key trigger",
          singleTriggerHint: "Hold the key for the configured time, then release to keep TabFlow open",
          enableSingle: "Enable single-key trigger",
          comboTrigger: "Key-combination trigger",
          comboTriggerHint: "Press once to open; press again or press Esc to close",
          enableCombo: "Enable key-combination trigger",
          holdDuration: "Hold duration",
          holdSlider: "Single-key hold duration",
          holdHint: "Hold a single key for {seconds} seconds to keep TabFlow open; release sooner to close it",
          holdValue: "{seconds} seconds",
          middleTrigger: "Middle-click trigger",
          middleTriggerHint: "Middle-click to pin TabFlow; middle-click again to close",
          enableMiddle: "Enable middle-click trigger",
          guidanceTest: "Guidance prompt tests",
          guidanceTestHint: "Show one of the three prompts or quickly create a tab-count test window",
          frequentSwitchPrompt: "Frequent-switch prompt",
          startupPrompt: "Browser-startup prompt",
          overloadPrompt: "Too-many-tabs prompt",
          open19Pages: "Open 19 pages in a new window",
          open20Pages: "Open 20 pages in a new window",
          singleNote: "Hold to open TabFlow. Release after the set duration to keep it open.",
          comboNote: "Press once to open; press again or press Esc to close.",
          stableMethod: "Most reliable option",
          stableMethodNote: "For a browser-level shortcut, set Alt + Q at chrome://extensions/shortcuts.",
          statusIdle: "Results will appear here",
          save: "Save",
          saveTitle: "Save shortcut settings",
          saving: "Saving...",
          testNow: "Test now",
          conflictUnavailable: "\u26A0 Unavailable",
          conflictCaution: "\u26A0 Caution",
          conflictClear: "\u2713 No conflict",
          conflictClearDetail: "No known conflicts were found for this shortcut",
          conflictMacMetaSingle: "macOS reserves the Command key, so it is not reliable as a single-key trigger.",
          conflictMacMetaCombo: "macOS or the browser may intercept combinations that use Command.",
          conflictShift: "Shift as a single key often conflicts with input-method switching.",
          conflictSpace: "Space as a single key affects page scrolling.",
          conflictControl: "The browser or operating system may intercept Ctrl as a single key.",
          conflictAlt: "Alt may open browser menus or permission bubbles and is usually less reliable than Alt+Q.",
          conflictBrowser: "Conflicts with a browser shortcut ({key}).",
          conflictWindows: "Conflicts with a Windows system shortcut ({key}).",
          conflictMac: "Conflicts with a macOS system shortcut ({key}).",
          conflictIme: "Conflicts with an input-method shortcut.",
          listeningWithModifier: "+ press a key\u2026 (release to use only the modifier)",
          listening: "Press any key or key combination\u2026",
          keycapListeningAria: "Recording a shortcut; press any key or key combination",
          reservedKey: "That key is unavailable. Press another key\u2026",
          singleSummary: "Single key {key} (hold for {seconds}s)",
          comboSummary: "Combination Alt+Q (press to toggle)",
          noShortcut: "No shortcut",
          middleSummary: " \xB7 Middle-click trigger enabled",
          savedApplied: "Saved: {summary}{middle} (applied to all web pages)",
          saveSuccess: "Saved successfully",
          unknownReason: "Unknown reason",
          saveFailed: "Could not save: {reason}",
          guidanceFailed: "Could not show the guidance prompt",
          guidanceFailedReason: "Could not show the guidance prompt: {reason}",
          openedTestPages: "Opened {count} Baidu pages in a new window",
          testWindowFailed: "Could not create the test window",
          testWindowFailedReason: "Could not create the test window: {reason}",
          noActiveTab: "Could not find the active tab",
          restrictedPage: "This page does not allow injection. Switch to a regular web page.",
          toggleFailed: "Could not open TabFlow",
          toggleFailedReason: "Could not open TabFlow: {reason}"
        }
      };
      function normalizeLanguagePreference(value) {
        const normalized = String(value || "").trim().toLowerCase();
        if (normalized === "en" || normalized.startsWith("en-")) return "en";
        if (normalized === "zh" || normalized.startsWith("zh-") || normalized.startsWith("zh_")) return "zh";
        return "system";
      }
      function browserLanguage() {
        const value = chrome.i18n?.getUILanguage?.() || navigator.language || "zh-CN";
        return String(value).toLowerCase().startsWith("zh") ? "zh" : "en";
      }
      var languagePreference = "system";
      var currentLanguage = browserLanguage();
      var themePreference = "system";
      var currentStatus = { key: "statusIdle", params: null };
      var languagePreferenceRevision = 0;
      var themePreferenceRevision = 0;
      var themeWriteQueue = Promise.resolve();
      var themeLastQueuedRevision = -1;
      function t(key, params = null) {
        let value = POPUP_COPY[currentLanguage]?.[key] || POPUP_COPY.zh[key] || key;
        if (params) {
          value = value.replace(/\{(\w+)\}/g, (_, name) => Object.prototype.hasOwnProperty.call(params, name) ? String(params[name]) : `{${name}}`);
        }
        return value;
      }
      function normalizeThemePreference(value) {
        const normalized = String(value || "").trim().toLowerCase();
        if (normalized === "system") return { value: "system", migrated: false };
        if (normalized === "dark") return { value: "dark", migrated: false };
        if (normalized === "light") return { value: "light", migrated: false };
        if (["noir", "ocean", "space", "crypto"].includes(normalized)) return { value: "dark", migrated: true };
        if (["snow", "paper", "pro"].includes(normalized)) return { value: "light", migrated: true };
        return { value: "system", migrated: false };
      }
      function persistThemePreference(value, expectedRevision = null) {
        const queuedRevision = themePreferenceRevision;
        themeLastQueuedRevision = Math.max(themeLastQueuedRevision, queuedRevision);
        const operation = themeWriteQueue.then(async () => {
          if (expectedRevision != null && expectedRevision !== themePreferenceRevision) return false;
          try {
            await chrome.storage.sync.set({ [THEME_KEY]: value });
          } catch (_) {
            return false;
          }
          const current2 = expectedRevision == null || expectedRevision === themePreferenceRevision;
          if (!current2 && themeLastQueuedRevision < themePreferenceRevision) {
            void persistThemePreference(themePreference, themePreferenceRevision);
          }
          return current2;
        });
        themeWriteQueue = operation.catch(() => false);
        return operation;
      }
      function migrateThemePreferenceBestEffort(value, expectedRevision = themePreferenceRevision) {
        void persistThemePreference(value, expectedRevision);
      }
      var elKeycap = document.getElementById("keycap");
      var presetChips = Array.from(document.querySelectorAll(".preset .chip"));
      var elSave = document.getElementById("save");
      var elTest = document.getElementById("test");
      var elStatus = document.getElementById("status");
      var elToastContainer = document.getElementById("toastContainer");
      var elMiddleToggle = document.getElementById("middleToggle");
      var elHoldSlider = document.getElementById("holdSlider");
      var elHoldVal = document.getElementById("holdVal");
      var elHoldHint = document.getElementById("holdHint");
      var elSingleToggle = document.getElementById("singleToggle");
      var elComboToggle = document.getElementById("comboToggle");
      var guidancePromptButtons = Array.from(document.querySelectorAll("[data-guidance-prompt]"));
      var guidanceWindowButtons = Array.from(document.querySelectorAll("[data-guidance-window]"));
      var current = { ...DEFAULTS };
      var pending = { ...DEFAULTS };
      var middleEnabled = true;
      var holdThreshold = 2e3;
      var singleEnabled = true;
      var comboEnabled = true;
      var saveInFlight = false;
      var listening = false;
      var heldMods = /* @__PURE__ */ new Set();
      var firstMod = null;
      var TOAST_ICONS = {
        success: "\u2713",
        error: "!",
        info: "i"
      };
      var RESERVED_KEYS = /* @__PURE__ */ new Set([
        "F1",
        "F2",
        "F3",
        "F4",
        "F5",
        "F6",
        "F7",
        "F8",
        "F9",
        "F10",
        "F11",
        "F12",
        "PrintScreen",
        "ScrollLock",
        "Pause",
        "Insert",
        "Home",
        "PageUp",
        "PageDown",
        "End",
        "ArrowUp",
        "ArrowDown",
        "ArrowLeft",
        "ArrowRight",
        "CapsLock",
        "NumLock"
      ]);
      var isMac = /^Mac/i.test(navigator.platform || navigator.userAgentData?.platform || "");
      var isWin = /^Win/i.test(navigator.platform || navigator.userAgentData?.platform || "");
      var colorSchemeQuery = window.matchMedia?.("(prefers-color-scheme: dark)") || null;
      var BROWSER_SHORTCUTS = {
        "Ctrl+C": "\u590D\u5236",
        "Ctrl+V": "\u7C98\u8D34",
        "Ctrl+X": "\u526A\u5207",
        "Ctrl+A": "\u5168\u9009",
        "Ctrl+Z": "\u64A4\u9500",
        "Ctrl+Y": "\u91CD\u505A",
        "Ctrl+Shift+Z": "\u91CD\u505A\uFF08\u90E8\u5206\u5E94\u7528\uFF09",
        "Ctrl+T": "\u65B0\u5EFA\u6807\u7B7E\u9875",
        "Ctrl+W": "\u5173\u95ED\u6807\u7B7E\u9875",
        "Ctrl+N": "\u65B0\u7A97\u53E3",
        "Ctrl+Shift+N": "\u65E0\u75D5\u7A97\u53E3",
        "Ctrl+Tab": "\u5207\u6362\u6807\u7B7E\u9875",
        "Ctrl+Shift+T": "\u6062\u590D\u5173\u95ED\u7684\u6807\u7B7E\u9875",
        "Ctrl+L": "\u805A\u7126\u5730\u5740\u680F",
        "Ctrl+D": "\u6DFB\u52A0\u4E66\u7B7E",
        "Ctrl+H": "\u5386\u53F2\u8BB0\u5F55",
        "Ctrl+J": "\u4E0B\u8F7D",
        "Ctrl+F": "\u9875\u9762\u67E5\u627E",
        "Ctrl+G": "\u67E5\u627E\u4E0B\u4E00\u4E2A",
        "Ctrl+R": "\u5237\u65B0",
        "Ctrl+Shift+R": "\u786C\u5237\u65B0",
        "Ctrl+Plus": "\u653E\u5927",
        "Ctrl+Minus": "\u7F29\u5C0F",
        "Ctrl+0": "\u91CD\u7F6E\u7F29\u653E",
        "Ctrl+P": "\u6253\u5370",
        "Ctrl+S": "\u4FDD\u5B58",
        "Ctrl+O": "\u6253\u5F00\u6587\u4EF6",
        "Ctrl+U": "\u67E5\u770B\u6E90\u7801",
        "Ctrl+K": "\u641C\u7D22",
        "Ctrl+E": "\u641C\u7D22",
        "Alt+F": "\u83DC\u5355",
        "Alt+Home": "\u4E3B\u9875",
        "Alt+Left": "\u540E\u9000",
        "Alt+Right": "\u524D\u8FDB",
        "Alt+F4": "\u5173\u95ED\u6D4F\u89C8\u5668\uFF08Windows\uFF09",
        "Shift+Escape": "\u4EFB\u52A1\u7BA1\u7406\u5668",
        "F11": "\u5168\u5C4F",
        "F12": "\u5F00\u53D1\u8005\u5DE5\u5177",
        "Ctrl+Shift+I": "\u5F00\u53D1\u8005\u5DE5\u5177",
        "Ctrl+Shift+J": "\u63A7\u5236\u53F0",
        "Ctrl+Shift+C": "\u68C0\u67E5\u5143\u7D20",
        "Ctrl+Shift+Delete": "\u6E05\u9664\u6D4F\u89C8\u6570\u636E"
      };
      var WIN_SYSTEM_SHORTCUTS = {
        "Ctrl+Shift+Esc": "\u4EFB\u52A1\u7BA1\u7406\u5668",
        "Alt+Tab": "\u5207\u6362\u7A97\u53E3",
        "Win+Tab": "\u4EFB\u52A1\u89C6\u56FE",
        "Win+D": "\u663E\u793A\u684C\u9762",
        "Win+E": "\u8D44\u6E90\u7BA1\u7406\u5668",
        "Win+L": "\u9501\u5C4F",
        "Win+R": "\u8FD0\u884C",
        "Win+Space": "\u5207\u6362\u8F93\u5165\u6CD5",
        "Ctrl+Space": "\u5207\u6362\u8F93\u5165\u6CD5\uFF08\u90E8\u5206\u8F93\u5165\u6CD5\uFF09",
        "Shift": "\u5207\u6362\u4E2D\u82F1\u6587\uFF08\u90E8\u5206\u8F93\u5165\u6CD5\uFF09",
        "Ctrl+Shift": "\u5207\u6362\u8F93\u5165\u6CD5",
        "Alt+Shift": "\u5207\u6362\u8F93\u5165\u6CD5\u8BED\u8A00"
      };
      var MAC_SYSTEM_SHORTCUTS = {
        "Meta+Q": "\u9000\u51FA\u5E94\u7528",
        "Meta+W": "\u5173\u95ED\u7A97\u53E3",
        "Meta+T": "\u65B0\u5EFA\u6807\u7B7E\u9875",
        "Meta+N": "\u65B0\u7A97\u53E3",
        "Meta+Shift+N": "\u65E0\u75D5\u7A97\u53E3",
        "Meta+Space": "Spotlight \u641C\u7D22",
        "Meta+Tab": "\u5207\u6362\u5E94\u7528",
        "Meta+Shift+Tab": "\u53CD\u5411\u5207\u6362\u5E94\u7528",
        "Ctrl+Space": "\u5207\u6362\u8F93\u5165\u6CD5",
        "Ctrl+Shift+Space": "\u6269\u5C55\u8F93\u5165\u6CD5\u9009\u8BCD",
        "F11": "\u663E\u793A\u684C\u9762",
        "F12": "Dashboard"
      };
      var IME_SHORTCUTS = {
        "Ctrl+Space": "\u5207\u6362\u4E2D\u82F1\u6587\uFF08\u641C\u72D7/\u5FAE\u8F6F\u62FC\u97F3\u7B49\uFF09",
        "Shift": "\u5207\u6362\u4E2D\u82F1\u6587\uFF08\u641C\u72D7/\u5FAE\u8F6F\u62FC\u97F3\u7B49\uFF09",
        "Ctrl+Shift": "\u5207\u6362\u8F93\u5165\u6CD5",
        "Ctrl+.": "\u5207\u6362\u6807\u70B9\u7B26\u53F7",
        "Ctrl+,": "\u8F93\u5165\u6CD5\u8BBE\u7F6E"
      };
      function applyTheme() {
        const isDark = themePreference === "dark" || themePreference === "system" && colorSchemeQuery?.matches === true;
        document.documentElement.dataset.theme = isDark ? "dark" : "light";
      }
      function setThemePreference(value) {
        themePreference = normalizeThemePreference(value).value;
        applyTheme();
      }
      function updateStatusTranslation() {
        if (currentStatus?.key) elStatus.textContent = t(currentStatus.key, currentStatus.params);
        else if (currentStatus?.raw) elStatus.textContent = currentStatus.raw;
      }
      function applyLanguage(value = languagePreference) {
        languagePreference = normalizeLanguagePreference(value);
        currentLanguage = languagePreference === "system" ? browserLanguage() : languagePreference;
        document.documentElement.lang = currentLanguage === "en" ? "en" : "zh-CN";
        document.title = t("documentTitle");
        document.querySelectorAll("[data-i18n]").forEach((element) => {
          element.textContent = t(element.dataset.i18n);
        });
        document.querySelectorAll("[data-i18n-title]").forEach((element) => {
          element.setAttribute("title", t(element.dataset.i18nTitle));
        });
        document.querySelectorAll("[data-i18n-aria-label]").forEach((element) => {
          element.setAttribute("aria-label", t(element.dataset.i18nAriaLabel));
        });
        setSaveBusy(saveInFlight);
        updateHoldSlider();
        updateStatusTranslation();
        render();
      }
      function getErrorMessage(error, fallback) {
        const message = error && typeof error === "object" && "message" in error ? String(error.message || "") : String(error || "");
        return message.trim() || fallback;
      }
      function setSaveBusy(isBusy) {
        saveInFlight = isBusy;
        elSave.disabled = isBusy;
        elSave.textContent = isBusy ? t("saving") : t("save");
      }
      function showToast(msg, type = "info", duration = 2200) {
        if (!elToastContainer || !msg) return;
        const toast = document.createElement("div");
        toast.className = "toast toast-" + type;
        toast.setAttribute("role", type === "error" ? "alert" : "status");
        toast.innerHTML = `<span class="toast-icon">${TOAST_ICONS[type] || TOAST_ICONS.info}</span><span>${msg}</span>`;
        elToastContainer.appendChild(toast);
        while (elToastContainer.children.length > 3) {
          elToastContainer.removeChild(elToastContainer.firstElementChild);
        }
        requestAnimationFrame(() => toast.classList.add("show"));
        window.setTimeout(() => {
          toast.classList.add("hide");
          toast.classList.remove("show");
          window.setTimeout(() => toast.remove(), 220);
        }, duration);
      }
      function checkConflict(cfg) {
        return checkShortcutConflict(cfg, {
          isMac,
          isWin,
          keyboardLockSupported: !!(navigator.keyboard && navigator.keyboard.lock),
          browserShortcuts: BROWSER_SHORTCUTS,
          winShortcuts: WIN_SYSTEM_SHORTCUTS,
          macShortcuts: MAC_SYSTEM_SHORTCUTS,
          imeShortcuts: IME_SHORTCUTS
        });
      }
      var CONFLICT_COPY_KEYS = /* @__PURE__ */ new Map([
        ["Mac \u4E0A Command \u952E\u4F1A\u88AB\u7CFB\u7EDF\u5360\u7528\uFF0C\u4E0D\u80FD\u53EF\u9760\u5730\u7528\u4F5C\u5355\u952E\u89E6\u53D1\u3002", "conflictMacMetaSingle"],
        ["Mac \u4E0A Cmd \u7EC4\u5408\u952E\u5E38\u88AB\u7CFB\u7EDF\u6216\u6D4F\u89C8\u5668\u62E6\u622A\u3002", "conflictMacMetaCombo"],
        ["Shift \u5355\u952E\u5E38\u4E0E\u8F93\u5165\u6CD5\u5207\u6362\u51B2\u7A81\u3002", "conflictShift"],
        ["Space \u5355\u952E\u4F1A\u5F71\u54CD\u9875\u9762\u6EDA\u52A8\u3002", "conflictSpace"],
        ["Ctrl \u5355\u952E\u5728\u90E8\u5206\u573A\u666F\u4E0B\u4F1A\u88AB\u6D4F\u89C8\u5668\u6216\u7CFB\u7EDF\u62E6\u622A\u3002", "conflictControl"],
        ["Alt \u5355\u952E\u53EF\u80FD\u89E6\u53D1\u6D4F\u89C8\u5668\u83DC\u5355\u6216\u6743\u9650\u6C14\u6CE1\uFF0C\u7A33\u5B9A\u6027\u901A\u5E38\u4E0D\u5982 Alt+Q\u3002", "conflictAlt"]
      ]);
      function localizeConflict(message) {
        if (currentLanguage !== "en") return message;
        const directKey = CONFLICT_COPY_KEYS.get(message);
        if (directKey) return t(directKey);
        let match = String(message).match(/^与浏览器快捷键冲突：.+（(.+)）$/);
        if (match) return t("conflictBrowser", { key: match[1] });
        match = String(message).match(/^与 Windows 系统热键冲突：.+（(.+)）$/);
        if (match) return t("conflictWindows", { key: match[1] });
        match = String(message).match(/^与 macOS 系统热键冲突：.+（(.+)）$/);
        if (match) return t("conflictMac", { key: match[1] });
        if (String(message).startsWith("\u4E0E\u8F93\u5165\u6CD5\u70ED\u952E\u51B2\u7A81\uFF1A")) return t("conflictIme");
        return message;
      }
      function renderConflictWarn(cfg) {
        const el = document.getElementById("conflictWarn");
        if (!el) return;
        const { warnings, errors } = checkConflict(cfg);
        if (errors.length > 0) {
          el.className = "conflict-warn error";
          el.innerHTML = `<b>${t("conflictUnavailable")}</b><br>` + errors.map(localizeConflict).join("<br>");
          el.style.display = "block";
        } else if (warnings.length > 0) {
          el.className = "conflict-warn warn";
          el.innerHTML = `<b>${t("conflictCaution")}</b><br>` + warnings.map(localizeConflict).join("<br>");
          el.style.display = "block";
        } else {
          el.className = "conflict-warn ok";
          el.innerHTML = `<b>${t("conflictClear")}</b> ${t("conflictClearDetail")}`;
          el.style.display = "block";
        }
      }
      function keyDisplay(cfg) {
        if (cfg.type === "combo") {
          return (cfg.modifiers || []).map(keyLabel).join("+") + '<span style="opacity:.6"> + </span><b>' + keyLabel(cfg.key) + "</b>";
        }
        return "<b>" + keyLabel(cfg.key) + "</b>";
      }
      function render() {
        if (listening) {
          if (heldMods.size > 0) {
            elKeycap.innerHTML = [...heldMods].map(keyLabel).join(" + ") + ` <small>${t("listeningWithModifier")}</small>`;
          } else {
            elKeycap.innerHTML = `<small>${t("listening")}</small>`;
          }
        } else {
          elKeycap.innerHTML = keyDisplay(pending);
        }
        elKeycap.classList.toggle("listening", listening);
        elKeycap.setAttribute("aria-label", listening ? t("keycapListeningAria") : t("keycapAria"));
        presetChips.forEach((c) => {
          const preset = c.dataset.preset;
          c.classList.toggle("active", preset && matchesTriggerPreset(pending, preset));
        });
        if (!listening) {
          renderConflictWarn(pending);
        } else {
          const el = document.getElementById("conflictWarn");
          if (el) el.style.display = "none";
        }
      }
      async function load() {
        const languageRevisionAtRead = languagePreferenceRevision;
        const themeRevisionAtRead = themePreferenceRevision;
        let storedSettings = {};
        try {
          storedSettings = await chrome.storage.sync.get([
            STORE_KEY,
            MIDDLE_KEY,
            HOLD_KEY,
            LANGUAGE_KEY,
            THEME_KEY,
            "tfa_single_enabled",
            "tfa_combo_enabled"
          ]) || {};
        } catch (_) {
        }
        const {
          [STORE_KEY]: saved,
          [MIDDLE_KEY]: middleSaved,
          [HOLD_KEY]: holdSaved,
          [LANGUAGE_KEY]: languageSaved,
          [THEME_KEY]: themeSaved,
          tfa_single_enabled,
          tfa_combo_enabled
        } = storedSettings;
        if (languageRevisionAtRead === languagePreferenceRevision) {
          applyLanguage(languageSaved);
        }
        if (themeRevisionAtRead === themePreferenceRevision) {
          const normalizedTheme = normalizeThemePreference(themeSaved);
          themePreference = normalizedTheme.value;
          applyTheme();
          if (normalizedTheme.migrated) {
            migrateThemePreferenceBestEffort(normalizedTheme.value, themeRevisionAtRead);
          }
        }
        if (saved && saved.key) {
          current = normalizeTriggerConfig(saved);
        }
        pending = { ...current };
        middleEnabled = middleSaved !== false;
        updateMiddleToggle();
        if (typeof holdSaved === "number" && holdSaved >= 1e3 && holdSaved <= 5e3) {
          holdThreshold = holdSaved;
        }
        updateHoldSlider();
        singleEnabled = tfa_single_enabled !== false;
        comboEnabled = tfa_combo_enabled !== false;
        updateSingleToggle();
        updateComboToggle();
        render();
      }
      async function save() {
        if (saveInFlight) return;
        const cfg = normalizeTriggerConfig(pending);
        setSaveBusy(true);
        try {
          await chrome.storage.sync.set({
            [STORE_KEY]: cfg,
            [MIDDLE_KEY]: middleEnabled,
            [HOLD_KEY]: holdThreshold,
            tfa_single_enabled: singleEnabled,
            tfa_combo_enabled: comboEnabled
          });
          current = { ...cfg };
          elKeycap.classList.remove("listening");
          listening = false;
          heldMods.clear();
          firstMod = null;
          pending = { ...cfg };
          render();
          try {
            const tabs = await chrome.tabs.query({});
            for (const t2 of tabs) {
              if (/^(chrome|chrome-extension|edge|about|devtools|view-source):/i.test(t2.url || "")) continue;
              chrome.tabs.sendMessage(t2.id, {
                type: "APPLY_SETTINGS",
                settings: cfg,
                middleTrigger: middleEnabled,
                holdThreshold,
                singleEnabled,
                comboEnabled
              }).catch(() => {
              });
            }
          } catch (e) {
          }
          const holdSec = Math.round(holdThreshold / 1e3);
          const parts = [];
          if (singleEnabled) {
            parts.push(t("singleSummary", {
              key: cfg.type === "single" ? cfg.label : "E",
              seconds: holdSec
            }));
          }
          if (comboEnabled) parts.push(t("comboSummary"));
          if (!parts.length) parts.push(t("noShortcut"));
          const mid = middleEnabled ? t("middleSummary") : "";
          flashTranslated("savedApplied", { summary: parts.join(" + "), middle: mid }, true);
          showToast(t("saveSuccess"), "success");
        } catch (error) {
          const reason = getErrorMessage(error, t("unknownReason"));
          const message = t("saveFailed", { reason });
          flashTranslated("saveFailed", { reason }, false);
          showToast(message, "error", 3200);
        } finally {
          setSaveBusy(false);
        }
      }
      function updateMiddleToggle() {
        elMiddleToggle.classList.toggle("active", middleEnabled);
        elMiddleToggle.setAttribute("aria-checked", String(middleEnabled));
      }
      function updateSingleToggle() {
        elSingleToggle.classList.toggle("active", singleEnabled);
        elSingleToggle.setAttribute("aria-checked", String(singleEnabled));
      }
      function updateComboToggle() {
        elComboToggle.classList.toggle("active", comboEnabled);
        elComboToggle.setAttribute("aria-checked", String(comboEnabled));
      }
      function updateHoldSlider() {
        const sec = Math.round(holdThreshold / 1e3);
        elHoldSlider.value = sec;
        elHoldVal.textContent = sec + "s";
        elHoldHint.textContent = t("holdHint", { seconds: sec });
        elHoldSlider.setAttribute("aria-valuetext", t("holdValue", { seconds: sec }));
        const pct = (sec - 1) / 4 * 100;
        elHoldSlider.style.backgroundSize = pct + "% 100%";
      }
      elMiddleToggle.addEventListener("click", () => {
        middleEnabled = !middleEnabled;
        updateMiddleToggle();
      });
      elSingleToggle.addEventListener("click", () => {
        singleEnabled = !singleEnabled;
        updateSingleToggle();
      });
      elComboToggle.addEventListener("click", () => {
        comboEnabled = !comboEnabled;
        updateComboToggle();
      });
      elHoldSlider.addEventListener("input", () => {
        const sec = parseInt(elHoldSlider.value, 10);
        holdThreshold = sec * 1e3;
        updateHoldSlider();
      });
      elKeycap.addEventListener("click", () => {
        listening = true;
        heldMods.clear();
        firstMod = null;
        render();
      });
      window.addEventListener("keydown", (e) => {
        if (!listening) return;
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        if (e.key === "Escape") {
          listening = false;
          heldMods.clear();
          firstMod = null;
          render();
          return;
        }
        if (e.key === "Process" || e.keyCode === 229) return;
        if (RESERVED_KEYS.has(e.key)) {
          elKeycap.innerHTML = `<small style="color:var(--err)">${t("reservedKey")}</small>`;
          return;
        }
        if (isModifier(e.key)) {
          heldMods.add(e.key);
          if (!firstMod) firstMod = e.key;
          render();
          return;
        }
        const mods = [...heldMods];
        if (mods.length > 0) {
          pending = {
            type: "combo",
            key: e.key,
            modifiers: mods,
            label: makeLabel({ type: "combo", key: e.key, modifiers: mods }),
            code: e.code || KEY_TO_CODE[e.key.toLowerCase()] || ""
          };
        } else {
          pending = {
            type: "single",
            key: e.key,
            modifiers: [],
            label: keyLabel(e.key),
            code: e.code || KEY_TO_CODE[e.key.toLowerCase()] || ""
          };
        }
        listening = false;
        heldMods.clear();
        firstMod = null;
        if (pending.type === "combo" && !comboEnabled) {
          comboEnabled = true;
          updateComboToggle();
        }
        if (pending.type === "single" && !singleEnabled) {
          singleEnabled = true;
          updateSingleToggle();
        }
        render();
        elKeycap.style.transform = "scale(1.05)";
        setTimeout(() => {
          elKeycap.style.transform = "";
        }, 150);
      }, true);
      window.addEventListener("keyup", (e) => {
        if (!listening) return;
        if (isModifier(e.key)) {
          heldMods.delete(e.key);
          if (heldMods.size === 0) {
            const singleKey = firstMod || e.key;
            pending = { type: "single", key: singleKey, modifiers: [], label: keyLabel(singleKey), code: e.code || "" };
            listening = false;
            firstMod = null;
            if (!singleEnabled) {
              singleEnabled = true;
              updateSingleToggle();
            }
            render();
          }
        }
      }, true);
      window.addEventListener("blur", () => {
        if (listening) {
          listening = false;
          heldMods.clear();
          firstMod = null;
          render();
        }
      });
      presetChips.forEach((chip) => {
        chip.addEventListener("click", () => {
          const presetConfig = buildTriggerConfigFromPreset(chip.dataset.preset);
          if (!presetConfig) return;
          pending = presetConfig;
          listening = false;
          heldMods.clear();
          firstMod = null;
          render();
        });
      });
      elSave.addEventListener("click", save);
      guidancePromptButtons.forEach((button) => {
        button.addEventListener("click", async () => {
          try {
            const response = await chrome.runtime.sendMessage({
              type: "ACTIVE_GUIDANCE_TEST_PROMPT",
              promptType: button.dataset.guidancePrompt
            });
            if (!response?.ok) {
              if (response?.error) flash(response.error, false);
              else flashTranslated("guidanceFailed", null, false);
              return;
            }
            window.close();
          } catch (error) {
            flashTranslated("guidanceFailedReason", { reason: error?.message || error }, false);
          }
        });
      });
      guidanceWindowButtons.forEach((button) => {
        button.addEventListener("click", async () => {
          const count = Number(button.dataset.guidanceWindow);
          button.disabled = true;
          try {
            const response = await chrome.runtime.sendMessage({
              type: "ACTIVE_GUIDANCE_TEST_WINDOW",
              count
            });
            if (response?.ok) flashTranslated("openedTestPages", { count }, true);
            else if (response?.error) flash(response.error, false);
            else flashTranslated("testWindowFailed", null, false);
          } catch (error) {
            flashTranslated("testWindowFailedReason", { reason: error?.message || error }, false);
          } finally {
            button.disabled = false;
          }
        });
      });
      async function getActiveTab() {
        const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
        return tab;
      }
      elTest.addEventListener("click", async () => {
        const tab = await getActiveTab();
        if (!tab) {
          flashTranslated("noActiveTab", null, false);
          return;
        }
        const url = tab.url || "";
        if (/^(chrome|chrome-extension|edge|about|devtools|view-source):/i.test(url)) {
          flashTranslated("restrictedPage", null, false);
          return;
        }
        try {
          const response = await chrome.runtime.sendMessage({
            type: "ENSURE_CONTENT_READY_AND_TOGGLE",
            tabId: tab.id
          });
          if (response && response.ok) {
            window.close();
            return;
          }
          if (response && response.error) flash(response.error, false);
          else flashTranslated("toggleFailed", null, false);
        } catch (e) {
          flashTranslated("toggleFailedReason", { reason: e && e.message ? e.message : e }, false);
        }
      });
      function flash(msg, ok) {
        currentStatus = { raw: String(msg || "") };
        elStatus.textContent = msg;
        elStatus.className = "test " + (ok ? "ok" : ok === false ? "err" : "");
      }
      function flashTranslated(key, params, ok) {
        currentStatus = { key, params };
        elStatus.textContent = t(key, params);
        elStatus.className = "test " + (ok ? "ok" : ok === false ? "err" : "");
      }
      function activateOnKeyboard(element, callback) {
        element.addEventListener("keydown", (event) => {
          if (event.key !== "Enter" && event.key !== " ") return;
          event.preventDefault();
          callback();
        });
      }
      activateOnKeyboard(elMiddleToggle, () => {
        middleEnabled = !middleEnabled;
        updateMiddleToggle();
      });
      activateOnKeyboard(elSingleToggle, () => {
        singleEnabled = !singleEnabled;
        updateSingleToggle();
      });
      activateOnKeyboard(elComboToggle, () => {
        comboEnabled = !comboEnabled;
        updateComboToggle();
      });
      activateOnKeyboard(elKeycap, () => {
        listening = true;
        heldMods.clear();
        firstMod = null;
        render();
      });
      function onStorageChanged(changes, areaName) {
        if (areaName !== "sync") return;
        if (Object.prototype.hasOwnProperty.call(changes, LANGUAGE_KEY)) {
          languagePreferenceRevision += 1;
          applyLanguage(changes[LANGUAGE_KEY]?.newValue);
        }
        if (Object.prototype.hasOwnProperty.call(changes, THEME_KEY)) {
          themePreferenceRevision += 1;
          setThemePreference(changes[THEME_KEY]?.newValue);
        }
      }
      chrome.storage.onChanged?.addListener(onStorageChanged);
      var onSystemThemeChanged = () => {
        if (themePreference === "system") applyTheme();
      };
      if (colorSchemeQuery?.addEventListener) colorSchemeQuery.addEventListener("change", onSystemThemeChanged);
      else colorSchemeQuery?.addListener?.(onSystemThemeChanged);
      applyTheme();
      applyLanguage("system");
      void load().catch(() => void 0);
    }
  });

  // src/popup/index.js
  var require_index = __commonJS({
    "src/popup/index.js"() {
      var import_version = __toESM(require_version());
      var import_shortcut_logic = __toESM(require_shortcut_logic());
      var import_runtime_contract = __toESM(require_runtime_contract());
      var import_popup = __toESM(require_popup());
    }
  });
  require_index();
})();
