{"version":3,"file":"rich-text-editor.cjs","sources":["../../../components/rich_text_editor/extensions/emoji/EmojiComponent.vue","../../../components/rich_text_editor/extensions/suggestion/SuggestionList.vue","../../../components/rich_text_editor/extensions/emoji/EmojiSuggestion.vue","../../../components/rich_text_editor/extensions/tippy_plugins/hide_on_esc.js","../../../components/rich_text_editor/extensions/emoji/suggestion.js","../../../components/rich_text_editor/extensions/emoji/emoji.js","../../../components/rich_text_editor/extensions/custom_link/utils.js","../../../components/rich_text_editor/extensions/custom_link/autolink.js","../../../components/rich_text_editor/extensions/custom_link/custom_link.js","../../../components/rich_text_editor/extensions/image/image.js","../../../components/rich_text_editor/extensions/div/div.js","../../../components/rich_text_editor/extensions/mentions/MentionComponent.vue","../../../components/rich_text_editor/extensions/mentions/mention.js","../../../components/rich_text_editor/extensions/channels/ChannelComponent.vue","../../../components/rich_text_editor/extensions/channels/channel.js","../../../components/rich_text_editor/extensions/slash_command/SlashCommandComponent.vue","../../../components/rich_text_editor/extensions/slash_command/slash_command.js","../../../components/rich_text_editor/extensions/mentions/MentionSuggestion.vue","../../../components/rich_text_editor/extensions/mentions/suggestion.js","../../../components/rich_text_editor/extensions/channels/ChannelSuggestion.vue","../../../components/rich_text_editor/extensions/channels/suggestion.js","../../../components/rich_text_editor/extensions/slash_command/SlashCommandSuggestion.vue","../../../components/rich_text_editor/extensions/slash_command/suggestion.js","../../../components/rich_text_editor/rich_text_editor.vue"],"sourcesContent":["<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <node-view-wrapper\n    class=\"d-d-inline-block d-va-bottom d-lh0\"\n  >\n    <dt-emoji\n      v-if=\"node.attrs.code\"\n      size=\"500\"\n      :code=\"node.attrs.code\"\n    />\n\n    <template v-else>\n      <dt-skeleton\n        v-if=\"showSkeleton\"\n        :offset=\"0\"\n        class=\"d-icon d-icon--size-500\"\n        :shape-option=\"{ shape: 'circle', size: '100%' }\"\n      />\n\n      <img\n        v-show=\"!showSkeleton\"\n        class=\"d-icon d-icon--size-500\"\n        :alt=\"node.attrs.name\"\n        :aria-label=\"node.attrs.name\"\n        :title=\"node.attrs.name\"\n        :src=\"node.attrs.image\"\n        @load=\"handleImageLoad\"\n        @error=\"handleImageError\"\n      >\n    </template>\n  </node-view-wrapper>\n</template>\n\n<script>\nimport { nodeViewProps, NodeViewWrapper } from '@tiptap/vue-2';\nimport { DtEmoji } from '@/components/emoji';\nimport { DtSkeleton } from '@/components/skeleton';\n\n\nexport default {\n  name: 'EmojiComponent',\n  components: {\n    NodeViewWrapper,\n    DtEmoji,\n    DtSkeleton,\n  },\n\n  props: nodeViewProps,\n\n  data () {\n    return {\n      showSkeleton: true,\n    };\n  },\n\n  methods: {\n    handleImageLoad () {\n      this.showSkeleton = false;\n    },\n\n    handleImageError: function (event) {\n      this.showSkeleton = false;\n      event.target.parentNode.remove();\n    },\n  },\n};\n</script>\n","<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <div class=\"d-popover__dialog d-suggestion-list__container\">\n    <ul\n      v-show=\"items.length\"\n      ref=\"suggestionList\"\n      class=\"d-suggestion-list\"\n    >\n      <dt-list-item\n        v-for=\"(item, index) in items\"\n        :key=\"item.id\"\n        :class=\"[\n          'd-suggestion-list__item',\n          { 'd-list-item--highlighted': index === selectedIndex },\n        ]\"\n        navigation-type=\"arrow-keys\"\n        @click=\"selectItem(index)\"\n        @keydown.prevent=\"onKeyDown\"\n      >\n        <component\n          :is=\"itemComponent\"\n          :item=\"item\"\n        />\n      </dt-list-item>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { DtListItem } from '@/components/list_item';\n\nexport default {\n  name: 'SuggestionList',\n  components: {\n    DtListItem,\n  },\n\n  props: {\n    items: {\n      type: Array,\n      required: true,\n    },\n\n    command: {\n      type: Function,\n      required: true,\n    },\n\n    itemComponent: {\n      type: Object,\n      required: true,\n    },\n\n    itemType: {\n      type: String,\n      required: true,\n    },\n  },\n\n  data () {\n    return {\n      selectedIndex: 0,\n    };\n  },\n\n  watch: {\n    items () {\n      this.selectedIndex = 0;\n    },\n  },\n\n  methods: {\n    onKeyDown ({ event }) {\n      if (event.key === 'ArrowUp') {\n        this.upHandler();\n        return true;\n      }\n\n      if (event.key === 'ArrowDown') {\n        this.downHandler();\n        return true;\n      }\n\n      if (event.key === 'Enter' || event.key === 'Tab') {\n        this.selectHandler();\n        return true;\n      }\n\n      return false;\n    },\n\n    upHandler () {\n      this.selectedIndex = ((this.selectedIndex + this.items.length) - 1) % this.items.length;\n\n      this.scrollActiveElementIntoView();\n    },\n\n    downHandler () {\n      this.selectedIndex = (this.selectedIndex + 1) % this.items.length;\n\n      this.scrollActiveElementIntoView();\n    },\n\n    async scrollActiveElementIntoView () {\n      await this.$nextTick();\n      const activeElement = this.$refs.suggestionList.querySelector('.d-list-item--highlighted');\n      if (activeElement) {\n        activeElement.scrollIntoView({\n          behaviour: 'smooth',\n          block: 'center',\n        });\n      }\n    },\n\n    selectHandler () {\n      this.selectItem(this.selectedIndex);\n    },\n\n    selectItem (index) {\n      const item = this.items[index];\n\n      switch (this.itemType) {\n        case 'emoji':\n          this.command(item);\n          return;\n        case 'mention':\n          this.command({ name: item.name, id: item.id, avatarSrc: item.avatarSrc });\n          break;\n        case 'channel':\n          this.command({ name: item.name, id: item.id });\n          break;\n        case 'slash-command':\n          this.command({ command: item.command });\n          break;\n      }\n    },\n  },\n};\n</script>\n","<template>\n  <dt-stack\n    direction=\"row\"\n    gap=\"400\"\n  >\n    <dt-emoji\n      size=\"200\"\n      :code=\"item.code\"\n    />\n    {{ item.code }}\n  </dt-stack>\n</template>\n\n<script>\nimport { DtEmoji } from '@/components/emoji';\nimport { DtStack } from '@/components/stack';\n\nexport default {\n  name: 'EmojiSuggestion',\n  components: {\n    DtEmoji,\n    DtStack,\n  },\n\n  props: {\n    item: {\n      type: Object,\n      required: true,\n    },\n  },\n};\n</script>\n","export default {\n  name: 'hideOnEsc',\n  defaultValue: true,\n  fn ({ hide }) {\n    function onKeyDown (event) {\n      if (event.keyCode === 27) {\n        hide();\n      }\n    }\n\n    return {\n      onShow () {\n        document.addEventListener('keydown', onKeyDown);\n      },\n      onHide () {\n        document.removeEventListener('keydown', onKeyDown);\n      },\n    };\n  },\n};\n","import { VueRenderer } from '@tiptap/vue-2';\nimport { emojisIndexed } from '@dialpad/dialtone-emojis';\n\nimport SuggestionList from '../suggestion/SuggestionList.vue';\nimport EmojiSuggestion from './EmojiSuggestion.vue';\n\nimport tippy from 'tippy.js';\nimport hideOnEsc from '../tippy_plugins/hide_on_esc';\n\nconst suggestionLimit = 20;\n\nexport default {\n  items: ({ query }) => {\n    if (query.length < 2) {\n      return [];\n    }\n    const emojiList = Object.values(emojisIndexed);\n    query = query.toLowerCase();\n\n    const filteredEmoji = emojiList\n      .filter(\n        item => [\n          item.name,\n          item.shortname.replaceAll(':', ''),\n          ...item.keywords,\n        ].some(text => text.startsWith(query)),\n      ).splice(0, suggestionLimit);\n    return filteredEmoji.map(item => ({ code: item.shortname }));\n  },\n\n  command: ({ editor, range, props }) => {\n    // increase range.to by one when the next node is of type \"text\"\n    // and starts with a space character\n    const nodeAfter = editor.view.state.selection.$to.nodeAfter;\n    const overrideSpace = nodeAfter?.text?.startsWith(' ');\n\n    if (overrideSpace) {\n      range.to += 1;\n    }\n\n    editor\n      .chain()\n      .focus()\n      .insertContentAt(range, [\n        {\n          type: 'emoji',\n          attrs: props,\n        },\n      ])\n      .run();\n\n    window.getSelection()?.collapseToEnd();\n  },\n\n  render: () => {\n    let component;\n    let popup;\n    let popupIsOpen = false;\n\n    return {\n      onStart: props => {\n        component = new VueRenderer(SuggestionList, {\n          parent: this,\n          propsData: {\n            itemComponent: EmojiSuggestion,\n            itemType: 'emoji',\n            ...props,\n          },\n          editor: props.editor,\n        });\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup = tippy('body', {\n          getReferenceClientRect: props.clientRect,\n          appendTo: () => document.body,\n          content: component.element,\n          showOnCreate: false,\n          onShow: () => { popupIsOpen = true; },\n          onHidden: () => { popupIsOpen = false; },\n          interactive: true,\n          trigger: 'manual',\n          placement: 'top-start',\n          zIndex: 650,\n          plugins: [hideOnEsc],\n        });\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        }\n      },\n\n      onUpdate (props) {\n        component?.updateProps(props);\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        } else {\n          popup?.[0].hide();\n        }\n        popup?.[0].setProps({\n          getReferenceClientRect: props.clientRect,\n        });\n      },\n\n      onKeyDown (props) {\n        if (popupIsOpen) {\n          return component?.ref?.onKeyDown(props);\n        }\n      },\n\n      onExit () {\n        popup?.[0].destroy();\n        popup = null;\n        component?.destroy();\n        component = null;\n      },\n    };\n  },\n};\n","import { InputRule, mergeAttributes, Node, nodePasteRule } from '@tiptap/core';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { VueNodeViewRenderer } from '@tiptap/vue-2';\nimport Suggestion from '@tiptap/suggestion';\nimport { emojiPattern } from 'regex-combined-emojis';\n\nimport EmojiComponent from './EmojiComponent.vue';\nimport { codeToEmojiData, emojiShortCodeRegex, emojiRegex, stringToUnicode } from '@/common/emoji';\nimport suggestionOptions from './suggestion';\n\nconst inputShortCodeRegex = /(:\\w+:)$/;\nconst inputUnicodeRegex = new RegExp(emojiPattern + '$');\n\nconst inputRuleMatch = (match) => {\n  if (match && codeToEmojiData(match[0])) {\n    const text = match[2] || match[0];\n    // needs to be a dict returned\n    // ref type InputRuleMatch:\n    // https://github.com/ueberdosis/tiptap/blob/main/packages/core/src/InputRule.ts#L16\n    return { text };\n  }\n};\n\nconst shortCodePasteMatch = (text) => {\n  const matches = [...text.matchAll(emojiShortCodeRegex)];\n\n  return matches\n    .filter(match => codeToEmojiData(match[0]))\n    .map(match => ({\n      index: match.index,\n      text: match[0],\n      match,\n    }));\n};\n\nexport const Emoji = Node.create({\n  name: 'emoji',\n  addOptions () {\n    return {\n      HTMLAttributes: {},\n    };\n  },\n  group: 'inline',\n  inline: true,\n  selectable: false,\n  atom: true,\n\n  addNodeView () {\n    return VueNodeViewRenderer(EmojiComponent);\n  },\n\n  addAttributes () {\n    return {\n      code: {\n        default: null,\n      },\n      image: {\n        default: null,\n      },\n      name: {\n        default: null,\n      },\n    };\n  },\n\n  parseHTML () {\n    return [\n      {\n        tag: 'emoji-component',\n      },\n    ];\n  },\n\n  renderText ({ node }) {\n    /**\n     image -- custom emoji\n     code -- unicode emoji\n    */\n\n    const { image, code } = node.attrs;\n\n    if(image !== null) {\n      return image;\n    }else{\n      const emojiData = codeToEmojiData(code);\n      const unicodeEmoji = stringToUnicode(emojiData.unicode_output);\n\n      return unicodeEmoji;\n    }\n  },\n\n  renderHTML ({ HTMLAttributes }) {\n    return ['emoji-component', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];\n  },\n\n  addInputRules () {\n    return [\n      new InputRule({\n        find: (text) => {\n          const match = text.match(inputShortCodeRegex) || text.match(inputUnicodeRegex);\n          if (!match) return;\n\n          return inputRuleMatch(match);\n        },\n        handler: ({ state, range, match}) => {\n          const { tr } = state;\n          const start = range.from;\n          const end = range.to;\n          tr.replaceWith(start, end, this.type.create({ code: match[0] }));\n        },\n      }),\n    ];\n  },\n\n  addPasteRules () {\n    return [\n      nodePasteRule({\n        find: shortCodePasteMatch,\n        type: this.type,\n        getAttributes (attrs) {\n          return {\n            code: attrs[0],\n            image: attrs[1],\n            name: attrs[2],\n          };\n        },\n      }),\n      nodePasteRule({\n        find: emojiRegex,\n        type: this.type,\n        getAttributes (attrs) {\n          return {\n            code: attrs[0],\n            image: attrs[1],\n            name: attrs[2],\n          };\n        },\n      }),\n    ];\n  },\n\n  addProseMirrorPlugins () {\n    return [\n      Suggestion({\n        char: ':',\n        pluginKey: new PluginKey('emoji'),\n        editor: this.editor,\n        ...this.options.suggestion,\n        ...suggestionOptions,\n      }),\n    ];\n  },\n\n  addKeyboardShortcuts () {\n    return {\n      Backspace: () => this.editor.commands.command(({ tr, state }) => {\n        let isEmoji = false;\n        const { selection } = state;\n        const { empty, anchor } = selection;\n        if (!empty) { return false; }\n        state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n          if (node.type.name === this.name) {\n            isEmoji = true;\n            tr.insertText('', pos, pos + node.nodeSize);\n            return false;\n          }\n        });\n        return isEmoji;\n      }),\n    };\n  },\n});\n","import { getMarksBetween } from '@tiptap/core';\nimport {\n  getPhoneNumberRegex,\n  linkRegex,\n} from '@/common/utils';\n\n/**\n * Get matches in a string and return the ones that pass the optional extra\n * validation or if no validator is provided return all matches.\n */\nexport function getRegexMatches (text, regex, validator = () => true) {\n  const matches = [];\n\n  // Reset the lastIndex since the last time this was run.\n  regex.lastIndex = 0;\n\n  let match;\n  while ((match = regex.exec(text))) {\n    if (validator(text, match)) {\n      matches.push(match);\n    }\n  }\n\n  return matches;\n}\n\n/**\n * Validate the prefix of a match in a string not to contain certain characters.\n */\nexport function hasValidPrefix (text, match) {\n  // The string match can't start with # or @ or have either preceding the match\n  // as they're reserved for mentions and hashtags.\n  return !['#', '@'].includes(text.charAt(match.index)) &&\n    !['#', '@'].includes(text.charAt(match.index - 1));\n}\n\n/**\n * Trim punctuation characters at the a of the string, e.g. \"dialpad.com!\" =>\n * \"dialpad.com\"\n */\nexport function trimEndPunctiation (string) {\n  const endPunctuationRegex = new RegExp(\n    '(?:' +\n    [\n      '[!?.,:;\\'\"]',\n      '(?:&|&amp;)(?:lt|gt|quot|apos|raquo|laquo|rsaquo|lsaquo);)+$',\n    ].join('|'),\n    'g',\n  );\n  return string.replace(endPunctuationRegex, '');\n}\n\n/**\n * Find the word from a string at a given index. For example for \"example here\"\n * - indices 0-7  => \"example\"\n * - indices 8-12 => \"here\".\n * Modified from https://stackoverflow.com/a/5174867\n */\nexport function getWordAt (text, index) {\n  // Position of the first non-whitespace character following a possible\n  // whitespace when looking from the index to the left.\n  const left = text.slice(0, index + 1).search(/\\S+\\s*$/);\n\n  // Position of the first whitespace when looking from the index to the right.\n  const right = text.slice(index).search(/\\s/);\n\n  // If the word is at the end of the string, right is -1.\n  if (right < 0) {\n    const word = text.slice(left);\n    return {\n      text: word,\n      from: left,\n      to: left + word.length,\n    };\n  }\n\n  return {\n    text: text.slice(left, right + index),\n    from: left,\n    to: right + index,\n  };\n}\n\n/**\n * Helper to check if a word at a given index matches a regex and if true, finds\n * the previous or next word until the regex doesn't match anymore. Useful to\n * find for example the entire phone number when it is separated by whitespace.\n */\nexport function getWordAtUntil (text, index, direction, regex) {\n  const word = getWordAt(text, index);\n\n  // Reset the lastIndex since the last time this was run.\n  regex.lastIndex = 0;\n\n  // If the word doesn't match the regex we can just return it.\n  if (!regex.test(word.text)) {\n    return word;\n  }\n\n  // Depending on the direction take one step to the left or right to find the\n  // preceding or following word.\n  const newIndex = direction === 'left' ? word.from - 1 : word.to + 1;\n\n  // Prevent an infinite loop for the base cases.\n  if (newIndex <= 0 || newIndex >= text.length || newIndex === index) {\n    return word;\n  }\n\n  // Run the preceding/following word through the validator until we meet the\n  // string boundaries or find a word that doesn't match the regex.\n  return getWordAtUntil(text, newIndex, direction, regex);\n}\n\n/**\n * Remove marks from a range.\n */\nexport function removeMarks (range, doc, tr, type) {\n  const from = Math.max(range.from - 1, 0);\n  const to = Math.min(range.to + 1, doc.content.size);\n  const marksInRange = getMarksBetween(from, to, doc);\n\n  for (const mark of marksInRange) {\n    if (mark.mark.type !== type) {\n      continue;\n    }\n\n    tr.removeMark(mark.from, mark.to, type);\n  }\n}\n\n// Regex to match partial phone numbers.\nconst partialPhoneNumberRegex = getPhoneNumberRegex(1, 15);\n\n/**\n * Find matches from text and add marks on them.\n */\nexport function addMarks (text, pos, from, to, tr, type) {\n  if (!text) {\n    return;\n  }\n\n  // from = start index for the change\n  // pos  = start index of the node\n  // 1    = range uses 1-based indexing, deduct 1\n  let rangeFrom = from - pos - 1;\n\n  // If the change spans multiple nodes/paragraphs the start index can become\n  // negative, so default to 0.\n  rangeFrom = rangeFrom < 0 ? 0 : rangeFrom;\n\n  // to  = end index of the change\n  // pos = start index of the node\n  const rangeTo = to - pos;\n\n  // Get the first word in the range.\n  const firstWordInRange = getWordAtUntil(\n    text,\n    rangeFrom,\n    'left',\n    partialPhoneNumberRegex,\n  );\n\n  // Get the last word in the range.\n  const lastWordInRange = getWordAtUntil(\n    text,\n    rangeTo,\n    'right',\n    partialPhoneNumberRegex,\n  );\n\n  // Create a substring that consists of whole words only.\n  const wordsInRange = text.slice(firstWordInRange.from, lastWordInRange.to);\n\n  // Find all valid matches within the substring.\n  const matches = getRegexMatches(wordsInRange, linkRegex, hasValidPrefix);\n\n  // Loop through the matches and add marks.\n  matches.forEach(match => {\n    // Trim any punctuation characters at the end of the match.\n    const word = trimEndPunctiation(match[0]);\n\n    // pos                   = start index of the node\n    // firstWordInRange.from = start index of the first word in range\n    // match.index           = index of the regex match\n    // 1                     = addMark() uses 1-based indexing, add 1\n    const from = pos + firstWordInRange.from + match.index + 1;\n\n    // Sum up the from index and the match length to get the end index.\n    const to = from + word.length;\n\n    tr.addMark(from, to, type.create());\n  });\n}\n","import {\n  combineTransactionSteps,\n  findChildrenInRange,\n  getChangedRanges,\n} from '@tiptap/core';\nimport {\n  Plugin,\n  PluginKey,\n} from '@tiptap/pm/state';\nimport {\n  addMarks,\n  removeMarks,\n} from './utils';\n\n/**\n * Plugin to automatically add links into content.\n */\nexport function autolink (options) {\n  // Flag to see if we've loaded this plugin once already. This is used to run\n  // the initial content through the plugin if the editor was mounted with some.\n  let hasInitialized = false;\n\n  return new Plugin({\n    key: new PluginKey('autolink'),\n\n    appendTransaction: (transactions, oldState, newState) => {\n      const contentChanged = transactions.some(tr => tr.docChanged) &&\n        !oldState.doc.eq(newState.doc);\n\n      // Every interaction with the editor is a transaction, but we only care\n      // about the ones with content changes.\n      if (hasInitialized && !contentChanged) {\n        return;\n      }\n\n      // The original transaction that we're manipulating.\n      const { tr } = newState;\n\n      // Text content after the original transaction.\n      const { textContent } = newState.doc;\n\n      // When the editor is initialized we want to add links to it.\n      if (!hasInitialized) {\n        addMarks(textContent, 0, 0, textContent.length, tr, options.type);\n      }\n\n      hasInitialized = true;\n\n      // The transformed state of the document.\n      const transform = combineTransactionSteps(\n        oldState.doc,\n        [...transactions],\n      );\n\n      // All the changes within the document.\n      const changes = getChangedRanges(transform);\n\n      changes.forEach(({ oldRange, newRange }) => {\n        // Remove all link marks in the changed range since we'll add them\n        // right back if they're still valid links.\n        removeMarks(newRange, newState.doc, tr, options.type);\n\n        // Find all paragraphs (Textblocks) that were affected since we want to\n        // handle matches in each paragraph separately.\n        const paragraphs = findChildrenInRange(\n          newState.doc,\n          newRange,\n          node => node.isTextblock,\n        );\n\n        paragraphs.forEach(({ node, pos }) => {\n          addMarks(\n            node.textContent,\n            pos,\n            oldRange.from,\n            newRange.to,\n            tr,\n            options.type,\n          );\n        });\n      });\n\n      // Return the modified transaction or the changes above wont have effect.\n      return tr;\n    },\n  });\n}\n","/**\n *\n * The custom link does some additional things on top of the built in TipTap link\n * extension such as styling phone numbers and IP adresses as links, and allows you\n * to linkify text without having to type a space after the link. Currently it is missing some\n * functionality such as editing links and will likely require more work to be fully usable,\n * so it is recommended to use the built in TipTap link for now.\n */\n\nimport {\n  mergeAttributes,\n  Mark,\n} from '@tiptap/core';\nimport { autolink } from './autolink';\n\nconst defaultAttributes = {\n  class: 'd-link d-c-text d-d-inline-block d-wb-break-all',\n  rel: 'noopener noreferrer nofollow',\n};\n\n// This is the actual extension code, which is mostly showing that all the\n// functionality comes from the ProseMirror plugin.\nexport const CustomLink = Mark.create({\n  name: 'CustomLink',\n\n  renderHTML ({ HTMLAttributes }) {\n    return [\n      'a',\n      mergeAttributes(\n        this.options.HTMLAttributes,\n        HTMLAttributes,\n        defaultAttributes,\n      ),\n    ];\n  },\n\n  renderText ({ node }) {\n    return node.attrs.text;\n  },\n\n  addProseMirrorPlugins () {\n    return [\n      autolink({ type: this.type }),\n    ];\n  },\n});\n","import Image from '@tiptap/extension-image';\n\nexport const ConfigurableImage = Image.extend({\n  name: 'ConfigurableImage',\n\n  addAttributes () {\n    return {\n      src: {\n        default: '',\n      },\n      alt: {\n        default: undefined,\n      },\n      title: {\n        default: undefined,\n      },\n      width: {\n        default: undefined,\n      },\n      height: {\n        default: undefined,\n      },\n      style: {\n        default: undefined,\n      },\n    };\n  },\n}).configure({ inline: true, allowBase64: true });\n","import { mergeAttributes } from '@tiptap/core';\nimport Paragraph from '@tiptap/extension-paragraph';\n\n/** Extension for div tag support\n * Replaces the default p tags when typing text to div tags\n * Extends the following extension: https://github.com/ueberdosis/tiptap/blob/main/packages/extension-paragraph/src/paragraph.ts\n */\nexport const DivParagraph = Paragraph.extend({\n  parseHTML () {\n    return [{ tag: 'div' }];\n  },\n\n  renderHTML ({ HTMLAttributes }) {\n    return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];\n  },\n\n});\n","<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <node-view-wrapper\n    class=\"d-d-inline-block\"\n  >\n    <dt-link\n      kind=\"mention\"\n    >\n      {{ text }}\n    </dt-link>\n  </node-view-wrapper>\n</template>\n\n<script>\nimport { nodeViewProps, NodeViewWrapper } from '@tiptap/vue-2';\n\nimport { DtLink } from '@/components/link';\n\nexport default {\n  name: 'MentionComponent',\n  components: {\n    NodeViewWrapper,\n    DtLink,\n  },\n\n  props: nodeViewProps,\n\n  computed: {\n    text () {\n      return '@' + this.$props.node.attrs.name;\n    },\n  },\n};\n</script>\n","import Mention from '@tiptap/extension-mention';\nimport { mergeAttributes } from '@tiptap/core';\nimport { VueNodeViewRenderer } from '@tiptap/vue-2';\nimport { PluginKey } from '@tiptap/pm/state';\n\n// Mention component\nimport MentionComponent from './MentionComponent.vue';\n\nexport const MentionPlugin = Mention.extend({\n\n  addNodeView () {\n    return VueNodeViewRenderer(MentionComponent);\n  },\n\n  parseHTML () {\n    return [\n      {\n        tag: 'mention-component',\n      },\n    ];\n  },\n\n  addAttributes () {\n    return {\n      name: {\n        default: '',\n      },\n      avatarSrc: {\n        default: '',\n      },\n      id: {\n        default: '',\n      },\n    };\n  },\n\n  renderText ({ node }) {\n    return `@${node.attrs.id}`;\n  },\n\n  renderHTML ({ HTMLAttributes }) {\n    return ['mention-component', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];\n  },\n\n}).configure({\n  suggestion: {\n    char: '@',\n    pluginKey: new PluginKey('mentionSuggestion'),\n  },\n});\n","<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <node-view-wrapper\n    class=\"d-d-inline-block\"\n  >\n    <dt-link\n      kind=\"mention\"\n    >\n      {{ text }}\n    </dt-link>\n  </node-view-wrapper>\n</template>\n\n<script>\nimport { nodeViewProps, NodeViewWrapper } from '@tiptap/vue-2';\n\nimport { DtLink } from '@/components/link';\n\nexport default {\n  name: 'ChannelComponent',\n  components: {\n    NodeViewWrapper,\n    DtLink,\n  },\n\n  props: nodeViewProps,\n\n  computed: {\n    text () {\n      return '#' + this.$props.node.attrs.name;\n    },\n  },\n};\n</script>\n","import Mention from '@tiptap/extension-mention';\nimport { mergeAttributes } from '@tiptap/core';\nimport { VueNodeViewRenderer } from '@tiptap/vue-2';\nimport { PluginKey } from '@tiptap/pm/state';\n\n// Channel Mention component\nimport ChannelComponent from './ChannelComponent.vue';\n\nexport const ChannelPlugin = Mention.extend({\n  name: 'channel',\n\n  addNodeView () {\n    return VueNodeViewRenderer(ChannelComponent);\n  },\n\n  parseHTML () {\n    return [\n      {\n        tag: 'channel-component',\n      },\n    ];\n  },\n\n  addAttributes () {\n    return {\n      name: {\n        default: '',\n      },\n      id: {\n        default: '',\n      },\n      locked: {\n        default: false,\n      },\n    };\n  },\n\n  renderText ({ node }) {\n    return `#${node.attrs.id}`;\n  },\n\n  renderHTML ({ HTMLAttributes }) {\n    return ['channel-component', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];\n  },\n\n}).configure({\n  suggestion: {\n    char: '#',\n    pluginKey: new PluginKey('channelSuggestion'),\n  },\n});\n","<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <node-view-wrapper\n    class=\"d-d-inline-block\"\n  >\n    {{ text }}\n  </node-view-wrapper>\n</template>\n\n<script>\nimport { nodeViewProps, NodeViewWrapper } from '@tiptap/vue-2';\n\nexport default {\n  name: 'SlashCommandsComponent',\n  components: {\n    NodeViewWrapper,\n  },\n\n  props: {\n    ...nodeViewProps,\n  },\n\n  emits: ['selected-command'],\n\n  computed: {\n    text () {\n      return '/' + this.$props.node.attrs.command;\n    },\n  },\n\n  created () {\n    const command = this.$props.node.attrs.command;\n\n    // First emit the event using the component's own emit\n    this.$emit('selected-command', command);\n\n    // Access the callback from the editor's storage\n    const onSelectedCommand = this.editor?.storage?.['slash-commands']?.onSelectedCommand;\n    if (onSelectedCommand && typeof onSelectedCommand === 'function') {\n      onSelectedCommand(command);\n    }\n  },\n};\n</script>\n","import Mention from '@tiptap/extension-mention';\nimport { VueNodeViewRenderer } from '@tiptap/vue-2';\nimport { PluginKey } from '@tiptap/pm/state';\n\n// Slash Command Mention component\nimport SlashCommandComponent from './SlashCommandComponent.vue';\nimport { mergeAttributes, nodeInputRule, nodePasteRule } from '@tiptap/core';\n\nconst slashCommandPasteMatch = (text, slashCommandRegex) => {\n  const matches = [...text.matchAll(slashCommandRegex)];\n\n  return matches\n    .map(match => {\n      let slashCommand = match[2];\n      if (!slashCommand.endsWith(' ')) slashCommand += ' ';\n      return {\n        index: match.index,\n        text: slashCommand,\n        match,\n      };\n    });\n};\n\nexport const SlashCommandPlugin = Mention.extend({\n  name: 'slash-commands',\n  group: 'inline',\n  inline: true,\n\n  addOptions () {\n    return {\n      ...this.parent?.(),\n      onSelectedCommand: null,\n    };\n  },\n\n  addStorage () {\n    return {\n      onSelectedCommand: this.options.onSelectedCommand,\n    };\n  },\n\n  addNodeView () {\n    return VueNodeViewRenderer(SlashCommandComponent);\n  },\n\n  parseHTML () {\n    return [\n      {\n        tag: 'command-component',\n      },\n    ];\n  },\n\n  addAttributes () {\n    return {\n      command: {\n        default: '',\n      },\n      parametersExample: {\n        default: '',\n      },\n      description: {\n        default: '',\n      },\n    };\n  },\n\n  renderText ({ node }) {\n    return `/${node.attrs.command}`;\n  },\n\n  renderHTML ({ HTMLAttributes }) {\n    return ['command-component', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];\n  },\n\n  addInputRules () {\n    const suggestions = this.options.suggestion?.items({ query: '' }).map(suggestion => suggestion.command);\n    const slashCommandRegex = new RegExp(`^((?:\\\\/)(${suggestions.join('|')})) $`);\n    return [\n      nodeInputRule({\n        find: slashCommandRegex,\n        type: this.type,\n        getAttributes (attrs) {\n          return { command: attrs[2] };\n        },\n      }),\n    ];\n  },\n\n  addPasteRules () {\n    const suggestions = this.options.suggestion?.items({ query: '' }).map(suggestion => suggestion.command);\n    const slashCommandRegex = new RegExp(`^((?:\\\\/)(${suggestions.join('|')})) ?$`, 'g');\n    return [\n      nodePasteRule({\n        find: (text) => slashCommandPasteMatch(text, slashCommandRegex),\n        type: this.type,\n        getAttributes (attrs) {\n          return { command: attrs[0].trim() };\n        },\n      }),\n    ];\n  },\n}).configure({\n  suggestion: {\n    char: '/',\n    pluginKey: new PluginKey('slashCommandSuggestion'),\n  },\n});\n","<template>\n  <dt-stack\n    direction=\"row\"\n    class=\"d-mention-suggestion__container\"\n    gap=\"400\"\n  >\n    <dt-avatar\n      :full-name=\"name\"\n      :image-src=\"avatarSrc\"\n      :image-alt=\"name\"\n      :show-presence=\"showDetails\"\n      :presence=\"presence\"\n      size=\"sm\"\n    />\n    <dt-stack\n      class=\"d-mention-suggestion__details-container\"\n      gap=\"100\"\n    >\n      <!-- eslint-disable-next-line vue/no-restricted-class -->\n      <span class=\"d-mention-suggestion__name\">\n        {{ name }}\n      </span>\n      <dt-stack\n        v-if=\"showDetails\"\n        direction=\"row\"\n        gap=\"300\"\n        class=\"d-label--sm-plain\"\n      >\n        <span\n          v-if=\"presenceText\"\n          class=\"d-mention-suggestion__presence\"\n          :class=\"[presenceFontColorClass]\"\n        >\n          {{ presenceText }}\n        </span>\n        <div\n          v-if=\"status && presenceText\"\n          class=\"d-mention-suggestion__divider\"\n        >\n          •\n        </div>\n        <div\n          v-if=\"status\"\n          class=\"d-mention-suggestion__status\"\n        >\n          {{ status }}\n        </div>\n      </dt-stack>\n    </dt-stack>\n  </dt-stack>\n</template>\n\n<script>\nimport { DtAvatar } from '@/components/avatar';\nimport { DtStack } from '@/components/stack';\n\nexport default {\n  name: 'MentionSuggestion',\n  components: {\n    DtAvatar,\n    DtStack,\n  },\n\n  props: {\n    item: {\n      type: Object,\n      required: true,\n    },\n  },\n\n  computed: {\n    name () {\n      return this.item.name;\n    },\n\n    avatarSrc () {\n      return this.item.avatarSrc;\n    },\n\n    presence () {\n      return this.item.presence;\n    },\n\n    status () {\n      return this.item.status;\n    },\n\n    presenceText () {\n      return this.item.presenceText;\n    },\n\n    presenceFontColorClass () {\n      const presenceFontColors = {\n        active: 'd-recipe-contact-row--active',\n        busy: 'd-recipe-contact-row--busy',\n        away: 'd-recipe-contact-row--away',\n        offline: 'd-recipe-contact-row--busy',\n      };\n\n      return presenceFontColors[this.presence];\n    },\n\n    showDetails () {\n      return this.item.showDetails;\n    },\n  },\n};\n</script>\n","import { VueRenderer } from '@tiptap/vue-2';\nimport tippy from 'tippy.js';\n\nimport SuggestionList from '../suggestion/SuggestionList.vue';\nimport MentionSuggestion from './MentionSuggestion.vue';\nimport hideOnEsc from '../tippy_plugins/hide_on_esc';\n\nexport default {\n\n  // This function comes from the user and passed to the editor directly.\n  // This will also activate the mention plugin on the editor\n  // items: ({ query }) => { return [] },\n\n  allowSpaces: true,\n\n  render: () => {\n    let component;\n    let popup;\n    let popupIsOpen = false;\n\n    return {\n      onStart: props => {\n        component = new VueRenderer(SuggestionList, {\n          parent: this,\n          propsData: {\n            itemComponent: MentionSuggestion,\n            itemType: 'mention',\n            ...props,\n          },\n          editor: props.editor,\n        });\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup = tippy('body', {\n          getReferenceClientRect: props.clientRect,\n          appendTo: () => document.body,\n          content: component.element,\n          showOnCreate: false,\n          onShow: () => { popupIsOpen = true; },\n          onHidden: () => { popupIsOpen = false; },\n          interactive: true,\n          trigger: 'manual',\n          placement: 'top-start',\n          zIndex: 650,\n          plugins: [hideOnEsc],\n        });\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        }\n      },\n\n      onUpdate (props) {\n        component?.updateProps(props);\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        } else {\n          popup?.[0].hide();\n        }\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup?.[0].setProps({\n          getReferenceClientRect: props.clientRect,\n        });\n      },\n\n      onKeyDown (props) {\n        if (popupIsOpen) {\n          return component?.ref?.onKeyDown(props);\n        }\n      },\n\n      onExit () {\n        popup?.[0].destroy();\n        popup = null;\n        component?.destroy();\n        component = null;\n      },\n    };\n  },\n};\n","<template>\n  <dt-stack\n    direction=\"row\"\n    gap=\"400\"\n  >\n    <dt-icon-hash\n      v-if=\"!item.locked\"\n      size=\"300\"\n    />\n    <dt-icon-lock\n      v-else\n      size=\"300\"\n    />\n    <span>{{ name }}</span>\n  </dt-stack>\n</template>\n\n<script>\nimport { DtStack } from '@/components/stack';\nimport DtIconHash from '@dialpad/dialtone-icons/vue2/hash';\nimport DtIconLock from '@dialpad/dialtone-icons/vue2/lock';\n\nexport default {\n  name: 'ChannelSuggestion',\n  components: {\n    DtStack,\n    DtIconHash,\n    DtIconLock,\n  },\n\n  props: {\n    item: {\n      type: Object,\n      required: true,\n    },\n  },\n\n  computed: {\n    name () {\n      return this.item.name;\n    },\n  },\n};\n</script>\n","import { VueRenderer } from '@tiptap/vue-2';\nimport tippy from 'tippy.js';\n\nimport SuggestionList from '../suggestion/SuggestionList.vue';\nimport ChannelSuggestion from './ChannelSuggestion.vue';\nimport hideOnEsc from '../tippy_plugins/hide_on_esc';\n\nexport default {\n\n  // This function comes from the user and passed to the editor directly.\n  // This will also activate the mention plugin on the editor\n  // items: ({ query }) => { return [] },\n\n  allowSpaces: true,\n\n  render: () => {\n    let component;\n    let popup;\n    let popupIsOpen = false;\n\n    return {\n      onStart: props => {\n        component = new VueRenderer(SuggestionList, {\n          parent: this,\n          propsData: {\n            itemComponent: ChannelSuggestion,\n            itemType: 'channel',\n            ...props,\n          },\n          editor: props.editor,\n        });\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup = tippy('body', {\n          getReferenceClientRect: props.clientRect,\n          appendTo: () => document.body,\n          content: component.element,\n          showOnCreate: false,\n          onShow: () => { popupIsOpen = true; },\n          onHidden: () => { popupIsOpen = false; },\n          interactive: true,\n          trigger: 'manual',\n          placement: 'top-start',\n          zIndex: 650,\n          plugins: [hideOnEsc],\n        });\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        }\n      },\n\n      onUpdate (props) {\n        component?.updateProps(props);\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        } else {\n          popup?.[0].hide();\n        }\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup?.[0].setProps({\n          getReferenceClientRect: props.clientRect,\n        });\n      },\n\n      onKeyDown (props) {\n        if (popupIsOpen) {\n          return component?.ref?.onKeyDown(props);\n        }\n      },\n\n      onExit () {\n        popup?.[0].destroy();\n        popup = null;\n        component?.destroy();\n        component = null;\n      },\n    };\n  },\n};\n","<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <div>\n    <div class=\"d-body--md-compact\">\n      <span>/{{ command }}</span><span v-if=\"parametersExample\"> {{ parametersExample }}</span>\n    </div>\n    <div class=\"d-body--sm d-fc-tertiary\">\n      {{ description }}\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'SlashCommandSuggestion',\n\n  props: {\n    item: {\n      type: Object,\n      required: true,\n    },\n  },\n\n  computed: {\n    command () {\n      return this.item.command;\n    },\n\n    description () {\n      return this.item.description;\n    },\n\n    parametersExample () {\n      return this.item.parametersExample;\n    },\n  },\n};\n</script>\n","import { VueRenderer } from '@tiptap/vue-2';\nimport tippy from 'tippy.js';\nimport hideOnEsc from '../tippy_plugins/hide_on_esc';\n\nimport SuggestionList from '../suggestion/SuggestionList.vue';\nimport SlashCommandSuggestion from './SlashCommandSuggestion.vue';\n\nexport default {\n\n  // This function comes from the user and passed to the editor directly.\n  // This will also activate the mention plugin on the editor\n  // items: ({ query }) => { return [] },\n\n  allowSpaces: true,\n  startOfLine: true,\n\n  render: () => {\n    let component;\n    let popup;\n    let popupIsOpen = false;\n\n    return {\n      onStart: props => {\n        component = new VueRenderer(SuggestionList, {\n          parent: this,\n          propsData: {\n            itemComponent: SlashCommandSuggestion,\n            itemType: 'slash-command',\n            ...props,\n          },\n          editor: props.editor,\n        });\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup = tippy('body', {\n          getReferenceClientRect: props.clientRect,\n          appendTo: () => document.body,\n          content: component.element,\n          showOnCreate: false,\n          onShow: () => { popupIsOpen = true; },\n          onHidden: () => { popupIsOpen = false; },\n          interactive: true,\n          trigger: 'manual',\n          placement: 'top-start',\n          zIndex: 650,\n          plugins: [hideOnEsc],\n        });\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        }\n      },\n\n      onUpdate (props) {\n        component?.updateProps(props);\n\n        if (props.items.length > 0) {\n          popup?.[0].show();\n        } else {\n          popup?.[0].hide();\n        }\n\n        if (!props.clientRect) {\n          return;\n        }\n\n        popup?.[0].setProps({\n          getReferenceClientRect: props.clientRect,\n        });\n      },\n\n      onKeyDown (props) {\n        if (popupIsOpen) {\n          return component?.ref?.onKeyDown(props);\n        }\n      },\n\n      onExit () {\n        popup?.[0].destroy();\n        popup = null;\n        component?.destroy();\n        component = null;\n      },\n    };\n  },\n};\n","<!-- eslint-disable vue/no-static-inline-styles -->\n<!-- eslint-disable vue/no-bare-strings-in-template -->\n<!-- eslint-disable vue/no-restricted-class -->\n<template>\n  <div>\n    <!-- why the hell is this visibility: hidden by default??? -->\n    <bubble-menu\n      v-if=\"editor && link && !hideLinkBubbleMenu\"\n      :editor=\"editor\"\n      :should-show=\"bubbleMenuShouldShow\"\n      :tippy-options=\"tippyOptions\"\n      style=\"visibility: visible;\"\n    >\n      <div class=\"d-popover__dialog\">\n        <dt-stack\n          direction=\"row\"\n          class=\"d-rich-text-editor-bubble-menu__button-stack\"\n          gap=\"0\"\n        >\n          <dt-button\n            kind=\"muted\"\n            importance=\"clear\"\n            @click=\"editLink\"\n          >\n            {{ i18n.$t('DIALTONE_RICH_TEXT_EDITOR_EDIT_BUTTON_LABEL') }}\n          </dt-button>\n          <dt-button\n            kind=\"muted\"\n            importance=\"clear\"\n            @click=\"openLink\"\n          >\n            {{ i18n.$t('DIALTONE_RICH_TEXT_EDITOR_OPEN_LINK_BUTTON_LABEL') }}\n          </dt-button>\n          <dt-button\n            kind=\"danger\"\n            importance=\"clear\"\n            @click=\"removeLink\"\n          >\n            {{ i18n.$t('DIALTONE_RICH_TEXT_EDITOR_REMOVE_BUTTON_LABEL') }}\n          </dt-button>\n        </dt-stack>\n      </div>\n    </bubble-menu>\n    <editor-content\n      ref=\"editor\"\n      :editor=\"editor\"\n      class=\"d-rich-text-editor\"\n      data-qa=\"dt-rich-text-editor\"\n      v-on=\"editorListeners\"\n    />\n  </div>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { Editor, EditorContent, BubbleMenu } from '@tiptap/vue-2';\nimport { Extension } from '@tiptap/core';\nimport { DtButton } from '../button';\nimport { DtStack } from '../stack';\nimport Blockquote from '@tiptap/extension-blockquote';\nimport CodeBlock from '@tiptap/extension-code-block';\nimport Code from '@tiptap/extension-code';\nimport Document from '@tiptap/extension-document';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport HardBreak from '@tiptap/extension-hard-break';\nimport Bold from '@tiptap/extension-bold';\nimport BulletList from '@tiptap/extension-bullet-list';\nimport Italic from '@tiptap/extension-italic';\nimport TipTapLink from '@tiptap/extension-link';\nimport ListItem from '@tiptap/extension-list-item';\nimport OrderedList from '@tiptap/extension-ordered-list';\nimport Strike from '@tiptap/extension-strike';\nimport Underline from '@tiptap/extension-underline';\nimport Text from '@tiptap/extension-text';\nimport TextAlign from '@tiptap/extension-text-align';\nimport History from '@tiptap/extension-history';\nimport TextStyle from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Emoji from './extensions/emoji';\nimport CustomLink from './extensions/custom_link';\nimport ConfigurableImage from './extensions/image';\nimport DivParagraph from './extensions/div';\nimport { MentionPlugin } from './extensions/mentions/mention';\nimport { ChannelPlugin } from './extensions/channels/channel';\nimport { SlashCommandPlugin } from './extensions/slash_command/slash_command';\nimport {\n  RICH_TEXT_EDITOR_OUTPUT_FORMATS,\n  RICH_TEXT_EDITOR_AUTOFOCUS_TYPES,\n  RICH_TEXT_EDITOR_SUPPORTED_LINK_PROTOCOLS,\n} from './rich_text_editor_constants';\nimport { emojiPattern } from 'regex-combined-emojis';\n\nimport mentionSuggestion from './extensions/mentions/suggestion';\nimport channelSuggestion from './extensions/channels/suggestion';\nimport slashCommandSuggestion from './extensions/slash_command/suggestion';\nimport { warnIfUnmounted } from '@/common/utils';\nimport deepEqual from 'deep-equal';\nimport { DialtoneLocalization } from '@/localization';\n\nexport default {\n  name: 'DtRichTextEditor',\n\n  components: {\n    EditorContent,\n    BubbleMenu,\n    DtButton,\n    DtStack,\n  },\n\n  props: {\n    /**\n     * Value of the input. The object format should match TipTap's JSON\n     * document structure: https://tiptap.dev/guide/output#option-1-json\n     */\n    value: {\n      type: [Object, String],\n      default: '',\n    },\n\n    /**\n     * Whether the input is editable\n     */\n    editable: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Prevents the user from typing any further. Deleting text will still work.\n     */\n    preventTyping: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * When this option is false the editor will only ever paste plain text, no rich text formatting will be applied,\n     * and any HTML will be rendered as text.\n     */\n    pasteRichText: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for line breaks to be introduced in the text by pressing enter. If this is disabled,\n     * line breaks can still be entered by pressing shift+enter.\n     */\n    allowLineBreaks: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Descriptive label for the input element\n     */\n    inputAriaLabel: {\n      type: String,\n      required: true,\n    },\n\n    /**\n     * Additional class name for the input element. Only accepts a String value\n     * because this is passed to the editor via options. For multiple classes,\n     * join them into one string, e.g. \"d-p8 d-hmx96\"\n     */\n    inputClass: {\n      type: String,\n      default: '',\n    },\n\n    /**\n     * Whether the input should receive focus after the component has been\n     * mounted. Either one of `start`, `end`, `all` or a Boolean or a Number.\n     * - `start`  Sets the focus to the beginning of the input\n     * - `end`    Sets the focus to the end of the input\n     * - `all`    Selects the whole contents of the input\n     * - `Number` Sets the focus to a specific position in the input\n     * - `true`   Defaults to `start`\n     * - `false`  Disables autofocus\n     * @values true, false, start, end, all, number\n     */\n    autoFocus: {\n      type: [Boolean, String, Number],\n      default: false,\n      validator (autoFocus) {\n        if (typeof autoFocus === 'string') {\n          return RICH_TEXT_EDITOR_AUTOFOCUS_TYPES.includes(autoFocus);\n        }\n        return true;\n      },\n    },\n\n    /**\n     * The output format that the editor uses when emitting the \"@input\" event.\n     * One of `text`, `json`, `html`. See https://tiptap.dev/guide/output for\n     * examples.\n     * @values text, json, html\n     */\n    outputFormat: {\n      type: String,\n      default: 'html',\n      validator (outputFormat) {\n        return RICH_TEXT_EDITOR_OUTPUT_FORMATS.includes(outputFormat);\n      },\n    },\n\n    /**\n     * Placeholder text\n     */\n    placeholder: {\n      type: String,\n      default: '',\n    },\n\n    /**\n     * Enables the TipTap Link extension and optionally passes configurations to it\n     *\n     * It is not recommended to use this and the custom link extension at the same time.\n     */\n    link: {\n      type: [Boolean, Object],\n      default: false,\n    },\n\n    /**\n     * Enables the Custom Link extension and optionally passes configurations to it\n     *\n     * It is not recommended to use this and the built in TipTap link extension at the same time.\n     *\n     * The custom link does some additional things on top of the built in TipTap link\n     * extension such as styling phone numbers and IP adresses as links, and allows you\n     * to linkify text without having to type a space after the link. Currently it is missing some\n     * functionality such as editing links and will likely require more work to be fully usable,\n     * so it is recommended to use the built in TipTap link for now.\n     */\n    customLink: {\n      type: [Boolean, Object],\n      default: false,\n    },\n\n    /**\n     * suggestion object containing the items query function.\n     * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n     *\n     * The only required key is the items function which is used to query the contacts for suggestion.\n     * items({ query }) => { return [ContactObject]; }\n     * ContactObject format:\n     * { name: string, avatarSrc: string, id: string }\n     *\n     * When null, it does not add the plugin.\n     */\n    mentionSuggestion: {\n      type: Object,\n      default: null,\n    },\n\n    /**\n     * suggestion object containing the items query function.\n     * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n     *\n     * The only required key is the items function which is used to query the channels for suggestion.\n     * items({ query }) => { return [ChannelObject]; }\n     * ChannelObject format:\n     * { name: string, id: string, locked: boolean }\n     *\n     * When null, it does not add the plugin. Setting locked to true will display a lock rather than hash.\n     */\n    channelSuggestion: {\n      type: Object,\n      default: null,\n    },\n\n    /**\n     * suggestion object containing the items query function.\n     * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n     *\n     * The only required key is the items function which is used to query the slash commands for suggestion.\n     * items({ query }) => { return [SlashCommandObject]; }\n     * SlashCommandObject format:\n     * { command: string, description: string, parametersExample?: string }\n     * The \"parametersExample\" parameter is optional, and describes an example\n     * of the parameters that command can take.\n     *\n     * When null, it does not add the plugin.\n     * Note that slash commands only work when they are the first word in the input.\n     */\n    slashCommandSuggestion: {\n      type: Object,\n      default: null,\n    },\n\n    /**\n     * Whether the input allows for block quote.\n     */\n    allowBlockquote: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for bold to be introduced in the text.\n     */\n    allowBold: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for bullet list to be introduced in the text.\n     */\n    allowBulletList: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for italic to be introduced in the text.\n     */\n    allowItalic: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for strike to be introduced in the text.\n     */\n    allowStrike: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows for underline to be introduced in the text.\n     */\n    allowUnderline: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows inline code (wrapped in backticks).\n     */\n    allowCode: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows codeblock to be introduced in the text.\n     */\n    allowCodeblock: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Whether the input allows inline images to be rendered.\n     */\n    allowInlineImages: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Whether the input allows color to be introduced in the text.\n     */\n    allowFontColor: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Whether the input allows different font-families to be introduced in the text.\n     */\n    allowFontFamily: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Additional TipTap extensions to be added to the editor.\n     */\n    additionalExtensions: {\n      type: Array,\n      default: () => [],\n    },\n\n    /**\n     * Manually hide the link bubble menu. The link bubble menu is shown when a link is selected via the cursor.\n     * There are some cases when you may want the link to remain selected but hide the bubble menu such as when You\n     * are showing a custom link editor popup.\n     */\n    hideLinkBubbleMenu: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Show text in HTML div tags instead of paragraph tags\n     */\n    useDivTags: {\n      type: Boolean,\n      default: false,\n    },\n  },\n\n  emits: [\n    /**\n     * Editor input event\n     * @event input\n     * @type {String|JSON}\n     */\n    'input',\n\n    /**\n     * Input event always in JSON format.\n     * @event input\n     * @type {JSON}\n     */\n    'json-input',\n\n    /**\n     * Input event always in HTML format.\n     * @event input\n     * @type {HTML}\n     */\n    'html-input',\n\n    /**\n     * Input event always in text format.\n     * @event input\n     * @type {String}\n     */\n    'text-input',\n\n    /**\n     * Event to sync the value with the parent\n     * @event update:value\n     * @type {String|JSON}\n     */\n    'update:value',\n\n    /**\n     * Editor blur event\n     * @event blur\n     * @type {FocusEvent}\n     */\n    'blur',\n\n    /**\n     * Editor focus event\n     * @event focus\n     * @type {FocusEvent}\n     */\n    'focus',\n\n    /**\n     * Enter was pressed. Note that shift enter must be pressed to line break the input.\n     * @event enter\n     * @type {String}\n     */\n    'enter',\n\n    /**\n     * \"Edit link\" button was clicked. Fires an event for the consuming component to handle the editing of the link.\n     * event contains the link object with two properties href and text.\n     * @event edit-link\n     * @type {Object}\n     */\n    'edit-link',\n\n    /**\n     * \"Selected\" event is fired when the user selects text in the editor. returns the currently selected text.\n     * If the selected text is partially a link, the full link text is returned.\n     * @event selected\n     * @type {String}\n     */\n    'selected',\n\n    /**\n     * Event fired when a slash command is selected\n     * @event selected-command\n     * @type {String}\n     */\n    'selected-command',\n  ],\n\n  data () {\n    return {\n      editor: null,\n      tippyOptions: {\n        appendTo: () => this.$refs.editor.$el.getRootNode()?.querySelector('body'),\n        placement: 'top-start',\n      },\n\n      i18n: new DialtoneLocalization(),\n    };\n  },\n\n  computed: {\n    editorListeners () {\n      return {\n        ...this.$listeners,\n        input: () => {},\n        focus: () => {},\n        blur: () => {},\n      };\n    },\n\n    // eslint-disable-next-line complexity\n    extensions () {\n      // These are the default extensions needed just for plain text.\n      const extensions = [Document, Text, History, HardBreak];\n      extensions.push(this.useDivTags ? DivParagraph : Paragraph);\n\n      // bold must come before blockquote due to keyboard shortcuts\n      if (this.allowBold) {\n        extensions.push(Bold);\n      }\n      if (this.allowBlockquote) {\n        extensions.push(Blockquote);\n      }\n\n      if (this.allowBulletList) {\n        extensions.push(BulletList);\n        extensions.push(ListItem.extend({\n          renderText ({ node }) {\n            return node.textContent;\n          },\n        }));\n        extensions.push(OrderedList);\n      }\n      if (this.allowItalic) {\n        extensions.push(Italic);\n      }\n      if (this.allowStrike) {\n        extensions.push(Strike);\n      }\n      if (this.allowUnderline) {\n        extensions.push(Underline);\n      }\n\n      // Enable placeholderText\n      if (this.placeholder) {\n        extensions.push(\n          Placeholder.configure({ placeholder: this.placeholder }),\n        );\n      }\n\n      const self = this;\n      const ShiftEnter = Extension.create({\n        addKeyboardShortcuts () {\n          return {\n            'Shift-Enter': ({ editor }) => {\n              if (self.allowLineBreaks) {\n                return false;\n              }\n              editor.commands.first(({ commands }) => [\n                () => commands.newlineInCode(),\n                () => self.allowBulletList && commands.splitListItem('listItem'),\n                () => commands.createParagraphNear(),\n                () => commands.liftEmptyBlock(),\n                () => commands.splitBlock(),\n              ]);\n              return true;\n            },\n            Enter: () => {\n              if (self.allowLineBreaks) {\n                return false;\n              }\n              self.$emit('enter');\n              return true;\n            },\n          };\n        },\n      });\n      extensions.push(ShiftEnter);\n\n      if (this.link) {\n        extensions.push(TipTapLink.extend({\n          inclusive: false,\n          addKeyboardShortcuts () {\n            return {\n              'Mod-k': () => {\n                self.$emit('edit-link');\n                return true;\n              },\n            };\n          },\n        }).configure({\n          HTMLAttributes: {\n            class: 'd-link d-wb-break-all',\n          },\n          openOnClick: false,\n          autolink: true,\n          protocols: RICH_TEXT_EDITOR_SUPPORTED_LINK_PROTOCOLS,\n        }));\n      }\n      if (this.customLink) {\n        extensions.push(this.getExtension(CustomLink, this.customLink));\n      }\n\n      if (this.mentionSuggestion) {\n        // Add both the suggestion plugin as well as means for user to add suggestion items to the plugin\n        const suggestionObject = { ...this.mentionSuggestion, ...mentionSuggestion };\n        extensions.push(MentionPlugin.configure({ suggestion: suggestionObject }));\n      }\n\n      if (this.channelSuggestion) {\n        // Add both the suggestion plugin as well as means for user to add suggestion items to the plugin\n        const suggestionObject = { ...this.channelSuggestion, ...channelSuggestion };\n        extensions.push(ChannelPlugin.configure({ suggestion: suggestionObject }));\n      }\n\n      if (this.slashCommandSuggestion) {\n        // Add both the suggestion plugin as well as means for user to add suggestion items to the plugin\n        const suggestionObject = { ...this.slashCommandSuggestion, ...slashCommandSuggestion };\n        extensions.push(SlashCommandPlugin.configure({\n          suggestion: suggestionObject,\n          onSelectedCommand: (command) => {\n            this.$emit('selected-command', command);\n          },\n        }));\n      }\n\n      // Emoji has some interactions with Enter key\n      // hence this should be done last otherwise the enter wont add a emoji.\n      extensions.push(Emoji);\n\n      extensions.push(TextAlign.configure({\n        types: ['paragraph'],\n      }));\n\n      if (this.allowCode) {\n        extensions.push(Code);\n      }\n\n      if (this.allowCodeblock) {\n        extensions.push(CodeBlock.extend({\n          renderText ({ node }) {\n            return `\\`\\`\\`\\n${node.textContent}\\n\\`\\`\\``;\n          },\n        }).configure({\n          HTMLAttributes: {\n            class: 'd-rich-text-editor__code-block',\n          },\n        }));\n      }\n\n      if (this.allowInlineImages) {\n        extensions.push(ConfigurableImage);\n      }\n\n      if (this.allowFontFamily || this.allowFontColor) {\n        extensions.push(TextStyle);\n\n        if (this.allowFontColor) {\n          extensions.push(Color);\n        }\n\n        if (this.allowFontFamily) {\n          extensions.push(FontFamily);\n        }\n      }\n\n      if (this.additionalExtensions.length) {\n        extensions.push(...this.additionalExtensions);\n      }\n\n      return extensions;\n    },\n\n    inputAttrs () {\n      const attrs = {\n        'aria-label': this.inputAriaLabel,\n        'aria-multiline': true,\n        role: 'textbox',\n      };\n      if (!this.editable) {\n        attrs['aria-readonly'] = true;\n      }\n      return attrs;\n    },\n  },\n\n  /**\n   * Because the Editor instance is initialized when mounted it does not get\n   * updated props automatically, so the ones that can change after mount have\n   * to be hooked up to the Editor's own API.\n   */\n  watch: {\n    editable (isEditable) {\n      this.editor.setEditable(isEditable);\n      this.updateEditorAttributes({ 'aria-readonly': !isEditable });\n    },\n\n    inputClass (newClass) {\n      this.updateEditorAttributes({ class: newClass });\n    },\n\n    inputAriaLabel (newLabel) {\n      this.updateEditorAttributes({ 'aria-label': newLabel });\n    },\n\n    extensions () {\n      // Extensions can't be registered on the fly, so just recreate the editor.\n      // https://github.com/ueberdosis/tiptap/issues/1044\n      this.destroyEditor();\n      this.createEditor();\n    },\n\n    value (newValue) {\n      this.processValue(newValue);\n    },\n  },\n\n  created () {\n    this.createEditor();\n  },\n\n  beforeDestroy () {\n    this.destroyEditor();\n  },\n\n  mounted () {\n    warnIfUnmounted(this.$el, this.$options.name);\n    this.processValue(this.value, false);\n  },\n\n  methods: {\n    createEditor () {\n      // For all available options, see https://tiptap.dev/api/editor#settings\n      this.editor = new Editor({\n        autofocus: this.autoFocus,\n        content: this.value,\n        editable: this.editable,\n        extensions: this.extensions,\n        parseOptions: {\n          preserveWhitespace: 'full',\n        },\n\n        editorProps: {\n          attributes: {\n            ...this.inputAttrs,\n            class: this.inputClass,\n          },\n\n          handleKeyDown: (view, event) => {\n            if (!this.preventTyping) return false;\n\n            const allowedKeys = ['Backspace'];\n            if (!this.allowLineBreaks && !event.shiftKey) {\n              allowedKeys.push('Enter');\n            }\n\n            return !allowedKeys.includes(event.key);\n          },\n\n          handlePaste: (view, event) => {\n            const clipboardData = event.clipboardData || window.clipboardData;\n            const textData = clipboardData.getData('text/plain');\n            const htmlData = clipboardData.getData('text/html');\n\n            return this.processPasteData(view, textData, htmlData);\n          },\n\n          // Moves the <br /> tags inside the previous closing tag to avoid\n          // Prosemirror wrapping them within another </p> tag.\n          transformPastedHTML (html) {\n            return html.replace(/(<\\/\\w+>)((<br \\/>)+)/g, '$2$3$1');\n          },\n        },\n      });\n      this.addEditorListeners();\n    },\n\n    bubbleMenuShouldShow ({ editor }) {\n      return editor.isActive('link');\n    },\n\n    /**\n     * If the selection contains a link, return the existing link text.\n     * Otherwise, use just the selected text.\n     * @param editor the editor instance.\n     */\n    getSelectedLinkText (editor) {\n      const { view, state } = editor;\n      const { from, to } = view.state.selection;\n      const text = state.doc.textBetween(from, to, '');\n      const linkNode = this.editor.state.doc.nodeAt(from);\n      if (linkNode && linkNode.marks?.at(0)?.type?.name === 'link') {\n        return linkNode.textContent;\n      } else {\n        return text;\n      }\n    },\n\n    editLink () {\n      const linkText = this.getSelectedLinkText(this.editor);\n\n      const link = {\n        href: this.editor.getAttributes('link').href,\n        text: linkText,\n      };\n      this.$emit('edit-link', link);\n    },\n\n    removeLink () {\n      this.editor?.chain()?.focus()?.unsetLink()?.run();\n    },\n\n    openLink () {\n      this.editor?.chain()?.focus();\n      const link = this.editor.getAttributes('link').href;\n      window.open(link, '_blank');\n    },\n\n    // eslint-disable-next-line complexity\n    setLink (linkInput, linkText, linkOptions, linkProtocols = RICH_TEXT_EDITOR_SUPPORTED_LINK_PROTOCOLS,\n      defaultPrefix) {\n      if (!linkInput) {\n        // If link text is set to empty string,\n        // remove any existing links.\n        this.removeLink();\n        return;\n      }\n\n      // Check if input matches any of the supported link formats\n      const prefix = linkProtocols.find(prefixRegex => prefixRegex.test(linkInput));\n\n      if (!prefix) {\n        // If no matching pattern is found, prepend default prefix\n        linkInput = `${defaultPrefix}${linkInput}`;\n      }\n\n      this.editor\n        .chain()\n        .focus()\n        .extendMarkRange('link')\n        .run();\n\n      const selection = this.editor?.view?.state?.selection;\n\n      this.editor\n        .chain()\n        .focus()\n        .insertContent(linkText)\n        .setTextSelection({ from: selection.from, to: selection.from + linkText.length })\n        .setLink({ href: linkInput, class: linkOptions.class })\n        .run();\n    },\n\n    // eslint-disable-next-line complexity\n    processValue (newValue, returnIfEqual = true) {\n      const currentValue = this.getOutput();\n\n      if (returnIfEqual && deepEqual(newValue, currentValue)) {\n        // The new value came from this component and was passed back down\n        // through the parent, so don't do anything here.\n        return;\n      }\n\n      // If the text contains emoji characters convert them to emoji component tags\n      if (typeof newValue === 'string' && this.outputFormat === 'text') {\n        const inputUnicodeRegex = new RegExp(`(${emojiPattern})`, 'g');\n        newValue = newValue?.replace(inputUnicodeRegex, '<emoji-component code=\"$1\"></emoji-component>');\n      }\n\n      // Otherwise replace the content (resets the cursor position).\n      this.editor.commands.setContent(newValue, false, { preserveWhitespace: 'full' });\n    },\n\n    destroyEditor () {\n      this.editor.destroy();\n    },\n\n    insertPlainTextWithHardBreaks (view, textData) {\n      const { tr } = view.state;\n      const { from, to } = view.state.selection;\n\n      // Delete selected content\n      tr.deleteRange(from, to);\n\n      // Split text by line breaks and insert with hard breaks\n      const lines = textData.split(/\\r?\\n/);\n      let pos = from;\n\n      for (let i = 0; i < lines.length; i++) {\n        if (i > 0) {\n          // Insert hard break for line breaks (except before first line)\n          tr.insert(pos, view.state.schema.nodes.hardBreak.create());\n          pos++;\n        }\n        // Insert text content (including empty strings for blank lines)\n        tr.insertText(lines[i], pos);\n        pos += lines[i].length;\n      }\n\n      view.dispatch(tr);\n    },\n\n    shouldPreserveLineBreaks (textData, htmlData) {\n      // When pasteRichText is false, always use plain text handling to ensure HTML tags are literal\n      if (!this.pasteRichText) {\n        return !!textData;\n      }\n      // When pasteRichText is true, preserve line breaks for plain text that contains blank lines\n      // or multiple consecutive line breaks to avoid losing formatting\n      return !htmlData && textData && this.hasBlankLines(textData);\n    },\n\n    processPasteData (view, textData, htmlData) {\n      if (this.shouldPreserveLineBreaks(textData, htmlData)) {\n        this.insertPlainTextWithHardBreaks(view, textData);\n        return true;\n      }\n\n      if (this.shouldHandlePreformattedHTML(htmlData)) {\n        const extractedText = this.extractPreformattedText(htmlData);\n        if (extractedText && extractedText.includes('\\n')) {\n          this.insertPlainTextWithHardBreaks(view, extractedText);\n          return true;\n        }\n      }\n\n      return false;\n    },\n\n    shouldHandlePreformattedHTML (htmlData) {\n      return this.pasteRichText && htmlData && this.containsPreformattedContent(htmlData);\n    },\n\n    containsPreformattedContent (htmlData) {\n      const tempDiv = document.createElement('div');\n      tempDiv.innerHTML = htmlData;\n      const elements = tempDiv.querySelectorAll('*');\n\n      for (const element of elements) {\n        if (this.hasPreWhitespace(element) && this.hasLineBreaks(element)) {\n          return true;\n        }\n      }\n      return false;\n    },\n\n    hasPreWhitespace (element) {\n      const styleAttr = element.getAttribute('style') || '';\n      const elementStyle = element.style.whiteSpace || '';\n\n      const hasPreElementStyle = elementStyle === 'pre' || elementStyle === 'pre-wrap';\n      const hasPreInlineStyle = styleAttr.includes('white-space: pre');\n\n      return hasPreElementStyle || hasPreInlineStyle;\n    },\n\n    hasLineBreaks (element) {\n      return element.textContent && element.textContent.includes('\\n');\n    },\n\n    hasBlankLines (textData) {\n      // Check for blank lines (empty lines between content) or multiple consecutive line breaks\n      return textData.includes('\\n\\n') || /\\n\\s*\\n/.test(textData);\n    },\n\n    extractPreformattedText (htmlData) {\n      const tempDiv = document.createElement('div');\n      tempDiv.innerHTML = htmlData;\n      return this.walkAndExtractText(tempDiv);\n    },\n\n    walkAndExtractText (node) {\n      let result = '';\n\n      if (node.nodeType === Node.TEXT_NODE) {\n        result += node.textContent;\n      } else if (node.nodeType === Node.ELEMENT_NODE) {\n        if (this.hasPreWhitespace(node)) {\n          result += node.textContent;\n        } else {\n          for (const child of node.childNodes) {\n            result += this.walkAndExtractText(child);\n          }\n        }\n      }\n\n      return result;\n    },\n\n    triggerInputChangeEvents () {\n      const value = this.getOutput();\n      this.$emit('input', value);\n      this.$emit('update:value', value);\n\n      // Always output JSON in a separate event\n      const jsonValue = this.editor.getJSON();\n      this.$emit('json-input', jsonValue);\n\n      // Always output HTML in a separate event\n      const htmlValue = this.editor.getHTML();\n      this.$emit('html-input', htmlValue);\n\n      // Always output HTML in a separate event\n      const textValue = this.editor.getText({ blockSeparator: '\\n' });\n      this.$emit('text-input', textValue);\n    },\n\n    /**\n     * The Editor exposes event hooks that we have to map our emits into. See\n     * https://tiptap.dev/api/events for all events.\n     */\n    addEditorListeners () {\n      this.editor.on('create', () => {\n        this.triggerInputChangeEvents();\n      });\n      // The content has changed.\n      this.editor.on('update', () => {\n        this.triggerInputChangeEvents();\n      });\n\n      this.editor.on('selectionUpdate', ({ editor }) => {\n        this.$emit('selected', this.getSelectedLinkText(editor));\n      });\n\n      // The editor is focused.\n      this.editor.on('focus', ({ event }) => {\n        this.$emit('focus', event);\n      });\n\n      // The editor isn’t focused anymore.\n      this.editor.on('blur', ({ event }) => {\n        this.$emit('blur', event);\n      });\n    },\n\n    getOutput () {\n      switch (this.outputFormat) {\n        case 'json':\n          return this.editor.getJSON();\n        case 'html':\n          return this.editor.getHTML();\n        case 'text':\n        default:\n          return this.editor.getText({ blockSeparator: '\\n' });\n      }\n    },\n\n    getExtension (extension, options) {\n      if (typeof options === 'boolean') {\n        return extension;\n      }\n      return extension.configure?.(options);\n    },\n\n    updateEditorAttributes (attributes) {\n      this.editor.setOptions({\n        editorProps: {\n          attributes: {\n            ...this.inputAttrs,\n            class: this.inputClass,\n            ...attributes,\n          },\n        },\n      });\n    },\n\n    focusEditor () {\n      this.editor.commands.focus();\n    },\n  },\n};\n</script>\n"],"names":["_sfc_main","NodeViewWrapper","DtEmoji","DtSkeleton","nodeViewProps","event","DtListItem","activeElement","index","item","DtStack","hideOnEsc","hide","onKeyDown","suggestionLimit","suggestionOptions","query","emojiList","emojisIndexed","text","editor","range","props","nodeAfter","_a","_b","component","popup","popupIsOpen","VueRenderer","SuggestionList","this","EmojiSuggestion","tippy","inputShortCodeRegex","inputUnicodeRegex","emojiPattern","inputRuleMatch","match","codeToEmojiData","shortCodePasteMatch","emojiShortCodeRegex","Emoji","Node","VueNodeViewRenderer","EmojiComponent","node","image","code","emojiData","stringToUnicode","HTMLAttributes","mergeAttributes","InputRule","state","tr","start","end","nodePasteRule","attrs","emojiRegex","Suggestion","PluginKey","isEmoji","selection","empty","anchor","pos","getRegexMatches","regex","validator","matches","hasValidPrefix","trimEndPunctiation","string","endPunctuationRegex","getWordAt","left","right","word","getWordAtUntil","direction","newIndex","removeMarks","doc","type","from","to","marksInRange","getMarksBetween","mark","partialPhoneNumberRegex","getPhoneNumberRegex","addMarks","rangeFrom","rangeTo","firstWordInRange","lastWordInRange","wordsInRange","linkRegex","autolink","options","hasInitialized","Plugin","transactions","oldState","newState","contentChanged","textContent","transform","combineTransactionSteps","getChangedRanges","oldRange","newRange","findChildrenInRange","defaultAttributes","CustomLink","Mark","ConfigurableImage","Image","DivParagraph","Paragraph","DtLink","MentionPlugin","Mention","MentionComponent","ChannelPlugin","ChannelComponent","command","onSelectedCommand","_c","slashCommandPasteMatch","slashCommandRegex","slashCommand","SlashCommandPlugin","SlashCommandComponent","suggestions","suggestion","nodeInputRule","DtAvatar","mentionSuggestion","MentionSuggestion","DtIconHash","DtIconLock","channelSuggestion","ChannelSuggestion","slashCommandSuggestion","SlashCommandSuggestion","EditorContent","BubbleMenu","DtButton","autoFocus","RICH_TEXT_EDITOR_AUTOFOCUS_TYPES","outputFormat","RICH_TEXT_EDITOR_OUTPUT_FORMATS","DialtoneLocalization","extensions","Document","Text","History","HardBreak","Bold","Blockquote","BulletList","ListItem","OrderedList","Italic","Strike","Underline","Placeholder","self","ShiftEnter","Extension","commands","TipTapLink","RICH_TEXT_EDITOR_SUPPORTED_LINK_PROTOCOLS","suggestionObject","TextAlign","Code","CodeBlock","TextStyle","Color","FontFamily","isEditable","newClass","newLabel","newValue","warnIfUnmounted","Editor","view","allowedKeys","clipboardData","textData","htmlData","html","linkNode","linkText","link","_d","linkInput","linkOptions","linkProtocols","defaultPrefix","prefixRegex","returnIfEqual","currentValue","deepEqual","lines","i","extractedText","tempDiv","elements","element","styleAttr","elementStyle","hasPreElementStyle","hasPreInlineStyle","result","child","value","jsonValue","htmlValue","textValue","extension","attributes"],"mappings":"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"}