@docs.plus/extension-hyperlink 1.5.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/helpers/autoHyperlink.ts","../src/helpers/tippyHelper.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/helpers/editHyperlink.ts","../src/hyperlink.ts","../src/modals/editeHyperlink.ts","../src/modals/icons.ts","../src/modals/previewHyperlink.ts","../src/modals/setHyperlink.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from \"@tiptap/core\";\nimport { MarkType } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { find, test } from \"linkifyjs\";\n\ntype AutoHyperlinkOptions = {\n type: MarkType;\n validate?: (url: string) => boolean;\n};\n\nexport default function autoHyperlink(options: AutoHyperlinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey(\"autoHyperlink\"),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges =\n transactions.some((transaction) => transaction.docChanged) &&\n !oldState.doc.eq(newState.doc);\n const preventAutoHyperlink = transactions.some((transaction) =>\n transaction.getMeta(\"preventAutoHyperlink\")\n );\n\n if (!docChanges || preventAutoHyperlink) {\n return;\n }\n\n const { tr } = newState;\n const transform = combineTransactionSteps(oldState.doc, [\n ...transactions,\n ]);\n const { mapping } = transform;\n const changes = getChangedRanges(transform);\n\n changes.forEach(({ oldRange, newRange }) => {\n // at first we check if we have to remove links\n getMarksBetween(oldRange.from, oldRange.to, oldState.doc)\n .filter((item) => item.mark.type === options.type)\n .forEach((oldMark) => {\n const newFrom = mapping.map(oldMark.from);\n const newTo = mapping.map(oldMark.to);\n const newMarks = getMarksBetween(\n newFrom,\n newTo,\n newState.doc\n ).filter((item) => item.mark.type === options.type);\n\n if (!newMarks.length) {\n return;\n }\n\n const newMark = newMarks[0];\n const oldLinkText = oldState.doc.textBetween(\n oldMark.from,\n oldMark.to,\n undefined,\n \" \"\n );\n const newLinkText = newState.doc.textBetween(\n newMark.from,\n newMark.to,\n undefined,\n \" \"\n );\n const wasLink = test(oldLinkText);\n const isLink = test(newLinkText);\n\n // remove only the link, if it was a link before too\n // because we don’t want to remove links that were set manually\n if (wasLink && !isLink) {\n tr.removeMark(newMark.from, newMark.to, options.type);\n }\n });\n\n // now let’s see if we can add new links\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n (node) => node.isTextblock\n );\n\n let textBlock: NodeWithPos | undefined;\n let textBeforeWhitespace: string | undefined;\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter)\n textBlock = nodesInChangedRanges[0];\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n \" \"\n );\n } else if (\n nodesInChangedRanges.length &&\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces\n newState.doc\n .textBetween(newRange.from, newRange.to, \" \", \" \")\n .endsWith(\" \")\n ) {\n textBlock = nodesInChangedRanges[0];\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n \" \"\n );\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace\n .split(\" \")\n .filter((s) => s !== \"\");\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false;\n }\n\n const lastWordBeforeSpace =\n wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1];\n const lastWordAndBlockOffset =\n textBlock.pos +\n textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace);\n\n if (!lastWordBeforeSpace) {\n return false;\n }\n\n find(lastWordBeforeSpace)\n .filter((link) => link.isLink)\n .filter((link) => {\n if (options.validate) {\n return options.validate(link.value);\n }\n return true;\n })\n // calculate link position\n .map((link) => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // add link mark\n .forEach((link) => {\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n })\n );\n });\n }\n });\n\n if (!tr.steps.length) {\n return;\n }\n\n return tr;\n },\n });\n}\n","import tippy, { Instance, Props, roundArrow } from \"tippy.js\";\nimport { Editor } from \"@tiptap/core\";\nimport { EditorView } from \"@tiptap/pm/view\";\nimport { posToDOMRect } from \"@tiptap/core\";\n\nexport interface TippyInitOptions {\n editor: Editor;\n validate?: (url: string) => boolean;\n}\n\nclass Tooltip {\n private tippyInstance?: Instance;\n private preventHide: boolean = false;\n private tippyWrapper: HTMLDivElement;\n private editor: Editor;\n private view: EditorView;\n\n constructor(options: TippyInitOptions) {\n this.editor = options.editor;\n this.view = this.editor.view;\n this.tippyWrapper = document.createElement(\"div\");\n this.tippyWrapper.addEventListener(\"mousedown\", this.mousedownHandler, {\n capture: true,\n });\n this.view.dom.addEventListener(\"dragstart\", this.dragstartHandler);\n this.editor.on(\"blur\", this.blurHandler);\n }\n\n init() {\n this.tippyWrapper.innerHTML = \"\";\n\n return { tippyModal: this.tippyWrapper, tippyInstance: this.tippyInstance };\n }\n\n show() {\n this.tippyInstance?.show();\n return true;\n }\n\n hide() {\n setTimeout(() => this.tippyInstance?.hide());\n return false;\n }\n\n private mousedownHandler = () => {\n this.preventHide = true;\n };\n\n private dragstartHandler = () => {\n this.hide();\n };\n\n private blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false;\n return;\n }\n if (\n event?.relatedTarget &&\n this.tippyWrapper.parentNode?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n this.hide();\n };\n\n private tippyBlurHandler = (event: FocusEvent) => {\n this.blurHandler({ event });\n };\n\n private createTooltip() {\n if (!this.editor || !this.editor.options) return;\n const { element: editorElement } = this.editor.options;\n const editorIsAttached = !!editorElement.parentElement;\n\n if (this.tippyInstance || !editorIsAttached) {\n return;\n }\n\n this.tippyInstance = tippy(editorElement, {\n duration: 0,\n getReferenceClientRect: null,\n content: this.tippyWrapper,\n interactive: true,\n trigger: \"manual\",\n placement: \"bottom\",\n hideOnClick: true,\n onClickOutside: (instance, event) => {\n this.hide();\n },\n onAfterUpdate: (instance, partialProps) => {\n this.show();\n },\n });\n\n if (this.tippyInstance.popper.firstChild) {\n (this.tippyInstance.popper.firstChild as HTMLElement).addEventListener(\n \"blur\",\n this.tippyBlurHandler\n );\n }\n }\n\n update(view: EditorView, option: any = {}) {\n this.createTooltip();\n\n option.arrow = option?.arrow ?? false;\n\n if (this.tippyInstance) {\n this.tippyInstance.setProps({\n ...option,\n getReferenceClientRect: () => {\n const pos = view.state.selection.from;\n // width: 0 is a hack to prevent tippy display in the wrong position\n return { ...posToDOMRect(view, pos, pos), width: 0 };\n },\n });\n }\n\n return {};\n }\n\n destroyTooltip() {\n if (this.tippyInstance) {\n this.tippyInstance.destroy();\n this.tippyInstance = undefined;\n this.tippyWrapper.removeEventListener(\"mousedown\", this.mousedownHandler, {\n capture: true,\n });\n this.view.dom.removeEventListener(\"dragstart\", this.dragstartHandler);\n this.editor.off(\"blur\", this.blurHandler);\n }\n }\n}\n\nexport default Tooltip;\n","import { getAttributes } from \"@tiptap/core\";\nimport { MarkType } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Editor } from \"@tiptap/core\";\nimport { EditorView } from \"@tiptap/pm/view\";\nimport Tooltip from \"./tippyHelper\";\n\n// Define type for the ClickHandlerOptions\ntype ClickHandlerOptions = {\n type: MarkType;\n editor: Editor;\n validate?: (url: string) => boolean;\n modal?: ((options: any) => void | HTMLElement) | null;\n};\n\nexport default function clickHandler(options: ClickHandlerOptions): Plugin {\n // Create the tooltip instance\n let tooltip = new Tooltip(options);\n\n // Initialize the tooltip\n let { tippyModal, tippyInstance } = tooltip.init();\n\n return new Plugin({\n key: new PluginKey(\"handleClickHyperlink\"),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) return false;\n\n // Get the target HTML element and its position\n const nodeTarget: HTMLElement = event.target as HTMLElement;\n const nodePos = view.posAtDOM(nodeTarget, 0);\n\n // Find the closest link element to the target element\n const link = nodeTarget?.closest(\"a\");\n\n // Extract attributes from the state\n const attrs = getAttributes(view.state, options.type.name);\n\n // Extract href and target attributes from the link element or the state\n const href = link?.href ?? attrs.href;\n const target = link?.target ?? attrs.target;\n\n // If there is no previewHyperlink modal provided, then open the link in new window\n if (!options.modal) {\n if (link && href) {\n window.open(href, target);\n }\n return true;\n }\n\n // if the link does not contain href attribute, hide the tooltip\n if (!link?.href) return tooltip.hide();\n\n // Create a preview of the hyperlink\n const hyperlinkPreview = options.modal({\n link,\n nodePos,\n tippy: tooltip,\n ...options,\n });\n\n // If there is no hyperlink preview, hide the modal\n if (!hyperlinkPreview) return tooltip.hide();\n\n // Empty the modal and append the hyperlink preview box\n\n while (tippyModal.firstChild) {\n tippyModal.removeChild(tippyModal.firstChild);\n }\n\n tippyModal.append(hyperlinkPreview);\n\n // Update the modal position\n tooltip.update(options.editor.view);\n\n return false;\n },\n },\n });\n}\n","import { Editor } from \"@tiptap/core\";\nimport { MarkType } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { find } from \"linkifyjs\";\n\ntype PasteHandlerOptions = {\n editor: Editor;\n type: MarkType;\n};\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey(\"handlePasteHyperlink\"),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view;\n const { selection } = state;\n const { empty } = selection;\n\n if (empty) {\n return false;\n }\n\n let textContent = \"\";\n\n slice.content.forEach((node) => {\n textContent += node.textContent;\n });\n\n const link = find(textContent).find(\n (item) => item.isLink && item.value === textContent\n );\n\n if (!textContent || !link) {\n return false;\n }\n\n options.editor.commands.setMark(options.type, {\n href: link.href,\n });\n\n return true;\n },\n },\n });\n}\n","import { Editor } from \"@tiptap/core\";\nimport { find } from \"linkifyjs\";\n\ntype EditHyperlinkOptions = {\n editor: Editor;\n validate?: (url: string) => boolean;\n newURL?: string;\n newText?: string;\n};\n\nexport default function editHyperlink(options: EditHyperlinkOptions) {\n const { state, dispatch } = options.editor.view;\n const { from, to } = state.selection;\n let link: HTMLAnchorElement | null = null;\n\n const selectedNode = options.editor.view.domAtPos(from - 1).node as HTMLElement;\n const nodeName = selectedNode?.nodeName;\n\n if (nodeName === \"#text\") {\n link = (selectedNode.parentNode as HTMLElement)?.closest(\"a\");\n } else {\n link = selectedNode?.closest(\"a\");\n }\n\n // If no link found and node is paragraph, try finding link in sibling/parent\n if (!link && options.editor.view.domAtPos(from).node.nodeName === \"P\" && selectedNode.nextSibling)\n link =\n (selectedNode.nextSibling as HTMLAnchorElement) ||\n (selectedNode.parentElement as HTMLAnchorElement);\n\n if (!link) return true;\n\n const text = options.newText || link?.innerText;\n // Get the position of the link in the editor view\n const nodePos = options.editor.view.posAtDOM(link, 0);\n\n const sanitizeURL = find(options.newURL || link.href)\n .filter((link) => link.isLink)\n .filter((link) => (options.validate ? options.validate(link.value) : true))\n .at(0);\n\n return options.editor\n .chain()\n .focus()\n .command(({ tr }) => {\n tr.deleteRange(nodePos, nodePos + (link?.innerText || \"\")?.length).replaceWith(\n nodePos,\n nodePos,\n options.editor.schema.text(text, [\n options.editor.schema.marks.hyperlink.create({\n href: sanitizeURL?.href,\n }),\n ])\n );\n\n return true;\n })\n .run();\n}\n","import { Mark, markPasteRule, mergeAttributes } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { find, registerCustomProtocol, reset } from \"linkifyjs\";\nimport autoHyperlink from \"./helpers/autoHyperlink\";\nimport clickHandler from \"./helpers/clickHandler\";\nimport { pasteHandler } from \"./helpers/pasteHandler\";\nimport editHyperlinkHelper from \"./helpers/editHyperlink\";\nimport Tooltip from \"./helpers/tippyHelper\";\nimport { roundArrow } from \"tippy.js\";\nimport { TSetHyperlinkModalOptions } from \"./modals/setHyperlink\";\nimport { THyperlinkPreviewModalOptions } from \"./modals/previewHyperlink\";\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface HyperlinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autoHyperlink: boolean;\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>;\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean;\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n hyperlinkOnPaste: boolean;\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>;\n /**\n * A list of modals to be rendered.\n * @default null\n * @example\n */\n modals: {\n previewHyperlink?: ((options: THyperlinkPreviewModalOptions) => void | HTMLElement) | null;\n setHyperlink?: ((options: TSetHyperlinkModalOptions) => void | HTMLElement) | null;\n };\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n link: {\n /**\n * Edit the hyperlink's text\n */\n editHyperLinkText: (text: string) => ReturnType;\n\n /**\n * Edit the hyperlink's href value\n */\n editHyperLinkHref: (href: string) => ReturnType;\n\n /**\n * Edit the hyperlink's\n */\n editHyperlink: (attributes?: { newText?: string; newURL?: string }) => ReturnType;\n\n /**\n * Set a hyperlink\n */\n setHyperlink: (attributes?: { href: string; target?: string | null }) => ReturnType;\n\n /**\n * Unset a link mark\n */\n unsetHyperlink: () => ReturnType;\n };\n }\n}\n\nexport const Hyperlink = Mark.create<HyperlinkOptions>({\n name: \"hyperlink\",\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach((protocol) => {\n if (typeof protocol === \"string\") {\n registerCustomProtocol(protocol);\n return;\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes);\n });\n },\n\n onDestroy() {\n reset();\n },\n\n inclusive() {\n return this.options.autoHyperlink;\n },\n\n addOptions() {\n return {\n openOnClick: true,\n hyperlinkOnPaste: true,\n autoHyperlink: true,\n protocols: [],\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer nofollow\",\n class: null,\n },\n modals: {\n previewHyperlink: null,\n setHyperlink: null,\n },\n validate: undefined,\n };\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"a\", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];\n },\n\n addCommands() {\n return {\n setHyperlink:\n (attributes) =>\n ({ editor, chain }) => {\n if (!this.options.modals.setHyperlink) {\n return chain()\n .setMark(this.name, attributes)\n .setMeta(\"preventAutohyperlink\", true)\n .run();\n } else {\n this.options.modals.setHyperlink({\n editor,\n validate: this.options.validate,\n extentionName: this.name,\n attributes,\n Tooltip,\n roundArrow,\n });\n return true;\n }\n },\n\n editHyperlink:\n (attributes) =>\n ({ editor }) => {\n return editHyperlinkHelper({\n ...attributes,\n editor,\n validate: this.options.validate,\n });\n },\n\n editHyperLinkText:\n (newText) =>\n ({ editor }) => {\n return editHyperlinkHelper({\n editor,\n newText,\n validate: this.options.validate,\n });\n },\n\n editHyperLinkHref:\n (newURL) =>\n ({ editor }) => {\n return editHyperlinkHelper({\n editor,\n validate: this.options.validate,\n newURL,\n });\n },\n\n unsetHyperlink:\n () =>\n ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta(\"preventAutohyperlink\", true)\n .run();\n },\n };\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: (text) =>\n find(text)\n .filter((link) => {\n if (this.options.validate) {\n return this.options.validate(link.value);\n }\n\n return true;\n })\n .filter((link) => link.isLink)\n .map((link) => ({\n text: link.value,\n index: link.start,\n data: link,\n })),\n type: this.type,\n getAttributes: (match) => ({\n href: match.data?.href,\n }),\n }),\n ];\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = [];\n\n if (this.options.autoHyperlink) {\n plugins.push(\n autoHyperlink({\n type: this.type,\n validate: this.options.validate,\n })\n );\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n editor: this.editor,\n validate: this.options.validate,\n modal: this.options.modals.previewHyperlink,\n })\n );\n }\n\n if (this.options.hyperlinkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n })\n );\n }\n\n return plugins;\n },\n});\n","import { Editor } from \"@tiptap/core\";\nimport { roundArrow } from \"tippy.js\";\nimport { find } from \"linkifyjs\";\nimport Tooltip from \"../helpers/tippyHelper\";\n\ntype EditHyperlinkModalOptions = {\n editor: Editor;\n validate?: (url: string) => boolean;\n link: HTMLAnchorElement;\n hyperlinkModal: HTMLElement;\n tippy: Tooltip;\n};\n\nexport const editHyperlinkHandler = (options: EditHyperlinkModalOptions) => {\n // Create the form\n const form = document.createElement(\"form\");\n\n const buttonsWrapper = document.createElement(\"div\");\n const inputsWrapper = document.createElement(\"div\");\n\n const linkTextInput = document.createElement(\"input\");\n const hrefInput = document.createElement(\"input\");\n const applyButton = document.createElement(\"button\");\n\n buttonsWrapper.classList.add(\"hyperlink-edit-modal__buttons-wrapper\");\n inputsWrapper.classList.add(\"hyperlink-edit-modal__inputs-wrapper\");\n\n linkTextInput.type = \"text\";\n linkTextInput.value = options.link?.innerText || \"\";\n linkTextInput.placeholder = \"Enter link text\";\n\n hrefInput.type = \"text\";\n hrefInput.value = options.link.href;\n hrefInput.placeholder = \"Enter href\";\n\n applyButton.type = \"submit\";\n applyButton.classList.add(\"hyperlink-edit-modal__apply-button\");\n applyButton.innerText = \"Apply\";\n\n buttonsWrapper.append(applyButton);\n inputsWrapper.append(linkTextInput, hrefInput);\n\n // Append to form\n form.append(inputsWrapper, buttonsWrapper);\n\n options.hyperlinkModal.innerHTML = \"\";\n options.hyperlinkModal.appendChild(form);\n\n hrefInput.addEventListener(\"keydown\", () => {\n hrefInput.style.outlineColor = \" #dadce0\";\n });\n\n hrefInput.addEventListener(\"keydown\", () => {\n linkTextInput.style.outlineColor = \" #dadce0\";\n });\n\n // Handle form submission\n form.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n\n const newLinkText = linkTextInput.value;\n const newHref = hrefInput.value;\n\n if (!newHref || !newLinkText) {\n if (!newHref) hrefInput.style.outlineColor = \"red\";\n if (!newLinkText) linkTextInput.style.outlineColor = \"red\";\n return;\n }\n\n const sanitizeURL = find(newHref)\n .filter((link) => link.isLink)\n .filter((link) => {\n if (options.validate) {\n return options.validate(link.value);\n }\n return true;\n })\n .at(0);\n\n if (!sanitizeURL?.href) {\n hrefInput.style.outlineColor = \"red\";\n return;\n }\n\n options.editor.chain().focus().extendMarkRange(\"hyperlink\").editHyperlink({\n newURL: newHref,\n newText: newLinkText,\n });\n\n options.tippy.hide();\n });\n\n // Show tooltip\n options.tippy.update(options.editor.view, {\n arrow: roundArrow,\n });\n\n setTimeout(() => linkTextInput.focus());\n};\n","interface IconProps {\n size?: number;\n fill?: string;\n}\n\n// prettier-ignore\nexport const Copy = ({ size = 24, fill = 'rgb(104, 81, 255)' }: IconProps = {}) => {\n return `\n <svg fill=${fill} viewBox=\"0 0 24 24\" width=${size} xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"m13 20a5.006 5.006 0 0 0 5-5v-8.757a3.972 3.972 0 0 0 -1.172-2.829l-2.242-2.242a3.972 3.972 0 0 0 -2.829-1.172h-4.757a5.006 5.006 0 0 0 -5 5v10a5.006 5.006 0 0 0 5 5zm-9-5v-10a3 3 0 0 1 3-3s4.919.014 5 .024v1.976a2 2 0 0 0 2 2h1.976c.01.081.024 9 .024 9a3 3 0 0 1 -3 3h-6a3 3 0 0 1 -3-3zm18-7v11a5.006 5.006 0 0 1 -5 5h-9a1 1 0 0 1 0-2h9a3 3 0 0 0 3-3v-11a1 1 0 0 1 2 0z\"/>\n </svg>\n `\n}\n\nexport const LinkSlash = ({\n size = 24,\n fill = \"rgb(104, 81, 255)\",\n}: IconProps = {}) => {\n return `\n <svg fill=${fill} viewBox=\"0 0 24 24\" width=${size} xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.953,17.993c-1.557-.074-3.021-.722-4.121-1.823-.23-.23-.446-.482-.641-.748-.325-.446-.227-1.072,.22-1.397,.446-.325,1.071-.227,1.397,.219,.129,.178,.274,.349,.437,.511,.749,.75,1.744,1.19,2.802,1.24,.552,.026,.979,.495,.952,1.046-.025,.536-.468,.953-.998,.953h-.048ZM1.831,13.331C.65,14.511,0,16.081,0,17.75c0,1.669,.65,3.239,1.831,4.419,1.18,1.181,2.749,1.831,4.419,1.831s3.239-.65,4.419-1.831l1.058-1.058c.391-.391,.391-1.023,0-1.414s-1.023-.391-1.414,0l-1.058,1.058c-.803,.803-1.87,1.245-3.005,1.245s-2.202-.442-3.005-1.245-1.245-1.87-1.245-3.005,.442-2.203,1.245-3.005l3.037-3.038c.391-.391,.391-1.024,0-1.414-.391-.391-1.023-.391-1.414,0l-3.037,3.038ZM.293,1.707L22.293,23.707c.195,.195,.451,.293,.707,.293s.512-.098,.707-.293c.391-.391,.391-1.023,0-1.414l-6.581-6.581,5.043-5.043c1.181-1.18,1.831-2.75,1.831-4.419,0-1.669-.65-3.239-1.831-4.419C20.989,.65,19.42,0,17.75,0s-3.239,.65-4.419,1.831l-1.058,1.058c-.391,.391-.391,1.023,0,1.414s1.023,.391,1.414,0l1.058-1.058c.803-.803,1.87-1.245,3.005-1.245s2.202,.442,3.005,1.245,1.245,1.87,1.245,3.005-.442,2.203-1.245,3.005l-5.043,5.043-5.852-5.852c1.612-.808,3.575-.52,4.894,.798,.162,.162,.308,.333,.437,.511,.196,.269,.501,.411,.81,.411,.204,0,.41-.063,.588-.192,.446-.325,.545-.951,.22-1.397-.194-.266-.41-.518-.641-.748-2.095-2.095-5.297-2.408-7.76-.835L1.707,.293c-.391-.391-1.023-.391-1.414,0s-.391,1.023,0,1.414Z\"/>\n </svg>\n `;\n};\n\nexport const Pencil = ({\n size = 24,\n fill = \"rgb(104, 81, 255)\",\n}: IconProps = {}) => {\n return `\n <svg fill=${fill} viewBox=\"0 0 24 24\" width=${size} xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M22.853,1.148a3.626,3.626,0,0,0-5.124,0L1.465,17.412A4.968,4.968,0,0,0,0,20.947V23a1,1,0,0,0,1,1H3.053a4.966,4.966,0,0,0,3.535-1.464L22.853,6.271A3.626,3.626,0,0,0,22.853,1.148ZM5.174,21.122A3.022,3.022,0,0,1,3.053,22H2V20.947a2.98,2.98,0,0,1,.879-2.121L15.222,6.483l2.3,2.3ZM21.438,4.857,18.932,7.364l-2.3-2.295,2.507-2.507a1.623,1.623,0,1,1,2.295,2.3Z\"/>\n </svg>\n `;\n};\n\nexport const AngleUp = ({\n size = 32,\n fill = \"rgb(104, 81, 255)\",\n}: IconProps = {}) => {\n return `\n <svg fill=${fill} viewBox=\"0 0 24 24\" width=${size} xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M17.293,15.207,12,9.914,6.707,15.207,5.293,13.793,10.586,8.5a2,2,0,0,1,2.828,0l5.293,5.293Z\"/>\n </svg>\n `;\n};\n","import { Editor } from \"@tiptap/core\";\nimport { editHyperlinkHandler } from \"./editeHyperlink\";\nimport { Copy, LinkSlash, Pencil } from \"./icons\";\nimport Tooltip from \"../helpers/tippyHelper\";\n\nexport type THyperlinkPreviewModalOptions = {\n editor: Editor;\n validate?: (url: string) => boolean;\n link: HTMLAnchorElement;\n node?: any;\n nodePos: number;\n tippy: Tooltip;\n};\n\nexport function previewHyperlinkModal(options: THyperlinkPreviewModalOptions): HTMLElement {\n const href = options.link.href;\n\n const hyperlinkModal = document.createElement(\"div\");\n const removeButton = document.createElement(\"button\");\n const copyButton = document.createElement(\"button\");\n const editButton = document.createElement(\"button\");\n\n const newBubble = document.createElement(\"div\");\n newBubble.classList.add(\"hyperlink-preview-modal__metadata\");\n\n const hrefTitle = document.createElement(\"a\");\n hrefTitle.setAttribute(\"target\", \"_blank\");\n hrefTitle.setAttribute(\"rel\", \"noreferrer\");\n hrefTitle.setAttribute(\"href\", href);\n hrefTitle.innerText = href;\n\n newBubble.append(hrefTitle);\n\n fetch(\"/api/metadata\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ url: href }),\n })\n .then((response) => response.json())\n .then((data) => {\n // Create a new bubble with the title\n hrefTitle.setAttribute(\"href\", href);\n\n hrefTitle.innerText = data.title || data[\"og:title\"] || href;\n newBubble.replaceChildren(hrefTitle);\n\n // Create an image element if image exists in metadata\n if (data.icon || data.image || data[\"og:image\"]) {\n const img = document.createElement(\"img\");\n img.src = data.icon || data.image || data[\"og:image\"];\n img.alt = data.title || data[\"og:title\"] || \"hyperlink image\";\n newBubble.appendChild(img);\n }\n })\n .catch((error) => {\n console.error(\"Error fetching metadata:\", error);\n });\n\n hyperlinkModal.classList.add(\"hyperlink-preview-modal\");\n\n removeButton.classList.add(\"hyperlink-preview-modal__remove-button\");\n removeButton.innerHTML = LinkSlash();\n\n editButton.classList.add(\"hyperlink-preview-modal__edit-button\");\n editButton.innerHTML = Pencil();\n\n copyButton.classList.add(\"hyperlink-preview-modal__copy-button\");\n copyButton.innerHTML = Copy();\n\n removeButton.addEventListener(\"click\", () => {\n options.tippy.hide();\n return options.editor.chain().focus().unsetHyperlink().run();\n });\n\n editButton.addEventListener(\"click\", () => editHyperlinkHandler({ ...options, hyperlinkModal }));\n\n copyButton.addEventListener(\"click\", () => {\n options.tippy.hide();\n navigator.clipboard.writeText(href);\n });\n\n hyperlinkModal.append(newBubble, copyButton, editButton, removeButton);\n\n return hyperlinkModal;\n}\n","import { Editor } from \"@tiptap/core\";\nimport Tooltip, { TippyInitOptions } from \"../helpers/tippyHelper\";\nimport { find } from \"linkifyjs\";\n\nexport type TSetHyperlinkModalOptions = {\n editor: Editor;\n validate?: (url: string) => boolean;\n extentionName: string;\n attributes?: { href: string; target?: string | null };\n Tooltip: new (options: TippyInitOptions) => Tooltip;\n roundArrow: string;\n};\n\nlet tooltip: Tooltip | undefined = undefined;\n\nexport function setHyperlinkModal(options: TSetHyperlinkModalOptions): void {\n // Create the tooltip instance\n if (!tooltip) tooltip = new options.Tooltip(options);\n\n // Initialize the tooltip\n let { tippyModal } = tooltip.init();\n\n const hyperlinkModal = document.createElement(\"div\");\n const buttonsWrapper = document.createElement(\"div\");\n const inputsWrapper = document.createElement(\"div\");\n\n hyperlinkModal.classList.add(\"hyperlink-set-modal\");\n\n buttonsWrapper.classList.add(\"hyperlink-set-modal__buttons-wrapper\");\n inputsWrapper.classList.add(\"hyperlink-set-modal__inputs-wrapper\");\n\n // create a form that contain url input and a button for submit\n const form = document.createElement(\"form\");\n const input = document.createElement(\"input\");\n const button = document.createElement(\"button\");\n\n input.setAttribute(\"type\", \"text\");\n input.setAttribute(\"placeholder\", \"https://example.com\");\n button.setAttribute(\"type\", \"submit\");\n button.innerText = \"Submit\";\n\n inputsWrapper.append(input);\n buttonsWrapper.append(button);\n form.append(inputsWrapper, buttonsWrapper);\n\n hyperlinkModal.append(form);\n\n tippyModal.innerHTML = \"\";\n tippyModal.append(hyperlinkModal);\n tooltip.update(options.editor.view, {\n arrow: options.roundArrow,\n });\n\n // make sure\n setTimeout(() => {\n input.focus();\n input.style.outlineColor = \" #dadce0\";\n }, 100);\n\n input.addEventListener(\"keydown\", () => {\n input.style.outlineColor = \" #dadce0\";\n });\n\n // event listenr for submit button\n form.addEventListener(\"submit\", (event) => {\n event.preventDefault();\n const url = input.value;\n\n if (!url) {\n input.style.outlineColor = \"red\";\n return;\n }\n\n const sanitizeURL = find(url)\n .filter((link) => link.isLink)\n .filter((link) => {\n if (options.validate) {\n return options.validate(link.value);\n }\n return true;\n })\n .at(0);\n\n if (!sanitizeURL?.href) {\n input.style.outlineColor = \"red\";\n return;\n }\n\n tooltip?.hide();\n\n return options.editor\n .chain()\n .setMark(options.extentionName, { href: sanitizeURL.href })\n .setMeta(\"preventautohyperlink\", true)\n .run();\n });\n}\n"],"names":["editHyperlinkHelper"],"mappings":";;;;;AAgBwB,SAAA,aAAa,CAAC,OAA6B,EAAA;IACjE,OAAO,IAAI,MAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAI,SAAS,CAAC,eAAe,CAAC;QACnC,iBAAiB,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAI;AACtD,YAAA,MAAM,UAAU,GACd,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,UAAU,CAAC;gBAC1D,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,YAAA,MAAM,oBAAoB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,KACzD,WAAW,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAC5C,CAAC;AAEF,YAAA,IAAI,CAAC,UAAU,IAAI,oBAAoB,EAAE;gBACvC,OAAO;AACR,aAAA;AAED,YAAA,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC;AACxB,YAAA,MAAM,SAAS,GAAG,uBAAuB,CAAC,QAAQ,CAAC,GAAG,EAAE;AACtD,gBAAA,GAAG,YAAY;AAChB,aAAA,CAAC,CAAC;AACH,YAAA,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;AAC9B,YAAA,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAI;;AAEzC,gBAAA,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC;AACtD,qBAAA,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC;AACjD,qBAAA,OAAO,CAAC,CAAC,OAAO,KAAI;oBACnB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtC,oBAAA,MAAM,QAAQ,GAAG,eAAe,CAC9B,OAAO,EACP,KAAK,EACL,QAAQ,CAAC,GAAG,CACb,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpD,oBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;wBACpB,OAAO;AACR,qBAAA;AAED,oBAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC5B,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC1C,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,EAAE,EACV,SAAS,EACT,GAAG,CACJ,CAAC;oBACF,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC1C,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,EAAE,EACV,SAAS,EACT,GAAG,CACJ,CAAC;AACF,oBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;AAClC,oBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;;;AAIjC,oBAAA,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE;AACtB,wBAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACvD,qBAAA;AACH,iBAAC,CAAC,CAAC;;AAGL,gBAAA,MAAM,oBAAoB,GAAG,mBAAmB,CAC9C,QAAQ,CAAC,GAAG,EACZ,QAAQ,EACR,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAC3B,CAAC;AAEF,gBAAA,IAAI,SAAkC,CAAC;AACvC,gBAAA,IAAI,oBAAwC,CAAC;AAE7C,gBAAA,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;;AAEnC,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;oBACpC,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EACvC,SAAS,EACT,GAAG,CACJ,CAAC;AACH,iBAAA;qBAAM,IACL,oBAAoB,CAAC,MAAM;;AAE3B,oBAAA,QAAQ,CAAC,GAAG;AACT,yBAAA,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC;yBACjD,QAAQ,CAAC,GAAG,CAAC,EAChB;AACA,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AACpC,oBAAA,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,QAAQ,CAAC,EAAE,EACX,SAAS,EACT,GAAG,CACJ,CAAC;AACH,iBAAA;gBAED,IAAI,SAAS,IAAI,oBAAoB,EAAE;oBACrC,MAAM,qBAAqB,GAAG,oBAAoB;yBAC/C,KAAK,CAAC,GAAG,CAAC;yBACV,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;AAE3B,oBAAA,IAAI,qBAAqB,CAAC,MAAM,IAAI,CAAC,EAAE;AACrC,wBAAA,OAAO,KAAK,CAAC;AACd,qBAAA;oBAED,MAAM,mBAAmB,GACvB,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1D,oBAAA,MAAM,sBAAsB,GAC1B,SAAS,CAAC,GAAG;AACb,wBAAA,oBAAoB,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;oBAExD,IAAI,CAAC,mBAAmB,EAAE;AACxB,wBAAA,OAAO,KAAK,CAAC;AACd,qBAAA;oBAED,IAAI,CAAC,mBAAmB,CAAC;yBACtB,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AAC7B,yBAAA,MAAM,CAAC,CAAC,IAAI,KAAI;wBACf,IAAI,OAAO,CAAC,QAAQ,EAAE;4BACpB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrC,yBAAA;AACD,wBAAA,OAAO,IAAI,CAAC;AACd,qBAAC,CAAC;;AAED,yBAAA,GAAG,CAAC,CAAC,IAAI,MAAM;AACd,wBAAA,GAAG,IAAI;AACP,wBAAA,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;AAC7C,wBAAA,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;AAC1C,qBAAA,CAAC,CAAC;;AAEF,yBAAA,OAAO,CAAC,CAAC,IAAI,KAAI;AAChB,wBAAA,EAAE,CAAC,OAAO,CACR,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;4BAClB,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,yBAAA,CAAC,CACH,CAAC;AACJ,qBAAC,CAAC,CAAC;AACN,iBAAA;AACH,aAAC,CAAC,CAAC;AAEH,YAAA,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE;gBACpB,OAAO;AACR,aAAA;AAED,YAAA,OAAO,EAAE,CAAC;SACX;AACF,KAAA,CAAC,CAAC;AACL;;AC5JA,MAAM,OAAO,CAAA;AAOX,IAAA,WAAA,CAAY,OAAyB,EAAA;QAL7B,IAAW,CAAA,WAAA,GAAY,KAAK,CAAC;QAgC7B,IAAgB,CAAA,gBAAA,GAAG,MAAK;AAC9B,YAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAC1B,SAAC,CAAC;QAEM,IAAgB,CAAA,gBAAA,GAAG,MAAK;YAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;AACd,SAAC,CAAC;AAEM,QAAA,IAAA,CAAA,WAAW,GAAG,CAAC,EAAE,KAAK,EAAyB,KAAI;;YACzD,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,gBAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,OAAO;AACR,aAAA;AACD,YAAA,IACE,CAAA,KAAK,KAAA,IAAA,IAAL,KAAK,KAAL,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,KAAK,CAAE,aAAa;AACpB,iBAAA,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,CAAC,UAAU,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,CAAA,EACnE;gBACA,OAAO;AACR,aAAA;YACD,IAAI,CAAC,IAAI,EAAE,CAAC;AACd,SAAC,CAAC;AAEM,QAAA,IAAA,CAAA,gBAAgB,GAAG,CAAC,KAAiB,KAAI;AAC/C,YAAA,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9B,SAAC,CAAC;AAlDA,QAAA,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,EAAE;AACrE,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;AACH,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;KAC1C;IAED,IAAI,GAAA;AACF,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,EAAE,CAAC;AAEjC,QAAA,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;KAC7E;IAED,IAAI,GAAA;;AACF,QAAA,CAAA,EAAA,GAAA,IAAI,CAAC,aAAa,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAI,EAAE,CAAC;AAC3B,QAAA,OAAO,IAAI,CAAC;KACb;IAED,IAAI,GAAA;AACF,QAAA,UAAU,CAAC,MAAK,EAAA,IAAA,EAAA,CAAA,CAAC,OAAA,CAAA,EAAA,GAAA,IAAI,CAAC,aAAa,0CAAE,IAAI,EAAE,CAAA,EAAA,CAAC,CAAC;AAC7C,QAAA,OAAO,KAAK,CAAC;KACd;IA4BO,aAAa,GAAA;QACnB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QACjD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACvD,QAAA,MAAM,gBAAgB,GAAG,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC;AAEvD,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,gBAAgB,EAAE;YAC3C,OAAO;AACR,SAAA;AAED,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,EAAE;AACxC,YAAA,QAAQ,EAAE,CAAC;AACX,YAAA,sBAAsB,EAAE,IAAI;YAC5B,OAAO,EAAE,IAAI,CAAC,YAAY;AAC1B,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,OAAO,EAAE,QAAQ;AACjB,YAAA,SAAS,EAAE,QAAQ;AACnB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,cAAc,EAAE,CAAC,QAAQ,EAAE,KAAK,KAAI;gBAClC,IAAI,CAAC,IAAI,EAAE,CAAC;aACb;AACD,YAAA,aAAa,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAI;gBACxC,IAAI,CAAC,IAAI,EAAE,CAAC;aACb;AACF,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE;AACvC,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAA0B,CAAC,gBAAgB,CACpE,MAAM,EACN,IAAI,CAAC,gBAAgB,CACtB,CAAC;AACH,SAAA;KACF;AAED,IAAA,MAAM,CAAC,IAAgB,EAAE,MAAA,GAAc,EAAE,EAAA;;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;AAErB,QAAA,MAAM,CAAC,KAAK,GAAG,CAAA,EAAA,GAAA,MAAM,KAAA,IAAA,IAAN,MAAM,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAN,MAAM,CAAE,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC;QAEtC,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC1B,gBAAA,GAAG,MAAM;gBACT,sBAAsB,EAAE,MAAK;oBAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;;AAEtC,oBAAA,OAAO,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;iBACtD;AACF,aAAA,CAAC,CAAC;AACJ,SAAA;AAED,QAAA,OAAO,EAAE,CAAC;KACX;IAED,cAAc,GAAA;QACZ,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;AAC7B,YAAA,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,EAAE;AACxE,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA,CAAC,CAAC;AACH,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACtE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;AAC3C,SAAA;KACF;AACF;;ACtHuB,SAAA,YAAY,CAAC,OAA4B,EAAA;;AAE/D,IAAA,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;;IAGnC,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAEnD,OAAO,IAAI,MAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAI,SAAS,CAAC,sBAAsB,CAAC;AAC1C,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,KAAI;;AAChC,gBAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;AAAE,oBAAA,OAAO,KAAK,CAAC;;AAGrC,gBAAA,MAAM,UAAU,GAAgB,KAAK,CAAC,MAAqB,CAAC;gBAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;;AAG7C,gBAAA,MAAM,IAAI,GAAG,UAAU,KAAA,IAAA,IAAV,UAAU,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAV,UAAU,CAAE,OAAO,CAAC,GAAG,CAAC,CAAC;;AAGtC,gBAAA,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;AAG3D,gBAAA,MAAM,IAAI,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,IAAI,CAAC;AACtC,gBAAA,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,MAAM,CAAC;;AAG5C,gBAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;oBAClB,IAAI,IAAI,IAAI,IAAI,EAAE;AAChB,wBAAA,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,qBAAA;AACD,oBAAA,OAAO,IAAI,CAAC;AACb,iBAAA;;gBAGD,IAAI,EAAC,IAAI,KAAA,IAAA,IAAJ,IAAI,KAAJ,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,IAAI,CAAE,IAAI,CAAA;AAAE,oBAAA,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;;AAGvC,gBAAA,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC;oBACrC,IAAI;oBACJ,OAAO;AACP,oBAAA,KAAK,EAAE,OAAO;AACd,oBAAA,GAAG,OAAO;AACX,iBAAA,CAAC,CAAC;;AAGH,gBAAA,IAAI,CAAC,gBAAgB;AAAE,oBAAA,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;;gBAI7C,OAAO,UAAU,CAAC,UAAU,EAAE;AAC5B,oBAAA,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/C,iBAAA;AAED,gBAAA,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;;gBAGpC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAEpC,gBAAA,OAAO,KAAK,CAAC;aACd;AACF,SAAA;AACF,KAAA,CAAC,CAAC;AACL;;ACrEM,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,OAAO,IAAI,MAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAI,SAAS,CAAC,sBAAsB,CAAC;AAC1C,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,KAAI;AAClC,gBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;AACvB,gBAAA,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;AAC5B,gBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;AAE5B,gBAAA,IAAI,KAAK,EAAE;AACT,oBAAA,OAAO,KAAK,CAAC;AACd,iBAAA;gBAED,IAAI,WAAW,GAAG,EAAE,CAAC;gBAErB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AAC7B,oBAAA,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC;AAClC,iBAAC,CAAC,CAAC;gBAEH,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CACjC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CACpD,CAAC;AAEF,gBAAA,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE;AACzB,oBAAA,OAAO,KAAK,CAAC;AACd,iBAAA;gBAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;oBAC5C,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,iBAAA,CAAC,CAAC;AAEH,gBAAA,OAAO,IAAI,CAAC;aACb;AACF,SAAA;AACF,KAAA,CAAC,CAAC;AACL;;ACnCwB,SAAA,aAAa,CAAC,OAA6B,EAAA;;IACjE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;IAChD,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,IAAI,IAAI,GAA6B,IAAI,CAAC;AAE1C,IAAA,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAmB,CAAC;IAChF,MAAM,QAAQ,GAAG,YAAY,KAAA,IAAA,IAAZ,YAAY,KAAZ,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,YAAY,CAAE,QAAQ,CAAC;IAExC,IAAI,QAAQ,KAAK,OAAO,EAAE;QACxB,IAAI,GAAG,CAAC,EAAA,GAAA,YAAY,CAAC,UAA0B,0CAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AAC/D,KAAA;AAAM,SAAA;QACL,IAAI,GAAG,YAAY,KAAA,IAAA,IAAZ,YAAY,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAZ,YAAY,CAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AACnC,KAAA;;IAGD,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,GAAG,IAAI,YAAY,CAAC,WAAW;QAC/F,IAAI;AACD,YAAA,YAAY,CAAC,WAAiC;gBAC9C,YAAY,CAAC,aAAmC,CAAC;AAEtD,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI,CAAC;AAEvB,IAAA,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,KAAI,IAAI,KAAJ,IAAA,IAAA,IAAI,KAAJ,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,IAAI,CAAE,SAAS,CAAA,CAAC;;AAEhD,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC;SAClD,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;SAC7B,MAAM,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;SAC1E,EAAE,CAAC,CAAC,CAAC,CAAC;IAET,OAAO,OAAO,CAAC,MAAM;AAClB,SAAA,KAAK,EAAE;AACP,SAAA,KAAK,EAAE;AACP,SAAA,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,KAAI;;AAClB,QAAA,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,IAAG,CAAA,EAAA,IAAC,CAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,SAAS,KAAI,EAAE,CAAC,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,CAAA,CAAC,CAAC,WAAW,CAC5E,OAAO,EACP,OAAO,EACP,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;YAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC;AAC3C,gBAAA,IAAI,EAAE,WAAW,KAAA,IAAA,IAAX,WAAW,KAAX,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,WAAW,CAAE,IAAI;aACxB,CAAC;AACH,SAAA,CAAC,CACH,CAAC;AAEF,QAAA,OAAO,IAAI,CAAC;AACd,KAAC,CAAC;AACD,SAAA,GAAG,EAAE,CAAC;AACX;;AC4Ba,MAAA,SAAS,GAAG,IAAI,CAAC,MAAM,CAAmB;AACrD,IAAA,IAAI,EAAE,WAAW;AAEjB,IAAA,QAAQ,EAAE,IAAI;AAEd,IAAA,WAAW,EAAE,KAAK;IAElB,QAAQ,GAAA;QACN,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;AAC1C,YAAA,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;gBAChC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;gBACjC,OAAO;AACR,aAAA;YACD,sBAAsB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;AACpE,SAAC,CAAC,CAAC;KACJ;IAED,SAAS,GAAA;AACP,QAAA,KAAK,EAAE,CAAC;KACT;IAED,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;KACnC;IAED,UAAU,GAAA;QACR,OAAO;AACL,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,gBAAgB,EAAE,IAAI;AACtB,YAAA,aAAa,EAAE,IAAI;AACnB,YAAA,SAAS,EAAE,EAAE;AACb,YAAA,cAAc,EAAE;AACd,gBAAA,MAAM,EAAE,QAAQ;AAChB,gBAAA,GAAG,EAAE,8BAA8B;AACnC,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,gBAAgB,EAAE,IAAI;AACtB,gBAAA,YAAY,EAAE,IAAI;AACnB,aAAA;AACD,YAAA,QAAQ,EAAE,SAAS;SACpB,CAAC;KACH;IAED,aAAa,GAAA;QACX,OAAO;AACL,YAAA,IAAI,EAAE;AACJ,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM;AAC5C,aAAA;AACD,YAAA,KAAK,EAAE;AACL,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK;AAC3C,aAAA;SACF,CAAC;KACH;IAED,SAAS,GAAA;AACP,QAAA,OAAO,CAAC,EAAE,GAAG,EAAE,wCAAwC,EAAE,CAAC,CAAC;KAC5D;IAED,UAAU,CAAC,EAAE,cAAc,EAAE,EAAA;AAC3B,QAAA,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;KAC/E;IAED,WAAW,GAAA;QACT,OAAO;AACL,YAAA,YAAY,EACV,CAAC,UAAU,KACX,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAI;gBACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE;AACrC,oBAAA,OAAO,KAAK,EAAE;AACX,yBAAA,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;AAC9B,yBAAA,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC;AACrC,yBAAA,GAAG,EAAE,CAAC;AACV,iBAAA;AAAM,qBAAA;AACL,oBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;wBAC/B,MAAM;AACN,wBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;wBAC/B,aAAa,EAAE,IAAI,CAAC,IAAI;wBACxB,UAAU;wBACV,OAAO;wBACP,UAAU;AACX,qBAAA,CAAC,CAAC;AACH,oBAAA,OAAO,IAAI,CAAC;AACb,iBAAA;aACF;YAEH,aAAa,EACX,CAAC,UAAU,KACX,CAAC,EAAE,MAAM,EAAE,KAAI;AACb,gBAAA,OAAOA,aAAmB,CAAC;AACzB,oBAAA,GAAG,UAAU;oBACb,MAAM;AACN,oBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAChC,iBAAA,CAAC,CAAC;aACJ;YAEH,iBAAiB,EACf,CAAC,OAAO,KACR,CAAC,EAAE,MAAM,EAAE,KAAI;AACb,gBAAA,OAAOA,aAAmB,CAAC;oBACzB,MAAM;oBACN,OAAO;AACP,oBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAChC,iBAAA,CAAC,CAAC;aACJ;YAEH,iBAAiB,EACf,CAAC,MAAM,KACP,CAAC,EAAE,MAAM,EAAE,KAAI;AACb,gBAAA,OAAOA,aAAmB,CAAC;oBACzB,MAAM;AACN,oBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;oBAC/B,MAAM;AACP,iBAAA,CAAC,CAAC;aACJ;YAEH,cAAc,EACZ,MACA,CAAC,EAAE,KAAK,EAAE,KAAI;AACZ,gBAAA,OAAO,KAAK,EAAE;qBACX,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACpD,qBAAA,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC;AACrC,qBAAA,GAAG,EAAE,CAAC;aACV;SACJ,CAAC;KACH;IAED,aAAa,GAAA;QACX,OAAO;AACL,YAAA,aAAa,CAAC;gBACZ,IAAI,EAAE,CAAC,IAAI,KACT,IAAI,CAAC,IAAI,CAAC;AACP,qBAAA,MAAM,CAAC,CAAC,IAAI,KAAI;AACf,oBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;wBACzB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1C,qBAAA;AAED,oBAAA,OAAO,IAAI,CAAC;AACd,iBAAC,CAAC;qBACD,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AAC7B,qBAAA,GAAG,CAAC,CAAC,IAAI,MAAM;oBACd,IAAI,EAAE,IAAI,CAAC,KAAK;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,oBAAA,IAAI,EAAE,IAAI;AACX,iBAAA,CAAC,CAAC;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,aAAa,EAAE,CAAC,KAAK,KAAI;;AAAC,oBAAA,QAAC;AACzB,wBAAA,IAAI,EAAE,CAAA,EAAA,GAAA,KAAK,CAAC,IAAI,0CAAE,IAAI;AACvB,qBAAA,EAAC;AAAA,iBAAA;aACH,CAAC;SACH,CAAC;KACH;IAED,qBAAqB,GAAA;QACnB,MAAM,OAAO,GAAa,EAAE,CAAC;AAE7B,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;AAC9B,YAAA,OAAO,CAAC,IAAI,CACV,aAAa,CAAC;gBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAChC,aAAA,CAAC,CACH,CAAC;AACH,SAAA;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;AAC5B,YAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM;AACnB,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAC/B,gBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB;AAC5C,aAAA,CAAC,CACH,CAAC;AACH,SAAA;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;AACjC,YAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;gBACX,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,aAAA,CAAC,CACH,CAAC;AACH,SAAA;AAED,QAAA,OAAO,OAAO,CAAC;KAChB;AACF,CAAA;;ACvQM,MAAM,oBAAoB,GAAG,CAAC,OAAkC,KAAI;;;IAEzE,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAErD,IAAA,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;AACtE,IAAA,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AAEpE,IAAA,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC;AAC5B,IAAA,aAAa,CAAC,KAAK,GAAG,CAAA,CAAA,EAAA,GAAA,OAAO,CAAC,IAAI,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,KAAI,EAAE,CAAC;AACpD,IAAA,aAAa,CAAC,WAAW,GAAG,iBAAiB,CAAC;AAE9C,IAAA,SAAS,CAAC,IAAI,GAAG,MAAM,CAAC;IACxB,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AACpC,IAAA,SAAS,CAAC,WAAW,GAAG,YAAY,CAAC;AAErC,IAAA,WAAW,CAAC,IAAI,GAAG,QAAQ,CAAC;AAC5B,IAAA,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAChE,IAAA,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC;AAEhC,IAAA,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnC,IAAA,aAAa,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;;AAG/C,IAAA,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAE3C,IAAA,OAAO,CAAC,cAAc,CAAC,SAAS,GAAG,EAAE,CAAC;AACtC,IAAA,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAEzC,IAAA,SAAS,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAK;AACzC,QAAA,SAAS,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;AAC5C,KAAC,CAAC,CAAC;AAEH,IAAA,SAAS,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAK;AACzC,QAAA,aAAa,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;AAChD,KAAC,CAAC,CAAC;;IAGH,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAI;QACpC,CAAC,CAAC,cAAc,EAAE,CAAC;AAEnB,QAAA,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC;AACxC,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAEhC,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE;AAC5B,YAAA,IAAI,CAAC,OAAO;AAAE,gBAAA,SAAS,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;AACnD,YAAA,IAAI,CAAC,WAAW;AAAE,gBAAA,aAAa,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YAC3D,OAAO;AACR,SAAA;AAED,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;aAC9B,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AAC7B,aAAA,MAAM,CAAC,CAAC,IAAI,KAAI;YACf,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrC,aAAA;AACD,YAAA,OAAO,IAAI,CAAC;AACd,SAAC,CAAC;aACD,EAAE,CAAC,CAAC,CAAC,CAAC;QAET,IAAI,EAAC,WAAW,KAAX,IAAA,IAAA,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;AACtB,YAAA,SAAS,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YACrC,OAAO;AACR,SAAA;AAED,QAAA,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC;AACxE,YAAA,MAAM,EAAE,OAAO;AACf,YAAA,OAAO,EAAE,WAAW;AACrB,SAAA,CAAC,CAAC;AAEH,QAAA,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACvB,KAAC,CAAC,CAAC;;IAGH,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;AACxC,QAAA,KAAK,EAAE,UAAU;AAClB,KAAA,CAAC,CAAC;IAEH,UAAU,CAAC,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;AAC1C,CAAC;;AC7FD;AACO,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,GAAG,mBAAmB,EAAgB,GAAA,EAAE,KAAI;IAC9E,OAAO,CAAA;AACS,kBAAA,EAAA,IAAI,8BAA8B,IAAI,CAAA;;;KAGrD,CAAA;AACL,CAAC,CAAA;AAEM,MAAM,SAAS,GAAG,CAAC,EACxB,IAAI,GAAG,EAAE,EACT,IAAI,GAAG,mBAAmB,GACb,GAAA,EAAE,KAAI;IACnB,OAAO,CAAA;AACW,kBAAA,EAAA,IAAI,8BAA8B,IAAI,CAAA;;;KAGrD,CAAC;AACN,CAAC,CAAC;AAEK,MAAM,MAAM,GAAG,CAAC,EACrB,IAAI,GAAG,EAAE,EACT,IAAI,GAAG,mBAAmB,GACb,GAAA,EAAE,KAAI;IACnB,OAAO,CAAA;AACW,kBAAA,EAAA,IAAI,8BAA8B,IAAI,CAAA;;;KAGrD,CAAC;AACN,CAAC;;ACpBK,SAAU,qBAAqB,CAAC,OAAsC,EAAA;AAC1E,IAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IAE/B,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEpD,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAChD,IAAA,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAC9C,IAAA,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3C,IAAA,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC5C,IAAA,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACrC,IAAA,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;AAE3B,IAAA,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE5B,KAAK,CAAC,eAAe,EAAE;AACrB,QAAA,MAAM,EAAE,MAAM;AACd,QAAA,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;KACpC,CAAC;SACC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;AACnC,SAAA,IAAI,CAAC,CAAC,IAAI,KAAI;;AAEb,QAAA,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAErC,QAAA,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;AAC7D,QAAA,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;;AAGrC,QAAA,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE;YAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC1C,YAAA,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;AACtD,YAAA,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,iBAAiB,CAAC;AAC9D,YAAA,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AAC5B,SAAA;AACH,KAAC,CAAC;AACD,SAAA,KAAK,CAAC,CAAC,KAAK,KAAI;AACf,QAAA,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;AACnD,KAAC,CAAC,CAAC;AAEL,IAAA,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AAExD,IAAA,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACrE,IAAA,YAAY,CAAC,SAAS,GAAG,SAAS,EAAE,CAAC;AAErC,IAAA,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACjE,IAAA,UAAU,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC;AAEhC,IAAA,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACjE,IAAA,UAAU,CAAC,SAAS,GAAG,IAAI,EAAE,CAAC;AAE9B,IAAA,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAK;AAC1C,QAAA,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACrB,QAAA,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,CAAC;AAC/D,KAAC,CAAC,CAAC;AAEH,IAAA,UAAU,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,oBAAoB,CAAC,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAEjG,IAAA,UAAU,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAK;AACxC,QAAA,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACrB,QAAA,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACtC,KAAC,CAAC,CAAC;IAEH,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAEvE,IAAA,OAAO,cAAc,CAAC;AACxB;;ACvEA,IAAI,OAAO,GAAwB,SAAS,CAAC;AAEvC,SAAU,iBAAiB,CAAC,OAAkC,EAAA;;AAElE,IAAA,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;;IAGrD,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAEpC,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAEpD,IAAA,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAEpD,IAAA,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AACrE,IAAA,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;;IAGnE,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAEhD,IAAA,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,IAAA,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AACzD,IAAA,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACtC,IAAA,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC;AAE5B,IAAA,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,IAAA,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9B,IAAA,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAE3C,IAAA,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAA,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;AAC1B,IAAA,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAClC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QAClC,KAAK,EAAE,OAAO,CAAC,UAAU;AAC1B,KAAA,CAAC,CAAC;;IAGH,UAAU,CAAC,MAAK;QACd,KAAK,CAAC,KAAK,EAAE,CAAC;AACd,QAAA,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;KACvC,EAAE,GAAG,CAAC,CAAC;AAER,IAAA,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAK;AACrC,QAAA,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;AACxC,KAAC,CAAC,CAAC;;IAGH,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAI;QACxC,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC;QAExB,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YACjC,OAAO;AACR,SAAA;AAED,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AAC7B,aAAA,MAAM,CAAC,CAAC,IAAI,KAAI;YACf,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrC,aAAA;AACD,YAAA,OAAO,IAAI,CAAC;AACd,SAAC,CAAC;aACD,EAAE,CAAC,CAAC,CAAC,CAAC;QAET,IAAI,EAAC,WAAW,KAAX,IAAA,IAAA,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;AACtB,YAAA,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YACjC,OAAO;AACR,SAAA;AAED,QAAA,OAAO,aAAP,OAAO,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAP,OAAO,CAAE,IAAI,EAAE,CAAC;QAEhB,OAAO,OAAO,CAAC,MAAM;AAClB,aAAA,KAAK,EAAE;AACP,aAAA,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;AAC1D,aAAA,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC;AACrC,aAAA,GAAG,EAAE,CAAC;AACX,KAAC,CAAC,CAAC;AACL;;;;"}
1
+ {"version":3,"sources":["../src/hyperlink.ts","../src/helpers/editHyperlink.ts","../src/utils/normalizeHref.ts","../src/utils/validateURL.ts","../src/utils/specialUrls.ts","../src/helpers/floatingToolbar.ts","../src/plugins/autolink.ts","../src/plugins/clickHandler.ts","../src/plugins/pasteHandler.ts","../src/utils/copyToClipboard.ts","../src/utils/createHTMLElement.ts","../src/utils/icons.ts","../src/popovers/createHyperlinkPopover.ts","../src/popovers/editHyperlinkPopover.ts","../src/popovers/previewHyperlinkPopover.ts","../src/index.ts"],"sourcesContent":["import { Editor, InputRule, Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { EditorView } from '@tiptap/pm/view'\nimport { find, registerCustomProtocol } from 'linkifyjs'\n\nimport { editHyperlinkCommand } from './helpers/editHyperlink'\nimport { createFloatingToolbar } from './helpers/floatingToolbar'\nimport autolinkPlugin from './plugins/autolink'\nimport clickHandlerPlugin from './plugins/clickHandler'\nimport pasteHandlerPlugin from './plugins/pasteHandler'\nimport { type LinkifyMatchLike, normalizeHref, normalizeLinkifyHref } from './utils/normalizeHref'\nimport { DANGEROUS_SCHEME_RE } from './utils/validateURL'\n\nconst INPUT_FOCUS_DELAY_MS = 100\n\nexport interface LinkProtocolOptions {\n scheme: string\n optionalSlashes?: boolean\n}\n\nexport type HyperlinkAttributes = {\n href: string | null\n target: string | null\n rel: string | null\n class: string | null\n title: string | null\n image: string | null\n [key: string]: unknown\n}\n\nexport type PreviewHyperlinkOptions = {\n editor: Editor\n view: EditorView\n link: HTMLAnchorElement\n nodePos: number\n attrs: HyperlinkAttributes\n linkCoords: { x: number; y: number; width: number; height: number }\n validate?: (url: string) => boolean\n}\n\nexport type CreateHyperlinkOptions = {\n editor: Editor\n extensionName: string\n attributes: Partial<HyperlinkAttributes>\n validate?: (url: string) => boolean\n}\n\nexport interface HyperlinkOptions {\n autolink: boolean\n protocols: Array<LinkProtocolOptions | string>\n openOnClick: boolean\n linkOnPaste: boolean\n HTMLAttributes: Partial<HyperlinkAttributes>\n popovers: {\n previewHyperlink?: ((options: PreviewHyperlinkOptions) => HTMLElement | null) | null\n createHyperlink?: ((options: CreateHyperlinkOptions) => HTMLElement | null) | null\n }\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n hyperlink: {\n editHyperlinkText: (text: string) => ReturnType\n editHyperlinkHref: (href: string) => ReturnType\n editHyperlink: (attributes?: {\n newText?: string\n newURL?: string\n title?: string\n image?: string\n }) => ReturnType\n setHyperlink: (attributes?: { href: string; target?: string | null }) => ReturnType\n unsetHyperlink: () => ReturnType\n }\n }\n}\n\nexport const Hyperlink = Mark.create<HyperlinkOptions>({\n name: 'hyperlink',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach((protocol) => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n } else {\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n }\n })\n },\n\n // linkifyjs.reset() was removed intentionally — it clears the global\n // protocol registry and breaks other editors on the same page.\n // Registered protocols are additive and persist for the page lifetime.\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: null,\n rel: 'noopener noreferrer nofollow',\n class: null\n },\n popovers: {\n previewHyperlink: null,\n createHyperlink: null\n },\n validate: undefined\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null\n },\n target: {\n default: this.options.HTMLAttributes.target,\n rendered: false\n },\n rel: {\n default: this.options.HTMLAttributes.rel\n },\n class: {\n default: this.options.HTMLAttributes.class\n },\n title: {\n default: null\n },\n image: {\n default: null\n }\n }\n },\n\n parseHTML() {\n // Reject anchors whose href uses any dangerous scheme. Keeping the list\n // aligned with DANGEROUS_SCHEME_RE is the one XSS invariant this\n // extension enforces at every boundary (parseHTML, input rules, paste,\n // click, preview); update them together.\n return [\n {\n tag: 'a[href]',\n getAttrs: (node: HTMLElement | string) => {\n if (typeof node === 'string') return false\n const href = node.getAttribute('href') ?? ''\n return DANGEROUS_SCHEME_RE.test(href) ? false : null\n }\n }\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setHyperlink:\n (attributes) =>\n ({ editor, chain }) => {\n if (!this.options.popovers.createHyperlink) {\n // Normalize at the command boundary so programmatic callers\n // (no popover) get the same bare-domain → `https://` guarantee\n // the create popover applies. When a popover IS configured\n // the factory is responsible for normalizing its own input.\n const normalized = attributes?.href\n ? { ...attributes, href: normalizeHref(attributes.href) }\n : attributes\n return chain().setMark(this.name, normalized).setMeta('preventAutolink', true).run()\n }\n\n const content = this.options.popovers.createHyperlink({\n editor,\n validate: this.options.validate,\n extensionName: this.name,\n attributes: attributes || {}\n })\n\n if (!content) return true\n\n const { from, to } = editor.state.selection\n const start = editor.view.coordsAtPos(from)\n const end = editor.view.coordsAtPos(to)\n\n const toolbar = createFloatingToolbar({\n coordinates: {\n x: start.left,\n y: start.top,\n width: end.left - start.left,\n height: end.bottom - start.top,\n contextElement: editor.view.dom\n },\n content,\n placement: 'bottom',\n showArrow: true\n })\n\n toolbar.show()\n\n const input = content.querySelector('input')\n if (input) setTimeout(() => input.focus(), INPUT_FOCUS_DELAY_MS)\n\n return true\n },\n\n editHyperlink: (attributes) =>\n editHyperlinkCommand({\n ...attributes,\n validate: this.options.validate,\n markName: this.name\n })(),\n\n editHyperlinkText: (newText) =>\n editHyperlinkCommand({\n newText,\n validate: this.options.validate,\n markName: this.name\n })(),\n\n editHyperlinkHref: (newURL) =>\n editHyperlinkCommand({\n newURL,\n validate: this.options.validate,\n markName: this.name\n })(),\n\n unsetHyperlink:\n () =>\n ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n }\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-k': () => this.editor.commands.setHyperlink()\n }\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /(\\[([^\\]]+)\\]\\(([^)]+)\\))$/,\n handler: ({ state, range, match }) => {\n const [_fullMatch, , linkText, url] = match\n const { tr } = state\n const start = range.from\n const end = range.to\n\n const trimmed = url.trim()\n if (DANGEROUS_SCHEME_RE.test(trimmed)) return\n const normalizedUrl = normalizeHref(trimmed)\n\n // Replace the markdown text with just the link text\n tr.replaceWith(start, end, state.schema.text(linkText))\n\n // Apply the hyperlink mark to the replaced text\n tr.addMark(start, start + linkText.length, this.type.create({ href: normalizedUrl }))\n }\n })\n ]\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: (text) =>\n find(text)\n .filter((link) => {\n if (this.options.validate) {\n return this.options.validate(link.value)\n }\n\n return true\n })\n .filter((link) => link.isLink)\n .map((link) => ({\n text: link.value,\n index: link.start,\n data: link\n })),\n type: this.type,\n // `match.data` is set unconditionally in the `find` callback above,\n // so the cast is documentary — the branch itself is guaranteed live.\n getAttributes: (match) => ({\n href: normalizeLinkifyHref(match.data as LinkifyMatchLike)\n })\n })\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolinkPlugin({\n type: this.type,\n validate: this.options.validate\n })\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandlerPlugin({\n type: this.type,\n editor: this.editor,\n validate: this.options.validate,\n popover: this.options.popovers.previewHyperlink\n })\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandlerPlugin({\n editor: this.editor,\n type: this.type,\n validate: this.options.validate\n })\n )\n }\n\n return plugins\n }\n})\n","import { getMarkRange, type RawCommands } from '@tiptap/core'\n\nimport { normalizeHref } from '../utils/normalizeHref'\nimport { validateURL } from '../utils/validateURL'\n\ntype EditHyperlinkAttributes = {\n newURL?: string\n newText?: string\n title?: string\n image?: string\n markName?: string\n validate?: (url: string) => boolean\n}\n\n/**\n * Edit the hyperlink at the current selection.\n *\n * Returns a composable Tiptap command so the caller's `editor.chain()` stays\n * a single dispatch — a previous footgun dispatched a nested chain inside\n * here and produced \"Applying a mismatched transaction\" when composed with\n * commands like `extendMarkRange`.\n *\n * All position + mark lookups happen against `tr.doc` inside the command,\n * never a state snapshot captured before the chain started.\n *\n * `newURL` is run through `normalizeHref` before writing, so bare domains\n * (`google.com`) become `https://google.com` — matching every other\n * write-boundary (create popover, `setHyperlink`, autolink, paste).\n */\nexport const editHyperlinkCommand =\n (attributes: EditHyperlinkAttributes = {}): RawCommands['editHyperlink'] =>\n () =>\n ({ tr, dispatch }) => {\n const { newURL, newText, title, image, validate, markName = 'hyperlink' } = attributes\n\n if (newURL && !validateURL(newURL, { customValidator: validate })) {\n return false\n }\n\n const markType = tr.doc.type.schema.marks[markName]\n if (!markType) return false\n\n const { from } = tr.selection\n const $pos = tr.doc.resolve(from)\n const range = getMarkRange($pos, markType)\n if (!range) return false\n\n let currentMark\n try {\n currentMark = tr.doc.nodeAt(range.from)?.marks.find((m) => m.type === markType)\n } catch (error) {\n console.warn('[hyperlink] editHyperlink: failed to read mark at position', error)\n return false\n }\n if (!currentMark) return false\n\n if (!dispatch) return true\n\n const text = newText || tr.doc.textBetween(range.from, range.to)\n const href = newURL ? normalizeHref(newURL) : currentMark.attrs.href\n\n const newMark = markType.create({\n ...currentMark.attrs,\n href,\n ...(title !== undefined && { title }),\n ...(image !== undefined && { image })\n })\n tr.replaceWith(range.from, range.to, tr.doc.type.schema.text(text, [newMark]))\n return true\n }\n","/**\n * Canonicalize a user-supplied href so it points somewhere absolute.\n *\n * `<a href=\"google.com\">` is legal HTML but the browser treats it as a\n * relative URL — `anchor.href` (the click target) resolves to\n * `http://<current-origin>/google.com`. Running every user-typed href\n * through this helper at the write boundary keeps the stored mark\n * pointing where the user intended, regardless of the host page.\n *\n * Rules:\n * 1. Trim whitespace; empty → `''` (callers validate non-emptiness).\n * 2. If the value already has a scheme or is protocol-relative (`//x`),\n * leave it alone.\n * 3. Otherwise, prepend `https://`.\n *\n * The scheme detector matches RFC 3986 §3.1 — permissive on purpose so\n * custom schemes (registered via `registerCustomProtocol(...)`) pass\n * through unmodified.\n */\nconst SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i\n\nexport const normalizeHref = (raw: string): string => {\n const trimmed = raw.trim()\n if (!trimmed) return ''\n if (SCHEME_RE.test(trimmed) || trimmed.startsWith('//')) return trimmed\n return `https://${trimmed}`\n}\n\n/**\n * Shape we depend on from a linkifyjs match (plus autolink's\n * manually-constructed special-scheme entries, which also set `type`).\n * Loosened to avoid importing linkifyjs types across the public boundary.\n */\nexport type LinkifyMatchLike = {\n type: string\n value: string\n href: string\n}\n\n/**\n * Canonicalize a linkifyjs match for storage.\n *\n * linkifyjs defaults URL matches to `http://…`; we prefer `https://` to\n * stay consistent with the create popover and markdown input rule, so\n * URL matches run through `normalizeHref(value)`. Non-URL matches\n * (emails → `mailto:`, etc.) already carry a meaningful scheme in `href`\n * and are returned unchanged.\n */\nexport const normalizeLinkifyHref = (link: LinkifyMatchLike): string => {\n return link.type === 'url' ? normalizeHref(link.value) : link.href\n}\n","import { find } from 'linkifyjs'\n\nimport { getSpecialUrlInfo } from './specialUrls'\n\n/** Schemes that must never be used as link hrefs (XSS vectors). */\nexport const DANGEROUS_SCHEME_RE = /^\\s*(javascript|data|vbscript):/i\n\n/** Web schemes whose host must look like a real domain (TLD / localhost / IP). */\nconst STANDARD_WEB_SCHEMES = new Set(['http', 'https', 'ftp', 'ftps'])\n\n/** IPv4 dotted quad. Deliberately loose on octet range — we only need a shape check. */\nconst IPV4_RE = /^\\d{1,3}(\\.\\d{1,3}){3}$/\n\ntype ValidateURLOptions = {\n customValidator?: (url: string) => boolean\n}\n\n/**\n * Check if a URL uses a valid special scheme or domain\n * @param url - The URL to check\n * @returns true if the URL uses a recognized special scheme or domain\n */\nconst isValidSpecialScheme = (url: string): boolean => {\n return getSpecialUrlInfo(url) !== null\n}\n\n/**\n * Is the host of this URL plausible enough to store as a hyperlink?\n *\n * linkifyjs accepts any `scheme://host` string, so typos like\n * `https://googlecom` or `https://asdf` pass its own validation. For\n * http(s)/ftp we additionally require that the host has either:\n * - a dot (any TLD — works for IDN and punycode), or\n * - equals `localhost` (legitimate dev host), or\n * - looks like an IPv4 or IPv6 literal.\n *\n * Non-standard schemes (mailto, tel, whatsapp, …) don't go through this\n * gate — they're handled by `isValidSpecialScheme`.\n */\nconst hasPlausibleHost = (url: string): boolean => {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n return false\n }\n const host = parsed.hostname\n if (!host) return false\n if (host === 'localhost') return true\n if (IPV4_RE.test(host)) return true\n // `new URL()` strips IPv6 brackets on most engines and leaves the raw\n // `::1`-style string, which contains a colon that can't appear in any\n // real hostname. Cheap and robust enough.\n if (host.includes(':')) return true\n return host.includes('.')\n}\n\n/**\n * Validates URLs including both standard web URLs and special app/protocol schemes\n *\n * Supports:\n * - Standard web URLs (http, https, ftp)\n * - Email addresses (mailto:)\n * - Phone numbers (tel:, sms:)\n * - App deep links (whatsapp:, discord:, etc.)\n * - Apple app schemes (maps:, music:, etc.)\n * - Development tools (github:, vscode:, etc.)\n * - Domain-based detection (wa.me, t.me, etc.)\n *\n * For http(s)/ftp(s) URLs, the host must also look real — a TLD dot,\n * `localhost`, or an IP literal. This rejects scheme-prefixed typos like\n * `https://googlecom` that linkifyjs alone would accept.\n *\n * @param url - The URL string to validate\n * @param options - Optional configuration\n * @param options.customValidator - Custom validation function to apply additional checks\n * @returns true if the URL is valid, false otherwise\n *\n * @example\n * ```typescript\n * validateURL('https://example.com') // true\n * validateURL('mailto:user@example.com') // true\n * validateURL('tel:+1234567890') // true\n * validateURL('whatsapp://send?text=hello') // true\n * validateURL('wa.me/1234567890') // true\n * validateURL('https://googlecom') // false (no TLD, no localhost, no IP)\n * validateURL('invalid-url') // false\n * ```\n */\nexport const validateURL = (url: string, options?: ValidateURLOptions): boolean => {\n if (!url.trim()) return false\n\n try {\n // First check if it's a special scheme URL or recognized domain\n if (isValidSpecialScheme(url)) {\n // Apply custom validator if provided\n if (options?.customValidator) {\n return options.customValidator(url)\n }\n return true\n }\n\n // For standard URLs, use linkifyjs to validate\n const validURL = find(url).find(\n (link) =>\n link.isLink && (options?.customValidator ? options.customValidator(link.value) : true)\n )\n\n if (!validURL?.href) return false\n\n // linkifyjs waves through anything scheme-shaped — require a plausible\n // host for web schemes so typos like `https://googlecom` are rejected.\n const scheme = getUrlScheme(validURL.href)\n if (scheme && STANDARD_WEB_SCHEMES.has(scheme)) {\n return hasPlausibleHost(validURL.href)\n }\n return true\n } catch (error) {\n console.error('URL validation error:', error)\n return false\n }\n}\n\n/**\n * Get the scheme/protocol from a URL\n * @param url - The URL to extract scheme from\n * @returns The scheme (e.g., 'https', 'mailto', 'tel') or null if invalid\n *\n * @example\n * ```typescript\n * getUrlScheme('https://example.com') // 'https'\n * getUrlScheme('mailto:user@example.com') // 'mailto'\n * getUrlScheme('invalid') // null\n * ```\n */\nexport const getUrlScheme = (url: string): string | null => {\n if (!url.trim()) return null\n\n const colonIndex = url.indexOf(':')\n if (colonIndex === -1) return null\n\n return url.substring(0, colonIndex).toLowerCase()\n}\n\n/**\n * Check if a URL is a special app/protocol scheme (not http/https)\n * @param url - The URL to check\n * @returns true if it's a special scheme, false for standard web URLs\n *\n * @example\n * ```typescript\n * isSpecialSchemeUrl('mailto:user@example.com') // true\n * isSpecialSchemeUrl('https://example.com') // false\n * ```\n */\nexport const isSpecialSchemeUrl = (url: string): boolean => {\n const scheme = getUrlScheme(url)\n return scheme !== null && !['http', 'https', 'ftp', 'ftps'].includes(scheme)\n}\n","/**\n * Special URL schemes and their corresponding SVG icons\n * Based on: https://github.com/bhagyas/app-urls\n */\n\nexport type SpecialUrlInfo = {\n type: string\n title: string\n /**\n * Icon identifier hint for consumers (e.g. `'HiMail'`, `'FaWhatsapp'`).\n * Not rendered by the extension — consumers map this to their own icon\n * components (React icons, SVG sprites, etc.).\n */\n icon: string\n category:\n | 'communication'\n | 'social'\n | 'productivity'\n | 'entertainment'\n | 'shopping'\n | 'development'\n | 'apple'\n | 'other'\n}\n\n// Communication & Phone\nconst COMMUNICATION_URLS: Record<string, SpecialUrlInfo> = {\n 'mailto:': { type: 'email', title: 'Email', icon: 'HiMail', category: 'communication' },\n 'tel:': { type: 'phone', title: 'Phone', icon: 'HiPhone', category: 'communication' },\n 'telprompt:': { type: 'phone', title: 'Phone', icon: 'HiPhone', category: 'communication' },\n 'sms:': { type: 'sms', title: 'SMS', icon: 'HiChatBubbleLeftRight', category: 'communication' },\n 'facetime:': {\n type: 'facetime',\n title: 'FaceTime',\n icon: 'HiVideoCamera',\n category: 'communication'\n },\n 'facetime-audio:': {\n type: 'facetime-audio',\n title: 'FaceTime Audio',\n icon: 'HiPhone',\n category: 'communication'\n }\n}\n\n// Social Media & Messaging\nconst SOCIAL_URLS: Record<string, SpecialUrlInfo> = {\n 'whatsapp:': { type: 'whatsapp', title: 'WhatsApp', icon: 'FaWhatsapp', category: 'social' },\n 'tg:': { type: 'telegram', title: 'Telegram', icon: 'FaTelegram', category: 'social' },\n 'discord:': { type: 'discord', title: 'Discord', icon: 'FaDiscord', category: 'social' },\n 'skype:': { type: 'skype', title: 'Skype', icon: 'FaSkype', category: 'social' },\n 'slack:': { type: 'slack', title: 'Slack', icon: 'FaSlack', category: 'social' },\n 'twitter:': { type: 'twitter', title: 'Twitter', icon: 'FaTwitter', category: 'social' },\n 'fb:': { type: 'facebook', title: 'Facebook', icon: 'FaFacebook', category: 'social' },\n 'instagram:': { type: 'instagram', title: 'Instagram', icon: 'FaInstagram', category: 'social' },\n 'linkedin:': { type: 'linkedin', title: 'LinkedIn', icon: 'FaLinkedin', category: 'social' },\n 'snapchat:': { type: 'snapchat', title: 'Snapchat', icon: 'FaSnapchat', category: 'social' },\n 'reddit:': { type: 'reddit', title: 'Reddit', icon: 'FaReddit', category: 'social' },\n 'tiktok:': { type: 'tiktok', title: 'TikTok', icon: 'SiTiktok', category: 'social' }\n}\n\n// Video Conferencing & Meeting\nconst MEETING_URLS: Record<string, SpecialUrlInfo> = {\n 'zoommtg:': { type: 'zoom', title: 'Zoom Meeting', icon: 'SiZoom', category: 'communication' },\n 'zoomus:': { type: 'zoom', title: 'Zoom', icon: 'SiZoom', category: 'communication' },\n 'msteams:': {\n type: 'teams',\n title: 'Microsoft Teams',\n icon: 'SiMicrosoftteams',\n category: 'communication'\n },\n 'webex:': { type: 'webex', title: 'Cisco Webex', icon: 'SiCisco', category: 'communication' }\n}\n\n// Apple Apps\nconst APPLE_URLS: Record<string, SpecialUrlInfo> = {\n 'calshow:': { type: 'calendar', title: 'Calendar', icon: 'HiCalendar', category: 'apple' },\n 'x-apple-calevent:': {\n type: 'calendar',\n title: 'Calendar Event',\n icon: 'HiCalendar',\n category: 'apple'\n },\n 'contacts:': { type: 'contacts', title: 'Contacts', icon: 'HiUsers', category: 'apple' },\n 'maps:': { type: 'maps', title: 'Maps', icon: 'HiMapPin', category: 'apple' },\n 'map:': { type: 'maps', title: 'Maps', icon: 'HiMapPin', category: 'apple' },\n 'music:': { type: 'music', title: 'Apple Music', icon: 'HiMusicalNote', category: 'apple' },\n 'videos:': { type: 'tv', title: 'Apple TV', icon: 'HiTv', category: 'apple' },\n 'mobilenotes:': { type: 'notes', title: 'Notes', icon: 'HiDocumentText', category: 'apple' },\n 'x-apple-reminder:': {\n type: 'reminders',\n title: 'Reminders',\n icon: 'HiCheckCircle',\n category: 'apple'\n },\n 'photos-redirect:': { type: 'photos', title: 'Photos', icon: 'HiPhoto', category: 'apple' },\n 'shortcuts:': {\n type: 'shortcuts',\n title: 'Shortcuts',\n icon: 'HiLightningBolt',\n category: 'apple'\n },\n 'itms-apps:': { type: 'appstore', title: 'App Store', icon: 'SiAppstore', category: 'apple' }\n}\n\n// Development & Productivity\nconst PRODUCTIVITY_URLS: Record<string, SpecialUrlInfo> = {\n 'github:': { type: 'github', title: 'GitHub', icon: 'FaGithub', category: 'development' },\n 'gitlab:': { type: 'gitlab', title: 'GitLab', icon: 'FaGitlab', category: 'development' },\n 'vscode:': {\n type: 'vscode',\n title: 'VS Code',\n icon: 'SiVisualstudiocode',\n category: 'development'\n },\n 'notion:': { type: 'notion', title: 'Notion', icon: 'SiNotion', category: 'productivity' },\n 'obsidian:': {\n type: 'obsidian',\n title: 'Obsidian',\n icon: 'SiObsidian',\n category: 'productivity'\n },\n 'figma:': { type: 'figma', title: 'Figma', icon: 'FaFigma', category: 'development' }\n}\n\n// Entertainment & Media\nconst ENTERTAINMENT_URLS: Record<string, SpecialUrlInfo> = {\n 'youtube:': { type: 'youtube', title: 'YouTube', icon: 'FaYoutube', category: 'entertainment' },\n 'spotify:': { type: 'spotify', title: 'Spotify', icon: 'FaSpotify', category: 'entertainment' },\n 'netflix:': { type: 'netflix', title: 'Netflix', icon: 'SiNetflix', category: 'entertainment' },\n 'twitch:': { type: 'twitch', title: 'Twitch', icon: 'FaTwitch', category: 'entertainment' }\n}\n\n// Shopping & Commerce\nconst SHOPPING_URLS: Record<string, SpecialUrlInfo> = {\n 'amazon:': { type: 'amazon', title: 'Amazon', icon: 'FaAmazon', category: 'shopping' },\n 'uber:': { type: 'uber', title: 'Uber', icon: 'SiUber', category: 'other' },\n 'lyft:': { type: 'lyft', title: 'Lyft', icon: 'SiLyft', category: 'other' }\n}\n\n// Combine all URL mappings\nconst ALL_SPECIAL_URLS = {\n ...COMMUNICATION_URLS,\n ...SOCIAL_URLS,\n ...MEETING_URLS,\n ...APPLE_URLS,\n ...PRODUCTIVITY_URLS,\n ...ENTERTAINMENT_URLS,\n ...SHOPPING_URLS\n}\n\n// Domain-based detection for web URLs\nconst DOMAIN_MAPPINGS: Record<string, SpecialUrlInfo> = {\n 'wa.me': { type: 'whatsapp', title: 'WhatsApp', icon: 'FaWhatsapp', category: 'social' },\n 't.me': { type: 'telegram', title: 'Telegram', icon: 'FaTelegram', category: 'social' },\n 'discord.gg': { type: 'discord', title: 'Discord Invite', icon: 'FaDiscord', category: 'social' },\n 'zoom.us': { type: 'zoom', title: 'Zoom Meeting', icon: 'SiZoom', category: 'communication' },\n 'meet.google.com': {\n type: 'meet',\n title: 'Google Meet',\n icon: 'SiGooglemeet',\n category: 'communication'\n },\n 'teams.microsoft.com': {\n type: 'teams',\n title: 'Microsoft Teams',\n icon: 'SiMicrosoftteams',\n category: 'communication'\n },\n 'github.com': { type: 'github', title: 'GitHub', icon: 'FaGithub', category: 'development' },\n 'gitlab.com': { type: 'gitlab', title: 'GitLab', icon: 'FaGitlab', category: 'development' },\n 'figma.com': { type: 'figma', title: 'Figma', icon: 'FaFigma', category: 'development' },\n 'notion.so': { type: 'notion', title: 'Notion', icon: 'SiNotion', category: 'productivity' },\n 'twitter.com': { type: 'twitter', title: 'Twitter', icon: 'FaTwitter', category: 'social' },\n 'x.com': { type: 'twitter', title: 'X (Twitter)', icon: 'FaTwitter', category: 'social' },\n 'instagram.com': {\n type: 'instagram',\n title: 'Instagram',\n icon: 'FaInstagram',\n category: 'social'\n },\n 'linkedin.com': { type: 'linkedin', title: 'LinkedIn', icon: 'FaLinkedin', category: 'social' },\n 'youtube.com': {\n type: 'youtube',\n title: 'YouTube',\n icon: 'FaYoutube',\n category: 'entertainment'\n },\n 'spotify.com': { type: 'spotify', title: 'Spotify', icon: 'FaSpotify', category: 'entertainment' }\n}\n\n/**\n * Detect special URL and return corresponding info\n */\nexport const getSpecialUrlInfo = (url: string): SpecialUrlInfo | null => {\n const lowerUrl = url.toLowerCase()\n\n // Check URL schemes first (protocol-based)\n for (const [scheme, info] of Object.entries(ALL_SPECIAL_URLS)) {\n if (lowerUrl.startsWith(scheme)) {\n return info\n }\n }\n\n // Check domain-based mappings for web URLs\n try {\n const urlObj = new URL(url)\n const hostname = urlObj.hostname.toLowerCase()\n\n // Remove www. prefix\n const cleanHostname = hostname.startsWith('www.') ? hostname.slice(4) : hostname\n\n // Direct domain match\n if (DOMAIN_MAPPINGS[cleanHostname]) {\n return DOMAIN_MAPPINGS[cleanHostname]\n }\n\n // Check for subdomain matches (e.g., api.github.com matches github.com)\n for (const [domain, info] of Object.entries(DOMAIN_MAPPINGS)) {\n if (cleanHostname.endsWith(`.${domain}`) || cleanHostname === domain) {\n return info\n }\n }\n } catch {\n // Not a valid URL, continue with scheme checking\n }\n\n return null\n}\n\n/**\n * Get all available categories\n */\nexport const getCategories = (): string[] => {\n const categories = new Set<string>()\n Object.values(ALL_SPECIAL_URLS).forEach((info) => categories.add(info.category))\n Object.values(DOMAIN_MAPPINGS).forEach((info) => categories.add(info.category))\n return Array.from(categories).sort()\n}\n\n/**\n * Get URLs by category\n */\nexport const getUrlsByCategory = (category: string): Record<string, SpecialUrlInfo> => {\n const result: Record<string, SpecialUrlInfo> = {}\n\n // Add scheme-based URLs\n Object.entries(ALL_SPECIAL_URLS).forEach(([scheme, info]) => {\n if (info.category === category) {\n result[scheme] = info\n }\n })\n\n // Add domain-based URLs\n Object.entries(DOMAIN_MAPPINGS).forEach(([domain, info]) => {\n if (info.category === category) {\n result[domain] = info\n }\n })\n\n return result\n}\n","import {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n hide as hideMiddleware,\n offset,\n type Placement,\n type ReferenceElement,\n shift,\n type VirtualElement\n} from '@floating-ui/dom'\n\nexport interface FloatingToolbarOptions {\n referenceElement?: HTMLElement\n coordinates?: {\n x: number\n y: number\n width?: number\n height?: number\n contextElement?: HTMLElement\n }\n content: HTMLElement\n placement?: Placement\n offset?: number\n showArrow?: boolean\n className?: string\n zIndex?: number\n onShow?: () => void\n onHide?: () => void\n}\n\nexport interface FloatingToolbarInstance {\n element: HTMLElement\n show: () => void\n hide: () => void\n destroy: () => void\n isVisible: () => boolean\n setContent: (content: HTMLElement) => void\n updateReference: (\n referenceElement?: HTMLElement,\n coordinates?: FloatingToolbarOptions['coordinates']\n ) => void\n}\n\nexport const DEFAULT_OFFSET = 8\nconst DEFAULT_Z_INDEX = 9999\nconst SHIFT_PADDING = 8\nconst ARROW_STATIC_OFFSET = '-5px'\nconst OUTSIDE_CLICK_DEFER_MS = 50\n\nlet currentToolbar: FloatingToolbarInstance | null = null\n\nfunction createVirtualReference(\n coords: NonNullable<FloatingToolbarOptions['coordinates']>\n): VirtualElement {\n const { x, y, width = 0, height = 0 } = coords\n return {\n getBoundingClientRect: () => ({\n width,\n height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x,\n y\n }),\n contextElement: coords.contextElement || document.body\n }\n}\n\nfunction setupKeyboardNav(container: HTMLElement): void {\n const focusable = container.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n )\n if (!focusable.length) return\n\n focusable.forEach((el, i) => {\n el.addEventListener('keydown', (e) => {\n if (e.key !== 'Tab') return\n e.preventDefault()\n const next = e.shiftKey\n ? (i - 1 + focusable.length) % focusable.length\n : (i + 1) % focusable.length\n focusable[next].focus()\n })\n })\n}\n\nexport function createFloatingToolbar(options: FloatingToolbarOptions): FloatingToolbarInstance {\n currentToolbar?.destroy()\n\n const {\n referenceElement,\n coordinates,\n content,\n placement = 'bottom-start',\n offset: offsetVal = DEFAULT_OFFSET,\n showArrow = false,\n className = '',\n zIndex = DEFAULT_Z_INDEX,\n onShow,\n onHide\n } = options\n\n if (!referenceElement && !coordinates) {\n throw new Error('Either referenceElement or coordinates must be provided')\n }\n\n let reference: ReferenceElement = referenceElement || createVirtualReference(coordinates!)\n const cleanups: (() => void)[] = []\n let visible = false\n let autoUpdateCleanup: (() => void) | null = null\n\n const toolbar = document.createElement('div')\n toolbar.className = `floating-toolbar ${className}`.trim()\n toolbar.setAttribute('role', 'toolbar')\n toolbar.setAttribute('tabindex', '-1')\n toolbar.style.zIndex = String(zIndex)\n toolbar.style.position = 'fixed'\n\n let arrowEl: HTMLElement | null = null\n if (showArrow) {\n arrowEl = document.createElement('div')\n arrowEl.className = 'floating-toolbar-arrow'\n toolbar.appendChild(arrowEl)\n }\n\n const contentContainer = document.createElement('div')\n contentContainer.className = 'floating-toolbar-content'\n toolbar.appendChild(contentContainer)\n\n const setContent = (el: HTMLElement): void => {\n contentContainer.innerHTML = ''\n contentContainer.appendChild(el)\n setupKeyboardNav(toolbar)\n }\n\n setContent(content)\n\n const updatePosition = async (): Promise<void> => {\n if (!visible) return\n\n const middleware = [offset(offsetVal), flip(), shift({ padding: SHIFT_PADDING })]\n if (arrowEl) middleware.push(arrow({ element: arrowEl }))\n middleware.push(hideMiddleware({ strategy: 'referenceHidden' }))\n\n const {\n x,\n y,\n placement: actual,\n middlewareData\n } = await computePosition(reference, toolbar, {\n placement,\n strategy: 'fixed',\n middleware\n })\n\n if (!visible) return\n\n Object.assign(toolbar.style, { left: `${x}px`, top: `${y}px` })\n\n // Hide when reference scrolls out of view\n toolbar.style.visibility = middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'\n\n if (arrowEl && middlewareData.arrow) {\n const { x: ax, y: ay } = middlewareData.arrow\n const side = actual.split('-')[0]\n const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[side]!\n\n arrowEl.className = `floating-toolbar-arrow floating-toolbar-arrow-${side}`\n Object.assign(arrowEl.style, {\n left: ax != null ? `${ax}px` : '',\n top: ay != null ? `${ay}px` : '',\n right: '',\n bottom: '',\n [staticSide]: ARROW_STATIC_OFFSET\n })\n }\n }\n\n const hide = (): void => {\n if (!visible) return\n visible = false\n\n autoUpdateCleanup?.()\n autoUpdateCleanup = null\n\n toolbar.classList.remove('visible')\n toolbar.remove()\n\n cleanups.forEach((fn) => fn())\n cleanups.length = 0\n\n onHide?.()\n }\n\n const show = (): void => {\n if (visible) return\n\n document.body.appendChild(toolbar)\n visible = true\n\n autoUpdateCleanup = autoUpdate(reference, toolbar, updatePosition)\n\n requestAnimationFrame(() => toolbar.classList.add('visible'))\n\n // Defer outside-click listener so the triggering event doesn't immediately close\n setTimeout(() => {\n if (!visible) return\n\n const onMouseDown = (e: MouseEvent) => {\n if (!toolbar.contains(e.target as Node)) hide()\n }\n const onTouchStart = (e: TouchEvent) => {\n if (!e.touches.length) return\n const target = document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY)\n if (!toolbar.contains(target)) hide()\n }\n\n document.addEventListener('mousedown', onMouseDown, { passive: true })\n document.addEventListener('touchstart', onTouchStart, { passive: true })\n cleanups.push(\n () => document.removeEventListener('mousedown', onMouseDown),\n () => document.removeEventListener('touchstart', onTouchStart)\n )\n }, OUTSIDE_CLICK_DEFER_MS)\n\n // Escape key\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault()\n hide()\n }\n }\n toolbar.addEventListener('keydown', onKeyDown)\n cleanups.push(() => toolbar.removeEventListener('keydown', onKeyDown))\n\n onShow?.()\n }\n\n const destroy = (): void => {\n hide()\n if (currentToolbar === instance) currentToolbar = null\n }\n\n const instance: FloatingToolbarInstance = {\n element: toolbar,\n show,\n hide,\n destroy,\n isVisible: () => visible,\n setContent,\n updateReference: (ref?: HTMLElement, coords?: FloatingToolbarOptions['coordinates']) => {\n if (ref) reference = ref\n else if (coords) reference = createVirtualReference(coords)\n updatePosition()\n }\n }\n\n currentToolbar = instance\n return instance\n}\n\nexport const getCurrentToolbar = (): FloatingToolbarInstance | null => currentToolbar\n\nexport const isToolbarVisible = (): boolean => currentToolbar?.isVisible() ?? false\n\nexport const hideCurrentToolbar = (): void => {\n currentToolbar?.hide()\n}\n\nexport const destroyCurrentToolbar = (): void => {\n currentToolbar?.destroy()\n}\n\nexport const updateCurrentToolbarPosition = (\n referenceElement?: HTMLElement,\n coordinates?: FloatingToolbarOptions['coordinates']\n): void => {\n currentToolbar?.updateReference(referenceElement, coordinates)\n}\n","import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find, test } from 'linkifyjs'\n\nimport { normalizeLinkifyHref } from '../utils/normalizeHref'\nimport { validateURL } from '../utils/validateURL'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nconst SPECIAL_SCHEME_REGEX_GLOBAL = /\\b[a-zA-Z][a-zA-Z0-9+.-]*:[^\\s]+/g\nconst SPECIAL_SCHEME_REGEX = /\\b[a-zA-Z][a-zA-Z0-9+.-]*:[^\\s]+/\nconst IMAGE_MARKDOWN_CONTEXT_CHARS = 15\n\nconst TRAILING_PUNCT_RE = /[.,;:!?)\\]}]+$/\n\n/**\n * Trim trailing punctuation from the match range so \"Visit google.com.\"\n * autolinks `google.com`, not `google.com.`. `href` and `value` only\n * diverge for linkifyjs email / custom-scheme matches (`mailto:…` vs raw\n * email text) — there the scheme prefix means `href` won't share the\n * trailing punctuation, so we leave it alone.\n */\nconst stripTrailingPunct = <T extends { value: string; href: string; end: number }>(link: T): T => {\n const tail = link.value.match(TRAILING_PUNCT_RE)\n if (!tail) return link\n const len = tail[0].length\n return {\n ...link,\n value: link.value.slice(0, -len),\n href: link.href.endsWith(tail[0]) ? link.href.slice(0, -len) : link.href,\n end: link.end - len\n }\n}\n\nconst findLinks = (text: string) => {\n const links = []\n\n const standardLinks = find(text).filter((link) => link.isLink)\n links.push(...standardLinks)\n\n // Custom special-scheme entries (e.g. `whatsapp://send`) that linkifyjs\n // doesn't recognize. Tagged `type: 'url'` so `normalizeLinkifyHref`\n // routes them through the same code path as real URL matches (which is\n // a no-op when a scheme is already present).\n for (const match of text.matchAll(SPECIAL_SCHEME_REGEX_GLOBAL)) {\n const url = match[0]\n const start = match.index!\n const end = start + url.length\n const alreadyCovered = standardLinks.some((link) => start >= link.start && end <= link.end)\n if (!alreadyCovered && validateURL(url)) {\n links.push({ type: 'url', href: url, value: url, start, end, isLink: true })\n }\n }\n\n return links.map(stripTrailingPunct)\n}\n\nconst testUrl = (text: string): boolean => {\n if (test(text)) return true\n return SPECIAL_SCHEME_REGEX.test(text) && validateURL(text)\n}\n\nexport default function autolinkPlugin(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('hyperlinkAutolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges =\n transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some((transaction) =>\n transaction.getMeta('preventAutolink')\n )\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const { mapping } = transform\n const changes = getChangedRanges(transform)\n\n for (const { oldRange, newRange } of changes) {\n // Check if we need to remove links\n for (const oldMark of getMarksBetween(oldRange.from, oldRange.to, oldState.doc).filter(\n (item) => item.mark.type === options.type\n )) {\n const newFrom = mapping.map(oldMark.from)\n const newTo = mapping.map(oldMark.to)\n const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(\n (item) => item.mark.type === options.type\n )\n\n if (!newMarks.length) continue\n\n const newMark = newMarks[0]\n const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ')\n const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ')\n const wasLink = testUrl(oldLinkText)\n const isLink = testUrl(newLinkText)\n\n if (wasLink && !isLink) {\n tr.removeMark(newMark.from, newMark.to, options.type)\n }\n }\n\n // Add new links\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n (node) => node.isTextblock\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' '\n )\n } else if (\n nodesInChangedRanges.length &&\n newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' '\n )\n }\n\n if (!textBlock || !textBeforeWhitespace) continue\n\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter((s) => s !== '')\n if (wordsBeforeWhitespace.length <= 0) continue\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n if (!lastWordBeforeSpace) continue\n\n const lastWordAndBlockOffset =\n textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n findLinks(lastWordBeforeSpace)\n .filter((link) => link.isLink)\n .filter((link) => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n .map((link) => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1\n }))\n .filter((link) => {\n const contextStart = Math.max(0, link.from - IMAGE_MARKDOWN_CONTEXT_CHARS)\n const beforeLink = newState.doc.textBetween(contextStart, link.from, ' ', ' ')\n const isInsideImageMarkdown = beforeLink.includes('![') && beforeLink.endsWith('](')\n return !isInsideImageMarkdown\n })\n .forEach((link) => {\n tr.addMark(\n link.from,\n link.to,\n options.type.create({ href: normalizeLinkifyHref(link) })\n )\n })\n }\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n }\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { EditorView } from '@tiptap/pm/view'\n\nimport {\n createFloatingToolbar,\n DEFAULT_OFFSET,\n hideCurrentToolbar\n} from '../helpers/floatingToolbar'\nimport type { HyperlinkAttributes, PreviewHyperlinkOptions } from '../hyperlink'\nimport { DANGEROUS_SCHEME_RE } from '../utils/validateURL'\n\ntype ClickHandlerOptions = {\n type: MarkType\n editor: Editor\n validate?: (url: string) => boolean\n popover?: ((options: PreviewHyperlinkOptions) => HTMLElement | null) | null\n}\n\nconst getLinkCoordinates = (el: HTMLElement) => {\n const rect = el.getBoundingClientRect()\n return { x: rect.left, y: rect.top, width: rect.width, height: rect.height }\n}\n\nfunction findLinkFromEvent(\n event: MouseEvent | TouchEvent,\n root: HTMLElement\n): HTMLAnchorElement | null {\n const target = event.target as HTMLElement | null\n if (!target) return null\n\n const link = target.closest<HTMLAnchorElement>('a')\n if (!link || !root.contains(link)) return null\n\n return link\n}\n\nfunction getMarkAttrsAtPos(view: EditorView, pos: number, type: MarkType): HyperlinkAttributes {\n const node = view.state.doc.nodeAt(pos)\n const mark = node?.marks.find((m) => m.type === type)\n return (mark?.attrs ?? {\n href: null,\n target: null,\n rel: null,\n class: null,\n title: null,\n image: null\n }) as HyperlinkAttributes\n}\n\nfunction showPopover(\n view: EditorView,\n link: HTMLAnchorElement,\n options: ClickHandlerOptions,\n clickPos: number | undefined\n): boolean {\n const nodePos = view.posAtDOM(link, 0)\n const attrs = getMarkAttrsAtPos(view, nodePos, options.type)\n // Prefer the stored mark attr — `link.href` resolves relative URLs\n // against `document.baseURI` and would leak the host page's origin\n // into window.open for bare-domain hrefs.\n const href = attrs.href ?? link.getAttribute('href')\n const targetAttr = link.target || attrs.target\n\n if (!options.popover) {\n if (href && !view.editable && !DANGEROUS_SCHEME_RE.test(href)) {\n window.open(href, targetAttr ?? undefined)\n }\n return !view.editable\n }\n\n if (!href) {\n hideCurrentToolbar()\n return true\n }\n\n const linkCoords = getLinkCoordinates(link)\n\n // Invoke the popover handler FIRST. A `null` return is the contract\n // by which a host can opt out of the floating-toolbar UI (e.g. to\n // render a mobile bottom sheet instead). When the host opts out we\n // must NOT focus the editor or update its selection — on iOS Safari\n // calling `.focus()` on a contenteditable triggers a synchronous\n // \"scroll focused element into view\", and the host typically wants\n // the editor's caret/keyboard left untouched while its sheet opens.\n const content = options.popover({\n editor: options.editor,\n view,\n link,\n nodePos,\n attrs,\n linkCoords,\n validate: options.validate\n })\n\n if (!content) {\n hideCurrentToolbar()\n return true\n }\n\n // Desktop popover path: anchor the caret at the link so subsequent\n // in-popover actions (edit, remove) operate on the right mark.\n if (clickPos !== undefined) {\n const { from, to } = view.state.selection\n const pos = from === to ? clickPos : { from, to }\n options.editor\n .chain()\n .focus(clickPos === 0 ? 'start' : clickPos)\n .setTextSelection(pos)\n .run()\n }\n\n const toolbar = createFloatingToolbar({\n referenceElement: link,\n content,\n placement: 'bottom',\n offset: DEFAULT_OFFSET,\n showArrow: true\n })\n\n toolbar.show()\n return true\n}\n\nexport default function clickHandlerPlugin(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('hyperlinkClickHandler'),\n\n // Two capture-phase listeners work together:\n // 1. mousedown + stopPropagation: ProseMirror tracks mousedown\n // position and fires handleSingleClick on mouseup — which reaches\n // showPopover's no-popover fallback and calls window.open.\n // Stopping mousedown propagation prevents that entire path.\n // 2. click + preventDefault (no stopPropagation): prevents browser\n // default navigation for target=\"_blank\" links, but lets the event\n // bubble so handleDOMEvents.click can show the popover.\n view(editorView) {\n const preventMouseDown = (event: MouseEvent) => {\n if (event.button !== 0) return\n const link = findLinkFromEvent(event, editorView.dom)\n if (!link) return\n event.preventDefault()\n event.stopPropagation()\n }\n\n const preventClick = (event: MouseEvent) => {\n if (event.button !== 0) return\n const link = findLinkFromEvent(event, editorView.dom)\n if (link) event.preventDefault()\n }\n\n editorView.dom.addEventListener('mousedown', preventMouseDown, true)\n editorView.dom.addEventListener('click', preventClick, true)\n return {\n destroy() {\n editorView.dom.removeEventListener('mousedown', preventMouseDown, true)\n editorView.dom.removeEventListener('click', preventClick, true)\n }\n }\n },\n\n props: {\n handleDOMEvents: {\n touchend: (view: EditorView, event: TouchEvent) => {\n const link = findLinkFromEvent(event, view.dom)\n if (!link) return false\n\n event.preventDefault()\n const { clientX, clientY } = event.changedTouches[0]\n const pos = view.posAtCoords({ left: clientX, top: clientY })\n return showPopover(view, link, options, pos?.pos)\n },\n\n click: (view: EditorView, event: MouseEvent) => {\n if (event.button !== 0) return false\n\n const link = findLinkFromEvent(event, view.dom)\n if (!link) return false\n\n event.preventDefault()\n const pos = view.posAtCoords({ left: event.clientX, top: event.clientY })\n return showPopover(view, link, options, pos?.pos)\n }\n }\n }\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\nimport { normalizeLinkifyHref } from '../utils/normalizeHref'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport default function pasteHandlerPlugin(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('hyperlinkPasteHandler'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach((node) => {\n textContent += node.textContent\n })\n\n const link = find(textContent).find((item) => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n if (options.validate && !options.validate(link.href)) {\n return false\n }\n\n options.editor.commands.setMark(options.type, {\n href: normalizeLinkifyHref(link)\n })\n\n return true\n }\n }\n })\n}\n","export const copyToClipboard = async (\n text: string,\n callback?: (success: boolean) => void\n): Promise<boolean> => {\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text)\n } else {\n const textArea = document.createElement('textarea')\n textArea.value = text\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n\n callback?.(true)\n return true\n } catch (error) {\n console.warn('Failed to copy to clipboard:', error)\n callback?.(false)\n return false\n }\n}\n","export const createHTMLElement = <K extends keyof HTMLElementTagNameMap>(\n type: K,\n props?: Partial<HTMLElementTagNameMap[K]>\n): HTMLElementTagNameMap[K] => {\n const element = document.createElement(type)\n\n if (props) {\n Object.assign(element, props)\n }\n\n return element\n}\n","interface IconProps {\n size?: number\n fill?: string\n}\n\nexport const Copy = ({ size = 24, fill = 'currentColor' }: IconProps = {}): string => {\n return `\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"${size}\" viewBox=\"0 -960 960 960\" width=\"${size}\" fill=\"${fill}\">\n <path d=\"M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z\"/>\n </svg>\n `\n}\n\nexport const LinkOff = ({ size = 24, fill = 'currentColor' }: IconProps = {}): string => {\n return `\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"${size}\" viewBox=\"0 -960 960 960\" width=\"${size}\" fill=\"${fill}\">\n <path d=\"m770-302-60-62q40-11 65-42.5t25-73.5q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 57-29.5 105T770-302ZM634-440l-80-80h86v80h-6ZM792-56 56-792l56-56 736 736-56 56ZM440-280H280q-83 0-141.5-58.5T80-480q0-69 42-123t108-71l74 74h-24q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h65l79 80H320Z\"/>\n </svg>\n `\n}\n\nexport const Link = ({ size = 24, fill = 'currentColor' }: IconProps = {}): string => {\n return `\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"${size}\" viewBox=\"0 -960 960 960\" width=\"${size}\" fill=\"${fill}\">\n <path d=\"M440-280H280q-83 0-141.5-58.5T80-480q0-83 58.5-141.5T280-680h160v80H280q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h320v80H320Zm200 160v-80h160q50 0 85-35t35-85q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 83-58.5 141.5T680-280H520Z\"/>\n </svg>\n `\n}\n\nexport const Pencil = ({ size = 24, fill = 'currentColor' }: IconProps = {}): string => {\n return `\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"${size}\" viewBox=\"0 -960 960 960\" width=\"${size}\" fill=\"${fill}\">\n <path d=\"M200-200h57l391-391-57-57-391 391v57Zm-80 80v-170l528-527q12-11 26.5-17t30.5-6q16 0 31 6t26 18l55 56q12 11 17.5 26t5.5 30q0 16-5.5 30.5T817-647L290-120H120Zm640-584-56-56 56 56Zm-141 85-28-29 57 57-29-28Z\"/>\n </svg>\n `\n}\n\nexport const Title = ({ size = 24, fill = 'currentColor' }: IconProps = {}): string => {\n return `\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"${size}\" viewBox=\"0 -960 960 960\" width=\"${size}\" fill=\"${fill}\">\n <path d=\"M420-160v-520H200v-120h560v120H540v520H420Z\"/>\n </svg>\n `\n}\n","import { hideCurrentToolbar } from '../helpers/floatingToolbar'\nimport type { CreateHyperlinkOptions } from '../hyperlink'\nimport { createHTMLElement, Link, normalizeHref, validateURL } from '../utils'\n\ntype HyperlinkElements = {\n root: HTMLElement\n form: HTMLFormElement\n input: HTMLInputElement\n button: HTMLButtonElement\n inputsWrapper: HTMLElement\n errorMessage: HTMLElement\n}\n\nconst createHyperlinkElements = (): HyperlinkElements | null => {\n try {\n const root = createHTMLElement('div', { className: 'hyperlink-create-popover' })\n const buttonsWrapper = createHTMLElement('div', { className: 'buttons-wrapper' })\n const inputsWrapper = createHTMLElement('div', { className: 'inputs-wrapper' })\n const form = createHTMLElement('form', {})\n\n const input = createHTMLElement('input', {\n type: 'text',\n inputMode: 'url',\n name: 'hyperlink-url',\n placeholder: 'https://example.com',\n autocomplete: 'new-password',\n spellcheck: false\n })\n\n const button = createHTMLElement('button', {\n type: 'submit',\n textContent: 'Apply',\n disabled: true\n })\n\n const errorMessage = createHTMLElement('div', {\n className: 'error-message',\n textContent: 'Please enter a valid URL'\n })\n\n const searchIcon = createHTMLElement('div', {\n className: 'search-icon',\n innerHTML: Link({ size: 24 })\n })\n\n inputsWrapper.append(searchIcon, input, errorMessage)\n buttonsWrapper.append(button)\n form.append(inputsWrapper, buttonsWrapper)\n root.append(form)\n\n return { root, form, input, button, inputsWrapper, errorMessage }\n } catch (error) {\n console.error('Failed to create hyperlink elements:', error)\n return null\n }\n}\n\nconst setupEventListeners = (elements: HyperlinkElements, options: CreateHyperlinkOptions) => {\n const { form, input, button, inputsWrapper, errorMessage } = elements\n\n const showError = () => {\n inputsWrapper.classList.add('error')\n errorMessage.classList.add('show')\n }\n\n const hideError = () => {\n inputsWrapper.classList.remove('error')\n errorMessage.classList.remove('show')\n }\n\n const updateButtonState = () => {\n const hasValue = input.value.trim().length > 0\n button.disabled = !hasValue\n if (hasValue) hideError()\n }\n\n input.addEventListener('input', updateButtonState)\n input.addEventListener('paste', () => setTimeout(updateButtonState, 0))\n inputsWrapper.addEventListener('click', () => input.focus())\n\n input.addEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n hideCurrentToolbar()\n options.editor.commands.focus()\n }\n })\n\n form.addEventListener('submit', (event: Event) => {\n event.preventDefault()\n if (button.disabled) return\n\n const url = input.value.trim()\n if (!validateURL(url, { customValidator: options.validate })) {\n showError()\n return\n }\n\n // Canonicalize before writing to the mark. `google.com` is a valid\n // link per linkifyjs, but stored verbatim it becomes a *relative*\n // href that resolves to the host page's origin on click. See\n // `normalizeHref` for the full rationale.\n const href = normalizeHref(url)\n\n hideCurrentToolbar()\n options.editor\n .chain()\n .setMark(options.extensionName, { href })\n .setMeta('preventAutolink', true)\n .run()\n })\n}\n\nexport default function createHyperlinkPopover(\n options: CreateHyperlinkOptions\n): HTMLElement | null {\n const elements = createHyperlinkElements()\n if (!elements) return null\n\n setupEventListeners(elements, options)\n return elements.root\n}\n","import { Editor } from '@tiptap/core'\nimport { EditorView } from '@tiptap/pm/view'\n\nimport { createFloatingToolbar, hideCurrentToolbar } from '../helpers/floatingToolbar'\nimport { createHTMLElement, Link, Title, validateURL } from '../utils'\n\nconst TOOLBAR_SHOW_DELAY_MS = 100\n\nexport type EditHyperlinkModalOptions = {\n editor: Editor\n validate?: (url: string) => boolean\n view: EditorView\n link: HTMLAnchorElement\n linkCoords: {\n x: number\n y: number\n width: number\n height: number\n }\n onBack?: () => void\n markName?: string\n}\n\nexport default function editHyperlinkPopover(options: EditHyperlinkModalOptions): void {\n const { editor, link, linkCoords, validate, view } = options\n\n const form = createHTMLElement('form', { className: 'hyperlink-edit-popover' })\n const inputsWrapper = createHTMLElement('div', { className: 'inputs-wrapper' })\n const buttonsWrapper = createHTMLElement('div', { className: 'buttons-wrapper' })\n\n // Text input\n const textWrapper = createHTMLElement('div', { className: 'text-wrapper' })\n const titleIcon = createHTMLElement('div', {\n className: 'search-icon',\n innerHTML: Title({ size: 24 })\n })\n const linkTextInput = createHTMLElement('input', {\n type: 'text',\n value: link?.innerText || '',\n placeholder: 'Enter link text'\n })\n const textError = createHTMLElement('div', {\n className: 'error-message',\n textContent: 'Please enter link text'\n })\n\n // URL input\n const hrefWrapper = createHTMLElement('div', { className: 'href-wrapper' })\n const anchorIcon = createHTMLElement('div', {\n className: 'search-icon',\n innerHTML: Link({ size: 24 })\n })\n const hrefInput = createHTMLElement('input', {\n type: 'text',\n inputMode: 'url',\n value: link.href,\n placeholder: 'Enter URL',\n autocomplete: 'new-password',\n spellcheck: false\n })\n const hrefError = createHTMLElement('div', {\n className: 'error-message',\n textContent: 'Please enter a valid URL'\n })\n\n // Buttons\n const backButton = createHTMLElement('button', {\n type: 'button',\n textContent: 'Back',\n className: 'back-button'\n })\n const applyButton = createHTMLElement('button', {\n type: 'submit',\n textContent: 'Apply',\n className: 'apply-button'\n })\n\n const showError = (wrapper: HTMLElement, errorEl: HTMLElement) => {\n wrapper.classList.add('error')\n errorEl.classList.add('show')\n }\n\n const hideError = (wrapper: HTMLElement, errorEl: HTMLElement) => {\n wrapper.classList.remove('error')\n errorEl.classList.remove('show')\n }\n\n linkTextInput.addEventListener('input', () => hideError(textWrapper, textError))\n hrefInput.addEventListener('input', () => hideError(hrefWrapper, hrefError))\n backButton.addEventListener('click', () => {\n if (options.onBack) options.onBack()\n })\n\n form.addEventListener('submit', (e) => {\n e.preventDefault()\n\n const newText = linkTextInput.value.trim()\n const newHref = hrefInput.value.trim()\n let hasErrors = false\n\n if (!newText) {\n showError(textWrapper, textError)\n hasErrors = true\n }\n\n if (!validateURL(newHref, { customValidator: validate })) {\n showError(hrefWrapper, hrefError)\n hasErrors = true\n }\n\n if (hasErrors) return\n\n editor\n .chain()\n .focus()\n .extendMarkRange(options.markName ?? 'hyperlink')\n .editHyperlink({ newURL: newHref, newText })\n .run()\n\n hideCurrentToolbar()\n })\n\n // Assemble DOM\n textWrapper.append(titleIcon, linkTextInput, textError)\n hrefWrapper.append(anchorIcon, hrefInput, hrefError)\n inputsWrapper.append(textWrapper, hrefWrapper)\n buttonsWrapper.append(backButton, applyButton)\n form.append(inputsWrapper, buttonsWrapper)\n\n hideCurrentToolbar()\n\n const toolbar = createFloatingToolbar({\n coordinates: {\n x: linkCoords.x,\n y: linkCoords.y,\n width: linkCoords.width,\n height: linkCoords.height,\n contextElement: view.dom\n },\n content: form,\n placement: 'bottom',\n showArrow: true,\n onShow: () => linkTextInput.focus()\n })\n\n setTimeout(() => toolbar.show(), TOOLBAR_SHOW_DELAY_MS)\n}\n","import { createFloatingToolbar, hideCurrentToolbar } from '../helpers/floatingToolbar'\nimport type { PreviewHyperlinkOptions } from '../hyperlink'\nimport {\n Copy,\n copyToClipboard,\n createHTMLElement,\n DANGEROUS_SCHEME_RE,\n LinkOff,\n Pencil\n} from '../utils'\nimport editHyperlinkPopover from './editHyperlinkPopover'\n\nfunction showPreviewToolbar(options: PreviewHyperlinkOptions): void {\n const content = previewHyperlinkPopover(options)\n const toolbar = createFloatingToolbar({\n referenceElement: options.link,\n content,\n placement: 'bottom',\n showArrow: true\n })\n toolbar.show()\n}\n\nexport default function previewHyperlinkPopover(options: PreviewHyperlinkOptions): HTMLElement {\n const { link, editor } = options\n // Prefer the stored mark attribute over `link.href`. The DOM property\n // silently resolves relative hrefs against `document.baseURI`, which\n // turns a stored `google.com` into `http://<current-origin>/google.com`\n // in the preview — see normalizeHref for context. `getAttribute('href')`\n // returns the raw string as a fallback for callers that construct the\n // popover by hand (e.g. the XSS-guard spec) without supplying `attrs`.\n const href = options.attrs?.href ?? link.getAttribute('href') ?? ''\n\n const root = createHTMLElement('div', { className: 'hyperlink-preview-popover' })\n const removeButton = createHTMLElement('button', { className: 'remove', innerHTML: LinkOff() })\n const copyButton = createHTMLElement('button', { className: 'copy', innerHTML: Copy() })\n const editButton = createHTMLElement('button', { className: 'edit', innerHTML: Pencil() })\n\n const hrefTitle = createHTMLElement('a', {\n target: '_blank',\n rel: 'noreferrer',\n href,\n innerText: href\n }) as HTMLAnchorElement\n\n hrefTitle.addEventListener('click', (event) => {\n event.preventDefault()\n if (!DANGEROUS_SCHEME_RE.test(href)) {\n window.open(href, '_blank')\n }\n })\n\n removeButton.addEventListener('click', () => {\n hideCurrentToolbar()\n editor.chain().focus().unsetHyperlink().run()\n })\n\n editButton.addEventListener('click', () => {\n editHyperlinkPopover({\n ...options,\n onBack: () => showPreviewToolbar(options)\n })\n })\n\n copyButton.addEventListener('click', () => {\n copyToClipboard(href, (success) => {\n if (success) hideCurrentToolbar()\n else console.error('Failed to copy to clipboard')\n })\n })\n\n root.append(hrefTitle, copyButton, editButton, removeButton)\n return root\n}\n","import { Hyperlink } from './hyperlink'\nexport * from './helpers/floatingToolbar'\nexport * from './hyperlink'\nexport * from './popovers'\nexport * from './utils'\nexport { registerCustomProtocol } from 'linkifyjs'\n\nexport default Hyperlink\n"],"mappings":"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","names":["InputRule","Mark","markPasteRule","mergeAttributes","find","registerCustomProtocol","getMarkRange","SCHEME_RE","normalizeHref","raw","trimmed","normalizeLinkifyHref","link","find","COMMUNICATION_URLS","SOCIAL_URLS","MEETING_URLS","APPLE_URLS","PRODUCTIVITY_URLS","ENTERTAINMENT_URLS","SHOPPING_URLS","ALL_SPECIAL_URLS","DOMAIN_MAPPINGS","getSpecialUrlInfo","url","lowerUrl","scheme","info","hostname","cleanHostname","domain","getCategories","categories","getUrlsByCategory","category","result","DANGEROUS_SCHEME_RE","STANDARD_WEB_SCHEMES","IPV4_RE","isValidSpecialScheme","url","getSpecialUrlInfo","hasPlausibleHost","parsed","host","validateURL","options","validURL","find","link","scheme","getUrlScheme","error","colonIndex","isSpecialSchemeUrl","editHyperlinkCommand","attributes","tr","dispatch","newURL","newText","title","image","validate","markName","validateURL","markType","from","$pos","range","getMarkRange","currentMark","m","error","text","href","normalizeHref","newMark","arrow","autoUpdate","computePosition","flip","hideMiddleware","offset","shift","DEFAULT_OFFSET","DEFAULT_Z_INDEX","SHIFT_PADDING","ARROW_STATIC_OFFSET","OUTSIDE_CLICK_DEFER_MS","currentToolbar","createVirtualReference","coords","x","y","width","height","setupKeyboardNav","container","focusable","el","i","e","next","createFloatingToolbar","options","referenceElement","coordinates","content","placement","offsetVal","showArrow","className","zIndex","onShow","onHide","reference","cleanups","visible","autoUpdateCleanup","toolbar","arrowEl","contentContainer","setContent","updatePosition","middleware","actual","middlewareData","ax","ay","side","staticSide","hide","fn","instance","onMouseDown","onTouchStart","target","onKeyDown","ref","getCurrentToolbar","isToolbarVisible","hideCurrentToolbar","destroyCurrentToolbar","updateCurrentToolbarPosition","combineTransactionSteps","findChildrenInRange","getChangedRanges","getMarksBetween","Plugin","PluginKey","find","test","SPECIAL_SCHEME_REGEX_GLOBAL","SPECIAL_SCHEME_REGEX","IMAGE_MARKDOWN_CONTEXT_CHARS","TRAILING_PUNCT_RE","stripTrailingPunct","link","tail","len","findLinks","text","links","standardLinks","find","match","url","start","end","validateURL","testUrl","test","autolinkPlugin","options","Plugin","PluginKey","transactions","oldState","newState","docChanges","transaction","preventAutolink","tr","transform","combineTransactionSteps","mapping","changes","getChangedRanges","oldRange","newRange","oldMark","getMarksBetween","item","newFrom","newTo","newMarks","newMark","oldLinkText","newLinkText","wasLink","isLink","nodesInChangedRanges","findChildrenInRange","node","textBlock","textBeforeWhitespace","wordsBeforeWhitespace","s","lastWordBeforeSpace","lastWordAndBlockOffset","contextStart","beforeLink","normalizeLinkifyHref","Plugin","PluginKey","getLinkCoordinates","el","rect","findLinkFromEvent","event","root","target","link","getMarkAttrsAtPos","view","pos","type","m","showPopover","options","clickPos","nodePos","attrs","href","targetAttr","DANGEROUS_SCHEME_RE","hideCurrentToolbar","linkCoords","content","from","to","createFloatingToolbar","DEFAULT_OFFSET","clickHandlerPlugin","Plugin","PluginKey","editorView","preventMouseDown","preventClick","clientX","clientY","Plugin","PluginKey","find","pasteHandlerPlugin","options","Plugin","PluginKey","view","event","slice","state","selection","empty","textContent","node","link","find","item","normalizeLinkifyHref","INPUT_FOCUS_DELAY_MS","Hyperlink","Mark","protocol","registerCustomProtocol","node","href","DANGEROUS_SCHEME_RE","HTMLAttributes","mergeAttributes","attributes","editor","chain","normalized","normalizeHref","content","from","to","start","end","createFloatingToolbar","input","editHyperlinkCommand","newText","newURL","InputRule","state","range","match","_fullMatch","linkText","url","tr","trimmed","normalizedUrl","markPasteRule","text","find","link","normalizeLinkifyHref","plugins","autolinkPlugin","clickHandlerPlugin","pasteHandlerPlugin","copyToClipboard","text","callback","textArea","error","createHTMLElement","type","props","element","Copy","size","fill","LinkOff","Link","Pencil","Title","createHyperlinkElements","root","createHTMLElement","buttonsWrapper","inputsWrapper","form","input","button","errorMessage","searchIcon","Link","error","setupEventListeners","elements","options","showError","hideError","updateButtonState","hasValue","event","hideCurrentToolbar","url","validateURL","href","normalizeHref","createHyperlinkPopover","TOOLBAR_SHOW_DELAY_MS","editHyperlinkPopover","options","editor","link","linkCoords","validate","view","form","createHTMLElement","inputsWrapper","buttonsWrapper","textWrapper","titleIcon","Title","linkTextInput","textError","hrefWrapper","anchorIcon","Link","hrefInput","hrefError","backButton","applyButton","showError","wrapper","errorEl","hideError","e","newText","newHref","hasErrors","validateURL","hideCurrentToolbar","toolbar","createFloatingToolbar","showPreviewToolbar","options","content","previewHyperlinkPopover","createFloatingToolbar","link","editor","href","root","createHTMLElement","removeButton","LinkOff","copyButton","Copy","editButton","Pencil","hrefTitle","event","DANGEROUS_SCHEME_RE","hideCurrentToolbar","editHyperlinkPopover","copyToClipboard","success","registerCustomProtocol","index_default","Hyperlink"]}