xzhao / 聊天助手大纲

// ==UserScript==
// @name         聊天助手大纲
// @namespace    http://tampermonkey.net/
// @version      0.1.5
// @author       xzhao
// @description  为多个AI聊天平台生成智能对话大纲,支持实时更新、层级结构、主题切换,提升聊天体验和内容导航效率
// @license      MIT
// @match        *://chatgpt.com/*
// @match        *://chat.deepseek.com/*
// @match        *://grok.com/*
// @match        *://www.qianwen.com/*
// @match        *://chat.qwen.ai/*
// @match        *://www.doubao.com/*
// @match        *://www.kimi.com/*
// @match        *://yuanbao.tencent.com/*
// @grant        GM.getValue
// @grant        GM.setValue
// @grant        GM_addStyle
// ==/UserScript==

(function () {
  'use strict';

  const d=new Set;const importCSS = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):(document.head||document.documentElement).appendChild(document.createElement("style")).append(t);})(e));};

  importCSS(" .modal-overlay.svelte-lmj43v{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000}.modal-content.svelte-lmj43v{background:var(--outline-bg);border:1px solid var(--outline-border);border-radius:8px;width:400px;max-width:90vw;max-height:80vh;overflow-y:auto;box-shadow:0 4px 12px #0000004d}.modal-header.svelte-lmj43v{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid var(--outline-border)}.modal-header.svelte-lmj43v h3:where(.svelte-lmj43v){margin:0;color:var(--outline-text);font-size:18px}.close-btn.svelte-lmj43v{background:none;border:none;font-size:20px;cursor:pointer;color:var(--outline-text);padding:0;width:24px;height:24px}.close-btn.svelte-lmj43v:hover{opacity:.7}.modal-body.svelte-lmj43v{padding:15px;display:flex;flex-direction:column;gap:16px}.setting-section.svelte-lmj43v{display:flex;flex-direction:column;gap:10px}.section-title.svelte-lmj43v{margin:0;padding-bottom:6px;border-bottom:1px solid var(--outline-border);color:var(--outline-text);font-size:14px;font-weight:600;opacity:.8}label.svelte-lmj43v{display:flex;align-items:center;gap:10px;color:var(--outline-text);font-size:14px}input[type=checkbox].svelte-lmj43v{cursor:pointer}input[type=number].svelte-lmj43v{width:80px;padding:4px 8px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-header-bg);color:var(--outline-text);font-size:14px}select.svelte-lmj43v{padding:4px 8px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-header-bg);color:var(--outline-text);font-size:14px;cursor:pointer}.chat-outline-header.svelte-zptf9e{display:flex;flex-direction:column;gap:6px;padding:10px 15px;border-bottom:1px solid var(--outline-border);background:var(--outline-header-bg);border-radius:var(--outline-radius) var(--outline-radius) 0 0}.title-row.svelte-zptf9e{display:flex;justify-content:space-between;align-items:center}.chat-outline-title.svelte-zptf9e{margin:0;color:var(--outline-text);font-size:16px;font-weight:700}.title-controls.svelte-zptf9e{display:flex;gap:8px;align-items:center}.tab-container.svelte-zptf9e{display:flex;gap:2px;background:var(--outline-border);border-radius:4px;padding:2px}.tab-btn.svelte-zptf9e{flex:1;padding:5px 10px;border:none;background:transparent;color:var(--outline-text);font-size:12px;cursor:pointer;border-radius:3px;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:4px}.tab-btn.active.svelte-zptf9e{background:var(--outline-bg);font-weight:500}.tab-btn.svelte-zptf9e:hover:not(.active){opacity:.8}.controls-row.svelte-zptf9e{display:flex;gap:8px;align-items:center;justify-content:space-between}.controls-left.svelte-zptf9e,.controls-right.svelte-zptf9e{display:flex;gap:8px;align-items:center}.filter-row.svelte-zptf9e{display:flex;gap:4px}.filter-input.svelte-zptf9e{flex:1;padding:4px 8px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-bg);color:var(--outline-text);font-size:14px}.outline-btn.svelte-zptf9e{background:none;border:1px solid var(--outline-border);border-radius:4px;padding:4px 8px;cursor:pointer;font-size:12px;color:var(--outline-text);transition:all .2s ease}.outline-btn.svelte-zptf9e:hover{background:var(--outline-border);transform:scale(1.05)}.outline-btn.active.svelte-zptf9e,.regex-btn.active.svelte-zptf9e{background:var(--outline-border);font-weight:700}.tree-container.svelte-2xi3vq{display:flex;flex-direction:column;gap:4px}.tree-node.svelte-2xi3vq{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;border-radius:3px;cursor:pointer;transition:background-color .2s}.tree-node.svelte-2xi3vq:hover{background-color:var(--outline-node-hover-bg)}.tree-node.has-bookmark.svelte-2xi3vq{border-left:2px solid var(--outline-bookmark-border, #ffc107)}.node-text.svelte-2xi3vq{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--outline-text)}.bookmark-indicator.svelte-2xi3vq{margin-right:4px;font-size:12px}.toggle-btn.svelte-2xi3vq{background:none;border:none;cursor:pointer;font-size:14px;color:var(--outline-text);padding:4px;border-radius:3px;transition:transform .2s,background-color .2s}.toggle-btn.svelte-2xi3vq:hover{background-color:var(--outline-border);transform:scale(1.1)}.header-level-1.svelte-2xi3vq{border-left:2px solid var(--header-h1)}.header-level-2.svelte-2xi3vq{border-left:2px solid var(--header-h2)}.header-level-3.svelte-2xi3vq{border-left:2px solid var(--header-h3)}.header-level-4.svelte-2xi3vq{border-left:2px solid var(--header-h4)}.header-level-5.svelte-2xi3vq{border-left:2px solid var(--header-h5)}.header-level-6.svelte-2xi3vq{border-left:2px solid var(--header-h6)}.outline-user-item.svelte-1iqb61w{margin:8px 15px;padding:8px;background:var(--outline-user-bg);border-left:3px solid var(--outline-user-border);border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--outline-text);font-size:14px;position:relative}.outline-user-item.svelte-1iqb61w:hover{background:var(--outline-user-hover-bg)}.has-bookmark.svelte-1iqb61w{border-left-color:var(--outline-bookmark-border, #ffc107)}.bookmark-indicator.svelte-1iqb61w{margin-right:4px;font-size:12px}.outline-ai-container.svelte-1iqb61w{margin:8px 15px;border-left:3px solid var(--outline-ai-border);border-radius:4px;background:var(--outline-ai-bg);transition:background-color .2s}.outline-ai-header.svelte-1iqb61w{padding:8px;cursor:pointer;font-weight:700;display:flex;justify-content:space-between;align-items:center;transition:background-color .2s;color:var(--outline-text)}.outline-ai-header.svelte-1iqb61w:hover{background:var(--outline-ai-hover-bg)}.outline-ai-header.has-bookmark.svelte-1iqb61w{border-left-color:var(--outline-bookmark-border, #ffc107)}.header-text.svelte-1iqb61w{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.outline-ai-content.svelte-1iqb61w{padding:0 8px 8px}.outline-ai-item.svelte-1iqb61w{margin:8px 15px;padding:8px;background:var(--outline-ai-bg);border-left:3px solid var(--outline-ai-border);border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--outline-text);font-size:14px}.outline-ai-item.svelte-1iqb61w:hover{background:var(--outline-ai-hover-bg)}.outline-ai-item.has-bookmark.svelte-1iqb61w{border-left-color:var(--outline-bookmark-border, #ffc107)}.toggle-btn.svelte-1iqb61w{background:none;border:none;cursor:pointer;font-size:14px;color:var(--outline-text);padding:4px;border-radius:3px;transition:transform .2s,background-color .2s;margin-left:8px}.toggle-btn.svelte-1iqb61w:hover{background-color:var(--outline-border);transform:scale(1.1)}.outline-active{background:var(--outline-active-bg)!important;outline:2px solid var(--outline-active-border);outline-offset:-1px}.outline-content.svelte-13g9af{overflow-y:auto;flex:1;padding-bottom:15px;position:relative;scroll-behavior:smooth}.draggable-toggle-button.svelte-nihy1m{position:fixed;right:2px;background:var(--outline-bg);border:1px solid var(--outline-border);border-radius:50%;width:40px;height:40px;cursor:pointer;font-size:16px;color:var(--outline-text);box-shadow:0 2px 8px var(--outline-shadow);transition:transform .3s ease,background-color .3s ease,box-shadow .3s ease;z-index:9999;display:flex;align-items:center;justify-content:center;user-select:none;-webkit-user-select:none;touch-action:none}.draggable-toggle-button.svelte-nihy1m:hover{background:var(--outline-border);box-shadow:0 4px 12px var(--outline-shadow)}.draggable-toggle-button.is-dragging.svelte-nihy1m{cursor:grabbing;box-shadow:0 6px 16px var(--outline-shadow);transition:none}.draggable-toggle-button.svelte-nihy1m:not(.is-dragging):hover{transform:translateY(-50%) scale(1.1)}.draggable-toggle-button.svelte-nihy1m:active{cursor:grabbing}.panel-notice-stack.svelte-1xjbolr{position:absolute;left:12px;right:12px;bottom:42px;z-index:2;display:flex;flex-direction:column;gap:8px;pointer-events:none}.panel-notice.svelte-1xjbolr{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 12px;border-radius:10px;border:1px solid var(--outline-border);box-shadow:0 8px 20px var(--outline-shadow);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);pointer-events:auto}.notice-info.svelte-1xjbolr{background:color-mix(in srgb,#3b82f6 18%,var(--outline-bg))}.notice-success.svelte-1xjbolr{background:color-mix(in srgb,#22c55e 18%,var(--outline-bg))}.notice-warning.svelte-1xjbolr{background:color-mix(in srgb,#f59e0b 18%,var(--outline-bg))}.notice-error.svelte-1xjbolr{background:color-mix(in srgb,#ef4444 18%,var(--outline-bg))}.notice-text.svelte-1xjbolr{color:var(--outline-text);font-size:13px;line-height:1.4}.notice-close.svelte-1xjbolr{flex:none;width:24px;height:24px;border:none;border-radius:50%;background:transparent;color:var(--outline-text);cursor:pointer}.service-status-bar.svelte-5fnl0z{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 12px 10px;border-top:1px solid var(--outline-border);background:color-mix(in srgb,var(--outline-header-bg) 70%,transparent)}.status-dot-button.svelte-5fnl0z{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;background:transparent;cursor:pointer}.status-dot-button.svelte-5fnl0z:hover .status-light:where(.svelte-5fnl0z){transform:scale(1.12)}.status-light.svelte-5fnl0z{width:10px;height:10px;border-radius:50%;background:var(--status-color);box-shadow:0 0 0 3px color-mix(in srgb,var(--status-color) 20%,transparent);transition:transform .2s ease}.empty-state.svelte-1dp0ytt{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:30px 20px;color:var(--outline-text);opacity:.6}.empty-icon.svelte-1dp0ytt{font-size:32px;margin-bottom:12px}.empty-state.svelte-1dp0ytt p:where(.svelte-1dp0ytt){margin:2px 0;font-size:13px}.hint.svelte-1dp0ytt{font-size:11px!important;opacity:.7}.bookmark-list.svelte-1dp0ytt{display:flex;flex-direction:column;gap:2px;padding:4px 8px}.bookmark-item.svelte-1dp0ytt{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--outline-bg);border-radius:4px;cursor:pointer;transition:background-color .15s;font-size:12px}.bookmark-item.svelte-1dp0ytt:hover{background:var(--outline-node-hover-bg)}.bookmark-item.svelte-1dp0ytt:focus{outline:1px solid var(--outline-primary, #007acc);outline-offset:-1px}.bookmark-icon.svelte-1dp0ytt{font-size:12px;flex-shrink:0;opacity:.8}.bookmark-name.svelte-1dp0ytt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--outline-text)}.bookmark-meta.svelte-1dp0ytt{flex-shrink:0;font-size:10px;color:var(--outline-text);opacity:.5}.bookmark-panel.svelte-19r7ywj{display:flex;flex-direction:column;height:100%;overflow:hidden}.bookmark-toolbar.svelte-19r7ywj{display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-bottom:1px solid var(--outline-border);background:var(--outline-header-bg)}.view-toggle.svelte-19r7ywj{display:flex;gap:2px;background:var(--outline-border);border-radius:4px;padding:2px}.toggle-btn.svelte-19r7ywj{flex:1;padding:5px 10px;border:none;background:transparent;color:var(--outline-text);font-size:12px;cursor:pointer;border-radius:3px;transition:all .2s}.toggle-btn.active.svelte-19r7ywj{background:var(--outline-bg);font-weight:500}.toggle-btn.svelte-19r7ywj:hover:not(.active){opacity:.8}.search-input.svelte-19r7ywj{width:100%;padding:6px 10px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-bg);color:var(--outline-text);font-size:12px;box-sizing:border-box}.search-input.svelte-19r7ywj:focus{outline:none;border-color:var(--outline-primary, #007acc)}.search-input.svelte-19r7ywj::placeholder{color:var(--outline-text);opacity:.5}.bookmark-content.svelte-19r7ywj{flex:1;overflow-y:auto;overflow-x:hidden}.empty-state.svelte-19r7ywj{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:30px 20px;color:var(--outline-text);opacity:.6}.empty-icon.svelte-19r7ywj{font-size:32px;margin-bottom:12px}.empty-state.svelte-19r7ywj p:where(.svelte-19r7ywj){margin:2px 0;font-size:13px}.hint.svelte-19r7ywj{font-size:11px!important;opacity:.7}.conversation-group.svelte-19r7ywj{border-bottom:1px solid var(--outline-border)}.conversation-group.svelte-19r7ywj:last-child{border-bottom:none}.conversation-header.svelte-19r7ywj{display:flex;align-items:center;gap:6px;padding:6px 10px;background:var(--outline-header-bg);cursor:pointer;font-size:12px;color:var(--outline-text);transition:background-color .15s}.conversation-header.svelte-19r7ywj:hover{background:var(--outline-node-hover-bg)}.toggle-icon.svelte-19r7ywj{font-size:10px;opacity:.6}.conversation-name.svelte-19r7ywj{flex:1;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversation-count.svelte-19r7ywj{min-width:18px;height:18px;font-size:10px;opacity:.8;background:var(--outline-border);border-radius:50%;display:inline-flex;align-items:center;justify-content:center}.bookmark-footer.svelte-19r7ywj{padding:6px 12px;border-top:1px solid var(--outline-border);background:var(--outline-header-bg)}.bookmark-count.svelte-19r7ywj{font-size:11px;color:var(--outline-text);opacity:.6}.context-menu.svelte-aof35l{position:fixed;z-index:100000;min-width:150px;background:var(--outline-bg);border:1px solid var(--outline-border);border-radius:6px;box-shadow:0 4px 12px var(--outline-shadow);padding:4px 0;animation:svelte-aof35l-fadeIn .15s ease-out}@keyframes svelte-aof35l-fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.menu-item.svelte-aof35l{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:none;color:var(--outline-text);font-size:14px;cursor:pointer;text-align:left;transition:background-color .15s}.menu-item.svelte-aof35l:hover:not(.disabled){background:var(--outline-border)}.menu-item.disabled.svelte-aof35l{opacity:.5;cursor:not-allowed}.menu-item.danger.svelte-aof35l{color:#dc3545}.menu-icon.svelte-aof35l{width:16px;text-align:center}.menu-label.svelte-aof35l{flex:1}.modal-overlay.svelte-7qu2ih{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:100000;animation:svelte-7qu2ih-fadeIn .15s ease-out}@keyframes svelte-7qu2ih-fadeIn{0%{opacity:0}to{opacity:1}}.modal-content.svelte-7qu2ih{background:var(--outline-bg);border:1px solid var(--outline-border);border-radius:8px;width:380px;max-width:90vw;box-shadow:0 4px 12px #0000004d;animation:svelte-7qu2ih-slideIn .15s ease-out}@keyframes svelte-7qu2ih-slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.modal-header.svelte-7qu2ih{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid var(--outline-border)}.modal-header.svelte-7qu2ih h3:where(.svelte-7qu2ih){margin:0;color:var(--outline-text);font-size:16px}.close-btn.svelte-7qu2ih{background:none;border:none;font-size:18px;cursor:pointer;color:var(--outline-text);padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:background-color .15s}.close-btn.svelte-7qu2ih:hover{background:var(--outline-border)}.modal-body.svelte-7qu2ih{padding:20px}.form-group.svelte-7qu2ih{display:flex;flex-direction:column;gap:6px}.form-group.svelte-7qu2ih label:where(.svelte-7qu2ih){color:var(--outline-text);font-size:14px;font-weight:500}.form-group.svelte-7qu2ih input:where(.svelte-7qu2ih){padding:8px 12px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-bg);color:var(--outline-text);font-size:14px;transition:border-color .15s}.form-group.svelte-7qu2ih input:where(.svelte-7qu2ih):focus{outline:none;border-color:var(--outline-primary, #007acc)}.hint.svelte-7qu2ih{font-size:12px;color:var(--outline-text);opacity:.7}.preview.svelte-7qu2ih{margin-top:15px;padding:10px;background:var(--outline-header-bg);border-radius:4px;display:flex;align-items:center;gap:8px}.preview-label.svelte-7qu2ih{font-size:12px;color:var(--outline-text);opacity:.7}.preview-name.svelte-7qu2ih{font-size:14px;color:var(--outline-text);font-weight:500;word-break:break-all}.warning-message.svelte-7qu2ih{padding:12px;background:#ffc10726;border:1px solid rgba(255,193,7,.3);border-radius:4px;color:var(--outline-text);font-size:14px}.modal-footer.svelte-7qu2ih{display:flex;justify-content:flex-end;gap:10px;padding:15px;border-top:1px solid var(--outline-border)}.btn.svelte-7qu2ih{padding:8px 16px;border-radius:4px;font-size:14px;cursor:pointer;transition:all .15s}.btn-secondary.svelte-7qu2ih{background:none;border:1px solid var(--outline-border);color:var(--outline-text)}.btn-secondary.svelte-7qu2ih:hover{background:var(--outline-border)}.btn-primary.svelte-7qu2ih{background:var(--outline-primary, #007acc);border:1px solid var(--outline-primary, #007acc);color:#fff}.btn-primary.svelte-7qu2ih:hover{opacity:.9}.btn-primary.svelte-7qu2ih:disabled{opacity:.6;cursor:not-allowed}.modal-overlay.svelte-9ypatm{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:100000;animation:svelte-9ypatm-fadeIn .15s ease-out}@keyframes svelte-9ypatm-fadeIn{0%{opacity:0}to{opacity:1}}.modal-content.svelte-9ypatm{background:var(--outline-bg);border:1px solid var(--outline-border);border-radius:8px;width:340px;max-width:90vw;box-shadow:0 4px 12px #0000004d;animation:svelte-9ypatm-slideIn .15s ease-out}@keyframes svelte-9ypatm-slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.modal-header.svelte-9ypatm{display:flex;justify-content:space-between;align-items:center;padding:12px 15px;border-bottom:1px solid var(--outline-border)}.modal-header.svelte-9ypatm h3:where(.svelte-9ypatm){margin:0;color:var(--outline-text);font-size:14px}.close-btn.svelte-9ypatm{background:none;border:none;font-size:16px;cursor:pointer;color:var(--outline-text);padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:background-color .15s}.close-btn.svelte-9ypatm:hover{background:var(--outline-border)}.modal-body.svelte-9ypatm{padding:15px}.form-group.svelte-9ypatm{display:flex;flex-direction:column;gap:6px}.form-group.svelte-9ypatm label:where(.svelte-9ypatm){color:var(--outline-text);font-size:13px;font-weight:500}.form-group.svelte-9ypatm input:where(.svelte-9ypatm){padding:8px 10px;border:1px solid var(--outline-border);border-radius:4px;background:var(--outline-bg);color:var(--outline-text);font-size:13px;transition:border-color .15s}.form-group.svelte-9ypatm input:where(.svelte-9ypatm):focus{outline:none;border-color:var(--outline-primary, #007acc)}.modal-footer.svelte-9ypatm{display:flex;justify-content:flex-end;gap:8px;padding:12px 15px;border-top:1px solid var(--outline-border)}.btn.svelte-9ypatm{padding:6px 14px;border-radius:4px;font-size:13px;cursor:pointer;transition:all .15s}.btn-secondary.svelte-9ypatm{background:none;border:1px solid var(--outline-border);color:var(--outline-text)}.btn-secondary.svelte-9ypatm:hover{background:var(--outline-border)}.btn-primary.svelte-9ypatm{background:var(--outline-primary, #007acc);border:1px solid var(--outline-primary, #007acc);color:#fff}.btn-primary.svelte-9ypatm:hover{opacity:.9}.btn-primary.svelte-9ypatm:disabled{opacity:.6;cursor:not-allowed}.chat-outline.svelte-n2r6vx{width:var(--outline-width);background:var(--outline-bg);border-radius:var(--outline-radius);padding:0;box-shadow:0 4px 12px var(--outline-shadow);font-size:var(--outline-font-size);transition:background-color .3s ease;height:100dvh;z-index:9999;display:flex;flex-direction:column;position:relative;overflow:hidden}.outline-fixed-right.svelte-n2r6vx{position:fixed;top:0;right:0;z-index:10000;height:100vh;border-radius:var(--outline-radius) 0 0 var(--outline-radius);border-right:none;box-shadow:-4px 0 12px var(--outline-shadow)} ");

  const DEV = false;
  var is_array = Array.isArray;
  var index_of = Array.prototype.indexOf;
  var includes = Array.prototype.includes;
  var array_from = Array.from;
  var define_property = Object.defineProperty;
  var get_descriptor = Object.getOwnPropertyDescriptor;
  var get_descriptors = Object.getOwnPropertyDescriptors;
  var object_prototype = Object.prototype;
  var array_prototype = Array.prototype;
  var get_prototype_of = Object.getPrototypeOf;
  var is_extensible = Object.isExtensible;
  const noop = () => {
  };
  function run_all(arr) {
    for (var i = 0; i < arr.length; i++) {
      arr[i]();
    }
  }
  function deferred() {
    var resolve;
    var reject;
    var promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });
    return { promise, resolve, reject };
  }
  const DERIVED = 1 << 1;
  const EFFECT = 1 << 2;
  const RENDER_EFFECT = 1 << 3;
  const MANAGED_EFFECT = 1 << 24;
  const BLOCK_EFFECT = 1 << 4;
  const BRANCH_EFFECT = 1 << 5;
  const ROOT_EFFECT = 1 << 6;
  const BOUNDARY_EFFECT = 1 << 7;
  const CONNECTED = 1 << 9;
  const CLEAN = 1 << 10;
  const DIRTY = 1 << 11;
  const MAYBE_DIRTY = 1 << 12;
  const INERT = 1 << 13;
  const DESTROYED = 1 << 14;
  const REACTION_RAN = 1 << 15;
  const EFFECT_TRANSPARENT = 1 << 16;
  const EAGER_EFFECT = 1 << 17;
  const HEAD_EFFECT = 1 << 18;
  const EFFECT_PRESERVED = 1 << 19;
  const USER_EFFECT = 1 << 20;
  const EFFECT_OFFSCREEN = 1 << 25;
  const WAS_MARKED = 1 << 16;
  const REACTION_IS_UPDATING = 1 << 21;
  const ASYNC = 1 << 22;
  const ERROR_VALUE = 1 << 23;
  const STATE_SYMBOL = Symbol("$state");
  const LEGACY_PROPS = Symbol("legacy props");
  const LOADING_ATTR_SYMBOL = Symbol("");
  const STALE_REACTION = new class StaleReactionError extends Error {
    name = "StaleReactionError";
    message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
  }();
  const IS_XHTML = (
!!globalThis.document?.contentType && globalThis.document.contentType.includes("xml")
  );
  function lifecycle_outside_component(name) {
    {
      throw new Error(`https://svelte.dev/e/lifecycle_outside_component`);
    }
  }
  function async_derived_orphan() {
    {
      throw new Error(`https://svelte.dev/e/async_derived_orphan`);
    }
  }
  function each_key_duplicate(a, b, value) {
    {
      throw new Error(`https://svelte.dev/e/each_key_duplicate`);
    }
  }
  function effect_in_teardown(rune) {
    {
      throw new Error(`https://svelte.dev/e/effect_in_teardown`);
    }
  }
  function effect_in_unowned_derived() {
    {
      throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`);
    }
  }
  function effect_orphan(rune) {
    {
      throw new Error(`https://svelte.dev/e/effect_orphan`);
    }
  }
  function effect_update_depth_exceeded() {
    {
      throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
    }
  }
  function props_invalid_value(key) {
    {
      throw new Error(`https://svelte.dev/e/props_invalid_value`);
    }
  }
  function state_descriptors_fixed() {
    {
      throw new Error(`https://svelte.dev/e/state_descriptors_fixed`);
    }
  }
  function state_prototype_fixed() {
    {
      throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
    }
  }
  function state_unsafe_mutation() {
    {
      throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
    }
  }
  function svelte_boundary_reset_onerror() {
    {
      throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
    }
  }
  const EACH_ITEM_REACTIVE = 1;
  const EACH_INDEX_REACTIVE = 1 << 1;
  const EACH_IS_CONTROLLED = 1 << 2;
  const EACH_IS_ANIMATED = 1 << 3;
  const EACH_ITEM_IMMUTABLE = 1 << 4;
  const PROPS_IS_IMMUTABLE = 1;
  const PROPS_IS_UPDATED = 1 << 2;
  const PROPS_IS_BINDABLE = 1 << 3;
  const PROPS_IS_LAZY_INITIAL = 1 << 4;
  const TEMPLATE_FRAGMENT = 1;
  const TEMPLATE_USE_IMPORT_NODE = 1 << 1;
  const UNINITIALIZED = Symbol();
  const NAMESPACE_HTML = "http://www.w3.org/1999/xhtml";
  function select_multiple_invalid_value() {
    {
      console.warn(`https://svelte.dev/e/select_multiple_invalid_value`);
    }
  }
  function svelte_boundary_reset_noop() {
    {
      console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
    }
  }
  function equals(value) {
    return value === this.v;
  }
  function safe_not_equal(a, b) {
    return a != a ? b == b : a !== b || a !== null && typeof a === "object" || typeof a === "function";
  }
  function safe_equals(value) {
    return !safe_not_equal(value, this.v);
  }
  let tracing_mode_flag = false;
  let component_context = null;
  function set_component_context(context) {
    component_context = context;
  }
  function push(props, runes = false, fn) {
    component_context = {
      p: component_context,
      i: false,
      c: null,
      e: null,
      s: props,
      x: null,
      l: null
    };
  }
  function pop(component) {
    var context = (
component_context
    );
    var effects = context.e;
    if (effects !== null) {
      context.e = null;
      for (var fn of effects) {
        create_user_effect(fn);
      }
    }
    context.i = true;
    component_context = context.p;
    return (
{}
    );
  }
  function is_runes() {
    return true;
  }
  let micro_tasks = [];
  function run_micro_tasks() {
    var tasks = micro_tasks;
    micro_tasks = [];
    run_all(tasks);
  }
  function queue_micro_task(fn) {
    if (micro_tasks.length === 0 && !is_flushing_sync) {
      var tasks = micro_tasks;
      queueMicrotask(() => {
        if (tasks === micro_tasks) run_micro_tasks();
      });
    }
    micro_tasks.push(fn);
  }
  function flush_tasks() {
    while (micro_tasks.length > 0) {
      run_micro_tasks();
    }
  }
  function handle_error(error) {
    var effect2 = active_effect;
    if (effect2 === null) {
      active_reaction.f |= ERROR_VALUE;
      return error;
    }
    if ((effect2.f & REACTION_RAN) === 0 && (effect2.f & EFFECT) === 0) {
      throw error;
    }
    invoke_error_boundary(error, effect2);
  }
  function invoke_error_boundary(error, effect2) {
    while (effect2 !== null) {
      if ((effect2.f & BOUNDARY_EFFECT) !== 0) {
        if ((effect2.f & REACTION_RAN) === 0) {
          throw error;
        }
        try {
          effect2.b.error(error);
          return;
        } catch (e) {
          error = e;
        }
      }
      effect2 = effect2.parent;
    }
    throw error;
  }
  const STATUS_MASK = -7169;
  function set_signal_status(signal, status) {
    signal.f = signal.f & STATUS_MASK | status;
  }
  function update_derived_status(derived2) {
    if ((derived2.f & CONNECTED) !== 0 || derived2.deps === null) {
      set_signal_status(derived2, CLEAN);
    } else {
      set_signal_status(derived2, MAYBE_DIRTY);
    }
  }
  function clear_marked(deps) {
    if (deps === null) return;
    for (const dep of deps) {
      if ((dep.f & DERIVED) === 0 || (dep.f & WAS_MARKED) === 0) {
        continue;
      }
      dep.f ^= WAS_MARKED;
      clear_marked(
dep.deps
      );
    }
  }
  function defer_effect(effect2, dirty_effects, maybe_dirty_effects) {
    if ((effect2.f & DIRTY) !== 0) {
      dirty_effects.add(effect2);
    } else if ((effect2.f & MAYBE_DIRTY) !== 0) {
      maybe_dirty_effects.add(effect2);
    }
    clear_marked(effect2.deps);
    set_signal_status(effect2, CLEAN);
  }
  const batches = new Set();
  let current_batch = null;
  let previous_batch = null;
  let batch_values = null;
  let queued_root_effects = [];
  let last_scheduled_effect = null;
  let is_flushing_sync = false;
  let collected_effects = null;
  class Batch {
current = new Map();
previous = new Map();
#commit_callbacks = new Set();
#discard_callbacks = new Set();
#pending = 0;
#blocking_pending = 0;
#deferred = null;
#dirty_effects = new Set();
#maybe_dirty_effects = new Set();
#skipped_branches = new Map();
    is_fork = false;
    #decrement_queued = false;
    #is_deferred() {
      return this.is_fork || this.#blocking_pending > 0;
    }
skip_effect(effect2) {
      if (!this.#skipped_branches.has(effect2)) {
        this.#skipped_branches.set(effect2, { d: [], m: [] });
      }
    }
unskip_effect(effect2) {
      var tracked = this.#skipped_branches.get(effect2);
      if (tracked) {
        this.#skipped_branches.delete(effect2);
        for (var e of tracked.d) {
          set_signal_status(e, DIRTY);
          schedule_effect(e);
        }
        for (e of tracked.m) {
          set_signal_status(e, MAYBE_DIRTY);
          schedule_effect(e);
        }
      }
    }
process(root_effects) {
      queued_root_effects = [];
      this.apply();
      var effects = collected_effects = [];
      var render_effects = [];
      for (const root2 of root_effects) {
        this.#traverse_effect_tree(root2, effects, render_effects);
      }
      collected_effects = null;
      if (this.#is_deferred()) {
        this.#defer_effects(render_effects);
        this.#defer_effects(effects);
        for (const [e, t] of this.#skipped_branches) {
          reset_branch(e, t);
        }
      } else {
        previous_batch = this;
        current_batch = null;
        for (const fn of this.#commit_callbacks) fn(this);
        this.#commit_callbacks.clear();
        if (this.#pending === 0) {
          this.#commit();
        }
        flush_queued_effects(render_effects);
        flush_queued_effects(effects);
        this.#dirty_effects.clear();
        this.#maybe_dirty_effects.clear();
        previous_batch = null;
        this.#deferred?.resolve();
      }
      batch_values = null;
    }
#traverse_effect_tree(root2, effects, render_effects) {
      root2.f ^= CLEAN;
      var effect2 = root2.first;
      while (effect2 !== null) {
        var flags2 = effect2.f;
        var is_branch = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0;
        var is_skippable_branch = is_branch && (flags2 & CLEAN) !== 0;
        var skip = is_skippable_branch || (flags2 & INERT) !== 0 || this.#skipped_branches.has(effect2);
        if (!skip && effect2.fn !== null) {
          if (is_branch) {
            effect2.f ^= CLEAN;
          } else if ((flags2 & EFFECT) !== 0) {
            effects.push(effect2);
          } else if (is_dirty(effect2)) {
            if ((flags2 & BLOCK_EFFECT) !== 0) this.#maybe_dirty_effects.add(effect2);
            update_effect(effect2);
          }
          var child2 = effect2.first;
          if (child2 !== null) {
            effect2 = child2;
            continue;
          }
        }
        while (effect2 !== null) {
          var next = effect2.next;
          if (next !== null) {
            effect2 = next;
            break;
          }
          effect2 = effect2.parent;
        }
      }
    }
#defer_effects(effects) {
      for (var i = 0; i < effects.length; i += 1) {
        defer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects);
      }
    }
capture(source2, value) {
      if (value !== UNINITIALIZED && !this.previous.has(source2)) {
        this.previous.set(source2, value);
      }
      if ((source2.f & ERROR_VALUE) === 0) {
        this.current.set(source2, source2.v);
        batch_values?.set(source2, source2.v);
      }
    }
    activate() {
      current_batch = this;
      this.apply();
    }
    deactivate() {
      if (current_batch !== this) return;
      current_batch = null;
      batch_values = null;
    }
    flush() {
      if (queued_root_effects.length > 0) {
        current_batch = this;
        flush_effects();
      } else if (this.#pending === 0 && !this.is_fork) {
        for (const fn of this.#commit_callbacks) fn(this);
        this.#commit_callbacks.clear();
        this.#commit();
        this.#deferred?.resolve();
      }
      this.deactivate();
    }
    discard() {
      for (const fn of this.#discard_callbacks) fn(this);
      this.#discard_callbacks.clear();
    }
    #commit() {
      if (batches.size > 1) {
        this.previous.clear();
        var previous_batch2 = current_batch;
        var previous_batch_values = batch_values;
        var is_earlier = true;
        for (const batch of batches) {
          if (batch === this) {
            is_earlier = false;
            continue;
          }
          const sources = [];
          for (const [source2, value] of this.current) {
            if (batch.current.has(source2)) {
              if (is_earlier && value !== batch.current.get(source2)) {
                batch.current.set(source2, value);
              } else {
                continue;
              }
            }
            sources.push(source2);
          }
          if (sources.length === 0) {
            continue;
          }
          const others = [...batch.current.keys()].filter((s) => !this.current.has(s));
          if (others.length > 0) {
            var prev_queued_root_effects = queued_root_effects;
            queued_root_effects = [];
            const marked = new Set();
            const checked = new Map();
            for (const source2 of sources) {
              mark_effects(source2, others, marked, checked);
            }
            if (queued_root_effects.length > 0) {
              current_batch = batch;
              batch.apply();
              for (const root2 of queued_root_effects) {
                batch.#traverse_effect_tree(root2, [], []);
              }
              batch.deactivate();
            }
            queued_root_effects = prev_queued_root_effects;
          }
        }
        current_batch = previous_batch2;
        batch_values = previous_batch_values;
      }
      this.#skipped_branches.clear();
      batches.delete(this);
    }
increment(blocking) {
      this.#pending += 1;
      if (blocking) this.#blocking_pending += 1;
    }
decrement(blocking) {
      this.#pending -= 1;
      if (blocking) this.#blocking_pending -= 1;
      if (this.#decrement_queued) return;
      this.#decrement_queued = true;
      queue_micro_task(() => {
        this.#decrement_queued = false;
        if (!this.#is_deferred()) {
          this.revive();
        } else if (queued_root_effects.length > 0) {
          this.flush();
        }
      });
    }
    revive() {
      for (const e of this.#dirty_effects) {
        this.#maybe_dirty_effects.delete(e);
        set_signal_status(e, DIRTY);
        schedule_effect(e);
      }
      for (const e of this.#maybe_dirty_effects) {
        set_signal_status(e, MAYBE_DIRTY);
        schedule_effect(e);
      }
      this.flush();
    }
oncommit(fn) {
      this.#commit_callbacks.add(fn);
    }
ondiscard(fn) {
      this.#discard_callbacks.add(fn);
    }
    settled() {
      return (this.#deferred ??= deferred()).promise;
    }
    static ensure() {
      if (current_batch === null) {
        const batch = current_batch = new Batch();
        batches.add(current_batch);
        if (!is_flushing_sync) {
          queue_micro_task(() => {
            if (current_batch !== batch) {
              return;
            }
            batch.flush();
          });
        }
      }
      return current_batch;
    }
    apply() {
      return;
    }
  }
  function flushSync(fn) {
    var was_flushing_sync = is_flushing_sync;
    is_flushing_sync = true;
    try {
      var result;
      if (fn) ;
      while (true) {
        flush_tasks();
        if (queued_root_effects.length === 0) {
          current_batch?.flush();
          if (queued_root_effects.length === 0) {
            last_scheduled_effect = null;
            return (
result
            );
          }
        }
        flush_effects();
      }
    } finally {
      is_flushing_sync = was_flushing_sync;
    }
  }
  function flush_effects() {
    try {
      var flush_count = 0;
      while (queued_root_effects.length > 0) {
        var batch = Batch.ensure();
        if (flush_count++ > 1e3) {
          var updates, entry;
          if (DEV) ;
          infinite_loop_guard();
        }
        batch.process(queued_root_effects);
        old_values.clear();
        if (DEV) ;
      }
    } finally {
      queued_root_effects = [];
      last_scheduled_effect = null;
      collected_effects = null;
    }
  }
  function infinite_loop_guard() {
    try {
      effect_update_depth_exceeded();
    } catch (error) {
      invoke_error_boundary(error, last_scheduled_effect);
    }
  }
  let eager_block_effects = null;
  function flush_queued_effects(effects) {
    var length = effects.length;
    if (length === 0) return;
    var i = 0;
    while (i < length) {
      var effect2 = effects[i++];
      if ((effect2.f & (DESTROYED | INERT)) === 0 && is_dirty(effect2)) {
        eager_block_effects = new Set();
        update_effect(effect2);
        if (effect2.deps === null && effect2.first === null && effect2.nodes === null && effect2.teardown === null && effect2.ac === null) {
          unlink_effect(effect2);
        }
        if (eager_block_effects?.size > 0) {
          old_values.clear();
          for (const e of eager_block_effects) {
            if ((e.f & (DESTROYED | INERT)) !== 0) continue;
            const ordered_effects = [e];
            let ancestor = e.parent;
            while (ancestor !== null) {
              if (eager_block_effects.has(ancestor)) {
                eager_block_effects.delete(ancestor);
                ordered_effects.push(ancestor);
              }
              ancestor = ancestor.parent;
            }
            for (let j = ordered_effects.length - 1; j >= 0; j--) {
              const e2 = ordered_effects[j];
              if ((e2.f & (DESTROYED | INERT)) !== 0) continue;
              update_effect(e2);
            }
          }
          eager_block_effects.clear();
        }
      }
    }
    eager_block_effects = null;
  }
  function mark_effects(value, sources, marked, checked) {
    if (marked.has(value)) return;
    marked.add(value);
    if (value.reactions !== null) {
      for (const reaction of value.reactions) {
        const flags2 = reaction.f;
        if ((flags2 & DERIVED) !== 0) {
          mark_effects(
reaction,
            sources,
            marked,
            checked
          );
        } else if ((flags2 & (ASYNC | BLOCK_EFFECT)) !== 0 && (flags2 & DIRTY) === 0 && depends_on(reaction, sources, checked)) {
          set_signal_status(reaction, DIRTY);
          schedule_effect(
reaction
          );
        }
      }
    }
  }
  function depends_on(reaction, sources, checked) {
    const depends = checked.get(reaction);
    if (depends !== void 0) return depends;
    if (reaction.deps !== null) {
      for (const dep of reaction.deps) {
        if (includes.call(sources, dep)) {
          return true;
        }
        if ((dep.f & DERIVED) !== 0 && depends_on(
dep,
          sources,
          checked
        )) {
          checked.set(
dep,
            true
          );
          return true;
        }
      }
    }
    checked.set(reaction, false);
    return false;
  }
  function schedule_effect(signal) {
    var effect2 = last_scheduled_effect = signal;
    var boundary2 = effect2.b;
    if (boundary2?.is_pending && (signal.f & (EFFECT | RENDER_EFFECT | MANAGED_EFFECT)) !== 0 && (signal.f & REACTION_RAN) === 0) {
      boundary2.defer_effect(signal);
      return;
    }
    while (effect2.parent !== null) {
      effect2 = effect2.parent;
      var flags2 = effect2.f;
      if (collected_effects !== null && effect2 === active_effect) {
        if ((signal.f & RENDER_EFFECT) === 0) {
          return;
        }
      }
      if ((flags2 & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
        if ((flags2 & CLEAN) === 0) {
          return;
        }
        effect2.f ^= CLEAN;
      }
    }
    queued_root_effects.push(effect2);
  }
  function reset_branch(effect2, tracked) {
    if ((effect2.f & BRANCH_EFFECT) !== 0 && (effect2.f & CLEAN) !== 0) {
      return;
    }
    if ((effect2.f & DIRTY) !== 0) {
      tracked.d.push(effect2);
    } else if ((effect2.f & MAYBE_DIRTY) !== 0) {
      tracked.m.push(effect2);
    }
    set_signal_status(effect2, CLEAN);
    var e = effect2.first;
    while (e !== null) {
      reset_branch(e, tracked);
      e = e.next;
    }
  }
  function createSubscriber(start) {
    let subscribers = 0;
    let version = source(0);
    let stop;
    return () => {
      if (effect_tracking()) {
        get$1(version);
        render_effect(() => {
          if (subscribers === 0) {
            stop = untrack(() => start(() => increment(version)));
          }
          subscribers += 1;
          return () => {
            queue_micro_task(() => {
              subscribers -= 1;
              if (subscribers === 0) {
                stop?.();
                stop = void 0;
                increment(version);
              }
            });
          };
        });
      }
    };
  }
  var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
  function boundary(node, props, children, transform_error) {
    new Boundary(node, props, children, transform_error);
  }
  class Boundary {
parent;
    is_pending = false;
transform_error;
#anchor;
#hydrate_open = null;
#props;
#children;
#effect;
#main_effect = null;
#pending_effect = null;
#failed_effect = null;
#offscreen_fragment = null;
    #local_pending_count = 0;
    #pending_count = 0;
    #pending_count_update_queued = false;
#dirty_effects = new Set();
#maybe_dirty_effects = new Set();
#effect_pending = null;
    #effect_pending_subscriber = createSubscriber(() => {
      this.#effect_pending = source(this.#local_pending_count);
      return () => {
        this.#effect_pending = null;
      };
    });
constructor(node, props, children, transform_error) {
      this.#anchor = node;
      this.#props = props;
      this.#children = (anchor) => {
        var effect2 = (
active_effect
        );
        effect2.b = this;
        effect2.f |= BOUNDARY_EFFECT;
        children(anchor);
      };
      this.parent =
active_effect.b;
      this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
      this.#effect = block(() => {
        {
          this.#render();
        }
      }, flags);
    }
    #hydrate_resolved_content() {
      try {
        this.#main_effect = branch(() => this.#children(this.#anchor));
      } catch (error) {
        this.error(error);
      }
    }
#hydrate_failed_content(error) {
      const failed = this.#props.failed;
      if (!failed) return;
      this.#failed_effect = branch(() => {
        failed(
          this.#anchor,
          () => error,
          () => () => {
          }
        );
      });
    }
    #hydrate_pending_content() {
      const pending = this.#props.pending;
      if (!pending) return;
      this.is_pending = true;
      this.#pending_effect = branch(() => pending(this.#anchor));
      queue_micro_task(() => {
        var fragment = this.#offscreen_fragment = document.createDocumentFragment();
        var anchor = create_text();
        fragment.append(anchor);
        this.#main_effect = this.#run(() => {
          Batch.ensure();
          return branch(() => this.#children(anchor));
        });
        if (this.#pending_count === 0) {
          this.#anchor.before(fragment);
          this.#offscreen_fragment = null;
          pause_effect(
this.#pending_effect,
            () => {
              this.#pending_effect = null;
            }
          );
          this.#resolve();
        }
      });
    }
    #render() {
      try {
        this.is_pending = this.has_pending_snippet();
        this.#pending_count = 0;
        this.#local_pending_count = 0;
        this.#main_effect = branch(() => {
          this.#children(this.#anchor);
        });
        if (this.#pending_count > 0) {
          var fragment = this.#offscreen_fragment = document.createDocumentFragment();
          move_effect(this.#main_effect, fragment);
          const pending = (
this.#props.pending
          );
          this.#pending_effect = branch(() => pending(this.#anchor));
        } else {
          this.#resolve();
        }
      } catch (error) {
        this.error(error);
      }
    }
    #resolve() {
      this.is_pending = false;
      for (const e of this.#dirty_effects) {
        set_signal_status(e, DIRTY);
        schedule_effect(e);
      }
      for (const e of this.#maybe_dirty_effects) {
        set_signal_status(e, MAYBE_DIRTY);
        schedule_effect(e);
      }
      this.#dirty_effects.clear();
      this.#maybe_dirty_effects.clear();
    }
defer_effect(effect2) {
      defer_effect(effect2, this.#dirty_effects, this.#maybe_dirty_effects);
    }
is_rendered() {
      return !this.is_pending && (!this.parent || this.parent.is_rendered());
    }
    has_pending_snippet() {
      return !!this.#props.pending;
    }
#run(fn) {
      var previous_effect = active_effect;
      var previous_reaction = active_reaction;
      var previous_ctx = component_context;
      set_active_effect(this.#effect);
      set_active_reaction(this.#effect);
      set_component_context(this.#effect.ctx);
      try {
        return fn();
      } catch (e) {
        handle_error(e);
        return null;
      } finally {
        set_active_effect(previous_effect);
        set_active_reaction(previous_reaction);
        set_component_context(previous_ctx);
      }
    }
#update_pending_count(d) {
      if (!this.has_pending_snippet()) {
        if (this.parent) {
          this.parent.#update_pending_count(d);
        }
        return;
      }
      this.#pending_count += d;
      if (this.#pending_count === 0) {
        this.#resolve();
        if (this.#pending_effect) {
          pause_effect(this.#pending_effect, () => {
            this.#pending_effect = null;
          });
        }
        if (this.#offscreen_fragment) {
          this.#anchor.before(this.#offscreen_fragment);
          this.#offscreen_fragment = null;
        }
      }
    }
update_pending_count(d) {
      this.#update_pending_count(d);
      this.#local_pending_count += d;
      if (!this.#effect_pending || this.#pending_count_update_queued) return;
      this.#pending_count_update_queued = true;
      queue_micro_task(() => {
        this.#pending_count_update_queued = false;
        if (this.#effect_pending) {
          internal_set(this.#effect_pending, this.#local_pending_count);
        }
      });
    }
    get_effect_pending() {
      this.#effect_pending_subscriber();
      return get$1(
this.#effect_pending
      );
    }
error(error) {
      var onerror = this.#props.onerror;
      let failed = this.#props.failed;
      if (!onerror && !failed) {
        throw error;
      }
      if (this.#main_effect) {
        destroy_effect(this.#main_effect);
        this.#main_effect = null;
      }
      if (this.#pending_effect) {
        destroy_effect(this.#pending_effect);
        this.#pending_effect = null;
      }
      if (this.#failed_effect) {
        destroy_effect(this.#failed_effect);
        this.#failed_effect = null;
      }
      var did_reset = false;
      var calling_on_error = false;
      const reset = () => {
        if (did_reset) {
          svelte_boundary_reset_noop();
          return;
        }
        did_reset = true;
        if (calling_on_error) {
          svelte_boundary_reset_onerror();
        }
        if (this.#failed_effect !== null) {
          pause_effect(this.#failed_effect, () => {
            this.#failed_effect = null;
          });
        }
        this.#run(() => {
          Batch.ensure();
          this.#render();
        });
      };
      const handle_error_result = (transformed_error) => {
        try {
          calling_on_error = true;
          onerror?.(transformed_error, reset);
          calling_on_error = false;
        } catch (error2) {
          invoke_error_boundary(error2, this.#effect && this.#effect.parent);
        }
        if (failed) {
          this.#failed_effect = this.#run(() => {
            Batch.ensure();
            try {
              return branch(() => {
                var effect2 = (
active_effect
                );
                effect2.b = this;
                effect2.f |= BOUNDARY_EFFECT;
                failed(
                  this.#anchor,
                  () => transformed_error,
                  () => reset
                );
              });
            } catch (error2) {
              invoke_error_boundary(
                error2,
this.#effect.parent
              );
              return null;
            }
          });
        }
      };
      queue_micro_task(() => {
        var result;
        try {
          result = this.transform_error(error);
        } catch (e) {
          invoke_error_boundary(e, this.#effect && this.#effect.parent);
          return;
        }
        if (result !== null && typeof result === "object" && typeof
result.then === "function") {
          result.then(
            handle_error_result,
(e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)
          );
        } else {
          handle_error_result(result);
        }
      });
    }
  }
  function flatten(blockers, sync, async, fn) {
    const d = derived$1;
    var pending = blockers.filter((b) => !b.settled);
    if (async.length === 0 && pending.length === 0) {
      fn(sync.map(d));
      return;
    }
    var parent = (
active_effect
    );
    var restore = capture();
    var blocker_promise = pending.length === 1 ? pending[0].promise : pending.length > 1 ? Promise.all(pending.map((b) => b.promise)) : null;
    function finish(values) {
      restore();
      try {
        fn(values);
      } catch (error) {
        if ((parent.f & DESTROYED) === 0) {
          invoke_error_boundary(error, parent);
        }
      }
      unset_context();
    }
    if (async.length === 0) {
      blocker_promise.then(() => finish(sync.map(d)));
      return;
    }
    function run() {
      restore();
      Promise.all(async.map((expression) => async_derived(expression))).then((result) => finish([...sync.map(d), ...result])).catch((error) => invoke_error_boundary(error, parent));
    }
    if (blocker_promise) {
      blocker_promise.then(run);
    } else {
      run();
    }
  }
  function capture() {
    var previous_effect = active_effect;
    var previous_reaction = active_reaction;
    var previous_component_context = component_context;
    var previous_batch2 = current_batch;
    return function restore(activate_batch = true) {
      set_active_effect(previous_effect);
      set_active_reaction(previous_reaction);
      set_component_context(previous_component_context);
      if (activate_batch) previous_batch2?.activate();
    };
  }
  function unset_context(deactivate_batch = true) {
    set_active_effect(null);
    set_active_reaction(null);
    set_component_context(null);
    if (deactivate_batch) current_batch?.deactivate();
  }
  function increment_pending() {
    var boundary2 = (

active_effect.b
    );
    var batch = (
current_batch
    );
    var blocking = boundary2.is_rendered();
    boundary2.update_pending_count(1);
    batch.increment(blocking);
    return () => {
      boundary2.update_pending_count(-1);
      batch.decrement(blocking);
    };
  }
function derived$1(fn) {
    var flags2 = DERIVED | DIRTY;
    var parent_derived = active_reaction !== null && (active_reaction.f & DERIVED) !== 0 ? (
active_reaction
    ) : null;
    if (active_effect !== null) {
      active_effect.f |= EFFECT_PRESERVED;
    }
    const signal = {
      ctx: component_context,
      deps: null,
      effects: null,
      equals,
      f: flags2,
      fn,
      reactions: null,
      rv: 0,
      v: (
UNINITIALIZED
      ),
      wv: 0,
      parent: parent_derived ?? active_effect,
      ac: null
    };
    return signal;
  }
function async_derived(fn, label, location) {
    let parent = (
active_effect
    );
    if (parent === null) {
      async_derived_orphan();
    }
    var promise = (

void 0
    );
    var signal = source(
UNINITIALIZED
    );
    var should_suspend = !active_reaction;
    var deferreds = new Map();
    async_effect(() => {
      var d = deferred();
      promise = d.promise;
      try {
        Promise.resolve(fn()).then(d.resolve, d.reject).finally(unset_context);
      } catch (error) {
        d.reject(error);
        unset_context();
      }
      var batch = (
current_batch
      );
      if (should_suspend) {
        var decrement_pending = increment_pending();
        deferreds.get(batch)?.reject(STALE_REACTION);
        deferreds.delete(batch);
        deferreds.set(batch, d);
      }
      const handler = (value, error = void 0) => {
        batch.activate();
        if (error) {
          if (error !== STALE_REACTION) {
            signal.f |= ERROR_VALUE;
            internal_set(signal, error);
          }
        } else {
          if ((signal.f & ERROR_VALUE) !== 0) {
            signal.f ^= ERROR_VALUE;
          }
          internal_set(signal, value);
          for (const [b, d2] of deferreds) {
            deferreds.delete(b);
            if (b === batch) break;
            d2.reject(STALE_REACTION);
          }
        }
        if (decrement_pending) {
          decrement_pending();
        }
      };
      d.promise.then(handler, (e) => handler(null, e || "unknown"));
    });
    teardown(() => {
      for (const d of deferreds.values()) {
        d.reject(STALE_REACTION);
      }
    });
    return new Promise((fulfil) => {
      function next(p) {
        function go() {
          if (p === promise) {
            fulfil(signal);
          } else {
            next(promise);
          }
        }
        p.then(go, go);
      }
      next(promise);
    });
  }
function user_derived(fn) {
    const d = derived$1(fn);
    push_reaction_value(d);
    return d;
  }
function derived_safe_equal(fn) {
    const signal = derived$1(fn);
    signal.equals = safe_equals;
    return signal;
  }
  function destroy_derived_effects(derived2) {
    var effects = derived2.effects;
    if (effects !== null) {
      derived2.effects = null;
      for (var i = 0; i < effects.length; i += 1) {
        destroy_effect(
effects[i]
        );
      }
    }
  }
  function get_derived_parent_effect(derived2) {
    var parent = derived2.parent;
    while (parent !== null) {
      if ((parent.f & DERIVED) === 0) {
        return (parent.f & DESTROYED) === 0 ? (
parent
        ) : null;
      }
      parent = parent.parent;
    }
    return null;
  }
  function execute_derived(derived2) {
    var value;
    var prev_active_effect = active_effect;
    set_active_effect(get_derived_parent_effect(derived2));
    {
      try {
        derived2.f &= ~WAS_MARKED;
        destroy_derived_effects(derived2);
        value = update_reaction(derived2);
      } finally {
        set_active_effect(prev_active_effect);
      }
    }
    return value;
  }
  function update_derived(derived2) {
    var value = execute_derived(derived2);
    if (!derived2.equals(value)) {
      derived2.wv = increment_write_version();
      if (!current_batch?.is_fork || derived2.deps === null) {
        derived2.v = value;
        if (derived2.deps === null) {
          set_signal_status(derived2, CLEAN);
          return;
        }
      }
    }
    if (is_destroying_effect) {
      return;
    }
    if (batch_values !== null) {
      if (effect_tracking() || current_batch?.is_fork) {
        batch_values.set(derived2, value);
      }
    } else {
      update_derived_status(derived2);
    }
  }
  function freeze_derived_effects(derived2) {
    if (derived2.effects === null) return;
    for (const e of derived2.effects) {
      if (e.teardown || e.ac) {
        e.teardown?.();
        e.ac?.abort(STALE_REACTION);
        e.teardown = noop;
        e.ac = null;
        remove_reactions(e, 0);
        destroy_effect_children(e);
      }
    }
  }
  function unfreeze_derived_effects(derived2) {
    if (derived2.effects === null) return;
    for (const e of derived2.effects) {
      if (e.teardown) {
        update_effect(e);
      }
    }
  }
  let eager_effects = new Set();
  const old_values = new Map();
  let eager_effects_deferred = false;
  function source(v, stack) {
    var signal = {
      f: 0,
v,
      reactions: null,
      equals,
      rv: 0,
      wv: 0
    };
    return signal;
  }
function state(v, stack) {
    const s = source(v);
    push_reaction_value(s);
    return s;
  }
function mutable_source(initial_value, immutable = false, trackable = true) {
    const s = source(initial_value);
    if (!immutable) {
      s.equals = safe_equals;
    }
    return s;
  }
  function set(source2, value, should_proxy = false) {
    if (active_reaction !== null &&

(!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) && is_runes() && (active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 && (current_sources === null || !includes.call(current_sources, source2))) {
      state_unsafe_mutation();
    }
    let new_value = should_proxy ? proxy(value) : value;
    return internal_set(source2, new_value);
  }
  function internal_set(source2, value) {
    if (!source2.equals(value)) {
      var old_value = source2.v;
      if (is_destroying_effect) {
        old_values.set(source2, value);
      } else {
        old_values.set(source2, old_value);
      }
      source2.v = value;
      var batch = Batch.ensure();
      batch.capture(source2, old_value);
      if ((source2.f & DERIVED) !== 0) {
        const derived2 = (
source2
        );
        if ((source2.f & DIRTY) !== 0) {
          execute_derived(derived2);
        }
        update_derived_status(derived2);
      }
      source2.wv = increment_write_version();
      mark_reactions(source2, DIRTY);
      if (active_effect !== null && (active_effect.f & CLEAN) !== 0 && (active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0) {
        if (untracked_writes === null) {
          set_untracked_writes([source2]);
        } else {
          untracked_writes.push(source2);
        }
      }
      if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) {
        flush_eager_effects();
      }
    }
    return value;
  }
  function flush_eager_effects() {
    eager_effects_deferred = false;
    for (const effect2 of eager_effects) {
      if ((effect2.f & CLEAN) !== 0) {
        set_signal_status(effect2, MAYBE_DIRTY);
      }
      if (is_dirty(effect2)) {
        update_effect(effect2);
      }
    }
    eager_effects.clear();
  }
  function increment(source2) {
    set(source2, source2.v + 1);
  }
  function mark_reactions(signal, status) {
    var reactions = signal.reactions;
    if (reactions === null) return;
    var length = reactions.length;
    for (var i = 0; i < length; i++) {
      var reaction = reactions[i];
      var flags2 = reaction.f;
      var not_dirty = (flags2 & DIRTY) === 0;
      if (not_dirty) {
        set_signal_status(reaction, status);
      }
      if ((flags2 & DERIVED) !== 0) {
        var derived2 = (
reaction
        );
        batch_values?.delete(derived2);
        if ((flags2 & WAS_MARKED) === 0) {
          if (flags2 & CONNECTED) {
            reaction.f |= WAS_MARKED;
          }
          mark_reactions(derived2, MAYBE_DIRTY);
        }
      } else if (not_dirty) {
        if ((flags2 & BLOCK_EFFECT) !== 0 && eager_block_effects !== null) {
          eager_block_effects.add(
reaction
          );
        }
        schedule_effect(
reaction
        );
      }
    }
  }
  function proxy(value) {
    if (typeof value !== "object" || value === null || STATE_SYMBOL in value) {
      return value;
    }
    const prototype = get_prototype_of(value);
    if (prototype !== object_prototype && prototype !== array_prototype) {
      return value;
    }
    var sources = new Map();
    var is_proxied_array = is_array(value);
    var version = state(0);
    var parent_version = update_version;
    var with_parent = (fn) => {
      if (update_version === parent_version) {
        return fn();
      }
      var reaction = active_reaction;
      var version2 = update_version;
      set_active_reaction(null);
      set_update_version(parent_version);
      var result = fn();
      set_active_reaction(reaction);
      set_update_version(version2);
      return result;
    };
    if (is_proxied_array) {
      sources.set("length", state(
value.length
      ));
    }
    return new Proxy(
value,
      {
        defineProperty(_, prop2, descriptor) {
          if (!("value" in descriptor) || descriptor.configurable === false || descriptor.enumerable === false || descriptor.writable === false) {
            state_descriptors_fixed();
          }
          var s = sources.get(prop2);
          if (s === void 0) {
            with_parent(() => {
              var s2 = state(descriptor.value);
              sources.set(prop2, s2);
              return s2;
            });
          } else {
            set(s, descriptor.value, true);
          }
          return true;
        },
        deleteProperty(target, prop2) {
          var s = sources.get(prop2);
          if (s === void 0) {
            if (prop2 in target) {
              const s2 = with_parent(() => state(UNINITIALIZED));
              sources.set(prop2, s2);
              increment(version);
            }
          } else {
            set(s, UNINITIALIZED);
            increment(version);
          }
          return true;
        },
        get(target, prop2, receiver) {
          if (prop2 === STATE_SYMBOL) {
            return value;
          }
          var s = sources.get(prop2);
          var exists = prop2 in target;
          if (s === void 0 && (!exists || get_descriptor(target, prop2)?.writable)) {
            s = with_parent(() => {
              var p = proxy(exists ? target[prop2] : UNINITIALIZED);
              var s2 = state(p);
              return s2;
            });
            sources.set(prop2, s);
          }
          if (s !== void 0) {
            var v = get$1(s);
            return v === UNINITIALIZED ? void 0 : v;
          }
          return Reflect.get(target, prop2, receiver);
        },
        getOwnPropertyDescriptor(target, prop2) {
          var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
          if (descriptor && "value" in descriptor) {
            var s = sources.get(prop2);
            if (s) descriptor.value = get$1(s);
          } else if (descriptor === void 0) {
            var source2 = sources.get(prop2);
            var value2 = source2?.v;
            if (source2 !== void 0 && value2 !== UNINITIALIZED) {
              return {
                enumerable: true,
                configurable: true,
                value: value2,
                writable: true
              };
            }
          }
          return descriptor;
        },
        has(target, prop2) {
          if (prop2 === STATE_SYMBOL) {
            return true;
          }
          var s = sources.get(prop2);
          var has = s !== void 0 && s.v !== UNINITIALIZED || Reflect.has(target, prop2);
          if (s !== void 0 || active_effect !== null && (!has || get_descriptor(target, prop2)?.writable)) {
            if (s === void 0) {
              s = with_parent(() => {
                var p = has ? proxy(target[prop2]) : UNINITIALIZED;
                var s2 = state(p);
                return s2;
              });
              sources.set(prop2, s);
            }
            var value2 = get$1(s);
            if (value2 === UNINITIALIZED) {
              return false;
            }
          }
          return has;
        },
        set(target, prop2, value2, receiver) {
          var s = sources.get(prop2);
          var has = prop2 in target;
          if (is_proxied_array && prop2 === "length") {
            for (var i = value2; i <
s.v; i += 1) {
              var other_s = sources.get(i + "");
              if (other_s !== void 0) {
                set(other_s, UNINITIALIZED);
              } else if (i in target) {
                other_s = with_parent(() => state(UNINITIALIZED));
                sources.set(i + "", other_s);
              }
            }
          }
          if (s === void 0) {
            if (!has || get_descriptor(target, prop2)?.writable) {
              s = with_parent(() => state(void 0));
              set(s, proxy(value2));
              sources.set(prop2, s);
            }
          } else {
            has = s.v !== UNINITIALIZED;
            var p = with_parent(() => proxy(value2));
            set(s, p);
          }
          var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
          if (descriptor?.set) {
            descriptor.set.call(receiver, value2);
          }
          if (!has) {
            if (is_proxied_array && typeof prop2 === "string") {
              var ls = (
sources.get("length")
              );
              var n = Number(prop2);
              if (Number.isInteger(n) && n >= ls.v) {
                set(ls, n + 1);
              }
            }
            increment(version);
          }
          return true;
        },
        ownKeys(target) {
          get$1(version);
          var own_keys = Reflect.ownKeys(target).filter((key2) => {
            var source3 = sources.get(key2);
            return source3 === void 0 || source3.v !== UNINITIALIZED;
          });
          for (var [key, source2] of sources) {
            if (source2.v !== UNINITIALIZED && !(key in target)) {
              own_keys.push(key);
            }
          }
          return own_keys;
        },
        setPrototypeOf() {
          state_prototype_fixed();
        }
      }
    );
  }
  function get_proxied_value(value) {
    try {
      if (value !== null && typeof value === "object" && STATE_SYMBOL in value) {
        return value[STATE_SYMBOL];
      }
    } catch {
    }
    return value;
  }
  function is(a, b) {
    return Object.is(get_proxied_value(a), get_proxied_value(b));
  }
  var $window;
  var is_firefox;
  var first_child_getter;
  var next_sibling_getter;
  function init_operations() {
    if ($window !== void 0) {
      return;
    }
    $window = window;
    is_firefox = /Firefox/.test(navigator.userAgent);
    var element_prototype = Element.prototype;
    var node_prototype = Node.prototype;
    var text_prototype = Text.prototype;
    first_child_getter = get_descriptor(node_prototype, "firstChild").get;
    next_sibling_getter = get_descriptor(node_prototype, "nextSibling").get;
    if (is_extensible(element_prototype)) {
      element_prototype.__click = void 0;
      element_prototype.__className = void 0;
      element_prototype.__attributes = null;
      element_prototype.__style = void 0;
      element_prototype.__e = void 0;
    }
    if (is_extensible(text_prototype)) {
      text_prototype.__t = void 0;
    }
  }
  function create_text(value = "") {
    return document.createTextNode(value);
  }
function get_first_child(node) {
    return (
first_child_getter.call(node)
    );
  }
function get_next_sibling(node) {
    return (
next_sibling_getter.call(node)
    );
  }
  function child(node, is_text) {
    {
      return get_first_child(node);
    }
  }
  function first_child(node, is_text = false) {
    {
      var first = get_first_child(node);
      if (first instanceof Comment && first.data === "") return get_next_sibling(first);
      return first;
    }
  }
  function sibling(node, count = 1, is_text = false) {
    let next_sibling = node;
    while (count--) {
      next_sibling =

get_next_sibling(next_sibling);
    }
    {
      return next_sibling;
    }
  }
  function clear_text_content(node) {
    node.textContent = "";
  }
  function create_element(tag, namespace, is2) {
    let options = void 0;
    return (
document.createElementNS(NAMESPACE_HTML, tag, options)
    );
  }
  let listening_to_form_reset = false;
  function add_form_reset_listener() {
    if (!listening_to_form_reset) {
      listening_to_form_reset = true;
      document.addEventListener(
        "reset",
        (evt) => {
          Promise.resolve().then(() => {
            if (!evt.defaultPrevented) {
              for (
                const e of
evt.target.elements
              ) {
                e.__on_r?.();
              }
            }
          });
        },
{ capture: true }
      );
    }
  }
  function without_reactive_context(fn) {
    var previous_reaction = active_reaction;
    var previous_effect = active_effect;
    set_active_reaction(null);
    set_active_effect(null);
    try {
      return fn();
    } finally {
      set_active_reaction(previous_reaction);
      set_active_effect(previous_effect);
    }
  }
  function listen_to_event_and_reset_event(element, event2, handler, on_reset = handler) {
    element.addEventListener(event2, () => without_reactive_context(handler));
    const prev = element.__on_r;
    if (prev) {
      element.__on_r = () => {
        prev();
        on_reset(true);
      };
    } else {
      element.__on_r = () => on_reset(true);
    }
    add_form_reset_listener();
  }
  function validate_effect(rune) {
    if (active_effect === null) {
      if (active_reaction === null) {
        effect_orphan();
      }
      effect_in_unowned_derived();
    }
    if (is_destroying_effect) {
      effect_in_teardown();
    }
  }
  function push_effect(effect2, parent_effect) {
    var parent_last = parent_effect.last;
    if (parent_last === null) {
      parent_effect.last = parent_effect.first = effect2;
    } else {
      parent_last.next = effect2;
      effect2.prev = parent_last;
      parent_effect.last = effect2;
    }
  }
  function create_effect(type, fn) {
    var parent = active_effect;
    if (parent !== null && (parent.f & INERT) !== 0) {
      type |= INERT;
    }
    var effect2 = {
      ctx: component_context,
      deps: null,
      nodes: null,
      f: type | DIRTY | CONNECTED,
      first: null,
      fn,
      last: null,
      next: null,
      parent,
      b: parent && parent.b,
      prev: null,
      teardown: null,
      wv: 0,
      ac: null
    };
    var e = effect2;
    if ((type & EFFECT) !== 0) {
      if (collected_effects !== null) {
        collected_effects.push(effect2);
      } else {
        schedule_effect(effect2);
      }
    } else if (fn !== null) {
      try {
        update_effect(effect2);
      } catch (e2) {
        destroy_effect(effect2);
        throw e2;
      }
      if (e.deps === null && e.teardown === null && e.nodes === null && e.first === e.last &&
(e.f & EFFECT_PRESERVED) === 0) {
        e = e.first;
        if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {
          e.f |= EFFECT_TRANSPARENT;
        }
      }
    }
    if (e !== null) {
      e.parent = parent;
      if (parent !== null) {
        push_effect(e, parent);
      }
      if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0 && (type & ROOT_EFFECT) === 0) {
        var derived2 = (
active_reaction
        );
        (derived2.effects ??= []).push(e);
      }
    }
    return effect2;
  }
  function effect_tracking() {
    return active_reaction !== null && !untracking;
  }
  function teardown(fn) {
    const effect2 = create_effect(RENDER_EFFECT, null);
    set_signal_status(effect2, CLEAN);
    effect2.teardown = fn;
    return effect2;
  }
  function user_effect(fn) {
    validate_effect();
    var flags2 = (
active_effect.f
    );
    var defer = !active_reaction && (flags2 & BRANCH_EFFECT) !== 0 && (flags2 & REACTION_RAN) === 0;
    if (defer) {
      var context = (
component_context
      );
      (context.e ??= []).push(fn);
    } else {
      return create_user_effect(fn);
    }
  }
  function create_user_effect(fn) {
    return create_effect(EFFECT | USER_EFFECT, fn);
  }
  function component_root(fn) {
    Batch.ensure();
    const effect2 = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);
    return (options = {}) => {
      return new Promise((fulfil) => {
        if (options.outro) {
          pause_effect(effect2, () => {
            destroy_effect(effect2);
            fulfil(void 0);
          });
        } else {
          destroy_effect(effect2);
          fulfil(void 0);
        }
      });
    };
  }
  function effect(fn) {
    return create_effect(EFFECT, fn);
  }
  function async_effect(fn) {
    return create_effect(ASYNC | EFFECT_PRESERVED, fn);
  }
  function render_effect(fn, flags2 = 0) {
    return create_effect(RENDER_EFFECT | flags2, fn);
  }
  function template_effect(fn, sync = [], async = [], blockers = []) {
    flatten(blockers, sync, async, (values) => {
      create_effect(RENDER_EFFECT, () => fn(...values.map(get$1)));
    });
  }
  function block(fn, flags2 = 0) {
    var effect2 = create_effect(BLOCK_EFFECT | flags2, fn);
    return effect2;
  }
  function branch(fn) {
    return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn);
  }
  function execute_effect_teardown(effect2) {
    var teardown2 = effect2.teardown;
    if (teardown2 !== null) {
      const previously_destroying_effect = is_destroying_effect;
      const previous_reaction = active_reaction;
      set_is_destroying_effect(true);
      set_active_reaction(null);
      try {
        teardown2.call(null);
      } finally {
        set_is_destroying_effect(previously_destroying_effect);
        set_active_reaction(previous_reaction);
      }
    }
  }
  function destroy_effect_children(signal, remove_dom = false) {
    var effect2 = signal.first;
    signal.first = signal.last = null;
    while (effect2 !== null) {
      const controller = effect2.ac;
      if (controller !== null) {
        without_reactive_context(() => {
          controller.abort(STALE_REACTION);
        });
      }
      var next = effect2.next;
      if ((effect2.f & ROOT_EFFECT) !== 0) {
        effect2.parent = null;
      } else {
        destroy_effect(effect2, remove_dom);
      }
      effect2 = next;
    }
  }
  function destroy_block_effect_children(signal) {
    var effect2 = signal.first;
    while (effect2 !== null) {
      var next = effect2.next;
      if ((effect2.f & BRANCH_EFFECT) === 0) {
        destroy_effect(effect2);
      }
      effect2 = next;
    }
  }
  function destroy_effect(effect2, remove_dom = true) {
    var removed = false;
    if ((remove_dom || (effect2.f & HEAD_EFFECT) !== 0) && effect2.nodes !== null && effect2.nodes.end !== null) {
      remove_effect_dom(
        effect2.nodes.start,
effect2.nodes.end
      );
      removed = true;
    }
    destroy_effect_children(effect2, remove_dom && !removed);
    remove_reactions(effect2, 0);
    set_signal_status(effect2, DESTROYED);
    var transitions = effect2.nodes && effect2.nodes.t;
    if (transitions !== null) {
      for (const transition of transitions) {
        transition.stop();
      }
    }
    execute_effect_teardown(effect2);
    var parent = effect2.parent;
    if (parent !== null && parent.first !== null) {
      unlink_effect(effect2);
    }
    effect2.next = effect2.prev = effect2.teardown = effect2.ctx = effect2.deps = effect2.fn = effect2.nodes = effect2.ac = null;
  }
  function remove_effect_dom(node, end) {
    while (node !== null) {
      var next = node === end ? null : get_next_sibling(node);
      node.remove();
      node = next;
    }
  }
  function unlink_effect(effect2) {
    var parent = effect2.parent;
    var prev = effect2.prev;
    var next = effect2.next;
    if (prev !== null) prev.next = next;
    if (next !== null) next.prev = prev;
    if (parent !== null) {
      if (parent.first === effect2) parent.first = next;
      if (parent.last === effect2) parent.last = prev;
    }
  }
  function pause_effect(effect2, callback, destroy = true) {
    var transitions = [];
    pause_children(effect2, transitions, true);
    var fn = () => {
      if (destroy) destroy_effect(effect2);
      if (callback) callback();
    };
    var remaining = transitions.length;
    if (remaining > 0) {
      var check = () => --remaining || fn();
      for (var transition of transitions) {
        transition.out(check);
      }
    } else {
      fn();
    }
  }
  function pause_children(effect2, transitions, local) {
    if ((effect2.f & INERT) !== 0) return;
    effect2.f ^= INERT;
    var t = effect2.nodes && effect2.nodes.t;
    if (t !== null) {
      for (const transition of t) {
        if (transition.is_global || local) {
          transitions.push(transition);
        }
      }
    }
    var child2 = effect2.first;
    while (child2 !== null) {
      var sibling2 = child2.next;
      var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 ||


(child2.f & BRANCH_EFFECT) !== 0 && (effect2.f & BLOCK_EFFECT) !== 0;
      pause_children(child2, transitions, transparent ? local : false);
      child2 = sibling2;
    }
  }
  function resume_effect(effect2) {
    resume_children(effect2, true);
  }
  function resume_children(effect2, local) {
    if ((effect2.f & INERT) === 0) return;
    effect2.f ^= INERT;
    if ((effect2.f & CLEAN) === 0) {
      set_signal_status(effect2, DIRTY);
      schedule_effect(effect2);
    }
    var child2 = effect2.first;
    while (child2 !== null) {
      var sibling2 = child2.next;
      var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 || (child2.f & BRANCH_EFFECT) !== 0;
      resume_children(child2, transparent ? local : false);
      child2 = sibling2;
    }
    var t = effect2.nodes && effect2.nodes.t;
    if (t !== null) {
      for (const transition of t) {
        if (transition.is_global || local) {
          transition.in();
        }
      }
    }
  }
  function move_effect(effect2, fragment) {
    if (!effect2.nodes) return;
    var node = effect2.nodes.start;
    var end = effect2.nodes.end;
    while (node !== null) {
      var next = node === end ? null : get_next_sibling(node);
      fragment.append(node);
      node = next;
    }
  }
  let is_updating_effect = false;
  let is_destroying_effect = false;
  function set_is_destroying_effect(value) {
    is_destroying_effect = value;
  }
  let active_reaction = null;
  let untracking = false;
  function set_active_reaction(reaction) {
    active_reaction = reaction;
  }
  let active_effect = null;
  function set_active_effect(effect2) {
    active_effect = effect2;
  }
  let current_sources = null;
  function push_reaction_value(value) {
    if (active_reaction !== null && true) {
      if (current_sources === null) {
        current_sources = [value];
      } else {
        current_sources.push(value);
      }
    }
  }
  let new_deps = null;
  let skipped_deps = 0;
  let untracked_writes = null;
  function set_untracked_writes(value) {
    untracked_writes = value;
  }
  let write_version = 1;
  let read_version = 0;
  let update_version = read_version;
  function set_update_version(value) {
    update_version = value;
  }
  function increment_write_version() {
    return ++write_version;
  }
  function is_dirty(reaction) {
    var flags2 = reaction.f;
    if ((flags2 & DIRTY) !== 0) {
      return true;
    }
    if (flags2 & DERIVED) {
      reaction.f &= ~WAS_MARKED;
    }
    if ((flags2 & MAYBE_DIRTY) !== 0) {
      var dependencies = (
reaction.deps
      );
      var length = dependencies.length;
      for (var i = 0; i < length; i++) {
        var dependency = dependencies[i];
        if (is_dirty(
dependency
        )) {
          update_derived(
dependency
          );
        }
        if (dependency.wv > reaction.wv) {
          return true;
        }
      }
      if ((flags2 & CONNECTED) !== 0 &&

batch_values === null) {
        set_signal_status(reaction, CLEAN);
      }
    }
    return false;
  }
  function schedule_possible_effect_self_invalidation(signal, effect2, root2 = true) {
    var reactions = signal.reactions;
    if (reactions === null) return;
    if (current_sources !== null && includes.call(current_sources, signal)) {
      return;
    }
    for (var i = 0; i < reactions.length; i++) {
      var reaction = reactions[i];
      if ((reaction.f & DERIVED) !== 0) {
        schedule_possible_effect_self_invalidation(
reaction,
          effect2,
          false
        );
      } else if (effect2 === reaction) {
        if (root2) {
          set_signal_status(reaction, DIRTY);
        } else if ((reaction.f & CLEAN) !== 0) {
          set_signal_status(reaction, MAYBE_DIRTY);
        }
        schedule_effect(
reaction
        );
      }
    }
  }
  function update_reaction(reaction) {
    var previous_deps = new_deps;
    var previous_skipped_deps = skipped_deps;
    var previous_untracked_writes = untracked_writes;
    var previous_reaction = active_reaction;
    var previous_sources = current_sources;
    var previous_component_context = component_context;
    var previous_untracking = untracking;
    var previous_update_version = update_version;
    var flags2 = reaction.f;
    new_deps =
null;
    skipped_deps = 0;
    untracked_writes = null;
    active_reaction = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
    current_sources = null;
    set_component_context(reaction.ctx);
    untracking = false;
    update_version = ++read_version;
    if (reaction.ac !== null) {
      without_reactive_context(() => {
        reaction.ac.abort(STALE_REACTION);
      });
      reaction.ac = null;
    }
    try {
      reaction.f |= REACTION_IS_UPDATING;
      var fn = (
reaction.fn
      );
      var result = fn();
      reaction.f |= REACTION_RAN;
      var deps = reaction.deps;
      var is_fork = current_batch?.is_fork;
      if (new_deps !== null) {
        var i;
        if (!is_fork) {
          remove_reactions(reaction, skipped_deps);
        }
        if (deps !== null && skipped_deps > 0) {
          deps.length = skipped_deps + new_deps.length;
          for (i = 0; i < new_deps.length; i++) {
            deps[skipped_deps + i] = new_deps[i];
          }
        } else {
          reaction.deps = deps = new_deps;
        }
        if (effect_tracking() && (reaction.f & CONNECTED) !== 0) {
          for (i = skipped_deps; i < deps.length; i++) {
            (deps[i].reactions ??= []).push(reaction);
          }
        }
      } else if (!is_fork && deps !== null && skipped_deps < deps.length) {
        remove_reactions(reaction, skipped_deps);
        deps.length = skipped_deps;
      }
      if (is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0) {
        for (i = 0; i <
untracked_writes.length; i++) {
          schedule_possible_effect_self_invalidation(
            untracked_writes[i],
reaction
          );
        }
      }
      if (previous_reaction !== null && previous_reaction !== reaction) {
        read_version++;
        if (previous_reaction.deps !== null) {
          for (let i2 = 0; i2 < previous_skipped_deps; i2 += 1) {
            previous_reaction.deps[i2].rv = read_version;
          }
        }
        if (previous_deps !== null) {
          for (const dep of previous_deps) {
            dep.rv = read_version;
          }
        }
        if (untracked_writes !== null) {
          if (previous_untracked_writes === null) {
            previous_untracked_writes = untracked_writes;
          } else {
            previous_untracked_writes.push(...
untracked_writes);
          }
        }
      }
      if ((reaction.f & ERROR_VALUE) !== 0) {
        reaction.f ^= ERROR_VALUE;
      }
      return result;
    } catch (error) {
      return handle_error(error);
    } finally {
      reaction.f ^= REACTION_IS_UPDATING;
      new_deps = previous_deps;
      skipped_deps = previous_skipped_deps;
      untracked_writes = previous_untracked_writes;
      active_reaction = previous_reaction;
      current_sources = previous_sources;
      set_component_context(previous_component_context);
      untracking = previous_untracking;
      update_version = previous_update_version;
    }
  }
  function remove_reaction(signal, dependency) {
    let reactions = dependency.reactions;
    if (reactions !== null) {
      var index2 = index_of.call(reactions, signal);
      if (index2 !== -1) {
        var new_length = reactions.length - 1;
        if (new_length === 0) {
          reactions = dependency.reactions = null;
        } else {
          reactions[index2] = reactions[new_length];
          reactions.pop();
        }
      }
    }
    if (reactions === null && (dependency.f & DERIVED) !== 0 &&


(new_deps === null || !includes.call(new_deps, dependency))) {
      var derived2 = (
dependency
      );
      if ((derived2.f & CONNECTED) !== 0) {
        derived2.f ^= CONNECTED;
        derived2.f &= ~WAS_MARKED;
      }
      update_derived_status(derived2);
      freeze_derived_effects(derived2);
      remove_reactions(derived2, 0);
    }
  }
  function remove_reactions(signal, start_index) {
    var dependencies = signal.deps;
    if (dependencies === null) return;
    for (var i = start_index; i < dependencies.length; i++) {
      remove_reaction(signal, dependencies[i]);
    }
  }
  function update_effect(effect2) {
    var flags2 = effect2.f;
    if ((flags2 & DESTROYED) !== 0) {
      return;
    }
    set_signal_status(effect2, CLEAN);
    var previous_effect = active_effect;
    var was_updating_effect = is_updating_effect;
    active_effect = effect2;
    is_updating_effect = true;
    try {
      if ((flags2 & (BLOCK_EFFECT | MANAGED_EFFECT)) !== 0) {
        destroy_block_effect_children(effect2);
      } else {
        destroy_effect_children(effect2);
      }
      execute_effect_teardown(effect2);
      var teardown2 = update_reaction(effect2);
      effect2.teardown = typeof teardown2 === "function" ? teardown2 : null;
      effect2.wv = write_version;
      var dep;
      if (DEV && tracing_mode_flag && (effect2.f & DIRTY) !== 0 && effect2.deps !== null) ;
    } finally {
      is_updating_effect = was_updating_effect;
      active_effect = previous_effect;
    }
  }
  async function tick() {
    await Promise.resolve();
    flushSync();
  }
  function get$1(signal) {
    var flags2 = signal.f;
    var is_derived = (flags2 & DERIVED) !== 0;
    if (active_reaction !== null && !untracking) {
      var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;
      if (!destroyed && (current_sources === null || !includes.call(current_sources, signal))) {
        var deps = active_reaction.deps;
        if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {
          if (signal.rv < read_version) {
            signal.rv = read_version;
            if (new_deps === null && deps !== null && deps[skipped_deps] === signal) {
              skipped_deps++;
            } else if (new_deps === null) {
              new_deps = [signal];
            } else {
              new_deps.push(signal);
            }
          }
        } else {
          (active_reaction.deps ??= []).push(signal);
          var reactions = signal.reactions;
          if (reactions === null) {
            signal.reactions = [active_reaction];
          } else if (!includes.call(reactions, active_reaction)) {
            reactions.push(active_reaction);
          }
        }
      }
    }
    if (is_destroying_effect && old_values.has(signal)) {
      return old_values.get(signal);
    }
    if (is_derived) {
      var derived2 = (
signal
      );
      if (is_destroying_effect) {
        var value = derived2.v;
        if ((derived2.f & CLEAN) === 0 && derived2.reactions !== null || depends_on_old_values(derived2)) {
          value = execute_derived(derived2);
        }
        old_values.set(derived2, value);
        return value;
      }
      var should_connect = (derived2.f & CONNECTED) === 0 && !untracking && active_reaction !== null && (is_updating_effect || (active_reaction.f & CONNECTED) !== 0);
      var is_new = (derived2.f & REACTION_RAN) === 0;
      if (is_dirty(derived2)) {
        if (should_connect) {
          derived2.f |= CONNECTED;
        }
        update_derived(derived2);
      }
      if (should_connect && !is_new) {
        unfreeze_derived_effects(derived2);
        reconnect(derived2);
      }
    }
    if (batch_values?.has(signal)) {
      return batch_values.get(signal);
    }
    if ((signal.f & ERROR_VALUE) !== 0) {
      throw signal.v;
    }
    return signal.v;
  }
  function reconnect(derived2) {
    derived2.f |= CONNECTED;
    if (derived2.deps === null) return;
    for (const dep of derived2.deps) {
      (dep.reactions ??= []).push(derived2);
      if ((dep.f & DERIVED) !== 0 && (dep.f & CONNECTED) === 0) {
        unfreeze_derived_effects(
dep
        );
        reconnect(
dep
        );
      }
    }
  }
  function depends_on_old_values(derived2) {
    if (derived2.v === UNINITIALIZED) return true;
    if (derived2.deps === null) return false;
    for (const dep of derived2.deps) {
      if (old_values.has(dep)) {
        return true;
      }
      if ((dep.f & DERIVED) !== 0 && depends_on_old_values(
dep
      )) {
        return true;
      }
    }
    return false;
  }
  function untrack(fn) {
    var previous_untracking = untracking;
    try {
      untracking = true;
      return fn();
    } finally {
      untracking = previous_untracking;
    }
  }
  function deep_read_state(value) {
    if (typeof value !== "object" || !value || value instanceof EventTarget) {
      return;
    }
    if (STATE_SYMBOL in value) {
      deep_read(value);
    } else if (!Array.isArray(value)) {
      for (let key in value) {
        const prop2 = value[key];
        if (typeof prop2 === "object" && prop2 && STATE_SYMBOL in prop2) {
          deep_read(prop2);
        }
      }
    }
  }
  function deep_read(value, visited = new Set()) {
    if (typeof value === "object" && value !== null &&
!(value instanceof EventTarget) && !visited.has(value)) {
      visited.add(value);
      if (value instanceof Date) {
        value.getTime();
      }
      for (let key in value) {
        try {
          deep_read(value[key], visited);
        } catch (e) {
        }
      }
      const proto = get_prototype_of(value);
      if (proto !== Object.prototype && proto !== Array.prototype && proto !== Map.prototype && proto !== Set.prototype && proto !== Date.prototype) {
        const descriptors = get_descriptors(proto);
        for (let key in descriptors) {
          const get2 = descriptors[key].get;
          if (get2) {
            try {
              get2.call(value);
            } catch (e) {
            }
          }
        }
      }
    }
  }
  const PASSIVE_EVENTS = ["touchstart", "touchmove"];
  function is_passive_event(name) {
    return PASSIVE_EVENTS.includes(name);
  }
  const event_symbol = Symbol("events");
  const all_registered_events = new Set();
  const root_event_handles = new Set();
  function create_event(event_name, dom, handler, options = {}) {
    function target_handler(event2) {
      if (!options.capture) {
        handle_event_propagation.call(dom, event2);
      }
      if (!event2.cancelBubble) {
        return without_reactive_context(() => {
          return handler?.call(this, event2);
        });
      }
    }
    if (event_name.startsWith("pointer") || event_name.startsWith("touch") || event_name === "wheel") {
      queue_micro_task(() => {
        dom.addEventListener(event_name, target_handler, options);
      });
    } else {
      dom.addEventListener(event_name, target_handler, options);
    }
    return target_handler;
  }
  function event(event_name, dom, handler, capture2, passive) {
    var options = { capture: capture2, passive };
    var target_handler = create_event(event_name, dom, handler, options);
    if (dom === document.body ||
dom === window ||
dom === document ||
dom instanceof HTMLMediaElement) {
      teardown(() => {
        dom.removeEventListener(event_name, target_handler, options);
      });
    }
  }
  function delegated(event_name, element, handler) {
    (element[event_symbol] ??= {})[event_name] = handler;
  }
  function delegate(events) {
    for (var i = 0; i < events.length; i++) {
      all_registered_events.add(events[i]);
    }
    for (var fn of root_event_handles) {
      fn(events);
    }
  }
  let last_propagated_event = null;
  function handle_event_propagation(event2) {
    var handler_element = this;
    var owner_document = (
handler_element.ownerDocument
    );
    var event_name = event2.type;
    var path = event2.composedPath?.() || [];
    var current_target = (
path[0] || event2.target
    );
    last_propagated_event = event2;
    var path_idx = 0;
    var handled_at = last_propagated_event === event2 && event2[event_symbol];
    if (handled_at) {
      var at_idx = path.indexOf(handled_at);
      if (at_idx !== -1 && (handler_element === document || handler_element ===
window)) {
        event2[event_symbol] = handler_element;
        return;
      }
      var handler_idx = path.indexOf(handler_element);
      if (handler_idx === -1) {
        return;
      }
      if (at_idx <= handler_idx) {
        path_idx = at_idx;
      }
    }
    current_target =
path[path_idx] || event2.target;
    if (current_target === handler_element) return;
    define_property(event2, "currentTarget", {
      configurable: true,
      get() {
        return current_target || owner_document;
      }
    });
    var previous_reaction = active_reaction;
    var previous_effect = active_effect;
    set_active_reaction(null);
    set_active_effect(null);
    try {
      var throw_error;
      var other_errors = [];
      while (current_target !== null) {
        var parent_element = current_target.assignedSlot || current_target.parentNode ||
current_target.host || null;
        try {
          var delegated2 = current_target[event_symbol]?.[event_name];
          if (delegated2 != null && (!
current_target.disabled ||

event2.target === current_target)) {
            delegated2.call(current_target, event2);
          }
        } catch (error) {
          if (throw_error) {
            other_errors.push(error);
          } else {
            throw_error = error;
          }
        }
        if (event2.cancelBubble || parent_element === handler_element || parent_element === null) {
          break;
        }
        current_target = parent_element;
      }
      if (throw_error) {
        for (let error of other_errors) {
          queueMicrotask(() => {
            throw error;
          });
        }
        throw throw_error;
      }
    } finally {
      event2[event_symbol] = handler_element;
      delete event2.currentTarget;
      set_active_reaction(previous_reaction);
      set_active_effect(previous_effect);
    }
  }
  const policy = (
globalThis?.window?.trustedTypes && globalThis.window.trustedTypes.createPolicy("svelte-trusted-html", {
createHTML: (html) => {
        return html;
      }
    })
  );
  function create_trusted_html(html) {
    return (
policy?.createHTML(html) ?? html
    );
  }
  function create_fragment_from_html(html) {
    var elem = create_element("template");
    elem.innerHTML = create_trusted_html(html.replaceAll("<!>", "<!---->"));
    return elem.content;
  }
  function assign_nodes(start, end) {
    var effect2 = (
active_effect
    );
    if (effect2.nodes === null) {
      effect2.nodes = { start, end, a: null, t: null };
    }
  }
function from_html(content, flags2) {
    var is_fragment = (flags2 & TEMPLATE_FRAGMENT) !== 0;
    var use_import_node = (flags2 & TEMPLATE_USE_IMPORT_NODE) !== 0;
    var node;
    var has_start = !content.startsWith("<!>");
    return () => {
      if (node === void 0) {
        node = create_fragment_from_html(has_start ? content : "<!>" + content);
        if (!is_fragment) node =

get_first_child(node);
      }
      var clone = (
use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)
      );
      if (is_fragment) {
        var start = (

get_first_child(clone)
        );
        var end = (
clone.lastChild
        );
        assign_nodes(start, end);
      } else {
        assign_nodes(clone, clone);
      }
      return clone;
    };
  }
  function text(value = "") {
    {
      var t = create_text(value + "");
      assign_nodes(t, t);
      return t;
    }
  }
  function comment() {
    var frag = document.createDocumentFragment();
    var start = document.createComment("");
    var anchor = create_text();
    frag.append(start, anchor);
    assign_nodes(start, anchor);
    return frag;
  }
  function append(anchor, dom) {
    if (anchor === null) {
      return;
    }
    anchor.before(
dom
    );
  }
  function set_text(text2, value) {
    var str = value == null ? "" : typeof value === "object" ? `${value}` : value;
    if (str !== (text2.__t ??= text2.nodeValue)) {
      text2.__t = str;
      text2.nodeValue = `${str}`;
    }
  }
  function mount(component, options) {
    return _mount(component, options);
  }
  const listeners = new Map();
  function _mount(Component, { target, anchor, props = {}, events, context, intro = true, transformError }) {
    init_operations();
    var component = void 0;
    var unmount2 = component_root(() => {
      var anchor_node = anchor ?? target.appendChild(create_text());
      boundary(
anchor_node,
        {
          pending: () => {
          }
        },
        (anchor_node2) => {
          push({});
          var ctx = (
component_context
          );
          if (context) ctx.c = context;
          if (events) {
            props.$$events = events;
          }
          component = Component(anchor_node2, props) || {};
          pop();
        },
        transformError
      );
      var registered_events = new Set();
      var event_handle = (events2) => {
        for (var i = 0; i < events2.length; i++) {
          var event_name = events2[i];
          if (registered_events.has(event_name)) continue;
          registered_events.add(event_name);
          var passive = is_passive_event(event_name);
          for (const node of [target, document]) {
            var counts = listeners.get(node);
            if (counts === void 0) {
              counts = new Map();
              listeners.set(node, counts);
            }
            var count = counts.get(event_name);
            if (count === void 0) {
              node.addEventListener(event_name, handle_event_propagation, { passive });
              counts.set(event_name, 1);
            } else {
              counts.set(event_name, count + 1);
            }
          }
        }
      };
      event_handle(array_from(all_registered_events));
      root_event_handles.add(event_handle);
      return () => {
        for (var event_name of registered_events) {
          for (const node of [target, document]) {
            var counts = (
listeners.get(node)
            );
            var count = (
counts.get(event_name)
            );
            if (--count == 0) {
              node.removeEventListener(event_name, handle_event_propagation);
              counts.delete(event_name);
              if (counts.size === 0) {
                listeners.delete(node);
              }
            } else {
              counts.set(event_name, count);
            }
          }
        }
        root_event_handles.delete(event_handle);
        if (anchor_node !== anchor) {
          anchor_node.parentNode?.removeChild(anchor_node);
        }
      };
    });
    mounted_components.set(component, unmount2);
    return component;
  }
  let mounted_components = new WeakMap();
  function unmount(component, options) {
    const fn = mounted_components.get(component);
    if (fn) {
      mounted_components.delete(component);
      return fn(options);
    }
    return Promise.resolve();
  }
  class BranchManager {
anchor;
#batches = new Map();
#onscreen = new Map();
#offscreen = new Map();
#outroing = new Set();
#transition = true;
constructor(anchor, transition = true) {
      this.anchor = anchor;
      this.#transition = transition;
    }
#commit = (batch) => {
      if (!this.#batches.has(batch)) return;
      var key = (
this.#batches.get(batch)
      );
      var onscreen = this.#onscreen.get(key);
      if (onscreen) {
        resume_effect(onscreen);
        this.#outroing.delete(key);
      } else {
        var offscreen = this.#offscreen.get(key);
        if (offscreen) {
          this.#onscreen.set(key, offscreen.effect);
          this.#offscreen.delete(key);
          offscreen.fragment.lastChild.remove();
          this.anchor.before(offscreen.fragment);
          onscreen = offscreen.effect;
        }
      }
      for (const [b, k] of this.#batches) {
        this.#batches.delete(b);
        if (b === batch) {
          break;
        }
        const offscreen2 = this.#offscreen.get(k);
        if (offscreen2) {
          destroy_effect(offscreen2.effect);
          this.#offscreen.delete(k);
        }
      }
      for (const [k, effect2] of this.#onscreen) {
        if (k === key || this.#outroing.has(k)) continue;
        const on_destroy = () => {
          const keys = Array.from(this.#batches.values());
          if (keys.includes(k)) {
            var fragment = document.createDocumentFragment();
            move_effect(effect2, fragment);
            fragment.append(create_text());
            this.#offscreen.set(k, { effect: effect2, fragment });
          } else {
            destroy_effect(effect2);
          }
          this.#outroing.delete(k);
          this.#onscreen.delete(k);
        };
        if (this.#transition || !onscreen) {
          this.#outroing.add(k);
          pause_effect(effect2, on_destroy, false);
        } else {
          on_destroy();
        }
      }
    };
#discard = (batch) => {
      this.#batches.delete(batch);
      const keys = Array.from(this.#batches.values());
      for (const [k, branch2] of this.#offscreen) {
        if (!keys.includes(k)) {
          destroy_effect(branch2.effect);
          this.#offscreen.delete(k);
        }
      }
    };
ensure(key, fn) {
      var batch = (
current_batch
      );
      if (fn && !this.#onscreen.has(key) && !this.#offscreen.has(key)) {
        {
          this.#onscreen.set(
            key,
            branch(() => fn(this.anchor))
          );
        }
      }
      this.#batches.set(batch, key);
      {
        this.#commit(batch);
      }
    }
  }
  function if_block(node, fn, elseif = false) {
    var branches = new BranchManager(node);
    var flags2 = elseif ? EFFECT_TRANSPARENT : 0;
    function update_branch(key, fn2) {
      branches.ensure(key, fn2);
    }
    block(() => {
      var has_branch = false;
      fn((fn2, key = 0) => {
        has_branch = true;
        update_branch(key, fn2);
      });
      if (!has_branch) {
        update_branch(false, null);
      }
    }, flags2);
  }
  function index(_, i) {
    return i;
  }
  function pause_effects(state2, to_destroy, controlled_anchor) {
    var transitions = [];
    var length = to_destroy.length;
    var group;
    var remaining = to_destroy.length;
    for (var i = 0; i < length; i++) {
      let effect2 = to_destroy[i];
      pause_effect(
        effect2,
        () => {
          if (group) {
            group.pending.delete(effect2);
            group.done.add(effect2);
            if (group.pending.size === 0) {
              var groups = (
state2.outrogroups
              );
              destroy_effects(array_from(group.done));
              groups.delete(group);
              if (groups.size === 0) {
                state2.outrogroups = null;
              }
            }
          } else {
            remaining -= 1;
          }
        },
        false
      );
    }
    if (remaining === 0) {
      var fast_path = transitions.length === 0 && controlled_anchor !== null;
      if (fast_path) {
        var anchor = (
controlled_anchor
        );
        var parent_node = (
anchor.parentNode
        );
        clear_text_content(parent_node);
        parent_node.append(anchor);
        state2.items.clear();
      }
      destroy_effects(to_destroy, !fast_path);
    } else {
      group = {
        pending: new Set(to_destroy),
        done: new Set()
      };
      (state2.outrogroups ??= new Set()).add(group);
    }
  }
  function destroy_effects(to_destroy, remove_dom = true) {
    for (var i = 0; i < to_destroy.length; i++) {
      destroy_effect(to_destroy[i], remove_dom);
    }
  }
  var offscreen_anchor;
  function each(node, flags2, get_collection, get_key, render_fn, fallback_fn = null) {
    var anchor = node;
    var items = new Map();
    var is_controlled = (flags2 & EACH_IS_CONTROLLED) !== 0;
    if (is_controlled) {
      var parent_node = (
node
      );
      anchor = parent_node.appendChild(create_text());
    }
    var fallback = null;
    var each_array = derived_safe_equal(() => {
      var collection = get_collection();
      return is_array(collection) ? collection : collection == null ? [] : array_from(collection);
    });
    var array;
    var first_run = true;
    function commit() {
      state2.fallback = fallback;
      reconcile(state2, array, anchor, flags2, get_key);
      if (fallback !== null) {
        if (array.length === 0) {
          if ((fallback.f & EFFECT_OFFSCREEN) === 0) {
            resume_effect(fallback);
          } else {
            fallback.f ^= EFFECT_OFFSCREEN;
            move(fallback, null, anchor);
          }
        } else {
          pause_effect(fallback, () => {
            fallback = null;
          });
        }
      }
    }
    var effect2 = block(() => {
      array =
get$1(each_array);
      var length = array.length;
      var keys = new Set();
      for (var index2 = 0; index2 < length; index2 += 1) {
        var value = array[index2];
        var key = get_key(value, index2);
        var item = first_run ? null : items.get(key);
        if (item) {
          if (item.v) internal_set(item.v, value);
          if (item.i) internal_set(item.i, index2);
        } else {
          item = create_item(
            items,
            first_run ? anchor : offscreen_anchor ??= create_text(),
            value,
            key,
            index2,
            render_fn,
            flags2,
            get_collection
          );
          if (!first_run) {
            item.e.f |= EFFECT_OFFSCREEN;
          }
          items.set(key, item);
        }
        keys.add(key);
      }
      if (length === 0 && fallback_fn && !fallback) {
        if (first_run) {
          fallback = branch(() => fallback_fn(anchor));
        } else {
          fallback = branch(() => fallback_fn(offscreen_anchor ??= create_text()));
          fallback.f |= EFFECT_OFFSCREEN;
        }
      }
      if (length > keys.size) {
        {
          each_key_duplicate();
        }
      }
      if (!first_run) {
        {
          commit();
        }
      }
      get$1(each_array);
    });
    var state2 = { effect: effect2, items, outrogroups: null, fallback };
    first_run = false;
  }
  function skip_to_branch(effect2) {
    while (effect2 !== null && (effect2.f & BRANCH_EFFECT) === 0) {
      effect2 = effect2.next;
    }
    return effect2;
  }
  function reconcile(state2, array, anchor, flags2, get_key) {
    var is_animated = (flags2 & EACH_IS_ANIMATED) !== 0;
    var length = array.length;
    var items = state2.items;
    var current = skip_to_branch(state2.effect.first);
    var seen;
    var prev = null;
    var to_animate;
    var matched = [];
    var stashed = [];
    var value;
    var key;
    var effect2;
    var i;
    if (is_animated) {
      for (i = 0; i < length; i += 1) {
        value = array[i];
        key = get_key(value, i);
        effect2 =
items.get(key).e;
        if ((effect2.f & EFFECT_OFFSCREEN) === 0) {
          effect2.nodes?.a?.measure();
          (to_animate ??= new Set()).add(effect2);
        }
      }
    }
    for (i = 0; i < length; i += 1) {
      value = array[i];
      key = get_key(value, i);
      effect2 =
items.get(key).e;
      if (state2.outrogroups !== null) {
        for (const group of state2.outrogroups) {
          group.pending.delete(effect2);
          group.done.delete(effect2);
        }
      }
      if ((effect2.f & EFFECT_OFFSCREEN) !== 0) {
        effect2.f ^= EFFECT_OFFSCREEN;
        if (effect2 === current) {
          move(effect2, null, anchor);
        } else {
          var next = prev ? prev.next : current;
          if (effect2 === state2.effect.last) {
            state2.effect.last = effect2.prev;
          }
          if (effect2.prev) effect2.prev.next = effect2.next;
          if (effect2.next) effect2.next.prev = effect2.prev;
          link(state2, prev, effect2);
          link(state2, effect2, next);
          move(effect2, next, anchor);
          prev = effect2;
          matched = [];
          stashed = [];
          current = skip_to_branch(prev.next);
          continue;
        }
      }
      if ((effect2.f & INERT) !== 0) {
        resume_effect(effect2);
        if (is_animated) {
          effect2.nodes?.a?.unfix();
          (to_animate ??= new Set()).delete(effect2);
        }
      }
      if (effect2 !== current) {
        if (seen !== void 0 && seen.has(effect2)) {
          if (matched.length < stashed.length) {
            var start = stashed[0];
            var j;
            prev = start.prev;
            var a = matched[0];
            var b = matched[matched.length - 1];
            for (j = 0; j < matched.length; j += 1) {
              move(matched[j], start, anchor);
            }
            for (j = 0; j < stashed.length; j += 1) {
              seen.delete(stashed[j]);
            }
            link(state2, a.prev, b.next);
            link(state2, prev, a);
            link(state2, b, start);
            current = start;
            prev = b;
            i -= 1;
            matched = [];
            stashed = [];
          } else {
            seen.delete(effect2);
            move(effect2, current, anchor);
            link(state2, effect2.prev, effect2.next);
            link(state2, effect2, prev === null ? state2.effect.first : prev.next);
            link(state2, prev, effect2);
            prev = effect2;
          }
          continue;
        }
        matched = [];
        stashed = [];
        while (current !== null && current !== effect2) {
          (seen ??= new Set()).add(current);
          stashed.push(current);
          current = skip_to_branch(current.next);
        }
        if (current === null) {
          continue;
        }
      }
      if ((effect2.f & EFFECT_OFFSCREEN) === 0) {
        matched.push(effect2);
      }
      prev = effect2;
      current = skip_to_branch(effect2.next);
    }
    if (state2.outrogroups !== null) {
      for (const group of state2.outrogroups) {
        if (group.pending.size === 0) {
          destroy_effects(array_from(group.done));
          state2.outrogroups?.delete(group);
        }
      }
      if (state2.outrogroups.size === 0) {
        state2.outrogroups = null;
      }
    }
    if (current !== null || seen !== void 0) {
      var to_destroy = [];
      if (seen !== void 0) {
        for (effect2 of seen) {
          if ((effect2.f & INERT) === 0) {
            to_destroy.push(effect2);
          }
        }
      }
      while (current !== null) {
        if ((current.f & INERT) === 0 && current !== state2.fallback) {
          to_destroy.push(current);
        }
        current = skip_to_branch(current.next);
      }
      var destroy_length = to_destroy.length;
      if (destroy_length > 0) {
        var controlled_anchor = (flags2 & EACH_IS_CONTROLLED) !== 0 && length === 0 ? anchor : null;
        if (is_animated) {
          for (i = 0; i < destroy_length; i += 1) {
            to_destroy[i].nodes?.a?.measure();
          }
          for (i = 0; i < destroy_length; i += 1) {
            to_destroy[i].nodes?.a?.fix();
          }
        }
        pause_effects(state2, to_destroy, controlled_anchor);
      }
    }
    if (is_animated) {
      queue_micro_task(() => {
        if (to_animate === void 0) return;
        for (effect2 of to_animate) {
          effect2.nodes?.a?.apply();
        }
      });
    }
  }
  function create_item(items, anchor, value, key, index2, render_fn, flags2, get_collection) {
    var v = (flags2 & EACH_ITEM_REACTIVE) !== 0 ? (flags2 & EACH_ITEM_IMMUTABLE) === 0 ? mutable_source(value, false, false) : source(value) : null;
    var i = (flags2 & EACH_INDEX_REACTIVE) !== 0 ? source(index2) : null;
    return {
      v,
      i,
      e: branch(() => {
        render_fn(anchor, v ?? value, i ?? index2, get_collection);
        return () => {
          items.delete(key);
        };
      })
    };
  }
  function move(effect2, next, anchor) {
    if (!effect2.nodes) return;
    var node = effect2.nodes.start;
    var end = effect2.nodes.end;
    var dest = next && (next.f & EFFECT_OFFSCREEN) === 0 ? (
next.nodes.start
    ) : anchor;
    while (node !== null) {
      var next_node = (

get_next_sibling(node)
      );
      dest.before(node);
      if (node === end) {
        return;
      }
      node = next_node;
    }
  }
  function link(state2, prev, next) {
    if (prev === null) {
      state2.effect.first = next;
    } else {
      prev.next = next;
    }
    if (next === null) {
      state2.effect.last = prev;
    } else {
      next.prev = prev;
    }
  }
  function action(dom, action2, get_value) {
    effect(() => {
      var payload = untrack(() => action2(dom, get_value?.()) || {});
      if (get_value && payload?.update) {
        var inited = false;
        var prev = (
{}
        );
        render_effect(() => {
          var value = get_value();
          deep_read_state(value);
          if (inited && safe_not_equal(prev, value)) {
            prev = value;
            payload.update(value);
          }
        });
        inited = true;
      }
      if (payload?.destroy) {
        return () => (
payload.destroy()
        );
      }
    });
  }
  const whitespace = [..." 	\n\r\f \v\uFEFF"];
  function to_class(value, hash, directives) {
    var classname = value == null ? "" : "" + value;
    if (hash) {
      classname = classname ? classname + " " + hash : hash;
    }
    if (directives) {
      for (var key of Object.keys(directives)) {
        if (directives[key]) {
          classname = classname ? classname + " " + key : key;
        } else if (classname.length) {
          var len = key.length;
          var a = 0;
          while ((a = classname.indexOf(key, a)) >= 0) {
            var b = a + len;
            if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) {
              classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
            } else {
              a = b;
            }
          }
        }
      }
    }
    return classname === "" ? null : classname;
  }
  function to_style(value, styles) {
    return value == null ? null : String(value);
  }
  function set_class(dom, is_html, value, hash, prev_classes, next_classes) {
    var prev = dom.__className;
    if (prev !== value || prev === void 0) {
      var next_class_name = to_class(value, hash, next_classes);
      {
        if (next_class_name == null) {
          dom.removeAttribute("class");
        } else {
          dom.className = next_class_name;
        }
      }
      dom.__className = value;
    } else if (next_classes && prev_classes !== next_classes) {
      for (var key in next_classes) {
        var is_present = !!next_classes[key];
        if (prev_classes == null || is_present !== !!prev_classes[key]) {
          dom.classList.toggle(key, is_present);
        }
      }
    }
    return next_classes;
  }
  function set_style(dom, value, prev_styles, next_styles) {
    var prev = dom.__style;
    if (prev !== value) {
      var next_style_attr = to_style(value);
      {
        if (next_style_attr == null) {
          dom.removeAttribute("style");
        } else {
          dom.style.cssText = next_style_attr;
        }
      }
      dom.__style = value;
    }
    return next_styles;
  }
  function select_option(select, value, mounting = false) {
    if (select.multiple) {
      if (value == void 0) {
        return;
      }
      if (!is_array(value)) {
        return select_multiple_invalid_value();
      }
      for (var option of select.options) {
        option.selected = value.includes(get_option_value(option));
      }
      return;
    }
    for (option of select.options) {
      var option_value = get_option_value(option);
      if (is(option_value, value)) {
        option.selected = true;
        return;
      }
    }
    if (!mounting || value !== void 0) {
      select.selectedIndex = -1;
    }
  }
  function init_select(select) {
    var observer = new MutationObserver(() => {
      select_option(select, select.__value);
    });
    observer.observe(select, {
childList: true,
      subtree: true,



attributes: true,
      attributeFilter: ["value"]
    });
    teardown(() => {
      observer.disconnect();
    });
  }
  function get_option_value(option) {
    if ("__value" in option) {
      return option.__value;
    } else {
      return option.value;
    }
  }
  const IS_CUSTOM_ELEMENT = Symbol("is custom element");
  const IS_HTML = Symbol("is html");
  const PROGRESS_TAG = IS_XHTML ? "progress" : "PROGRESS";
  function set_value(element, value) {
    var attributes = get_attributes(element);
    if (attributes.value === (attributes.value =
value ?? void 0) ||

element.value === value && (value !== 0 || element.nodeName !== PROGRESS_TAG)) {
      return;
    }
    element.value = value ?? "";
  }
  function set_checked(element, checked) {
    var attributes = get_attributes(element);
    if (attributes.checked === (attributes.checked =
checked ?? void 0)) {
      return;
    }
    element.checked = checked;
  }
  function set_attribute(element, attribute, value, skip_warning) {
    var attributes = get_attributes(element);
    if (attributes[attribute] === (attributes[attribute] = value)) return;
    if (attribute === "loading") {
      element[LOADING_ATTR_SYMBOL] = value;
    }
    if (value == null) {
      element.removeAttribute(attribute);
    } else if (typeof value !== "string" && get_setters(element).includes(attribute)) {
      element[attribute] = value;
    } else {
      element.setAttribute(attribute, value);
    }
  }
  function get_attributes(element) {
    return (

element.__attributes ??= {
        [IS_CUSTOM_ELEMENT]: element.nodeName.includes("-"),
        [IS_HTML]: element.namespaceURI === NAMESPACE_HTML
      }
    );
  }
  var setters_cache = new Map();
  function get_setters(element) {
    var cache_key = element.getAttribute("is") || element.nodeName;
    var setters = setters_cache.get(cache_key);
    if (setters) return setters;
    setters_cache.set(cache_key, setters = []);
    var descriptors;
    var proto = element;
    var element_proto = Element.prototype;
    while (element_proto !== proto) {
      descriptors = get_descriptors(proto);
      for (var key in descriptors) {
        if (descriptors[key].set) {
          setters.push(key);
        }
      }
      proto = get_prototype_of(proto);
    }
    return setters;
  }
  function bind_value(input, get2, set2 = get2) {
    var batches2 = new WeakSet();
    listen_to_event_and_reset_event(input, "input", async (is_reset) => {
      var value = is_reset ? input.defaultValue : input.value;
      value = is_numberlike_input(input) ? to_number(value) : value;
      set2(value);
      if (current_batch !== null) {
        batches2.add(current_batch);
      }
      await tick();
      if (value !== (value = get2())) {
        var start = input.selectionStart;
        var end = input.selectionEnd;
        var length = input.value.length;
        input.value = value ?? "";
        if (end !== null) {
          var new_length = input.value.length;
          if (start === end && end === length && new_length > length) {
            input.selectionStart = new_length;
            input.selectionEnd = new_length;
          } else {
            input.selectionStart = start;
            input.selectionEnd = Math.min(end, new_length);
          }
        }
      }
    });
    if (



untrack(get2) == null && input.value
    ) {
      set2(is_numberlike_input(input) ? to_number(input.value) : input.value);
      if (current_batch !== null) {
        batches2.add(current_batch);
      }
    }
    render_effect(() => {
      var value = get2();
      if (input === document.activeElement) {
        var batch = (
previous_batch ?? current_batch
        );
        if (batches2.has(batch)) {
          return;
        }
      }
      if (is_numberlike_input(input) && value === to_number(input.value)) {
        return;
      }
      if (input.type === "date" && !value && !input.value) {
        return;
      }
      if (value !== input.value) {
        input.value = value ?? "";
      }
    });
  }
  function is_numberlike_input(input) {
    var type = input.type;
    return type === "number" || type === "range";
  }
  function to_number(value) {
    return value === "" ? null : +value;
  }
  function is_bound_this(bound_value, element_or_component) {
    return bound_value === element_or_component || bound_value?.[STATE_SYMBOL] === element_or_component;
  }
  function bind_this(element_or_component = {}, update, get_value, get_parts) {
    effect(() => {
      var old_parts;
      var parts;
      render_effect(() => {
        old_parts = parts;
        parts = [];
        untrack(() => {
          if (element_or_component !== get_value(...parts)) {
            update(element_or_component, ...parts);
            if (old_parts && is_bound_this(get_value(...old_parts), element_or_component)) {
              update(null, ...old_parts);
            }
          }
        });
      });
      return () => {
        queue_micro_task(() => {
          if (parts && is_bound_this(get_value(...parts), element_or_component)) {
            update(null, ...parts);
          }
        });
      };
    });
    return element_or_component;
  }
  function subscribe_to_store(store, run, invalidate) {
    if (store == null) {
      run(void 0);
      if (invalidate) invalidate(void 0);
      return noop;
    }
    const unsub = untrack(
      () => store.subscribe(
        run,
invalidate
      )
    );
    return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
  }
  const subscriber_queue = [];
  function readable(value, start) {
    return {
      subscribe: writable(value, start).subscribe
    };
  }
  function writable(value, start = noop) {
    let stop = null;
    const subscribers = new Set();
    function set2(new_value) {
      if (safe_not_equal(value, new_value)) {
        value = new_value;
        if (stop) {
          const run_queue = !subscriber_queue.length;
          for (const subscriber of subscribers) {
            subscriber[1]();
            subscriber_queue.push(subscriber, value);
          }
          if (run_queue) {
            for (let i = 0; i < subscriber_queue.length; i += 2) {
              subscriber_queue[i][0](subscriber_queue[i + 1]);
            }
            subscriber_queue.length = 0;
          }
        }
      }
    }
    function update(fn) {
      set2(fn(
value
      ));
    }
    function subscribe(run, invalidate = noop) {
      const subscriber = [run, invalidate];
      subscribers.add(subscriber);
      if (subscribers.size === 1) {
        stop = start(set2, update) || noop;
      }
      run(
value
      );
      return () => {
        subscribers.delete(subscriber);
        if (subscribers.size === 0 && stop) {
          stop();
          stop = null;
        }
      };
    }
    return { set: set2, update, subscribe };
  }
  function derived(stores, fn, initial_value) {
    const single = !Array.isArray(stores);
    const stores_array = single ? [stores] : stores;
    if (!stores_array.every(Boolean)) {
      throw new Error("derived() expects stores as input, got a falsy value");
    }
    const auto = fn.length < 2;
    return readable(initial_value, (set2, update) => {
      let started = false;
      const values = [];
      let pending = 0;
      let cleanup = noop;
      const sync = () => {
        if (pending) {
          return;
        }
        cleanup();
        const result = fn(single ? values[0] : values, set2, update);
        if (auto) {
          set2(result);
        } else {
          cleanup = typeof result === "function" ? result : noop;
        }
      };
      const unsubscribers = stores_array.map(
        (store, i) => subscribe_to_store(
          store,
          (value) => {
            values[i] = value;
            pending &= ~(1 << i);
            if (started) {
              sync();
            }
          },
          () => {
            pending |= 1 << i;
          }
        )
      );
      started = true;
      sync();
      return function stop() {
        run_all(unsubscribers);
        cleanup();
        started = false;
      };
    });
  }
  function get(store) {
    let value;
    subscribe_to_store(store, (_) => value = _)();
    return value;
  }
  let is_store_binding = false;
  let IS_UNMOUNTED = Symbol();
  function store_get(store, store_name, stores) {
    const entry = stores[store_name] ??= {
      store: null,
      source: mutable_source(void 0),
      unsubscribe: noop
    };
    if (entry.store !== store && !(IS_UNMOUNTED in stores)) {
      entry.unsubscribe();
      entry.store = store ?? null;
      if (store == null) {
        entry.source.v = void 0;
        entry.unsubscribe = noop;
      } else {
        var is_synchronous_callback = true;
        entry.unsubscribe = subscribe_to_store(store, (v) => {
          if (is_synchronous_callback) {
            entry.source.v = v;
          } else {
            set(entry.source, v);
          }
        });
        is_synchronous_callback = false;
      }
    }
    if (store && IS_UNMOUNTED in stores) {
      return get(store);
    }
    return get$1(entry.source);
  }
  function setup_stores() {
    const stores = {};
    function cleanup() {
      teardown(() => {
        for (var store_name in stores) {
          const ref = stores[store_name];
          ref.unsubscribe();
        }
        define_property(stores, IS_UNMOUNTED, {
          enumerable: false,
          value: true
        });
      });
    }
    return [stores, cleanup];
  }
  function capture_store_binding(fn) {
    var previous_is_store_binding = is_store_binding;
    try {
      is_store_binding = false;
      return [fn(), is_store_binding];
    } finally {
      is_store_binding = previous_is_store_binding;
    }
  }
  function prop(props, key, flags2, fallback) {
    var bindable = (flags2 & PROPS_IS_BINDABLE) !== 0;
    var lazy = (flags2 & PROPS_IS_LAZY_INITIAL) !== 0;
    var fallback_value = (
fallback
    );
    var fallback_dirty = true;
    var get_fallback = () => {
      if (fallback_dirty) {
        fallback_dirty = false;
        fallback_value = lazy ? untrack(
fallback
        ) : (
fallback
        );
      }
      return fallback_value;
    };
    var setter;
    if (bindable) {
      var is_entry_props = STATE_SYMBOL in props || LEGACY_PROPS in props;
      setter = get_descriptor(props, key)?.set ?? (is_entry_props && key in props ? (v) => props[key] = v : void 0);
    }
    var initial_value;
    var is_store_sub = false;
    if (bindable) {
      [initial_value, is_store_sub] = capture_store_binding(() => (
props[key]
      ));
    } else {
      initial_value =
props[key];
    }
    if (initial_value === void 0 && fallback !== void 0) {
      initial_value = get_fallback();
      if (setter) {
        props_invalid_value();
        setter(initial_value);
      }
    }
    var getter;
    {
      getter = () => {
        var value = (
props[key]
        );
        if (value === void 0) return get_fallback();
        fallback_dirty = true;
        return value;
      };
    }
    if ((flags2 & PROPS_IS_UPDATED) === 0) {
      return getter;
    }
    if (setter) {
      var legacy_parent = props.$$legacy;
      return (
(function(value, mutation) {
          if (arguments.length > 0) {
            if (!mutation || legacy_parent || is_store_sub) {
              setter(mutation ? getter() : value);
            }
            return value;
          }
          return getter();
        })
      );
    }
    var overridden = false;
    var d = ((flags2 & PROPS_IS_IMMUTABLE) !== 0 ? derived$1 : derived_safe_equal)(() => {
      overridden = false;
      return getter();
    });
    if (bindable) get$1(d);
    var parent_effect = (
active_effect
    );
    return (
(function(value, mutation) {
        if (arguments.length > 0) {
          const new_value = mutation ? get$1(d) : bindable ? proxy(value) : value;
          set(d, new_value);
          overridden = true;
          if (fallback_value !== void 0) {
            fallback_value = new_value;
          }
          return value;
        }
        if (is_destroying_effect && overridden || (parent_effect.f & DESTROYED) !== 0) {
          return d.v;
        }
        return get$1(d);
      })
    );
  }
  function onMount(fn) {
    if (component_context === null) {
      lifecycle_outside_component();
    }
    {
      user_effect(() => {
        const cleanup = untrack(fn);
        if (typeof cleanup === "function") return (
cleanup
        );
      });
    }
  }
  function onDestroy(fn) {
    if (component_context === null) {
      lifecycle_outside_component();
    }
    onMount(() => () => untrack(fn));
  }
  const appCss = ":root{--outline-bg: #ffffff;--outline-text: #333333;--outline-border: #dddddd;--outline-shadow: rgba(0, 0, 0, .15);--outline-header-bg: #ffffff;--outline-user-bg: #f0f8ff;--outline-user-hover-bg: #e6f3ff;--outline-user-border: #007acc;--outline-ai-bg: #f8f8f8;--outline-ai-hover-bg: #f0f0f0;--outline-ai-border: #28a745;--outline-node-hover-bg: #e9ecef;--header-h1: #dc3545;--header-h2: #fd7e14;--header-h3: #ffc107;--header-h4: #28a745;--header-h5: #17a2b8;--header-h6: #6f42c1;--outline-width: 300px;--outline-radius: 8px;--outline-padding: 15px;--outline-font-size: 14px;--outline-highlight-color: rgba(131, 218, 255, .16);--outline-active-bg: rgba(0, 122, 204, .15);--outline-active-border: #007acc;--outline-primary: #007acc;--outline-bookmark-border: #ffc107;--outline-bookmark-bg: rgba(255, 193, 7, .1)}[cbe-data-theme=dark]{--outline-bg: #2d2d2d;--outline-text: #e0e0e0;--outline-border: #555555;--outline-shadow: rgba(0, 0, 0, .3);--outline-header-bg: #2d2d2d;--outline-user-bg: #3a3a3a;--outline-user-hover-bg: #4a4a4a;--outline-user-border: #64b5f6;--outline-ai-bg: #3a3a3a;--outline-ai-hover-bg: #4a4a4a;--outline-ai-border: #4caf50;--outline-node-hover-bg: #4a4a4a;--header-h1: #f48fb1;--header-h2: #ffab91;--header-h3: #fff176;--header-h4: #81c784;--header-h5: #4dd0e1;--header-h6: #b39ddb;--outline-active-bg: rgba(100, 181, 246, .2);--outline-active-border: #64b5f6;--outline-primary: #64b5f6;--outline-bookmark-border: #ffc107;--outline-bookmark-bg: rgba(255, 193, 7, .15)}.highlight-animation{animation:highlight 1s ease-in-out}@keyframes highlight{0%{background-color:transparent}50%{background-color:var(--outline-highlight-color)}to{background-color:transparent}}.tree-node,.outline-user-item,.outline-ai-item,.outline-ai-header{will-change:transform;backface-visibility:hidden}";
  importCSS(appCss);
  const PUBLIC_VERSION = "5";
  if (typeof window !== "undefined") {
    ((window.__svelte ??= {}).v ??= new Set()).add(PUBLIC_VERSION);
  }
  const defaultThemeConfig = {
    highlightColor: "#83daff2a",
    highlightTime: 2e3,
    currentTheme: "light",
    colors: {
      light: {
        primary: "#28a745",
        user: "#007acc",
        background: "#ffffff",
        border: "#ddd",
        shadow: "rgba(0,0,0,0.15)",
        text: "#333",
        headerBg: "#ffffff",
        headers: {
          h1: "#dc3545",
          h2: "#fd7e14",
          h3: "#ffc107",
          h4: "#28a745",
          h5: "#17a2b8",
          h6: "#6f42c1"
        }
      },
      dark: {
        primary: "#4caf50",
        user: "#64b5f6",
        background: "#2d2d2d",
        border: "#555",
        shadow: "rgba(0,0,0,0.3)",
        text: "#e0e0e0",
        headerBg: "#2d2d2d",
        headers: {
          h1: "#f48fb1",
          h2: "#ffab91",
          h3: "#fff176",
          h4: "#81c784",
          h5: "#4dd0e1",
          h6: "#b39ddb"
        }
      }
    },
    sizes: {
      outlineWidth: "300px",
      borderRadius: "8px",
      padding: "15px",
      fontSize: "14px",
      indentSize: 15
    }
  };
  function loadThemeFromStorage() {
    const saved = localStorage.getItem("chat-outline-theme");
    if (saved === "light" || saved === "dark") {
      return saved;
    }
    return "light";
  }
  const themeStore = writable({
    ...defaultThemeConfig,
    currentTheme: loadThemeFromStorage()
  });
  derived(themeStore, ($theme) => {
    return $theme.colors[$theme.currentTheme];
  });
  function toggleTheme() {
    themeStore.update((theme) => {
      const newTheme = theme.currentTheme === "light" ? "dark" : "light";
      localStorage.setItem("chat-outline-theme", newTheme);
      return { ...theme, currentTheme: newTheme };
    });
  }
  function getCurrentColors() {
    const theme = get(themeStore);
    return theme.colors[theme.currentTheme];
  }
  const LOG_LEVELS = {
    debug: 0,
    info: 1,
    warn: 2,
    error: 3
  };
  let currentLevel = "info";
  function setLogLevel(level) {
    currentLevel = level;
  }
  function shouldLog(level) {
    return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
  }
  function formatTaggedArgs(tag, args) {
    return [`[${tag}]`, ...args];
  }
  const logger$1 = {
    debug: (...args) => {
      if (shouldLog("debug")) console.log("[DEBUG]", ...args);
    },
    info: (...args) => {
      if (shouldLog("info")) console.log("[INFO]", ...args);
    },
    warn: (...args) => {
      if (shouldLog("warn")) console.warn("[WARN]", ...args);
    },
    error: (...args) => {
      if (shouldLog("error")) console.error("[ERROR]", ...args);
    }
  };
  function createTaggedLogger(tag) {
    return {
      debug: (...args) => {
        logger$1.debug(...formatTaggedArgs(tag, args));
      },
      info: (...args) => {
        logger$1.info(...formatTaggedArgs(tag, args));
      },
      warn: (...args) => {
        logger$1.warn(...formatTaggedArgs(tag, args));
      },
      error: (...args) => {
        logger$1.error(...formatTaggedArgs(tag, args));
      }
    };
  }
  const defaultFeatures = {
    autoExpand: true,
    showUserMessages: true,
    showAIMessages: true,
    isVisible: true,
    textLength: 50,
    debouncedInterval: 500,
    syncScroll: true,
    logLevel: "info",
    bookmarkGetTextLength: 20
  };
  const STORAGE_KEY$1 = "chat-outline-features";
  const gmLogger$1 = createTaggedLogger("GM");
  function loadFeaturesFromLocalStorage() {
    try {
      const saved = window.localStorage.getItem(STORAGE_KEY$1);
      gmLogger$1.debug("loadFeaturesFromLocalStorage result", {
        hasSavedFeatures: Boolean(saved),
        storageKey: STORAGE_KEY$1
      });
      if (!saved) {
        return defaultFeatures;
      }
      return { ...defaultFeatures, ...JSON.parse(saved) };
    } catch (error) {
      gmLogger$1.warn("Failed to load features from localStorage, fallback to default", error);
      return defaultFeatures;
    }
  }
  function saveFeaturesToLocalStorage(features) {
    try {
      window.localStorage.setItem(STORAGE_KEY$1, JSON.stringify(features));
      gmLogger$1.debug("Features persisted to localStorage", {
        storageKey: STORAGE_KEY$1,
        logLevel: features.logLevel,
        syncScroll: features.syncScroll
      });
    } catch (error) {
      gmLogger$1.warn("Failed to persist features to localStorage", error);
    }
  }
  function getSafeGMGetValue() {
    if (typeof GM !== "undefined" && typeof GM.getValue === "function") {
      gmLogger$1.debug("GM.getValue is available");
      return GM.getValue.bind(GM);
    }
    gmLogger$1.warn("GM.getValue is unavailable, fallback to default features", {
      href: window.location.href,
      readyState: document.readyState,
      topWindow: window.top === window
    });
    return null;
  }
  function getSafeGMSetValue() {
    if (typeof GM !== "undefined" && typeof GM.setValue === "function") {
      gmLogger$1.debug("GM.setValue is available");
      return GM.setValue.bind(GM);
    }
    gmLogger$1.warn("GM.setValue is unavailable, skip persisting features", {
      href: window.location.href,
      readyState: document.readyState,
      topWindow: window.top === window
    });
    return null;
  }
  function loadFeaturesFromStorage() {
    const safeGetValue = getSafeGMGetValue();
    if (!safeGetValue) {
      gmLogger$1.debug("Fallback to localStorage for loading features");
      return loadFeaturesFromLocalStorage();
    }
    try {
      const saved = safeGetValue(STORAGE_KEY$1, null);
      gmLogger$1.debug("loadFeaturesFromStorage result", {
        hasSavedFeatures: Boolean(saved),
        storageKey: STORAGE_KEY$1
      });
      if (!saved) {
        return defaultFeatures;
      }
      return { ...defaultFeatures, ...saved };
    } catch (error) {
      gmLogger$1.warn("Failed to load features from GM storage, fallback to default", error);
      gmLogger$1.debug("Fallback to localStorage after GM storage read failure");
      return loadFeaturesFromLocalStorage();
    }
  }
  function saveFeaturesToStorage(features) {
    const safeSetValue = getSafeGMSetValue();
    if (!safeSetValue) {
      gmLogger$1.debug("Fallback to localStorage for persisting features");
      saveFeaturesToLocalStorage(features);
      return;
    }
    try {
      safeSetValue(STORAGE_KEY$1, features);
      gmLogger$1.debug("Features persisted to GM storage", {
        storageKey: STORAGE_KEY$1,
        logLevel: features.logLevel,
        syncScroll: features.syncScroll
      });
    } catch (error) {
      gmLogger$1.warn("Failed to persist features to GM storage", error);
      gmLogger$1.debug("Fallback to localStorage after GM storage write failure");
      saveFeaturesToLocalStorage(features);
    }
  }
  const featuresStore = writable(loadFeaturesFromStorage());
  featuresStore.subscribe((features) => {
    saveFeaturesToStorage(features);
    setLogLevel(features.logLevel);
  });
  function toggleVisibility() {
    featuresStore.update((features) => ({
      ...features,
      isVisible: !features.isVisible
    }));
  }
  const allExpandedStore = writable(true);
  function toggleAllExpanded() {
    allExpandedStore.update((expanded) => !expanded);
  }
  const outlineStore = writable([]);
  var MessageOwner = ((MessageOwner2) => {
    MessageOwner2["User"] = "user";
    MessageOwner2["Assistant"] = "assistant";
    MessageOwner2["Other"] = "other";
    return MessageOwner2;
  })(MessageOwner || {});
  const deepseekConfig = {
selectChatArea: function() {
      const ele = document.querySelectorAll(".ds-scroll-area")[2];
      if (ele.tagName == "TEXTAREA") {
        return ele.parentElement?.parentElement?.parentElement?.parentElement;
      } else {
        return ele;
      }
    },
getMessageList: function(root2) {
      const items = root2.querySelectorAll(".ds-virtual-list-visible-items")[0];
      if (items === void 0) {
        return [];
      }
      return items.children;
    },
determineMessageOwner: function(messageEle) {
      if (messageEle.style[0]) {
        return MessageOwner.Assistant;
      }
      return MessageOwner.User;
    },
getOutlineContainer: function() {
      let b1 = document.querySelectorAll(".ds-scroll-area")[0]?.parentElement?.parentElement?.parentElement;
      return b1 || null;
    },
    getScrollContainer: function(chatArea) {
      return chatArea.querySelector(".ds-virtual-list");
    },

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 4 && parts[0] === "a" && parts[1] === "chat" && parts[2] === "s") {
        return parts[3];
      }
      return null;
    },
    getConversationName: function() {
      const ele = document.querySelectorAll(".ds-scroll-area")[2];
      return ele.children[0].textContent;
    },
    buildConversationUrl: function(conversationId) {
      return `/a/chat/s/${conversationId}`;
    }
  };
  const doubaoConfig = {
selectChatArea: function() {
      return document.querySelector('[data-testid="scroll_view"]')?.parentElement?.parentElement;
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelector) {
        return null;
      }
      const children = root2.querySelectorAll(".container-PvPoAn");
      if (!children) {
        return null;
      }
      return children;
    },
determineMessageOwner: function(messageEle) {
      if (messageEle.querySelector('[data-testid*="send_message"]') || messageEle.querySelector('[data-testid="send_message"]')) {
        return MessageOwner.User;
      }
      if (messageEle.querySelector('[data-testid*="receive_message"]') || messageEle.querySelector('[data-testid="receive_message"]')) {
        return MessageOwner.Assistant;
      }
      return MessageOwner.Other;
    },
getOutlineContainer: function() {
      return document.querySelector("main") || null;
    },
    getScrollContainer(chatArea) {
      return chatArea.querySelector('[class^="scrollable"]');
    },

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "chat") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      const titleElement = document.querySelector("main")?.firstElementChild?.firstElementChild?.children[1]?.firstChild?.firstChild?.firstChild;
      return titleElement?.textContent?.trim() || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/chat/${conversationId}`;
    }
  };
  const chatgptConfig = {
selectChatArea: function() {
      return document.querySelector("#main") || document.querySelector("main");
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      const messages = root2.querySelectorAll("[data-message-author-role]");
      if (messages) {
        return messages;
      }
      const articles = root2.querySelectorAll("article");
      if (articles && articles.length > 0) {
        return articles;
      }
      return null;
    },
determineMessageOwner: function(messageEle) {
      const authorRole = messageEle.getAttribute("data-message-author-role");
      if (authorRole === "user") {
        return MessageOwner.User;
      }
      if (authorRole === "assistant") {
        return MessageOwner.Assistant;
      }
      if (messageEle.querySelector('[data-message-author-role="user"]')) {
        return MessageOwner.User;
      }
      if (messageEle.querySelector('[data-message-author-role="assistant"]')) {
        return MessageOwner.Assistant;
      }
      return MessageOwner.Other;
    },
getOutlineContainer: function() {
      const mainContainer = document.querySelector("#main")?.parentElement?.parentElement?.parentElement;
      return mainContainer || null;
    },
    getScrollContainer(chatArea) {
      return document.querySelector("[data-scroll-root]");
    },
    timeout: 5e3,

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "c") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      const titleElement = document.querySelector("#history a[data-active]");
      return titleElement?.textContent?.trim() || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/c/${conversationId}`;
    }
  };
  const grokConfig = {
selectChatArea: function() {
      return document.querySelector("#last-reply-container")?.parentElement;
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      let messages = root2.querySelectorAll(":scope > .relative");
      return Array.from(messages).concat(Array.from(root2.querySelectorAll(":scope > #last-reply-container > div > .relative")));
    },
determineMessageOwner: function(messageEle) {
      const l = messageEle.children[2].firstChild.children.length;
      if (l < 5) {
        return MessageOwner.User;
      }
      return MessageOwner.Assistant;
    },
getOutlineContainer: function() {
      const chatContainer = document.querySelector("main");
      return chatContainer?.parentElement ?? null;
    },
    getScrollContainer(chatArea) {
      return chatArea.querySelector(".scrollbar-gutter-stable");
    },

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "c") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      let title = document.title.trim();
      title = title.substring(0, title.length - 7);
      return title || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/c/${conversationId}`;
    }
  };
  const tongyiConfig = {
selectChatArea: function() {
      return document.querySelector('[class^="scrollOutWrapper"]');
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      let messages = root2.querySelectorAll('div[class^="content-"]');
      return messages;
    },
determineMessageOwner: function(messageEle) {
      let className = messageEle.parentElement.parentElement.className;
      if (className.includes("questionItem")) {
        return MessageOwner.User;
      }
      className = messageEle.parentElement.parentElement.parentElement.className;
      if (className.includes("answerItem")) {
        return MessageOwner.Assistant;
      }
      return MessageOwner.Other;
    },
getOutlineContainer: function() {
      const tongyiContainer = document.querySelector("[class^=mainContent]").parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement;
      return tongyiContainer;
    },
    getScrollContainer: function(chatArea) {
      return chatArea.parentElement;
    },

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "chat") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      const titleElement = document.querySelector(".mobile\\:pr-3 > div.hover\\:\\!bg-tag > .space-x-1");
      return titleElement?.textContent?.trim() || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/chat/${conversationId}`;
    }
  };
  const qwenConfig = {
selectChatArea: function() {
      return document.querySelector("#chat-message-container");
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      let messages = root2.querySelectorAll(".response-message-content, .chat-user-message");
      return messages;
    },
determineMessageOwner: function(messageEle) {
      if (messageEle.className.includes("chat-user-message")) {
        return MessageOwner.User;
      }
      return MessageOwner.Assistant;
    },
getOutlineContainer: function() {
      const mainContainer = document.querySelector(".desktop-layout");
      mainContainer.style.backgroundColor = getCurrentColors().background;
      return mainContainer;
    },
    getScrollContainer(chatArea) {
      return chatArea.parentElement;
    },

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "c") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      const titleElement = document.querySelector(".folder-content .chat-item-drag-active");
      return titleElement?.textContent?.trim() || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/c/${conversationId}`;
    }
  };
  const kimiConfig = {
selectChatArea: function() {
      return document.querySelector(".layout-content-main");
    },
getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      let messages = root2.querySelectorAll(".chat-content-item");
      return messages;
    },
determineMessageOwner: function(messageEle) {
      if (messageEle.className.includes("chat-content-item-user")) {
        return MessageOwner.User;
      } else if (messageEle.className.includes("chat-content-item-assistant")) {
        return MessageOwner.Assistant;
      }
      return MessageOwner.Other;
    },
getOutlineContainer: function() {
      const mainContainer = document.querySelector(".main");
      return mainContainer;
    },
    getScrollContainer(chatArea) {
      return chatArea.querySelector(".chat-detail-main");
    },
    timeout: 5e3,

getConversationId: function() {
      const pathname = window.location.pathname;
      const parts = pathname.split("/").filter(Boolean);
      if (parts.length >= 2 && parts[0] === "chat") {
        return parts[1];
      }
      return null;
    },
    getConversationName: function() {
      const titleElement = document.querySelector(".chat-header-content");
      return titleElement?.textContent?.trim() || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/chat/${conversationId}`;
    }
  };
  const yuanbaoConfig = {
    selectChatArea: function() {
      return document.querySelector(".agent-chat__list__content");
    },
    getMessageList: function(root2) {
      if (!root2 || !root2.querySelectorAll) {
        return null;
      }
      return root2.querySelectorAll(".agent-chat__bubble__content");
    },
    determineMessageOwner: function(messageEle) {
      const className = messageEle.firstElementChild?.className;
      if (typeof className !== "string") {
        return MessageOwner.Other;
      }
      if (className.includes("-ai_")) {
        return MessageOwner.Assistant;
      } else {
        return MessageOwner.User;
      }
    },
    getOutlineContainer: function() {
      return document.querySelector(".agent-dialogue");
    },
    getScrollContainer: function(chatArea) {
      return chatArea.parentElement;
    },
    getConversationId: function() {
      const parts = window.location.pathname.split("/").filter(Boolean);
      if (parts.length >= 3 && parts[0] === "chat") {
        return `${parts[1]}/${parts[2]}`;
      }
      return null;
    },
    getConversationName: function() {
      const title = document.title.trim();
      return title || null;
    },
    buildConversationUrl: function(conversationId) {
      return `/chat/${conversationId}`;
    }
  };
  const platformStore = writable("unknown");
  const parserConfigStore = writable(null);
  function judgePlatform() {
    const hostname = window.location.hostname;
    if (hostname.includes("deepseek.com")) return "deepseek";
    if (hostname.includes("doubao.com")) return "doubao";
    if (hostname.includes("chatgpt.com")) return "chatgpt";
    if (hostname.includes("grok.com")) return "grok";
    if (hostname.includes("qianwen.com")) return "tongyi";
    if (hostname.includes("qwen.ai")) return "qwen";
    if (hostname.includes("kimi.com")) return "kimi";
    if (hostname.includes("yuanbao.tencent.com")) return "yuanbao";
    return "unknown";
  }
  function setPlatform(platform) {
    platformStore.set(platform);
    const config = getParserConfigForPlatform(platform);
    parserConfigStore.set(config);
  }
  function getParserConfigForPlatform(platform) {
    switch (platform) {
      case "deepseek":
        return deepseekConfig;
      case "doubao":
        return doubaoConfig;
      case "chatgpt":
        return chatgptConfig;
      case "grok":
        return grokConfig;
      case "tongyi":
        return tongyiConfig;
      case "qwen":
        return qwenConfig;
      case "kimi":
        return kimiConfig;
      case "yuanbao":
        return yuanbaoConfig;
      default:
        return null;
    }
  }
  let idCounter = 0;
  function generateUniqueId() {
    return `${Date.now()}-${++idCounter}`;
  }
  const defaultServiceStatus = {
    outlineRuntime: {
      key: "outlineRuntime",
      label: "大纲运行时",
      state: "idle",
      message: "大纲运行时尚未初始化",
      updatedAt: Date.now()
    },
    scrollSync: {
      key: "scrollSync",
      label: "滚动监听",
      state: "idle",
      message: "滚动监听尚未初始化",
      updatedAt: Date.now()
    }
  };
  const serviceStatusStore = writable(defaultServiceStatus);
  const panelNoticeStore = writable([]);
  let noticeId = 0;
  function setServiceStatus(key, patch) {
    serviceStatusStore.update((status) => ({
      ...status,
      [key]: {
        ...status[key],
        ...patch,
        updatedAt: Date.now()
      }
    }));
  }
  function resetServiceStatus() {
    serviceStatusStore.set({
      outlineRuntime: { ...defaultServiceStatus.outlineRuntime, updatedAt: Date.now() },
      scrollSync: { ...defaultServiceStatus.scrollSync, updatedAt: Date.now() }
    });
  }
  function pushPanelNotice(message, level = "info", duration = 3e3) {
    const id = ++noticeId;
    const notice = {
      id,
      level,
      message,
      createdAt: Date.now()
    };
    panelNoticeStore.update((list) => [...list, notice]);
    if (duration > 0) {
      window.setTimeout(() => {
        removePanelNotice(id);
      }, duration);
    }
    return id;
  }
  function removePanelNotice(id) {
    panelNoticeStore.update((list) => list.filter((notice) => notice.id !== id));
  }
  const DEFAULT_CONVERSATION_ID = "default";
  function getConversationId() {
    const config = get(parserConfigStore);
    if (config?.getConversationId) {
      const id = config.getConversationId();
      return id ?? DEFAULT_CONVERSATION_ID;
    }
    return DEFAULT_CONVERSATION_ID;
  }
  function getConversationName() {
    const config = get(parserConfigStore);
    if (config?.getConversationName) {
      const name = config.getConversationName();
      return name ?? getConversationId();
    }
    return getConversationId();
  }
  function isInConversation(targetConversationId) {
    return getConversationId() === targetConversationId;
  }
  const STORAGE_KEY = "chat-outline-bookmarks";
  const EXPORT_VERSION = "2.0.0";
  const gmLogger = createTaggedLogger("Bookmarks");
  function generateBookmarkId() {
    return `bm_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
  }
  function loadBookmarksFromStorage() {
    try {
      const saved = window.localStorage.getItem(STORAGE_KEY);
      if (!saved) {
        return {};
      }
      const parsed = JSON.parse(saved);
      const data = {};
      for (const [conversationId, value] of Object.entries(parsed)) {
        if (Array.isArray(value)) {
          data[conversationId] = {
            name: null,
            bookmarks: value.map((b) => ({
              id: b.id,
              name: b.name,
              outlineItemType: b.outlineItemType,
              messageIndex: b.messageIndex,
              messageHash: b.messageHash,
              headerPath: b.headerPath,
              createdAt: b.createdAt
            }))
          };
        } else {
          data[conversationId] = value;
        }
      }
      gmLogger.debug("从 localStorage 加载书签", { conversationCount: Object.keys(data).length });
      return data;
    } catch (error) {
      gmLogger.warn("加载书签失败", error);
      return {};
    }
  }
  function saveBookmarksToStorage(data) {
    try {
      window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
      gmLogger.debug("书签已保存到 localStorage");
    } catch (error) {
      gmLogger.error("保存书签失败", error);
    }
  }
  function createBookmarksStore() {
    const { subscribe, set: set2, update } = writable(loadBookmarksFromStorage());
    subscribe((data) => {
      saveBookmarksToStorage(data);
    });
    return {
      subscribe,
addBookmark(params) {
        const bookmark = {
          id: generateBookmarkId(),
          name: params.name,
          outlineItemType: params.outlineItemType,
          messageHash: params.messageHash,
          messageIndex: params.messageIndex,
          headerPath: params.headerPath,
          createdAt: Date.now()
        };
        update((data) => {
          if (!data[params.conversationId]) {
            const convName = getConversationName();
            data[params.conversationId] = {
              name: convName,
              bookmarks: []
            };
          }
          data[params.conversationId].bookmarks.push(bookmark);
          return { ...data };
        });
        gmLogger.info("添加书签", { id: bookmark.id, name: bookmark.name, headerPath: params.headerPath });
        return bookmark;
      },
removeBookmark(bookmarkId) {
        update((data) => {
          for (const conversationId of Object.keys(data)) {
            const index2 = data[conversationId].bookmarks.findIndex((b) => b.id === bookmarkId);
            if (index2 !== -1) {
              data[conversationId].bookmarks.splice(index2, 1);
              if (data[conversationId].bookmarks.length === 0) {
                delete data[conversationId];
              }
              gmLogger.info("删除书签", { id: bookmarkId });
              break;
            }
          }
          return { ...data };
        });
      },
updateBookmarkName(bookmarkId, newName) {
        update((data) => {
          for (const conversationId of Object.keys(data)) {
            const bookmark = data[conversationId].bookmarks.find((b) => b.id === bookmarkId);
            if (bookmark) {
              bookmark.name = newName;
              gmLogger.info("更新书签名称", { id: bookmarkId, newName });
              break;
            }
          }
          return { ...data };
        });
      },
getBookmarksByConversation(conversationId) {
        const data = get({ subscribe });
        return data[conversationId]?.bookmarks || [];
      },
getConversationData(conversationId) {
        const data = get({ subscribe });
        return data[conversationId];
      },
getCurrentConversationBookmarks() {
        const conversationId = getConversationId();
        return this.getBookmarksByConversation(conversationId);
      },
getAllBookmarks() {
        const data = get({ subscribe });
        const result = [];
        for (const [conversationId, convData] of Object.entries(data)) {
          for (const bookmark of convData.bookmarks) {
            result.push({ ...bookmark, conversationId });
          }
        }
        return result;
      },
getAllBookmarksGrouped() {
        return get({ subscribe });
      },
getAllConversations() {
        const data = get({ subscribe });
        return Object.entries(data).map(([conversationId, convData]) => ({
          conversationId,
          name: convData.name,
          bookmarkCount: convData.bookmarks.length
        }));
      },
searchBookmarks(query, conversationId) {
        const data = get({ subscribe });
        const lowerQuery = query.toLowerCase();
        const result = [];
        const searchInConv = (convId, bookmarks) => {
          for (const b of bookmarks) {
            if (b.name.toLowerCase().includes(lowerQuery)) {
              result.push({ ...b, conversationId: convId });
            }
          }
        };
        if (conversationId) {
          const convData = data[conversationId];
          if (convData) {
            searchInConv(conversationId, convData.bookmarks);
          }
        } else {
          for (const [convId, convData] of Object.entries(data)) {
            searchInConv(convId, convData.bookmarks);
          }
        }
        return result;
      },
hasBookmarkForMessageIndex(messageIndex, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.some((b) => b.messageIndex === messageIndex && b.outlineItemType === "message");
      },
hasBookmarkForHeader(messageIndex, headerPath, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.some(
          (b) => b.messageIndex === messageIndex && b.outlineItemType === "header" && b.headerPath === headerPath
        );
      },
getBookmarkByMessageIndex(messageIndex, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.find((b) => b.messageIndex === messageIndex && b.outlineItemType === "message");
      },
getBookmarkByHeaderPath(messageIndex, headerPath, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.find(
          (b) => b.messageIndex === messageIndex && b.outlineItemType === "header" && b.headerPath === headerPath
        );
      },
getBookmarksForMessage(messageIndex, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.filter((b) => b.messageIndex === messageIndex);
      },
hasAnyBookmarkForMessage(messageIndex, conversationId) {
        const data = get({ subscribe });
        const convId = conversationId || getConversationId();
        const bookmarks = data[convId]?.bookmarks || [];
        return bookmarks.some((b) => b.messageIndex === messageIndex);
      },
getBookmarkById(bookmarkId) {
        const data = get({ subscribe });
        for (const [conversationId, convData] of Object.entries(data)) {
          const bookmark = convData.bookmarks.find((b) => b.id === bookmarkId);
          if (bookmark) {
            return { ...bookmark, conversationId };
          }
        }
        return void 0;
      },
exportBookmarks() {
        const data = get({ subscribe });
        return {
          version: EXPORT_VERSION,
          exportedAt: Date.now(),
          data: { ...data }
        };
      },
importBookmarks(exportData, merge = true) {
        let importedCount = 0;
        update((data) => {
          for (const [conversationId, convData] of Object.entries(exportData.data)) {
            if (!merge) {
              data[conversationId] = convData;
              importedCount += convData.bookmarks.length;
            } else {
              if (!data[conversationId]) {
                data[conversationId] = convData;
                importedCount += convData.bookmarks.length;
              } else {
                for (const bookmark of convData.bookmarks) {
                  const exists = data[conversationId].bookmarks.some(
                    (b) => b.messageIndex === bookmark.messageIndex && b.outlineItemType === bookmark.outlineItemType && b.headerPath === bookmark.headerPath
                  );
                  if (!exists) {
                    data[conversationId].bookmarks.push(bookmark);
                    importedCount++;
                  }
                }
              }
            }
          }
          return { ...data };
        });
        gmLogger.info("导入书签", { count: importedCount, merge });
        return importedCount;
      },
clearAll() {
        set2({});
        gmLogger.info("清空所有书签");
      },
clearConversation(conversationId) {
        update((data) => {
          delete data[conversationId];
          return { ...data };
        });
        gmLogger.info("清空会话书签", { conversationId });
      }
    };
  }
  const bookmarksStore = createBookmarksStore();
  var root$9 = from_html(`<div class="modal-overlay svelte-lmj43v" role="button" tabindex="0"><div class="modal-content svelte-lmj43v" role="dialog" aria-modal="true" tabindex="-1"><div class="modal-header svelte-lmj43v"><h3 class="svelte-lmj43v">设置</h3> <button class="close-btn svelte-lmj43v">✕</button></div> <div class="modal-body svelte-lmj43v"><div class="setting-section svelte-lmj43v"><h4 class="section-title svelte-lmj43v">显示设置</h4> <label class="svelte-lmj43v"><input type="checkbox" class="svelte-lmj43v"/> 自动展开节点</label> <label class="svelte-lmj43v"><input type="checkbox" class="svelte-lmj43v"/> 显示用户消息</label> <label class="svelte-lmj43v"><input type="checkbox" class="svelte-lmj43v"/> 显示AI回复</label> <label class="svelte-lmj43v"><input type="checkbox" class="svelte-lmj43v"/> 同步滚动</label></div> <div class="setting-section svelte-lmj43v"><h4 class="section-title svelte-lmj43v">书签设置</h4> <label class="svelte-lmj43v">书签默认名称长度 <input type="number" min="10" max="100" class="svelte-lmj43v"/></label></div> <div class="setting-section svelte-lmj43v"><h4 class="section-title svelte-lmj43v">高级设置</h4> <label class="svelte-lmj43v">文本长度限制 <input type="number" min="10" max="200" class="svelte-lmj43v"/></label> <label class="svelte-lmj43v">更新间隔 (ms) <input type="number" min="100" max="2000" step="100" class="svelte-lmj43v"/></label> <label class="svelte-lmj43v">日志级别 <select class="svelte-lmj43v"><option>Debug</option><option>Info</option><option>Warn</option><option>Error</option></select></label></div></div></div></div>`);
  function SettingsModal($$anchor, $$props) {
    push($$props, true);
    const $featuresStore = () => store_get(featuresStore, "$featuresStore", $$stores);
    const [$$stores, $$cleanup] = setup_stores();
    let features = state(proxy($featuresStore()));
    user_effect(() => {
      set(features, $featuresStore(), true);
    });
    function updateFeature(key, value) {
      featuresStore.update((f) => ({ ...f, [key]: value }));
    }
    var div = root$9();
    var div_1 = child(div);
    var div_2 = child(div_1);
    var button = sibling(child(div_2), 2);
    var div_3 = sibling(div_2, 2);
    var div_4 = child(div_3);
    var label = sibling(child(div_4), 2);
    var input = child(label);
    var label_1 = sibling(label, 2);
    var input_1 = child(label_1);
    var label_2 = sibling(label_1, 2);
    var input_2 = child(label_2);
    var label_3 = sibling(label_2, 2);
    var input_3 = child(label_3);
    var div_5 = sibling(div_4, 2);
    var label_4 = sibling(child(div_5), 2);
    var input_4 = sibling(child(label_4));
    var div_6 = sibling(div_5, 2);
    var label_5 = sibling(child(div_6), 2);
    var input_5 = sibling(child(label_5));
    var label_6 = sibling(label_5, 2);
    var input_6 = sibling(child(label_6));
    var label_7 = sibling(label_6, 2);
    var select = sibling(child(label_7));
    var option = child(select);
    option.value = option.__value = "debug";
    var option_1 = sibling(option);
    option_1.value = option_1.__value = "info";
    var option_2 = sibling(option_1);
    option_2.value = option_2.__value = "warn";
    var option_3 = sibling(option_2);
    option_3.value = option_3.__value = "error";
    var select_value;
    init_select(select);
    template_effect(() => {
      set_checked(input, get$1(features).autoExpand);
      set_checked(input_1, get$1(features).showUserMessages);
      set_checked(input_2, get$1(features).showAIMessages);
      set_checked(input_3, get$1(features).syncScroll);
      set_value(input_4, get$1(features).bookmarkGetTextLength);
      set_value(input_5, get$1(features).textLength);
      set_value(input_6, get$1(features).debouncedInterval);
      if (select_value !== (select_value = get$1(features).logLevel)) {
        select.value = (select.__value = get$1(features).logLevel) ?? "", select_option(select, get$1(features).logLevel);
      }
    });
    delegated("click", div, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    delegated("keydown", div, (e) => e.key === "Escape" && $$props.onClose());
    delegated("click", div_1, (e) => e.stopPropagation());
    delegated("keydown", div_1, (e) => e.stopPropagation());
    delegated("click", button, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    delegated("change", input, (e) => updateFeature("autoExpand", e.currentTarget.checked));
    delegated("change", input_1, (e) => updateFeature("showUserMessages", e.currentTarget.checked));
    delegated("change", input_2, (e) => updateFeature("showAIMessages", e.currentTarget.checked));
    delegated("change", input_3, (e) => updateFeature("syncScroll", e.currentTarget.checked));
    delegated("change", input_4, (e) => updateFeature("bookmarkGetTextLength", parseInt(e.currentTarget.value)));
    delegated("change", input_5, (e) => updateFeature("textLength", parseInt(e.currentTarget.value)));
    delegated("change", input_6, (e) => updateFeature("debouncedInterval", parseInt(e.currentTarget.value)));
    delegated("change", select, (e) => updateFeature("logLevel", e.currentTarget.value));
    append($$anchor, div);
    pop();
    $$cleanup();
  }
  delegate(["click", "keydown", "change"]);
  function debounce(func, wait) {
    let timeout = null;
    return function executedFunction(...args) {
      const later = () => {
        timeout = null;
        func(...args);
      };
      if (timeout !== null) {
        clearTimeout(timeout);
      }
      timeout = setTimeout(later, wait);
    };
  }
  async function getEleWithRetry(getFunc, args = [], judgeRes = true, maxRetries = 10, retryDelay = 1e3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      try {
        const res = getFunc(...args);
        if (!judgeRes) return true;
        if (res) {
          logger$1.info(`调用 ${getFunc.name} 获取目标成功,尝试次数: ${attempt + 1}`);
          return res;
        }
        if (attempt < maxRetries - 1) {
          logger$1.debug(`第 ${attempt + 1} 次调用 ${getFunc.name} 获取目标失败,${retryDelay}ms 后重试...`);
          await new Promise((resolve) => setTimeout(resolve, retryDelay));
        }
      } catch (error) {
        logger$1.error(`调用 ${getFunc.name} 获取目标时发生错误 (尝试 ${attempt + 1}):`, error);
        if (attempt < maxRetries - 1) {
          await new Promise((resolve) => setTimeout(resolve, retryDelay));
        }
      }
    }
    logger$1.error(`经过 ${maxRetries} 次尝试后仍无法获取到目标`);
    return null;
  }
  function highlightElement(element) {
    element.classList.remove("highlight-animation");
    element.offsetHeight;
    element.classList.add("highlight-animation");
    const theme = get(themeStore);
    setTimeout(() => {
      element.classList.remove("highlight-animation");
    }, theme.highlightTime);
  }
  var root_1$9 = from_html(`<button class="outline-btn svelte-zptf9e" title="强制刷新大纲" aria-label="强制刷新大纲">🔄</button> <button class="outline-btn svelte-zptf9e" title="同步大纲位置" aria-label="同步大纲位置">📍</button> <button class="outline-btn svelte-zptf9e"> </button>`, 1);
  var root_2$6 = from_html(`<div class="filter-row svelte-zptf9e"><input type="text" class="filter-input svelte-zptf9e" placeholder="筛选..."/> <button>.*</button></div>`);
  var root$8 = from_html(`<header class="chat-outline-header svelte-zptf9e"><div class="title-row svelte-zptf9e"><h3 class="chat-outline-title svelte-zptf9e"></h3> <div class="title-controls svelte-zptf9e"><button class="outline-btn svelte-zptf9e" title="设置" aria-label="设置">⚙️</button> <button class="outline-btn svelte-zptf9e" title="隐藏大纲" aria-label="隐藏大纲">✕</button></div></div> <div class="tab-container svelte-zptf9e"><button>📋 大纲</button> <button>📚 书签</button></div> <div class="controls-row svelte-zptf9e"><div class="controls-left svelte-zptf9e"><!></div> <div class="controls-right svelte-zptf9e"><button class="outline-btn svelte-zptf9e" title="切换主题" aria-label="切换主题"> </button></div></div> <!></header> <!>`, 1);
  function OutlineHeader($$anchor, $$props) {
    push($$props, true);
    let filterText = state("");
    let useRegex = state(false);
    let showSettings = state(false);
    const emitFilterChange = debounce(
      (filter, regex) => {
        $$props.onFilterChange(filter, regex);
      },
      150
    );
    function handleFilterInput(e) {
      set(filterText, e.target.value, true);
      emitFilterChange(get$1(filterText), get$1(useRegex));
    }
    function toggleRegex() {
      set(useRegex, !get$1(useRegex));
      $$props.onFilterChange(get$1(filterText), get$1(useRegex));
    }
    var fragment = root$8();
    var header = first_child(fragment);
    var div = child(header);
    var h3 = child(div);
    h3.textContent = "对话大纲";
    var div_1 = sibling(h3, 2);
    var button = child(div_1);
    var button_1 = sibling(button, 2);
    var div_2 = sibling(div, 2);
    var button_2 = child(div_2);
    let classes;
    var button_3 = sibling(button_2, 2);
    let classes_1;
    var div_3 = sibling(div_2, 2);
    var div_4 = child(div_3);
    var node = child(div_4);
    {
      var consequent = ($$anchor2) => {
        var fragment_1 = root_1$9();
        var button_4 = first_child(fragment_1);
        var button_5 = sibling(button_4, 2);
        var button_6 = sibling(button_5, 2);
        var text2 = child(button_6);
        template_effect(() => {
          set_attribute(button_6, "title", $$props.allExpanded ? "收起所有节点" : "展开所有节点");
          set_attribute(button_6, "aria-label", $$props.allExpanded ? "收起所有节点" : "展开所有节点");
          set_text(text2, $$props.allExpanded ? "📂" : "📁");
        });
        delegated("click", button_4, function(...$$args) {
          $$props.onRefresh?.apply(this, $$args);
        });
        delegated("click", button_5, function(...$$args) {
          $$props.onSync?.apply(this, $$args);
        });
        delegated("click", button_6, function(...$$args) {
          $$props.onToggleAll?.apply(this, $$args);
        });
        append($$anchor2, fragment_1);
      };
      if_block(node, ($$render) => {
        if ($$props.viewMode === "outline") $$render(consequent);
      });
    }
    var div_5 = sibling(div_4, 2);
    var button_7 = child(div_5);
    var text_1 = child(button_7);
    var node_1 = sibling(div_3, 2);
    {
      var consequent_1 = ($$anchor2) => {
        var div_6 = root_2$6();
        var input = child(div_6);
        var button_8 = sibling(input, 2);
        let classes_2;
        template_effect(() => {
          set_value(input, get$1(filterText));
          classes_2 = set_class(button_8, 1, "outline-btn regex-btn svelte-zptf9e", null, classes_2, { active: get$1(useRegex) });
          set_attribute(button_8, "title", get$1(useRegex) ? "关闭正则表达式" : "启用正则表达式");
        });
        delegated("input", input, handleFilterInput);
        delegated("click", button_8, toggleRegex);
        append($$anchor2, div_6);
      };
      if_block(node_1, ($$render) => {
        if ($$props.viewMode === "outline") $$render(consequent_1);
      });
    }
    var node_2 = sibling(header, 2);
    {
      var consequent_2 = ($$anchor2) => {
        SettingsModal($$anchor2, { onClose: () => set(showSettings, false) });
      };
      if_block(node_2, ($$render) => {
        if (get$1(showSettings)) $$render(consequent_2);
      });
    }
    template_effect(() => {
      classes = set_class(button_2, 1, "tab-btn svelte-zptf9e", null, classes, { active: $$props.viewMode === "outline" });
      classes_1 = set_class(button_3, 1, "tab-btn svelte-zptf9e", null, classes_1, { active: $$props.viewMode === "bookmark" });
      set_text(text_1, $$props.currentTheme === "light" ? "🌙" : "☀️");
    });
    delegated("click", button, () => set(showSettings, true));
    delegated("click", button_1, function(...$$args) {
      $$props.onHide?.apply(this, $$args);
    });
    delegated("click", button_2, () => $$props.onTabChange("outline"));
    delegated("click", button_3, () => $$props.onTabChange("bookmark"));
    delegated("click", button_7, function(...$$args) {
      $$props.onToggleTheme?.apply(this, $$args);
    });
    append($$anchor, fragment);
    pop();
  }
  delegate(["click", "input"]);
  const HEADER_SELECTOR = "h1, h2, h3, h4, h5, h6";
  function getMessageText(messageElement) {
    return messageElement.textContent || "";
  }
  function buildMessageHash(index2, text2) {
    const idLength = 10;
    if (text2.length <= idLength * 2) {
      return `${index2}${text2}`;
    }
    const res = [];
    const step = Math.max(1, Math.ceil((text2.length - idLength) / idLength));
    for (let i = 0; i < text2.length - idLength && res.length < idLength; i += step) {
      res.push(text2[i]);
    }
    return `${index2}${res.join("")}${text2.substring(text2.length - idLength)}`;
  }
  function buildHeaderTreeWithPrefix(headers, prefix) {
    const tree = [];
    const stack = [];
    headers.forEach((header) => {
      const level = Number.parseInt(header.tagName.charAt(1), 10);
      const node = {
        id: "",
        element: header,
        level,
        text: header.textContent || "",
        children: []
      };
      while (stack.length > 0 && stack[stack.length - 1].level >= level) {
        stack.pop();
      }
      const parent = stack[stack.length - 1];
      const localId = parent ? `${parent.id}.${parent.children.length}` : `${tree.length}`;
      node.id = prefix ? `${prefix}:${localId}` : localId;
      if (parent) {
        parent.children.push(node);
      } else {
        tree.push(node);
      }
      stack.push(node);
    });
    return tree;
  }
  function buildOutlineData(messageElement, type, textLength, headerIdPrefix = "") {
    const searchText = getMessageText(messageElement);
    const text2 = searchText.substring(0, textLength) + (searchText.length > textLength ? "..." : "");
    if (type !== MessageOwner.Assistant) {
      return { text: text2, searchText };
    }
    const headers = messageElement.querySelectorAll(HEADER_SELECTOR);
    return {
      text: text2,
      searchText,
      headers: headers.length > 0 ? buildHeaderTreeWithPrefix(Array.from(headers), headerIdPrefix) : void 0
    };
  }
  function createOutlineViewItem(params) {
    const { id, index: index2, type, element, textLength } = params;
    const built = buildOutlineData(element, type, textLength, id);
    return {
      id,
      index: index2,
      type,
      text: built.text,
      searchText: built.searchText,
      element,
      headers: built.headers,
      isExpanded: true
    };
  }
  class MessageCacheManager {
    cache = [];
    cacheByMessageId = new Map();
    cacheByOutlineId = new Map();
    getCache() {
      return this.cache;
    }
    setCache(cache) {
      this.cache = cache;
      this.rebuildIndexes();
    }
    clearCache() {
      this.cache = [];
      this.cacheByMessageId.clear();
      this.cacheByOutlineId.clear();
    }
    get length() {
      return this.cache.length;
    }
    get(index2) {
      return this.cache[index2];
    }
    ensureMessageId(messageElement) {
      let messageId = messageElement.getAttribute("cbe-message-id");
      if (!messageId) {
        messageId = generateUniqueId();
        messageElement.setAttribute("cbe-message-id", messageId);
      }
      return messageId;
    }
    checkLastMessage(messageElements) {
      if (this.cache.length === 0 || messageElements.length === 0) {
        return { shouldRefreshAll: true, lastMessageNeedsUpdate: true, lastIndex: -1 };
      }
      const lastIndex = messageElements.length - 1;
      const lastMessage = messageElements[lastIndex];
      const lastCached = this.cache[this.cache.length - 1];
      const messageId = this.ensureMessageId(lastMessage);
      if (messageId !== lastCached.messageId) {
        return { shouldRefreshAll: true, lastMessageNeedsUpdate: true, lastIndex };
      }
      const currentHash = buildMessageHash(lastIndex, lastMessage.textContent || "");
      return {
        shouldRefreshAll: false,
        lastMessageNeedsUpdate: currentHash !== lastCached.messageHash,
        lastIndex
      };
    }
    updateLastCache(messageElement, index2, outlineItem, outlineElement) {
      const messageId = this.ensureMessageId(messageElement);
      const newCacheItem = {
        messageId,
        messageHash: buildMessageHash(index2, messageElement.textContent || ""),
        textLength: messageElement.textContent?.length || 0,
        outlineElement,
        outlineItem,
        timestamp: Date.now()
      };
      this.cache[this.cache.length - 1] = newCacheItem;
      this.cacheByMessageId.set(messageId, newCacheItem);
      this.cacheByOutlineId.set(outlineItem.id, newCacheItem);
    }
    rebuildCache(messageElements, parserConfig, options) {
      const nextCache = [];
      const outlineItems = [];
      const changedIndices = [];
      let displayIndex = 0;
      for (let rawIndex = 0; rawIndex < messageElements.length; rawIndex++) {
        const messageElement = messageElements[rawIndex];
        const messageType = parserConfig.determineMessageOwner(messageElement);
        const shouldShow = messageType === MessageOwner.User && options.features.showUserMessages || messageType === MessageOwner.Assistant && options.features.showAIMessages;
        if (!shouldShow) {
          continue;
        }
        const messageId = this.ensureMessageId(messageElement);
        const messageHash = buildMessageHash(rawIndex, messageElement.textContent || "");
        const oldCached = this.cacheByMessageId.get(messageId);
        let nextCached;
        if (oldCached && oldCached.messageHash === messageHash) {
          nextCached = oldCached;
          if (nextCached.outlineItem.index !== displayIndex) {
            nextCached.outlineItem.index = displayIndex;
            changedIndices.push(displayIndex);
          }
          nextCached.outlineItem.element = messageElement;
        } else {
          const stableOutlineId = oldCached?.outlineItem.id || generateUniqueId();
          const outlineItem = createOutlineViewItem({
            id: stableOutlineId,
            index: displayIndex,
            type: messageType,
            element: messageElement,
            textLength: options.features.textLength
          });
          nextCached = {
            messageId,
            messageHash,
            textLength: messageElement.textContent?.length || 0,
            outlineElement: oldCached?.outlineElement || null,
            outlineItem,
            timestamp: Date.now()
          };
          changedIndices.push(displayIndex);
        }
        nextCache.push(nextCached);
        outlineItems.push(nextCached.outlineItem);
        displayIndex += 1;
      }
      const addedCount = Math.max(0, nextCache.length - this.cache.length);
      const removedCount = Math.max(0, this.cache.length - nextCache.length);
      const hasChanges = changedIndices.length > 0 || addedCount > 0 || removedCount > 0 || nextCache.length !== this.cache.length;
      this.cache = nextCache;
      this.rebuildIndexes();
      const changes = {
        hasChanges,
        changedIndices: [...new Set(changedIndices)],
        addedCount,
        removedCount
      };
      logger$1.debug("Cache 重建完成:", changes);
      return { changes, outlineItems };
    }
    updateOutlineElement(outlineItemId, outlineElement) {
      const cachedItem = this.cacheByOutlineId.get(outlineItemId);
      if (!cachedItem || cachedItem.outlineElement === outlineElement) {
        return;
      }
      cachedItem.outlineElement = outlineElement;
    }
    getOutlineElementByIndex(messageIndex) {
      const element = this.cache[messageIndex]?.outlineElement;
      return element ?? void 0;
    }
    getCacheIndexByMessageId(messageId) {
      if (!messageId) {
        return -1;
      }
      for (let index2 = 0; index2 < this.cache.length; index2++) {
        if (this.cache[index2].messageId === messageId) {
          return index2;
        }
      }
      return -1;
    }
    scrollOutlineToMessage(messageIndex) {
      const outlineElement = this.getOutlineElementByIndex(messageIndex);
      outlineElement?.scrollIntoView({ behavior: "smooth", block: "center" });
    }
    rebuildIndexes() {
      this.cacheByMessageId.clear();
      this.cacheByOutlineId.clear();
      for (const item of this.cache) {
        this.cacheByMessageId.set(item.messageId, item);
        this.cacheByOutlineId.set(item.outlineItem.id, item);
      }
    }
  }
  const messageCacheManager = new MessageCacheManager();
  const BIND_RETRY_COUNT = 5;
  const BIND_RETRY_DELAY = 1e3;
  const MAX_AUTO_RETRY_COUNT = 5;
  class ScrollSyncService {
    scrollContainer = null;
    scrollHandler = null;
    isSyncing = false;
    debounceTimer = null;
    outlineContainer = null;
    chatArea = null;
    parserConfig = null;
    currentHighlightedElement = null;
    highlightTimer = null;
    lastHighlightElement = null;
    autoRetryTimer = null;
    postRefreshCheckTimer = null;
    isBinding = false;
    retryGeneration = 0;
    autoRetryCount = 0;
    lastSyncScrollEnabled = null;
    lastVisibleIndex = -1;
    intersectionObserver = null;
    visibleMessageMetrics = new Map();
    manualNavigationUntil = 0;
    headerOutlineElements = new Map();
    scrollAnchors = [];
    anchorOffsetsDirty = true;
    rebuildScrollAnchorsTimer = null;
    focusOutlineElement(outlineElement) {
      if (!outlineElement) {
        return;
      }
      this.manualNavigationUntil = Date.now() + 800;
      this.lastHighlightElement = outlineElement;
    }
    registerHeaderOutlineElement(nodeId, outlineElement) {
      this.headerOutlineElements.set(nodeId, outlineElement);
      this.scheduleRebuildScrollAnchors();
    }
    unregisterHeaderOutlineElement(nodeId) {
      if (this.headerOutlineElements.delete(nodeId)) {
        this.scheduleRebuildScrollAnchors();
      }
    }
    getHeaderOutlineElement(nodeId) {
      return this.headerOutlineElements.get(nodeId) || null;
    }
    scheduleRebuildScrollAnchors() {
      if (this.rebuildScrollAnchorsTimer) {
        return;
      }
      this.rebuildScrollAnchorsTimer = setTimeout(() => {
        this.rebuildScrollAnchorsTimer = null;
        this.rebuildScrollAnchors();
      }, 0);
    }
    markAnchorOffsetsDirty() {
      this.anchorOffsetsDirty = true;
    }
    constructor() {
      featuresStore.subscribe((features) => {
        if (this.lastSyncScrollEnabled === features.syncScroll) {
          return;
        }
        this.lastSyncScrollEnabled = features.syncScroll;
        if (features.syncScroll) {
          void this.bindScrollListenerWithRetry("sync-toggle", true);
        } else {
          this.clearAutoRetryTimer();
          this.unbindScrollListener();
          this.autoRetryCount = 0;
          this.updateStatus("idle", "滚动监听开关已关闭");
        }
      });
    }
    init(chatArea, parserConfig) {
      this.chatArea = chatArea;
      this.parserConfig = parserConfig;
      this.scrollContainer = null;
      this.autoRetryCount = 0;
      this.updateStatus("syncing", "正在获取滚动容器并绑定监听");
      void this.bindScrollListenerWithRetry("init", true);
    }
    setOutlineContainer(container) {
      this.outlineContainer = container;
      if (!this.chatArea) {
        this.handleAbnormalState("warning", "大纲容器已就绪,但聊天区域尚未绑定", false);
        return;
      }
      if (this.scrollHandler) {
        this.updateStatus("ready", "滚动监听已成功绑定");
        this.triggerInitialSync();
        return;
      }
      this.updateStatus("syncing", "大纲容器已就绪,等待滚动监听绑定");
      void this.bindScrollListenerWithRetry("outline-ready", true);
    }
    manualSync() {
      logger$1.info("手动同步大纲滚动");
      this.lastHighlightElement = null;
      this.lastVisibleIndex = -1;
      this.visibleMessageMetrics.clear();
      this.markAnchorOffsetsDirty();
      this.syncOutlineScroll();
    }
    schedulePostRefreshCheck() {
      if (!get(featuresStore).syncScroll) {
        return;
      }
      if (this.postRefreshCheckTimer) {
        clearTimeout(this.postRefreshCheckTimer);
      }
      this.postRefreshCheckTimer = setTimeout(() => {
        this.postRefreshCheckTimer = null;
        void this.performPostRefreshCheck();
      }, 500);
    }
    async forceRebind() {
      if (!this.parserConfig) {
        this.handleAbnormalState("error", "未找到解析配置,无法重新绑定滚动监听", false);
        pushPanelNotice("滚动监听重新绑定失败:解析配置不存在", "error");
        return false;
      }
      const nextChatArea = await getEleWithRetry(
        this.parserConfig.selectChatArea,
        [],
        true,
        BIND_RETRY_COUNT,
        BIND_RETRY_DELAY
      );
      if (!nextChatArea) {
        this.handleAbnormalState("error", "未找到聊天区域,无法重新绑定滚动监听", false);
        pushPanelNotice("滚动监听重新绑定失败:未找到聊天区域", "error");
        return false;
      }
      this.chatArea = nextChatArea;
      this.autoRetryCount = 0;
      this.updateStatus("syncing", "正在重新获取滚动容器并绑定监听");
      const isBound = await this.bindScrollListenerWithRetry("manual-rebind", false, false);
      if (!isBound) {
        pushPanelNotice("滚动监听重新绑定失败,请检查页面是否已稳定", "error");
        return false;
      }
      pushPanelNotice("滚动监听重新绑定完成", "success");
      return true;
    }
    rebind(chatArea, parserConfig) {
      this.lastHighlightElement = null;
      this.chatArea = chatArea;
      this.parserConfig = parserConfig;
      this.scrollContainer = null;
      this.autoRetryCount = 0;
      this.disconnectIntersectionObserver();
      this.scrollAnchors = [];
      this.unbindScrollListener();
      if (!get(featuresStore).syncScroll) {
        this.updateStatus("idle", "滚动监听开关已关闭");
        return;
      }
      this.updateStatus("syncing", "正在重新获取滚动容器并绑定监听");
      void this.bindScrollListenerWithRetry("rebind", true);
    }
    destroy(resetStatus = true) {
      this.clearAutoRetryTimer();
      this.clearPostRefreshCheckTimer();
      this.disconnectIntersectionObserver();
      this.unbindScrollListener();
      if (this.highlightTimer) {
        clearTimeout(this.highlightTimer);
        this.highlightTimer = null;
      }
      this.scrollContainer = null;
      this.outlineContainer = null;
      this.chatArea = null;
      this.parserConfig = null;
      this.currentHighlightedElement = null;
      this.lastHighlightElement = null;
      this.lastVisibleIndex = -1;
      this.visibleMessageMetrics.clear();
      this.headerOutlineElements.clear();
      this.scrollAnchors = [];
      this.manualNavigationUntil = 0;
      this.isBinding = false;
      this.retryGeneration += 1;
      this.autoRetryCount = 0;
      if (resetStatus) {
        this.updateStatus("idle", "滚动监听尚未初始化");
      }
    }
    syncOutlineScroll() {
      if (!this.scrollContainer || !this.outlineContainer) {
        this.handleAbnormalState("warning", "缺少滚动容器或大纲容器,无法执行同步", false);
        return;
      }
      if (Date.now() < this.manualNavigationUntil) {
        return;
      }
      if (!this.scrollHandler) {
        this.handleAbnormalState("warning", "滚动监听未绑定,正在尝试自动重试");
        return;
      }
      const activeAnchor = this.findActiveAnchor();
      if (activeAnchor) {
        this.scrollToOutlineAnchor(activeAnchor);
        return;
      }
      const visibleIndex = this.findVisibleMessageIndex();
      if (visibleIndex === -1) {
        this.updateStatus("warning", "未找到当前可见消息,滚动监听暂不可用");
        return;
      }
      this.scrollToOutlineItem(visibleIndex);
    }
    async bindScrollListenerWithRetry(reason, allowAutoRetry, shouldTriggerInitialSync = true) {
      if (this.isBinding) {
        return false;
      }
      if (!get(featuresStore).syncScroll) {
        this.updateStatus("idle", "滚动监听开关已关闭");
        return false;
      }
      if (!this.chatArea || !this.parserConfig) {
        this.handleAbnormalState("warning", "聊天区域或解析配置未就绪,无法绑定滚动监听", false);
        return false;
      }
      this.isBinding = true;
      this.retryGeneration += 1;
      const generation = this.retryGeneration;
      this.clearAutoRetryTimer();
      this.unbindScrollListener();
      this.updateStatus("syncing", `正在绑定滚动监听(${reason})`);
      try {
        const resolvedContainer = await this.resolveScrollContainerWithRetry();
        if (generation !== this.retryGeneration) {
          return false;
        }
        if (!resolvedContainer) {
          this.handleAbnormalState("warning", "未找到滚动容器,已进入自动重试", allowAutoRetry);
          return false;
        }
        this.scrollContainer = resolvedContainer;
        this.scrollHandler = () => {
          if (this.isSyncing) {
            return;
          }
          if (this.debounceTimer) {
            clearTimeout(this.debounceTimer);
          }
          this.debounceTimer = setTimeout(() => {
            this.syncOutlineScroll();
          }, 300);
        };
        this.scrollContainer.addEventListener("scroll", this.scrollHandler, {
          passive: true
        });
        logger$1.info("绑定滚动监听成功,容器:", this.scrollContainer);
        this.autoRetryCount = 0;
        this.updateStatus("ready", "滚动监听已成功绑定");
        this.observeVisibleMessages();
        if (shouldTriggerInitialSync) {
          this.triggerInitialSync();
        }
        return true;
      } catch (error) {
        logger$1.error("绑定滚动监听时发生异常:", error);
        this.handleAbnormalState("error", "绑定滚动监听时发生异常,已进入自动重试", allowAutoRetry);
        return false;
      } finally {
        if (generation === this.retryGeneration) {
          this.isBinding = false;
        }
      }
    }
    async resolveScrollContainerWithRetry() {
      if (!this.chatArea || !this.parserConfig) {
        return null;
      }
      if (!this.parserConfig.getScrollContainer) {
        return this.chatArea;
      }
      return getEleWithRetry(
        () => this.parserConfig?.getScrollContainer?.(this.chatArea) ?? null,
        [],
        true,
        BIND_RETRY_COUNT,
        BIND_RETRY_DELAY
      );
    }
    handleAbnormalState(state2, message, allowAutoRetry = true) {
      this.updateStatus(state2, message);
      if (allowAutoRetry) {
        this.scheduleAutoRetry(message);
      }
    }
    scheduleAutoRetry(message) {
      if (!get(featuresStore).syncScroll || !this.chatArea || !this.parserConfig) {
        return;
      }
      if (this.autoRetryTimer || this.isBinding) {
        return;
      }
      if (this.autoRetryCount >= MAX_AUTO_RETRY_COUNT) {
        this.updateStatus("error", `滚动监听自动重试失败,已达 ${MAX_AUTO_RETRY_COUNT} 次上限`);
        pushPanelNotice(`滚动监听自动重试失败:${message}`, "error");
        return;
      }
      this.autoRetryCount += 1;
      this.autoRetryTimer = setTimeout(async () => {
        this.autoRetryTimer = null;
        const isBound = await this.bindScrollListenerWithRetry(
          `auto-retry-${this.autoRetryCount}`,
          true,
          true
        );
        if (!isBound && this.autoRetryCount >= MAX_AUTO_RETRY_COUNT) {
          this.updateStatus("error", `滚动监听自动重试失败,已达 ${MAX_AUTO_RETRY_COUNT} 次上限`);
          pushPanelNotice(`滚动监听自动重试失败:${message}`, "error");
        }
      }, BIND_RETRY_DELAY);
    }
    clearAutoRetryTimer() {
      if (this.autoRetryTimer) {
        clearTimeout(this.autoRetryTimer);
        this.autoRetryTimer = null;
      }
    }
    clearPostRefreshCheckTimer() {
      if (this.postRefreshCheckTimer) {
        clearTimeout(this.postRefreshCheckTimer);
        this.postRefreshCheckTimer = null;
      }
    }
    async performPostRefreshCheck() {
      if (!get(featuresStore).syncScroll) {
        return;
      }
      if (!this.chatArea || !this.parserConfig) {
        this.updateStatus("warning", "等待聊天区域初始化完成");
        return;
      }
      if (!this.isOutlineReady()) {
        this.updateStatus("syncing", "等待大纲初始化完成");
        return;
      }
      this.rebuildScrollAnchors();
      this.observeVisibleMessages();
      if (this.needsRebind()) {
        this.updateStatus("syncing", "大纲已刷新,正在校正滚动监听绑定");
        await this.bindScrollListenerWithRetry("post-refresh", true, false);
        return;
      }
      this.syncOutlineScroll();
    }
    isOutlineReady() {
      if (!this.outlineContainer) {
        return false;
      }
      if (messageCacheManager.getCache().length === 0) {
        return false;
      }
      return messageCacheManager.getCache().some((item) => Boolean(item.outlineElement));
    }
    needsRebind() {
      return !this.scrollContainer || !this.scrollHandler || this.isBinding;
    }
    triggerInitialSync() {
      if (!this.outlineContainer || !this.scrollContainer || !this.scrollHandler) {
        return;
      }
      setTimeout(() => {
        if (!this.outlineContainer || !this.scrollContainer || !this.scrollHandler) {
          return;
        }
        this.syncOutlineScroll();
      }, 0);
    }
    rebuildScrollAnchors() {
      if (!this.scrollContainer) {
        this.scrollAnchors = [];
        this.anchorOffsetsDirty = true;
        return;
      }
      const nextAnchors = [];
      for (const cachedItem of messageCacheManager.getCache()) {
        if (cachedItem.outlineElement) {
          nextAnchors.push({
            id: cachedItem.outlineItem.id,
            type: "message",
            targetElement: cachedItem.outlineItem.element,
            outlineElement: cachedItem.outlineElement,
            topOffset: 0,
            depth: 0
          });
        }
        if (cachedItem.outlineItem.headers) {
          this.appendHeaderAnchors(cachedItem.outlineItem.headers, nextAnchors);
        }
      }
      this.scrollAnchors = nextAnchors;
      this.anchorOffsetsDirty = true;
      this.refreshAnchorOffsets();
    }
    refreshAnchorOffsets() {
      if (!this.scrollContainer || this.scrollAnchors.length === 0 || !this.anchorOffsetsDirty) {
        return;
      }
      const containerRect = this.scrollContainer.getBoundingClientRect();
      const scrollTop = this.getScrollTop();
      for (const anchor of this.scrollAnchors) {
        const rect = anchor.targetElement.getBoundingClientRect();
        anchor.topOffset = rect.top - containerRect.top + scrollTop;
      }
      this.scrollAnchors.sort((left, right) => {
        if (left.topOffset !== right.topOffset) {
          return left.topOffset - right.topOffset;
        }
        if (left.depth !== right.depth) {
          return left.depth - right.depth;
        }
        return left.type === right.type ? 0 : left.type === "message" ? -1 : 1;
      });
      this.anchorOffsetsDirty = false;
    }
    appendHeaderAnchors(headers, anchors) {
      for (const header of headers) {
        const outlineElement = this.headerOutlineElements.get(header.id);
        if (outlineElement) {
          anchors.push({
            id: header.id,
            type: "header",
            targetElement: header.element,
            outlineElement,
            topOffset: 0,
            depth: header.level
          });
        }
        if (header.children.length > 0) {
          this.appendHeaderAnchors(header.children, anchors);
        }
      }
    }
    observeVisibleMessages() {
      if (!this.scrollContainer || typeof IntersectionObserver === "undefined") {
        return;
      }
      this.disconnectIntersectionObserver();
      this.visibleMessageMetrics.clear();
      const cache = messageCacheManager.getCache();
      if (cache.length === 0) {
        return;
      }
      this.intersectionObserver = new IntersectionObserver(
        (entries) => {
          for (const entry of entries) {
            const messageId = entry.target.getAttribute("cbe-message-id");
            if (!messageId) {
              continue;
            }
            if (!entry.isIntersecting) {
              this.visibleMessageMetrics.delete(messageId);
              continue;
            }
            this.visibleMessageMetrics.set(messageId, {
              top: entry.boundingClientRect.top,
              bottom: entry.boundingClientRect.bottom
            });
          }
        },
        {
          root: this.scrollContainer,
          threshold: [0, 0.1, 0.5],
          rootMargin: "0px 0px -60% 0px"
        }
      );
      for (const item of cache) {
        this.intersectionObserver.observe(item.outlineItem.element);
      }
    }
    disconnectIntersectionObserver() {
      if (this.intersectionObserver) {
        this.intersectionObserver.disconnect();
        this.intersectionObserver = null;
      }
      this.visibleMessageMetrics.clear();
    }
    unbindScrollListener() {
      if (this.scrollHandler && this.scrollContainer) {
        this.scrollContainer.removeEventListener("scroll", this.scrollHandler);
        logger$1.debug("解绑滚动监听");
      }
      if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
        this.debounceTimer = null;
      }
      if (this.rebuildScrollAnchorsTimer) {
        clearTimeout(this.rebuildScrollAnchorsTimer);
        this.rebuildScrollAnchorsTimer = null;
      }
      this.scrollHandler = null;
    }
    findVisibleMessageIndex() {
      const observedIndex = this.findVisibleMessageIndexFromObserver();
      if (observedIndex !== -1) {
        this.lastVisibleIndex = observedIndex;
        return observedIndex;
      }
      if (!this.scrollContainer) {
        return -1;
      }
      const containerTop = this.scrollContainer.getBoundingClientRect().top + 10;
      const cache = messageCacheManager.getCache();
      if (cache.length === 0) {
        this.lastVisibleIndex = -1;
        return -1;
      }
      const nearIndex = this.findVisibleMessageIndexNear(cache, containerTop);
      if (nearIndex !== -1) {
        this.lastVisibleIndex = nearIndex;
        return nearIndex;
      }
      const fallbackIndex = this.findVisibleMessageIndexFull(cache, containerTop);
      this.lastVisibleIndex = fallbackIndex;
      return fallbackIndex;
    }
    findActiveAnchor() {
      if (!this.scrollContainer || this.scrollAnchors.length === 0) {
        return null;
      }
      this.refreshAnchorOffsets();
      const currentTop = this.getScrollTop() + Math.max(24, this.getContainerClientHeight() * 0.18);
      let left = 0;
      let right = this.scrollAnchors.length - 1;
      let answer = -1;
      while (left <= right) {
        const middle = Math.floor((left + right) / 2);
        if (this.scrollAnchors[middle].topOffset <= currentTop) {
          answer = middle;
          left = middle + 1;
        } else {
          right = middle - 1;
        }
      }
      if (answer === -1) {
        return this.scrollAnchors[0] || null;
      }
      return this.refineActiveAnchor(answer, currentTop);
    }
    refineActiveAnchor(index2, currentTop) {
      let bestAnchor = this.scrollAnchors[index2] || null;
      if (!bestAnchor) {
        return null;
      }
      const tolerance = 36;
      for (let current = index2 + 1; current < this.scrollAnchors.length; current++) {
        const candidate = this.scrollAnchors[current];
        if (candidate.topOffset > currentTop + tolerance) {
          break;
        }
        if (candidate.type === "header" && candidate.depth >= bestAnchor.depth) {
          bestAnchor = candidate;
        }
      }
      return bestAnchor;
    }
    findVisibleMessageIndexFromObserver() {
      if (!this.scrollContainer || this.visibleMessageMetrics.size === 0) {
        return -1;
      }
      const rootTop = this.scrollContainer.getBoundingClientRect().top + 10;
      let targetMessageId = null;
      let targetTop = Number.POSITIVE_INFINITY;
      for (const [messageId, metrics] of this.visibleMessageMetrics.entries()) {
        if (metrics.bottom <= rootTop) {
          continue;
        }
        if (metrics.top < targetTop) {
          targetTop = metrics.top;
          targetMessageId = messageId;
        }
      }
      return messageCacheManager.getCacheIndexByMessageId(targetMessageId);
    }
    findVisibleMessageIndexNear(cache, containerTop) {
      if (this.lastVisibleIndex < 0 || this.lastVisibleIndex >= cache.length) {
        return -1;
      }
      const maxOffset = 5;
      const start = Math.max(0, this.lastVisibleIndex - maxOffset);
      const end = Math.min(cache.length - 1, this.lastVisibleIndex + maxOffset);
      for (let index2 = start; index2 <= end; index2++) {
        const rect = cache[index2].outlineItem.element.getBoundingClientRect();
        if (rect.top >= containerTop || rect.bottom > containerTop) {
          return index2;
        }
      }
      return -1;
    }
    findVisibleMessageIndexFull(cache, containerTop) {
      for (let index2 = 0; index2 < cache.length; index2++) {
        const rect = cache[index2].outlineItem.element.getBoundingClientRect();
        if (rect.top >= containerTop || rect.bottom > containerTop) {
          return index2;
        }
      }
      return -1;
    }
    scrollToOutlineItem(index2) {
      const outlineElement = messageCacheManager.getOutlineElementByIndex(index2);
      if (!outlineElement || !this.outlineContainer) {
        return;
      }
      if (this.lastHighlightElement === outlineElement) {
        this.updateStatus("ready", `滚动监听已成功绑定,最近同步到第 ${index2 + 1} 条消息`);
        return;
      }
      logger$1.debug("scroll to ", outlineElement);
      this.isSyncing = true;
      this.updateStatus("syncing", `滚动监听已触发,正在同步第 ${index2 + 1} 条消息`);
      this.applyOutlineFocus(outlineElement);
      setTimeout(() => {
        this.isSyncing = false;
        this.updateStatus("ready", `滚动监听已成功绑定,最近同步到第 ${index2 + 1} 条消息`);
      }, 300);
    }
    scrollToOutlineAnchor(anchor) {
      if (this.lastHighlightElement === anchor.outlineElement) {
        this.updateStatus("ready", `滚动监听已成功绑定,最近同步到${anchor.type === "header" ? "标题" : "消息"}锚点`);
        return;
      }
      this.isSyncing = true;
      this.updateStatus("syncing", `滚动监听已触发,正在同步到${anchor.type === "header" ? "标题" : "消息"}锚点`);
      this.applyOutlineFocus(anchor.outlineElement);
      setTimeout(() => {
        this.isSyncing = false;
        this.updateStatus("ready", `滚动监听已成功绑定,最近同步到${anchor.type === "header" ? "标题" : "消息"}锚点`);
      }, 300);
    }
    applyOutlineFocus(outlineElement) {
      this.lastHighlightElement = outlineElement;
      if (this.highlightTimer) {
        clearTimeout(this.highlightTimer);
      }
      if (this.currentHighlightedElement) {
        this.currentHighlightedElement.classList.remove("outline-active");
      }
      outlineElement.classList.add("outline-active");
      this.currentHighlightedElement = outlineElement;
      this.highlightTimer = setTimeout(() => {
        if (this.currentHighlightedElement) {
          this.currentHighlightedElement.classList.remove("outline-active");
          this.currentHighlightedElement = null;
        }
      }, 1e3);
      outlineElement.scrollIntoView({ behavior: "smooth", block: "center" });
    }
    getScrollTop() {
      return this.scrollContainer?.scrollTop || 0;
    }
    getContainerClientHeight() {
      return this.scrollContainer?.clientHeight || 0;
    }
    updateStatus(state2, message) {
      setServiceStatus("scrollSync", {
        state: state2,
        message
      });
    }
  }
  const scrollSyncService = new ScrollSyncService();
  var root_2$5 = from_html(`<span class="bookmark-indicator svelte-2xi3vq">🔖</span>`);
  var root_3$3 = from_html(`<button class="toggle-btn svelte-2xi3vq"> </button>`);
  var root_1$8 = from_html(`<div class="tree-node-wrapper"><div role="button" tabindex="0"><span class="node-text svelte-2xi3vq"><!> </span> <!></div> <!></div>`);
  var root$7 = from_html(`<div class="tree-container svelte-2xi3vq"></div>`);
  function HeaderTree_1($$anchor, $$props) {
    push($$props, true);
    let depth = prop($$props, "depth", 3, 0), allExpanded = prop($$props, "allExpanded", 3, true), parentMessageIndex = prop($$props, "parentMessageIndex", 3, 0), parentMessageText = prop($$props, "parentMessageText", 3, ""), parentMessageHash = prop($$props, "parentMessageHash", 3, ""), currentPath = prop($$props, "currentPath", 3, ""), headerBookmarks = prop($$props, "headerBookmarks", 19, () => new Set());
    let expandedStates = proxy({});
    user_effect(() => {
      if (allExpanded() !== void 0) {
        $$props.nodes.forEach((node) => {
          if (expandedStates[node.id] !== allExpanded()) {
            expandedStates[node.id] = allExpanded();
          }
        });
      }
    });
    function toggleExpand(nodeId, e) {
      e.stopPropagation();
      expandedStates[nodeId] = !expandedStates[nodeId];
    }
    function scrollToElement(element, e) {
      e.stopPropagation();
      scrollSyncService.focusOutlineElement(e.currentTarget);
      element.scrollIntoView({ behavior: "smooth", block: "start" });
      highlightElement(element);
    }
    function handleContextMenu(e, node, nodePath) {
      e.preventDefault();
      if ($$props.onContextMenu) {
        $$props.onContextMenu(e, {
          outlineItemType: "header",
          messageIndex: parentMessageIndex(),
          messageText: parentMessageText(),
          messageHash: parentMessageHash(),
          headerPath: nodePath,
          headerText: node.text
        });
      }
    }
    function registerNode(element, nodeId) {
      scrollSyncService.registerHeaderOutlineElement(nodeId, element);
      return {
        destroy() {
          scrollSyncService.unregisterHeaderOutlineElement(nodeId);
        }
      };
    }
    function hasHeaderBookmark(nodePath) {
      return headerBookmarks().has(nodePath);
    }
    function buildChildPath(index2) {
      if (currentPath()) {
        return `${currentPath()}.${index2}`;
      }
      return `${index2}`;
    }
    var div = root$7();
    each(div, 21, () => $$props.nodes, index, ($$anchor2, node, index2) => {
      const nodePath = user_derived(() => buildChildPath(index2));
      var div_1 = root_1$8();
      var div_2 = child(div_1);
      let classes;
      var span = child(div_2);
      var node_1 = child(span);
      {
        var consequent = ($$anchor3) => {
          var span_1 = root_2$5();
          append($$anchor3, span_1);
        };
        var d = user_derived(() => hasHeaderBookmark(get$1(nodePath)));
        if_block(node_1, ($$render) => {
          if (get$1(d)) $$render(consequent);
        });
      }
      var text2 = sibling(node_1);
      var node_2 = sibling(span, 2);
      {
        var consequent_1 = ($$anchor3) => {
          var button = root_3$3();
          var text_1 = child(button);
          template_effect(() => {
            set_attribute(button, "aria-label", expandedStates[get$1(node).id] ? "收起" : "展开");
            set_text(text_1, expandedStates[get$1(node).id] ? "▼" : "▶");
          });
          delegated("click", button, (e) => toggleExpand(get$1(node).id, e));
          append($$anchor3, button);
        };
        if_block(node_2, ($$render) => {
          if (get$1(node).children.length > 0) $$render(consequent_1);
        });
      }
      action(div_2, ($$node, $$action_arg) => registerNode?.($$node, $$action_arg), () => get$1(node).id);
      var node_3 = sibling(div_2, 2);
      {
        var consequent_2 = ($$anchor3) => {
          {
            let $0 = user_derived(() => depth() + 1);
            HeaderTree_1($$anchor3, {
              get nodes() {
                return get$1(node).children;
              },
              get depth() {
                return get$1($0);
              },
              get allExpanded() {
                return allExpanded();
              },
              get onContextMenu() {
                return $$props.onContextMenu;
              },
              get parentMessageIndex() {
                return parentMessageIndex();
              },
              get parentMessageText() {
                return parentMessageText();
              },
              get parentMessageHash() {
                return parentMessageHash();
              },
              get currentPath() {
                return get$1(nodePath);
              },
              get headerBookmarks() {
                return headerBookmarks();
              }
            });
          }
        };
        if_block(node_3, ($$render) => {
          if (get$1(node).children.length > 0 && expandedStates[get$1(node).id]) $$render(consequent_2);
        });
      }
      template_effect(
        ($0) => {
          classes = set_class(div_2, 1, `tree-node header-level-${get$1(node).level ?? ""}`, "svelte-2xi3vq", classes, $0);
          set_text(text2, ` ${get$1(node).text ?? ""}`);
        },
        [
          () => ({ "has-bookmark": hasHeaderBookmark(get$1(nodePath)) })
        ]
      );
      delegated("click", div_2, (e) => scrollToElement(get$1(node).element, e));
      delegated("contextmenu", div_2, (e) => handleContextMenu(e, get$1(node), get$1(nodePath)));
      delegated("keydown", div_2, (e) => e.key === "Enter" && scrollToElement(get$1(node).element, e));
      append($$anchor2, div_1);
    });
    template_effect(() => set_style(div, `margin-left: ${depth() * 15}px;`));
    append($$anchor, div);
    pop();
  }
  delegate(["click", "contextmenu", "keydown"]);
  var root_2$4 = from_html(`<span class="bookmark-indicator svelte-1iqb61w">🔖</span>`);
  var root_1$7 = from_html(`<div role="button" tabindex="0"><!> </div>`);
  var root_5 = from_html(`<span class="bookmark-indicator svelte-1iqb61w">🔖</span>`);
  var root_6 = from_html(`<div class="outline-ai-content svelte-1iqb61w"><!></div>`);
  var root_4$1 = from_html(`<div class="outline-ai-container svelte-1iqb61w"><div role="button" tabindex="0"><span class="header-text svelte-1iqb61w"><!> </span> <button class="toggle-btn svelte-1iqb61w"> </button></div> <!></div>`);
  var root_8 = from_html(`<span class="bookmark-indicator svelte-1iqb61w">🔖</span>`);
  var root_7 = from_html(`<div role="button" tabindex="0"><!> </div>`);
  function OutlineItem($$anchor, $$props) {
    push($$props, true);
    let allExpanded = prop($$props, "allExpanded", 3, true), hasBookmark = prop($$props, "hasBookmark", 3, false), headerBookmarks = prop($$props, "headerBookmarks", 19, () => new Set());
    let isExpanded = state(true);
    let containerElement = state(void 0);
    function scrollToElement() {
      scrollSyncService.focusOutlineElement(get$1(containerElement));
      $$props.item.element.scrollIntoView({ behavior: "smooth", block: "start" });
      highlightElement($$props.item.element);
    }
    function handleKeydown(e) {
      if (e.key === "Enter") {
        scrollToElement();
      }
    }
    function toggleExpand(e) {
      e.stopPropagation();
      set(isExpanded, !get$1(isExpanded));
    }
    function handleContextMenu(e) {
      e.preventDefault();
      if ($$props.onContextMenu) {
        const hash = buildMessageHash($$props.item.index, $$props.item.searchText);
        $$props.onContextMenu(e, {
          outlineItemType: "message",
          messageIndex: $$props.item.index,
          messageText: $$props.item.searchText,
          messageHash: hash
        });
      }
    }
    user_effect(() => {
      set(isExpanded, allExpanded());
    });
    user_effect(() => {
      if (get$1(containerElement) && $$props.item.id) {
        messageCacheManager.updateOutlineElement($$props.item.id, get$1(containerElement));
        scrollSyncService.scheduleRebuildScrollAnchors();
      }
    });
    var fragment = comment();
    var node = first_child(fragment);
    {
      var consequent_1 = ($$anchor2) => {
        var div = root_1$7();
        let classes;
        var node_1 = child(div);
        {
          var consequent = ($$anchor3) => {
            var span = root_2$4();
            append($$anchor3, span);
          };
          if_block(node_1, ($$render) => {
            if (hasBookmark()) $$render(consequent);
          });
        }
        var text2 = sibling(node_1);
        bind_this(div, ($$value) => set(containerElement, $$value), () => get$1(containerElement));
        template_effect(() => {
          classes = set_class(div, 1, "outline-user-item svelte-1iqb61w", null, classes, { "has-bookmark": hasBookmark() });
          set_text(text2, ` 👤 ${$$props.item.index + 1}. ${$$props.item.text ?? ""}`);
        });
        delegated("click", div, scrollToElement);
        delegated("keydown", div, handleKeydown);
        delegated("contextmenu", div, handleContextMenu);
        append($$anchor2, div);
      };
      var consequent_6 = ($$anchor2) => {
        var fragment_1 = comment();
        var node_2 = first_child(fragment_1);
        {
          var consequent_4 = ($$anchor3) => {
            var div_1 = root_4$1();
            var div_2 = child(div_1);
            let classes_1;
            var span_1 = child(div_2);
            var node_3 = child(span_1);
            {
              var consequent_2 = ($$anchor4) => {
                var span_2 = root_5();
                append($$anchor4, span_2);
              };
              if_block(node_3, ($$render) => {
                if (hasBookmark()) $$render(consequent_2);
              });
            }
            var text_1 = sibling(node_3);
            var button = sibling(span_1, 2);
            var text_2 = child(button);
            var node_4 = sibling(div_2, 2);
            {
              var consequent_3 = ($$anchor4) => {
                var div_3 = root_6();
                var node_5 = child(div_3);
                {
                  let $0 = user_derived(() => buildMessageHash($$props.item.index, $$props.item.searchText));
                  HeaderTree_1(node_5, {
                    get nodes() {
                      return $$props.item.headers;
                    },
                    get allExpanded() {
                      return allExpanded();
                    },
                    get onContextMenu() {
                      return $$props.onContextMenu;
                    },
                    get parentMessageIndex() {
                      return $$props.item.index;
                    },
                    get parentMessageText() {
                      return $$props.item.searchText;
                    },
                    get parentMessageHash() {
                      return get$1($0);
                    },
                    get headerBookmarks() {
                      return headerBookmarks();
                    }
                  });
                }
                append($$anchor4, div_3);
              };
              if_block(node_4, ($$render) => {
                if (get$1(isExpanded)) $$render(consequent_3);
              });
            }
            bind_this(div_1, ($$value) => set(containerElement, $$value), () => get$1(containerElement));
            template_effect(() => {
              classes_1 = set_class(div_2, 1, "outline-ai-header svelte-1iqb61w", null, classes_1, { "has-bookmark": hasBookmark() });
              set_text(text_1, ` 🤖 ${$$props.item.index + 1}. ${$$props.item.text ?? ""}`);
              set_attribute(button, "aria-label", get$1(isExpanded) ? "收起" : "展开");
              set_text(text_2, get$1(isExpanded) ? "▼" : "▶");
            });
            delegated("click", div_2, scrollToElement);
            delegated("keydown", div_2, handleKeydown);
            delegated("contextmenu", div_2, handleContextMenu);
            delegated("click", button, toggleExpand);
            append($$anchor3, div_1);
          };
          var alternate = ($$anchor3) => {
            var div_4 = root_7();
            let classes_2;
            var node_6 = child(div_4);
            {
              var consequent_5 = ($$anchor4) => {
                var span_3 = root_8();
                append($$anchor4, span_3);
              };
              if_block(node_6, ($$render) => {
                if (hasBookmark()) $$render(consequent_5);
              });
            }
            var text_3 = sibling(node_6);
            bind_this(div_4, ($$value) => set(containerElement, $$value), () => get$1(containerElement));
            template_effect(() => {
              classes_2 = set_class(div_4, 1, "outline-ai-item svelte-1iqb61w", null, classes_2, { "has-bookmark": hasBookmark() });
              set_text(text_3, ` 🤖 ${$$props.item.index ?? ""}. ${$$props.item.text ?? ""}`);
            });
            delegated("click", div_4, scrollToElement);
            delegated("keydown", div_4, handleKeydown);
            delegated("contextmenu", div_4, handleContextMenu);
            append($$anchor3, div_4);
          };
          if_block(node_2, ($$render) => {
            if ($$props.item.headers && $$props.item.headers.length > 0) $$render(consequent_4);
            else $$render(alternate, false);
          });
        }
        append($$anchor2, fragment_1);
      };
      if_block(node, ($$render) => {
        if ($$props.item.type === MessageOwner.User) $$render(consequent_1);
        else if ($$props.item.type === MessageOwner.Assistant) $$render(consequent_6, 1);
      });
    }
    append($$anchor, fragment);
    pop();
  }
  delegate(["click", "keydown", "contextmenu"]);
  var root$6 = from_html(`<div class="outline-content svelte-13g9af" id="outline-content"></div>`);
  function OutlineList($$anchor, $$props) {
    push($$props, true);
    const $bookmarksStore = () => store_get(bookmarksStore, "$bookmarksStore", $$stores);
    const [$$stores, $$cleanup] = setup_stores();
    let filterText = prop($$props, "filterText", 3, ""), useRegex = prop($$props, "useRegex", 3, false);
    let items = state(proxy([]));
    let allExpanded = state(true);
    let outlineContainer;
    let messageBookmarks = state(proxy( new Set()));
    let headerBookmarks = state(proxy( new Map()));
    user_effect(() => {
      const storeData = $bookmarksStore();
      const conversationId = getConversationId();
      const convData = conversationId ? storeData[conversationId] : void 0;
      const bookmarks = convData?.bookmarks || [];
      const msgBookmarks = new Set();
      const hdrBookmarks = new Map();
      for (const bookmark of bookmarks) {
        if (bookmark.outlineItemType === "message") {
          msgBookmarks.add(bookmark.messageIndex);
        } else if (bookmark.outlineItemType === "header" && bookmark.headerPath) {
          let headerSet = hdrBookmarks.get(bookmark.messageIndex);
          if (!headerSet) {
            headerSet = new Set();
            hdrBookmarks.set(bookmark.messageIndex, headerSet);
          }
          headerSet.add(bookmark.headerPath);
        }
      }
      set(messageBookmarks, msgBookmarks, true);
      set(headerBookmarks, hdrBookmarks, true);
    });
    function filterItems(items2, filter, regex) {
      if (!filter) return items2;
      if (regex) {
        try {
          const reg = new RegExp(filter, "i");
          return items2.filter((item) => reg.test(item.searchText));
        } catch {
          return items2;
        }
      }
      return items2.filter((item) => {
        return item.searchText.toLocaleLowerCase().includes(filter.toLocaleLowerCase());
      });
    }
    let showItems = user_derived(() => {
      return filterItems(get$1(items), filterText(), useRegex());
    });
    onMount(() => {
      const unsubscribeOutline = outlineStore.subscribe((value) => {
        set(items, value, true);
      });
      const unsubscribeAllExpanded = allExpandedStore.subscribe((value) => {
        set(allExpanded, value, true);
      });
      set(items, get(outlineStore), true);
      set(allExpanded, get(allExpandedStore), true);
      if (outlineContainer) {
        scrollSyncService.setOutlineContainer(outlineContainer);
      }
      return () => {
        unsubscribeOutline();
        unsubscribeAllExpanded();
      };
    });
    var div = root$6();
    each(div, 21, () => get$1(showItems), (item) => item.id, ($$anchor2, item) => {
      {
        let $0 = user_derived(() => get$1(messageBookmarks).has(get$1(item).index));
        let $1 = user_derived(() => get$1(headerBookmarks).get(get$1(item).index) || new Set());
        OutlineItem($$anchor2, {
          get item() {
            return get$1(item);
          },
          get allExpanded() {
            return get$1(allExpanded);
          },
          get onContextMenu() {
            return $$props.onContextMenu;
          },
          get hasBookmark() {
            return get$1($0);
          },
          get headerBookmarks() {
            return get$1($1);
          }
        });
      }
    });
    bind_this(div, ($$value) => outlineContainer = $$value, () => outlineContainer);
    append($$anchor, div);
    pop();
    $$cleanup();
  }
  var root$5 = from_html(`<button id="show-outline-btn">📋</button>`);
  function DraggableToggleButton($$anchor, $$props) {
    push($$props, true);
    let title = prop($$props, "title", 3, "显示对话大纲"), ariaLabel = prop($$props, "ariaLabel", 3, "显示对话大纲");
    const STORAGE_KEY2 = "chat_outline_button_position";
    const BUTTON_SIZE = 40;
    let positionY = state(
      50
);
    let isDragging = state(false);
    let dragStartY = state(0);
    let initialPositionY = state(0);
    function loadPosition() {
      try {
        const saved = localStorage.getItem(STORAGE_KEY2);
        if (saved) {
          const parsed = JSON.parse(saved);
          if (typeof parsed.y === "number") {
            set(positionY, Math.max(0, Math.min(100, parsed.y)), true);
          }
        }
      } catch (e) {
        logger$1.warn("Failed to load button position:", e);
      }
    }
    function savePosition() {
      try {
        localStorage.setItem(STORAGE_KEY2, JSON.stringify({ y: get$1(positionY) }));
      } catch (e) {
        logger$1.warn("Failed to save button position:", e);
      }
    }
    function handleMouseDown(event2) {
      set(isDragging, true);
      set(dragStartY, event2.clientY, true);
      set(initialPositionY, get$1(positionY), true);
      window.addEventListener("mousemove", handleMouseMove);
      window.addEventListener("mouseup", handleMouseUp);
      event2.preventDefault();
    }
    function handleTouchStart(event2) {
      set(isDragging, true);
      set(dragStartY, event2.touches[0].clientY, true);
      set(initialPositionY, get$1(positionY), true);
      window.addEventListener("touchmove", handleTouchMove, { passive: false });
      window.addEventListener("touchend", handleTouchEnd);
      event2.preventDefault();
    }
    function handleMouseMove(event2) {
      if (!get$1(isDragging)) return;
      updatePosition(event2.clientY);
    }
    function handleTouchMove(event2) {
      if (!get$1(isDragging)) return;
      updatePosition(event2.touches[0].clientY);
      event2.preventDefault();
    }
    function updatePosition(clientY) {
      const deltaY = clientY - get$1(dragStartY);
      const viewportHeight = window.innerHeight;
      const deltaPercent = deltaY / viewportHeight * 100;
      let newPosition = get$1(initialPositionY) + deltaPercent;
      const minPosition = BUTTON_SIZE / 2 / viewportHeight * 100;
      const maxPosition = 100 - BUTTON_SIZE / 2 / viewportHeight * 100;
      set(positionY, Math.max(minPosition, Math.min(maxPosition, newPosition)), true);
    }
    function handleMouseUp() {
      if (get$1(isDragging)) {
        set(isDragging, false);
        savePosition();
        cleanupListeners();
      }
    }
    function handleTouchEnd() {
      if (get$1(isDragging)) {
        set(isDragging, false);
        savePosition();
        cleanupListeners();
      }
    }
    function cleanupListeners() {
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", handleMouseUp);
      window.removeEventListener("touchmove", handleTouchMove);
      window.removeEventListener("touchend", handleTouchEnd);
    }
    let dragThreshold = 5;
    let hasDragged = state(false);
    function handleClick() {
      if (!get$1(hasDragged)) {
        $$props.onClick();
      }
    }
    user_effect(() => {
      if (get$1(isDragging)) {
        set(hasDragged, false);
      }
    });
    user_effect(() => {
      if (get$1(isDragging) && Math.abs(get$1(positionY) - get$1(initialPositionY)) > dragThreshold) {
        set(hasDragged, true);
      }
    });
    function handleResize() {
      const viewportHeight = window.innerHeight;
      const minPosition = BUTTON_SIZE / 2 / viewportHeight * 100;
      const maxPosition = 100 - BUTTON_SIZE / 2 / viewportHeight * 100;
      if (get$1(positionY) < minPosition) {
        set(positionY, minPosition);
        savePosition();
      } else if (get$1(positionY) > maxPosition) {
        set(positionY, maxPosition);
        savePosition();
      }
    }
    onMount(() => {
      loadPosition();
      window.addEventListener("resize", handleResize);
    });
    onDestroy(() => {
      cleanupListeners();
      window.removeEventListener("resize", handleResize);
    });
    var button = root$5();
    let classes;
    template_effect(() => {
      classes = set_class(button, 1, "draggable-toggle-button svelte-nihy1m", null, classes, { "is-dragging": get$1(isDragging) });
      set_style(button, `top: ${get$1(positionY) ?? ""}%; transform: translateY(-50%)`);
      set_attribute(button, "title", title());
      set_attribute(button, "aria-label", ariaLabel());
    });
    delegated("click", button, handleClick);
    delegated("mousedown", button, handleMouseDown);
    delegated("touchstart", button, handleTouchStart);
    append($$anchor, button);
    pop();
  }
  delegate(["click", "mousedown", "touchstart"]);
  var root_2$3 = from_html(`<div role="status" aria-live="polite"><span class="notice-text svelte-1xjbolr"> </span> <button class="notice-close svelte-1xjbolr" type="button" aria-label="关闭提示">×</button></div>`);
  var root_1$6 = from_html(`<div class="panel-notice-stack svelte-1xjbolr"></div>`);
  function PanelNoticeStack($$anchor, $$props) {
    push($$props, true);
    let notices = state(proxy([]));
    const classMap = {
      info: "notice-info",
      success: "notice-success",
      warning: "notice-warning",
      error: "notice-error"
    };
    onMount(() => {
      const unsubscribe = panelNoticeStore.subscribe((value) => {
        set(notices, value, true);
      });
      set(notices, get(panelNoticeStore), true);
      return () => {
        unsubscribe();
      };
    });
    var fragment = comment();
    var node = first_child(fragment);
    {
      var consequent = ($$anchor2) => {
        var div = root_1$6();
        each(div, 21, () => get$1(notices), (notice) => notice.id, ($$anchor3, notice) => {
          var div_1 = root_2$3();
          var span = child(div_1);
          var text2 = child(span);
          var button = sibling(span, 2);
          template_effect(() => {
            set_class(div_1, 1, `panel-notice ${classMap[get$1(notice).level]}`, "svelte-1xjbolr");
            set_text(text2, get$1(notice).message);
          });
          delegated("click", button, () => removePanelNotice(get$1(notice).id));
          append($$anchor3, div_1);
        });
        append($$anchor2, div);
      };
      if_block(node, ($$render) => {
        if (get$1(notices).length > 0) $$render(consequent);
      });
    }
    append($$anchor, fragment);
    pop();
  }
  delegate(["click"]);
  var root_1$5 = from_html(`<button class="status-dot-button svelte-5fnl0z" type="button"><span class="status-light svelte-5fnl0z"></span></button>`);
  var root$4 = from_html(`<div class="service-status-bar svelte-5fnl0z" aria-label="服务状态栏"></div>`);
  function ServiceStatusBar($$anchor, $$props) {
    push($$props, true);
    let items = state(proxy([]));
    const colorMap = {
      idle: "#94a3b8",
      ready: "#22c55e",
      warning: "#f59e0b",
      error: "#ef4444",
      syncing: "#3b82f6"
    };
    onMount(() => {
      const unsubscribe = serviceStatusStore.subscribe((status) => {
        set(items, [status.outlineRuntime, status.scrollSync], true);
      });
      const current = get(serviceStatusStore);
      set(items, [current.outlineRuntime, current.scrollSync], true);
      return () => {
        unsubscribe();
      };
    });
    function getTooltip(item) {
      const time = new Date(item.updatedAt).toLocaleTimeString();
      return `${item.label}:${item.message}(最近更新 ${time},点击可重新获取并绑定)`;
    }
    async function handleClick(item) {
      if (item.key === "outlineRuntime") {
        await outlineRuntimeService.forceRebind();
        return;
      }
      scrollSyncService.forceRebind();
    }
    var div = root$4();
    each(div, 21, () => get$1(items), (item) => item.key, ($$anchor2, item) => {
      var button = root_1$5();
      var span = child(button);
      template_effect(
        ($0, $1) => {
          set_attribute(button, "title", $0);
          set_attribute(button, "aria-label", $1);
          set_style(span, `--status-color: ${colorMap[get$1(item).state]}`);
        },
        [() => getTooltip(get$1(item)), () => getTooltip(get$1(item))]
      );
      delegated("click", button, () => handleClick(get$1(item)));
      append($$anchor2, button);
    });
    append($$anchor, div);
    pop();
  }
  delegate(["click"]);
  var root_1$4 = from_html(`<div class="empty-state svelte-1dp0ytt"><span class="empty-icon svelte-1dp0ytt">📚</span> <p class="svelte-1dp0ytt">暂无书签</p> <p class="hint svelte-1dp0ytt">在大纲上右键可添加书签</p></div>`);
  var root_3$2 = from_html(`<div class="bookmark-item svelte-1dp0ytt" role="button" tabindex="0"><span class="bookmark-icon svelte-1dp0ytt"><!></span> <span class="bookmark-name svelte-1dp0ytt"> </span> <span class="bookmark-meta svelte-1dp0ytt"> </span></div>`);
  var root_2$2 = from_html(`<div class="bookmark-list svelte-1dp0ytt"></div>`);
  function BookmarkList($$anchor, $$props) {
    push($$props, true);
    function formatDate(timestamp) {
      const date = new Date(timestamp);
      const now = new Date();
      const diffMs = now.getTime() - date.getTime();
      const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
      if (diffDays === 0) {
        return date.toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" });
      } else if (diffDays === 1) {
        return "昨天";
      } else if (diffDays < 7) {
        return `${diffDays}天前`;
      } else {
        return date.toLocaleDateString("zh-CN", { month: "short", day: "numeric" });
      }
    }
    function handleClick(bookmark) {
      $$props.onNavigate?.(bookmark, $$props.conversationId);
    }
    function handleContextMenu(e, bookmark) {
      e.preventDefault();
      $$props.onContextMenu?.(e, bookmark, $$props.conversationId);
    }
    function handleKeydown(e, bookmark) {
      if (e.key === "Enter") {
        handleClick(bookmark);
      }
    }
    var fragment = comment();
    var node = first_child(fragment);
    {
      var consequent = ($$anchor2) => {
        var div = root_1$4();
        append($$anchor2, div);
      };
      var alternate_1 = ($$anchor2) => {
        var div_1 = root_2$2();
        each(div_1, 21, () => $$props.bookmarks, (bookmark) => bookmark.id, ($$anchor3, bookmark) => {
          var div_2 = root_3$2();
          var span = child(div_2);
          var node_1 = child(span);
          {
            var consequent_1 = ($$anchor4) => {
              var text$1 = text("📑");
              append($$anchor4, text$1);
            };
            var alternate = ($$anchor4) => {
              var text_1 = text("🔖");
              append($$anchor4, text_1);
            };
            if_block(node_1, ($$render) => {
              if (get$1(bookmark).outlineItemType === "header") $$render(consequent_1);
              else $$render(alternate, false);
            });
          }
          var span_1 = sibling(span, 2);
          var text_2 = child(span_1);
          var span_2 = sibling(span_1, 2);
          var text_3 = child(span_2);
          template_effect(
            ($0) => {
              set_text(text_2, get$1(bookmark).name);
              set_text(text_3, `#${get$1(bookmark).messageIndex + 1} · ${$0 ?? ""}`);
            },
            [() => formatDate(get$1(bookmark).createdAt)]
          );
          delegated("click", div_2, () => handleClick(get$1(bookmark)));
          delegated("contextmenu", div_2, (e) => handleContextMenu(e, get$1(bookmark)));
          delegated("keydown", div_2, (e) => handleKeydown(e, get$1(bookmark)));
          append($$anchor3, div_2);
        });
        append($$anchor2, div_1);
      };
      if_block(node, ($$render) => {
        if ($$props.bookmarks.length === 0) $$render(consequent);
        else $$render(alternate_1, false);
      });
    }
    append($$anchor, fragment);
    pop();
  }
  delegate(["click", "contextmenu", "keydown"]);
  const contextMenuState = writable({
    visible: false,
    x: 0,
    y: 0,
    items: [],
    context: null,
    bookmark: null,
    conversationId: null
  });
  const addBookmarkModalState = writable({
    visible: false,
    context: null
  });
  const renameBookmarkModalState = writable({
    visible: false,
    bookmark: null
  });
  function showContextMenu(event2, context) {
    event2.preventDefault();
    event2.stopPropagation();
    let hasBookmark = false;
    let existingBookmark;
    if (context.outlineItemType === "header") {
      hasBookmark = bookmarksStore.hasBookmarkForHeader(context.messageIndex, context.headerPath || "");
      existingBookmark = bookmarksStore.getBookmarkByHeaderPath(context.messageIndex, context.headerPath || "");
    } else {
      hasBookmark = bookmarksStore.hasBookmarkForMessageIndex(context.messageIndex);
      existingBookmark = bookmarksStore.getBookmarkByMessageIndex(context.messageIndex);
    }
    const items = [];
    if (hasBookmark && existingBookmark) {
      items.push({
        id: "delete",
        label: "删除书签",
        icon: "🗑️",
        danger: true
      });
      items.push({
        id: "rename",
        label: "重命名",
        icon: "✏️"
      });
    } else {
      items.push({
        id: "add",
        label: "添加书签",
        icon: "🔖"
      });
    }
    contextMenuState.set({
      visible: true,
      x: event2.clientX,
      y: event2.clientY,
      items,
      context,
      bookmark: existingBookmark ?? null,
      conversationId: getConversationId()
    });
  }
  function showBookmarkContextMenu(event2, bookmark, conversationId) {
    event2.preventDefault();
    event2.stopPropagation();
    const items = [
      {
        id: "navigate",
        label: "跳转到书签",
        icon: "📍"
      },
      {
        id: "rename",
        label: "重命名",
        icon: "✏️"
      },
      {
        id: "delete",
        label: "删除书签",
        icon: "🗑️",
        danger: true
      }
    ];
    contextMenuState.set({
      visible: true,
      x: event2.clientX,
      y: event2.clientY,
      items,
      context: null,
      bookmark,
      conversationId
    });
  }
  function hideContextMenu() {
    contextMenuState.set({
      visible: false,
      x: 0,
      y: 0,
      items: [],
      context: null,
      bookmark: null,
      conversationId: null
    });
  }
  function handleMenuSelect(itemId) {
    const state2 = get(contextMenuState);
    const resultBookmark = state2.bookmark ? state2.bookmark : void 0;
    const result = {
      action: itemId,
      bookmark: resultBookmark,
      conversationId: state2.conversationId ?? void 0
    };
    switch (itemId) {
      case "add":
        if (state2.context) {
          addBookmarkModalState.set({
            visible: true,
            context: state2.context
          });
        }
        break;
      case "delete":
        if (state2.bookmark) {
          bookmarksStore.removeBookmark(state2.bookmark.id);
        } else if (state2.context) {
          let bookmark;
          if (state2.context.outlineItemType === "header") {
            bookmark = bookmarksStore.getBookmarkByHeaderPath(state2.context.messageIndex, state2.context.headerPath || "");
          } else {
            bookmark = bookmarksStore.getBookmarkByMessageIndex(state2.context.messageIndex);
          }
          if (bookmark) {
            bookmarksStore.removeBookmark(bookmark.id);
          }
        }
        break;
      case "rename":
        if (state2.bookmark) {
          renameBookmarkModalState.set({
            visible: true,
            bookmark: state2.bookmark
          });
        } else if (state2.context) {
          let bookmark;
          if (state2.context.outlineItemType === "header") {
            bookmark = bookmarksStore.getBookmarkByHeaderPath(state2.context.messageIndex, state2.context.headerPath || "");
          } else {
            bookmark = bookmarksStore.getBookmarkByMessageIndex(state2.context.messageIndex);
          }
          if (bookmark) {
            renameBookmarkModalState.set({
              visible: true,
              bookmark
            });
          }
        }
        break;
    }
    hideContextMenu();
    return result;
  }
  function hideAddBookmarkModal() {
    addBookmarkModalState.set({
      visible: false,
      context: null
    });
  }
  function hideRenameBookmarkModal() {
    renameBookmarkModalState.set({
      visible: false,
      bookmark: null
    });
  }
  function getDefaultNameLength() {
    return get(featuresStore).bookmarkGetTextLength || 20;
  }
  function buildOutlineItemContext(outlineItemType, messageIndex, messageText, messageHash, element, headerPath, headerText) {
    return {
      outlineItemType,
      messageIndex,
      messageText,
      messageHash,
      headerPath,
      headerText,
      element
    };
  }
  var root_1$3 = from_html(`<div class="empty-state svelte-19r7ywj"><span class="empty-icon svelte-19r7ywj">📚</span> <p class="svelte-19r7ywj">暂无书签</p> <p class="hint svelte-19r7ywj">在大纲上右键可添加书签</p></div>`);
  var root_4 = from_html(`<div class="conversation-header svelte-19r7ywj" role="button" tabindex="0"><span class="toggle-icon svelte-19r7ywj"> </span> <span class="conversation-name svelte-19r7ywj"> </span> <span class="conversation-count svelte-19r7ywj"> </span></div>`);
  var root_3$1 = from_html(`<div class="conversation-group svelte-19r7ywj"><!> <!></div>`);
  var root$3 = from_html(`<div class="bookmark-panel svelte-19r7ywj"><div class="bookmark-toolbar svelte-19r7ywj"><div class="view-toggle svelte-19r7ywj"><button>当前</button> <button>全部</button></div> <input type="text" class="search-input svelte-19r7ywj" placeholder="搜索书签..."/></div> <div class="bookmark-content svelte-19r7ywj"><!></div> <div class="bookmark-footer svelte-19r7ywj"><span class="bookmark-count svelte-19r7ywj"> </span></div></div>`);
  function BookmarkPanel($$anchor, $$props) {
    push($$props, true);
    let viewMode = state("current");
    let searchQuery = state("");
    let bookmarksData = state(proxy({}));
    let collapsedConversations = state(proxy( new Set()));
    let currentConversationId = state("");
    function getConversationDisplayName(conversationId, convData) {
      if (conversationId === get$1(currentConversationId)) {
        return "当前会话";
      }
      if (convData?.name) {
        return convData.name;
      }
      return conversationId.length > 12 ? conversationId.substring(0, 12) + "..." : conversationId;
    }
    let filteredData = user_derived(() => () => {
      const result = [];
      if (get$1(viewMode) === "current") {
        const convData = get$1(bookmarksData)[get$1(currentConversationId)];
        if (convData) {
          const filtered = filterBookmarks(convData.bookmarks);
          if (filtered.length > 0) {
            result.push({
              conversationId: get$1(currentConversationId),
              convData,
              bookmarks: filtered
            });
          }
        }
      } else {
        for (const [conversationId, convData] of Object.entries(get$1(bookmarksData))) {
          const filtered = filterBookmarks(convData.bookmarks);
          if (filtered.length > 0) {
            result.push({ conversationId, convData, bookmarks: filtered });
          }
        }
        result.sort((a, b) => {
          const aLatest = Math.max(...a.bookmarks.map((b2) => b2.createdAt));
          const bLatest = Math.max(...b.bookmarks.map((b2) => b2.createdAt));
          return bLatest - aLatest;
        });
      }
      return result;
    });
    function filterBookmarks(bookmarks) {
      if (!get$1(searchQuery).trim()) return bookmarks;
      const query = get$1(searchQuery).toLowerCase();
      return bookmarks.filter((b) => b.name.toLowerCase().includes(query));
    }
    let totalBookmarks = user_derived(() => () => {
      let count = 0;
      for (const item of get$1(filteredData)()) {
        count += item.bookmarks.length;
      }
      return count;
    });
    let unsubscribe = null;
    onMount(() => {
      set(currentConversationId, getConversationId(), true);
      unsubscribe = bookmarksStore.subscribe((data) => {
        set(bookmarksData, data, true);
      });
      return () => {
        unsubscribe?.();
      };
    });
    function handleNavigate(bookmark, conversationId) {
      $$props.onNavigate?.({ ...bookmark, conversationId });
    }
    function handleContextMenu(e, bookmark, conversationId) {
      showBookmarkContextMenu(e, bookmark, conversationId);
    }
    function handleSearchInput(e) {
      set(searchQuery, e.target.value, true);
    }
    function toggleConversation(conversationId) {
      const newCollapsed = new Set(get$1(collapsedConversations));
      if (newCollapsed.has(conversationId)) {
        newCollapsed.delete(conversationId);
      } else {
        newCollapsed.add(conversationId);
      }
      set(collapsedConversations, newCollapsed, true);
    }
    function isCollapsed(conversationId) {
      return get$1(collapsedConversations).has(conversationId);
    }
    var div = root$3();
    var div_1 = child(div);
    var div_2 = child(div_1);
    var button = child(div_2);
    let classes;
    var button_1 = sibling(button, 2);
    let classes_1;
    var input = sibling(div_2, 2);
    var div_3 = sibling(div_1, 2);
    var node = child(div_3);
    {
      var consequent = ($$anchor2) => {
        var div_4 = root_1$3();
        append($$anchor2, div_4);
      };
      var d = user_derived(() => get$1(filteredData)().length === 0);
      var alternate = ($$anchor2) => {
        var fragment = comment();
        var node_1 = first_child(fragment);
        each(node_1, 17, () => get$1(filteredData)(), (group) => group.conversationId, ($$anchor3, group) => {
          var div_5 = root_3$1();
          var node_2 = child(div_5);
          {
            var consequent_1 = ($$anchor4) => {
              var div_6 = root_4();
              var span = child(div_6);
              var text2 = child(span);
              var span_1 = sibling(span, 2);
              var text_1 = child(span_1);
              var span_2 = sibling(span_1, 2);
              var text_2 = child(span_2);
              template_effect(
                ($0, $1) => {
                  set_text(text2, $0);
                  set_text(text_1, $1);
                  set_text(text_2, get$1(group).bookmarks.length);
                },
                [
                  () => isCollapsed(get$1(group).conversationId) ? "▶" : "▼",
                  () => getConversationDisplayName(get$1(group).conversationId, get$1(group).convData)
                ]
              );
              delegated("click", div_6, () => toggleConversation(get$1(group).conversationId));
              delegated("keydown", div_6, (e) => e.key === "Enter" && toggleConversation(get$1(group).conversationId));
              append($$anchor4, div_6);
            };
            if_block(node_2, ($$render) => {
              if (get$1(viewMode) === "all") $$render(consequent_1);
            });
          }
          var node_3 = sibling(node_2, 2);
          {
            var consequent_2 = ($$anchor4) => {
              BookmarkList($$anchor4, {
                get bookmarks() {
                  return get$1(group).bookmarks;
                },
                get conversationId() {
                  return get$1(group).conversationId;
                },
                onNavigate: handleNavigate,
                onContextMenu: handleContextMenu
              });
            };
            var d_1 = user_derived(() => !isCollapsed(get$1(group).conversationId));
            if_block(node_3, ($$render) => {
              if (get$1(d_1)) $$render(consequent_2);
            });
          }
          append($$anchor3, div_5);
        });
        append($$anchor2, fragment);
      };
      if_block(node, ($$render) => {
        if (get$1(d)) $$render(consequent);
        else $$render(alternate, false);
      });
    }
    var div_7 = sibling(div_3, 2);
    var span_3 = child(div_7);
    var text_3 = child(span_3);
    template_effect(
      ($0) => {
        classes = set_class(button, 1, "toggle-btn svelte-19r7ywj", null, classes, { active: get$1(viewMode) === "current" });
        classes_1 = set_class(button_1, 1, "toggle-btn svelte-19r7ywj", null, classes_1, { active: get$1(viewMode) === "all" });
        set_value(input, get$1(searchQuery));
        set_text(text_3, `共 ${$0 ?? ""} 个书签`);
      },
      [() => get$1(totalBookmarks)()]
    );
    delegated("click", button, () => set(viewMode, "current"));
    delegated("click", button_1, () => set(viewMode, "all"));
    delegated("input", input, handleSearchInput);
    append($$anchor, div);
    pop();
  }
  delegate(["click", "input", "keydown"]);
  var root_2$1 = from_html(`<span class="menu-icon svelte-aof35l"> </span>`);
  var root_1$2 = from_html(`<button role="menuitem"><!> <span class="menu-label svelte-aof35l"> </span></button>`);
  var root$2 = from_html(`<div class="context-menu svelte-aof35l" role="menu"></div>`);
  function ContextMenu($$anchor, $$props) {
    push($$props, true);
    let menuElement = state(void 0);
    let adjustedX = user_derived(() => {
      if (!get$1(menuElement)) return $$props.x;
      const rect = get$1(menuElement).getBoundingClientRect();
      const padding = 8;
      if (rect.right > window.innerWidth - padding) {
        return window.innerWidth - rect.width - padding;
      }
      return $$props.x;
    });
    let adjustedY = user_derived(() => {
      if (!get$1(menuElement)) return $$props.y;
      const rect = get$1(menuElement).getBoundingClientRect();
      const padding = 8;
      if (rect.bottom > window.innerHeight - padding) {
        return window.innerHeight - rect.height - padding;
      }
      return $$props.y;
    });
    function handleItemClick(item) {
      if (!item.disabled) {
        $$props.onSelect(item.id);
        $$props.onClose();
      }
    }
    function handleKeydown(e) {
      if (e.key === "Escape") {
        $$props.onClose();
      }
    }
    onMount(() => {
      const handleClickOutside = (e) => {
        if (get$1(menuElement) && !get$1(menuElement).contains(e.target)) {
          $$props.onClose();
        }
      };
      const timer = setTimeout(
        () => {
          document.addEventListener("click", handleClickOutside);
          document.addEventListener("contextmenu", handleClickOutside);
          document.addEventListener("mousedown", handleClickOutside);
        },
        100
      );
      return () => {
        clearTimeout(timer);
        document.removeEventListener("click", handleClickOutside);
        document.removeEventListener("contextmenu", handleClickOutside);
        document.removeEventListener("mousedown", handleClickOutside);
      };
    });
    var div = root$2();
    event("keydown", $window, handleKeydown);
    each(div, 21, () => $$props.items, index, ($$anchor2, item) => {
      var button = root_1$2();
      let classes;
      var node = child(button);
      {
        var consequent = ($$anchor3) => {
          var span = root_2$1();
          var text2 = child(span);
          template_effect(() => set_text(text2, get$1(item).icon));
          append($$anchor3, span);
        };
        if_block(node, ($$render) => {
          if (get$1(item).icon) $$render(consequent);
        });
      }
      var span_1 = sibling(node, 2);
      var text_1 = child(span_1);
      template_effect(() => {
        classes = set_class(button, 1, "menu-item svelte-aof35l", null, classes, { disabled: get$1(item).disabled, danger: get$1(item).danger });
        button.disabled = get$1(item).disabled;
        set_text(text_1, get$1(item).label);
      });
      delegated("click", button, () => handleItemClick(get$1(item)));
      append($$anchor2, button);
    });
    bind_this(div, ($$value) => set(menuElement, $$value), () => get$1(menuElement));
    template_effect(() => set_style(div, `left: ${get$1(adjustedX) ?? ""}px; top: ${get$1(adjustedY) ?? ""}px;`));
    append($$anchor, div);
    pop();
  }
  delegate(["click"]);
  var root_1$1 = from_html(`<div class="warning-message svelte-7qu2ih">⚠️ 该位置已存在书签,无法重复添加</div>`);
  var root_2 = from_html(`<div class="form-group svelte-7qu2ih"><label for="bookmark-name" class="svelte-7qu2ih">书签名称</label> <input id="bookmark-name" type="text" maxlength="100" class="svelte-7qu2ih"/> <span class="hint svelte-7qu2ih"> </span></div> <div class="preview svelte-7qu2ih"><span class="preview-label svelte-7qu2ih">预览:</span> <span class="preview-name svelte-7qu2ih"> </span></div>`, 1);
  var root_3 = from_html(`<button class="btn btn-primary svelte-7qu2ih"> </button>`);
  var root$1 = from_html(`<div class="modal-overlay svelte-7qu2ih" role="dialog" aria-modal="true" tabindex="-1"><div class="modal-content svelte-7qu2ih" role="document"><div class="modal-header svelte-7qu2ih"><h3 class="svelte-7qu2ih">🔖 添加书签</h3> <button class="close-btn svelte-7qu2ih">✕</button></div> <div class="modal-body svelte-7qu2ih"><!></div> <div class="modal-footer svelte-7qu2ih"><button class="btn btn-secondary svelte-7qu2ih">取消</button> <!></div></div></div>`);
  function AddBookmarkModal($$anchor, $$props) {
    push($$props, true);
    let nameSourceText = user_derived(() => $$props.context.outlineItemType === "header" && $$props.context.headerText ? $$props.context.headerText : $$props.context.messageText);
    let defaultName = user_derived(() => get$1(nameSourceText).substring(0, $$props.defaultNameLength) + (get$1(nameSourceText).length > $$props.defaultNameLength ? "..." : ""));
    let customName = state("");
    let isSubmitting = state(false);
    let hasExistingBookmark = user_derived(() => bookmarksStore.hasBookmarkForMessageIndex($$props.context.messageIndex));
    let finalName = user_derived(() => get$1(customName).trim() || get$1(defaultName));
    function handleSubmit() {
      if (get$1(isSubmitting) || get$1(hasExistingBookmark)) return;
      set(isSubmitting, true);
      const conversationId = getConversationId();
      bookmarksStore.addBookmark({
        name: get$1(finalName),
        conversationId,
        outlineItemType: $$props.context.outlineItemType,
        messageHash: $$props.context.messageHash,
        messageIndex: $$props.context.messageIndex,
        headerPath: $$props.context.headerPath
      });
      set(isSubmitting, false);
      $$props.onAdded?.();
      $$props.onClose();
    }
    function handleKeydown(e) {
      if (e.key === "Enter" && !get$1(hasExistingBookmark)) {
        handleSubmit();
      } else if (e.key === "Escape") {
        $$props.onClose();
      }
    }
    function handleOverlayClick(e) {
      if (e.target === e.currentTarget) {
        $$props.onClose();
      }
    }
    function handleOverlayKeydown(e) {
      if (e.key === "Escape") {
        $$props.onClose();
      }
    }
    var div = root$1();
    event("keydown", $window, handleKeydown);
    var div_1 = child(div);
    var div_2 = child(div_1);
    var button = sibling(child(div_2), 2);
    var div_3 = sibling(div_2, 2);
    var node = child(div_3);
    {
      var consequent = ($$anchor2) => {
        var div_4 = root_1$1();
        append($$anchor2, div_4);
      };
      var alternate = ($$anchor2) => {
        var fragment = root_2();
        var div_5 = first_child(fragment);
        var input = sibling(child(div_5), 2);
        var span = sibling(input, 2);
        var text2 = child(span);
        var div_6 = sibling(div_5, 2);
        var span_1 = sibling(child(div_6), 2);
        var text_1 = child(span_1);
        template_effect(() => {
          set_attribute(input, "placeholder", get$1(defaultName));
          set_text(text2, `留空则使用默认名称:${get$1(defaultName) ?? ""}`);
          set_text(text_1, get$1(finalName));
        });
        bind_value(input, () => get$1(customName), ($$value) => set(customName, $$value));
        append($$anchor2, fragment);
      };
      if_block(node, ($$render) => {
        if (get$1(hasExistingBookmark)) $$render(consequent);
        else $$render(alternate, false);
      });
    }
    var div_7 = sibling(div_3, 2);
    var button_1 = child(div_7);
    var node_1 = sibling(button_1, 2);
    {
      var consequent_1 = ($$anchor2) => {
        var button_2 = root_3();
        var text_2 = child(button_2);
        template_effect(() => {
          button_2.disabled = get$1(isSubmitting);
          set_text(text_2, get$1(isSubmitting) ? "添加中..." : "确定");
        });
        delegated("click", button_2, handleSubmit);
        append($$anchor2, button_2);
      };
      if_block(node_1, ($$render) => {
        if (!get$1(hasExistingBookmark)) $$render(consequent_1);
      });
    }
    delegated("click", div, handleOverlayClick);
    delegated("keydown", div, handleOverlayKeydown);
    delegated("click", div_1, (e) => e.stopPropagation());
    delegated("keydown", div_1, (e) => e.stopPropagation());
    delegated("click", button, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    delegated("click", button_1, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    append($$anchor, div);
    pop();
  }
  delegate(["click", "keydown"]);
  var root = from_html(`<div class="modal-overlay svelte-9ypatm" role="dialog" aria-modal="true" tabindex="-1"><div class="modal-content svelte-9ypatm" role="document"><div class="modal-header svelte-9ypatm"><h3 class="svelte-9ypatm">✏️ 重命名书签</h3> <button class="close-btn svelte-9ypatm">✕</button></div> <div class="modal-body svelte-9ypatm"><div class="form-group svelte-9ypatm"><label for="bookmark-name" class="svelte-9ypatm">书签名称</label> <input id="bookmark-name" type="text" maxlength="100" class="svelte-9ypatm"/></div></div> <div class="modal-footer svelte-9ypatm"><button class="btn btn-secondary svelte-9ypatm">取消</button> <button class="btn btn-primary svelte-9ypatm"> </button></div></div></div>`);
  function RenameBookmarkModal($$anchor, $$props) {
    push($$props, true);
    let newName = state("");
    let isSubmitting = state(false);
    user_effect(() => {
      set(newName, $$props.bookmark.name, true);
    });
    function handleSubmit() {
      if (get$1(isSubmitting) || !get$1(newName).trim()) return;
      set(isSubmitting, true);
      bookmarksStore.updateBookmarkName($$props.bookmark.id, get$1(newName).trim());
      set(isSubmitting, false);
      $$props.onClose();
    }
    function handleKeydown(e) {
      if (e.key === "Enter" && get$1(newName).trim()) {
        handleSubmit();
      } else if (e.key === "Escape") {
        $$props.onClose();
      }
    }
    function handleOverlayClick(e) {
      if (e.target === e.currentTarget) {
        $$props.onClose();
      }
    }
    function handleOverlayKeydown(e) {
      if (e.key === "Escape") {
        $$props.onClose();
      }
    }
    var div = root();
    event("keydown", $window, handleKeydown);
    var div_1 = child(div);
    var div_2 = child(div_1);
    var button = sibling(child(div_2), 2);
    var div_3 = sibling(div_2, 2);
    var div_4 = child(div_3);
    var input = sibling(child(div_4), 2);
    var div_5 = sibling(div_3, 2);
    var button_1 = child(div_5);
    var button_2 = sibling(button_1, 2);
    var text2 = child(button_2);
    template_effect(
      ($0) => {
        button_2.disabled = $0;
        set_text(text2, get$1(isSubmitting) ? "保存中..." : "保存");
      },
      [() => get$1(isSubmitting) || !get$1(newName).trim()]
    );
    delegated("click", div, handleOverlayClick);
    delegated("keydown", div, handleOverlayKeydown);
    delegated("click", div_1, (e) => e.stopPropagation());
    delegated("keydown", div_1, (e) => e.stopPropagation());
    delegated("click", button, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    bind_value(input, () => get$1(newName), ($$value) => set(newName, $$value));
    delegated("click", button_1, function(...$$args) {
      $$props.onClose?.apply(this, $$args);
    });
    delegated("click", button_2, handleSubmit);
    append($$anchor, div);
    pop();
  }
  delegate(["click", "keydown"]);
  const logger = createTaggedLogger("BookmarkNav");
  const PENDING_NAV_KEY = "chat-outline-pending-nav";
  const NAV_TIMEOUT = 3e4;
  class BookmarkNavigationService {
async navigateToBookmark(bookmark) {
      if (!isInConversation(bookmark.conversationId)) {
        return this.handleCrossConversationNavigation(bookmark);
      }
      return this.executeNavigation(bookmark);
    }
handleCrossConversationNavigation(bookmark) {
      const config = get(parserConfigStore);
      if (!config?.buildConversationUrl) {
        return {
          success: false,
          message: "当前平台不支持跨会话跳转"
        };
      }
      const targetUrl = config.buildConversationUrl(bookmark.conversationId);
      if (!targetUrl) {
        return {
          success: false,
          message: "无法构建目标会话URL"
        };
      }
      const pendingNav = {
        bookmarkId: bookmark.id,
        conversationId: bookmark.conversationId,
        timestamp: Date.now()
      };
      try {
        sessionStorage.setItem(PENDING_NAV_KEY, JSON.stringify(pendingNav));
        logger.info("保存待跳转书签", { bookmarkId: bookmark.id, conversationId: bookmark.conversationId });
        return {
          success: true,
          message: "正在跳转到目标会话...",
          needsRedirect: true,
          redirectUrl: targetUrl
        };
      } catch (error) {
        logger.error("保存待跳转信息失败", error);
        return {
          success: false,
          message: "保存跳转信息失败"
        };
      }
    }
async executeNavigation(bookmark) {
      const cache = messageCacheManager.getCache();
      const cachedItem = cache[bookmark.messageIndex];
      if (cachedItem) {
        const currentHash = cachedItem.messageHash;
        if (currentHash !== bookmark.messageHash) {
          pushPanelNotice("内容已变更,书签位置可能不准确", "warning", 3e3);
        }
        if (bookmark.outlineItemType === "header" && bookmark.headerPath) {
          const headerNode = this.findHeaderByPath(
            cachedItem.outlineItem.headers || [],
            bookmark.headerPath
          );
          if (headerNode) {
            const headerOutlineElement = scrollSyncService.getHeaderOutlineElement(headerNode.id);
            return this.scrollToElement(headerNode.element, headerOutlineElement || cachedItem.outlineElement);
          }
          pushPanelNotice("标题结构已变更,跳转到消息位置", "warning", 3e3);
        }
        return this.scrollToElement(cachedItem.outlineItem.element, cachedItem.outlineElement);
      }
      if (cache.length > 0) {
        const lastItem = cache[cache.length - 1];
        pushPanelNotice("消息索引超出范围,跳转到最近位置", "warning", 3e3);
        return this.scrollToElement(lastItem.outlineItem.element, lastItem.outlineElement);
      }
      return {
        success: false,
        message: "未找到对应内容,书签可能已失效"
      };
    }
findHeaderByPath(headers, headerPath) {
      if (!headerPath) return null;
      const indices = headerPath.split(".").map((s) => parseInt(s, 10));
      let currentNodes = headers;
      let targetNode = null;
      for (let i = 0; i < indices.length; i++) {
        const index2 = indices[i];
        if (index2 < 0 || index2 >= currentNodes.length) {
          logger.warn("标题路径索引越界", { headerPath, index: index2, level: i });
          return null;
        }
        targetNode = currentNodes[index2];
        currentNodes = targetNode.children;
      }
      return targetNode;
    }
scrollToElement(targetElement, outlineElement) {
      targetElement.scrollIntoView({ behavior: "smooth", block: "start" });
      highlightElement(targetElement);
      if (outlineElement) {
        scrollSyncService.focusOutlineElement(outlineElement);
        scrollSyncService.applyOutlineFocus(outlineElement);
      }
      return {
        success: true,
        message: "已跳转到书签位置"
      };
    }
checkAndResumePendingNavigation() {
      try {
        const saved = sessionStorage.getItem(PENDING_NAV_KEY);
        if (!saved) {
          return null;
        }
        const pendingNav = JSON.parse(saved);
        if (Date.now() - pendingNav.timestamp > NAV_TIMEOUT) {
          logger.warn("待跳转书签已超时");
          sessionStorage.removeItem(PENDING_NAV_KEY);
          return null;
        }
        sessionStorage.removeItem(PENDING_NAV_KEY);
        const bookmark = bookmarksStore.getBookmarkById(pendingNav.bookmarkId);
        if (!bookmark) {
          logger.warn("未找到待跳转的书签", { bookmarkId: pendingNav.bookmarkId });
          return null;
        }
        logger.info("恢复待跳转书签", {
          bookmarkId: bookmark.id,
          name: bookmark.name,
          conversationId: bookmark.conversationId,
          headerPath: bookmark.headerPath
        });
        return bookmark;
      } catch (error) {
        logger.error("检查待跳转书签失败", error);
        return null;
      }
    }
async resumeNavigation(bookmark) {
      await this.waitForOutlineReady();
      const result = await this.executeNavigation(bookmark);
      if (result.success) {
        pushPanelNotice(result.message, "success", 2e3);
      } else {
        pushPanelNotice(result.message, "error", 3e3);
      }
    }
waitForOutlineReady(timeout = 5e3) {
      return new Promise((resolve) => {
        const startTime = Date.now();
        const check = () => {
          const cache = messageCacheManager.getCache();
          if (cache.length > 0 && cache.some((item) => item.outlineElement !== null)) {
            resolve();
            return;
          }
          if (Date.now() - startTime > timeout) {
            logger.warn("等待大纲超时");
            resolve();
            return;
          }
          setTimeout(check, 100);
        };
        check();
      });
    }
executeRedirect(url) {
      logger.info("执行跨会话跳转", { url });
      window.location.href = url;
    }
  }
  const bookmarkNavigationService = new BookmarkNavigationService();
  var root_1 = from_html(`<div id="chat-outline"><!> <!> <!> <!></div> <!> <!> <!>`, 1);
  function OutlinePanel($$anchor, $$props) {
    push($$props, true);
    let isFixedRight = prop($$props, "isFixedRight", 3, false);
    let currentTheme = state("light");
    let allExpanded = state(true);
    let isVisible = state(true);
    let filterText = state("");
    let useRegex = state(false);
    let viewMode = state("outline");
    let menuState = state(proxy(get(contextMenuState)));
    let addModalState = state(proxy(get(addBookmarkModalState)));
    let renameModalState = state(proxy(get(renameBookmarkModalState)));
    onMount(() => {
      const unsubscribeTheme = themeStore.subscribe((theme2) => {
        set(currentTheme, theme2.currentTheme, true);
      });
      const unsubscribeAllExpanded = allExpandedStore.subscribe((value) => {
        set(allExpanded, value, true);
      });
      const unsubscribeFeatures = featuresStore.subscribe((features) => {
        set(isVisible, features.isVisible, true);
      });
      const unsubscribeMenu = contextMenuState.subscribe((state2) => {
        set(menuState, state2, true);
      });
      const unsubscribeAddModal = addBookmarkModalState.subscribe((state2) => {
        set(addModalState, state2, true);
      });
      const unsubscribeRenameModal = renameBookmarkModalState.subscribe((state2) => {
        set(renameModalState, state2, true);
      });
      const theme = get(themeStore);
      set(currentTheme, theme.currentTheme, true);
      set(allExpanded, get(allExpandedStore), true);
      set(isVisible, get(featuresStore).isVisible, true);
      const pendingBookmark = bookmarkNavigationService.checkAndResumePendingNavigation();
      if (pendingBookmark) {
        setTimeout(
          () => {
            bookmarkNavigationService.resumeNavigation(pendingBookmark);
          },
          500
        );
      }
      return () => {
        unsubscribeTheme();
        unsubscribeAllExpanded();
        unsubscribeFeatures();
        unsubscribeMenu();
        unsubscribeAddModal();
        unsubscribeRenameModal();
      };
    });
    function handleToggleAll() {
      toggleAllExpanded();
    }
    function handleToggleTheme() {
      toggleTheme();
    }
    function handleHide() {
      toggleVisibility();
    }
    function handleSync() {
      scrollSyncService.manualSync();
    }
    function handleFilterChange(filter, regex) {
      set(filterText, filter, true);
      set(useRegex, regex, true);
    }
    function handleTabChange(tab) {
      set(viewMode, tab, true);
    }
    function handleContextMenu(e, context) {
      const fullContext = buildOutlineItemContext(context.outlineItemType, context.messageIndex, context.messageText, context.messageHash, e.target, context.headerPath, context.headerText);
      showContextMenu(e, fullContext);
    }
    async function handleBookmarkNavigate(bookmark) {
      set(viewMode, "outline");
      await new Promise((resolve) => setTimeout(resolve, 50));
      const result = await bookmarkNavigationService.navigateToBookmark(bookmark);
      if (result.needsRedirect && result.redirectUrl) {
        bookmarkNavigationService.executeRedirect(result.redirectUrl);
      }
    }
    function handleMenuSelectWrapper(itemId) {
      const result = handleMenuSelect(itemId);
      if (itemId === "navigate" && result.bookmark && result.conversationId) {
        handleBookmarkNavigate({ ...result.bookmark, conversationId: result.conversationId });
      }
    }
    var fragment = comment();
    var node = first_child(fragment);
    {
      var consequent_4 = ($$anchor2) => {
        var fragment_1 = root_1();
        var div = first_child(fragment_1);
        let classes;
        var node_1 = child(div);
        OutlineHeader(node_1, {
          get onRefresh() {
            return $$props.onRefresh;
          },
          onToggleAll: handleToggleAll,
          onToggleTheme: handleToggleTheme,
          onHide: handleHide,
          onSync: handleSync,
          onFilterChange: handleFilterChange,
          get viewMode() {
            return get$1(viewMode);
          },
          onTabChange: handleTabChange,
          get allExpanded() {
            return get$1(allExpanded);
          },
          get currentTheme() {
            return get$1(currentTheme);
          }
        });
        var node_2 = sibling(node_1, 2);
        PanelNoticeStack(node_2, {});
        var node_3 = sibling(node_2, 2);
        {
          var consequent = ($$anchor3) => {
            OutlineList($$anchor3, {
              get filterText() {
                return get$1(filterText);
              },
              get useRegex() {
                return get$1(useRegex);
              },
              onContextMenu: handleContextMenu
            });
          };
          var alternate = ($$anchor3) => {
            BookmarkPanel($$anchor3, { onNavigate: handleBookmarkNavigate });
          };
          if_block(node_3, ($$render) => {
            if (get$1(viewMode) === "outline") $$render(consequent);
            else $$render(alternate, false);
          });
        }
        var node_4 = sibling(node_3, 2);
        ServiceStatusBar(node_4, {});
        var node_5 = sibling(div, 2);
        {
          var consequent_1 = ($$anchor3) => {
            ContextMenu($$anchor3, {
              get x() {
                return get$1(menuState).x;
              },
              get y() {
                return get$1(menuState).y;
              },
              get items() {
                return get$1(menuState).items;
              },
              onSelect: handleMenuSelectWrapper,
              get onClose() {
                return hideContextMenu;
              }
            });
          };
          if_block(node_5, ($$render) => {
            if (get$1(menuState).visible) $$render(consequent_1);
          });
        }
        var node_6 = sibling(node_5, 2);
        {
          var consequent_2 = ($$anchor3) => {
            {
              let $0 = user_derived(getDefaultNameLength);
              AddBookmarkModal($$anchor3, {
                get context() {
                  return get$1(addModalState).context;
                },
                get defaultNameLength() {
                  return get$1($0);
                },
                get onClose() {
                  return hideAddBookmarkModal;
                }
              });
            }
          };
          if_block(node_6, ($$render) => {
            if (get$1(addModalState).visible && get$1(addModalState).context) $$render(consequent_2);
          });
        }
        var node_7 = sibling(node_6, 2);
        {
          var consequent_3 = ($$anchor3) => {
            RenameBookmarkModal($$anchor3, {
              get bookmark() {
                return get$1(renameModalState).bookmark;
              },
              get onClose() {
                return hideRenameBookmarkModal;
              }
            });
          };
          if_block(node_7, ($$render) => {
            if (get$1(renameModalState).visible && get$1(renameModalState).bookmark) $$render(consequent_3);
          });
        }
        template_effect(() => classes = set_class(div, 1, "chat-outline svelte-n2r6vx", null, classes, { "outline-fixed-right": isFixedRight() }));
        append($$anchor2, fragment_1);
      };
      var alternate_1 = ($$anchor2) => {
        DraggableToggleButton($$anchor2, {
          get onClick() {
            return toggleVisibility;
          }
        });
      };
      if_block(node, ($$render) => {
        if (get$1(isVisible)) $$render(consequent_4);
        else $$render(alternate_1, false);
      });
    }
    append($$anchor, fragment);
    pop();
  }
  let currentObserver = null;
  let debouncedRefresh = null;
  function getMessageHost(node) {
    if (node instanceof Element) {
      return node.closest("[cbe-message-id]");
    }
    return node.parentElement?.closest("[cbe-message-id]") || null;
  }
  function hasRelevantMutation(mutations) {
    let lastMessageHost = null;
    for (const mutation of mutations) {
      if (mutation.type === "childList") {
        if (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0) {
          return true;
        }
        continue;
      }
      if (mutation.type !== "characterData") {
        continue;
      }
      const messageHost = getMessageHost(mutation.target);
      if (!messageHost) {
        continue;
      }
      if (!lastMessageHost) {
        const messageList = messageHost.parentElement?.querySelectorAll?.("[cbe-message-id]");
        lastMessageHost = messageList && messageList.length > 0 ? messageList[messageList.length - 1] : null;
      }
      if (!lastMessageHost || messageHost === lastMessageHost) {
        return true;
      }
    }
    return false;
  }
  function setupMutationObserver(chatArea, onRefresh) {
    if (currentObserver) {
      currentObserver.disconnect();
      logger$1.debug("已断开原有的 MutationObserver");
    }
    const features = get(featuresStore);
    debouncedRefresh = debounce(onRefresh, features.debouncedInterval);
    const observer = new MutationObserver((mutations) => {
      if (hasRelevantMutation(mutations) && debouncedRefresh) {
        debouncedRefresh();
      }
    });
    observer.observe(chatArea, {
      childList: true,
      subtree: true,
attributes: false,
      characterData: true
});
    currentObserver = observer;
    logger$1.info("已设置新的 MutationObserver 监听:", chatArea);
    return observer;
  }
  function disconnectObserver() {
    if (currentObserver) {
      currentObserver.disconnect();
      currentObserver = null;
      logger$1.debug("已断开 MutationObserver");
    }
  }
  const observerService = {
    setup: setupMutationObserver,
    disconnect: disconnectObserver
  };
  class MessageSourceService {
    cachedChatArea = null;
    getCachedChatArea(parserConfig, forceRefresh = false) {
      if (forceRefresh || !this.cachedChatArea) {
        this.cachedChatArea = parserConfig?.selectChatArea() || null;
        logger$1.debug("get chatArea:", this.cachedChatArea);
      }
      return this.cachedChatArea;
    }
    clearChatAreaCache() {
      this.cachedChatArea = null;
    }
    collect(parserConfig) {
      const chatArea = this.getCachedChatArea(parserConfig);
      if (!chatArea) {
        return {
          chatArea: null,
          messageElements: []
        };
      }
      const messageListResult = parserConfig.getMessageList(chatArea);
      if (messageListResult == null) {
        return {
          chatArea,
          messageElements: []
        };
      }
      const messageElements = Array.from(messageListResult);
      for (const messageElement of messageElements) {
        messageCacheManager.ensureMessageId(messageElement);
      }
      return {
        chatArea,
        messageElements
      };
    }
  }
  const messageSourceService = new MessageSourceService();
  class OutlineRefreshService {
    getCachedChatArea(parserConfig, forceRefresh = false) {
      return messageSourceService.getCachedChatArea(parserConfig, forceRefresh);
    }
    refresh(parserConfig) {
      const { chatArea, messageElements } = messageSourceService.collect(parserConfig);
      if (!chatArea) {
        logger$1.warn("无法定位到对话区域");
        return;
      }
      if (messageElements.length === 0) {
        const messageListResult = parserConfig.getMessageList(chatArea);
        if (messageListResult == null) {
          logger$1.warn("对话区域无效,大纲生成失败, chatArea:", chatArea);
          return;
        }
      }
      const features = get(featuresStore);
      logger$1.debug("刷新大纲, 消息数量:", messageElements.length, "缓存数量:", messageCacheManager.length);
      if (messageElements.length === 0) {
        messageCacheManager.clearCache();
        outlineStore.set([]);
        scrollSyncService.schedulePostRefreshCheck();
        return;
      }
      const lastCheck = messageCacheManager.checkLastMessage(messageElements);
      if (!lastCheck.shouldRefreshAll && !lastCheck.lastMessageNeedsUpdate) {
        logger$1.debug("没有变化,跳过更新");
        return;
      }
      if (!lastCheck.shouldRefreshAll && lastCheck.lastMessageNeedsUpdate) {
        this.refreshLastMessage(messageElements, lastCheck.lastIndex, parserConfig);
        return;
      }
      const result = messageCacheManager.rebuildCache(messageElements, parserConfig, {
        features: {
          showUserMessages: features.showUserMessages,
          showAIMessages: features.showAIMessages,
          textLength: features.textLength
        }
      });
      if (result.changes.hasChanges) {
        outlineStore.set(result.outlineItems);
        logger$1.info("大纲刷新完成,共", result.outlineItems.length, "项,变更:", result.changes);
      } else {
        logger$1.debug("缓存完全命中,跳过store更新");
      }
      scrollSyncService.schedulePostRefreshCheck();
    }
    forceRefresh(parserConfig) {
      logger$1.info("执行强制刷新...");
      messageCacheManager.clearCache();
      messageSourceService.clearChatAreaCache();
      const newChatArea = this.getCachedChatArea(parserConfig, true);
      if (!newChatArea) {
        logger$1.error("强制刷新失败:无法获取到chatArea");
        return;
      }
      this.refresh(parserConfig);
      scrollSyncService.rebind(newChatArea, parserConfig);
      logger$1.info("强制刷新完成");
    }
    refreshLastMessage(messageElements, lastIndex, parserConfig) {
      const features = get(featuresStore);
      const lastMessage = messageElements[lastIndex];
      const lastMessageType = parserConfig.determineMessageOwner(lastMessage);
      const shouldShow = lastMessageType === MessageOwner.User && features.showUserMessages || lastMessageType === MessageOwner.Assistant && features.showAIMessages;
      if (!shouldShow) {
        return;
      }
      const lastCached = messageCacheManager.get(messageCacheManager.length - 1);
      const newOutlineItem = createOutlineViewItem({
        id: lastCached?.outlineItem.id || generateUniqueId(),
        index: messageCacheManager.length - 1,
        type: lastMessageType,
        element: lastMessage,
        textLength: features.textLength
      });
      messageCacheManager.updateLastCache(
        lastMessage,
        messageElements.length - 1,
        newOutlineItem,
        lastCached?.outlineElement || null
      );
      outlineStore.set(messageCacheManager.getCache().map((item) => item.outlineItem));
      scrollSyncService.schedulePostRefreshCheck();
    }
  }
  const outlineRefreshService = new OutlineRefreshService();
  class OutlineRuntimeService {
    parserConfig = null;
    outlineContainer = null;
    outlineInstance = null;
    isFixedRight = false;
    destroyed = false;
    async start(parserConfig) {
      setServiceStatus("outlineRuntime", {
        state: "syncing",
        message: "正在初始化大纲运行时"
      });
      this.destroy(false);
      this.destroyed = false;
      this.parserConfig = parserConfig;
      this.isFixedRight = false;
      parserConfig.init?.();
      const timeout = parserConfig.timeout || 0;
      if (timeout > 0) {
        await this.delay(timeout);
      }
      if (this.destroyed) {
        setServiceStatus("outlineRuntime", {
          state: "warning",
          message: "初始化被中断"
        });
        return { isFixedRight: this.isFixedRight, isReady: false };
      }
      setServiceStatus("outlineRuntime", {
        state: "syncing",
        message: "正在获取大纲挂载容器"
      });
      await this.resolveOutlineContainer();
      if (this.destroyed) {
        setServiceStatus("outlineRuntime", {
          state: "warning",
          message: "挂载前初始化被中断"
        });
        return { isFixedRight: this.isFixedRight, isReady: false };
      }
      this.mountOutlinePanel();
      setServiceStatus("outlineRuntime", {
        state: "syncing",
        message: "正在获取 chatArea"
      });
      const chatArea = await this.resolveChatArea();
      if (!chatArea || this.destroyed) {
        setServiceStatus("outlineRuntime", {
          state: "error",
          message: "chatArea 获取失败,无法完成绑定"
        });
        return { isFixedRight: this.isFixedRight, isReady: false };
      }
      setServiceStatus("outlineRuntime", {
        state: "syncing",
        message: "chatArea 已获取,正在绑定监听"
      });
      this.initializeOutlineRuntime(chatArea);
      setServiceStatus("outlineRuntime", {
        state: "ready",
        message: this.isFixedRight ? "chatArea 已获取,监听已绑定,当前使用右侧固定模式" : "chatArea 已获取,MutationObserver 已绑定"
      });
      logger$1.info("对话大纲脚本已启动");
      return { isFixedRight: this.isFixedRight, isReady: true };
    }
    refresh() {
      if (!this.parserConfig) {
        logger$1.warn("刷新大纲失败:parserConfig 不存在");
        return;
      }
      outlineRefreshService.refresh(this.parserConfig);
    }
    forceRefresh() {
      if (!this.parserConfig) {
        logger$1.warn("强制刷新失败:parserConfig 不存在");
        setServiceStatus("outlineRuntime", {
          state: "error",
          message: "运行时未初始化,无法刷新大纲"
        });
        return;
      }
      outlineRefreshService.forceRefresh(this.parserConfig);
      setServiceStatus("outlineRuntime", {
        state: "ready",
        message: "chatArea 已获取,监听保持绑定,大纲已刷新"
      });
    }
    async forceRebind() {
      if (!this.parserConfig) {
        setServiceStatus("outlineRuntime", {
          state: "error",
          message: "运行时未初始化,无法重新获取并绑定监听"
        });
        pushPanelNotice("运行时未初始化,无法重新绑定", "error");
        return false;
      }
      const parserConfig = this.parserConfig;
      setServiceStatus("outlineRuntime", {
        state: "syncing",
        message: "正在重新获取 chatArea 并绑定监听"
      });
      pushPanelNotice("正在重新获取 chatArea 并绑定监听...", "info", 2e3);
      const result = await this.start(parserConfig);
      if (result.isReady) {
        pushPanelNotice("大纲运行时重新绑定完成", "success");
        return true;
      }
      setServiceStatus("outlineRuntime", {
        state: "error",
        message: "重新获取 chatArea 或绑定监听失败"
      });
      pushPanelNotice("大纲运行时重新绑定失败", "error");
      return false;
    }
    destroy(resetStatus = true) {
      this.destroyed = true;
      observerService.disconnect();
      scrollSyncService.destroy(false);
      if (this.outlineInstance) {
        unmount(this.outlineInstance);
        this.outlineInstance = null;
      }
      this.outlineContainer = null;
      this.parserConfig = null;
      this.isFixedRight = false;
      if (resetStatus) {
        resetServiceStatus();
      }
    }
    async resolveOutlineContainer() {
      try {
        this.outlineContainer = await getEleWithRetry(
          this.parserConfig.getOutlineContainer,
          [],
          true,
          5,
          1e3
        );
        if (!this.outlineContainer) {
          throw new Error("未找到大纲挂载容器");
        }
        logger$1.info("成功获取大纲挂载目标:", this.outlineContainer);
        this.parserConfig?.afterGetContainer?.(this.outlineContainer);
      } catch (error) {
        logger$1.error("大纲挂载失败,回退到 body 右侧固定模式:", error);
        this.isFixedRight = true;
        this.outlineContainer = document.body;
        setServiceStatus("outlineRuntime", {
          state: "warning",
          message: "未找到宿主容器,已回退到右侧固定模式"
        });
      }
    }
    mountOutlinePanel() {
      if (!this.outlineContainer) {
        return;
      }
      const existingOutline = this.outlineContainer.querySelector(".chat-outline");
      if (existingOutline) {
        logger$1.debug("已存在大纲组件,跳过重复挂载");
        return;
      }
      this.outlineInstance = mount(OutlinePanel, {
        target: this.outlineContainer,
        props: {
          onRefresh: () => this.forceRefresh(),
          isFixedRight: this.isFixedRight
        }
      });
    }
    async resolveChatArea() {
      logger$1.info("开始获取 chatArea...");
      const chatArea = await getEleWithRetry(this.parserConfig.selectChatArea);
      if (!chatArea) {
        logger$1.error("多次重试后仍未找到聊天区域,初始化失败");
        setServiceStatus("outlineRuntime", {
          state: "error",
          message: "未找到 chatArea,请检查页面是否加载完成"
        });
        return null;
      }
      logger$1.info("成功定位 chatArea:", chatArea);
      this.parserConfig?.afterGetChatArea?.(chatArea);
      return chatArea;
    }
    initializeOutlineRuntime(chatArea) {
      this.refresh();
      scrollSyncService.init(chatArea, this.parserConfig);
      observerService.setup(chatArea, () => {
        this.refresh();
      });
    }
    delay(ms) {
      return new Promise((resolve) => {
        window.setTimeout(resolve, ms);
      });
    }
  }
  const outlineRuntimeService = new OutlineRuntimeService();
  function App($$anchor, $$props) {
    push($$props, true);
    const $themeStore = () => store_get(themeStore, "$themeStore", $$stores);
    const [$$stores, $$cleanup] = setup_stores();
    let parserConfig = state(null);
    user_effect(() => {
      document.documentElement.setAttribute("cbe-data-theme", $themeStore().currentTheme);
    });
    onMount(() => {
      const platform = judgePlatform();
      if (platform === "unknown") {
        logger$1.warn("不支持的平台");
        return;
      }
      setPlatform(platform);
      set(parserConfig, get(parserConfigStore), true);
      if (!get$1(parserConfig)) {
        logger$1.error("无法获取解析配置");
        return;
      }
      void outlineRuntimeService.start(get$1(parserConfig));
      return () => {
        outlineRuntimeService.destroy();
      };
    });
    pop();
    $$cleanup();
  }
  mount(App, {
    target: (() => {
      const container = document.createElement("div");
      document.body.append(container);
      return container;
    })()
  });

})();