{"version":3,"file":"blocksuite-editor.cjs","sources":["../../../../packages/components/src/editor/blocksuite-editor.ts"],"sourcesContent":["import { Editor, Extension, mergeAttributes, Node as TiptapNode } from '@tiptap/core'\nimport Blockquote from '@tiptap/extension-blockquote'\nimport Bold from '@tiptap/extension-bold'\nimport BulletList from '@tiptap/extension-bullet-list'\nimport Code from '@tiptap/extension-code'\nimport Document from '@tiptap/extension-document'\nimport Heading from '@tiptap/extension-heading'\nimport History from '@tiptap/extension-history'\nimport HorizontalRule from '@tiptap/extension-horizontal-rule'\nimport Image from '@tiptap/extension-image'\nimport Italic from '@tiptap/extension-italic'\nimport Link from '@tiptap/extension-link'\nimport ListItem from '@tiptap/extension-list-item'\nimport OrderedList from '@tiptap/extension-ordered-list'\nimport Paragraph from '@tiptap/extension-paragraph'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport Strike from '@tiptap/extension-strike'\nimport { Table } from '@tiptap/extension-table'\nimport { TableCell } from '@tiptap/extension-table-cell'\nimport { TableHeader } from '@tiptap/extension-table-header'\nimport { TableRow } from '@tiptap/extension-table-row'\nimport Text from '@tiptap/extension-text'\nimport TextAlign from '@tiptap/extension-text-align'\nimport Underline from '@tiptap/extension-underline'\nimport { css, html, LitElement } from 'lit'\nimport type { EditorToolbarItem } from './toolbar'\nimport { property, state } from 'lit/decorators.js'\nimport {\n  EMPTY_EDITOR_HTML,\n  transformIncomingContentByFormat,\n  transformOutgoingContentByFormat,\n} from './content-format'\nimport {\n  DEFAULT_EDITOR_TOOLBAR,\n  SIMPLE_EDITOR_TOOLBAR,\n  parseEditorToolbarItems,\n} from './toolbar'\nimport type {\n  ContentTransform,\n  ImageUploadHandler,\n  QxsBlocksuiteEditorContentFormat,\n  QxsBlocksuiteEditorContentSnapshot,\n  QxsBlocksuiteEditorHeaderToolbarLabelKey,\n  QxsBlocksuiteEditorHeaderToolbarLabels,\n  QxsBlocksuiteEditorImageUploadErrorDetail,\n  QxsBlocksuiteEditorToolbarPreset,\n  ToolbarMode,\n  ToolbarPosition,\n} from './types'\nimport { safeCustomElement } from '../base/define'\n\ntype SlashInlineMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    taskList: {\n      toggleTaskList: () => ReturnType\n    }\n  }\n}\n\nconst DEFAULT_IMAGE_WIDTH = 560\nconst MIN_IMAGE_WIDTH = 24\nconst DEFAULT_HEADER_PLACEHOLDER = '输入内容'\nconst DEFAULT_SLASH_PLACEHOLDER = '输入 / 唤出快捷命令'\nconst DEFAULT_MIN_HEIGHT = '80px'\nconst DEFAULT_HEADER_TOOLBAR_LABELS: QxsBlocksuiteEditorHeaderToolbarLabels = {\n  image: '插入图片',\n  link: '插入链接',\n}\nconst HEADER_TOOLBAR_LABEL_KEYS = new Set<QxsBlocksuiteEditorHeaderToolbarLabelKey>([\n  'bold',\n  'italic',\n  'underline',\n  'strike',\n  'code',\n  'link',\n  'image',\n  'bulletList',\n  'orderedList',\n  'taskList',\n  'blockquote',\n  'table',\n])\n\nconst TaskList = TiptapNode.create({\n  name: 'taskList',\n  group: 'block list',\n  content: 'taskItem+',\n  defining: true,\n\n  parseHTML() {\n    return [{ tag: 'ul[data-type=\"taskList\"]' }]\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return ['ul', mergeAttributes(HTMLAttributes, { 'data-type': 'taskList' }), 0]\n  },\n\n  addCommands() {\n    return {\n      toggleTaskList: () => ({ commands }) => commands.toggleList(this.name, 'taskItem'),\n    }\n  },\n})\n\nconst TaskItem = TiptapNode.create({\n  name: 'taskItem',\n  defining: true,\n  content: 'paragraph block*',\n\n  addAttributes() {\n    return {\n      checked: {\n        default: false,\n        parseHTML: element => element.getAttribute('data-checked') === 'true',\n        renderHTML: attributes => ({ 'data-checked': String(Boolean(attributes.checked)) }),\n      },\n    }\n  },\n\n  parseHTML() {\n    return [{ tag: 'li[data-type=\"taskItem\"]' }]\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    const checked = Boolean(HTMLAttributes.checked)\n\n    return [\n      'li',\n      mergeAttributes(HTMLAttributes, { 'data-type': 'taskItem' }),\n      [\n        'label',\n        { contenteditable: 'false' },\n        ['input', { type: 'checkbox', checked: checked ? 'checked' : null }],\n        ['span'],\n      ],\n      ['div', 0],\n    ]\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      Enter: () => this.editor.commands.splitListItem(this.name),\n      Tab: () => this.editor.commands.sinkListItem(this.name),\n      'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n    }\n  },\n})\n\nconst ExtendedListItem = ListItem.extend({\n  addKeyboardShortcuts() {\n    return {\n      Enter: () => this.editor.commands.splitListItem(this.name),\n      Tab: () => this.editor.commands.sinkListItem(this.name),\n      'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n    }\n  },\n})\n\nconst ExtendedImage = Image.extend({\n  addAttributes() {\n    return {\n      ...this.parent?.(),\n      width: {\n        default: null,\n        parseHTML: (element) => {\n          const attr = element.getAttribute('width')\n          const value = Number(attr)\n          return Number.isFinite(value) && value > 0 ? value : null\n        },\n        renderHTML: attributes => attributes.width ? { width: String(attributes.width) } : {},\n      },\n      align: {\n        default: 'left',\n        parseHTML: element => element.getAttribute('data-align') || 'left',\n        renderHTML: attributes => attributes.align ? { 'data-align': String(attributes.align) } : {},\n      },\n    }\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    const width = Number(HTMLAttributes.width)\n\n    const style = [\n      'max-width:100%',\n      'height:auto',\n      Number.isFinite(width) && width > 0 ? `width:${width}px` : '',\n      HTMLAttributes.style || '',\n    ]\n      .filter(Boolean)\n      .join(';')\n\n    return ['img', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { style })]\n  },\n})\n\n@safeCustomElement('qxs-blocksuite-editor')\nexport class QxsBlocksuiteEditor extends LitElement {\n  static styles = css`\n    :host {\n      display: block;\n      font-family: inherit;\n    }\n\n    .editor-wrapper {\n      border: 1px solid #e3e3e3;\n      border-radius: 12px;\n      background: #fff;\n      overflow: visible;\n      position: relative;\n      min-height: var(--qxs-editor-min-height, 80px);\n    }\n\n    .editor-wrapper:focus-within {\n      border-color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .editor-wrapper.preview {\n      border: none;\n      border-radius: 0;\n      background: transparent;\n    }\n\n    .editor-wrapper.preview .editor-content {\n      padding: 8px 12px;\n      min-height: unset;\n      max-height: none;\n      overflow: visible;\n    }\n\n    .editor-wrapper.toolbar-bottom .editor-header {\n      border-bottom: none;\n      border-top: 1px solid transparent;\n    }\n\n    .editor-wrapper.toolbar-bottom .editor-header.is-visible {\n      border-top-color: #eef1f5;\n      border-bottom-color: transparent;\n    }\n\n    .editor-header {\n      max-height: 0;\n      opacity: 0;\n      overflow: hidden;\n      padding: 0 16px;\n      border-bottom: 1px solid transparent;\n      transition:\n        max-height 0.24s ease,\n        opacity 0.18s ease,\n        padding 0.24s ease,\n        border-color 0.24s ease;\n    }\n\n    .editor-header.is-visible {\n      max-height: 132px;\n      opacity: 1;\n      overflow: visible;\n      padding: 10px 12px;\n      border-bottom-color: #eef1f5;\n    }\n\n    .editor-header__inner {\n      display: flex;\n      align-items: center;\n      flex-wrap: wrap;\n      overflow: visible;\n    }\n\n    .editor-content {\n      padding: 12px 16px;\n      min-height: var(--qxs-editor-min-height, 80px);\n      max-height: var(--qxs-editor-max-height, none);\n      overflow-y: var(--qxs-editor-overflow-y, visible);\n      cursor: text;\n    }\n\n    .editor-content:empty::before {\n      content: attr(data-empty-hint);\n      color: #c0c0c0;\n      pointer-events: none;\n      display: block;\n      padding-top: 28px;\n      text-align: center;\n    }\n\n    .editor-wrapper:not(.preview) .ProseMirror {\n      min-height: var(--qxs-editor-min-height, 80px);\n    }\n\n    .editor-footer {\n      display: flex;\n      justify-content: flex-end;\n      padding: 0 16px 12px;\n      color: #909399;\n      font-size: 12px;\n      line-height: 1;\n    }\n\n    .ProseMirror p.is-editor-empty:first-child::before {\n      content: attr(data-placeholder);\n      color: #c0c0c0;\n      pointer-events: none;\n      float: left;\n      height: 0;\n    }\n\n    .ProseMirror p.is-empty:only-child::before,\n    .ProseMirror p.is-empty:only-child > br:first-child + *::before {\n      content: attr(data-placeholder);\n      color: #c0c0c0;\n      pointer-events: none;\n      float: left;\n      height: 0;\n    }\n\n    .editor-wrapper.loading {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 200px;\n      background: #fafafa;\n    }\n\n    .loading-placeholder {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 12px;\n      color: #909399;\n      font-size: 14px;\n    }\n\n    .loading-spinner {\n      width: 24px;\n      height: 24px;\n      border: 2px solid #e3e3e3;\n      border-top-color: var(--qxs-color-primary, #3D61E3);\n      border-radius: 50%;\n      animation: spin 0.8s linear infinite;\n    }\n\n    @keyframes spin {\n      to { transform: rotate(360deg); }\n    }\n\n    .ProseMirror {\n      outline: none;\n      line-height: 1.7;\n      color: #37352f;\n      font-size: 15px;\n    }\n\n    .ProseMirror > * + * {\n      margin-top: 0.5em;\n    }\n\n    .ProseMirror > *:first-child {\n      margin-top: 0 !important;\n    }\n\n    .ProseMirror p {\n      margin: 0;\n    }\n\n    .ProseMirror h1 {\n      font-size: 1.875em;\n      font-weight: 700;\n      margin: 0 0 0.25em;\n      line-height: 1.3;\n    }\n\n    .ProseMirror > h1:first-child {\n      margin-top: 0 !important;\n      line-height: 1.15;\n    }\n\n    .ProseMirror > p:first-child {\n      margin-top: 0 !important;\n    }\n\n    .ProseMirror h2 {\n      font-size: 1.5em;\n      font-weight: 600;\n      margin: 0.5em 0 0.25em;\n      line-height: 1.3;\n    }\n\n    .ProseMirror h3 {\n      font-size: 1.25em;\n      font-weight: 600;\n      margin: 0.5em 0 0.25em;\n      line-height: 1.3;\n    }\n\n    .ProseMirror ul,\n    .ProseMirror ol {\n      padding-left: 1.5em;\n      margin: 0;\n    }\n\n    .ProseMirror ul[data-type=\"taskList\"] {\n      padding-left: 0;\n      list-style: none;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"] {\n      display: flex;\n      align-items: flex-start;\n      gap: 8px;\n      list-style: none;\n      margin: 0.2em 0;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"] > label {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 18px;\n      height: 28px;\n      flex: 0 0 18px;\n      cursor: pointer;\n      user-select: none;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"] > label > input {\n      width: 14px;\n      height: 14px;\n      margin: 0;\n      cursor: pointer;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"] > label > span {\n      display: none;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"] > div {\n      flex: 1;\n      min-width: 0;\n    }\n\n    .ProseMirror li[data-type=\"taskItem\"][data-checked=\"true\"] > div p {\n      color: #8a8f98;\n      text-decoration: line-through;\n    }\n\n    .ProseMirror li {\n      margin: 0.1em 0;\n    }\n\n    .ProseMirror li::marker {\n      color: #37352f;\n    }\n\n    .ProseMirror strong {\n      font-weight: 700;\n    }\n\n    .ProseMirror em {\n      font-style: italic;\n      font-synthesis: none;\n      transform: skewX(-12deg);\n      display: inline-block;\n    }\n\n    .ProseMirror u {\n      text-decoration: underline;\n    }\n\n    .ProseMirror s {\n      text-decoration: line-through;\n      color: #787774;\n    }\n\n    .ProseMirror code {\n      background: rgba(135, 131, 120, 0.14);\n      color: #eb5757;\n      padding: 2px 4px;\n      border-radius: 4px;\n      font-family: 'SFMono-Regular', Menlo, Consolas, monospace;\n      font-size: 85%;\n    }\n\n    .ProseMirror pre {\n      background: #f6f6f7;\n      border-radius: 8px;\n      padding: 12px 16px;\n      overflow-x: auto;\n    }\n\n    .ProseMirror pre code {\n      background: none;\n      padding: 0;\n      color: #37352f;\n    }\n\n    .ProseMirror blockquote {\n      border-left: 3px solid #e3e3e3;\n      padding-left: 1em;\n      margin: 0.75em 0;\n      color: #787774;\n    }\n\n    .ProseMirror hr {\n      border: none;\n      border-top: 1px solid #e3e3e3;\n      margin: 1.5em 0;\n    }\n\n    .ProseMirror img {\n      max-width: 100%;\n      height: auto;\n      border-radius: 8px;\n    }\n\n    .ProseMirror img[data-align=\"left\"] {\n      display: block !important;\n      margin: 16px auto 16px 0 !important;\n    }\n\n    .ProseMirror img[data-align=\"center\"] {\n      display: block !important;\n      margin: 16px auto !important;\n    }\n\n    .ProseMirror img[data-align=\"right\"] {\n      display: block !important;\n      margin: 16px 0 16px auto !important;\n    }\n\n    .ProseMirror a {\n      color: var(--qxs-color-primary, #3D61E3);\n      text-decoration: underline;\n      cursor: pointer;\n    }\n\n    .ProseMirror img.ProseMirror-selectednode {\n      outline: 2px solid var(--qxs-color-primary, #3D61E3);\n      outline-offset: 2px;\n      box-shadow: 0 0 0 4px rgba(61, 97, 227, 0.12);\n    }\n\n    /* Table styles */\n    .ProseMirror table {\n      border-collapse: collapse;\n      width: 100%;\n      margin: 1em 0;\n      border: 1px solid #e3e3e3;\n      border-radius: 8px;\n      overflow: hidden;\n    }\n\n    .ProseMirror th,\n    .ProseMirror td {\n      border: 1px solid #e3e3e3;\n      padding: 8px 12px;\n      text-align: left;\n      vertical-align: top;\n    }\n\n    .ProseMirror th {\n      background: #fafafa;\n      font-weight: 600;\n    }\n\n    .ProseMirror .selectedCell {\n      background: rgba(30, 150, 252, 0.1);\n    }\n\n    /* Table Cell Toolbar */\n    .table-cell-toolbar {\n      position: absolute;\n      z-index: 50;\n      display: flex;\n      gap: 2px;\n      padding: 4px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 6px;\n      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n    }\n\n    .table-cell-toolbar-btn {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      width: 28px;\n      height: 28px;\n      border: none;\n      background: transparent;\n      border-radius: 4px;\n      cursor: pointer;\n      color: #606266;\n      transition: all 0.15s;\n    }\n\n    .table-cell-toolbar-btn:hover {\n      background: #ecf5ff;\n      color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .table-cell-toolbar-btn.danger:hover {\n      background: #fef0f0;\n      color: #f56c6c;\n    }\n\n    /* Bubble Menu */\n    .bubble-menu {\n      position: absolute;\n      display: flex;\n      align-items: center;\n      gap: 2px;\n      padding: 4px 6px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 8px;\n      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n      z-index: 100;\n      opacity: 0;\n      visibility: hidden;\n      transition: opacity 0.15s, visibility 0.15s, transform 0.15s;\n      transform: translateY(4px);\n      max-width: calc(100vw - 40px);\n    }\n\n    .bubble-menu.is-visible {\n      opacity: 1;\n      visibility: visible;\n      transform: translateY(0);\n    }\n\n    .bubble-btn {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      width: 28px;\n      height: 28px;\n      border: none;\n      background: transparent;\n      color: #37352f;\n      border-radius: 4px;\n      cursor: pointer;\n      transition: all 0.15s;\n      position: relative;\n    }\n\n    .bubble-btn.has-label {\n      gap: 6px;\n      width: auto;\n      padding: 0 10px;\n      white-space: nowrap;\n    }\n\n    .bubble-btn:hover {\n      background: rgba(55, 53, 47, 0.08);\n    }\n\n    .bubble-btn.is-active {\n      background: var(--qxs-color-primary, #3D61E3);\n      color: #fff;\n    }\n\n    .bubble-btn.danger:hover {\n      background: #fef0f0;\n      color: #f56c6c;\n    }\n\n    .bubble-btn svg {\n      width: 16px;\n      height: 16px;\n      stroke: currentColor;\n      stroke-width: 2;\n      fill: none;\n      flex: 0 0 auto;\n    }\n\n    .bubble-btn__label {\n      font-size: 12px;\n      font-weight: 500;\n      line-height: 1;\n    }\n\n    .bubble-divider {\n      width: 1px;\n      height: 16px;\n      background: #e3e3e3;\n      margin: 0 3px;\n    }\n\n    /* Dropdown */\n    .bubble-dropdown {\n      position: relative;\n    }\n\n    .bubble-dropdown-btn {\n      display: flex;\n      align-items: center;\n      gap: 4px;\n      padding: 0 6px;\n      height: 28px;\n      border: none;\n      background: transparent;\n      color: #37352f;\n      border-radius: 4px;\n      cursor: pointer;\n      font-size: 12px;\n      font-weight: 500;\n      font-family: inherit;\n      transition: all 0.15s;\n      white-space: nowrap;\n    }\n\n    .bubble-dropdown-btn.has-label {\n      gap: 6px;\n      padding: 0 10px;\n    }\n\n    .bubble-dropdown-btn:hover {\n      background: rgba(55, 53, 47, 0.08);\n    }\n\n    .bubble-dropdown-btn svg {\n      width: 12px;\n      height: 12px;\n      stroke: currentColor;\n      stroke-width: 2;\n      fill: none;\n    }\n\n    .bubble-dropdown-btn__label {\n      font-size: 12px;\n      font-weight: 500;\n      line-height: 1;\n    }\n\n    .bubble-dropdown-menu {\n      position: absolute;\n      top: 100%;\n      left: 0;\n      margin-top: 4px;\n      min-width: 120px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 6px;\n      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n      padding: 4px;\n      opacity: 0;\n      visibility: hidden;\n      transform: translateY(-4px);\n      transition: all 0.15s;\n      z-index: 101;\n    }\n\n    .bubble-dropdown:hover .bubble-dropdown-menu,\n    .bubble-dropdown.is-open .bubble-dropdown-menu {\n      opacity: 1;\n      visibility: visible;\n      transform: translateY(0);\n    }\n\n    .bubble-dropdown-item {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      width: 100%;\n      padding: 6px 8px;\n      border: none;\n      background: transparent;\n      color: #37352f;\n      border-radius: 4px;\n      cursor: pointer;\n      font-size: 12px;\n      font-weight: 500;\n      font-family: inherit;\n      text-align: left;\n      transition: all 0.15s;\n    }\n\n    .bubble-dropdown-item:hover {\n      background: rgba(55, 53, 47, 0.08);\n    }\n\n    .bubble-dropdown-item.is-active {\n      background: var(--qxs-color-primary, #3D61E3);\n      color: #fff;\n    }\n\n    .bubble-dropdown-item svg {\n      width: 16px;\n      height: 16px;\n      stroke: currentColor;\n      stroke-width: 2;\n      fill: none;\n    }\n\n    /* Keep the file input programmatically clickable inside shadow hosts. */\n    .image-input {\n      position: absolute;\n      inset: 0 auto auto 0;\n      width: 1px;\n      height: 1px;\n      padding: 0;\n      margin: 0;\n      opacity: 0;\n      pointer-events: none;\n    }\n\n    .table-grid-preview {\n      display: grid;\n      grid-template-columns: repeat(10, 18px);\n      gap: 2px;\n      padding: 8px;\n    }\n\n    .table-grid-preview .table-cell {\n      width: 18px;\n      height: 18px;\n      border: 1px solid #e3e3e3;\n      border-radius: 2px;\n      background: #fff;\n      cursor: pointer;\n      transition: all 0.1s;\n    }\n\n    .table-grid-preview .table-cell:hover {\n      background: rgba(30, 150, 252, 0.3);\n      border-color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .table-grid-preview .table-cell.selected {\n      background: rgba(30, 150, 252, 0.15);\n      border-color: rgba(30, 150, 252, 0.5);\n    }\n\n    .table-size-hint {\n      text-align: center;\n      padding: 4px 8px 6px;\n      font-size: 10px;\n      color: #8c8c8c;\n    }\n\n    .image-size-control {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      padding-left: 8px;\n      margin-left: 2px;\n      border-left: 1px solid #e3e3e3;\n      white-space: nowrap;\n    }\n\n    .image-size-label {\n      font-size: 12px;\n      color: #7a7f88;\n    }\n\n    .image-size-range {\n      width: 72px;\n      height: 26px;\n      padding: 0 8px;\n      border: 1px solid #d8dde6;\n      border-radius: 6px;\n      font-size: 12px;\n      color: #37352f;\n      background: #fff;\n      outline: none;\n    }\n\n    .image-size-range:focus {\n      border-color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .link-editor {\n      position: absolute;\n      z-index: 120;\n      display: grid;\n      gap: 8px;\n      min-width: 320px;\n      padding: 10px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 10px;\n      box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);\n    }\n\n    .link-editor__field {\n      display: grid;\n      gap: 4px;\n    }\n\n    .link-editor__label {\n      font-size: 12px;\n      color: #6b7280;\n      line-height: 1;\n    }\n\n    .link-editor__input {\n      min-width: 0;\n      height: 32px;\n      padding: 0 10px;\n      border: 1px solid #d8dde6;\n      border-radius: 8px;\n      outline: none;\n      font-size: 13px;\n      color: #37352f;\n      background: #fff;\n    }\n\n    .link-editor__input:focus {\n      border-color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .link-editor__actions {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n\n    .link-editor__action {\n      height: 32px;\n      padding: 0 12px;\n      border: 1px solid #d8dde6;\n      border-radius: 8px;\n      background: #fff;\n      color: #4b5563;\n      font-size: 12px;\n      font-family: inherit;\n      cursor: pointer;\n      transition: all 0.15s ease;\n      white-space: nowrap;\n    }\n\n    .link-editor__action:hover {\n      border-color: #c3cad5;\n      background: #f8fafc;\n    }\n\n    .link-editor__action.primary {\n      border-color: var(--qxs-color-primary, #3D61E3);\n      background: var(--qxs-color-primary, #3D61E3);\n      color: #fff;\n    }\n\n    .link-editor__action.danger {\n      color: #f56c6c;\n    }\n\n    /* Image Toolbar */\n    .image-toolbar {\n      position: absolute;\n      display: flex;\n      align-items: center;\n      gap: 2px;\n      padding: 4px 6px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 6px;\n      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n      z-index: 100;\n      transform: translateX(-50%);\n    }\n\n    .image-toolbar-btn {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      width: 28px;\n      height: 28px;\n      border: none;\n      background: transparent;\n      border-radius: 4px;\n      cursor: pointer;\n      color: #595959;\n      transition: all 0.15s;\n    }\n\n    .image-toolbar-btn:hover {\n      background: #f5f5f5;\n      color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .image-toolbar-btn.danger:hover {\n      background: #fff1f0;\n      color: #ff4d4f;\n    }\n\n    .image-toolbar-btn svg {\n      width: 16px;\n      height: 16px;\n      stroke: currentColor;\n      stroke-width: 2;\n      fill: none;\n    }\n\n    .image-toolbar-divider {\n      width: 1px;\n      height: 20px;\n      background: #e3e3e3;\n      margin: 0 4px;\n    }\n\n    .image-control-label {\n      display: inline-flex;\n      align-items: center;\n      padding: 0 4px;\n      font-size: 12px;\n      color: #909399;\n      user-select: none;\n      white-space: nowrap;\n    }\n\n    /* Image More Menu */\n    .image-more-menu {\n      position: absolute;\n      top: 100%;\n      right: 0;\n      margin-top: 4px;\n      padding: 4px;\n      background: #fff;\n      border: 1px solid #e3e3e3;\n      border-radius: 6px;\n      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n      z-index: 101;\n      min-width: 120px;\n    }\n\n    .image-more-menu-item {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n      padding: 8px 12px;\n      border: none;\n      background: transparent;\n      width: 100%;\n      text-align: left;\n      font-size: 13px;\n      color: #595959;\n      border-radius: 4px;\n      cursor: pointer;\n      transition: all 0.15s;\n    }\n\n    .image-more-menu-item:hover {\n      background: #f5f5f5;\n      color: var(--qxs-color-primary, #3D61E3);\n    }\n\n    .image-more-menu-item svg {\n      width: 14px;\n      height: 14px;\n      stroke: currentColor;\n      stroke-width: 2;\n      fill: none;\n    }\n\n    /* Selected Image */\n    .ProseMirror img.selected {\n      outline: 2px solid var(--qxs-color-primary, #3D61E3);\n      outline-offset: 2px;\n    }\n  `\n\n  @property({ type: String, attribute: 'content' })\n  content = ''\n\n  @property({ type: String, attribute: 'model-value' })\n  'model-value' = ''\n\n  @property({ type: String, attribute: 'placeholder' })\n  placeholder = DEFAULT_HEADER_PLACEHOLDER\n\n  @property({ type: String, attribute: 'toolbar-mode' })\n  'toolbar-mode': ToolbarMode = 'header'\n\n  @property({ attribute: 'toolbar' })\n  toolbar: string | EditorToolbarItem[] = ''\n\n  @property({ type: String, attribute: 'toolbar-preset' })\n  'toolbar-preset': QxsBlocksuiteEditorToolbarPreset = 'full'\n\n  @property({ attribute: 'header-toolbar-labels' })\n  'header-toolbar-labels': string | QxsBlocksuiteEditorHeaderToolbarLabels = DEFAULT_HEADER_TOOLBAR_LABELS\n\n  private _lastInvalidHeaderToolbarLabelsSource: unknown = undefined\n\n  @property({ type: String, attribute: 'header-always-visible' })\n  'header-always-visible': boolean | string = 'true'\n\n  @property({ type: String, attribute: 'use-model' })\n  'use-model': boolean | string = 'false'\n\n  @property({ type: String, attribute: 'readonly' })\n  readonly: boolean | string = 'false'\n\n  @property({ type: String, attribute: 'preview' })\n  preview: boolean | string = 'false'\n\n  @property({ attribute: 'editable' })\n  editable: boolean | string | null = null\n\n  @property({ type: String, attribute: 'min-height' })\n  'min-height' = DEFAULT_MIN_HEIGHT\n\n  @property({ type: String, attribute: 'max-height' })\n  'max-height' = ''\n\n  @property({ type: String, attribute: 'show-character-count' })\n  'show-character-count': boolean | string = 'false'\n\n  @property({ type: String, attribute: 'toolbar-position' })\n  'toolbar-position': ToolbarPosition = 'top'\n\n  @property({ type: String, attribute: 'custom-styles' })\n  'custom-styles' = ''\n\n  @property({ type: String, attribute: 'content-format' })\n  'content-format': QxsBlocksuiteEditorContentFormat = 'html'\n\n  @property({ type: Object, attribute: 'deserialize-content' })\n  'deserialize-content': ContentTransform | null = null\n\n  @property({ type: Object, attribute: 'serialize-content' })\n  'serialize-content': ContentTransform | null = null\n\n  private _injectedStyleEl: HTMLStyleElement | null = null\n\n  private _injectCustomStyles() {\n    const shadow = this.shadowRoot\n    if (!shadow) { return }\n\n    if (this._injectedStyleEl) {\n      this._injectedStyleEl.remove()\n      this._injectedStyleEl = null\n    }\n\n    if (!this['custom-styles']) { return }\n\n    const styleEl = document.createElement('style')\n    styleEl.textContent = this['custom-styles']\n    shadow.appendChild(styleEl)\n    this._injectedStyleEl = styleEl\n  }\n\n  private get _useModelValue(): boolean {\n    return this['use-model'] === true || this['use-model'] === 'true' || this['use-model'] === '' || this.hasAttribute('use-model')\n  }\n\n  private get _readonlyValue(): boolean {\n    return this.readonly !== false && this.readonly !== 'false'\n  }\n\n  private get _previewValue(): boolean {\n    return this.preview !== false && this.preview !== 'false'\n  }\n\n  private get _editableValue(): boolean | null {\n    if (this.editable === null || this.editable === undefined) {\n      return null\n    }\n\n    return this.editable !== false && this.editable !== 'false'\n  }\n\n  private get _isEditable(): boolean {\n    if (this._previewValue) {\n      return false\n    }\n\n    if (this._editableValue !== null) {\n      return this._editableValue\n    }\n\n    return !this._readonlyValue\n  }\n\n  private get _toolbarModeValue(): ToolbarMode {\n    return this['toolbar-mode'] === 'header' ? 'header' : 'slash'\n  }\n\n  private get _headerAlwaysVisibleValue(): boolean {\n    return this['header-always-visible'] === true\n      || this['header-always-visible'] === 'true'\n      || this['header-always-visible'] === ''\n      || this.hasAttribute('header-always-visible')\n  }\n\n  private get _toolbarPositionValue(): ToolbarPosition {\n    return this['toolbar-position'] === 'bottom' ? 'bottom' : 'top'\n  }\n\n  private get _toolbarPresetValue(): QxsBlocksuiteEditorToolbarPreset {\n    if (this['toolbar-preset'] === 'simple') {\n      return 'simple'\n    }\n\n    if (this['toolbar-preset'] === 'none') {\n      return 'none'\n    }\n\n    return 'full'\n  }\n\n  private get _contentFormatValue(): QxsBlocksuiteEditorContentFormat {\n    if (this['content-format'] === 'markdown') {\n      return 'markdown'\n    }\n\n    if (this['content-format'] === 'custom') {\n      return 'custom'\n    }\n\n    return 'html'\n  }\n\n  private get _showCharacterCountValue(): boolean {\n    return this['show-character-count'] === true\n      || this['show-character-count'] === 'true'\n      || this['show-character-count'] === ''\n      || this.hasAttribute('show-character-count')\n  }\n\n  private get _resolvedMinHeight(): string {\n    return this['min-height']?.trim() || DEFAULT_MIN_HEIGHT\n  }\n\n  private get _resolvedMaxHeight(): string {\n    return this['max-height']?.trim() || 'none'\n  }\n\n  private get _wrapperStyleValue(): string {\n    const overflowY = this['max-height']?.trim() ? 'auto' : 'visible'\n\n    return [\n      `--qxs-editor-min-height: ${this._resolvedMinHeight}`,\n      `--qxs-editor-max-height: ${this._resolvedMaxHeight}`,\n      `--qxs-editor-overflow-y: ${overflowY}`,\n    ].join('; ')\n  }\n\n  private get _resolvedPlaceholder(): string {\n    if (\n      this.placeholder\n      && this.placeholder !== DEFAULT_HEADER_PLACEHOLDER\n      && this.placeholder !== DEFAULT_SLASH_PLACEHOLDER\n    ) {\n      return this.placeholder\n    }\n    return this._toolbarModeValue === 'header'\n      ? DEFAULT_HEADER_PLACEHOLDER\n      : DEFAULT_SLASH_PLACEHOLDER\n  }\n\n  private get _toolbarItemsValue(): EditorToolbarItem[] {\n    if (Array.isArray(this.toolbar)) {\n      return parseEditorToolbarItems(this.toolbar)\n    }\n\n    if (typeof this.toolbar === 'string' && this.toolbar.trim()) {\n      return parseEditorToolbarItems(this.toolbar)\n    }\n\n    if (this._toolbarPresetValue === 'simple') {\n      return [...SIMPLE_EDITOR_TOOLBAR]\n    }\n\n    if (this._toolbarPresetValue === 'none') {\n      return []\n    }\n\n    return [...DEFAULT_EDITOR_TOOLBAR]\n  }\n\n  private _hasToolbarItem(item: EditorToolbarItem): boolean {\n    return this._toolbarItemsValue.includes(item)\n  }\n\n  private get _headerToolbarLabelsValue(): QxsBlocksuiteEditorHeaderToolbarLabels {\n    const source = this['header-toolbar-labels']\n    if (!source) {\n      return {}\n    }\n\n    let parsed: unknown = source\n    if (typeof source === 'string') {\n      if (source === '[object Object]') {\n        this._warnInvalidHeaderToolbarLabels(\n          source,\n          'received \"[object Object]\"; Vue hosts should pass object values with `.prop`, for example `:header-toolbar-labels.prop=\"headerToolbarLabels\"`',\n        )\n        return {}\n      }\n\n      try {\n        parsed = JSON.parse(source)\n      }\n      catch (error) {\n        this._warnInvalidHeaderToolbarLabels(source, 'parse failed, fallback to empty map', error)\n        return {}\n      }\n    }\n\n    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n      return {}\n    }\n\n    const labels: QxsBlocksuiteEditorHeaderToolbarLabels = {}\n    for (const [key, value] of Object.entries(parsed)) {\n      if (\n        HEADER_TOOLBAR_LABEL_KEYS.has(key as QxsBlocksuiteEditorHeaderToolbarLabelKey)\n        && typeof value === 'string'\n        && value.trim()\n      ) {\n        labels[key as QxsBlocksuiteEditorHeaderToolbarLabelKey] = value.trim()\n      }\n    }\n\n    return labels\n  }\n\n  private _warnInvalidHeaderToolbarLabels(source: unknown, message: string, error?: unknown) {\n    if (this._lastInvalidHeaderToolbarLabelsSource === source) {\n      return\n    }\n\n    this._lastInvalidHeaderToolbarLabelsSource = source\n    if (error) {\n      console.warn(`[qxs-blocksuite-editor] header-toolbar-labels ${message}`, error)\n      return\n    }\n\n    console.warn(`[qxs-blocksuite-editor] header-toolbar-labels ${message}`)\n  }\n\n  private _getHeaderToolbarLabel(key: QxsBlocksuiteEditorHeaderToolbarLabelKey): string {\n    if (this._toolbarModeValue !== 'header') {\n      return ''\n    }\n\n    return this._headerToolbarLabelsValue[key] || ''\n  }\n\n  private _renderToolbarButton(\n    key: QxsBlocksuiteEditorHeaderToolbarLabelKey,\n    options: {\n      title: string\n      icon: unknown\n      active?: boolean\n      danger?: boolean\n      onClick: (event: MouseEvent) => void\n    },\n  ) {\n    const label = this._getHeaderToolbarLabel(key)\n    const className = [\n      'bubble-btn',\n      options.active ? 'is-active' : '',\n      options.danger ? 'danger' : '',\n      label ? 'has-label' : '',\n    ]\n      .filter(Boolean)\n      .join(' ')\n\n    return html`\n      <button class=${className} @click=${options.onClick} title=${options.title}>\n        ${options.icon}\n        ${label ? html`<span class=\"bubble-btn__label\">${label}</span>` : null}\n      </button>\n    `\n  }\n\n  private _transformIncomingContent(value: string | null | undefined): string {\n    const source = value || ''\n    const transform = this['deserialize-content']\n\n    if (!transform) {\n      return transformIncomingContentByFormat(source, this._contentFormatValue)\n    }\n\n    try {\n      return transform(source) || EMPTY_EDITOR_HTML\n    }\n    catch (error) {\n      console.warn('[qxs-blocksuite-editor] deserialize-content failed, fallback to raw content', error)\n      return transformIncomingContentByFormat(source, this._contentFormatValue)\n    }\n  }\n\n  private _transformOutgoingContent(value: string): string {\n    const transform = this['serialize-content']\n\n    if (!transform) {\n      return transformOutgoingContentByFormat(value, this._contentFormatValue)\n    }\n\n    try {\n      return transform(value)\n    }\n    catch (error) {\n      console.warn('[qxs-blocksuite-editor] serialize-content failed, fallback to raw html', error)\n      return transformOutgoingContentByFormat(value, this._contentFormatValue)\n    }\n  }\n\n  private _getEditorCharacterCount(): number {\n    return this._editor?.getText().length ?? 0\n  }\n\n  @property({ type: Object, attribute: 'upload-image' })\n  'upload-image': ImageUploadHandler = async (file: File) => {\n    return new Promise((resolve, reject) => {\n      const reader = new FileReader()\n      reader.onload = e => resolve(e.target?.result as string)\n      reader.onerror = reject\n      reader.readAsDataURL(file)\n    })\n  }\n\n  @state() private _editor: Editor | null = null\n  private _pendingContent: string | null = null\n  private _tableRows = 3\n  private _tableCols = 3\n  @state() private _hoverRow = 0\n  @state() private _hoverCol = 0\n  @state() private _tableDropdownOpen = false\n  @state() private _tableCellToolbar: { x: number, y: number, visible: boolean, cellRow: number, cellCol: number } = { x: 0, y: 0, visible: false, cellRow: 0, cellCol: 0 }\n  @state() private _imageToolbar: { x: number, y: number, visible: boolean } = { x: 0, y: 0, visible: false }\n  @state() private _linkEditor = { x: 0, y: 0, visible: false, url: '', label: '' }\n  @state() private _isEditorFocused = false\n  @state() private _selectedImage: { pos: number, width: number, align: string } | null = null\n  private _hasSlashCommand = false\n  private _slashCommandRange: { from: number, to: number } | null = null\n  private _slashInlineMarkState: { type: SlashInlineMark, lineStart: number, startPos: number } | null = null\n  private _isComposingText = false\n  private _isUpdating = false\n  private _pendingImageInsertPos: number | null = null\n  private _linkSelection: { from: number, to: number } | null = null\n  private _preserveFocusOnInternalClick = false\n\n  private _initEditor() {\n    if (this._editor) { return }\n\n    const el = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n    if (!el) {\n      requestAnimationFrame(() => this._initEditor())\n      return\n    }\n\n    while (el.firstChild) {\n      el.removeChild(el.firstChild)\n    }\n\n    const useModel = this._useModelValue\n    const modelValue = this.getAttribute('model-value') ?? this['model-value']\n    const contentValue = this.content\n\n    const initialContent = useModel\n      ? this._transformIncomingContent(this._pendingContent ?? modelValue)\n      : this._transformIncomingContent(this._pendingContent ?? contentValue)\n\n    const extensions: any[] = [\n      Document,\n      Paragraph,\n      Text,\n      Bold,\n      Italic,\n      Underline,\n      Strike,\n      Code,\n      Heading.configure({ levels: [1, 2, 3] }),\n      BulletList,\n      OrderedList,\n      TaskList,\n      TaskItem,\n      ExtendedListItem,\n      Blockquote,\n      HorizontalRule,\n      History,\n      ExtendedImage.configure({\n        inline: false,\n        allowBase64: true,\n      }),\n      Link.extend({\n        inclusive: false,\n      }).configure({\n        openOnClick: false,\n        HTMLAttributes: {\n          rel: 'noopener noreferrer',\n        },\n      }),\n      TextAlign.configure({\n        types: ['heading', 'paragraph'],\n      }),\n      Table.configure({\n        resizable: true,\n      }),\n      TableRow,\n      TableCell,\n      TableHeader,\n      Placeholder.configure({\n        placeholder: this._resolvedPlaceholder,\n      }),\n    ]\n\n    this._editor = new Editor({\n      element: el,\n      extensions,\n      editable: this._isEditable,\n      content: initialContent,\n    })\n\n    this._editor.view.dom.addEventListener('compositionstart', this._handleCompositionStart)\n    this._editor.view.dom.addEventListener('compositionend', this._handleCompositionEnd)\n\n    this._pendingContent = null\n\n    this._editor.on('selectionUpdate', () => {\n      this._syncSlashInlineMarkState()\n      this._restoreSlashInlineMarkIfNeeded()\n      if (this._toolbarModeValue === 'slash') {\n        this._updateBubbleMenuPosition()\n      }\n      if (this._editor?.isActive('table')) {\n        this._showTableCellToolbar()\n      }\n      else {\n        this._hideTableCellToolbar()\n      }\n      this._syncImageSelectionState()\n    })\n\n    this._editor.on('transaction', () => {\n      if (this._editor?.isActive('table')) {\n        this._showTableCellToolbar()\n      }\n      else {\n        this._hideTableCellToolbar()\n      }\n      this._checkSlashCommand()\n      this._syncSlashInlineMarkState()\n      this._restoreSlashInlineMarkIfNeeded()\n      this._setupTableEdgeDetection()\n      this._syncImageSelectionState()\n    })\n\n    this._editor.on('update', () => {\n      this._emitContentChange()\n    })\n  }\n\n  private _tableEdgeDetectionSetup = false\n\n  private _toggleTaskItemChecked(event: Event) {\n    const target = event.target\n    const editor = this._editor\n    if (!(target instanceof HTMLInputElement) || target.type !== 'checkbox' || !editor) {\n      return\n    }\n\n    const taskItem = target.closest('li[data-type=\"taskItem\"]')\n    if (!taskItem) {\n      return\n    }\n\n    event.preventDefault()\n    event.stopPropagation()\n\n    const basePos = editor.view.posAtDOM(taskItem, 0)\n    const searchFrom = Math.max(0, basePos - 2)\n    const searchTo = Math.min(editor.state.doc.content.size, basePos + 2)\n\n    let taskItemPos: number | null = null\n    editor.state.doc.nodesBetween(searchFrom, searchTo, (node, pos) => {\n      if (node.type.name === 'taskItem') {\n        taskItemPos = pos\n        return false\n      }\n      return undefined\n    })\n\n    if (taskItemPos === null) {\n      return\n    }\n\n    const node = editor.state.doc.nodeAt(taskItemPos)\n    if (!node || node.type.name !== 'taskItem') {\n      return\n    }\n\n    editor.view.dispatch(editor.state.tr.setNodeMarkup(taskItemPos, undefined, {\n      ...node.attrs,\n      checked: !node.attrs.checked,\n    }))\n  }\n\n  private _emitContentChange() {\n    if (!this._editor) { return }\n    const snapshot = this.getContentSnapshot()\n\n    if (this._showCharacterCountValue) {\n      this.requestUpdate()\n    }\n\n    this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorContentSnapshot>('content-update', {\n      detail: snapshot,\n      bubbles: true,\n      composed: true,\n    }))\n\n    this.dispatchEvent(new CustomEvent('content-change', {\n      detail: snapshot.value,\n      bubbles: true,\n      composed: true,\n    }))\n  }\n\n  private _setupTableEdgeDetection() {\n    const editorContent = this.shadowRoot?.querySelector('.editor-content')\n    const editorWrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n    if (!editorContent || this._tableEdgeDetectionSetup) { return }\n\n    this._tableEdgeDetectionSetup = true\n\n    const handleEditorClick = (event: Event) => {\n      this._toggleTaskItemChecked(event)\n\n      const target = event.target\n      if (\n        target instanceof Element\n        && target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n      ) {\n        return\n      }\n      if (!this._isEditable) {\n        return\n      }\n      this._editor?.chain().focus().run()\n    }\n\n    editorContent.addEventListener('click', handleEditorClick as EventListener)\n    editorWrapper?.addEventListener('click', handleEditorClick as EventListener)\n  }\n\n  private _handleWrapperFocusIn() {\n    this._preserveFocusOnInternalClick = false\n    this._isEditorFocused = true\n  }\n\n  private _handleHeaderToolbarMouseDown(event: MouseEvent) {\n    if (!this._isEditable) {\n      return\n    }\n\n    const target = event.target\n    if (!(target instanceof Element) || !target.closest('button, .bubble-dropdown, .table-cell')) {\n      return\n    }\n\n    // Keep the ProseMirror selection alive while using the header toolbar.\n    event.preventDefault()\n    this._preserveFocusOnInternalClick = true\n    requestAnimationFrame(() => {\n      this._preserveFocusOnInternalClick = false\n    })\n  }\n\n  private _handleWrapperMouseDown(event: MouseEvent) {\n    const target = event.target\n    if (\n      !this._isEditable\n      || !(target instanceof Element)\n      || target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n    ) {\n      return\n    }\n\n    this._preserveFocusOnInternalClick = true\n    requestAnimationFrame(() => {\n      this._preserveFocusOnInternalClick = false\n    })\n  }\n\n  private _handleWrapperFocusOut(event: FocusEvent) {\n    const nextTarget = event.relatedTarget as Node | null\n    const wrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n    if (this._preserveFocusOnInternalClick) {\n      return\n    }\n    if (nextTarget && wrapper?.contains(nextTarget)) {\n      return\n    }\n    this._isEditorFocused = false\n    this._tableDropdownOpen = false\n    this._selectedImage = null\n    this._hideImageToolbar()\n    this._closeLinkEditor()\n  }\n\n  private _isHeaderVisible(): boolean {\n    return this._toolbarModeValue === 'header'\n      && !this._previewValue\n      && (\n        this._headerAlwaysVisibleValue\n        || this._isEditorFocused\n        || this._tableDropdownOpen\n        || Boolean(this._selectedImage)\n      )\n  }\n\n  private _getImageSelection() {\n    const editor = this._editor\n    const selection: any = editor?.state.selection\n    if (!editor || !selection?.node || selection.node.type?.name !== 'image') {\n      return null\n    }\n\n    return {\n      pos: selection.from,\n      attrs: selection.node.attrs ?? {},\n    }\n  }\n\n  private _getImageMaxWidth() {\n    const editorContent = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n    const availableWidth = (editorContent?.clientWidth ?? DEFAULT_IMAGE_WIDTH) - 32\n    return Math.max(MIN_IMAGE_WIDTH, Math.min(DEFAULT_IMAGE_WIDTH, availableWidth))\n  }\n\n  private async _getImageNaturalWidth(file: File) {\n    return await new Promise<number | null>((resolve) => {\n      const objectUrl = URL.createObjectURL(file)\n      const image = new window.Image()\n\n      image.onload = () => {\n        const naturalWidth = image.naturalWidth\n        URL.revokeObjectURL(objectUrl)\n        resolve(Number.isFinite(naturalWidth) && naturalWidth > 0 ? naturalWidth : null)\n      }\n\n      image.onerror = () => {\n        URL.revokeObjectURL(objectUrl)\n        resolve(null)\n      }\n\n      image.src = objectUrl\n    })\n  }\n\n  private _syncImageSelectionState() {\n    const selection = this._getImageSelection()\n    if (!selection) {\n      this._selectedImage = null\n      if (this._toolbarModeValue === 'slash') {\n        this._hideImageToolbar()\n      }\n      return\n    }\n\n    const width = Number(selection.attrs.width)\n    const align = String(selection.attrs.align || 'left')\n    this._selectedImage = {\n      pos: selection.pos,\n      width: Number.isFinite(width) && width > 0 ? width : this._getImageMaxWidth(),\n      align,\n    }\n\n    if (this._toolbarModeValue !== 'slash') {\n      this._hideImageToolbar()\n      return\n    }\n\n    const editor = this._editor\n    const wrapperRect = this.shadowRoot?.querySelector('.editor-wrapper')?.getBoundingClientRect()\n    if (!editor || !wrapperRect) { return }\n    const coords = editor.view.coordsAtPos(selection.pos)\n    const x = coords.left - wrapperRect.left + (coords.right - coords.left) / 2\n    const y = coords.top - wrapperRect.top - 40\n    this._showImageToolbar({ x, y })\n  }\n\n  private _clearSlashCommandText() {\n    if (!this._editor || !this._slashCommandRange) { return }\n    const { from, to } = this._slashCommandRange\n    this._editor.chain().focus().deleteRange({ from, to }).run()\n    this._hasSlashCommand = false\n    this._slashCommandRange = null\n  }\n\n  private _checkSlashCommand() {\n    if (!this._editor) { return }\n    const { selection } = this._editor.state\n    if (!selection.empty) {\n      this._hasSlashCommand = false\n      this._slashCommandRange = null\n      return\n    }\n\n    const { $from } = selection as any\n    const textBefore = $from.parent.textBetween(0, $from.parentOffset, ' ', ' ')\n    const matched = /(?:^|\\s)(\\/\\S*)$/.exec(textBefore)\n\n    if (!matched) {\n      this._hasSlashCommand = false\n      this._slashCommandRange = null\n      return\n    }\n\n    const slashText = matched[1]\n    this._hasSlashCommand = true\n    this._slashCommandRange = {\n      from: selection.from - slashText.length,\n      to: selection.from,\n    }\n  }\n\n  firstUpdated() {\n    this._injectCustomStyles()\n    queueMicrotask(() => {\n      if (this.isConnected) {\n        this._initEditor()\n      }\n    })\n  }\n\n  updated(changed: Map<string, unknown>) {\n    if (changed.has('custom-styles')) {\n      this._injectCustomStyles()\n    }\n\n    if (this._editor) {\n      if (\n        changed.has('content')\n        || (changed.has('model-value') && this._useModelValue)\n        || changed.has('deserialize-content')\n        || changed.has('content-format')\n      ) {\n        const nextValue = this._useModelValue ? this['model-value'] : this.content\n        const newContent = this._transformIncomingContent(nextValue)\n        const isFormatReconfigured = changed.has('deserialize-content') || changed.has('content-format')\n        const isControlledEcho = !isFormatReconfigured && (nextValue ?? '') === this.getContent()\n\n        if (!isControlledEcho && newContent !== this._editor.getHTML()) {\n          this._editor.commands.setContent(newContent)\n        }\n      }\n      if (changed.has('readonly') || changed.has('preview') || changed.has('editable')) {\n        this._editor.setEditable(this._isEditable)\n      }\n      return\n    }\n\n    // 编辑器未初始化时，只保存待处理内容，不重复初始化\n    if (changed.has('content')) {\n      this._pendingContent = this.content\n    }\n\n    if (changed.has('model-value') && this._useModelValue) {\n      this._pendingContent = this['model-value']\n    }\n\n    // 只有在 firstUpdated 时才会初始化编辑器\n    // 这里不再重复调用 _initEditor()\n  }\n\n  disconnectedCallback() {\n    super.disconnectedCallback()\n    const editorDom = this._editor?.view?.dom\n    editorDom?.removeEventListener('compositionstart', this._handleCompositionStart)\n    editorDom?.removeEventListener('compositionend', this._handleCompositionEnd)\n    this._editor?.destroy()\n    this._editor = null\n  }\n\n  getContent(): string {\n    return this.getContentSnapshot().value\n  }\n\n  getContentSnapshot(): QxsBlocksuiteEditorContentSnapshot {\n    const html = this._editor?.getHTML() ?? ''\n    const text = this._editor?.getText().trim() ?? ''\n\n    return {\n      value: html ? this._transformOutgoingContent(html) : '',\n      html,\n      text,\n      format: this._contentFormatValue,\n    }\n  }\n\n  forceUpdate(): void {\n    this.requestUpdate()\n    if (this._editor) {\n      const newContent = this._transformIncomingContent(this._useModelValue ? this['model-value'] : this.content)\n      if (newContent !== this._editor.getHTML()) {\n        this._editor.commands.setContent(newContent)\n      }\n    }\n  }\n\n  private _applyFormat(command: () => void) {\n    this._clearSlashCommandText()\n    this._clearSlashInlineMarkState(true)\n    command()\n  }\n\n  private _getCurrentLineStart(editor: Editor) {\n    const { selection } = editor.state\n    if (!selection.empty) { return null }\n    return selection.$from.start()\n  }\n\n  private _handleCompositionStart = () => {\n    this._isComposingText = true\n  }\n\n  private _handleCompositionEnd = () => {\n    this._isComposingText = false\n    requestAnimationFrame(() => {\n      this._syncSlashInlineMarkState()\n      this._restoreSlashInlineMarkIfNeeded()\n    })\n  }\n\n  private _getSlashCommandContext() {\n    const editor = this._editor\n    const range = this._slashCommandRange\n    if (!editor || !range) { return null }\n\n    const $from = editor.state.doc.resolve(range.from)\n    return {\n      lineFrom: $from.start(),\n      lineTo: range.from,\n    }\n  }\n\n  private _clearSlashInlineMarkState(force = false) {\n    const editor = this._editor\n    const state = this._slashInlineMarkState\n    if (!editor || !state) { return }\n\n    const { selection } = editor.state\n    const currentLineStart = this._getCurrentLineStart(editor)\n    if (!force && currentLineStart === state.lineStart && selection.empty && selection.to >= state.startPos) {\n      return\n    }\n\n    this._slashInlineMarkState = null\n\n    const pos = editor.state.selection.to\n    let chain = editor.chain().focus().setTextSelection({ from: pos, to: pos })\n\n    switch (state.type) {\n      case 'bold':\n        chain = chain.unsetBold()\n        break\n      case 'italic':\n        chain = chain.unsetItalic()\n        break\n      case 'underline':\n        chain = chain.unsetUnderline()\n        break\n      case 'strike':\n        chain = chain.unsetStrike()\n        break\n      case 'code':\n        chain = chain.unsetCode()\n        break\n    }\n\n    chain.run()\n  }\n\n  private _runInlineMarkAction(\n    type: SlashInlineMark,\n    chain: ReturnType<Editor['chain']>,\n    mode: 'set' | 'unset',\n  ) {\n    switch (type) {\n      case 'bold':\n        return mode === 'set' ? chain.setBold() : chain.unsetBold()\n      case 'italic':\n        return mode === 'set' ? chain.setItalic() : chain.unsetItalic()\n      case 'underline':\n        return mode === 'set' ? chain.setUnderline() : chain.unsetUnderline()\n      case 'strike':\n        return mode === 'set' ? chain.setStrike() : chain.unsetStrike()\n      case 'code':\n        return mode === 'set' ? chain.setCode() : chain.unsetCode()\n    }\n  }\n\n  private _syncSlashInlineMarkState() {\n    if (!this._slashInlineMarkState || !this._editor) { return }\n    if (this._isComposingText) { return }\n    if (this._shouldEndSlashInlineMarkAtCursor()) {\n      this._clearSlashInlineMarkState(true)\n      return\n    }\n    this._clearSlashInlineMarkState()\n  }\n\n  private _shouldEndSlashInlineMarkAtCursor() {\n    const editor = this._editor\n    const state = this._slashInlineMarkState\n    if (!editor || !state) { return false }\n\n    const { selection } = editor.state\n    const currentLineStart = this._getCurrentLineStart(editor)\n    if (!selection.empty || currentLineStart !== state.lineStart || selection.to <= state.startPos) {\n      return false\n    }\n\n    const charBefore = editor.state.doc.textBetween(selection.to - 1, selection.to, '\\n', '\\n')\n    return /\\s/.test(charBefore)\n  }\n\n  private _hasInlineMarkAtCursor(type: SlashInlineMark) {\n    const editor = this._editor\n    if (!editor) { return false }\n\n    const markType = editor.schema.marks[type]\n    if (!markType) { return false }\n\n    const { selection, storedMarks } = editor.state\n    if (!selection.empty) { return false }\n\n    const marks = storedMarks ?? selection.$from.marks()\n    return marks.some(mark => mark.type === markType)\n  }\n\n  private _restoreSlashInlineMarkIfNeeded() {\n    const editor = this._editor\n    const state = this._slashInlineMarkState\n    if (!editor || !state) { return }\n\n    const { selection } = editor.state\n    const currentLineStart = this._getCurrentLineStart(editor)\n    if (!selection.empty || currentLineStart !== state.lineStart || selection.to < state.startPos) { return }\n    if (this._hasInlineMarkAtCursor(state.type)) { return }\n\n    const pos = editor.state.selection.to\n    this._runInlineMarkAction(\n      state.type,\n      editor.chain().focus().setTextSelection({ from: pos, to: pos }),\n      'set',\n    ).run()\n  }\n\n  private _setInlineMarkState(type: SlashInlineMark, startPos: number) {\n    const lineStart = this._getCurrentLineStart(this._editor!)\n    this._slashInlineMarkState = lineStart === null ? null : { type, lineStart, startPos }\n  }\n\n  private _applyInlineMarkToCurrentLine(type: SlashInlineMark, mode: 'set' | 'unset') {\n    const editor = this._editor\n    if (!editor) { return false }\n\n    const { selection } = editor.state\n    if (!selection.empty) {\n      this._runInlineMarkAction(\n        type,\n        editor.chain().focus().setTextSelection({ from: selection.from, to: selection.to }),\n        mode,\n      ).run()\n      if (mode === 'unset') {\n        this._clearSlashInlineMarkState(true)\n      }\n      return true\n    }\n\n    const cursorPos = selection.from\n    const $from = editor.state.doc.resolve(cursorPos)\n    const lineRange = { from: $from.start(), to: $from.end() }\n\n    this._clearSlashInlineMarkState(true)\n\n    if (lineRange.from < lineRange.to) {\n      this._runInlineMarkAction(\n        type,\n        editor.chain().focus().setTextSelection(lineRange),\n        mode,\n      ).run()\n    }\n\n    this._runInlineMarkAction(\n      type,\n      editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n      mode,\n    ).run()\n\n    if (mode === 'set') {\n      this._setInlineMarkState(type, cursorPos)\n    }\n\n    return true\n  }\n\n  private _toggleToolbarInlineMark(type: SlashInlineMark) {\n    return this._applyInlineMarkToCurrentLine(\n      type,\n      this._hasInlineMarkAtCursor(type) ? 'unset' : 'set',\n    )\n  }\n\n  private _applySlashInlineMark(\n    type: SlashInlineMark,\n  ) {\n    const editor = this._editor\n    const context = this._getSlashCommandContext()\n    if (!editor || !context) { return false }\n\n    this._clearSlashCommandText()\n    this._clearSlashInlineMarkState(true)\n\n    const cursorPos = editor.state.selection.to\n    const lineRange = {\n      from: context.lineFrom,\n      to: editor.state.doc.resolve(cursorPos).end(),\n    }\n\n    if (lineRange.from < lineRange.to) {\n      this._runInlineMarkAction(\n        type,\n        editor.chain().focus().setTextSelection(lineRange),\n        'set',\n      ).run()\n    }\n\n    this._runInlineMarkAction(\n      type,\n      editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n      'set',\n    ).run()\n\n    this._setInlineMarkState(type, cursorPos)\n    return true\n  }\n\n  private _applySlashLineBlock(\n    applyBlock: (chain: ReturnType<Editor['chain']>) => ReturnType<Editor['chain']>,\n  ) {\n    const editor = this._editor\n    const context = this._getSlashCommandContext()\n    if (!editor || !context) { return false }\n\n    this._clearSlashCommandText()\n    applyBlock(\n      editor.chain().focus().setTextSelection({ from: context.lineFrom, to: context.lineTo }),\n    ).run()\n    return true\n  }\n\n  private _toggleBold() {\n    if (this._applySlashInlineMark('bold')) {\n      return\n    }\n    this._toggleToolbarInlineMark('bold')\n  }\n\n  private _toggleItalic() {\n    if (this._applySlashInlineMark('italic')) {\n      return\n    }\n    this._toggleToolbarInlineMark('italic')\n  }\n\n  private _toggleUnderline() {\n    if (this._applySlashInlineMark('underline')) {\n      return\n    }\n    this._toggleToolbarInlineMark('underline')\n  }\n\n  private _toggleStrike() {\n    if (this._applySlashInlineMark('strike')) {\n      return\n    }\n    this._toggleToolbarInlineMark('strike')\n  }\n\n  private _toggleCode() {\n    if (this._applySlashInlineMark('code')) {\n      return\n    }\n    this._toggleToolbarInlineMark('code')\n  }\n\n  private _setHeading(level: number) {\n    if (this._applySlashLineBlock(chain => chain.setHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }))) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run())\n  }\n\n  private _setParagraph() {\n    if (this._applySlashLineBlock(chain => chain.setParagraph())) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().setParagraph().run())\n  }\n\n  private _toggleBulletList() {\n    if (this._applySlashLineBlock(chain => chain.toggleBulletList())) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().toggleBulletList().run())\n  }\n\n  private _toggleOrderedList() {\n    if (this._applySlashLineBlock(chain => chain.toggleOrderedList())) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().toggleOrderedList().run())\n  }\n\n  private _toggleTaskList() {\n    if (this._applySlashLineBlock(chain => chain.toggleTaskList())) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().toggleTaskList().run())\n  }\n\n  private _toggleBlockquote() {\n    if (this._applySlashLineBlock(chain => chain.toggleBlockquote())) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().toggleBlockquote().run())\n  }\n\n  private _setTextAlign(align: string) {\n    if (this._applySlashLineBlock(chain => chain.setTextAlign(align as any))) {\n      return\n    }\n    this._applyFormat(() => this._editor?.chain().focus().setTextAlign(align as any).run())\n  }\n\n  private _normalizeLinkUrl(url: string) {\n    const trimmed = url.trim()\n    if (!trimmed) { return '' }\n    if (/^(https?:\\/\\/|mailto:|tel:|#|\\/)/i.test(trimmed)) {\n      return trimmed\n    }\n    return `https://${trimmed}`\n  }\n\n  private _getLinkLabelFromRange(range: { from: number, to: number } | null) {\n    const editor = this._editor\n    if (!editor || !range || range.from >= range.to) {\n      return ''\n    }\n    return editor.state.doc.textBetween(range.from, range.to, '')\n  }\n\n  private _getLinkTargetRange() {\n    const editor = this._editor\n    if (!editor) { return null }\n\n    const { selection } = editor.state\n    if (!selection.empty) {\n      return { from: selection.from, to: selection.to }\n    }\n\n    if (editor.isActive('link')) {\n      editor.chain().focus().extendMarkRange('link').run()\n      return {\n        from: editor.state.selection.from,\n        to: editor.state.selection.to,\n      }\n    }\n\n    const $from = editor.state.doc.resolve(selection.from)\n    return {\n      from: $from.start(),\n      to: $from.end(),\n    }\n  }\n\n  private _setLink(event: MouseEvent) {\n    const editor = this._editor\n    const wrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n    const trigger = event.currentTarget instanceof HTMLElement ? event.currentTarget : null\n    if (!editor || !wrapper || !trigger) { return }\n\n    const linkRange = this._getLinkTargetRange()\n    this._linkSelection = linkRange\n\n    const wrapperRect = wrapper.getBoundingClientRect()\n    const triggerRect = trigger.getBoundingClientRect()\n    const maxLeft = Math.max(12, wrapperRect.width - 332)\n    const left = Math.min(Math.max(12, triggerRect.left - wrapperRect.left), maxLeft)\n    const top = triggerRect.bottom - wrapperRect.top + 8\n    const currentHref = String(editor.getAttributes('link').href || '')\n    const currentLabel = this._getLinkLabelFromRange(linkRange)\n\n    this._linkEditor = {\n      x: left,\n      y: top,\n      visible: true,\n      url: currentHref,\n      label: currentLabel,\n    }\n\n    this.updateComplete.then(() => {\n      const input = this.shadowRoot?.querySelector<HTMLInputElement>('.link-editor__input[data-field=\"url\"]')\n      input?.focus()\n      input?.select()\n    })\n  }\n\n  private _closeLinkEditor() {\n    this._linkEditor = { ...this._linkEditor, visible: false }\n  }\n\n  private _handleLinkEditorInput(event: Event) {\n    const target = event.target as HTMLInputElement\n    const field = target.dataset.field === 'label' ? 'label' : 'url'\n    this._linkEditor = {\n      ...this._linkEditor,\n      [field]: target.value,\n    }\n  }\n\n  private _applyLink() {\n    const editor = this._editor\n    const href = this._normalizeLinkUrl(this._linkEditor.url)\n    const label = this._linkEditor.label.trim() || href\n    if (!editor || !href) { return }\n\n    this._clearSlashCommandText()\n\n    const selection = this._linkSelection ?? this._getLinkTargetRange() ?? editor.state.selection\n    const insertTo = selection.from + label.length\n\n    editor\n      .chain()\n      .focus()\n      .insertContentAt(\n        { from: selection.from, to: selection.to },\n        {\n          type: 'text',\n          text: label,\n          marks: [{ type: 'link', attrs: { href } }],\n        },\n      )\n      .setTextSelection({ from: insertTo, to: insertTo })\n      .run()\n\n    this._closeLinkEditor()\n  }\n\n  private _removeLink() {\n    const editor = this._editor\n    if (!editor) { return }\n\n    const selection = this._linkSelection ?? editor.state.selection\n    let chain = editor.chain().focus()\n    if (selection.from !== selection.to) {\n      chain = chain.setTextSelection(selection)\n    }\n    chain.extendMarkRange('link').unsetLink().run()\n    this._closeLinkEditor()\n  }\n\n  private _handleLinkEditorKeydown(event: KeyboardEvent) {\n    if (event.key === 'Enter') {\n      event.preventDefault()\n      this._applyLink()\n      return\n    }\n    if (event.key === 'Escape') {\n      event.preventDefault()\n      this._closeLinkEditor()\n    }\n  }\n\n  private _insertTable(rows?: number, cols?: number) {\n    this._editor?.chain().focus().insertTable({ rows: rows ?? this._tableRows, cols: cols ?? this._tableCols, withHeaderRow: true }).run()\n  }\n\n  private async _handleImageUpload(e: Event) {\n    const input = e.target as HTMLInputElement\n    const files = Array.from(input.files ?? [])\n    if (!files.length) {\n      input.value = ''\n      return\n    }\n\n    this._clearSlashCommandText()\n    let insertRange = this._pendingImageInsertPos !== null\n      ? { from: this._pendingImageInsertPos, to: this._pendingImageInsertPos }\n      : this._editor\n        ? { from: this._editor.state.selection.from, to: this._editor.state.selection.to }\n        : null\n    this._pendingImageInsertPos = null\n\n    for (const file of files) {\n      try {\n        const naturalWidth = await this._getImageNaturalWidth(file)\n        const src = await this['upload-image'](file)\n        const initialWidth = naturalWidth\n          ? Math.min(naturalWidth, this._getImageMaxWidth())\n          : this._getImageMaxWidth()\n        if (!insertRange && this._editor) {\n          insertRange = { from: this._editor.state.selection.from, to: this._editor.state.selection.to }\n        }\n\n        if (!insertRange) {\n          continue\n        }\n\n        const nextInsertPos = this._insertImageAt(insertRange, {\n          src,\n          width: initialWidth,\n          align: 'left',\n        })\n        insertRange = { from: nextInsertPos, to: nextInsertPos }\n      }\n      catch (err) {\n        console.error('图片上传失败:', err)\n        const error = err instanceof Error ? err : new Error('图片上传失败')\n        this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorImageUploadErrorDetail>('image-upload-error', {\n          detail: {\n            file,\n            error,\n          },\n          bubbles: true,\n          composed: true,\n        }))\n      }\n    }\n    input.value = ''\n  }\n\n  private _triggerImageUpload() {\n    this._clearSlashCommandText()\n    const input = this.shadowRoot?.querySelector<HTMLInputElement>('.image-input')\n    if (!input) { return }\n\n    input.value = ''\n\n    const pickerInput = input as HTMLInputElement & { showPicker?: () => void }\n    if (typeof pickerInput.showPicker === 'function') {\n      try {\n        pickerInput.showPicker()\n        return\n      }\n      catch {\n        // Fall back to click() for browsers that reject showPicker in this context.\n      }\n    }\n\n    input.click()\n  }\n\n  private _insertTableByClick(rows: number, cols: number) {\n    this._clearSlashCommandText()\n    this._tableRows = rows\n    this._tableCols = cols\n    this._insertTable(rows, cols)\n  }\n\n  private _showTableCellToolbar() {\n    if (!this._editor?.isActive('table')) { return }\n    const { state } = this._editor\n    const { selection } = state\n    const coords = this._editor.view.coordsAtPos(selection.from)\n    const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n    if (!editorWrapper) { return }\n    const wrapperRect = editorWrapper.getBoundingClientRect()\n\n    const cellRow = this._getTableCellRow()\n    const cellCol = this._getTableCellCol()\n    const isTopRow = cellRow === 0\n    const isLeftCol = cellCol === 0\n\n    // Only show toolbar on top row or left column\n    if (!isTopRow && !isLeftCol) { return }\n\n    requestAnimationFrame(() => {\n      this._tableCellToolbar = {\n        x: coords.left - wrapperRect.left,\n        y: coords.bottom - wrapperRect.top + 8,\n        visible: true,\n        cellRow,\n        cellCol,\n      }\n    })\n  }\n\n  private _getTableCellRow(): number {\n    if (!this._editor) { return 0 }\n    const { selection } = this._editor.state\n    const $pos = this._editor.state.doc.resolve(selection.from)\n    for (let d = $pos.depth; d > 0; d--) {\n      const node = $pos.node(d)\n      if (node.type.name === 'tableCell') {\n        return $pos.index(d - 1)\n      }\n    }\n    return 0\n  }\n\n  private _getTableCellCol(): number {\n    if (!this._editor) { return 0 }\n    const { selection } = this._editor.state\n    const $pos = this._editor.state.doc.resolve(selection.from)\n    for (let d = $pos.depth; d > 0; d--) {\n      const node = $pos.node(d)\n      if (node.type.name === 'tableCell') {\n        return $pos.index(d)\n      }\n    }\n    return 0\n  }\n\n  private _hideTableCellToolbar() {\n    requestAnimationFrame(() => {\n      this._tableCellToolbar = { ...this._tableCellToolbar, visible: false }\n    })\n  }\n\n  private _addTableRowAbove() {\n    this._editor?.chain().focus().addRowBefore().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _addTableRowBelow() {\n    this._editor?.chain().focus().addRowAfter().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _addTableColumnLeft() {\n    this._editor?.chain().focus().addColumnBefore().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _addTableColumnRight() {\n    this._editor?.chain().focus().addColumnAfter().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _deleteTableRow() {\n    this._editor?.chain().focus().deleteRow().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _deleteTableColumn() {\n    this._editor?.chain().focus().deleteColumn().run()\n    this._hideTableCellToolbar()\n  }\n\n  private _deleteTable() {\n    this._editor?.chain().focus().deleteTable().run()\n    this._hideTableCellToolbar()\n  }\n\n  // Image Toolbar Methods\n  private _showImageToolbar(pos: { x: number, y: number }) {\n    requestAnimationFrame(() => {\n      this._imageToolbar = { x: pos.x, y: pos.y, visible: true }\n    })\n  }\n\n  private _hideImageToolbar() {\n    requestAnimationFrame(() => {\n      this._imageToolbar = { ...this._imageToolbar, visible: false }\n    })\n  }\n\n  private _deleteImage() {\n    const selectedImage = this._getSelectedImageNode()\n    if (!selectedImage) { return }\n\n    const { editor, pos, node } = selectedImage\n    editor.view.dispatch(editor.state.tr.delete(pos, pos + node.nodeSize))\n    this._selectedImage = null\n    this._pendingImageInsertPos = null\n    this._hideImageToolbar()\n  }\n\n  private _insertImageAfter() {\n    const selectedImage = this._getSelectedImageNode()\n    if (!selectedImage) {\n      this._triggerImageUpload()\n      return\n    }\n\n    this._pendingImageInsertPos = selectedImage.pos + selectedImage.node.nodeSize\n    this._triggerImageUpload()\n  }\n\n  private _getSelectedImageNode() {\n    const editor = this._editor\n    const pos = this._selectedImage?.pos\n    if (!editor || pos === undefined) { return null }\n\n    const node = editor.state.doc.nodeAt(pos)\n    if (!node || node.type.name !== 'image') { return null }\n\n    return { editor, pos, node }\n  }\n\n  private _insertImageAt(pos: number | { from: number, to: number }, attrs: Record<string, unknown>) {\n    const editor = this._editor\n    if (!editor) { return 0 }\n\n    const range = typeof pos === 'number'\n      ? {\n          from: Math.max(0, Math.min(pos, editor.state.doc.content.size)),\n          to: Math.max(0, Math.min(pos, editor.state.doc.content.size)),\n        }\n      : {\n          from: Math.max(0, Math.min(pos.from, editor.state.doc.content.size)),\n          to: Math.max(0, Math.min(pos.to, editor.state.doc.content.size)),\n        }\n    const insertPos = range.from\n\n    const chain = editor.chain().focus() as any\n\n    if (typeof chain.insertContentAt === 'function') {\n      let nextChain = chain.insertContentAt(range, { type: 'image', attrs })\n      if (typeof nextChain?.setNodeSelection === 'function') {\n        nextChain = nextChain.setNodeSelection(insertPos)\n      }\n      nextChain.run()\n\n      const insertedNodeSize = editor.state.doc.nodeAt(insertPos)?.nodeSize ?? 1\n      return insertPos + insertedNodeSize\n    }\n\n    if (typeof chain.setImage === 'function') {\n      chain.setImage(attrs).run()\n      return insertPos + 1\n    }\n\n    return insertPos\n  }\n\n  private _updateSelectedImageAttributes(attrs: Record<string, unknown>) {\n    const selectedImage = this._getSelectedImageNode()\n    if (!selectedImage) { return }\n\n    const { editor, pos, node } = selectedImage\n    editor.view.dispatch(editor.state.tr.setNodeMarkup(pos, undefined, {\n      ...node.attrs,\n      ...attrs,\n    }))\n  }\n\n  private _setImageWidth(width: number) {\n    const nextWidth = Math.max(MIN_IMAGE_WIDTH, Math.min(this._getImageMaxWidth(), Math.round(width)))\n    this._updateSelectedImageAttributes({ width: nextWidth })\n  }\n\n  private _handleImageWidthInput(e: Event) {\n    const rawValue = (e.target as HTMLInputElement).value.trim()\n    if (!rawValue) { return }\n\n    const value = Number(rawValue)\n    if (!Number.isFinite(value)) { return }\n    this._setImageWidth(value)\n  }\n\n  private _setImageAlignLeft() {\n    this._updateSelectedImageAttributes({ align: 'left' })\n  }\n\n  private _setImageAlignCenter() {\n    this._updateSelectedImageAttributes({ align: 'center' })\n  }\n\n  private _setImageAlignRight() {\n    this._updateSelectedImageAttributes({ align: 'right' })\n  }\n\n  private _getTextLabel(): string {\n    const editor = this._editor\n    if (!editor) { return '正文' }\n    if (editor.isActive('heading', { level: 1 })) { return '标题 1' }\n    if (editor.isActive('heading', { level: 2 })) { return '标题 2' }\n    if (editor.isActive('heading', { level: 3 })) { return '标题 3' }\n    return '正文'\n  }\n\n  private _getAlignLabel(): string {\n    const editor = this._editor\n    if (!editor) { return '对齐' }\n    if (editor.isActive({ textAlign: 'center' })) { return '居中' }\n    if (editor.isActive({ textAlign: 'right' })) { return '右对齐' }\n    return '左对齐'\n  }\n\n  private _renderImageControls() {\n    const selectedImage = this._selectedImage\n    if (!selectedImage) { return '' }\n\n    return html`\n      <button class=\"bubble-btn danger\" title=\"删除图片\" @click=${this._deleteImage}>\n        <svg viewBox=\"0 0 24 24\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n      </button>\n      <button class=\"bubble-btn\" title=\"添加图片\" @click=${this._insertImageAfter}>\n        <svg viewBox=\"0 0 24 24\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n      </button>\n      <div class=\"bubble-divider\"></div>\n      <span class=\"image-control-label\">对齐</span>\n      <button class=\"bubble-btn ${selectedImage.align === 'left' ? 'is-active' : ''}\" title=\"左对齐\" @click=${this._setImageAlignLeft}>\n        <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n      </button>\n      <button class=\"bubble-btn ${selectedImage.align === 'center' ? 'is-active' : ''}\" title=\"居中\" @click=${this._setImageAlignCenter}>\n        <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n      </button>\n      <button class=\"bubble-btn ${selectedImage.align === 'right' ? 'is-active' : ''}\" title=\"右对齐\" @click=${this._setImageAlignRight}>\n        <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n      </button>\n      <div class=\"image-size-control\">\n        <span class=\"image-size-label\">宽度</span>\n        <input\n          class=\"image-size-range\"\n          type=\"number\"\n          min=\"${MIN_IMAGE_WIDTH}\"\n          max=\"${this._getImageMaxWidth()}\"\n          .value=${String(selectedImage.width)}\n          @input=${this._handleImageWidthInput}\n        />\n      </div>\n    `\n  }\n\n  private _joinToolbarGroups(groups: unknown[]) {\n    return groups.flatMap((group, index) => index === 0\n      ? [group]\n      : [html`<div class=\"bubble-divider\"></div>`, group])\n  }\n\n  private _renderFormatToolbarGroup(editor: Editor | null) {\n    return html`\n      ${this._renderToolbarButton('bold', {\n        title: '加粗',\n        active: editor?.isActive('bold'),\n        onClick: this._toggleBold,\n        icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>`,\n      })}\n      ${this._renderToolbarButton('italic', {\n        title: '斜体',\n        active: editor?.isActive('italic'),\n        onClick: this._toggleItalic,\n        icon: html`<svg viewBox=\"0 0 24 24\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>`,\n      })}\n      ${this._renderToolbarButton('underline', {\n        title: '下划线',\n        active: editor?.isActive('underline'),\n        onClick: this._toggleUnderline,\n        icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>`,\n      })}\n      ${this._renderToolbarButton('strike', {\n        title: '删除线',\n        active: editor?.isActive('strike'),\n        onClick: this._toggleStrike,\n        icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M17.3 4.9c-2.3-.6-4.4-1-6.2-.9-2.7 0-5.3.7-5.3 3.6 0 1.5 1.8 3.3 5.3 3.9h.2m8.2 3.2c.3.4.4.8.4 1.3 0 2.9-2.7 3.6-6.2 3.6-2.3 0-4.4-.3-6.2-.9M4 12h16\"/></svg>`,\n      })}\n    `\n  }\n\n  private _renderHeadingToolbarGroup(editor: Editor | null) {\n    return html`\n      <div class=\"bubble-dropdown\">\n        <button class=\"bubble-dropdown-btn\">\n          ${this._getTextLabel()}\n          <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n        </button>\n        <div class=\"bubble-dropdown-menu\">\n          <button class=\"bubble-dropdown-item ${!editor?.isActive('heading') ? 'is-active' : ''}\" @click=${this._setParagraph}>正文</button>\n          <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 1 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(1)}>标题 1</button>\n          <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(2)}>标题 2</button>\n          <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 3 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(3)}>标题 3</button>\n        </div>\n      </div>\n    `\n  }\n\n  private _renderAlignToolbarGroup(editor: Editor | null) {\n    return html`\n      <div class=\"bubble-dropdown\">\n        <button class=\"bubble-dropdown-btn\">\n          ${this._getAlignLabel()}\n          <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n        </button>\n        <div class=\"bubble-dropdown-menu\">\n          <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'left' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('left')}>\n            <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n            左对齐\n          </button>\n          <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'center' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('center')}>\n            <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n            居中\n          </button>\n          <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'right' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('right')}>\n            <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n            右对齐\n          </button>\n        </div>\n      </div>\n    `\n  }\n\n  private _renderCodeLinkImageToolbarGroup(editor: Editor | null) {\n    return html`\n      ${this._hasToolbarItem('code')\n        ? this._renderToolbarButton('code', {\n            title: '行内代码',\n            active: editor?.isActive('code'),\n            onClick: this._toggleCode,\n            icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n          })\n        : ''}\n      ${this._hasToolbarItem('link')\n        ? this._renderToolbarButton('link', {\n            title: '链接',\n            active: editor?.isActive('link'),\n            onClick: this._setLink,\n            icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n          })\n        : ''}\n      ${this._hasToolbarItem('image')\n        ? this._renderToolbarButton('image', {\n            title: '图片',\n            onClick: this._triggerImageUpload,\n            icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n          })\n        : ''}\n    `\n  }\n\n  private _renderCodeToolbarButton(editor: Editor | null) {\n    return this._renderToolbarButton('code', {\n      title: '行内代码',\n      active: editor?.isActive('code'),\n      onClick: this._toggleCode,\n      icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n    })\n  }\n\n  private _renderLinkToolbarButton(editor: Editor | null) {\n    return this._renderToolbarButton('link', {\n      title: '链接',\n      active: editor?.isActive('link'),\n      onClick: this._setLink,\n      icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n    })\n  }\n\n  private _renderImageToolbarButton() {\n    return this._renderToolbarButton('image', {\n      title: '图片',\n      onClick: this._triggerImageUpload,\n      icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n    })\n  }\n\n  private _renderListToolbarGroup(editor: Editor | null) {\n    return html`\n      ${this._renderToolbarButton('bulletList', {\n        title: '无序列表',\n        active: editor?.isActive('bulletList'),\n        onClick: this._toggleBulletList,\n        icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n          <line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/>\n          <line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/>\n          <line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/>\n          <circle cx=\"4\" cy=\"6\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n          <circle cx=\"4\" cy=\"12\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n          <circle cx=\"4\" cy=\"18\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n        </svg>`,\n      })}\n      ${this._renderToolbarButton('orderedList', {\n        title: '有序列表',\n        active: editor?.isActive('orderedList'),\n        onClick: this._toggleOrderedList,\n        icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n          <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/>\n          <line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/>\n          <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/>\n          <path d=\"M4 6h1v4\"/>\n          <path d=\"M4 10h2\"/>\n          <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1.5\"/>\n        </svg>`,\n      })}\n      ${this._renderToolbarButton('taskList', {\n        title: '待办列表',\n        active: editor?.isActive('taskList'),\n        onClick: this._toggleTaskList,\n        icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n          <rect x=\"3\" y=\"5\" width=\"4\" height=\"4\" rx=\"1\"/>\n          <polyline points=\"4 7 5 8 6.5 6.5\"/>\n          <line x1=\"10\" y1=\"7\" x2=\"21\" y2=\"7\"/>\n          <rect x=\"3\" y=\"15\" width=\"4\" height=\"4\" rx=\"1\"/>\n          <line x1=\"10\" y1=\"17\" x2=\"21\" y2=\"17\"/>\n        </svg>`,\n      })}\n    `\n  }\n\n  private _renderBlockquoteToolbarGroup(editor: Editor | null) {\n    return html`\n      ${this._renderToolbarButton('blockquote', {\n        title: '引用',\n        active: editor?.isActive('blockquote'),\n        onClick: this._toggleBlockquote,\n        icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/></svg>`,\n      })}\n    `\n  }\n\n  private _renderTableToolbarGroup() {\n    const label = this._getHeaderToolbarLabel('table')\n    return html`\n      <div\n        class=\"bubble-dropdown ${this._tableDropdownOpen ? 'is-open' : ''}\"\n        @mouseenter=${() => {\n          this._tableDropdownOpen = true\n          this._hoverRow = 0\n          this._hoverCol = 0\n        }}\n        @mouseleave=${() => this._tableDropdownOpen = false}\n      >\n        <button class=\"bubble-dropdown-btn ${label ? 'has-label' : ''}\" title=\"表格\">\n          <svg viewBox=\"0 0 24 24\" style=\"width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none;\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>\n          ${label ? html`<span class=\"bubble-dropdown-btn__label\">${label}</span>` : null}\n        </button>\n        <div class=\"bubble-dropdown-menu\">\n          <div class=\"table-grid-preview\">\n            ${this._renderTableGrid()}\n          </div>\n          <div class=\"table-size-hint\">\n            <span>${this._hoverRow > 0 ? `${this._hoverRow} × ${this._hoverCol}` : `${this._tableRows} × ${this._tableCols}`}</span>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private _getToolbarMergeKey(item: EditorToolbarItem): string {\n    if (item === 'code' || item === 'link' || item === 'image') {\n      return 'code-link-image'\n    }\n\n    return item\n  }\n\n  private _renderToolbarItemByKey(editor: Editor | null, item: EditorToolbarItem): unknown {\n    switch (item) {\n      case 'format':\n        return this._renderFormatToolbarGroup(editor)\n      case 'heading':\n        return this._renderHeadingToolbarGroup(editor)\n      case 'align':\n        return this._renderAlignToolbarGroup(editor)\n      case 'code':\n        return this._renderCodeToolbarButton(editor)\n      case 'link':\n        return this._renderLinkToolbarButton(editor)\n      case 'image':\n        return this._renderImageToolbarButton()\n      case 'list':\n        return this._renderListToolbarGroup(editor)\n      case 'blockquote':\n        return this._renderBlockquoteToolbarGroup(editor)\n      case 'table':\n        return this._renderTableToolbarGroup()\n      default:\n        return null\n    }\n  }\n\n  private _renderTextToolbar(editor: Editor | null) {\n    const groups: unknown[] = []\n\n    let currentMergeKey = ''\n    let currentGroup: unknown[] = []\n\n    const flushGroup = () => {\n      if (currentGroup.length) {\n        groups.push([...currentGroup])\n        currentGroup = []\n      }\n    }\n\n    for (const item of this._toolbarItemsValue) {\n      const rendered = this._renderToolbarItemByKey(editor, item)\n      if (!rendered) {\n        continue\n      }\n\n      const mergeKey = this._getToolbarMergeKey(item)\n      if (currentGroup.length && mergeKey !== currentMergeKey) {\n        flushGroup()\n      }\n\n      currentMergeKey = mergeKey\n      currentGroup.push(rendered)\n    }\n\n    flushGroup()\n\n    return this._joinToolbarGroups(groups)\n  }\n\n  private _updateBubbleMenuPosition() {\n    if (this._toolbarModeValue !== 'slash') { return }\n    requestAnimationFrame(() => {\n      const bubbleMenu = this.shadowRoot?.querySelector<HTMLElement>('.bubble-menu')\n      const proseMirror = this.shadowRoot?.querySelector<HTMLElement>('.ProseMirror')\n      const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n      if (!bubbleMenu || !proseMirror || !editorWrapper) { return }\n\n      const editor = this._editor\n      const isInTable = editor?.isActive('table') ?? false\n      const { selection } = editor?.state ?? { selection: null }\n\n      // 如果选中了表格节点（而不只是单元格内的文字），隐藏菜单\n      if (isInTable && selection && !selection.empty && editor) {\n        const { from, to } = selection\n        const $from = editor.state.doc.resolve(from)\n        const $to = editor.state.doc.resolve(to)\n        // 检查选区起点和终点之间是否有表格节点\n        let hasTableInSelection = false\n        for (let d = $from.depth; d >= 0; d--) {\n          if ($from.node(d).type.name === 'table') {\n            hasTableInSelection = true\n            break\n          }\n        }\n        // 如果选区起点在表格外但终点在表格内，或者选区跨越了表格\n        const fromAncestor = $from.node($from.depth)\n        const toAncestor = $to.node($to.depth)\n        if (fromAncestor.type.name === 'table' || toAncestor.type.name === 'table') {\n          hasTableInSelection = true\n        }\n        if (hasTableInSelection) {\n          bubbleMenu.style.opacity = '0'\n          bubbleMenu.style.visibility = 'hidden'\n          return\n        }\n      }\n\n      // 如果有选中文字，显示菜单\n      if (selection && !selection.empty) {\n        // continue to show menu\n      }\n      else if (!selection || (selection.empty && !this._hasSlashCommand)) {\n        bubbleMenu.style.opacity = '0'\n        bubbleMenu.style.visibility = 'hidden'\n        return\n      }\n\n      const wrapperRect = editorWrapper.getBoundingClientRect()\n      const menuRect = bubbleMenu.getBoundingClientRect()\n\n      const { from } = selection!\n      const coords = this._editor?.view.coordsAtPos(from)\n      if (!coords) { return }\n\n      let left = coords.left - wrapperRect.left\n      let top = coords.top - wrapperRect.top - 40\n\n      if (left + menuRect.width > wrapperRect.width) {\n        left = wrapperRect.width - menuRect.width - 8\n      }\n      if (left < 0) {\n        left = 8\n      }\n\n      if (top < 0) {\n        top = coords.bottom - wrapperRect.top + 8\n      }\n\n      bubbleMenu.style.left = `${left}px`\n      bubbleMenu.style.top = `${top}px`\n      bubbleMenu.style.opacity = '1'\n      bubbleMenu.style.visibility = 'visible'\n    })\n  }\n\n  render() {\n    const editor = this._editor\n    const headerTemplate = !this._previewValue && this._toolbarModeValue === 'header'\n      ? html`\n        <div class=\"editor-header ${this._isHeaderVisible() ? 'is-visible' : ''}\">\n          <div class=\"editor-header__inner\" @mousedown=${this._handleHeaderToolbarMouseDown}>\n            ${this._selectedImage\n              ? this._renderImageControls()\n              : this._renderTextToolbar(editor)}\n          </div>\n        </div>\n      `\n      : null\n    const shouldShowCharacterCount = this._showCharacterCountValue && !this._previewValue\n\n    return html`\n      <div\n        class=\"editor-wrapper ${!editor ? 'loading' : ''} ${this._previewValue ? 'preview' : ''} ${this._toolbarPositionValue === 'bottom' ? 'toolbar-bottom' : ''}\"\n        style=${this._wrapperStyleValue}\n        @mousedown=${this._handleWrapperMouseDown}\n        @focusin=${this._handleWrapperFocusIn}\n        @focusout=${this._handleWrapperFocusOut}\n      >\n        ${!editor\n          ? html`\n          <div class=\"loading-placeholder\">\n            <div class=\"loading-spinner\"></div>\n            <span>编辑器加载中...</span>\n          </div>\n        `\n          : ''}\n        <input\n          type=\"file\"\n          accept=\"image/*\"\n          multiple\n          class=\"image-input\"\n          @change=${this._handleImageUpload}\n        />\n\n        ${this._toolbarPositionValue === 'top' ? headerTemplate : null}\n\n        <!-- Bubble Menu (悬浮操作栏) -->\n        ${!this._previewValue && this._toolbarModeValue === 'slash'\n          ? html`\n        <div class=\"bubble-menu\">\n          ${this._renderTextToolbar(editor)}\n        </div>\n        `\n          : ''}\n\n        <div class=\"editor-content\" data-empty-hint=${this._resolvedPlaceholder}></div>\n\n        ${this._toolbarPositionValue === 'bottom' ? headerTemplate : null}\n\n        ${shouldShowCharacterCount\n          ? html`<div class=\"editor-footer\">${this._getEditorCharacterCount()} 字符</div>`\n          : null}\n\n        ${this._linkEditor.visible\n          ? html`\n          <div\n            class=\"link-editor\"\n            style=\"left: ${this._linkEditor.x}px; top: ${this._linkEditor.y}px;\"\n            @mousedown=${(event: MouseEvent) => event.stopPropagation()}\n            @click=${(event: MouseEvent) => event.stopPropagation()}\n          >\n            <div class=\"link-editor__field\">\n              <span class=\"link-editor__label\">链接地址</span>\n              <input\n                class=\"link-editor__input\"\n                data-field=\"url\"\n                type=\"text\"\n                placeholder=\"输入或粘贴链接\"\n                .value=${this._linkEditor.url}\n                @input=${this._handleLinkEditorInput}\n                @keydown=${this._handleLinkEditorKeydown}\n              />\n            </div>\n            <div class=\"link-editor__field\">\n              <span class=\"link-editor__label\">链接名字</span>\n              <input\n                class=\"link-editor__input\"\n                data-field=\"label\"\n                type=\"text\"\n                placeholder=\"输入展示名称\"\n                .value=${this._linkEditor.label}\n                @input=${this._handleLinkEditorInput}\n                @keydown=${this._handleLinkEditorKeydown}\n              />\n            </div>\n            <div class=\"link-editor__actions\">\n              <button class=\"link-editor__action primary\" title=\"应用链接\" @click=${this._applyLink}>应用</button>\n              <button class=\"link-editor__action\" title=\"取消链接编辑\" @click=${this._closeLinkEditor}>取消</button>\n              ${(editor?.isActive('link') || this._linkEditor.url)\n                ? html`<button class=\"link-editor__action danger\" title=\"移除链接\" @click=${this._removeLink}>移除</button>`\n                : ''}\n            </div>\n          </div>\n          `\n          : ''}\n\n        <!-- Table Cell Toolbar -->\n        ${this._tableCellToolbar.visible && editor?.isActive('table')\n          ? html`\n          <div\n            class=\"table-cell-toolbar\"\n            style=\"left: ${this._tableCellToolbar.x}px; top: ${this._tableCellToolbar.y}px;\"\n            @mousedown=${(e: Event) => e.preventDefault()}\n          >\n            ${this._tableCellToolbar.cellRow === 0\n              ? html`\n              <button class=\"table-cell-toolbar-btn\" title=\"上方添加行\" @click=${this._addTableRowAbove}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"7\"/><line x1=\"10\" y1=\"5\" x2=\"14\" y2=\"5\"/></svg>\n              </button>\n              <button class=\"table-cell-toolbar-btn\" title=\"下方添加行\" @click=${this._addTableRowBelow}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"17\"/><line x1=\"10\" y1=\"19\" x2=\"14\" y2=\"19\"/></svg>\n              </button>\n              <button class=\"table-cell-toolbar-btn danger\" title=\"删除行\" @click=${this._deleteTableRow}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\"/><line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"14\"/></svg>\n              </button>\n            `\n              : ''}\n            ${this._tableCellToolbar.cellCol === 0\n              ? html`\n              ${this._tableCellToolbar.cellRow !== 0 ? html`<div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>` : ''}\n              <button class=\"table-cell-toolbar-btn\" title=\"左侧添加列\" @click=${this._addTableColumnLeft}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"7\" y2=\"12\"/><line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\"/></svg>\n              </button>\n              <button class=\"table-cell-toolbar-btn\" title=\"右侧添加列\" @click=${this._addTableColumnRight}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"21\" y1=\"12\" x2=\"17\" y2=\"12\"/><line x1=\"19\" y1=\"10\" x2=\"19\" y2=\"14\"/></svg>\n              </button>\n              <button class=\"table-cell-toolbar-btn danger\" title=\"删除列\" @click=${this._deleteTableColumn}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"10\" y1=\"9\" x2=\"14\" y2=\"9\"/><line x1=\"10\" y1=\"15\" x2=\"14\" y2=\"15\"/></svg>\n              </button>\n            `\n              : ''}\n            ${this._tableCellToolbar.cellRow === 0 && this._tableCellToolbar.cellCol === 0\n              ? html`\n              <div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>\n              <button class=\"table-cell-toolbar-btn danger\" title=\"删除表格\" @click=${this._deleteTable}>\n                <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n              </button>\n            `\n              : ''}\n          </div>\n          `\n          : ''}\n\n        <!-- Image Toolbar -->\n        ${this._toolbarModeValue === 'slash' && this._imageToolbar.visible\n          ? html`\n          <div\n            class=\"image-toolbar\"\n            style=\"left: ${this._imageToolbar.x}px; top: ${this._imageToolbar.y}px;\"\n            @mousedown=${(e: Event) => e.preventDefault()}\n          >\n            ${this._renderImageControls()}\n          </div>\n          `\n          : ''}\n      </div>\n    `\n  }\n\n  private _renderTableGrid() {\n    const cells = []\n    for (let i = 0; i < 100; i++) {\n      const row = Math.floor(i / 10) + 1\n      const col = (i % 10) + 1\n      const isHighlight = this._hoverRow > 0 && row <= this._hoverRow && col <= this._hoverCol\n      cells.push(html`\n        <div\n          class=\"table-cell ${isHighlight ? 'selected' : ''}\"\n          @click=${() => {\n            this._insertTableByClick(row, col)\n            this._tableDropdownOpen = false\n          }}\n          @mouseenter=${() => {\n            this._hoverRow = row\n            this._hoverCol = col\n          }}\n          @mouseleave=${() => {\n            this._hoverRow = 0\n            this._hoverCol = 0\n          }}\n        ></div>\n      `)\n    }\n    return cells\n  }\n}\n\nexport function register() {}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'qxs-blocksuite-editor': QxsBlocksuiteEditor\n  }\n}\n"],"names":["DEFAULT_IMAGE_WIDTH","MIN_IMAGE_WIDTH","DEFAULT_HEADER_PLACEHOLDER","DEFAULT_SLASH_PLACEHOLDER","DEFAULT_MIN_HEIGHT","DEFAULT_HEADER_TOOLBAR_LABELS","HEADER_TOOLBAR_LABEL_KEYS","TaskList","TiptapNode","HTMLAttributes","mergeAttributes","commands","TaskItem","element","attributes","checked","ExtendedListItem","ListItem","ExtendedImage","Image","attr","value","width","style","QxsBlocksuiteEditor","LitElement","file","resolve","reject","reader","e","shadow","styleEl","overflowY","parseEditorToolbarItems","SIMPLE_EDITOR_TOOLBAR","DEFAULT_EDITOR_TOOLBAR","item","source","parsed","error","labels","key","message","options","label","className","html","transform","transformIncomingContentByFormat","EMPTY_EDITOR_HTML","transformOutgoingContentByFormat","el","useModel","modelValue","contentValue","initialContent","extensions","Document","Paragraph","Text","Bold","Italic","Underline","Strike","Code","Heading","BulletList","OrderedList","Blockquote","HorizontalRule","History","Link","TextAlign","Table","TableRow","TableCell","TableHeader","Placeholder","Editor","event","target","editor","taskItem","basePos","searchFrom","searchTo","taskItemPos","node","pos","snapshot","editorContent","editorWrapper","handleEditorClick","nextTarget","wrapper","selection","availableWidth","objectUrl","image","naturalWidth","align","wrapperRect","coords","x","y","from","to","$from","textBefore","matched","slashText","changed","nextValue","newContent","editorDom","text","command","range","force","state","currentLineStart","chain","type","mode","charBefore","markType","storedMarks","mark","startPos","lineStart","cursorPos","lineRange","context","applyBlock","level","url","trimmed","trigger","linkRange","triggerRect","maxLeft","left","top","currentHref","currentLabel","input","field","href","insertTo","rows","cols","files","insertRange","src","initialWidth","nextInsertPos","err","pickerInput","cellRow","cellCol","$pos","d","selectedImage","attrs","insertPos","nextChain","insertedNodeSize","nextWidth","rawValue","groups","group","index","currentMergeKey","currentGroup","flushGroup","rendered","mergeKey","bubbleMenu","proseMirror","isInTable","$to","hasTableInSelection","fromAncestor","toAncestor","menuRect","headerTemplate","shouldShowCharacterCount","cells","i","row","col","isHighlight","css","__decorateClass","property","safeCustomElement"],"mappings":"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A;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAA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"}