UNPKG

quikdown

Version:

Small, safe, bidirectional Markdown parser and editor with streaming, undo/redo, rich fences, MCP tools, and a standalone airgapped build. Zero runtime deps. Browser and Node.js.

13 lines • 106 kB
/**
 * Quikdown Editor - Drop-in Markdown Parser
 * @version 1.2.22
 * @license BSD-2-Clause
 * @copyright DeftIO 2025
 */
function e(e){if(e.length<3)return!1;let t="";for(let n=0;n<e.length;n++){const o=e[n];" "!==o&&"\t"!==o&&(t+=o)}if(t.length<3)return!1;const n=t[0];if("-"!==n&&"*"!==n&&"_"!==n)return!1;for(let e=1;e<t.length;e++)if(t[e]!==n)return!1;return!0}function t(e){if(e.length<3)return null;const t=e[0];if("`"!==t&&"~"!==t)return null;let n=1;for(;n<e.length&&e[n]===t;)n++;if(n<3)return null;return{char:t,len:n,lang:e.slice(n).trim()}}function n(e,t,n){if(e.length<n)return!1;let o=0;for(;o<e.length&&e[o]===t;)o++;if(o<n)return!1;for(let t=o;t<e.length;t++)if(" "!==e[t]&&"\t"!==e[t])return!1;return!0}function o(t){return/^#{1,6}\s/.test(t)?"heading":e(t)?"hr":/^\d+\.\s/.test(t)?"list-ol":/^[-*+]\s/.test(t)?"list-ul":/^>/.test(t)?"blockquote":/^\|/.test(t)?"table":"paragraph"}function r(e){return e.includes("|")}const i="quikdown-",a="§CB",s="§HT",l="§BE",c="§NL§",d={href:1,src:1,action:1,formaction:1},h={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},u={h1:"font-size:2em;margin:.67em 0;text-align:left",h2:"font-size:1.5em;margin:.83em 0",h3:"font-size:1.25em;margin:1em 0",h4:"font-size:1em;margin:1.33em 0",h5:"font-size:.875em;margin:1.67em 0",h6:"font-size:.85em;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em",alert:"padding:1em;margin:1em 0;border-left:4px solid #0969da;border-radius:4px;background:#ddf4ff","alert-title":"font-weight:600;margin:0 0 .4em","alert-note":"border-left-color:#0969da;background:#ddf4ff","alert-tip":"border-left-color:#1a7f37;background:#dafbe1","alert-important":"border-left-color:#8250df;background:#fbefff","alert-warning":"border-left-color:#9a6700;background:#fff8c5","alert-caution":"border-left-color:#cf222e;background:#ffebe9",sup:"font-size:.75em;vertical-align:super;line-height:0",footnotes:"margin-top:2em;font-size:.9em","footnote-backref":"text-decoration:none;margin-left:.25em"};function p(e){if(null==e||""===e)return{url:"",title:null};const t=e.match(/^(.*)\s+(?:"([^"]*)"|&quot;([^&]*?)&quot;)\s*$/);if(t)return{url:t[1].replace(/\s+$/,""),title:t[2]??t[3]};const n=e.match(/^(.*)\s+(?:'([^']*)'|&#39;([^&]*?)&#39;)\s*$/);return n?{url:n[1].replace(/\s+$/,""),title:n[2]??n[3]}:e.startsWith("&lt;")&&e.endsWith("&gt;")?{url:e.slice(4,-4),title:null}:{url:e,title:null}}function g(e){return e.replace(/[*_`~]/g,"").trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"section"}function m(e,t){const n=t.get(e)||0;return t.set(e,n+1),0===n?e:`${e}-${n}`}function f(e){let t=0,n=0;for(;n<e.length&&e.startsWith("&gt;",n);)n+=4,t++," "===e[n]&&n++;return{depth:t,content:e.slice(n)}}function w(t){const n=t.trim();return""===n||(!!/^#{1,6}\s/.test(n)||(!!e(n)||(!!/^&gt;/.test(n)||(!!/^[-*+]\s/.test(n)||(!!/^\d+\.\s/.test(n)||(!!n.startsWith("|")||!!n.startsWith(a)))))))}const b=[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<![A-Za-z0-9_])_(?![_\s])(.+?)(?<![\s_])_(?![A-Za-z0-9_])/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`\n]+)`/g,"code"]],y={NOTE:"Note",TIP:"Tip",IMPORTANT:"Important",WARNING:"Warning",CAUTION:"Caution"};function x(e,t,n){const o=e.length>0&&1===e[0].depth?e[0].content.trim().match(/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*$/i):null;let r="";const a=[],s=t("blockquote").includes("style=");for(let l=0;l<e.length;l++){const{depth:c,content:d}=e[l];if(!(c<=0)){if(o&&0===l){const e=o[1].toUpperCase(),t=e.toLowerCase();if(s){const e=u.alert,o=u["alert-"+t];r+=`<div style="${o?`${e};${o}`:e}"${n(">")}>`}else r+=`<div class="${i}alert ${i}alert-${t}"${n(">")}>`;const l=y[e];r+=s?`<p style="${u["alert-title"]}">${l}</p>`:`<p class="${i}alert-title">${l}</p>`,a.push("alert");continue}for(;a.length>c;){r+="alert"===a.pop()?"</div>":"</blockquote>"}for(;a.length<c;)0===a.length&&o?a.push("alert"):(r+=`<blockquote${t("blockquote")}${n(">")}>`,a.push("blockquote"));r+=d,l<e.length-1&&(r+="\n")}}for(;a.length>0;){r+="alert"===a.pop()?"</div>":"</blockquote>"}return r.trimEnd()}function v(e){if(0===e.length)return!1;const t=e.match(/^([ \t]+)(.*)$/);if(!t)return!1;if(t[1].replace(/\t/g,"    ").length<4)return!1;const n=t[2];return!(/^[-*+]\s/.test(n)||/^\d+\.\s/.test(n)||/^>/.test(n)||/^#{1,6}\s/.test(n))}function q(e){if(e.startsWith("    "))return e.slice(4);if("\t"===e[0])return e.slice(1);const t=e.match(/^[ \t]+(.*)$/);return t?t[1]:e}const $=/^(\s*)([*\-+]|\d+\.)\s+(.+)$/;function k(e){const t=e.match(/^[ \t]+(\S.*)$/);if(!t)return!1;const n=t[1];return!/^(```|~~~|>|&gt;|\||#{1,6}(\s|$)|<)/.test(n)&&!/^([-*_])\1{2,}\s*$/.test(n)}function S(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|")}function A(t,n={}){if(!t||"string"!=typeof t)return"";const{fence_plugin:o,inline_styles:r=!1,bidirectional:y=!1,lazy_linefeeds:S=!1,allow_unsafe_html:A=!1,heading_ids:M=!1,reference_links:L=!1,footnotes:C=!1}=n,T=function(e,t){return function(n,o=""){if(e){let e=t[n];return e||o?(o&&o.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${o?e?`${e}${o}`:o:e}"`):""}{const e=` class="${i}${n}"`;return o?`${e} style="${o}"`:e}}}(r,u),E=new Map;function H(e){return e.replace(/[&<>"']/g,e=>h[e])}const j=y?e=>` data-qd="${H(e)}"`:()=>"";function N(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),o=n.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?n:"#";return n}let F=t;const z=[],B=[];F=F.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,t,n,r)=>{const i=`${a}${z.length}§`,s=n?n.trim():"";return o&&o.render&&"function"==typeof o.render?z.push({lang:s,code:r.trimEnd(),custom:!0,fence:t,hasReverse:!!o.reverse}):z.push({lang:s,code:H(r.trimEnd()),custom:!1,fence:t}),i});const R=[];F=F.replace(/\\`/g,()=>{const e=`${l}${R.length}§`;return R.push("`"),e}),F=F.replace(/`([^`\n]+)`/g,(e,t)=>{const n=`§IC${B.length}§`;return B.push(H(t)),n}),F=F.replace(/\\([\\*_{}[\]()#+\-.!~|<>])/g,(e,t)=>{const n=`${l}${R.length}§`;return R.push(H(t)),n});const I=new Map,P=new Map,U=[];if(L||C){const V=F.split("\n"),G=[];let Z=0;for(;Z<V.length;){const X=V[Z];if(X.includes(a))G.push(X),Z++;else{if(C){const Q=X.match(/^\[\^([^\]]+)\]:\s+([\s\S]*)$/);if(Q){const Y=Q[1];let K=Q[2];for(;Z+1<V.length;){const te=V[Z+1];if(!/^[ \t]+\S/.test(te)||te.includes(a))break;K+=" "+te.trim(),Z++}const ee=Y;P.has(ee)||P.set(ee,K),Z++;continue}}if(L){const ne=X.match(/^\[([^\]]+)\]:\s+<?([^\s>]+)>?(?:\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\)))?\s*$/);if(ne){const oe=ne[1].toLowerCase(),re=ne[2],ie=void 0!==ne[3]?ne[3]:void 0!==ne[4]?ne[4]:void 0!==ne[5]?ne[5]:null;I.has(oe)||I.set(oe,{url:re,title:ie}),Z++;continue}}G.push(X),Z++}}F=G.join("\n")}const J=[],O=Array.isArray(A)?Object.fromEntries(A.map(e=>[e,1])):A&&"object"==typeof A?A:null;if(O&&(F=F.replace(/<!--[\s\S]*?-->/g,e=>{const t=J.length;return J.push(e),`${s}${t}§`}),F=F.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)\b[^>]*\/?>/g,(e,t)=>{if(t.toLowerCase()in O){const t=function(e){if(!/\s/.test(e.replace(/<\/?[a-zA-Z][a-zA-Z0-9]*/,"").replace(/\/?>$/,"")))return e;const t=e.match(/^(<\/?[a-zA-Z][a-zA-Z0-9]*)([\s\S]*?)(\/?>)$/);if(!t)return e;const[,n,o,r]=t,i=/([a-zA-Z_][\w\-.:]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/g,a=[];let s;for(;null!==(s=i.exec(o));){const e=s[1],t=void 0!==s[2]?s[2]:void 0!==s[3]?s[3]:s[4];if(!/^on/i.test(e))if(void 0===t)a.push(e);else{let n=t;e.toLowerCase()in d&&(n=N(t)),a.push(`${e}="${n}"`)}}return n+(a.length?" "+a.join(" "):"")+r}(e),n=J.length;return J.push(t),`${s}${n}§`}return e})),!0!==A&&(F=H(F)),O&&J.forEach((e,t)=>{F=F.replace(`${s}${t}§`,e)}),F=function(e,t,n){const o=e.split("\n"),r=[];let i=0,a=!1;for(;i<o.length;){const e=o[i];if($.test(e)){a=!0,r.push(e),i++;continue}if(a){if(k(e)){r.push(e),i++;continue}a=!1}if(!v(e)){r.push(e),i++;continue}const s=[];for(;i<o.length;){const e=o[i];if(""===e){if(i+1<o.length&&v(o[i+1])){s.push(""),i++;continue}break}if(!v(e))break;s.push(q(e)),i++}const l=s.join(c);r.push(`<pre${t("pre")}${n("    ")}><code${t("code")}>${l}</code></pre>`)}return r.join("\n")}(F,T,j),F=function(e,t,n){const o=e.split("\n"),r=[];let i=!1,a=[];for(let e=0;e<o.length;e++){const s=o[e].trim();if(s.includes("|")&&(s.startsWith("|")||/[^\\|]/.test(s)))i||(i=!0,a=[]),a.push(s);else{if(i){const e=_(a,t,n);e?r.push(e):r.push(...a),i=!1,a=[]}r.push(o[e])}}if(i&&a.length>0){const e=_(a,t,n);e?r.push(e):r.push(...a)}return r.join("\n")}(F,T,y),F=function(t,n,o,r,i,a){const s=t.split("\n"),l=[];let c=0;for(;c<s.length;){const t=s[c];if(/^\[\/\/\]: #/.test(t)){c++;continue}let d=0;for(;d<t.length&&d<7&&"#"===t[d];)d++;if(d>=1&&d<=6&&" "===t[d]){const e=t.slice(d+1).replace(/\s*#+\s*$/,""),s="h"+d;let h="";if(r){h=` id="${a(m(g(e),i))}"`}l.push(`<${s}${n(s)}${h}${o("#".repeat(d))}>${e}</${s}>`),c++;continue}if(e(t))l.push(`<hr${n("hr")}${o(t.trim())}>`),c++;else{if(f(t).depth>0){const e=[];let t=0;for(;c<s.length;){const n=f(s[c]);if(n.depth>0)e.push(n),t=n.depth,c++;else{if(!(t>0)||w(s[c]))break;e.push({depth:t,content:s[c]}),c++}}l.push(x(e,n,o));continue}l.push(t),c++}}return l.join("\n")}(F,T,j,M,E,H),F=function(e,t,n,o){const r=e.split("\n"),a=[],s=[];let l=0,c=!1;const d=e=>e.replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e])),h=o?e=>` data-qd="${d(e)}"`:()=>"";for(let e=0;e<r.length;e++){const o=r[e],d=o.match($);if(d){const[,e,o,r]=d;0===s.length&&(l=e.length);const u=Math.max(0,Math.floor((e.length-l)/2)),p=/^\d+\./.test(o),g=p?"ol":"ul";let m=r,f="";const w=r.match(/^\[([x ])\]\s+(.*)$/i);if(w&&!p){const[,e,t]=w,o="x"===e.toLowerCase();m=`<input type="checkbox"${n?' style="margin-right:.5em"':` class="${i}task-checkbox"`}${o?" checked":""} disabled> ${t}`,f=n?' style="list-style:none"':` class="${i}task-item"`}for(;s.length>u+1;){const e=s.pop();a.push(`</${e.type}>`)}for(s.length===u+1&&s[u].type!==g&&a.push(`</${s.pop().type}>`);s.length<u+1;)s.push({type:g,level:s.length}),a.push(`<${g}${t(g)}>`);const b=f||t("li");a.push(`<li${b}${h(o)}>${m}</li>`),c=!0}else if(c&&k(o)){let e=a[a.length-1].slice(0,-5);/( {2}|\\)$/.test(e)?e=e.replace(/( {2}|\\)$/,`<br${t("br")}>`):e+=" ",a[a.length-1]=`${e}${o.trim()}</li>`}else{for(;s.length>0;){const e=s.pop();a.push(`</${e.type}>`)}a.push(o),c=!1}}for(;s.length>0;){const e=s.pop();a.push(`</${e.type}>`)}return a.join("\n")}(F,T,r,y),F=F.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,t,o)=>{const{url:r,title:i}=p(o),a=N(r,n.allow_unsafe_urls),s=i?` title="${H(i)}"`:"",l=y&&t?` data-qd-alt="${H(t)}"`:"",c=y?` data-qd-src="${H(r)}"`:"",d=y&&i?` data-qd-title="${H(i)}"`:"";return`<img${T("img")} src="${a}" alt="${t}"${s}${l}${c}${d}${j("!")}>`}),F=F.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,t,o)=>{const{url:r,title:i}=p(o),a=N(r,n.allow_unsafe_urls),s=/^https?:\/\//i.test(a)?' rel="noopener noreferrer"':"",l=i?` title="${H(i)}"`:"",c=y?` data-qd-text="${H(t)}"`:"",d=y&&i?` data-qd-title="${H(i)}"`:"";return`<a${T("a")} href="${a}"${s}${l}${c}${d}${j("[")}>${t}</a>`}),F=F.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,t,o)=>{const{url:r,trailing:i}=function(e){let t="";const n=/[.,;:!?)]/;for(;e.length>0&&n.test(e[e.length-1]);){const n=e[e.length-1];if(")"===n&&(e.match(/\(/g)||[]).length>=(e.match(/\)/g)||[]).length)break;t=n+t,e=e.slice(0,-1)}return{url:e,trailing:t}}(o),a=N(r,n.allow_unsafe_urls);return`${t}<a${T("a")} href="${a}" rel="noopener noreferrer">${r}</a>${i}`}),L&&I.size>0){function ae(e,t,o){const r=N(e.url,n.allow_unsafe_urls),i=/^https?:\/\//i.test(r)?' rel="noopener noreferrer"':"",a=e.title?` title="${H(e.title)}"`:"",s=y?` data-qd-ref="${H(t)}"`:"";return`<a${T("a")} href="${r}"${i}${a}${s}${j("[ref")}>${o}</a>`}F=F.replace(/\[([^\]]+)\]\[([^\]]*)\]/g,(e,t,n)=>{const o=I.get((""===n?t:n).toLowerCase());return o?ae(o,n,t):e}),F=F.replace(/(?<!\])\[([^\]^[\n]+)\](?!\(|\[)/g,(e,t)=>{const n=I.get(t.toLowerCase());return n?ae(n,t,t):e})}C&&P.size>0&&(F=F.replace(/\[\^([^\]]+)\]/g,(e,t)=>{if(!P.has(t))return e;let n=U.indexOf(t);-1===n?(U.push(t),n=U.length):n+=1;const o=y?` data-qd-fn="${H(t)}"`:"";return`<sup${T("sup")}${o}${j("[^")}><a href="#fn-${H(t)}" id="fnref-${H(t)}">${n}</a></sup>`}));const W=[];F=F.replace(/<[^>]+>/g,e=>(W.push(e),`%%T${W.length-1}%%`));const D=["**","__","*","_","~~"];for(let se=0;se<5;se++){const[le,ce]=b[se];F=F.replace(le,`<${ce}${T(ce)}${j(D[se])}>$1</${ce}>`)}if(F=F.replace(/%%T(\d+)%%/g,(e,t)=>W[t]),F=F.replace(/\\\n/g,`<br${T("br")}>`),S){const de=[];let he=0;F=F.replace(/<(table|[uo]l)[^>]*>[\s\S]*?<\/\1>/g,e=>(de[he]=e,`§B${he++}§`)),F=F.replace(/\n\n+/g,"§P§").replace(/(<\/(?:h[1-6]|blockquote|pre)>)\n/g,"$1§N§").replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\n/g,"$1§N§").replace(/\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g,"§N§$1").replace(/\n(§B\d+§)/g,"§N§$1").replace(/(§B\d+§)\n/g,"$1§N§").replace(/\n/g,`<br${T("br")}>`).replace(/§N§/g,"\n").replace(/§P§/g,"</p><p>"),de.forEach((e,t)=>F=F.replace(`§B${t}§`,e)),F="<p>"+F+"</p>"}else F=F.replace(/ {2}$/gm,`<br${T("br")}>`),F=F.replace(/\n\n+/g,(e,t)=>F.substring(0,t).match(/<\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)?"<p>":"</p><p>"),F="<p>"+F+"</p>";if([[/<p><\/p>/g,""],[/<p>(<h[1-6][^>]*>)/g,"$1"],[/(<\/h[1-6]>)<\/p>/g,"$1"],[/<p>(<blockquote[^>]*>)/g,"$1"],[/(<\/blockquote>)<\/p>/g,"$1"],[/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"],[/(<\/ul>|<\/ol>)<\/p>/g,"$1"],[/<p>(<hr[^>]*>)<\/p>/g,"$1"],[/<p>(<table[^>]*>)/g,"$1"],[/(<\/table>)<\/p>/g,"$1"],[/<p>(<pre[^>]*>)/g,"$1"],[/(<\/pre>)<\/p>/g,"$1"],[/<p>(<div[^>]*>)/g,"$1"],[/(<\/div>)<\/p>/g,"$1"],[/<p>(<section[^>]*>)/g,"$1"],[/(<\/section>)<\/p>/g,"$1"],[new RegExp(`<p>(${a}\\d+§)</p>`,"g"),"$1"]].forEach(([e,t])=>{F=F.replace(e,t)}),F=F.replace(/(<\/(?:h[1-6]|blockquote|div|section|ul|ol|table|pre|hr)>)\n([^<])/g,"$1\n<p>$2"),C&&U.length>0){const ue=y?' data-qd="[^section"':"";let pe=`<section${T("footnotes")}${ue}>`;pe+=`<hr${T("hr")}>`,pe+=`<ol${T("ol")}>`;for(const ge of U){const me=P.get(ge)||"";let fe=!0===A?me:H(me);for(const[be,ye]of b)fe=fe.replace(be,`<${ye}${T(ye)}>$1</${ye}>`);const we=y?` data-qd-fn-id="${H(ge)}"`:"";pe+=`<li${T("li")} id="fn-${H(ge)}"${we}>${fe} <a href="#fnref-${H(ge)}"${T("footnote-backref")}>↩</a></li>`}pe+="</ol></section>",F+=pe}return z.forEach((e,t)=>{let n;if(e.custom&&o&&o.render)if(n=o.render(e.code,e.lang),void 0===n){const t=!r&&e.lang?` class="language-${H(e.lang)}"`:"",o=r?T("code"):t,i=y&&e.lang?` data-qd-lang="${H(e.lang)}"`:"",a=y?` data-qd-fence="${H(e.fence)}"`:"";n=`<pre${T("pre")}${a}${i}><code${o}>${H(e.code)}</code></pre>`}else y&&(n=n.replace(/^<(\w+)/,`<$1 data-qd-fence="${H(e.fence)}" data-qd-lang="${H(e.lang)}" data-qd-source="${H(e.code)}"`));else{const t=!r&&e.lang?` class="language-${H(e.lang)}"`:"",o=r?T("code"):t,i=y&&e.lang?` data-qd-lang="${H(e.lang)}"`:"",a=y?` data-qd-fence="${H(e.fence)}"`:"";n=`<pre${T("pre")}${a}${i}><code${o}>${e.code}</code></pre>`}const i=`${a}${t}§`;F=F.replace(i,n)}),B.forEach((e,t)=>{const n=`§IC${t}§`;F=F.replace(n,`<code${T("code")}${j("`")}>${e}</code>`)}),R.forEach((e,t)=>{F=F.replace(`${l}${t}§`,e)}),F=F.split(c).join("\n"),F.trim()}function M(e,t){return[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<![A-Za-z0-9_])_(?![_\s])(.+?)(?<![\s_])_(?![A-Za-z0-9_])/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`\n]+)`/g,"code"]].forEach(([n,o])=>{e=e.replace(n,`<${o}${t(o)}>$1</${o}>`)}),e}function _(e,t,n){if(e.length<2)return null;let o,r,i,a=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){a=t;break}if(-1===a)o=[e[0]],r=e.slice(1),i=S(e[0]).map(()=>"left");else{o=e.slice(0,a),r=e.slice(a+1);const t=S(e[a]);i=t.map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"})}const s=i.length,l=n?` data-qd-align="${i.join(",")}"`:"";let c=`<table${t("table")}${l}>\n`;return c+=`<thead${t("thead")}>\n`,o.forEach(e=>{c+=`<tr${t("tr")}>\n`;const n=S(e);for(let e=0;e<s;e++){const o=e<n.length?n[e]:"",r=i[e]&&"left"!==i[e]?`text-align:${i[e]}`:"",a=M(o.trim(),t);c+=`<th${t("th",r)}>${a}</th>\n`}c+="</tr>\n"}),c+="</thead>\n",r.length>0&&(c+=`<tbody${t("tbody")}>\n`,r.forEach(e=>{c+=`<tr${t("tr")}>\n`;const n=S(e);for(let e=0;e<s;e++){const o=e<n.length?n[e]:"",r=i[e]&&"left"!==i[e]?`text-align:${i[e]}`:"",a=M(o.trim(),t);c+=`<td${t("td",r)}>${a}</td>\n`}c+="</tr>\n"}),c+="</tbody>\n"),c+="</table>",c}function C(e,t={}){return A(e,{...t,bidirectional:!0})}A.emitStyles=function(e="quikdown-",t="light"){const n=u,o={"#f4f4f4":"#2a2a2a","#f0f0f0":"#2a2a2a","#f2f2f2":"#2a2a2a","#ddd":"#3a3a3a","#06c":"#6db3f2","#ddf4ff":"#162d50","#dafbe1":"#16351d","#fbefff":"#2d1a42","#fff8c5":"#342a10","#ffebe9":"#3d1418",_textColor:"#e0e0e0"},r={_textColor:"#333"};let i="";for(const[a,s]of Object.entries(n)){let n=s;if("dark"===t&&o){for(const[e,t]of Object.entries(o))e.startsWith("_")||(n=n.replaceAll(e,t));["h1","h2","h3","h4","h5","h6","td","li","blockquote","alert","alert-title"].includes(a)&&(n+=`;color:${o._textColor}`)}else if("light"===t&&r){["h1","h2","h3","h4","h5","h6","td","li","blockquote","alert","alert-title"].includes(a)&&(n+=`;color:${r._textColor}`)}i+=`.${e}${a} { ${n} }\n`}return i},A.configure=function(e){return function(t){return A(t,e)}},A.version="1.2.22","undefined"!=typeof module&&module.exports&&(module.exports=A),"undefined"!=typeof window&&(window.quikdown=A),Object.keys(A).forEach(e=>{"configure"!==e&&(C[e]=A[e])}),C.toMarkdown=function(e,t={}){let n;if("string"==typeof e)n=document.createElement("div"),n.innerHTML=e;else{if(!(e instanceof Element))return"";n=e}function o(e,n={}){if(e.nodeType===Node.TEXT_NODE)return e.textContent;if(e.nodeType!==Node.ELEMENT_NODE)return"";const i=e.tagName.toLowerCase(),a=e.getAttribute("data-qd");let s="";for(const t of e.childNodes)s+=o(t,{parentTag:i,...n});switch(i){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":const n=parseInt(i[1]);return`${a||"#".repeat(n)} ${s.trim()}\n\n`;case"strong":case"b":if(!s)return"";const o=a||"**";return`${o}${s}${o}`;case"em":case"i":if(!s)return"";const l=a||"*";return`${l}${s}${l}`;case"del":case"s":case"strike":if(!s)return"";const c=a||"~~";return`${c}${s}${c}`;case"code":if(!s)return"";const d=a||"`";return`${d}${s}${d}`;case"pre":const h=e.getAttribute("data-qd-fence")||a||"```",u=e.getAttribute("data-qd-lang")||"";if(t.fence_plugin&&t.fence_plugin.reverse&&u)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||h;return`${e}${n.lang||u}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const p=e.getAttribute("data-qd-source");if(p)return`${h}${u}\n${p}\n${h}\n\n`;const g=e.querySelector("code");return`${h}${u}\n${(g?g.textContent:s).trimEnd()}\n${h}\n\n`;case"blockquote":const m=a||">";return s.trim().split("\n").map(e=>`${m} ${e}`).join("\n")+"\n\n";case"hr":return`${a||"---"}\n\n`;case"br":return`${a||"  "}\n`;case"a":{const t=e.getAttribute("href")||"";if(t.startsWith("#fnref-"))return"";const n=e.getAttribute("data-qd-ref");if(null!==n){const t=e.getAttribute("data-qd-text")||s.trim();return""===n?`[${t}][]`:n.toLowerCase()===t.toLowerCase()?`[${n}]`:`[${t}][${n}]`}const o=e.getAttribute("data-qd-text")||s.trim();return o!==t||a?`[${o}](${t})`:`<${t}>`}case"sup":{const t=e.getAttribute("data-qd-fn");return t?`[^${t}]`:s}case"section":if("[^section"===a){let t="";const n=e.querySelector("ol");if(n)for(const e of n.children){if("LI"!==e.tagName)continue;const n=e.getAttribute("data-qd-fn-id");if(!n)continue;let o="";for(const t of e.childNodes)if(t.nodeType===Node.TEXT_NODE)o+=t.textContent;else if(t.nodeType===Node.ELEMENT_NODE){if("A"===t.tagName&&(t.getAttribute("href")||"").startsWith("#fnref-"))continue;o+=t.textContent}t+=`[^${n}]: ${o.trim()}\n`}return t?"\n"+t:""}return s;case"img":return`${a||"!"}[${e.getAttribute("data-qd-alt")||e.getAttribute("alt")||""}](${e.getAttribute("data-qd-src")||e.getAttribute("src")||""})`;case"ul":case"ol":return r(e,"ol"===i)+"\n";case"li":case"span":default:return s;case"table":return function(e){let t="";const n=e.getAttribute("data-qd-align"),o=n?n.split(","):[],r=e.querySelector("thead");if(r){const e=r.querySelector("tr");if(e){const n=[];for(const t of e.querySelectorAll("th"))n.push(t.textContent.trim());t+="| "+n.join(" | ")+" |\n";t+="| "+n.map((e,t)=>{const n=o[t]||"left";return"center"===n?":---:":"right"===n?"---:":"---"}).join(" | ")+" |\n"}}const i=e.querySelector("tbody");if(i)for(const e of i.querySelectorAll("tr")){const n=[];for(const t of e.querySelectorAll("td"))n.push(t.textContent.trim());n.length>0&&(t+="| "+n.join(" | ")+" |\n")}return t.trim()}(e)+"\n\n";case"p":if(s.trim()){const e=s.split("\n");let t=s.trim();if(e.length>1){let n=0;for(let t=e.length-1;t>=0&&""===e[t].trim();t--)n++;if(n>0)return t+="\n ",t+"\n"}return t+"\n\n"}return"";case"div":const f=e.getAttribute("data-qd-lang"),w=e.getAttribute("data-qd-fence");if(f&&t.fence_plugin&&t.fence_plugin.reverse)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||w||"```";return`${e}${n.lang||f}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const b=e.getAttribute("data-qd-source");if(b&&w)return`${w}${f||""}\n${b}\n${w}\n\n`;if(e.classList&&e.classList.contains("mermaid-container")){const t=e.getAttribute("data-qd-fence")||"```",n=e.getAttribute("data-qd-lang")||"mermaid",o=e.getAttribute("data-qd-source");if(o){const e=document.createElement("textarea");e.innerHTML=o;return`${t}${n}\n${e.value}\n${t}\n\n`}const r=e.querySelector("pre.mermaid");if(r){const e=r.getAttribute("data-qd-source");if(e){const o=document.createElement("textarea");o.innerHTML=e;return`${t}${n}\n${o.value}\n${t}\n\n`}}const i=e.querySelector(".mermaid-source");if(i){const e=document.createElement("div");e.innerHTML=i.innerHTML;return`${t}${n}\n${e.textContent}\n${t}\n\n`}const a=e.querySelector(".mermaid");if(a&&a.textContent.includes("graph"))return`${t}${n}\n${a.textContent.trim()}\n${t}\n\n`}if(e.classList&&e.classList.contains("mermaid")){const t=e.getAttribute("data-qd-fence")||"```";return`${t}${e.getAttribute("data-qd-lang")||"mermaid"}\n${e.textContent.trim()}\n${t}\n\n`}return s}}function r(e,t,n=0){let i="",a=1;const s="  ".repeat(n);for(const l of e.children){if("UL"===l.tagName||"OL"===l.tagName){i+=r(l,"OL"===l.tagName,n+1);continue}if("LI"!==l.tagName)continue;let e=l.getAttribute("data-qd")||(t?`${a}.`:"-");const c=l.querySelector('input[type="checkbox"]');if(c){const t=c.checked?"x":" ";e="-";const n="\n"+s+" ".repeat(e.length+5);let r="";for(const e of l.childNodes)e.nodeType===Node.TEXT_NODE?r+=e.textContent:e.tagName&&"INPUT"!==e.tagName&&(r+=o(e));i+=`${s}${e} [${t}] ${r.trim().replace(/\n/g,n)}\n`}else{const t="\n"+s+" ".repeat(e.length+1);let a="",c="";for(const e of l.childNodes)"UL"===e.tagName||"OL"===e.tagName?c+=r(e,"OL"===e.tagName,n+1):a+=o(e);i+=`${s}${e} ${a.trim().replace(/\n/g,t)}\n${c}`}a++}return i}let i=o(n);return i=i.replace(/\n{3,}/g,"\n\n"),i=i.trim(),i},C.configure=function(e){const t=A.configure({...e,bidirectional:!0});return function(e){return t(e)}},"undefined"!=typeof module&&module.exports&&(module.exports=C),"undefined"!=typeof window&&(window.quikdown_bd=C);const T=["default","stripped","quikdown"],E={h1:{fontSize:"24pt",marginTop:"0.6em",marginBottom:"0.35em"},h2:{fontSize:"18pt",marginTop:"0.55em",marginBottom:"0.3em"},h3:{fontSize:"15pt",marginTop:"0.5em",marginBottom:"0.25em"},h4:{fontSize:"13pt",marginTop:"0.45em",marginBottom:"0.25em"},h5:{fontSize:"11pt",marginTop:"0.4em",marginBottom:"0.2em"},h6:{fontSize:"10pt",marginTop:"0.35em",marginBottom:"0.2em"}};async function H(e,t=!1){return new Promise((n,o)=>{const r=(new XMLSerializer).serializeToString(e),i=document.createElement("canvas"),a=i.getContext("2d"),s=new Image,l=e.closest(".mermaid")||e.classList.contains("mermaid"),c=e.getAttribute("width")&&e.getAttribute("height");let d,h;l||!c?(d=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,h=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300):(d=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,h=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300);let u=r;if(d&&h){const e=document.createElement("div");e.innerHTML=r;const t=e.querySelector("svg");t&&(t.setAttribute("width",d.toString()),t.setAttribute("height",h.toString()),u=(new XMLSerializer).serializeToString(t))}i.width=2*d,i.height=2*h,a.scale(2,2),s.onload=()=>{try{t&&(a.fillStyle="white",a.fillRect(0,0,i.width,i.height)),a.drawImage(s,0,0,d,h),i.toBlob(e=>{n(e)},"image/png",1)}catch(e){o(e)}},s.onerror=o;const p=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(u)}`;s.src=p})}async function j(e){try{if(!e._map)return console.warn("No map found on container"),null;const t=e.getBoundingClientRect(),n=Math.round(t.width),o=Math.round(t.height);if(0===n||0===o)return console.warn("Map container has zero dimensions"),null;const r=document.createElement("canvas"),i=window.devicePixelRatio||1;r.width=n*i,r.height=o*i,r.style.width=n+"px",r.style.height=o+"px";const a=r.getContext("2d");a.scale(i,i),a.fillStyle="#FFFFFF",a.fillRect(0,0,n,o);const s=e.querySelectorAll(".leaflet-tile"),l=[];for(const e of s)l.push(new Promise(n=>{const o=new Image;o.crossOrigin="anonymous",o.onload=()=>{try{const n=e.getBoundingClientRect(),r=n.left-t.left,i=n.top-t.top;a.drawImage(o,r,i,n.width,n.height)}catch(e){console.warn("Failed to draw tile:",e)}n()},o.onerror=()=>{console.warn("Failed to load tile:",e.src),n()},o.src=e.src}));await Promise.all(l);const c=e.querySelectorAll("svg:not(.leaflet-attribution-flag)");for(const e of c)if(!e.closest(".leaflet-control"))try{const n=e.getBoundingClientRect(),o=n.left-t.left,r=n.top-t.top,i=(new XMLSerializer).serializeToString(e),s=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(s);await new Promise((e,t)=>{const i=new Image;i.onload=()=>{a.drawImage(i,o,r,n.width,n.height),URL.revokeObjectURL(l),e()},i.onerror=()=>{URL.revokeObjectURL(l),t(new Error("Failed to load SVG overlay"))},i.src=l})}catch(e){console.warn("Failed to draw SVG overlay:",e)}const d=e.querySelectorAll(".leaflet-marker-icon");for(const e of d)try{const n=new Image;n.crossOrigin="anonymous",await new Promise(o=>{n.onload=()=>{const r=e.getBoundingClientRect(),i=r.left-t.left,s=r.top-t.top;a.drawImage(n,i,s,r.width,r.height),o()},n.onerror=o,n.src=e.src})}catch(e){console.warn("Failed to draw marker icon:",e)}return r.toDataURL("image/png",1)}catch(e){return console.error("Failed to rasterize GeoJSON map:",e),null}}async function N(e,t={}){const n=t.output||"default";if(!T.includes(n))throw new Error(`Invalid output profile "${n}". Must be one of: ${T.join(", ")}`);if(!e)throw new Error("No preview panel available");const o=e.querySelectorAll(".math-display");if(o.length>0){if(Array.from(o).some(e=>!e.querySelector("mjx-container"))&&window.MathJax&&window.MathJax.typesetPromise)try{await window.MathJax.typesetPromise(Array.from(o))}catch(e){console.warn("MathJax typesetting failed:",e)}}const r=e.cloneNode(!0);try{"stripped"!==n&&(r.querySelectorAll("strong, b").forEach(e=>{e.style.fontWeight="bold"}),r.querySelectorAll("em, i").forEach(e=>{e.style.fontStyle="italic"}),r.querySelectorAll("del, s, strike").forEach(e=>{e.style.textDecoration="line-through"}),r.querySelectorAll("u").forEach(e=>{e.style.textDecoration="underline"}),r.querySelectorAll("code:not(pre code)").forEach(e=>{e.style.backgroundColor="#f4f4f4",e.style.padding="2px 4px",e.style.borderRadius="3px",e.style.fontFamily="monospace",e.style.fontSize="0.9em"}),Object.entries(E).forEach(([e,t])=>{r.querySelectorAll(e).forEach(e=>{e.style.fontSize=t.fontSize,"quikdown"===n&&(e.style.fontWeight="bold"),e.style.lineHeight="1.25",e.style.marginTop=t.marginTop,e.style.marginBottom=t.marginBottom})}),r.querySelectorAll("blockquote").forEach(e=>{e.style.borderLeft="4px solid #ddd",e.style.marginLeft="0",e.style.paddingLeft="1em",e.style.color="#666"}),r.querySelectorAll("hr").forEach(e=>{e.style.border="none",e.style.borderTop="1px solid #ccc",e.style.margin="1em 0"}),r.querySelectorAll("table").forEach(e=>{e.style.borderCollapse="collapse",e.style.width="100%",e.style.marginBottom="1em"}),r.querySelectorAll("th").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left",e.style.backgroundColor="#f0f0f0",e.style.fontWeight="bold"}),r.querySelectorAll("td").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left"}),r.querySelectorAll("a").forEach(e=>{e.style.color="#0066cc",e.style.textDecoration="underline"}),r.querySelectorAll("pre code").forEach(e=>{const t=e.parentElement;e.classList.contains("hljs")&&(e.querySelectorAll(".hljs-keyword").forEach(e=>{e.style.color="#d73a49",e.style.fontWeight="bold"}),e.querySelectorAll(".hljs-string").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-number").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-comment").forEach(e=>{e.style.color="#6a737d",e.style.fontStyle="italic"}),e.querySelectorAll(".hljs-function").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-class").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-title").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-built_in").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-literal").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-meta").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-attr").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-variable").forEach(e=>{e.style.color="#e36209"}),e.querySelectorAll(".hljs-regexp").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-selector-class").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-selector-id").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-selector-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-name").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-attribute").forEach(e=>{e.style.color="#6f42c1"}));const n=document.createElement("table");n.style.width="100%",n.style.borderCollapse="collapse",n.style.border="none",n.style.marginBottom="1em";const o=document.createElement("tr"),r=document.createElement("td");r.style.backgroundColor="#f7f7f7",r.style.padding="12px",r.style.fontFamily='Consolas, Monaco, "Courier New", monospace',r.style.fontSize="14px",r.style.lineHeight="1.4",r.style.whiteSpace="pre",r.style.overflowX="auto",r.style.border="1px solid #ddd",r.style.borderRadius="4px",r.innerHTML=e.innerHTML,o.appendChild(r),n.appendChild(o),t.parentNode.replaceChild(n,t)}));const t=r.querySelectorAll("img");for(const e of t){!e.width&&e.naturalWidth&&(e.width=e.naturalWidth),!e.height&&e.naturalHeight&&(e.height=e.naturalHeight);const t=800,n=600;if(e.width>t||e.height>n){const o=Math.min(t/e.width,n/e.height);e.width=Math.round(e.width*o),e.height=Math.round(e.height*o)}if(e.width&&(e.setAttribute("width",e.width.toString()),e.style.width=e.width+"px"),e.height&&(e.setAttribute("height",e.height.toString()),e.style.height=e.height+"px"),e.getAttribute("v:shapes")||e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),e.src&&!e.src.startsWith("data:"))try{const t=await fetch(e.src),n=await t.blob(),o=2097152;if(n.size>o){console.warn("Image too large for inline data URL:",e.src,"Size:",n.size);continue}const r=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)});e.src=r}catch(t){console.warn("Failed to convert image to data URL:",e.src,t)}}const o=r.querySelectorAll(".qde-stl-container");for(const t of o){try{const n=t.dataset.stlId,o=e.querySelector(`.qde-stl-container[data-stl-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=o._threeRenderer,r=o._threeScene,i=o._threeCamera;n&&r&&i&&n.render(r,i);const a=e.toDataURL("image/png",1),s=document.createElement("img");s.src=a;const l=e.width/2,c=e.height/2;s.width=l,s.height=c,s.setAttribute("width",l.toString()),s.setAttribute("height",c.toString()),s.style.width=l+"px",s.style.height=c+"px",s.style.maxWidth="none",s.style.maxHeight="none",s.style.border="1px solid #ddd",s.style.borderRadius="4px",s.style.margin="0.5em 0",s.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),s.alt="STL 3D Model",t.parentNode.replaceChild(s,t);continue}catch(e){console.warn("Failed to convert STL canvas to image (likely WebGL context issue):",e)}else console.warn("No valid canvas found in STL container")}else console.warn("Could not find original STL container")}catch(e){console.error("Error processing STL container for copy:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[STL 3D Model - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const i=r.querySelectorAll(".mermaid");for(const e of i){const t=e.querySelector("svg");if(t)try{const n=await H(t),o=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)}),r=document.createElement("img");r.src=o;const i=t.closest(".mermaid")||t.classList.contains("mermaid"),a=t.getAttribute("width")&&t.getAttribute("height");let s,l;i||!a?(s=t.clientWidth||t.viewBox&&t.viewBox.baseVal.width||parseFloat(t.getAttribute("width"))||400,l=t.clientHeight||t.viewBox&&t.viewBox.baseVal.height||parseFloat(t.getAttribute("height"))||300):(s=parseFloat(t.getAttribute("width"))||t.viewBox&&t.viewBox.baseVal.width||t.clientWidth||400,l=parseFloat(t.getAttribute("height"))||t.viewBox&&t.viewBox.baseVal.height||t.clientHeight||300),r.width=s,r.height=l,r.setAttribute("width",s.toString()),r.setAttribute("height",l.toString()),r.style.width=s+"px",r.style.height=l+"px",r.style.maxWidth="none",r.style.maxHeight="none",r.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),r.alt="Mermaid Diagram",e.parentNode.replaceChild(r,e)}catch(e){console.warn("Failed to convert Mermaid diagram:",e)}}const a=r.querySelectorAll(".qde-abc-container");for(const e of a){const t=e.querySelector("svg");if(t)try{const n=await H(t),o=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)}),r=document.createElement("img");r.src=o;const i=t.viewBox&&t.viewBox.baseVal;let a,s;if(i&&i.width&&i.height){const e=i.width/i.height;a=t.clientWidth||i.width,s=Math.round(a/e)}else a=t.clientWidth||parseFloat(t.getAttribute("width"))||400,s=t.clientHeight||parseFloat(t.getAttribute("height"))||200;r.width=a,r.height=s,r.setAttribute("width",a.toString()),r.setAttribute("height",s.toString()),r.style.width=a+"px",r.style.height=s+"px",r.style.maxWidth="none",r.style.maxHeight="none",r.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),r.alt="Music Notation",e.parentNode.replaceChild(r,e)}catch(e){console.warn("Failed to convert ABC notation:",e)}else{const t=document.createElement("div");t.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",t.textContent="[Music Notation - Interactive content not available in copy]",e.parentNode.replaceChild(t,e)}}const s=r.querySelectorAll(".qde-vega-container");for(const e of s){const t=e.querySelector("svg");if(t)try{const n=await H(t),o=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)}),r=document.createElement("img");r.src=o;const i=t.clientWidth||parseFloat(t.getAttribute("width"))||400,a=t.clientHeight||parseFloat(t.getAttribute("height"))||300;r.width=i,r.height=a,r.setAttribute("width",i.toString()),r.setAttribute("height",a.toString()),r.style.width=i+"px",r.style.height=a+"px",r.style.maxWidth="none",r.style.maxHeight="none",r.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),r.alt="Data Visualization",e.parentNode.replaceChild(r,e)}catch(e){console.warn("Failed to convert Vega chart:",e)}else{const t=document.createElement("div");t.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",t.textContent="[Vega Chart - Interactive content not available in copy]",e.parentNode.replaceChild(t,e)}}const l=r.querySelectorAll(".qde-chart-container");for(const t of l){try{const n=t.dataset.chartId,o=e.querySelector(`.qde-chart-container[data-chart-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=e.toDataURL("image/png",1),o=document.createElement("img");o.src=n;const r=e.width,i=e.height;o.width=r,o.height=i,o.setAttribute("width",r.toString()),o.setAttribute("height",i.toString()),o.style.width=r+"px",o.style.height=i+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.style.margin="0.5em 0",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="Chart",t.parentNode.replaceChild(o,t);continue}catch(e){console.warn("Failed to convert chart canvas to image:",e)}}}catch(e){console.warn("Error processing chart container:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[Chart - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const c=r.querySelectorAll(".qde-svg-container svg");for(const e of c)try{const t=await H(e),n=await new Promise(e=>{const n=new FileReader;n.onloadend=()=>e(n.result),n.readAsDataURL(t)}),o=document.createElement("img");o.src=n;let r,i;e.getAttribute("width")&&e.getAttribute("height")?(r=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,i=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300):(r=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,i=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300),o.width=r,o.height=i,o.setAttribute("width",r.toString()),o.setAttribute("height",i.toString()),o.style.width=r+"px",o.style.height=i+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="SVG Image",e.parentNode.replaceChild(o,e)}catch(e){console.warn("Failed to convert SVG to image:",e)}const d=Array.from(r.querySelectorAll(".math-display"));if(d.length>0)for(const e of d)try{const t=e.querySelector("svg");if(!t){console.warn("No SVG found in math element, skipping");continue}const n=(new XMLSerializer).serializeToString(t),o=new Blob([n],{type:"image/svg+xml;charset=utf-8"}),r=URL.createObjectURL(o),i=new Image,a=await new Promise((e,n)=>{i.onload=function(){const n=document.createElement("canvas");let o,a;try{o=t.width.baseVal.value,a=t.height.baseVal.value}catch(e){t.viewBox&&t.viewBox.baseVal?(o=t.viewBox.baseVal.width,a=t.viewBox.baseVal.height):(o=i.naturalWidth||i.width||200,a=i.naturalHeight||i.height||50)}let s=.04;const l=o*s,c=a*s;if(l>150||c>45){const e=150/l,t=45/c;s*=Math.min(e,t)}o*=s,a*=s;n.width=2*o,n.height=2*a,n.style.width=o+"px",n.style.height=a+"px";const d=n.getContext("2d");d.scale(2,2),d.fillStyle="#FFFFFF",d.fillRect(0,0,o,a),d.drawImage(i,0,0,o,a),URL.revokeObjectURL(r),e(n.toDataURL("image/png"))},i.onerror=()=>{URL.revokeObjectURL(r),n(new Error("Failed to load SVG image"))},i.src=r}),s=document.createElement("img");s.src=a;const l=new Image;l.src=a,await new Promise(e=>{l.onload=e,l.onerror=e,setTimeout(e,100)});const c=l.naturalWidth/2,d=l.naturalHeight/2;s.width=c,s.height=d,s.style.cssText=`display:inline-block;margin:0.5em 0;width:${c}px;height:${d}px;vertical-align:middle;`,s.alt="Math equation",e.parentNode.replaceChild(s,e)}catch(e){console.error("Failed to convert math element to image:",e)}const h=r.querySelectorAll(".geojson-container");if(h.length>0)for(const t of h)try{const n=t.getAttribute("data-original-source");if(!n){console.warn("No original source found for GeoJSON container");continue}let o=null;const r=e.querySelectorAll(".geojson-container");for(const e of r)if(e.getAttribute("data-original-source")===n){o=e;break}if(!o){console.warn("Could not find live GeoJSON container");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t);continue}if(!o._map){console.warn("Map not initialized yet");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Still loading]",t.parentNode.replaceChild(e,t);continue}const i=await j(o);if(i){const e=document.createElement("img");e.src=i,e.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0;",e.alt="GeoJSON Map",t.parentNode.replaceChild(e,t)}else{const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t)}}catch(e){console.error("Failed to process GeoJSON container:",e);const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const u=r.querySelectorAll('[data-qd-lang="geojson"]');for(const t of u)try{const n=t.id,o=n?e.querySelector(`#${n}`):null;if(!o)continue;const r=o.querySelector(".leaflet-container");if(!r)continue;const i=Math.max(1,window.devicePixelRatio||1),a=r.clientWidth||600,s=r.clientHeight||400,l=document.createElement("canvas");l.width=Math.round(a*i),l.height=Math.round(s*i);const c=l.getContext("2d");c.scale(i,i),c.fillStyle="#FFFFFF",c.fillRect(0,0,a,s);const d=r.getBoundingClientRect(),h=Array.from(r.querySelectorAll("img.leaflet-tile"));for(const e of h)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),i=Math.round(t.height),a=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),s=window.getComputedStyle(e);r>0&&i>0&&a&&"none"!==s.display&&"hidden"!==s.visibility&&c.drawImage(e,n,o,r+1,i+1)}catch(e){console.warn("Failed to draw tile:",e)}const u=o.querySelectorAll(".leaflet-overlay-pane svg");for(const e of u)try{const t=(new XMLSerializer).serializeToString(e),n="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(t),o=new Image;await new Promise(e=>{o.onload=e,o.onerror=e,o.src=n});const r=e.getBoundingClientRect(),i=Math.round(r.left-d.left),a=Math.round(r.top-d.top),s=Math.round(r.width),l=Math.round(r.height),h=!(r.right<=d.left||r.left>=d.right||r.bottom<=d.top||r.top>=d.bottom);s>0&&l>0&&h&&c.drawImage(o,i,a,s,l)}catch(e){console.warn("Failed to draw overlay SVG:",e)}const p=o.querySelectorAll(".leaflet-marker-pane img.leaflet-marker-icon");for(const e of p)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),i=Math.round(t.height),a=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),s=window.getComputedStyle(e);r>0&&i>0&&a&&"none"!==s.display&&"hidden"!==s.visibility&&c.drawImage(e,n,o,r,i)}catch(e){console.warn("Failed to draw marker icon:",e)}let g="";try{g=l.toDataURL("image/png",1)}catch(e){console.warn("Map canvas tainted; falling back to placeholder")}const m=document.createElement("img");g?(m.src=g,m.width=a,m.height=s,m.setAttribute("width",String(a)),m.setAttribute("height",String(s)),m.style.width=a+"px",m.style.height=s+"px",m.style.display="block",m.style.border="1px solid #ddd",m.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),m.alt="Map"):(m.alt="Map",m.style.width=a+"px",m.style.height=s+"px",m.style.border="1px solid #ddd",m.style.backgroundColor="#f0f0f0"),t.parentNode.replaceChild(m,t)}catch(e){console.warn("Failed to process map container:",e)}const p=r.querySelectorAll(".qde-html-container");for(const e of p)try{const t=e.getAttribute("data-qd-source"),n=e.querySelector("pre");if(t){const n=document.createElement("div");n.innerHTML=t,n.querySelectorAll("script").forEach(e=>e.remove()),n.querySelectorAll("*").forEach(e=>{for(const t of Array.from(e.attributes))/^on/i.test(t.name)&&e.removeAttribute(t.name)});const o=n.querySelectorAll("img");for(const e of o){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const o=document.createElement("canvas"),r=o.getContext("2d"),i=new Image;i.crossOrigin="anonymous",await new Promise((a,s)=>{if(i.onload=function(){let s=0,l=0;if(t&&!t.includes("%")&&(s=parseInt(t)),n&&!n.includes("%")&&(l=parseInt(n)),s>0&&0===l){if(i.naturalWidth>0){const e=i.naturalHeight/i.naturalWidth;l=Math.round(s*e)}}else if(l>0&&0===s){if(i.naturalHeight>0){const e=i.naturalWidth/i.naturalHeight;s=Math.round(l*e)}}else 0===s&&0===l&&(s=i.naturalWidth||250,l=i.naturalHeight||200);o.width=s,o.height=l,r.drawImage(i,0,0,s,l);const c=o.toDataURL("image/png",1);e.src=c,e.width=s,e.height=l,e.setAttribute("width",s.toString()),e.setAttribute("height",l.toString()),e.style.width=s+"px",e.style.height=l+"px",a()},i.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),s(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))i.src=e.src;else{const t=new Image;t.src=e.src,i.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}e.innerHTML=n.innerHTML}else if(!n){const t=e.querySelectorAll("img");for(const e of t){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const t=document.createElement("canvas"),n=t.getContext("2d"),o=new Image;o.crossOrigin="anonymous",await new Promise((r,i)=>{if(o.onload=function(){let i=e.width||0,a=e.height||0;if(i&&!a){const e=o.naturalHeight/o.naturalWidth;a=Math.round(i*e)}else if(a&&!i){const e=o.naturalWidth/o.naturalHeight;i=Math.round(a*e)}else i||a||(i=o.naturalWidth||250,a=o.naturalHeight||Math.round(o.naturalHeight/o.naturalWidth*250));t.width=i,t.height=a,n.drawImage(o,0,0,i,a);const s=t.toDataURL("image/png",1);e.src=s,e.width=i,e.height=a,e.setAttribute("width",i.toString()),e.setAttribute("height",a.toString()),e.style.width=i+"px",e.style.height=a+"px",r()},o.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),i(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))o.src=e.src;else{const t=new Image;t.src=e.src,o.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}}}catch(e){console.warn("Failed to process HTML container:",e)}const g=r.innerHTML,m=function(e){return"stripped"===e?"":Object.entries(E).map(([t,n])=>{const o="quikdown"===e?" font-weight:bold;":"";return`${t} { font-size:${n.fontSize};${o} line-height:1.25; margin:${n.marginTop} 0 ${n.marginBottom}; }`}).join("\n                  ")}(n),f=`\n            <!DOCTYPE html>\n            <html xmlns:v="urn:schemas-microsoft-com:vml"\n                  xmlns:o="urn:schemas-microsoft-com:office:office"\n                  xmlns:w="urn:schemas-microsoft-com:office:word">\n              <head>\n                <meta charset="utf-8">\n                <style>\n                  ${"stripped"===n?"/* Minimal styles */\n                  img { max-width: 100%; height: auto; }":`${m}\n\n                  /* Table styling */\n                  table { border-collapse: collapse; width: 100%; margin-bottom: 1em; }\n                  th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }\n                  th { background-color: #f0f0f0; font-weight: bold; }\n\n                  /* Code block styling */\n                  pre { background-color: #f4f4f4; padding: 1em; border-radius: 4px; overflow-x: auto; }\n                  code { font-family: monospace; background-color: #f4f4f4; padding: 0.2em 0.4em; border-radius: 3px; }\n\n                  /* Image handling */\n                  img { display: block; max-width: 100%; height: auto; margin: 0.5em 0; }\n\n                  /* Blockquote */\n                  blockquote { border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666; }`}\n                  \n                  /* Math equations centered like squibview */\n                  .math-display { text-align: center; margin: 1em 0; }\n                  .math-display img { display: inline-block; margin: 0 auto; }\n                </style>\n              </head>\n              <body>\x3c!--StartFragment--\x3e${g}\x3c!--EndFragment--\x3e</body>\n            </html>`,w=r.textContent||r.innerText||"";if("macos"===function(){const e=navigator.platform?.toLowerCase()||"",t=navigator.userAgent?.toLowerCase()||"";return e.includes("mac")||t.includes("mac")?"macos":t.includes("windows")?"windows":t.includes("linux")?"linux":"unknown"}())try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([f],{type:"text/html"}),"text/plain":new Blob([w],{type:"text/plain"})})]),{success:!0,html:f,text:w}}catch(e){if(console.warn("Modern clipboard API failed, trying Safari fallback:",e),function(e){let t,n;try{t=document.createElement("div"),t.style.position="fixed",t.style.left="-9999px",t.style.top="0",t.style.width="1px",t.style.height="1px",t.style.overflow="hidden",t.innerHTML=e,document.body.appendChild(t);const o=document.createRange();o.selectNodeContents(t);const r=window.getSelection();r.removeAllRanges(),r.addRange(o),n=document.execCommand("copy"),r.removeAllRanges()}catch(e){console.error("Fallback copy failed:",e),n=!1}finally{t&&t.parentNode&&document.body.removeChild(t)}return n}(g))return{success:!0,html:f,text:w};throw new Error("Fallback copy failed",{cause:e})}else{const e=document.createElement("div");e.style.position="fixed",e.style.left="-9999px",e.style.top="0",e.innerHTML=g,document.body.appendChild(e);try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([f],{type:"text/html"}),"text/plain":new Blob([w],{type:"text/plain"})})]),{success:!0,html:f,text:w}}catch(t){console.warn("Modern clipboard API failed, trying execCommand fallback:",t);const n=window.getSelection(),o=document.createRange();o.selectNodeContents(e),n.removeAllRanges(),n.addRange(o);if(!document.execCommand("copy"))throw new Error("Fallback copy failed",{cause:t});return{success:!0,html:f,text:w}}finally{e&&e.parentNode&&document.body.removeChild(e)}}}catch(e){throw console.error("Failed to copy rendered content:",e),e}}
/**
 * Quikdown Editor - A drop-in markdown editor control
 * @license BSD-2-Clause
 */const F={b:1,i:1,em:1,strong:1,del:1,s:1,u:1,mark:1,sup:1,sub:1,kbd:1,abbr:1,var:1,samp:1,cite:1,small:1,ins:1,dfn:1,ruby:1,rt:1,rp:1,time:1,wbr:1,img:1,picture:1,source:1,video:1,audio:1,figure:1,figcaption:1,a:1,br:1,hr:1,div:1,span:1,p:1,details:1,summary:1,section:1,article:1,aside:1,header:1,footer:1,nav:1,main:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,ul:1,ol:1,li:1,dl:1,dt:1,dd:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,blockquote:1,pre:1,code:1},z={mode:"split",showToolbar:!0,showRemoveHR:!1,showLazyLinefeeds:!1,theme:"auto",lazy_linefeeds:!1,inline_styles:!1,debounceDelay:20,placeholder:"Start typing markdown...",plugins:{highlightjs:!1,mermaid:!1},preloadFences:null,customFences:{},enableComplexFences:!0,showUndoRedo:!1,undoStackSize:100,allowUnsafeHTML:!1,showAllowUnsafeHTML:!1,allowExternalFetch:!0,reference_links:!1,footnotes:!1},B={highlightjs:{check:()=>void 0!==window.hljs,script:"https://unpkg.com/@highlightjs/cdn-assets/highlight.min.js",css:"https://unpkg.com/@highlightjs/cdn-assets/styles/github.min.css",cssDark:"https://unpkg.com/@highlightjs/cdn-assets/styles/github-dark.min.css"},mermaid:{check:()=>void 0!==window.mermaid,script:"https://unpkg.com/mermaid/dist/mermaid.min.js",afterLoad:()=>{window.mermaid&&window.mermaid.initialize({startOnLoad:!1})}},math:{check:()=>void 0!==window.MathJax,script:"https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js",beforeLoad:()=>{window.MathJax||(window.MathJax={loader:{load:["input/tex","output/svg"]},tex:{packages:{"[+]":["ams"]},inlineMath:[["$","$"],["\\(","\\)"]],displayMath:[["$$","$$"],["\\[","\\]"]],processEscapes:!0,processEnvironments:!0},options:{renderActions:{addMenu:[]},ignoreHtmlClass:"tex2jax_ignore",processHtmlClass:"tex2jax_process"},svg:{fontCache:"none"},startup:{typeset:!1}})}},geojson:{check:()=>void 0!==window.L,script:"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",css:"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"},stl:{check:()=>void 0!==window.THREE,script:"https://unpkg.com/three@0.147.0/build/three.min.js"},abc:{check:()=>void 0!==window.ABCJS,script:"https://cdn.jsdelivr.net/npm/abcjs@6/dist/abcjs-basic-min.js"},music:{check:()=>void 0!==window.ABCJS,script:"https://cdn.jsdelivr.net/npm/abcjs@6/dist/abcjs-basic-min.js"},vega:{check:()=>void 0!==window.vegaEmbed,scripts:["https://cdn.jsdelivr.net/npm/vega@5","https://cdn.jsdelivr.net/npm/vega-lite@5","https://cdn.jsdelivr.net/npm/vega-embed@6"]}};class R{constructor(e,t={}){if(this.container="string"==typeof e?document.querySelector(e):e,!this.container)throw new Error("QuikdownEditor: Invalid container");this.options={...z,...t},this._markdown="",this._html="",this.currentMode=this.options.mode,this.updateTimer=null,this._undoStack=[],this._redoStack=[],this._isUndoRedo=!1,this._fenceLibraries={...B},this.initPromise=this.init()}async init(){await this.loadPlugins(),this.buildUI(),this.attachEvents(),this.applyTheme(),this.setMode(this.currentMode),this.options.initialContent&&this.setMarkdown(this.options.initialContent)}buildUI(){this.container.innerHTML="",this.container.classList.add("qde-container"),this.options.showToolbar&&(this.toolbar=this.createToolbar(),this.container.appendChild(this.toolbar)),this.editorArea=document.createElement("div"),this.editorArea.className="qde-editor",this.sourcePanel=document.createElement("div"),this.sourcePanel.className="qde-source",this.sourceTextarea=document.createElement("textarea"),this.sourceTextarea.className="qde-textarea",this.sourceTextarea.spellcheck=!1,this.sourceTextarea.placeholder=this.options.placeholder,this.sourcePanel.appendChild(this.sourceTextarea),this.previewPanel=document.createElement("div"),this.previewPanel.className="qde-preview",this.previewPanel.contentEditable=!0,this.previewPanel.spellcheck=!1,this.editorArea.appendChild(this.sourcePanel),this.editorArea.appendChild(this.previewPanel),this.container.appendChild(this.editorArea),this.injectStyles()}createToolbar(){const e=document.createElement("div");e.className="qde-toolbar";const t={source:"Source",split:"Split",preview:"Rendered"};["source","split","preview"].forEach(n=>{const o=document.createElement("button");o.className="qde-btn",o.dataset.mode=n,o.textContent=t[n],o.title=`Switch to ${t[n]} view`,e.appendChild(o)});const n=document.createElement("button");if(n.className="qde-btn qde-split-toggle",n.textContent="Preview",n.title="Toggle between source and preview in split mode",e.appendChild(n),this.options.showUndoRedo){const t=document.createElement("button");t.className="qde-btn disabled",t.dataset.action="undo",t.textContent="Undo",t.title="Undo (Ctrl+Z)",e.appendChild(t);const n=document.createElement("button");n.className="qde-btn disabled",n.dataset.action="redo",n.textContent="Redo",n.title="Redo (Ctrl+Shift+Z / Ctrl+Y)",e.appendChild(n)}const o=document.createElement("span");o.className="qde-spacer",e.appendChild(o);if([{action:"copy-markdown",text:"Copy MD",title:"Copy markdown to clipboard"},{action:"copy-html",text:"Copy HTML",title:"Copy HTML to clipboard"},{action:"copy-rendered",text:"Copy Rendered",title:"Copy rich text to clipboard"}].forEach(({action:t,text:n,title:o})=>{const r=document.createElement("button");r.className="qde-btn",r.dataset.action=t,r.textContent=n,r.title=o,e.appendChild(r)}),this.options.showRemoveHR){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="remove-hr",t.textContent="Remove HR",t.title="Remove all horizontal rules (---) from markdown",e.appendChild(t)}if(this.options.showLazyLinefeeds){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="lazy-linefeeds",t.textContent="Fix Linefeeds",t.title="Convert single newlines to paragraph breaks (one-time transform)",e.appendChild(t)}if(this.options.showAllowUnsafeHTML){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="toggle-html-mode",t.textContent=this._getHtmlModeLabel(this.options.allowUnsafeHTML),t.title=this._getHtmlModeTooltip(this.options.allowUnsafeHTML),e.appendChild(t)}return e}injectStyles(){if(document.getElementById("qde-styles"))return;const e=document.createElement("style");e.id="qde-styles",e.textContent='\n            .qde-container {\n                display: flex;\n                flex-direction: column;\n                height: 100%;\n                border: 1px solid #ddd;\n                border-radius: 4px;\n                overflow: hidden;\n                background: white;\n                color: #1f2937;\n            }\n            \n            .qde-toolbar {\n                display: flex;\n                align-items: center;\n                flex-wrap: wrap;\n                padding: 8px;\n                background: #f5f5f5;\n                border-bottom: 1px solid #ddd;\n                gap: 4px;\n            }\n            \n            .qde-btn {\n                padding: 6px 12px;\n                border: 1px solid #ccc;\n                background: white;\n                border-radius: 3px;\n                cursor: pointer;\n                font-size: 14px;\n                transition: all 0.2s;\n            }\n            \n            .qde-btn:hover {\n                background: #e9e9e9;\n                border-color: #999;\n            }\n            \n            .qde-btn.active {\n                background: #007bff;\n                color: white;\n                border-color: #0056b3;\n            }\n\n            .qde-btn.disabled {\n                opacity: 0.4;\n                pointer-events: none;\n            }\n            .qde-btn[data-action="toggle-html-mode"] {\n                position: relative;\n            }\n            .qde-btn[data-action="toggle-html-mode"]:hover::after {\n                content: attr(title);\n                position: absolute;\n                bottom: calc(100% + 6px);\n                left: 50%;\n                transform: translateX(-50%);\n                padding: 5px 10px;\n                background: #1f2937;\n                color: #fff;\n                font-size: 0.75rem;\n                font-weight: 400;\n                white-space: nowrap;\n                border-radius: 4px;\n                pointer-events: none;\n                z-index: 10;\n            }\n            \n            .qde-spacer {\n                flex: 1;\n            }\n            \n            .qde-editor {\n                display: flex;\n                flex: 1;\n                overflow: hidden;\n            }\n            \n            .qde-source, .qde-preview {\n                flex: 1 1 0;\n                min-width: 0;       /* allow flex shrinking below content size */\n                min-height: 0;\n                overflow: auto;\n                padding: 16px;\n                box-sizing: border-box;\n            }\n\n            .qde-source {\n                border-right: 1px solid #ddd;\n                /* Source pane is just a container for the textarea — make it\n                   a positioning context so the textarea can fill it absolutely */\n                position: relative;\n                padding: 0;          /* textarea brings its own padding */\n            }\n\n            .qde-textarea {\n                display: block;\n                position: absolute;\n                inset: 0;\n                width: 100%;\n                height: 100%;\n                border: none;\n                outline: none;\n                resize: none;\n                padding: 16px;\n                box-sizing: border-box;\n                font-family: \'Monaco\', \'Courier New\', monospace;\n                font-size: 14px;\n                line-height: 1.5;\n                background: transparent;\n                color: inherit;\n                /* Wrap long lines so the textarea only scrolls VERTICALLY.\n                   pre-wrap preserves intentional line breaks/whitespace\n                   while soft-wrapping at the right edge. */\n                white-space: pre-wrap;\n                word-wrap: break-word;\n                overflow-x: hidden;\n                overflow-y: auto;\n            }\n            \n            .qde-preview {\n                font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n                font-size: 16px;\n                line-height: 1.6;\n                outline: none;\n                cursor: text;  /* Standard text cursor */\n                overflow-x: hidden;  /* never scroll horizontally; clip wide content */\n            }\n\n            /* Code blocks and inline code — self-contained so the editor\n               does not depend on any external stylesheet for these. */\n            .qde-preview pre {\n                background: #f4f4f4;\n                color: #1f2937;\n                padding: 10px;\n                border-radius: 4px;\n                overflow-x: auto;\n                margin: 0.6em 0;\n                font-size: 0.9em;\n                line-height: 1.5;\n                font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",\n                             "Roboto Mono", Consolas, "Courier New", monospace;\n            }\n            .qde-preview code {\n                padding: 2px 4px;\n                font-size: 0.9em;\n                border-radius: 3px;\n                background: #f0f0f0;\n                color: #1f2937;\n                font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code",\n                             "Roboto Mono", Consolas, "Courier New", monospace;\n            }\n            .qde-preview pre code {\n                padding: 0;\n                font-size: inherit;\n                border-radius: 0;\n                background: transparent;\n                color: inherit;\n            }\n\n            /* Wide fence content (Leaflet maps, large SVGs, STL canvases,\n               iframes, raw <img>) must never overflow the preview pane */\n            .qde-preview .geojson-container,\n            .qde-preview .qde-stl-container,\n            .qde-preview .qde-svg-container,\n            .qde-preview .leaflet-container,\n            .qde-preview iframe,\n            .qde-preview img,\n            .qde-preview > svg {\n                max-width: 100%;\n            }\n            .qde-preview img {\n                display: inline;\n            }\n            .qde-preview .leaflet-container { box-sizing: border-box; }\n            .qde-preview .leaflet-container.qde-offline-map {\n                background: #b8d4f0;\n            }\n            .qde-preview .leaflet-container.qde-offline-map path {\n                shape-rendering: geometricPrecision;\n            }\n            .qde-dark .qde-preview .leaflet-container.qde-offline-map {\n                background: #1a3048;\n            }\n\n            /* Standard markdown tables (the .quikdown-table class) need to\n               scroll horizontally inside their own wrapper rather than\n               making the whole preview pane scroll */\n            .qde-preview table.quikdown-table,\n            .qde-preview table.qde-csv-table {\n                display: block;\n                max-width: 100%;\n                overflow-x: auto;\n            }\n\n            /* Fence-specific styles */\n            .qde-svg-container {\n                max-width: 100%;\n                overflow: auto;\n            }\n\n            .qde-svg-container svg {\n                max-width: 100%;\n                height: auto;\n            }\n            \n            .qde-html-container {\n                /* HTML containers inherit background */\n                margin: 12px 0;\n            }\n            \n            .qde-math-container {\n                text-align: center;\n                margin: 16px 0;\n                overflow-x: auto;\n            }\n            \n            /* All tables in preview (both regular markdown and CSV) */\n            .qde-preview table {\n                width: 100%;\n                border-collapse: collapse;\n                margin: 12px 0;\n                font-size: 14px;\n            }\n            \n            .qde-preview table th,\n            .qde-preview table td {\n                border: 1px solid #ddd;\n                padding: 8px;\n            }\n            \n            /* Support for alignment classes from quikdown */\n            .qde-preview .quikdown-left { text-align: left; }\n            .qde-preview .quikdown-center { text-align: center; }\n            .qde-preview .quikdown-right { text-align: right; }\n            \n            .qde-preview table th {\n                background: #f5f5f5;\n                font-weight: bold;\n            }\n            \n            .qde-preview table tr:nth-child(even) {\n                background: #f9f9f9;\n            }\n            \n            /* Specific to CSV-generated tables */\n            .qde-data-table {\n                /* Can add specific CSV table styles here if needed */\n            }\n            \n            .qde-json {\n                /* Let highlight.js handle styling */\n                overflow-x: auto;\n            }\n            \n            .qde-error {\n                background: #fee;\n                border: 1px solid #fcc;\n                color: #c00;\n                padding: 8px;\n                border-radius: 4px;\n                font-family: monospace;\n                font-size: 12px;\n            }\n            \n            /* Read-only complex fence blocks in preview */\n            .qde-preview [contenteditable="false"] {\n                cursor: auto;  /* Use automatic cursor (arrow for non-text) */\n                user-select: text;\n                position: relative;\n            }\n            \n            /* Reset headings inside the preview to plain browser defaults so\n               parent-page styles (site navs, marketing pages, design systems)\n               cannot bleed in. Business-casual: black text, decreasing sizes,\n               no decorative borders. See docs/quikdown-editor.md for how\n               embedders can override these with their own stylesheet. */\n            .qde-preview h1 { font-size: 2em; }\n            .qde-preview h2 { font-size: 1.5em; }\n            .qde-preview h3 { font-size: 1.25em; }\n            .qde-preview h4 { font-size: 1em; }\n            .qde-preview h5 { font-size: 0.875em; }\n            .qde-preview h6 { font-size: 0.85em; }\n            .qde-preview h1,\n            .qde-preview h2,\n            .qde-preview h3,\n            .qde-preview h4,\n            .qde-preview h5,\n            .qde-preview h6 {\n                font-weight: bold;\n                color: inherit;\n                border: none;\n                margin: 0.6em 0 0.3em 0;\n                line-height: 1.25;\n            }\n            .qde-preview p {\n                margin: 0.35em 0;\n            }\n            .qde-preview ul,\n            .qde-preview ol {\n                padding-left: 1.8em;\n                margin: 0.4em 0;\n            }\n            .qde-preview li {\n                margin: 0.15em 0;\n            }\n            .qde-preview blockquote {\n                margin: 0.5em 0;\n                padding-left: 1em;\n            }\n\n            /* Ensure proper cursor for editable text elements */\n            .qde-preview p,\n            .qde-preview h1,\n            .qde-preview h2,\n            .qde-preview h3,\n            .qde-preview h4,\n            .qde-preview h5,\n            .qde-preview h6,\n            .qde-preview li,\n            .qde-preview td,\n            .qde-preview th,\n            .qde-preview blockquote,\n            .qde-preview pre[contenteditable="true"],\n            .qde-preview code[contenteditable="true"] {\n                cursor: text;\n            }\n            \n            \n            /* Non-editable complex renderers */\n            .qde-preview .qde-svg-container[contenteditable="false"],\n            .qde-preview .qde-html-container[contenteditable="false"],\n            .qde-preview .qde-math-container[contenteditable="false"],\n            .qde-preview .mermaid[contenteditable="false"] {\n                opacity: 0.98;\n            }\n            \n            /* Subtle hover effect for read-only blocks */\n            .qde-preview [contenteditable="false"]:hover::after {\n                content: "Read-only";\n                position: absolute;\n                top: 2px;\n                right: 2px;\n                font-size: 10px;\n                color: #999;\n                background: rgba(255, 255, 255, 0.9);\n                padding: 2px 4px;\n                border-radius: 2px;\n                pointer-events: none;\n            }\n            \n            /* Fix list padding in preview */\n            .qde-preview ul,\n            .qde-preview ol {\n                padding-left: 2em;\n                margin: 0.5em 0;\n            }\n            \n            .qde-preview li {\n                margin: 0.25em 0;\n            }\n            \n            /* Mode-specific visibility */\n            .qde-mode-source .qde-preview { display: none; }\n            .qde-mode-source .qde-source { border-right: none; }\n            .qde-mode-preview .qde-source { display: none; }\n            .qde-mode-split .qde-source,\n            .qde-mode-split .qde-preview { display: block; }\n            \n            /* Dark theme */\n            .qde-dark {\n                background: #1e1e1e;\n                color: #e0e0e0;\n                border-color: #444;\n            }\n            \n            .qde-dark .qde-toolbar {\n                background: #2d2d2d;\n                border-color: #444;\n            }\n            \n            .qde-dark .qde-btn {\n                background: #3a3a3a;\n                color: #e0e0e0;\n                border-color: #555;\n            }\n            \n            .qde-dark .qde-btn:hover {\n                background: #4a4a4a;\n            }\n            \n            .qde-dark .qde-source {\n                border-color: #444;\n            }\n            \n            .qde-dark .qde-textarea {\n                background: #1e1e1e;\n                color: #e0e0e0;\n            }\n            \n            .qde-dark .qde-preview {\n                background: #1e1e1e;\n                color: #e0e0e0;\n            }\n            \n            /* Dark mode code blocks */\n            .qde-dark .qde-preview pre {\n                background: #2d2d3a;\n                color: #e6e6f0;\n            }\n            .qde-dark .qde-preview code {\n                background: #2a2a3a;\n                color: #e6e6f0;\n            }\n            .qde-dark .qde-preview pre code {\n                background: transparent;\n                color: inherit;\n            }\n\n            /* Dark mode table styles */\n            .qde-dark .qde-preview table th,\n            .qde-dark .qde-preview table td {\n                border-color: #3a3a3a;\n            }\n            \n            .qde-dark .qde-preview table th {\n                background: #2d2d2d;\n            }\n            \n            .qde-dark .qde-preview table tr:nth-child(even) {\n                background: #252525;\n            }\n            \n            /* Mobile split toggle — hidden by default */\n            .qde-split-toggle { display: none; }\n\n            /* Mobile responsive — compact toolbar for all small screens */\n            @media (max-width: 720px) {\n                .qde-toolbar {\n                    padding: 6px;\n                    gap: 3px;\n                }\n                .qde-btn {\n                    padding: 5px 8px;\n                    font-size: 12px;\n                }\n                .qde-source, .qde-preview {\n                    padding: 10px;\n                }\n                .qde-textarea {\n                    padding: 10px;\n                }\n                /* Undo/Redo: show circular arrows instead of text */\n                .qde-btn[data-action="undo"] { font-size: 0; }\n                .qde-btn[data-action="undo"]::after { content: "\\21B6"; font-size: 14px; }\n                .qde-btn[data-action="redo"] { font-size: 0; }\n                .qde-btn[data-action="redo"]::after { content: "\\21B7"; font-size: 14px; }\n                /* Hide secondary utility buttons to reduce clutter */\n                .qde-btn[data-action="remove-hr"],\n                .qde-btn[data-action="lazy-linefeeds"],\n                .qde-btn[data-action="copy-rendered"] { display: none; }\n            }\n\n            /* Portrait mobile: drop split mode entirely */\n            @media (max-width: 720px) and (orientation: portrait) {\n                .qde-btn[data-mode="split"] { display: none; }\n                .qde-split-toggle { display: none !important; }\n                /* Fallback: if still in split mode, show source only */\n                .qde-mode-split .qde-source { border-right: none; }\n                .qde-mode-split .qde-preview { display: none; }\n                .qde-mode-split.qde-split-preview .qde-source { display: none; }\n                .qde-mode-split.qde-split-preview .qde-preview { display: block; }\n            }\n        ',document.head.appendChild(e)}attachEvents(){if(this.sourceTextarea.addEventListener("input",()=>{this.handleSourceInput()}),this.previewPanel.addEventListener("input",()=>{this.handlePreviewInput()}),this.toolbar&&this.toolbar.addEventListener("click",e=>{const t=e.target.closest(".qde-btn");if(t){if(t.classList.contains("qde-split-toggle")){this.container.classList.toggle("qde-split-preview");const e=this.container.classList.contains("qde-split-preview");return void(t.textContent=e?"Source":"Preview")}t.dataset.mode?this.setMode(t.dataset.mode):t.dataset.action&&this.handleAction(t.dataset.action)}}),document.addEventListener("keydown",e=>{if(e.ctrlKey||e.metaKey)switch(e.key){case"1":e.preventDefault(),this.setMode("source");break;case"2":e.preventDefault(),this.setMode("split");break;case"3":e.preventDefault(),this.setMode("preview");break;case"z":case"Z":e.shiftKey?(e.preventDefault(),this.redo()):(e.preventDefault(),this.undo());break;case"y":case"Y":e.preventDefault(),this.redo()}}),"function"==typeof window.matchMedia){const e=window.matchMedia("(max-width: 720px) and (orientation: portrait)"),t=()=>{e.matches&&"split"===this.currentMode&&this.setMode("source")};Promise.resolve().then(t),e.addEventListener("change",t)}}handleSourceInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromMarkdown(this.sourceTextarea.value)},this.options.debounceDelay)}handlePreviewInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromHTML()},this.options.debounceDelay)}updateFromMarkdown(e){if(this._isUndoRedo||this._pushUndoState(e||""),this._isUndoRedo=!1,this._markdown=e||"",this._markdown.trim()){const t=this.options.allowUnsafeHTML,n="limited"===t?F:t;this._html=C(e,{fence_plugin:this.createFencePlugin(),lazy_linefeeds:this.options.lazy_linefeeds,inline_styles:this.options.inline_styles,allow_unsafe_html:n,reference_links:this.options.reference_links,footnotes:this.options.footnotes}),"source"!==this.currentMode&&(this.previewPanel.innerHTML=this._html,this._typesetMath(this.previewPanel))}else this._html="","source"!==this.currentMode&&(this.previewPanel.innerHTML='<div style="color: #999; font-style: italic; padding: 16px;">Start typing markdown in the source panel...</div>');this.options.onChange&&this.options.onChange(this._markdown,this._html)}updateFromHTML(){const e=this.previewPanel.cloneNode(!0);this.preprocessSpecialElements(e),this._html=this.previewPanel.innerHTML;const t=C.toMarkdown(e,{fence_plugin:this.createFencePlugin()});this._isUndoRedo||this._pushUndoState(t),this._isUndoRedo=!1,this._markdown=t,"preview"!==this.currentMode&&(this.sourceTextarea.value=this._markdown),this.options.onChange&&this.options.onChange(this._markdown,this._html),this._updateUndoButtons()}preprocessSpecialElements(e){if(!e)return;e.querySelectorAll('[contenteditable="false"][data-qd-source]').forEach(e=>{const t=e.getAttribute("data-qd-source"),n=e.getAttribute("data-qd-fence")||"```",o=e.getAttribute("data-qd-lang")||"",r=document.createElement("pre");r.setAttribute("data-qd-fence",n),o&&r.setAttribute("data-qd-lang",o);const i=document.createElement("code");i.textContent=t,r.appendChild(i),e.parentNode.replaceChild(r,e)});e.querySelectorAll("table.qde-csv-table[data-qd-lang]").forEach(e=>{const t=e.getAttribute("data-qd-lang");if(!t||!["csv","psv","tsv"].includes(t))return;const n="csv"===t?",":"psv"===t?"|":"\t";let o="";const r=[];e.querySelectorAll("thead th").forEach(e=>{const t=e.textContent.trim(),o=t.includes(n)||t.includes('"')||t.includes("\n");r.push(o?`"${t.replace(/"/g,'""')}"`:t)}),o+=r.join(n)+"\n";e.querySelectorAll("tbody tr").forEach(e=>{const t=[];e.querySelectorAll("td").forEach(e=>{const o=e.textContent.trim(),r=o.includes(n)||o.includes('"')||o.includes("\n");t.push(r?`"${o.replace(/"/g,'""')}"`:o)}),o+=t.join(n)+"\n"});const i=document.createElement("pre");i.setAttribute("data-qd-fence","```"),i.setAttribute("data-qd-lang",t);const a=document.createElement("code");a.textContent=o.trim(),i.appendChild(a),e.parentNode.replaceChild(i,e)})}createFencePlugin(){return{render:(e,t)=>{if(this.options.customFences&&this.options.customFences[t])try{return this.options.customFences[t](e,t)}catch(n){return console.error(`Custom fence plugin error for ${t}:`,n),`<pre><code class="language-${this.escapeHtml(t)}">${this.escapeHtml(e)}</code></pre>`}if(!!this.options.enableComplexFences)switch(t){case"svg":return this.renderSVG(e);case"html":return this.renderHTML(e);case"math":case"tex":case"latex":return this.renderMath(e,t);case"csv":case"psv":case"tsv":return this.renderTable(e,t);case"json":case"json5":return this.renderJSON(e,t);case"katex":return this.renderMath(e,"katex");case"mermaid":if(window.mermaid)return this.renderMermaid(e);break;case"geojson":return this.renderGeoJSON(e);case"stl":return this.renderSTL(e);case"abc":case"music":return this.renderABC(e);case"vega":case"vega-lite":case"vegalite":return this.renderVega(e,t)}if(window.hljs&&t&&hljs.getLanguage(t)){const n=hljs.highlight(e,{language:t}).value;return`<pre data-qd-fence="\`\`\`" data-qd-lang="${this.escapeHtml(t)}"><code class="hljs language-${this.escapeHtml(t)}">${n}</code></pre>`}},reverse:e=>{const t=e.getAttribute("data-qd-lang")||"";let n;if(e.querySelector("code.hljs")){const t=e.querySelector("code.hljs");n=t.textContent||t.innerText||""}else if(e.querySelector("code")){const t=e.querySelector("code");n=t.textContent||t.innerText||""}else n=e.textContent||e.innerText||"";return{content:n,lang:t,fence:"```"}}}}renderSVG(e){try{const t=(new DOMParser).parseFromString(e,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid SVG");const n=t.documentElement;n.querySelectorAll("script").forEach(e=>e.remove());const o=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);let r;for(;r=o.nextNode();)for(let e=r.attributes.length-1;e>=0;e--){const t=r.attributes[e];(t.name.startsWith("on")||t.value.includes("javascript:"))&&r.removeAttribute(t.name)}const i=document.createElement("div");return i.className="qde-svg-container",i.contentEditable="false",i.setAttribute("data-qd-fence","```"),i.setAttribute("data-qd-lang","svg"),i.setAttribute("data-qd-source",e),i.innerHTML=(new XMLSerializer).serializeToString(n),i.outerHTML}catch(e){const t=document.createElement("pre");return t.className="qde-error",t.contentEditable="false",t.setAttribute("data-qd-fence","```"),t.setAttribute("data-qd-lang","svg"),t.textContent=`Invalid SVG: ${e.message}`,t.outerHTML}}renderHTML(e){const t=`html-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;if(window.DOMPurify){const t=DOMPurify.sanitize(e),n=document.createElement("div");return n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e),n.innerHTML=t,n.outerHTML}this.lazyLoadLibrary("DOMPurify",()=>window.DOMPurify,"https://unpkg.com/dompurify/dist/purify.min.js").then(n=>{if(n){const n=document.getElementById(t);if(n){const t=DOMPurify.sanitize(e);n.innerHTML=t,n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html")}}});const n=document.createElement("div");n.id=t,n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e);const o=document.createElement("pre");return o.textContent=e,n.appendChild(o),n.outerHTML}renderMath(e,t){const n=`math-${Math.random().toString(36).substring(2,15)}`,o=document.createElement("div");o.id=n,o.className="math-display",o.contentEditable="false",o.setAttribute("data-source-type","math");const r=e.replace(/\r?\n/g," ").replace(/\s+/g," ").trim();return o.textContent=`$$${r}$$`,o.style.textAlign="center",o.style.margin="1em 0",window.MathJax&&window.MathJax.typesetPromise||this.ensureMathJaxLoaded(),o.outerHTML}_typesetMath(e){const t=(e||this.previewPanel||document).querySelectorAll(".math-display");if(0===t.length)return;const n=Array.from(t);if(window.MathJax&&window.MathJax.typesetPromise)window.MathJax.typesetPromise(n).catch(()=>{});else if(window.MathJax&&window.MathJax.startup&&window.MathJax.startup.promise)window.MathJax.startup.promise.then(()=>{window.MathJax.typesetPromise&&window.MathJax.typesetPromise(n).catch(()=>{})}).catch(()=>{});else if(window.MathJax){const e=t=>{t<=0||setTimeout(()=>{window.MathJax&&(window.MathJax.typesetPromise?window.MathJax.typesetPromise(n).catch(()=>{}):window.MathJax.startup&&window.MathJax.startup.promise?window.MathJax.startup.promise.then(()=>{window.MathJax&&window.MathJax.typesetPromise&&window.MathJax.typesetPromise(n).catch(()=>{})}).catch(()=>{}):e(t-1))},100)};e(50)}}ensureMathJaxLoaded(){if(void 0===window.MathJax&&!window.mathJaxLoading){window.mathJaxLoading=!0,window.MathJax||(window.MathJax={loader:{load:["input/tex","output/svg"]},tex:{packages:{"[+]":["ams"]},inlineMath:[["$","$"],["\\(","\\)"]],displayMath:[["$$","$$"],["\\[","\\]"]],processEscapes:!0,processEnvironments:!0},options:{renderActions:{addMenu:[]},ignoreHtmlClass:"tex2jax_ignore",processHtmlClass:"tex2jax_process"},svg:{fontCache:"none"},startup:{typeset:!1}});const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js",e.async=!0,e.onload=()=>{window.mathJaxLoading=!1,this._typesetMath(this.previewPanel||document)},e.onerror=()=>{window.mathJaxLoading=!1,console.error("Failed to load MathJax")},document.head.appendChild(e)}}renderTable(e,t){const n=this.escapeHtml(e);try{const o="csv"===t?",":"psv"===t?"|":"\t",r=e.trim().split("\n");if(0===r.length)return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`;let i=`<table class="qde-data-table qde-csv-table" data-qd-fence="\`\`\`" data-qd-lang="${t}">`;const a=this.parseCSVLine(r[0],o);if(i+="<thead><tr>",a.forEach(e=>{i+=`<th>${this.escapeHtml(e.trim())}</th>`}),i+="</tr></thead>",r.length>1){i+="<tbody>";for(let e=1;e<r.length;e++){const t=this.parseCSVLine(r[e],o);i+="<tr>",t.forEach(e=>{i+=`<td>${this.escapeHtml(e.trim())}</td>`}),i+="</tr>"}i+="</tbody>"}return i+="</table>",i}catch(e){return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`}}parseCSVLine(e,t){const n=[];let o="",r=!1;for(let i=0;i<e.length;i++){const a=e[i],s=e[i+1];'"'===a?r&&'"'===s?(o+='"',i++):r=!r:a!==t||r?o+=a:(n.push(o),o="")}return n.push(o),n}renderJSON(e,t){if(window.hljs&&hljs.getLanguage("json"))try{let n=e;try{const t=JSON.parse(e);n=JSON.stringify(t,null,2)}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}"><code class="hljs language-json">${hljs.highlight(n,{language:"json"}).value}</code></pre>`}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}">${this.escapeHtml(e)}</pre>`}renderGeoJSON(e){const t=`map-${Math.random().toString(36).substr(2,15)}`,n=()=>{const n=document.getElementById(t+"-container");if(n&&window.L)try{const o=JSON.parse(e),r=document.createElement("div");r.id=t,r.style.cssText="width: 100%; height: 300px;",n.innerHTML="",n.appendChild(r);const i=!this.options.allowExternalFetch,a={zoomAnimation:!i,fadeAnimation:!i};i&&(a.minZoom=2,a.maxBounds=[[-84,-180],[84,180]],a.maxBoundsViscosity=.85);const s=L.map(t,a);if(i){s.getContainer().classList.add("qde-offline-map");const e=s.getPane("tilePane");e&&(e.style.display="none")}n._map=s;let l=null;const c=this.container.classList.contains("qde-dark");if(!this.options.allowExternalFetch&&window._qde_worldGeoJSON){const e=e=>({weight:e<4?.45:e<6?.75:c?1:1.1,color:c?"#b8b8b8":"#1a1a1a",fillColor:c?"#3a3a3e":"#ebe6d9",fillOpacity:1}),t=e=>({weight:e<6?.45:c?.5:.6,color:c?"#666":"#555",fillOpacity:0,fill:!1}),n=L.geoJSON(window._qde_worldGeoJSON,{smoothFactor:1.5,style:()=>e(s.getZoom()),interactive:!1}).addTo(s);let o=null;window._qde_admin1GeoJSON&&(o=L.geoJSON(window._qde_admin1GeoJSON,{smoothFactor:1,style:()=>t(s.getZoom()),interactive:!1}));const r=()=>{const r=s.getZoom();n.setStyle(e(r)),o&&(r>=5?(o.setStyle(t(r)),s.hasLayer(o)||o.addTo(s)):s.hasLayer(o)&&s.removeLayer(o))};s.on("zoomend",r),r()}else l=L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:"",crossOrigin:"anonymous"}),l.addTo(s);const d=L.geoJSON(o);d.addTo(s);const h=d.getBounds();if(h.isValid()){const e=h.getSouthWest(),t=h.getNorthEast();e.lat===t.lat&&e.lng===t.lng?s.setView([e.lat,e.lng],8):s.fitBounds(h,{padding:[28,28],maxZoom:6})}else s.setView([0,0],2);n._tileLayer=l,n._geoJsonLayer=d,l?l.on("load",()=>{n.setAttribute("data-tiles-loaded","true")}):n.setAttribute("data-tiles-loaded","true")}catch(e){n.innerHTML=`<pre class="qde-error">GeoJSON error: ${this.escapeHtml(e.message)}</pre>`}},o=()=>{!this.options.allowExternalFetch&&!window._qde_worldGeoJSON&&"function"==typeof window._qde_ensureBasemap?window._qde_ensureBasemap().then(()=>n()).catch(e=>{const n=document.getElementById(t+"-container");n&&(n.innerHTML=`<pre class="qde-error">Basemap load failed: ${this.escapeHtml(e.message)}</pre>`)}):n()};window.L?setTimeout(o,0):(window._qde_leaflet_loading||(window._qde_leaflet_loading=this.lazyLoadLibrary("Leaflet",()=>window.L,"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js","https://unpkg.com/leaflet@1.9.4/dist/leaflet.css").catch(e=>(console.warn("Failed to load Leaflet:",e),window._qde_leaflet_loading=null,!1))),window._qde_leaflet_loading.then(e=>{if(e)o();else{const e=document.getElementById(t+"-container");e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load map library</div>')}}).catch(()=>{}));const r=document.createElement("div");return r.className="geojson-container",r.id=t+"-container",r.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0; background: #f0f0f0;",r.contentEditable="false",r.setAttribute("data-source-type","geojson"),r.setAttribute("data-original-source",this.escapeHtml(e)),r.setAttribute("data-qd-fence","```"),r.setAttribute("data-qd-lang","geojson"),r.setAttribute("data-qd-source",e),r.textContent="Loading map...",r.outerHTML}renderSTL(e){const t=`qde-stl-viewer-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,n=()=>{const n=document.getElementById(t);if(n)try{const t=window.THREE,o=new t.Scene;o.background=new t.Color(15790320);const r=new t.PerspectiveCamera(75,n.clientWidth/400,.1,1e3),i=new t.WebGLRenderer({antialias:!0});i.setSize(n.clientWidth,400),n.innerHTML="",n.appendChild(i.domElement),n._threeScene=o,n._threeCamera=r,n._threeRenderer=i;const a=this.parseSTL(e),s=new t.MeshLambertMaterial({color:26367}),l=new t.Mesh(a,s);o.add(l);const c=new t.AmbientLight(4210752,.6);o.add(c);const d=new t.DirectionalLight(16777215,.8);d.position.set(1,1,1).normalize(),o.add(d);const h=(new t.Box3).setFromObject(l),u=h.getCenter(new t.Vector3),p=h.getSize(new t.Vector3),g=Math.max(p.x,p.y,p.z);r.position.set(u.x+g,u.y+g,u.z+g),r.lookAt(u);const m=()=>{requestAnimationFrame(m),l.rotation.y+=.01,i.render(o,r)};m()}catch(e){console.error("STL rendering error:",e),n.innerHTML=`<pre class="qde-error">STL error: ${this.escapeHtml(e.message)}</pre>`}};return window.THREE?setTimeout(n,0):(window._qde_three_loading||(window._qde_three_loading=this.lazyLoadLibrary("Three.js",()=>window.THREE,"https://unpkg.com/three@0.147.0/build/three.min.js").catch(e=>(console.warn("Failed to load Three.js for STL rendering"),window._qde_three_loading=null,!1))),window._qde_three_loading.then(e=>{if(e)n();else{const e=document.getElementById(t);e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load Three.js for STL rendering</div>')}})),`<div id="${t}" class="qde-stl-container" data-stl-id="${t}" data-qd-fence="\`\`\`" data-qd-lang="stl" data-qd-source="${this.escapeHtml(e)}" contenteditable="false" style="height: 400px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;">Loading 3D model...</div>`}parseSTL(e){const t=window.THREE,n=new t.BufferGeometry,o=[],r=[],i=e.split("\n");let a=null;for(let e of i)if(e=e.trim(),e.startsWith("facet normal")){const t=e.split(/\s+/);a=[parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4])]}else if(e.startsWith("vertex")){const t=e.split(/\s+/);o.push(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3])),a&&r.push(a[0],a[1],a[2])}return n.setAttribute("position",new t.Float32BufferAttribute(o,3)),n.setAttribute("normal",new t.Float32BufferAttribute(r,3)),n}renderABC(e){const t=`qde-abc-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,n=()=>{const n=document.getElementById(t);if(n&&window.ABCJS)try{n.innerHTML="",window.ABCJS.renderAbc(n,e,{responsive:"resize"})}catch(e){n.innerHTML=`<pre class="qde-error">ABC notation error: ${this.escapeHtml(e.message)}</pre>`}};window.ABCJS?setTimeout(n,0):(window._qde_abcjs_loading||(window._qde_abcjs_loading=this.lazyLoadLibrary("ABCJS",()=>window.ABCJS,"https://cdn.jsdelivr.net/npm/abcjs@6/dist/abcjs-basic-min.js").catch(e=>(console.warn("Failed to load ABCJS:",e),window._qde_abcjs_loading=null,!1))),window._qde_abcjs_loading.then(e=>{if(e)n();else{const e=document.getElementById(t);e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load ABC notation library</div>')}}));const o=document.createElement("div");return o.id=t,o.className="qde-abc-container",o.contentEditable="false",o.setAttribute("data-qd-source",e),o.setAttribute("data-qd-fence","```"),o.setAttribute("data-qd-lang","abc"),o.style.cssText="min-height: 80px; margin: 0.5em 0;",o.textContent="Loading music notation...",o.outerHTML}renderVega(e,t){const n=`qde-vega-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,o=()=>{const o=document.getElementById(n);if(o&&window.vegaEmbed)try{const n=JSON.parse(e);if("vega-lite"!==t&&"vegalite"!==t||n.$schema||(n.$schema="https://vega.github.io/schema/vega-lite/v5.json"),!this.options.allowExternalFetch){const e=JSON.stringify(n);if(/"url"\s*:/.test(e))return void(o.innerHTML='<div style="padding: 12px; background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; color: #856404; font-size: 0.9em;">⚠ This Vega spec references external data URLs. External fetch is disabled in offline mode. Use inline <code>"values"</code> instead.</div>')}window.vegaEmbed(o,n,{renderer:"svg",actions:!1}).catch(e=>{o.innerHTML=`<pre class="qde-error">Vega error: ${this.escapeHtml(e.message)}</pre>`})}catch(e){o.innerHTML=`<pre class="qde-error">Vega JSON error: ${this.escapeHtml(e.message)}</pre>`}};window.vegaEmbed?setTimeout(o,0):(window._qde_vega_loading||(window._qde_vega_loading=(async()=>{try{return await this.loadScript("https://cdn.jsdelivr.net/npm/vega@5"),await this.loadScript("https://cdn.jsdelivr.net/npm/vega-lite@5"),await this.loadScript("https://cdn.jsdelivr.net/npm/vega-embed@6"),!!window.vegaEmbed}catch(e){return console.warn("Failed to load Vega:",e),window._qde_vega_loading=null,!1}})()),window._qde_vega_loading.then(e=>{if(e)o();else{const e=document.getElementById(n);e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load Vega visualization library</div>')}}));const r=document.createElement("div");return r.id=n,r.className="qde-vega-container",r.contentEditable="false",r.setAttribute("data-qd-source",e),r.setAttribute("data-qd-fence","```"),r.setAttribute("data-qd-lang",t),r.style.cssText="min-height: 100px; margin: 0.5em 0;",r.textContent="Loading visualization...",r.outerHTML}renderMermaid(e){const t=`mermaid-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;setTimeout(()=>{const n=document.getElementById(t);n&&window.mermaid&&mermaid.render(t+"-svg",e).then(e=>{n.innerHTML=e.svg}).catch(e=>{n.innerHTML=`<pre>Error rendering diagram: ${this.escapeHtml(e.message)}</pre>`})},0);const n=document.createElement("div");return n.id=t,n.className="mermaid",n.contentEditable="false",n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","mermaid"),n.textContent="Loading diagram...",n.outerHTML}escapeHtml(e){return(e??"").replace(/[&"'<>]/g,e=>({"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"}[e]))}async loadPlugins(){const e=new Set;this.options.plugins&&(this.options.plugins.highlightjs&&e.add("highlightjs"),this.options.plugins.mermaid&&e.add("mermaid"));const t=this.options.preloadFences;if("all"===t)Object.keys(this._fenceLibraries).forEach(t=>e.add(t));else if(Array.isArray(t))for(const n of t)"string"==typeof n?this._fenceLibraries[n]?e.add(n):console.warn(`QuikdownEditor: unknown preloadFences entry "${n}"`):n&&"object"==typeof n&&n.script&&(e.add("__custom__:"+(n.name||n.script)),this._fenceLibraries["__custom__:"+(n.name||n.script)]={check:()=>!1,script:n.script,css:n.css});else t&&console.warn('QuikdownEditor: preloadFences should be "all", an array, or null');const n=[];for(const t of e){const e=this._fenceLibraries[t];if(!e||e.check())continue;e.beforeLoad&&e.beforeLoad();const o=(async()=>{try{const t=[];if(e.scripts)for(const t of e.scripts)await this.loadScript(t);else e.script&&t.push(this.loadScript(e.script));e.css&&t.push(this.loadCSS(e.css,"qde-hljs-light")),e.cssDark&&t.push(this.loadCSS(e.cssDark,"qde-hljs-dark")),await Promise.all(t),e.css&&e.cssDark&&this._syncHljsTheme(),e.afterLoad&&e.afterLoad()}catch(e){console.warn(`QuikdownEditor: failed to preload ${t}:`,e)}})();n.push(o)}await Promise.all(n)}async lazyLoadLibrary(e,t,n,o=null){if(t())return!0;try{const e=[];return n&&e.push(this.loadScript(n)),o&&e.push(this.loadCSS(o)),await Promise.all(e),t()}catch(t){return console.error(`Failed to load ${e}:`,t),!1}}loadScript(e){return new Promise((t,n)=>{const o=document.createElement("script");o.src=e,o.onload=t,o.onerror=n,document.head.appendChild(o)})}loadCSS(e,t){return new Promise(n=>{const o=document.createElement("link");o.rel="stylesheet",o.href=e,t&&(o.id=t),o.onload=n,document.head.appendChild(o),setTimeout(n,1e3)})}_syncHljsTheme(){const e=this.container.classList.contains("qde-dark"),t=document.getElementById("qde-hljs-light"),n=document.getElementById("qde-hljs-dark");t&&(t.disabled=e),n&&(n.disabled=!e)}applyTheme(){const e=this.options.theme;if(this._autoThemeListener&&(window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change",this._autoThemeListener),this._autoThemeListener=null),"auto"===e){const e=window.matchMedia("(prefers-color-scheme: dark)");this.container.classList.toggle("qde-dark",e.matches),this._autoThemeListener=e=>{this.container.classList.toggle("qde-dark",e.matches),this._syncHljsTheme()},e.addEventListener("change",this._autoThemeListener)}else this.container.classList.toggle("qde-dark","dark"===e);this._syncHljsTheme()}setTheme(e){["light","dark","auto"].includes(e)&&(this.options.theme=e,this.applyTheme())}getTheme(){return this.options.theme}setLazyLinefeeds(e){this.options.lazy_linefeeds=e,this._markdown&&this.updateFromMarkdown(this._markdown)}getLazyLinefeeds(){return this.options.lazy_linefeeds}setDebounceDelay(e){this.options.debounceDelay=Math.max(0,e)}getDebounceDelay(){return this.options.debounceDelay}setMode(e){if(!["source","preview","split"].includes(e))return;const t=this.container.classList.contains("qde-dark"),n=this.currentMode;if(this.currentMode=e,this.container.className=`qde-container qde-mode-${e}`,t&&this.container.classList.add("qde-dark"),this.toolbar){const e=this.toolbar.querySelector(".qde-split-toggle");e&&(e.textContent="Preview")}this.toolbar&&this.toolbar.querySelectorAll(".qde-btn[data-mode]").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)}),"source"!==e&&"source"===n&&this._html&&(this.previewPanel.innerHTML=this._html,this._typesetMath(this.previewPanel)),this.options.onModeChange&&this.options.onModeChange(e)}_pushUndoState(e){if(e===this._markdown)return;this._undoStack.push(this._markdown);const t=this.options.undoStackSize||100;this._undoStack.length>t&&this._undoStack.splice(0,this._undoStack.length-t),this._redoStack=[],this._updateUndoButtons()}undo(){if(!this.canUndo())return;this._redoStack.push(this._markdown);const e=this._undoStack.pop();this._isUndoRedo=!0,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e),this._updateUndoButtons()}redo(){if(!this.canRedo())return;this._undoStack.push(this._markdown);const e=this._redoStack.pop();this._isUndoRedo=!0,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e),this._updateUndoButtons()}canUndo(){return this._undoStack.length>0}canRedo(){return this._redoStack.length>0}clearHistory(){this._undoStack=[],this._redoStack=[],this._updateUndoButtons()}_updateUndoButtons(){if(!this.toolbar)return;const e=this.toolbar.querySelector('[data-action="undo"]'),t=this.toolbar.querySelector('[data-action="redo"]');e&&e.classList.toggle("disabled",!this.canUndo()),t&&t.classList.toggle("disabled",!this.canRedo())}handleAction(e){switch(e){case"copy-markdown":this.copy("markdown");break;case"copy-html":this.copy("html");break;case"copy-rendered":this.copyRendered();break;case"remove-hr":this.removeHR();break;case"lazy-linefeeds":this.convertLazyLinefeeds();break;case"undo":this.undo();break;case"redo":this.redo();break;case"toggle-html-mode":this.cycleAllowUnsafeHTML()}}async copy(e){const t="markdown"===e?this._markdown:this._html;try{await navigator.clipboard.writeText(t);const n=this.toolbar.querySelector(`[data-action="copy-${e}"]`);if(n){const e=n.textContent;n.textContent="Copied!",setTimeout(()=>{n.textContent=e},1500)}}catch(e){console.error("Failed to copy:",e)}}get markdown(){return this._markdown}set markdown(e){this.setMarkdown(e)}get html(){return this._html}get mode(){return this.currentMode}async setMarkdown(e){this.initPromise&&await this.initPromise,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e)}getMarkdown(){return this._markdown}getHTML(){return this._html}async removeHR(){const e=R.removeHRFromMarkdown(this._markdown);await this.setMarkdown(e);const t=this.toolbar?.querySelector('[data-action="remove-hr"]');if(t){const e=t.textContent;t.textContent="Removed!",setTimeout(()=>{t.textContent=e},1500)}}static removeHRFromMarkdown(o){const i=(o||"").split("\n"),a=[];let s=!1,l=null,c=0;for(let o=0;o<i.length;o++){const d=i[o],h=d.trim();if(s)n(h,l,c)&&(s=!1,l=null,c=0),a.push(d);else{{const e=t(h);if(e){s=!0,l=e.char,c=e.len,a.push(d);continue}}if(/^\|.*\|$/.test(h)||/^[-| :]+$/.test(h)&&h.includes("|"))a.push(d);else{if(e(h)){const e=o>0?i[o-1].trim():"",t=o<i.length-1?i[o+1].trim():"";if(r(e)||r(t)){a.push(d);continue}continue}a.push(d)}}}return a.join("\n")}async convertLazyLinefeeds(){const e=R.convertLazyLinefeeds(this._markdown);await this.setMarkdown(e);const t=this.toolbar?.querySelector('[data-action="lazy-linefeeds"]');if(t){const e=t.textContent;t.textContent="Converted!",setTimeout(()=>{t.textContent=e},1500)}}static convertLazyLinefeeds(e){const r=(e||"").split("\n"),i=[];let a=!1,s=null,l=0;for(const e of r){const r=e,c=r.trim();if(a){n(c,s,l)?(a=!1,s=null,l=0,i.push({line:r,kind:"fence-close"})):i.push({line:r,kind:"fence-body"});continue}{const e=t(c);if(e){a=!0,s=e.char,l=e.len,i.push({line:r,kind:"fence-open"});continue}}if(""===c){i.push({line:"",kind:"blank"});continue}let d=o(c);"paragraph"===d&&/^(?: {4}|\t| {2,}[-*+]| {2,}\d+\.)/.test(r)&&(d="list-cont"),i.push({line:r,kind:"content",category:d})}const c=[];let d=null;function h(e,t){return!(!e||!t)&&(!("list-ul"!==e.category&&"list-ol"!==e.category&&"list-cont"!==e.category||"list-ul"!==t.category&&"list-ol"!==t.category&&"list-cont"!==t.category)||("blockquote"===e.category&&"blockquote"===t.category||"table"===e.category&&"table"===t.category))}for(const e of i)"fence-open"!==e.kind&&"fence-body"!==e.kind&&"fence-close"!==e.kind?"blank"!==e.kind&&(d&&(h(d,e)||""!==c[c.length-1]&&c.push("")),c.push(e.line),d=e):("fence-open"===e.kind&&d&&c.length>0&&""!==c[c.length-1]&&c.push(""),c.push(e.line),"fence-close"===e.kind&&(d={kind:"content",category:"fence"}));for(;c.length>0&&""===c[c.length-1];)c.pop();return c.join("\n")}async copyRendered(e="default"){try{if((await N(this.previewPanel,{output:e})).success){const e=this.toolbar?.querySelector('[data-action="copy-rendered"]');if(e){const t=e.textContent;e.textContent="Copied!",setTimeout(()=>{e.textContent=t},1500)}}}catch(e){console.error("Failed to copy rendered content:",e)}}_getHtmlModeLabel(e){return!0===e?"HTML: Raw":"limited"===e?"HTML: Safe":"HTML: Off"}_getHtmlModeTooltip(e){return!0===e?"All HTML passes through — no protection":"limited"===e?"Safe tags render, dangerous tags escaped":"All HTML tags shown as text"}cycleAllowUnsafeHTML(){const e=this.options.allowUnsafeHTML;let t;t=!1===e?"limited":"limited"===e,this.setAllowUnsafeHTML(t)}setAllowUnsafeHTML(e){if(!1===e||!0===e||"limited"===e){if(this.options.allowUnsafeHTML=e,this.toolbar){const t=this.toolbar.querySelector('[data-action="toggle-html-mode"]');t&&(t.textContent=this._getHtmlModeLabel(e),t.title=this._getHtmlModeTooltip(e))}this.updateFromMarkdown(this._markdown)}}getAllowUnsafeHTML(){return this.options.allowUnsafeHTML}destroy(){clearTimeout(this.updateTimer),this.container.innerHTML="",this.container.classList.remove("qde-container","qde-dark");if(0===document.querySelectorAll(".qde-container").length){const e=document.getElementById("qde-styles");e&&e.remove()}}}R.SAFE_HTML_TAGS=F,R.version="1.2.22","undefined"!=typeof module&&module.exports&&(module.exports=R),"undefined"!=typeof window&&(window.QuikdownEditor=R);export{R as default};
//# sourceMappingURL=quikdown_edit.esm.min.js.map