quikchat 1.1.16 → 1.2.4
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/README.md +160 -354
- package/dist/build-manifest.json +157 -0
- package/dist/quikchat-md-full.cjs.js +2742 -0
- package/dist/quikchat-md-full.cjs.js.map +1 -0
- package/dist/quikchat-md-full.cjs.min.js +10 -0
- package/dist/quikchat-md-full.cjs.min.js.map +1 -0
- package/dist/quikchat-md-full.esm.js +2740 -0
- package/dist/quikchat-md-full.esm.js.map +1 -0
- package/dist/quikchat-md-full.esm.min.js +10 -0
- package/dist/quikchat-md-full.esm.min.js.map +1 -0
- package/dist/quikchat-md-full.umd.js +2748 -0
- package/dist/quikchat-md-full.umd.js.map +1 -0
- package/dist/quikchat-md-full.umd.min.js +10 -0
- package/dist/quikchat-md-full.umd.min.js.map +1 -0
- package/dist/quikchat-md.cjs.js +1641 -0
- package/dist/quikchat-md.cjs.js.map +1 -0
- package/dist/quikchat-md.cjs.min.js +8 -0
- package/dist/quikchat-md.cjs.min.js.map +1 -0
- package/dist/quikchat-md.esm.js +1639 -0
- package/dist/quikchat-md.esm.js.map +1 -0
- package/dist/quikchat-md.esm.min.js +8 -0
- package/dist/quikchat-md.esm.min.js.map +1 -0
- package/dist/quikchat-md.umd.js +1647 -0
- package/dist/quikchat-md.umd.js.map +1 -0
- package/dist/quikchat-md.umd.min.js +8 -0
- package/dist/quikchat-md.umd.min.js.map +1 -0
- package/dist/quikchat.cjs.js +449 -1421
- package/dist/quikchat.cjs.js.map +1 -1
- package/dist/quikchat.cjs.min.js +1 -1
- package/dist/quikchat.cjs.min.js.map +1 -1
- package/dist/quikchat.css +753 -226
- package/dist/quikchat.esm.js +449 -1421
- package/dist/quikchat.esm.js.map +1 -1
- package/dist/quikchat.esm.min.js +1 -1
- package/dist/quikchat.esm.min.js.map +1 -1
- package/dist/quikchat.min.css +1 -1
- package/dist/quikchat.umd.js +449 -1421
- package/dist/quikchat.umd.js.map +1 -1
- package/dist/quikchat.umd.min.js +1 -1
- package/dist/quikchat.umd.min.js.map +1 -1
- package/package.json +59 -34
- package/dist/quikchat.d.ts +0 -194
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quikchat-md-full.esm.min.js","sources":["../src/quikchat.js","../node_modules/quikdown/dist/quikdown_bd.esm.js","../src/quikchat-md-full.js"],"sourcesContent":["\nclass quikchat {\n /**\n *\n * @param string or DOM element parentElement\n * @param {*} meta\n */\n constructor(parentElement, onSend = () => { }, options = {}) {\n const defaultOpts = {\n theme: 'quikchat-theme-light',\n trackHistory: true,\n showTimestamps: false,\n titleArea: { title: \"Chat\", show: false, align: \"center\" },\n messagesArea: { alternating: true },\n };\n const meta = { ...defaultOpts, ...options }; // merge options with defaults\n\n if (typeof parentElement === 'string') {\n parentElement = document.querySelector(parentElement);\n }\n this._parentElement = parentElement;\n this._theme = meta.theme;\n this._onSend = onSend ? onSend : () => { }; // call back function for onSend\n this._messageFormatter = meta.messageFormatter || null;\n this._sanitize = meta.sanitize || false;\n this._createWidget();\n // title area\n if (meta.titleArea) {\n this.titleAreaSetContents(meta.titleArea.title, meta.titleArea.align);\n if (meta.titleArea.show === true) {\n this.titleAreaShow();\n } else {\n this.titleAreaHide();\n }\n }\n // messages area\n if (meta.messagesArea) {\n this.messagesAreaAlternateColors(meta.messagesArea.alternating);\n }\n // timestamps\n if (meta.showTimestamps) {\n this.messagesAreaShowTimestamps(true);\n }\n // direction (ltr/rtl)\n if (meta.direction) {\n this.setDirection(meta.direction);\n }\n // plumbing\n this._attachEventListeners();\n this.trackHistory = meta.trackHistory !== false;\n this._historyLimit = 10000000;\n this._history = [];\n }\n\n _createWidget() {\n const widgetHTML =\n `\n <div class=\"quikchat-base ${this.theme}\">\n <div class=\"quikchat-title-area\"></div>\n <div class=\"quikchat-messages-wrapper\"><div class=\"quikchat-messages-area\" role=\"log\" aria-live=\"polite\" aria-label=\"Chat messages\"></div><button class=\"quikchat-scroll-bottom\" aria-label=\"Scroll to bottom\"></button></div>\n <div class=\"quikchat-input-area\">\n <textarea class=\"quikchat-input-textbox\" rows=\"1\" aria-label=\"Type a message\"></textarea>\n <button class=\"quikchat-input-send-btn\">Send</button>\n </div>\n </div>\n `;\n\n this._parentElement.innerHTML = widgetHTML;\n this._chatWidget = this._parentElement.querySelector('.quikchat-base');\n this._titleArea = this._chatWidget.querySelector('.quikchat-title-area');\n this._messagesWrapper = this._chatWidget.querySelector('.quikchat-messages-wrapper');\n this._messagesArea = this._chatWidget.querySelector('.quikchat-messages-area');\n this._scrollBottomBtn = this._messagesWrapper.querySelector('.quikchat-scroll-bottom');\n this._inputArea = this._chatWidget.querySelector('.quikchat-input-area');\n this._textEntry = this._inputArea.querySelector('.quikchat-input-textbox');\n this._sendButton = this._inputArea.querySelector('.quikchat-input-send-btn');\n this.msgid = 0;\n }\n\n /**\n * Attach event listeners to the widget\n */\n _attachEventListeners() {\n this._sendButton.addEventListener('click', () => {\n const text = this._textEntry.value.trim();\n if (text === '') return;\n this._onSend(this, text);\n });\n this._textEntry.addEventListener('keydown', (event) => {\n // Check if Shift + Enter is pressed\n if (event.shiftKey && event.keyCode === 13) {\n event.preventDefault();\n const text = this._textEntry.value.trim();\n if (text === '') return;\n this._onSend(this, text);\n }\n });\n\n // Auto-grow textarea\n this._textEntry.addEventListener('input', () => this._autoGrowTextarea());\n\n this._messagesArea.addEventListener('scroll', () => {\n const { scrollTop, scrollHeight, clientHeight } = this._messagesArea;\n this.userScrolledUp = scrollTop + clientHeight < scrollHeight - 1;\n this._updateScrollBottomBtn();\n });\n\n // Scroll-to-bottom button\n this._scrollBottomBtn.addEventListener('click', () => this.scrollToBottom());\n\n // Ctrl+End to scroll to bottom\n this._chatWidget.addEventListener('keydown', (event) => {\n if (event.ctrlKey && event.key === 'End') {\n event.preventDefault();\n this.scrollToBottom();\n }\n });\n\n // Use ResizeObserver to detect parent container resize\n if (typeof ResizeObserver !== 'undefined') {\n this._resizeObserver = new ResizeObserver(() => this._handleContainerResize());\n this._resizeObserver.observe(this._parentElement);\n }\n }\n\n // set the onSend function callback.\n setCallbackOnSend(callback) {\n this._onSend = callback;\n }\n // set a callback for everytime a message is added (listener)\n setCallbackonMessageAdded(callback) {\n this._onMessageAdded = callback;\n }\n setCallbackonMessageAppend(callback) {\n this._onMessageAppend = callback;\n }\n setCallbackonMessageReplace(callback) {\n this._onMessageReplace = callback;\n }\n setCallbackonMessageDelete(callback) {\n this._onMessageDelete = callback;\n }\n\n // Public methods\n titleAreaToggle() {\n if (this._titleArea.style.display === 'none') {\n this.titleAreaShow();\n } else {\n this.titleAreaHide();\n }\n }\n\n titleAreaShow() {\n this._titleArea.style.display = '';\n }\n\n titleAreaHide() {\n this._titleArea.style.display = 'none';\n }\n\n titleAreaSetContents(title, align = 'center') {\n this._titleArea.innerHTML = title;\n this._titleArea.style.textAlign = align;\n }\n\n titleAreaGetContents() {\n return this._titleArea.innerHTML;\n }\n\n inputAreaToggle() {\n if (this._inputArea.style.display === 'none') {\n this.inputAreaShow();\n } else {\n this.inputAreaHide();\n }\n }\n\n inputAreaShow() {\n this._inputArea.style.display = '';\n }\n\n inputAreaHide() {\n this._inputArea.style.display = 'none';\n }\n\n inputAreaSetEnabled(enabled) {\n this._textEntry.disabled = !enabled;\n this._sendButton.disabled = !enabled;\n }\n\n inputAreaSetButtonText(text) {\n this._sendButton.textContent = text;\n }\n\n inputAreaGetButtonText() {\n return this._sendButton.textContent;\n }\n\n setDirection(dir) {\n const d = dir === 'rtl' ? 'rtl' : 'ltr';\n this._chatWidget.setAttribute('dir', d);\n if (d === 'rtl') {\n this._chatWidget.classList.add('quikchat-rtl');\n } else {\n this._chatWidget.classList.remove('quikchat-rtl');\n }\n }\n\n getDirection() {\n return this._chatWidget.getAttribute('dir') || 'ltr';\n }\n\n _handleContainerResize() {\n // Layout is handled by CSS flexbox — no JS height calculation needed.\n // This hook exists for future use or custom resize callbacks.\n }\n\n scrollToBottom() {\n this._messagesArea.scrollTop = this._messagesArea.scrollHeight;\n this.userScrolledUp = false;\n this._updateScrollBottomBtn();\n }\n\n _updateScrollBottomBtn() {\n if (this.userScrolledUp) {\n this._scrollBottomBtn.classList.add('quikchat-scroll-bottom-visible');\n } else {\n this._scrollBottomBtn.classList.remove('quikchat-scroll-bottom-visible');\n }\n }\n\n _autoGrowTextarea() {\n const el = this._textEntry;\n el.style.height = 'auto';\n const maxHeight = parseInt(getComputedStyle(el).getPropertyValue('--quikchat-input-max-height')) || 120;\n el.style.height = Math.min(el.scrollHeight, maxHeight) + 'px';\n el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden';\n }\n\n _formatTimestamp(isoString) {\n const d = new Date(isoString);\n const h = d.getHours();\n const m = String(d.getMinutes()).padStart(2, '0');\n const ampm = h >= 12 ? 'PM' : 'AM';\n const h12 = h % 12 || 12;\n return h12 + ':' + m + ' ' + ampm;\n }\n\n messagesAreaShowTimestamps(show) {\n if (show) {\n this._messagesArea.classList.add('quikchat-show-timestamps');\n } else {\n this._messagesArea.classList.remove('quikchat-show-timestamps');\n }\n }\n\n messagesAreaShowTimestampsGet() {\n return this._messagesArea.classList.contains('quikchat-show-timestamps');\n }\n\n messagesAreaShowTimestampsToggle() {\n this._messagesArea.classList.toggle('quikchat-show-timestamps');\n }\n\n _escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n _processContent(content) {\n if (this._sanitize === true) {\n content = this._escapeHTML(content);\n } else if (typeof this._sanitize === 'function') {\n content = this._sanitize(content);\n }\n if (this._messageFormatter) {\n content = this._messageFormatter(content);\n }\n return content;\n }\n\n //messagesArea functions\n messagesAreaAlternateColors(alt = true) {\n if (alt) {\n this._messagesArea.classList.add('quikchat-messages-area-alt');\n }\n else {\n this._messagesArea.classList.remove('quikchat-messages-area-alt');\n }\n return alt === true;\n }\n messagesAreaAlternateColorsToggle() {\n this._messagesArea.classList.toggle('quikchat-messages-area-alt');\n }\n messagesAreaAlternateColorsGet() {\n return this._messagesArea.classList.contains('quikchat-messages-area-alt');\n }\n // message functions\n messageAddFull(input = { content: \"\", userString: \"user\", align: \"right\", role: \"user\", userID: -1 }) {\n const msgid = this.msgid;\n const messageDiv = document.createElement('div');\n const msgidClass = 'quikchat-msgid-' + String(msgid).padStart(10, '0');\n messageDiv.classList.add('quikchat-message', msgidClass);\n messageDiv.classList.add('quikchat-role-' + (input.role || 'user'));\n messageDiv.classList.add('quikchat-align-' + (input.align || 'right'));\n this.msgid++;\n messageDiv.classList.add(this._messagesArea.children.length % 2 === 1 ? 'quikchat-message-1' : 'quikchat-message-2');\n\n // Visibility: default true, hidden messages get display:none\n const visible = input.visible !== false;\n if (!visible) {\n messageDiv.style.display = 'none';\n }\n\n // Tags: array of strings for group-based visibility control\n const tags = Array.isArray(input.tags) ? input.tags.slice() : [];\n\n const userDiv = document.createElement('div');\n userDiv.classList.add('quikchat-user-label');\n userDiv.style.textAlign = input.align;\n userDiv.innerHTML = input.userString;\n\n const contentDiv = document.createElement('div');\n contentDiv.classList.add('quikchat-message-content');\n contentDiv.style.textAlign = input.align;\n contentDiv.innerHTML = this._processContent(input.content);\n\n const timestamp = new Date().toISOString();\n const timestampSpan = document.createElement('span');\n timestampSpan.classList.add('quikchat-timestamp');\n timestampSpan.textContent = this._formatTimestamp(timestamp);\n\n messageDiv.appendChild(userDiv);\n messageDiv.appendChild(contentDiv);\n messageDiv.appendChild(timestampSpan);\n this._messagesArea.appendChild(messageDiv);\n\n // Scroll to the last message only if the user is not actively scrolling up\n if (!this.userScrolledUp) {\n this._messagesArea.scrollTop = this._messagesArea.scrollHeight;\n }\n\n this._textEntry.value = '';\n this._autoGrowTextarea();\n const updatedtime = timestamp;\n\n if (this.trackHistory) {\n this._history.push({ msgid, ...input, visible, tags, timestamp, updatedtime, messageDiv });\n if (this._history.length > this._historyLimit) {\n this._history.shift();\n }\n }\n\n if (this._onMessageAdded) {\n this._onMessageAdded(this, msgid);\n }\n\n return msgid;\n }\n\n\n messageAddNew(content = \"\", userString = \"user\", align = \"right\", role = \"user\") {\n return this.messageAddFull(\n { content: content, userString: userString, align: align, role: role }\n );\n }\n messageRemove(n) {\n let success = false;\n try {\n this._messagesArea.removeChild(this._messagesArea.querySelector(`.quikchat-msgid-${String(n).padStart(10, '0')}`));\n success = true;\n }\n catch (_error) {\n // Message ID not found\n }\n if (success) {\n this._history.splice(this._history.findIndex((item) => item.msgid === n), 1);\n if (this._onMessageDelete) {\n this._onMessageDelete(this, n);\n }\n }\n return success;\n }\n /* returns the message html object from the DOM\n */\n messageGetDOMObject(n) {\n let msg = null;\n try {\n msg = this._messagesArea.querySelector(`.quikchat-msgid-${String(n).padStart(10, '0')}`);\n }\n catch (_error) {\n // Message ID not found\n }\n return msg;\n }\n /* returns the message content only\n */\n messageGetContent(n) {\n let content = \"\";\n try {\n content = this._history.filter((item) => item.msgid === n)[0].content;\n }\n catch (_error) {\n // Message ID not found\n }\n return content;\n }\n\n messageSetVisible(n, visible) {\n const msgEl = this.messageGetDOMObject(n);\n if (!msgEl) return false;\n msgEl.style.display = visible ? '' : 'none';\n const item = this._history.find((entry) => entry.msgid === n);\n if (item) item.visible = visible;\n return true;\n }\n\n messageGetVisible(n) {\n const item = this._history.find((entry) => entry.msgid === n);\n return item ? item.visible !== false : false;\n }\n\n messageToggleVisible(n) {\n const current = this.messageGetVisible(n);\n return this.messageSetVisible(n, !current);\n }\n\n messageSetVisibleByTag(tag, visible) {\n let count = 0;\n for (const item of this._history) {\n if (item.tags && item.tags.includes(tag)) {\n this.messageSetVisible(item.msgid, visible);\n count++;\n }\n }\n return count;\n }\n\n messageGetTags(n) {\n const item = this._history.find((entry) => entry.msgid === n);\n return item && item.tags ? item.tags.slice() : [];\n }\n\n messageSetTags(n, tags) {\n const item = this._history.find((entry) => entry.msgid === n);\n if (!item) return false;\n item.tags = Array.isArray(tags) ? tags.slice() : [];\n return true;\n }\n\n /* append message to the message content\n */\n messageAppendContent(n, content) {\n let success = false;\n try {\n const msgEl = this._messagesArea.querySelector(`.quikchat-msgid-${String(n).padStart(10, '0')}`);\n const item = this._history.filter((entry) => entry.msgid === n)[0];\n item.content += content;\n item.updatedtime = new Date().toISOString();\n msgEl.querySelector('.quikchat-message-content').innerHTML = this._processContent(item.content);\n msgEl.classList.remove('quikchat-typing');\n success = true;\n\n if (!this.userScrolledUp) {\n this._messagesArea.scrollTop = this._messagesArea.scrollHeight;\n }\n if (this._onMessageAppend) {\n this._onMessageAppend(this, n, content);\n }\n } catch (_error) {\n // Message ID not found\n }\n return success;\n }\n\n /* replace message content\n */\n messageReplaceContent(n, content) {\n let success = false;\n try {\n const msgEl = this._messagesArea.querySelector(`.quikchat-msgid-${String(n).padStart(10, '0')}`);\n const item = this._history.filter((entry) => entry.msgid === n)[0];\n item.content = content;\n item.updatedtime = new Date().toISOString();\n msgEl.querySelector('.quikchat-message-content').innerHTML = this._processContent(content);\n msgEl.classList.remove('quikchat-typing');\n success = true;\n\n if (!this.userScrolledUp) {\n this._messagesArea.scrollTop = this._messagesArea.scrollHeight;\n }\n if (this._onMessageReplace) {\n this._onMessageReplace(this, n, content);\n }\n } catch (_error) {\n // Message ID not found\n }\n return success;\n }\n\n messageAddTypingIndicator(userString = '', align = 'left') {\n const msgid = this.messageAddFull({\n content: '',\n userString: userString,\n align: align,\n role: 'assistant',\n });\n const msgEl = this.messageGetDOMObject(msgid);\n msgEl.classList.add('quikchat-typing');\n const contentDiv = msgEl.querySelector('.quikchat-message-content');\n contentDiv.innerHTML = '<span class=\"quikchat-typing-dots\"><span>.</span><span>.</span><span>.</span></span>';\n return msgid;\n }\n\n setMessageFormatter(formatter) {\n this._messageFormatter = formatter;\n }\n\n setSanitize(sanitize) {\n this._sanitize = sanitize;\n }\n\n // history functions\n /**\n *\n * @param {*} n\n * @param {*} m\n * @returns array of history messages\n */\n historyGet(n, m) {\n if (n === undefined) {\n return this._history.slice();\n }\n if (m === undefined) {\n if (n < 0) {\n return this._history.slice(n);\n }\n return this._history.slice(n, n + 1);\n }\n return this._history.slice(n, m);\n }\n\n historyClear() {\n this.msgid = 0;\n this._history = [];\n }\n\n historyGetLength() {\n return this._history.length;\n }\n\n historyGetMessage(n) {\n if (n >= 0 && n < this._history.length) {\n return this._history[n];\n }\n return {};\n }\n\n historyGetMessageContent(n) {\n if (n >= 0 && n < this._history.length) {\n return this._history[n].content;\n }\n return \"\";\n }\n\n historyExport() {\n return this._history.map((item) => ({\n msgid: item.msgid,\n content: item.content,\n userString: item.userString,\n align: item.align,\n role: item.role,\n userID: item.userID,\n visible: item.visible,\n tags: item.tags ? item.tags.slice() : [],\n timestamp: item.timestamp,\n updatedtime: item.updatedtime,\n }));\n }\n\n historyImport(data) {\n // Clear existing messages from DOM and history\n this._messagesArea.innerHTML = '';\n this._history = [];\n this.msgid = 0;\n\n for (const entry of data) {\n this.messageAddFull({\n content: entry.content || '',\n userString: entry.userString || 'user',\n align: entry.align || 'right',\n role: entry.role || 'user',\n userID: entry.userID,\n visible: entry.visible,\n tags: entry.tags,\n });\n }\n }\n\n changeTheme(newTheme) {\n this._chatWidget.classList.remove(this._theme);\n this._chatWidget.classList.add(newTheme);\n this._theme = newTheme;\n }\n\n get theme() {\n return this._theme;\n }\n\n static version() {\n return { \"version\": \"1.2.4\", \"license\": \"BSD-2\", \"url\": \"https://github/deftio/quikchat\" };\n }\n\n /**\n * quikchat.loremIpsum() - Generate a simple string of Lorem Ipsum text (sample typographer's text) of numChars in length.\n * borrowed from github.com/deftio/bitwrench.js\n * @param {number} numChars - The number of characters to generate (random btw 25 and 150 if undefined).\n * @param {number} [startSpot=0] - The starting index in the Lorem Ipsum text. If undefined, a random startSpot will be generated.\n * @param {boolean} [startWithCapitalLetter=true] - If true, capitalize the first character or inject a capital letter if the first character isn't a capital letter.\n *\n * @returns {string} A string of Lorem Ipsum text.\n *\n * @example\n * // Returns 200 characters of Lorem Ipsum starting from index 50\n * loremIpsum(200, 50);\n *\n * @example\n * //Returns a 200 Lorem Ipsum characters starting from a random index\n * loremIpsum(200);\n */\n\n static loremIpsum(numChars, startSpot = undefined, startWithCapitalLetter = true) {\n const loremText = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \";\n\n if (typeof numChars !== \"number\") {\n numChars = Math.floor(Math.random() * 126) + 25;\n }\n\n if (startSpot === undefined) {\n startSpot = Math.floor(Math.random() * loremText.length);\n }\n\n startSpot = startSpot % loremText.length;\n\n // Move startSpot to the next non-whitespace and non-punctuation character\n while (loremText[startSpot] === ' ' || /[.,:;!?]/.test(loremText[startSpot])) {\n startSpot = (startSpot + 1) % loremText.length;\n }\n\n const l = loremText.substring(startSpot) + loremText.substring(0, startSpot);\n\n let s = \"\";\n while (numChars > 0) {\n s += numChars < l.length ? l.substring(0, numChars) : l;\n numChars -= l.length;\n }\n\n if (s[s.length - 1] === \" \") {\n s = s.substring(0, s.length - 1) + \".\"; // always end on non-whitespace. \".\" was chosen arbitrarily.\n }\n\n if (startWithCapitalLetter) {\n s = s[0].toUpperCase() + s.substring(1);\n }\n\n return s;\n };\n\n\n}\n\nexport default quikchat;\n","/**\n * quikdown_bd - Bidirectional Markdown Parser\n * @version 1.1.1\n * @license BSD-2-Clause\n * @copyright DeftIO 2025\n */\n/**\n * quikdown - A minimal markdown parser optimized for chat/LLM output\n * Supports tables, code blocks, lists, and common formatting\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @param {Function} options.fence_plugin - Custom renderer for fenced code blocks\n * (content, fence_string) => html string\n * @param {boolean} options.inline_styles - If true, uses inline styles instead of classes\n * @param {boolean} options.bidirectional - If true, adds data-qd attributes for source tracking\n * @param {boolean} options.lazy_linefeeds - If true, single newlines become <br> tags\n * @returns {string} - The rendered HTML\n */\n\n// Version will be injected at build time \nconst quikdownVersion = '1.1.1';\n\n// Constants for reuse\nconst CLASS_PREFIX = 'quikdown-';\nconst PLACEHOLDER_CB = '§CB';\nconst PLACEHOLDER_IC = '§IC';\n\n// Escape map at module level\nconst ESC_MAP = {'&':'&','<':'<','>':'>','\"':'"',\"'\":'''};\n\n// Single source of truth for all style definitions - optimized\nconst QUIKDOWN_STYLES = {\n h1: 'font-size:2em;font-weight:600;margin:.67em 0;text-align:left',\n h2: 'font-size:1.5em;font-weight:600;margin:.83em 0',\n h3: 'font-size:1.25em;font-weight:600;margin:1em 0',\n h4: 'font-size:1em;font-weight:600;margin:1.33em 0',\n h5: 'font-size:.875em;font-weight:600;margin:1.67em 0',\n h6: 'font-size:.85em;font-weight:600;margin:2em 0',\n pre: 'background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0',\n code: 'background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace',\n blockquote: 'border-left:4px solid #ddd;margin-left:0;padding-left:1em',\n table: 'border-collapse:collapse;width:100%;margin:1em 0',\n th: 'border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left',\n td: 'border:1px solid #ddd;padding:8px;text-align:left',\n hr: 'border:none;border-top:1px solid #ddd;margin:1em 0',\n img: 'max-width:100%;height:auto',\n a: 'color:#06c;text-decoration:underline',\n strong: 'font-weight:bold',\n em: 'font-style:italic',\n del: 'text-decoration:line-through',\n ul: 'margin:.5em 0;padding-left:2em',\n ol: 'margin:.5em 0;padding-left:2em',\n li: 'margin:.25em 0',\n // Task list specific styles\n 'task-item': 'list-style:none',\n 'task-checkbox': 'margin-right:.5em'\n};\n\n// Factory function to create getAttr for a given context\nfunction createGetAttr(inline_styles, styles) {\n return function(tag, additionalStyle = '') {\n if (inline_styles) {\n let style = styles[tag];\n if (!style && !additionalStyle) return '';\n \n // Remove default text-align if we're adding a different alignment\n if (additionalStyle && additionalStyle.includes('text-align') && style && style.includes('text-align')) {\n style = style.replace(/text-align:[^;]+;?/, '').trim();\n if (style && !style.endsWith(';')) style += ';';\n }\n \n /* istanbul ignore next - defensive: additionalStyle without style doesn't occur with current tags */\n const fullStyle = additionalStyle ? (style ? `${style}${additionalStyle}` : additionalStyle) : style;\n return ` style=\"${fullStyle}\"`;\n } else {\n const classAttr = ` class=\"${CLASS_PREFIX}${tag}\"`;\n // Apply inline styles for alignment even when using CSS classes\n if (additionalStyle) {\n return `${classAttr} style=\"${additionalStyle}\"`;\n }\n return classAttr;\n }\n };\n}\n\nfunction quikdown(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false, bidirectional = false, lazy_linefeeds = false } = options;\n const styles = QUIKDOWN_STYLES; // Use module-level styles\n const getAttr = createGetAttr(inline_styles, styles); // Create getAttr once\n\n // Escape HTML entities to prevent XSS\n function escapeHtml(text) {\n return text.replace(/[&<>\"']/g, m => ESC_MAP[m]);\n }\n \n // Helper to add data-qd attributes for bidirectional support\n const dataQd = bidirectional ? (marker) => ` data-qd=\"${escapeHtml(marker)}\"` : () => '';\n \n // Sanitize URLs to prevent XSS attacks\n function sanitizeUrl(url, allowUnsafe = false) {\n /* istanbul ignore next - defensive programming, regex ensures url is never empty */\n if (!url) return '';\n \n // If unsafe URLs are explicitly allowed, return as-is\n if (allowUnsafe) return url;\n \n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n \n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n \n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n // Exception: Allow data:image/* for images\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n // Return safe empty link for dangerous protocols\n return '#';\n }\n }\n \n return trimmedUrl;\n }\n\n // Process the markdown in phases\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks and inline code\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks first (supports both ``` and ~~~)\n // Match paired fences - ``` with ``` and ~~~ with ~~~\n // Fence must be at start of line\n html = html.replace(/^(```|~~~)([^\\n]*)\\n([\\s\\S]*?)^\\1$/gm, (match, fence, lang, code) => {\n const placeholder = `${PLACEHOLDER_CB}${codeBlocks.length}§`;\n \n // Trim the language specification\n const langTrimmed = lang ? lang.trim() : '';\n \n // If custom fence plugin is provided, use it (v1.1.0: object format required)\n if (fence_plugin && fence_plugin.render && typeof fence_plugin.render === 'function') {\n codeBlocks.push({\n lang: langTrimmed,\n code: code.trimEnd(),\n custom: true,\n fence: fence,\n hasReverse: !!fence_plugin.reverse\n });\n } else {\n codeBlocks.push({\n lang: langTrimmed,\n code: escapeHtml(code.trimEnd()),\n custom: false,\n fence: fence\n });\n }\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `${PLACEHOLDER_IC}${inlineCodes.length}§`;\n inlineCodes.push(escapeHtml(code));\n return placeholder;\n });\n \n // Now escape HTML in the rest of the content\n html = escapeHtml(html);\n \n // Phase 2: Process block elements\n \n // Process tables\n html = processTable(html, getAttr);\n \n // Process headings (supports optional trailing #'s)\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n return `<h${level}${getAttr('h' + level)}${dataQd(hashes)}>${content}</h${level}>`;\n });\n \n // Process blockquotes (must handle escaped > since we already escaped HTML)\n html = html.replace(/^>\\s+(.+)$/gm, `<blockquote${getAttr('blockquote')}>$1</blockquote>`);\n // Merge consecutive blockquotes\n html = html.replace(/<\\/blockquote>\\n<blockquote>/g, '\\n');\n \n // Process horizontal rules (allow trailing spaces)\n html = html.replace(/^---+\\s*$/gm, `<hr${getAttr('hr')}>`);\n \n // Process lists\n html = processLists(html, getAttr, inline_styles, bidirectional);\n \n // Phase 3: Process inline elements\n \n // Images (must come before links, with URL sanitization)\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n const sanitizedSrc = sanitizeUrl(src, options.allow_unsafe_urls);\n const altAttr = bidirectional && alt ? ` data-qd-alt=\"${escapeHtml(alt)}\"` : '';\n const srcAttr = bidirectional ? ` data-qd-src=\"${escapeHtml(src)}\"` : '';\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${alt}\"${altAttr}${srcAttr}${dataQd('!')}>`;\n });\n \n // Links (with URL sanitization)\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n // Sanitize URL to prevent XSS\n const sanitizedHref = sanitizeUrl(href, options.allow_unsafe_urls);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n const textAttr = bidirectional ? ` data-qd-text=\"${escapeHtml(text)}\"` : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}${textAttr}${dataQd('[')}>${text}</a>`;\n });\n \n // Autolinks - convert bare URLs to clickable links\n html = html.replace(/(^|\\s)(https?:\\/\\/[^\\s<]+)/g, (match, prefix, url) => {\n const sanitizedUrl = sanitizeUrl(url, options.allow_unsafe_urls);\n return `${prefix}<a${getAttr('a')} href=\"${sanitizedUrl}\" rel=\"noopener noreferrer\">${url}</a>`;\n });\n \n // Process inline formatting (bold, italic, strikethrough)\n const inlinePatterns = [\n [/\\*\\*(.+?)\\*\\*/g, 'strong', '**'],\n [/__(.+?)__/g, 'strong', '__'],\n [/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, 'em', '*'],\n [/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, 'em', '_'],\n [/~~(.+?)~~/g, 'del', '~~']\n ];\n \n inlinePatterns.forEach(([pattern, tag, marker]) => {\n html = html.replace(pattern, `<${tag}${getAttr(tag)}${dataQd(marker)}>$1</${tag}>`);\n });\n \n // Line breaks\n if (lazy_linefeeds) {\n // Lazy linefeeds: single newline becomes <br> (except between paragraphs and after/before block elements)\n const blocks = [];\n let bi = 0;\n \n // Protect tables and lists \n html = html.replace(/<(table|[uo]l)[^>]*>[\\s\\S]*?<\\/\\1>/g, m => {\n blocks[bi] = m;\n return `§B${bi++}§`;\n });\n \n // Handle paragraphs and block elements\n html = html.replace(/\\n\\n+/g, '§P§')\n // After block elements\n .replace(/(<\\/(?:h[1-6]|blockquote|pre)>)\\n/g, '$1§N§')\n .replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\\n/g, '$1§N§')\n // Before block elements \n .replace(/\\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g, '§N§$1')\n .replace(/\\n(§B\\d+§)/g, '§N§$1')\n .replace(/(§B\\d+§)\\n/g, '$1§N§')\n // Convert remaining newlines\n .replace(/\\n/g, `<br${getAttr('br')}>`)\n // Restore\n .replace(/§N§/g, '\\n')\n .replace(/§P§/g, '</p><p>');\n \n // Restore protected blocks\n blocks.forEach((b, i) => html = html.replace(`§B${i}§`, b));\n \n html = '<p>' + html + '</p>';\n } else {\n // Standard: two spaces at end of line for line breaks\n html = html.replace(/ $/gm, `<br${getAttr('br')}>`);\n \n // Paragraphs (double newlines)\n // Don't add </p> after block elements (they're not in paragraphs)\n html = html.replace(/\\n\\n+/g, (match, offset) => {\n // Check if we're after a block element closing tag\n const before = html.substring(0, offset);\n if (before.match(/<\\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)) {\n return '<p>'; // Just open a new paragraph\n }\n return '</p><p>'; // Normal paragraph break\n });\n html = '<p>' + html + '</p>';\n }\n \n // Clean up empty paragraphs and unwrap block elements\n const cleanupPatterns = [\n [/<p><\\/p>/g, ''],\n [/<p>(<h[1-6][^>]*>)/g, '$1'],\n [/(<\\/h[1-6]>)<\\/p>/g, '$1'],\n [/<p>(<blockquote[^>]*>)/g, '$1'],\n [/(<\\/blockquote>)<\\/p>/g, '$1'],\n [/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1'],\n [/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1'],\n [/<p>(<hr[^>]*>)<\\/p>/g, '$1'],\n [/<p>(<table[^>]*>)/g, '$1'],\n [/(<\\/table>)<\\/p>/g, '$1'],\n [/<p>(<pre[^>]*>)/g, '$1'],\n [/(<\\/pre>)<\\/p>/g, '$1'],\n [new RegExp(`<p>(${PLACEHOLDER_CB}\\\\d+§)<\\/p>`, 'g'), '$1']\n ];\n \n cleanupPatterns.forEach(([pattern, replacement]) => {\n html = html.replace(pattern, replacement);\n });\n \n // Fix orphaned closing </p> tags after block elements\n // When a paragraph follows a block element, ensure it has opening <p>\n html = html.replace(/(<\\/(?:h[1-6]|blockquote|ul|ol|table|pre|hr)>)\\n([^<])/g, '$1\\n<p>$2');\n \n // Phase 4: Restore code blocks and inline code\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n let replacement;\n \n if (block.custom && fence_plugin && fence_plugin.render) {\n // Use custom fence plugin (v1.1.0: object format with render function)\n replacement = fence_plugin.render(block.code, block.lang);\n \n // If plugin returns undefined, fall back to default rendering\n if (replacement === undefined) {\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n const langAttr = bidirectional && block.lang ? ` data-qd-lang=\"${escapeHtml(block.lang)}\"` : '';\n const fenceAttr = bidirectional ? ` data-qd-fence=\"${escapeHtml(block.fence)}\"` : '';\n replacement = `<pre${getAttr('pre')}${fenceAttr}${langAttr}><code${codeAttr}>${escapeHtml(block.code)}</code></pre>`;\n } else if (bidirectional) {\n // If bidirectional and plugin provided HTML, add data attributes for roundtrip\n replacement = replacement.replace(/^<(\\w+)/, \n `<$1 data-qd-fence=\"${escapeHtml(block.fence)}\" data-qd-lang=\"${escapeHtml(block.lang)}\" data-qd-source=\"${escapeHtml(block.code)}\"`);\n }\n } else {\n // Default rendering\n const langClass = !inline_styles && block.lang ? ` class=\"language-${block.lang}\"` : '';\n const codeAttr = inline_styles ? getAttr('code') : langClass;\n const langAttr = bidirectional && block.lang ? ` data-qd-lang=\"${escapeHtml(block.lang)}\"` : '';\n const fenceAttr = bidirectional ? ` data-qd-fence=\"${escapeHtml(block.fence)}\"` : '';\n replacement = `<pre${getAttr('pre')}${fenceAttr}${langAttr}><code${codeAttr}>${block.code}</code></pre>`;\n }\n \n const placeholder = `${PLACEHOLDER_CB}${i}§`;\n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline code\n inlineCodes.forEach((code, i) => {\n const placeholder = `${PLACEHOLDER_IC}${i}§`;\n html = html.replace(placeholder, `<code${getAttr('code')}${dataQd('`')}>${code}</code>`);\n });\n \n return html.trim();\n}\n\n/**\n * Process inline markdown formatting\n */\nfunction processInlineMarkdown(text, getAttr) {\n \n // Process inline formatting patterns\n const patterns = [\n [/\\*\\*(.+?)\\*\\*/g, 'strong'],\n [/__(.+?)__/g, 'strong'],\n [/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, 'em'],\n [/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, 'em'],\n [/~~(.+?)~~/g, 'del'],\n [/`([^`]+)`/g, 'code']\n ];\n \n patterns.forEach(([pattern, tag]) => {\n text = text.replace(pattern, `<${tag}${getAttr(tag)}>$1</${tag}>`);\n });\n \n return text;\n}\n\n/**\n * Process markdown tables\n */\nfunction processTable(text, getAttr) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Check if this line looks like a table row (with or without trailing |)\n if (line.includes('|') && (line.startsWith('|') || /[^\\\\|]/.test(line))) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n // Not a table line\n if (inTable) {\n // Process the accumulated table\n const tableHtml = buildTable(tableLines, getAttr);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n // Not a valid table, restore original lines\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n // Handle table at end of text\n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTable(tableLines, getAttr);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n/**\n * Build an HTML table from markdown table lines\n */\nfunction buildTable(lines, getAttr) {\n \n if (lines.length < 2) return null;\n \n // Check for separator line (second line should be the separator)\n let separatorIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n // Support separator with or without leading/trailing pipes\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n const headerLines = lines.slice(0, separatorIndex);\n const bodyLines = lines.slice(separatorIndex + 1);\n \n // Parse alignment from separator\n const separator = lines[separatorIndex];\n // Handle pipes at start/end or not\n const separatorCells = separator.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n const alignments = separatorCells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n \n let html = `<table${getAttr('table')}>\\n`;\n \n // Build header\n // Note: headerLines will always have length > 0 since separatorIndex starts from 1\n html += `<thead${getAttr('thead')}>\\n`;\n headerLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), getAttr);\n html += `<th${getAttr('th', alignStyle)}>${processedCell}</th>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</thead>\\n';\n \n // Build body\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr')}>\\n`;\n // Handle pipes at start/end or not\n const cells = line.trim().replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n const processedCell = processInlineMarkdown(cell.trim(), getAttr);\n html += `<td${getAttr('td', alignStyle)}>${processedCell}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Process markdown lists (ordered and unordered)\n */\nfunction processLists(text, getAttr, inline_styles, bidirectional) {\n \n const lines = text.split('\\n');\n const result = [];\n let listStack = []; // Track nested lists\n \n // Helper to escape HTML for data-qd attributes\n const escapeHtml = (text) => text.replace(/[&<>\"']/g, m => ({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''})[m]);\n const dataQd = bidirectional ? (marker) => ` data-qd=\"${escapeHtml(marker)}\"` : () => '';\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n \n // Check for task list items\n let listItemContent = content;\n let taskListClass = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n const checkboxAttr = inline_styles \n ? ' style=\"margin-right:.5em\"' \n : ` class=\"${CLASS_PREFIX}task-checkbox\"`;\n listItemContent = `<input type=\"checkbox\"${checkboxAttr}${isChecked ? ' checked' : ''} disabled> ${taskContent}`;\n taskListClass = inline_styles ? ' style=\"list-style:none\"' : ` class=\"${CLASS_PREFIX}task-item\"`;\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n // Need to open a new list\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n } else if (listStack.length === level + 1) {\n // Check if we need to switch list type\n const currentList = listStack[listStack.length - 1];\n if (currentList.type !== listType) {\n result.push(`</${currentList.type}>`);\n listStack.pop();\n listStack.push({ type: listType, level });\n result.push(`<${listType}${getAttr(listType)}>`);\n }\n }\n \n const liAttr = taskListClass || getAttr('li');\n result.push(`<li${liAttr}${dataQd(marker)}>${listItemContent}</li>`);\n } else {\n // Not a list item, close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close any remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n/**\n * Emit CSS styles for quikdown elements\n * @param {string} prefix - Optional class prefix (default: 'quikdown-')\n * @param {string} theme - Optional theme: 'light' (default) or 'dark'\n * @returns {string} CSS string with quikdown styles\n */\nquikdown.emitStyles = function(prefix = 'quikdown-', theme = 'light') {\n const styles = QUIKDOWN_STYLES;\n \n // Define theme color overrides\n const themeOverrides = {\n dark: {\n '#f4f4f4': '#2a2a2a', // pre background\n '#f0f0f0': '#2a2a2a', // code background\n '#f2f2f2': '#2a2a2a', // th background\n '#ddd': '#3a3a3a', // borders\n '#06c': '#6db3f2', // links\n _textColor: '#e0e0e0'\n },\n light: {\n _textColor: '#333' // Explicit text color for light theme\n }\n };\n \n let css = '';\n for (const [tag, style] of Object.entries(styles)) {\n let themedStyle = style;\n \n // Apply theme overrides if dark theme\n if (theme === 'dark' && themeOverrides.dark) {\n // Replace colors\n for (const [oldColor, newColor] of Object.entries(themeOverrides.dark)) {\n if (!oldColor.startsWith('_')) {\n themedStyle = themedStyle.replace(new RegExp(oldColor, 'g'), newColor);\n }\n }\n \n // Add text color for certain elements in dark theme\n const needsTextColor = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'td', 'li', 'blockquote'];\n if (needsTextColor.includes(tag)) {\n themedStyle += `;color:${themeOverrides.dark._textColor}`;\n }\n } else if (theme === 'light' && themeOverrides.light) {\n // Add explicit text color for light theme elements too\n const needsTextColor = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'td', 'li', 'blockquote'];\n if (needsTextColor.includes(tag)) {\n themedStyle += `;color:${themeOverrides.light._textColor}`;\n }\n }\n \n css += `.${prefix}${tag} { ${themedStyle} }\\n`;\n }\n \n return css;\n};\n\n/**\n * Configure quikdown with options and return a function\n * @param {Object} options - Configuration options\n * @returns {Function} Configured quikdown function\n */\nquikdown.configure = function(options) {\n return function(markdown) {\n return quikdown(markdown, options);\n };\n};\n\n/**\n * Version information\n */\nquikdown.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown;\n}\n\n// For browser global\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown = quikdown;\n}\n\n/**\n * quikdown_bd - Bidirectional markdown/HTML converter\n * Extends core quikdown with HTML→Markdown conversion\n * \n * Uses data-qd attributes to preserve original markdown syntax\n * Enables HTML→Markdown conversion for quikdown-generated HTML\n */\n\n\n/**\n * Create bidirectional version by extending quikdown\n * This wraps quikdown and adds the toMarkdown method\n */\nfunction quikdown_bd(markdown, options = {}) {\n // Use core quikdown with bidirectional flag to add data-qd attributes\n return quikdown(markdown, { ...options, bidirectional: true });\n}\n\n// Copy all properties and methods from quikdown (including version)\nObject.keys(quikdown).forEach(key => {\n quikdown_bd[key] = quikdown[key];\n});\n\n// Add the toMarkdown method for HTML→Markdown conversion\nquikdown_bd.toMarkdown = function(htmlOrElement, options = {}) {\n // Accept either HTML string or DOM element\n let container;\n if (typeof htmlOrElement === 'string') {\n container = document.createElement('div');\n container.innerHTML = htmlOrElement;\n } else if (htmlOrElement instanceof Element) {\n /* istanbul ignore next - browser-only code path, not testable in jsdom */\n container = htmlOrElement;\n } else {\n return '';\n }\n \n // Walk the DOM tree and reconstruct markdown\n function walkNode(node, parentContext = {}) {\n if (node.nodeType === Node.TEXT_NODE) {\n // Return text content, preserving whitespace where needed\n return node.textContent;\n }\n \n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n \n const tag = node.tagName.toLowerCase();\n const dataQd = node.getAttribute('data-qd');\n \n // Process children with context\n let childContent = '';\n for (let child of node.childNodes) {\n childContent += walkNode(child, { parentTag: tag, ...parentContext });\n }\n \n // Determine markdown based on element and attributes\n switch (tag) {\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n const level = parseInt(tag[1]);\n const prefix = dataQd || '#'.repeat(level);\n return `${prefix} ${childContent.trim()}\\n\\n`;\n \n case 'strong':\n case 'b':\n if (!childContent) return ''; // Don't add markers for empty content\n const boldMarker = dataQd || '**';\n return `${boldMarker}${childContent}${boldMarker}`;\n \n case 'em':\n case 'i':\n if (!childContent) return ''; // Don't add markers for empty content\n const emMarker = dataQd || '*';\n return `${emMarker}${childContent}${emMarker}`;\n \n case 'del':\n case 's':\n case 'strike':\n if (!childContent) return ''; // Don't add markers for empty content\n const delMarker = dataQd || '~~';\n return `${delMarker}${childContent}${delMarker}`;\n \n case 'code':\n // Note: code inside pre is handled directly by the pre case using querySelector\n if (!childContent) return ''; // Don't add markers for empty content\n const codeMarker = dataQd || '`';\n return `${codeMarker}${childContent}${codeMarker}`;\n \n case 'pre':\n const fence = node.getAttribute('data-qd-fence') || dataQd || '```';\n const lang = node.getAttribute('data-qd-lang') || '';\n \n // Check if this was created by a fence plugin with reverse handler\n if (options.fence_plugin && options.fence_plugin.reverse && lang) {\n try {\n const result = options.fence_plugin.reverse(node);\n if (result && result.content) {\n const fenceMarker = result.fence || fence;\n const langStr = result.lang || lang;\n return `${fenceMarker}${langStr}\\n${result.content}\\n${fenceMarker}\\n\\n`;\n }\n } catch (err) {\n console.warn('Fence reverse handler error:', err);\n // Fall through to default handling\n }\n }\n \n // Fallback: use data-qd-source if available\n const source = node.getAttribute('data-qd-source');\n if (source) {\n return `${fence}${lang}\\n${source}\\n${fence}\\n\\n`;\n }\n \n // Final fallback: extract text content\n const codeEl = node.querySelector('code');\n const codeContent = codeEl ? codeEl.textContent : childContent;\n return `${fence}${lang}\\n${codeContent.trimEnd()}\\n${fence}\\n\\n`;\n \n case 'blockquote':\n const quoteMarker = dataQd || '>';\n const lines = childContent.trim().split('\\n');\n return lines.map(line => `${quoteMarker} ${line}`).join('\\n') + '\\n\\n';\n \n case 'hr':\n const hrMarker = dataQd || '---';\n return `${hrMarker}\\n\\n`;\n \n case 'br':\n const brMarker = dataQd || ' ';\n return `${brMarker}\\n`;\n \n case 'a':\n const linkText = node.getAttribute('data-qd-text') || childContent.trim();\n const href = node.getAttribute('href') || '';\n // Check for autolinks\n if (linkText === href && !dataQd) {\n return `<${href}>`;\n }\n return `[${linkText}](${href})`;\n \n case 'img':\n const alt = node.getAttribute('data-qd-alt') || node.getAttribute('alt') || '';\n const src = node.getAttribute('data-qd-src') || node.getAttribute('src') || '';\n const imgMarker = dataQd || '!';\n return `${imgMarker}[${alt}](${src})`;\n \n case 'ul':\n case 'ol':\n return walkList(node, tag === 'ol') + '\\n';\n \n case 'li':\n // Handled by list processor\n return childContent;\n \n case 'table':\n return walkTable(node) + '\\n\\n';\n \n case 'p':\n // Check if it's actually a paragraph or just a wrapper\n if (childContent.trim()) {\n // Check if paragraph ends with a line that's just whitespace\n // This indicates an intentional blank line before the next element\n const lines = childContent.split('\\n');\n let content = childContent.trim();\n \n // If the last line(s) are just whitespace, preserve one blank line\n if (lines.length > 1) {\n let trailingBlankLines = 0;\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].trim() === '') {\n trailingBlankLines++;\n } else {\n break;\n }\n }\n if (trailingBlankLines > 0) {\n // Add a line with just a space, followed by single newline\n // The \\n\\n will be added below for paragraph separation\n content = content + '\\n ';\n // Only add one newline since we're preserving the space line\n return content + '\\n';\n }\n }\n \n return content + '\\n\\n';\n }\n return '';\n \n case 'div':\n // Check if this was created by a fence plugin with reverse handler\n const divLang = node.getAttribute('data-qd-lang');\n const divFence = node.getAttribute('data-qd-fence');\n \n if (divLang && options.fence_plugin && options.fence_plugin.reverse) {\n try {\n const result = options.fence_plugin.reverse(node);\n if (result && result.content) {\n const fenceMarker = result.fence || divFence || '```';\n const langStr = result.lang || divLang;\n return `${fenceMarker}${langStr}\\n${result.content}\\n${fenceMarker}\\n\\n`;\n }\n } catch (err) {\n console.warn('Fence reverse handler error:', err);\n // Fall through to default handling\n }\n }\n \n // Fallback: use data-qd-source if available\n const divSource = node.getAttribute('data-qd-source');\n if (divSource && divFence) {\n return `${divFence}${divLang || ''}\\n${divSource}\\n${divFence}\\n\\n`;\n }\n \n // Check if it's a mermaid container\n if (node.classList && node.classList.contains('mermaid-container')) {\n const fence = node.getAttribute('data-qd-fence') || '```';\n const lang = node.getAttribute('data-qd-lang') || 'mermaid';\n \n // First check for data-qd-source attribute on the container\n const source = node.getAttribute('data-qd-source');\n if (source) {\n // Decode HTML entities from the attribute (mainly ")\n const temp = document.createElement('textarea');\n temp.innerHTML = source;\n const code = temp.value;\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n \n // Check for source on the pre.mermaid element\n const mermaidPre = node.querySelector('pre.mermaid');\n if (mermaidPre) {\n const preSource = mermaidPre.getAttribute('data-qd-source');\n if (preSource) {\n const temp = document.createElement('textarea');\n temp.innerHTML = preSource;\n const code = temp.value;\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n }\n \n // Fallback: Look for the legacy .mermaid-source element\n const sourceElement = node.querySelector('.mermaid-source');\n if (sourceElement) {\n // Decode HTML entities\n const temp = document.createElement('div');\n temp.innerHTML = sourceElement.innerHTML;\n const code = temp.textContent;\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n \n // Final fallback: try to extract from the mermaid element (unreliable after rendering)\n const mermaidElement = node.querySelector('.mermaid');\n if (mermaidElement && mermaidElement.textContent.includes('graph')) {\n return `${fence}${lang}\\n${mermaidElement.textContent.trim()}\\n${fence}\\n\\n`;\n }\n }\n // Check if it's a standalone mermaid diagram (legacy)\n if (node.classList && node.classList.contains('mermaid')) {\n const fence = node.getAttribute('data-qd-fence') || '```';\n const lang = node.getAttribute('data-qd-lang') || 'mermaid';\n const code = node.textContent.trim();\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n // Pass through other divs\n return childContent;\n \n case 'span':\n // Pass through container elements\n return childContent;\n \n default:\n return childContent;\n }\n }\n \n // Walk list elements\n function walkList(listNode, isOrdered, depth = 0) {\n let result = '';\n let index = 1;\n const indent = ' '.repeat(depth);\n \n for (let child of listNode.children) {\n if (child.tagName !== 'LI') continue;\n \n const dataQd = child.getAttribute('data-qd');\n let marker = dataQd || (isOrdered ? `${index}.` : '-');\n \n // Check for task list checkbox\n const checkbox = child.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n const checked = checkbox.checked ? 'x' : ' ';\n marker = '-';\n // Get text without the checkbox\n let text = '';\n for (let node of child.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent;\n } else if (node.tagName && node.tagName !== 'INPUT') {\n text += walkNode(node);\n }\n }\n result += `${indent}${marker} [${checked}] ${text.trim()}\\n`;\n } else {\n let itemContent = '';\n \n for (let node of child.childNodes) {\n if (node.tagName === 'UL' || node.tagName === 'OL') {\n itemContent += walkList(node, node.tagName === 'OL', depth + 1);\n } else {\n itemContent += walkNode(node);\n }\n }\n \n result += `${indent}${marker} ${itemContent.trim()}\\n`;\n }\n \n index++;\n }\n \n return result;\n }\n \n // Walk table elements\n function walkTable(table) {\n let result = '';\n const alignData = table.getAttribute('data-qd-align');\n const alignments = alignData ? alignData.split(',') : [];\n \n // Process header\n const thead = table.querySelector('thead');\n if (thead) {\n const headerRow = thead.querySelector('tr');\n if (headerRow) {\n const headers = [];\n for (let th of headerRow.querySelectorAll('th')) {\n headers.push(th.textContent.trim());\n }\n result += '| ' + headers.join(' | ') + ' |\\n';\n \n // Add separator with alignment\n const separators = headers.map((_, i) => {\n const align = alignments[i] || 'left';\n if (align === 'center') return ':---:';\n if (align === 'right') return '---:';\n return '---';\n });\n result += '| ' + separators.join(' | ') + ' |\\n';\n }\n }\n \n // Process body\n const tbody = table.querySelector('tbody');\n if (tbody) {\n for (let row of tbody.querySelectorAll('tr')) {\n const cells = [];\n for (let td of row.querySelectorAll('td')) {\n cells.push(td.textContent.trim());\n }\n if (cells.length > 0) {\n result += '| ' + cells.join(' | ') + ' |\\n';\n }\n }\n }\n \n return result.trim();\n }\n \n // Process the DOM tree\n let markdown = walkNode(container);\n \n // Clean up\n markdown = markdown.replace(/\\n{3,}/g, '\\n\\n'); // Remove excessive newlines\n markdown = markdown.trim();\n \n return markdown;\n};\n\n// Override the configure method to return a bidirectional version\nquikdown_bd.configure = function(options) {\n return function(markdown) {\n return quikdown_bd(markdown, options);\n };\n};\n\n// Set version\n// Version is already copied from quikdown via Object.keys loop\n\n// Export for both module and browser\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_bd;\n}\n\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown_bd = quikdown_bd;\n}\n\nexport { quikdown_bd as default };\n","import quikchat from './quikchat.js';\nimport quikdownBD from 'quikdown/bd';\n\n// CDN URLs for dynamic loading (same as quikdown editor uses)\nconst CDN = {\n hljs: 'https://unpkg.com/@highlightjs/cdn-assets/highlight.min.js',\n hljsCSS: 'https://unpkg.com/@highlightjs/cdn-assets/styles/github.min.css',\n hljsCSSdark:'https://unpkg.com/@highlightjs/cdn-assets/styles/github-dark.min.css',\n mathjax: 'https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js',\n mermaid: 'https://unpkg.com/mermaid/dist/mermaid.min.js',\n leaflet: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js',\n leafletCSS: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css',\n dompurify: 'https://unpkg.com/dompurify/dist/purify.min.js',\n};\n\n// Load a script from CDN (cached — only loads once)\nconst _loaded = {};\nfunction loadScript(src) {\n if (_loaded[src]) return _loaded[src];\n _loaded[src] = new Promise((resolve, reject) => {\n const s = document.createElement('script');\n s.src = src;\n s.onload = () => resolve(true);\n s.onerror = () => { _loaded[src] = null; reject(new Error('Failed to load: ' + src)); };\n document.head.appendChild(s);\n });\n return _loaded[src];\n}\nfunction loadCSS(href) {\n if (_loaded[href]) return _loaded[href];\n _loaded[href] = new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n link.onload = () => resolve(true);\n document.head.appendChild(link);\n setTimeout(resolve, 1000); // CSS doesn't always fire onload\n });\n return _loaded[href];\n}\n\n/**\n * Process fence blocks rendered by quikdown/bd.\n * Detects code blocks with language tags and renders them with the appropriate library.\n * Libraries are loaded from CDN on first use.\n */\nasync function postProcessMessage(el) {\n if (!el) return;\n\n // --- Syntax highlighting (highlight.js) ---\n const codeBlocks = el.querySelectorAll('pre.quikdown-pre code[class*=\"language-\"]');\n if (codeBlocks.length > 0) {\n const langSet = new Set();\n codeBlocks.forEach(cb => {\n const match = cb.className.match(/language-(\\S+)/);\n if (match) langSet.add(match[1]);\n });\n\n // Skip languages handled by other renderers\n const specialLangs = new Set(['svg', 'html', 'math', 'tex', 'latex', 'katex', 'mermaid', 'geojson', 'csv', 'tsv', 'psv', 'json', 'json5', 'stl']);\n const needsHljs = [...langSet].some(l => !specialLangs.has(l));\n\n if (needsHljs && !window.hljs) {\n try {\n await Promise.all([loadScript(CDN.hljs), loadCSS(CDN.hljsCSS)]);\n } catch (_e) { /* continue without highlighting */ }\n }\n if (window.hljs) {\n codeBlocks.forEach(cb => {\n const match = cb.className.match(/language-(\\S+)/);\n if (match && !specialLangs.has(match[1]) && !cb.classList.contains('hljs')) {\n window.hljs.highlightElement(cb);\n }\n });\n }\n }\n\n // --- SVG (inline, no external lib) ---\n const svgBlocks = el.querySelectorAll('pre.quikdown-pre[data-qd-lang=\"svg\"], pre.quikdown-pre code.language-svg');\n svgBlocks.forEach(block => {\n const pre = block.closest('pre') || block;\n const code = pre.querySelector('code') || pre;\n const svgSource = code.textContent;\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgSource, 'image/svg+xml');\n if (!doc.querySelector('parsererror')) {\n const svg = doc.documentElement;\n // Sanitize: remove scripts and event handlers\n svg.querySelectorAll('script').forEach(s => s.remove());\n const walker = document.createTreeWalker(svg, NodeFilter.SHOW_ELEMENT);\n let node = walker.nextNode();\n while (node) {\n for (let i = node.attributes.length - 1; i >= 0; i--) {\n const attr = node.attributes[i];\n if (attr.name.startsWith('on') || attr.value.includes('javascript:')) {\n node.removeAttribute(attr.name);\n }\n }\n node = walker.nextNode();\n }\n const container = document.createElement('div');\n container.className = 'qde-svg-container';\n container.innerHTML = new XMLSerializer().serializeToString(svg);\n pre.replaceWith(container);\n }\n } catch (_e) { /* leave as code block */ }\n });\n\n // --- HTML (inline, sanitized with DOMPurify) ---\n const htmlBlocks = el.querySelectorAll('pre.quikdown-pre code.language-html');\n for (const block of htmlBlocks) {\n const pre = block.closest('pre');\n if (!pre) continue;\n // Only render if the code is likely meant as rendered HTML (short snippets)\n // Skip if it looks like documentation (contains doctype, html, head tags)\n const src = block.textContent;\n if (src.match(/<(!DOCTYPE|html|head|body)/i)) continue;\n\n if (!window.DOMPurify) {\n try { await loadScript(CDN.dompurify); } catch (_e) { continue; }\n }\n if (window.DOMPurify) {\n const container = document.createElement('div');\n container.className = 'qde-html-container';\n container.innerHTML = window.DOMPurify.sanitize(src);\n pre.replaceWith(container);\n }\n }\n\n // --- Math (MathJax) ---\n // Look for math fences and inline math ($...$, $$...$$)\n const mathBlocks = el.querySelectorAll('pre.quikdown-pre code.language-math, pre.quikdown-pre code.language-tex, pre.quikdown-pre code.language-latex, pre.quikdown-pre code.language-katex');\n const hasInlineMath = el.innerHTML.match(/\\$\\$[\\s\\S]+?\\$\\$|\\$[^$\\n]+?\\$/);\n\n if (mathBlocks.length > 0 || hasInlineMath) {\n if (!window.MathJax || !window.MathJax.typesetPromise) {\n if (!window.mathJaxLoading) {\n window.mathJaxLoading = true;\n window.MathJax = {\n loader: { load: ['input/tex', 'output/svg'] },\n tex: {\n inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],\n displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],\n processEscapes: true,\n processEnvironments: true\n },\n options: { renderActions: { addMenu: [] } },\n svg: { fontCache: 'none' },\n startup: { typeset: false }\n };\n try { await loadScript(CDN.mathjax); } catch (_e) { /* continue */ }\n window.mathJaxLoading = false;\n }\n }\n\n // Convert math fence blocks to divs MathJax can process\n mathBlocks.forEach(block => {\n const pre = block.closest('pre');\n if (!pre) return;\n const mathDiv = document.createElement('div');\n mathDiv.className = 'math-display';\n mathDiv.textContent = '$$' + block.textContent + '$$';\n pre.replaceWith(mathDiv);\n });\n\n if (window.MathJax && window.MathJax.typesetPromise) {\n try { await window.MathJax.typesetPromise([el]); } catch (_e) { /* continue */ }\n }\n }\n\n // --- Mermaid diagrams ---\n const mermaidBlocks = el.querySelectorAll('pre.quikdown-pre code.language-mermaid');\n if (mermaidBlocks.length > 0) {\n if (!window.mermaid) {\n try {\n await loadScript(CDN.mermaid);\n if (window.mermaid) {\n window.mermaid.initialize({ startOnLoad: false, theme: 'default' });\n }\n } catch (_e) { /* continue without mermaid */ }\n }\n if (window.mermaid) {\n for (const block of mermaidBlocks) {\n const pre = block.closest('pre');\n if (!pre) continue;\n const container = document.createElement('div');\n container.className = 'qde-mermaid-container';\n const mermaidId = 'mermaid-' + Math.random().toString(36).substring(2, 9);\n try {\n const { svg } = await window.mermaid.render(mermaidId, block.textContent);\n container.innerHTML = svg;\n pre.replaceWith(container);\n } catch (_e) { /* leave as code block */ }\n }\n }\n }\n\n // --- GeoJSON / Leaflet maps ---\n const geoBlocks = el.querySelectorAll('pre.quikdown-pre code.language-geojson');\n if (geoBlocks.length > 0) {\n if (!window.L) {\n try { await Promise.all([loadScript(CDN.leaflet), loadCSS(CDN.leafletCSS)]); } catch (_e) { /* continue */ }\n }\n if (window.L) {\n for (const block of geoBlocks) {\n const pre = block.closest('pre');\n if (!pre) continue;\n try {\n const geojson = JSON.parse(block.textContent);\n const container = document.createElement('div');\n container.className = 'qde-geojson-container';\n container.style.cssText = 'height: 300px; width: 100%; border-radius: 4px;';\n pre.replaceWith(container);\n const map = window.L.map(container);\n window.L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap'\n }).addTo(map);\n const layer = window.L.geoJSON(geojson).addTo(map);\n map.fitBounds(layer.getBounds());\n } catch (_e) { /* leave as code block */ }\n }\n }\n }\n\n // --- CSV / TSV / PSV tables ---\n const tableBlocks = el.querySelectorAll('pre.quikdown-pre code.language-csv, pre.quikdown-pre code.language-tsv, pre.quikdown-pre code.language-psv');\n tableBlocks.forEach(block => {\n const pre = block.closest('pre');\n if (!pre) return;\n const lang = block.className.match(/language-(csv|tsv|psv)/);\n if (!lang) return;\n const delim = { csv: ',', tsv: '\\t', psv: '|' }[lang[1]];\n const lines = block.textContent.trim().split('\\n');\n if (lines.length < 2) return;\n try {\n const table = document.createElement('table');\n table.className = 'quikdown-table';\n lines.forEach((line, i) => {\n const row = document.createElement('tr');\n const cells = line.split(delim).map(c => c.trim());\n cells.forEach(cell => {\n const td = document.createElement(i === 0 ? 'th' : 'td');\n td.className = i === 0 ? 'quikdown-th' : 'quikdown-td';\n td.textContent = cell;\n row.appendChild(td);\n });\n table.appendChild(row);\n });\n pre.replaceWith(table);\n } catch (_e) { /* leave as code block */ }\n });\n\n // --- JSON pretty-print ---\n const jsonBlocks = el.querySelectorAll('pre.quikdown-pre code.language-json, pre.quikdown-pre code.language-json5');\n jsonBlocks.forEach(block => {\n try {\n const obj = JSON.parse(block.textContent);\n block.textContent = JSON.stringify(obj, null, 2);\n // If hljs is loaded, re-highlight\n if (window.hljs && window.hljs.getLanguage('json')) {\n window.hljs.highlightElement(block);\n }\n } catch (_e) { /* not valid JSON, leave as is */ }\n });\n}\n\n\n/**\n * quikchat-md-full: batteries-included build.\n * Uses quikdown/bd for markdown parsing, then post-processes fence blocks\n * with dynamically loaded renderers (highlight.js, MathJax, Mermaid, Leaflet, etc.).\n */\nclass quikchatMDFull extends quikchat {\n constructor(parentElement, onSend, options = {}) {\n if (!options.messageFormatter) {\n options.messageFormatter = (content) => quikdownBD(content);\n }\n super(parentElement, onSend, options);\n }\n\n // Override message methods to add post-processing\n messageAddNew(content = \"\", userString = \"user\", align = \"right\", role = \"user\") {\n const id = super.messageAddNew(content, userString, align, role);\n const el = this.messageGetDOMObject(id);\n if (el) {\n postProcessMessage(el.querySelector('.quikchat-message-content'));\n }\n return id;\n }\n\n messageAddFull(input) {\n const id = super.messageAddFull(input);\n const el = this.messageGetDOMObject(id);\n if (el) {\n postProcessMessage(el.querySelector('.quikchat-message-content'));\n }\n return id;\n }\n\n messageAppendContent(n, content) {\n const result = super.messageAppendContent(n, content);\n if (result) {\n const el = this.messageGetDOMObject(n);\n if (el) {\n postProcessMessage(el.querySelector('.quikchat-message-content'));\n }\n }\n return result;\n }\n\n messageReplaceContent(n, content) {\n const result = super.messageReplaceContent(n, content);\n if (result) {\n const el = this.messageGetDOMObject(n);\n if (el) {\n postProcessMessage(el.querySelector('.quikchat-message-content'));\n }\n }\n return result;\n }\n\n destroy() {\n // No hidden container to clean up in this approach\n }\n}\n\n// Expose quikdown bd and post-processor for direct access\nquikchatMDFull.quikdown = quikdownBD;\nquikchatMDFull.postProcessMessage = postProcessMessage;\n\nexport default quikchatMDFull;\n"],"names":["quikchat","_createClass","parentElement","onSend","arguments","length","undefined","options","_classCallCheck","meta","_objectSpread","theme","trackHistory","showTimestamps","titleArea","title","show","align","messagesArea","alternating","document","querySelector","this","_parentElement","_theme","_onSend","_messageFormatter","messageFormatter","_sanitize","sanitize","_createWidget","titleAreaSetContents","titleAreaShow","titleAreaHide","messagesAreaAlternateColors","messagesAreaShowTimestamps","direction","setDirection","_attachEventListeners","_historyLimit","_history","key","value","widgetHTML","concat","innerHTML","_chatWidget","_titleArea","_messagesWrapper","_messagesArea","_scrollBottomBtn","_inputArea","_textEntry","_sendButton","msgid","_this","addEventListener","text","trim","event","shiftKey","keyCode","preventDefault","_autoGrowTextarea","_this$_messagesArea","scrollTop","scrollHeight","clientHeight","userScrolledUp","_updateScrollBottomBtn","scrollToBottom","ctrlKey","ResizeObserver","_resizeObserver","_handleContainerResize","observe","callback","_onMessageAdded","_onMessageAppend","_onMessageReplace","_onMessageDelete","style","display","textAlign","inputAreaShow","inputAreaHide","enabled","disabled","textContent","dir","d","setAttribute","classList","add","remove","getAttribute","el","height","maxHeight","parseInt","getComputedStyle","getPropertyValue","Math","min","overflowY","isoString","Date","h","getHours","String","getMinutes","padStart","contains","toggle","str","div","createElement","content","_escapeHTML","alt","input","userString","role","userID","messageDiv","msgidClass","children","visible","tags","Array","isArray","slice","userDiv","contentDiv","_processContent","timestamp","toISOString","timestampSpan","_formatTimestamp","appendChild","updatedtime","push","shift","messageAddFull","n","success","removeChild","_error","splice","findIndex","item","msg","filter","msgEl","messageGetDOMObject","find","entry","current","messageGetVisible","messageSetVisible","tag","_step","count","_iterator","_createForOfIteratorHelper","s","done","includes","err","e","f","formatter","m","map","data","_step2","_iterator2","newTheme","get","version","license","url","numChars","startSpot","startWithCapitalLetter","loremText","floor","random","test","l","substring","toUpperCase","CLASS_PREFIX","PLACEHOLDER_CB","PLACEHOLDER_IC","ESC_MAP","QUIKDOWN_STYLES","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","th","td","hr","img","a","strong","em","del","ul","ol","li","quikdown","markdown","fence_plugin","inline_styles","bidirectional","lazy_linefeeds","getAttr","styles","additionalStyle","replace","endsWith","classAttr","createGetAttr","escapeHtml","dataQd","marker","sanitizeUrl","allowUnsafe","trimmedUrl","lowerUrl","toLowerCase","dangerousProtocols","protocol","startsWith","html","codeBlocks","inlineCodes","match","fence","lang","placeholder","langTrimmed","render","trimEnd","custom","hasReverse","reverse","lines","split","result","inTable","tableLines","i","line","tableHtml","buildTable","join","processTable","hashes","level","listStack","indent","isOrdered","listType","listItemContent","taskListClass","taskMatch","checked","taskContent","isChecked","list","pop","type","currentList","liAttr","processLists","src","sanitizedSrc","allow_unsafe_urls","altAttr","srcAttr","href","sanitizedHref","rel","textAttr","prefix","sanitizedUrl","forEach","pattern","blocks","bi","b","offset","RegExp","replacement","block","langClass","codeAttr","langAttr","fenceAttr","processInlineMarkdown","separatorIndex","headerLines","bodyLines","alignments","cell","trimmed","alignStyle","processedCell","quikdown_bd","emitStyles","themeOverrides","_textColor","css","Object","entries","themedStyle","oldColor","newColor","configure","module","exports","window","keys","toMarkdown","htmlOrElement","container","Element","walkNode","node","parentContext","nodeType","Node","TEXT_NODE","ELEMENT_NODE","tagName","childContent","child","childNodes","parentTag","repeat","boldMarker","emMarker","delMarker","codeMarker","fenceMarker","console","warn","source","codeEl","quoteMarker","linkText","walkList","alignData","thead","headerRow","headers","querySelectorAll","_","tbody","row","cells","walkTable","trailingBlankLines","divLang","divFence","divSource","temp","mermaidPre","preSource","sourceElement","mermaidElement","listNode","depth","index","checkbox","itemContent","CDN","hljs","hljsCSS","mathjax","mermaid","leaflet","leafletCSS","dompurify","_loaded","loadScript","Promise","resolve","reject","onload","onerror","Error","head","loadCSS","link","setTimeout","postProcessMessage","_x","_postProcessMessage","apply","_regenerator","_callee","langSet","specialLangs","htmlBlocks","_block2","_pre2","_container2","mathBlocks","hasInlineMath","mermaidBlocks","mermaidId","_yield$window$mermaid","svg","geoBlocks","_iterator3","_step3","_block","_pre","geojson","_container","layer","_t3","_t8","_t0","w","_context","p","Set","cb","className","_toConsumableArray","some","has","all","v","highlightElement","closest","svgSource","doc","DOMParser","parseFromString","documentElement","walker","createTreeWalker","NodeFilter","SHOW_ELEMENT","nextNode","attributes","attr","name","removeAttribute","XMLSerializer","serializeToString","replaceWith","_e","DOMPurify","MathJax","typesetPromise","mathJaxLoading","loader","load","tex","inlineMath","displayMath","processEscapes","processEnvironments","renderActions","addMenu","fontCache","startup","typeset","mathDiv","initialize","startOnLoad","toString","L","JSON","parse","cssText","tileLayer","attribution","addTo","geoJSON","fitBounds","getBounds","delim","csv","tsv","psv","c","obj","stringify","getLanguage","quikchatMDFull","quikdownBD","_callSuper","_inherits","id","_superPropGet"],"mappings":"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","x_google_ignoreList":[1]}
|