export function createSidebarPageAiMarkdownRuntime(context) { const { escapeHtml } = context; function textFromUnknown(value) { if (value == null) return ''; if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value); if (Array.isArray(value)) return value.map(textFromUnknown).filter(Boolean).join(' '); if (typeof value !== 'object') return ''; var parts = []; ['text', 'title', 'content', 'children', 'blocks', 'body'].forEach(function(key) { if (Object.prototype.hasOwnProperty.call(value, key)) { var text = textFromUnknown(value[key]); if (text) parts.push(text); } }); return parts.join(' '); } function renderPageAiMarkdownInline(text) { var html = escapeHtml(String(text || '')); var codeSpans = []; var htmlSpans = []; function stashHtml(value) { var key = '\u0000HTML' + htmlSpans.length + '\u0000'; htmlSpans.push(value); return key; } html = html.replace(/`([^`\n]+)`/g, function(_, code) { var key = '\u0000CODE' + codeSpans.length + '\u0000'; codeSpans.push('' + code + ''); return key; }); html = html.replace(/\[((?:\\.|[^\]\n])+)\]\(([^)\n]+)\)/g, function(match, label, href) { var normalizedHref = normalizePageAiMarkdownHref(href); if (!normalizedHref) return match; var citationAttr = isMnoteCitationHref(normalizedHref) ? ' data-page-ai-citation-link="true"' : ''; return stashHtml('' + unescapePageAiMarkdownLabel(label) + ''); }); html = html.replace(/(^|[\s(])((?:https?:\/\/|\/documents\/|mnote:\/\/open(?:Resource)?)[^\s<>()]+[^\s<>().,;:!?])/g, function(_, prefix, href) { var normalizedHref = normalizePageAiMarkdownHref(href); if (!normalizedHref) return prefix + href; var citationAttr = isMnoteCitationHref(normalizedHref) ? ' data-page-ai-citation-link="true"' : ''; return prefix + stashHtml('' + escapeHtml(normalizedHref) + ''); }); html = html.replace(/\*\*([^*\n]+)\*\*/g, '$1'); html = html.replace(/(^|[^*])\*([^*\n]+)\*/g, '$1$2'); codeSpans.forEach(function(value, index) { html = html.replace('\u0000CODE' + index + '\u0000', value); }); htmlSpans.forEach(function(value, index) { html = html.replace('\u0000HTML' + index + '\u0000', value); }); return html; } function normalizePageAiMarkdownHref(value) { var href = String(value || '').trim() .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, "'"); while (href.includes('&')) href = href.replace(/&/g, '&'); if (href.startsWith('<') && href.endsWith('>')) href = href.slice(1, -1).trim(); if (!href || /[\u0000-\u001f<>"']/.test(href)) return ''; var lower = href.toLowerCase(); if (lower.startsWith('javascript:') || lower.startsWith('data:') || lower.startsWith('vbscript:')) return ''; if (lower.startsWith('mnote://open')) href = normalizePageAiMnoteOpenHref(href); href = normalizePageAiLegacyCitationHref(href); if (href.startsWith('/') || href.startsWith('#')) return href; if (/^https?:\/\//i.test(href) || /^mailto:/i.test(href)) return href; return ''; } function unescapePageAiMarkdownLabel(value) { return String(value || '').replace(/\\([\\\[\]()*_`])/g, '$1'); } function normalizePageAiMnoteOpenHref(href) { try { var url = new URL(href); if (url.protocol !== 'mnote:' || (url.hostname !== 'open' && url.hostname !== 'openResource')) return href; var path = String(url.searchParams.get('path') || url.searchParams.get('resourcePath') || '').trim(); if (!path) return ''; var params = new URLSearchParams(); var rootUri = String(url.searchParams.get('rootUri') || '').trim(); if (!rootUri) { try { rootUri = new URL(window.location.href).searchParams.get('rootUri') || ''; } catch (_locationError) {} } if (rootUri) params.set('rootUri', rootUri); params.set('path', path); ['page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) { var value = String(url.searchParams.get(key) || '').trim(); if (value) params.set(key, value); }); return '/api/local-folder/files/open?' + params.toString(); } catch (_error) { return href; } } function normalizePageAiLegacyCitationHref(href) { try { var url = new URL(href, window.location.origin); var unwrappedHref = normalizePageAiSearchWrappedCitationHref(url); if (unwrappedHref) return normalizePageAiLegacyCitationHref(unwrappedHref); if (!isPageAiSameMnoteOrigin(url) && !isPageAiPortableMnoteCitationUrl(url)) return href; if (url.pathname === '/api/local-folder/files/open') return url.pathname + url.search; if (!url.pathname.startsWith('/documents/')) return href; if (isPageAiUnsafeCitationDocumentId(url)) { var fileOpenHref = normalizePageAiCitationFileOpenHref(url); if (fileOpenHref) return fileOpenHref; } var decodedHash = ''; try { decodedHash = decodeURIComponent(url.hash || ''); } catch (_decodeError) { decodedHash = url.hash || ''; } var marker = '#resource-tab-'; var markerIndex = decodedHash.indexOf(marker); if (markerIndex < 0 || url.searchParams.get('resourceTab')) { return url.pathname + url.search + url.hash; } var identity = decodedHash.slice(markerIndex + marker.length).replace(/^#+/, '').trim(); if (!identity.startsWith('resource:file:')) return url.pathname + url.search + url.hash; url.searchParams.set('resourceTab', identity); if (!url.searchParams.get('sourceKind')) url.searchParams.set('sourceKind', 'local_folder'); var rootUri = String(url.searchParams.get('rootUri') || '').trim(); var prefix = 'resource:file:' + rootUri + ':'; if (rootUri && identity.startsWith(prefix) && !url.searchParams.get('resourcePath')) { url.searchParams.set('resourcePath', identity.slice(prefix.length).replace(/^\/+/, '')); } url.hash = ''; return url.pathname + url.search; } catch (_error) { return href; } } function normalizePageAiSearchWrappedCitationHref(url) { var raw = ''; ['wd', 'q', 'query'].some(function(key) { raw = String(url.searchParams.get(key) || '').trim(); return Boolean(raw); }); if (!raw) return ''; if (/^documents\//i.test(raw)) raw = '/' + raw; if (!/^\/documents\//i.test(raw) && !/^https?:\/\/[^/]+\/documents\//i.test(raw) && !/^mnote:\/\/open/i.test(raw)) return ''; if (/^mnote:\/\/open/i.test(raw)) return normalizePageAiMnoteOpenHref(raw); var nested = new URL(raw, window.location.origin); if (!nested.pathname.startsWith('/documents/')) return ''; ['sourceKind', 'rootUri', 'workspaceId', 'resourceTab', 'resourcePath', 'page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) { if (nested.searchParams.get(key)) return; var value = String(url.searchParams.get(key) || '').trim(); if (value) nested.searchParams.set(key, value); }); return nested.pathname + nested.search; } function normalizePageAiCitationFileOpenHref(url) { var rootUri = String(url.searchParams.get('rootUri') || '').trim(); var path = String(url.searchParams.get('resourcePath') || '').trim(); if (!rootUri || !path) return ''; var params = new URLSearchParams(); params.set('rootUri', rootUri); params.set('path', path); ['page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) { var value = String(url.searchParams.get(key) || '').trim(); if (value) params.set(key, value); }); return '/api/local-folder/files/open?' + params.toString(); } function isPageAiUnsafeCitationDocumentId(url) { try { var raw = String(url.pathname || '').replace(/^\/documents\//, '').split('/')[0] || ''; if (!raw) return false; var decoded = decodeURIComponent(raw); return decoded.indexOf('%') >= 0 || decoded.indexOf('\uFFFD') >= 0; } catch (_error) { return true; } } function isPageAiPortableMnoteCitationUrl(url) { try { if (url.pathname === '/api/local-folder/files/open') { return Boolean(String(url.searchParams.get('rootUri') || '').trim()) && Boolean(String(url.searchParams.get('path') || '').trim()); } if (!url.pathname.startsWith('/documents/')) return false; var resourceTab = String(url.searchParams.get('resourceTab') || '').trim(); return String(url.searchParams.get('sourceKind') || '').trim() === 'local_folder' || Boolean(String(url.searchParams.get('rootUri') || '').trim()) || Boolean(String(url.searchParams.get('resourcePath') || '').trim()) || resourceTab.startsWith('resource:file:'); } catch (_error) { return false; } } function isPageAiMarkdownTableDivider(line) { var cells = splitPageAiMarkdownTableRow(line); if (cells.length < 2) return false; return cells.every(function(cell) { return /^:?-{3,}:?$/.test(cell.trim()); }); } function splitPageAiMarkdownTableRow(line) { var text = String(line || '').trim(); if (!text.includes('|')) return []; if (text.startsWith('|')) text = text.slice(1); if (text.endsWith('|')) text = text.slice(0, -1); return text.split('|').map(function(cell) { return cell.trim(); }); } function renderPageAiMarkdownTable(lines, startIndex) { if (startIndex + 1 >= lines.length || !isPageAiMarkdownTableDivider(lines[startIndex + 1])) return null; var header = splitPageAiMarkdownTableRow(lines[startIndex]); var divider = splitPageAiMarkdownTableRow(lines[startIndex + 1]); if (!header.length || header.length !== divider.length) return null; var rows = []; var index = startIndex + 2; while (index < lines.length && lines[index].trim() && lines[index].includes('|')) { var cells = splitPageAiMarkdownTableRow(lines[index]); if (!cells.length) break; rows.push(cells); index += 1; } function cellHtml(tag, value) { return '<' + tag + '>' + renderPageAiMarkdownInline(value) + ''; } var head = '' + header.map(function(cell) { return cellHtml('th', cell); }).join('') + ''; var body = rows.length ? '' + rows.map(function(row) { return '' + header.map(function(_, cellIndex) { return cellHtml('td', row[cellIndex] || ''); }).join('') + ''; }).join('') + '' : ''; return { html: '
' + head + body + '
', nextIndex: index }; } function isMnoteCitationHref(href) { try { var url = new URL(href, window.location.origin); if (!isPageAiSameMnoteOrigin(url)) return false; return url.pathname.startsWith('/documents/') || url.pathname === '/api/local-folder/files/open'; } catch (_error) { return false; } } function isPageAiSameMnoteOrigin(url) { try { var current = new URL(window.location.origin); if (url.origin === current.origin) return true; if (url.hostname === 'mnote.local') return true; var localNames = ['localhost', '127.0.0.1', '::1', 'mnote.local']; return localNames.indexOf(url.hostname) >= 0 && localNames.indexOf(current.hostname) >= 0 && String(url.port || defaultPortForProtocol(url.protocol)) === String(current.port || defaultPortForProtocol(current.protocol)); } catch (_error) { return false; } } function defaultPortForProtocol(protocol) { return protocol === 'https:' ? '443' : protocol === 'http:' ? '80' : ''; } function renderPageAiMarkdown(content) { var lines = String(content || '').replace(/\r\n?/g, '\n').split('\n'); var blocks = []; var index = 0; function isBlockBoundary(line) { return !line.trim() || /^```/.test(line.trim()) || /^#{1,6}\s+/.test(line) || /^\s*[-*]\s+/.test(line) || /^\s*\d+[.)]\s+/.test(line); } while (index < lines.length) { var line = lines[index]; if (!line.trim()) { index += 1; continue; } if (/^```/.test(line.trim())) { index += 1; var codeLines = []; while (index < lines.length && !/^```/.test(lines[index].trim())) { codeLines.push(lines[index]); index += 1; } if (index < lines.length) index += 1; blocks.push('
' + escapeHtml(codeLines.join('\n')) + '
'); continue; } if (/^\s*-{3,}\s*$/.test(line)) { blocks.push('
'); index += 1; continue; } var table = renderPageAiMarkdownTable(lines, index); if (table) { blocks.push(table.html); index = table.nextIndex; continue; } var heading = line.match(/^(#{1,6})\s+(.+)$/); if (heading) { var level = Math.min(6, heading[1].length); blocks.push('' + renderPageAiMarkdownInline(heading[2]) + ''); index += 1; continue; } if (/^\s*[-*]\s+/.test(line)) { var unordered = []; while (index < lines.length && /^\s*[-*]\s+/.test(lines[index])) { unordered.push('
  • ' + renderPageAiMarkdownInline(lines[index].replace(/^\s*[-*]\s+/, '')) + '
  • '); index += 1; } blocks.push(''); continue; } if (/^\s*\d+[.)]\s+/.test(line)) { var ordered = []; while (index < lines.length && /^\s*\d+[.)]\s+/.test(lines[index])) { ordered.push('
  • ' + renderPageAiMarkdownInline(lines[index].replace(/^\s*\d+[.)]\s+/, '')) + '
  • '); index += 1; } blocks.push('
      ' + ordered.join('') + '
    '); continue; } var paragraph = []; while (index < lines.length && !isBlockBoundary(lines[index])) { paragraph.push(renderPageAiMarkdownInline(lines[index])); index += 1; } if (paragraph.length) { blocks.push('

    ' + paragraph.join('
    ') + '

    '); } else { index += 1; } } return blocks.join('') || escapeHtml(String(content || '')); } return { textFromUnknown, renderPageAiMarkdown, renderPageAiMarkdownInline }; }