jotterjs 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,7 @@ A lightweight, vanilla JS rich-text editor component built on `contenteditable`.
12
12
  - Pre-built toolbar presets (`minimal`, `writing`, `full`) and fully custom toolbar support
13
13
  - Custom toolbar buttons with `onClick` callbacks
14
14
  - Replaceable insert dialogs — swap the built-in image/link/video/embed popups for your own UI
15
+ - Click to select an image, video, or embed block: resize by dragging its handles, drag it to reposition, or copy/cut/paste it like any other content
15
16
  - Selection bookmarks that survive async host UI and DOM mutation
16
17
  - Event system (`change`, `focus`, `blur`)
17
18
  - Keyboard-operable toolbar — every control activates with Enter and Space
@@ -261,6 +262,33 @@ Two known gaps: `Tab` inside the editing area inserts indentation rather than
261
262
  moving focus, so reach the toolbar by tabbing in from before the editor; and the
262
263
  symbol and special-character grids are one tab stop per character.
263
264
 
265
+ ## Media blocks
266
+
267
+ Images, YouTube embeds, and generic embeds behave as atomic, direct-manipulation
268
+ blocks rather than plain inline content:
269
+
270
+ - **Select** — click one to show a selection frame with resize handles. Video
271
+ and embed content is never interactive while editing (clicking it always
272
+ selects the block instead of playing/activating it), so nothing behind it
273
+ can hijack the click.
274
+ - **Resize** — drag any handle to change its width; height always follows on
275
+ its own (natural image aspect ratio, the video's 16:9 box, or an embed's
276
+ normal reflow), so there's nothing to distort.
277
+ - **Move** — once selected, drag the block itself to reposition it elsewhere
278
+ in the document. A plain click that doesn't move the pointer just keeps it
279
+ selected, exactly as before.
280
+ - **Delete** — Backspace or Delete removes the selected block.
281
+ - **Copy / Cut / Paste** — work like they do anywhere else, including across
282
+ browser tabs and other JotterJS instances: copying or cutting a selected
283
+ block puts clean HTML on the system clipboard (no internal bookkeeping like
284
+ the click-shield leaks out), and pasting sanitizes and re-inserts it, so a
285
+ pasted video/embed block is fully functional again.
286
+
287
+ All of the above go through `document.execCommand`, so they participate in the
288
+ same native undo/redo stack as typing and toolbar commands (Ctrl+Z / Ctrl+Y,
289
+ or the Undo/Redo buttons). A move is internally a delete-then-insert, so
290
+ unwinding one takes two undo steps rather than one.
291
+
264
292
  ## Development
265
293
 
266
294
  ```bash
@@ -1,5 +1,5 @@
1
- var JotterJS=(()=>{var v=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var M=(h,e)=>{for(var t in e)v(h,t,{get:e[t],enumerable:!0})},w=(h,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of L(e))!T.call(h,o)&&o!==t&&v(h,o,{get:()=>e[o],enumerable:!(i=x(e,o))||i.enumerable});return h};var j=h=>w(v({},"__esModule",{value:!0}),h);var D={};M(D,{JotterJS:()=>m,default:()=>z});var f={source:{custom:"toggleSource",label:"Source",title:"Edit HTML Source"},sep:{type:"sep"},blockformat:{type:"blockformat"},fontfamily:{type:"fontfamily"},fontsize:{type:"fontsize"},theme:{type:"theme"},undo:{cmd:"undo",icon:"undo",title:"Undo (Ctrl+Z)"},redo:{cmd:"redo",icon:"redo",title:"Redo (Ctrl+Y)"},bold:{cmd:"bold",icon:"format_bold",title:"Bold (Ctrl+B)"},italic:{cmd:"italic",icon:"format_italic",title:"Italic (Ctrl+I)"},underline:{cmd:"underline",icon:"format_underlined",title:"Underline (Ctrl+U)"},strike:{cmd:"strikeThrough",icon:"strikethrough_s",title:"Strikethrough"},subscript:{cmd:"subscript",icon:"subscript",title:"Subscript"},superscript:{cmd:"superscript",icon:"superscript",title:"Superscript"},code:{custom:"code",icon:"code",title:"Inline Code"},copy:{cmd:"copy",icon:"content_copy",title:"Copy"},cut:{cmd:"cut",icon:"content_cut",title:"Cut"},paste:{cmd:"paste",icon:"content_paste",title:"Paste"},clearFormat:{cmd:"removeFormat",icon:"format_clear",title:"Clear Formatting"},alignLeft:{cmd:"justifyLeft",icon:"format_align_left",title:"Align Left"},alignCenter:{cmd:"justifyCenter",icon:"format_align_center",title:"Align Center"},alignRight:{cmd:"justifyRight",icon:"format_align_right",title:"Align Right"},bullets:{cmd:"insertUnorderedList",icon:"format_list_bulleted",title:"Bullet List"},numbered:{cmd:"insertOrderedList",icon:"format_list_numbered",title:"Numbered List"},link:{type:"popup",id:"link",icon:"insert_link",title:"Insert Link"},unlink:{cmd:"unlink",icon:"link_off",title:"Remove Link"},foreColor:{type:"color",cmd:"foreColor",icon:"format_color_text",title:"Text Color"},hiliteColor:{type:"color",cmd:"hiliteColor",icon:"format_color_fill",title:"Background Color"},image:{type:"popup",id:"image",icon:"image",title:"Insert Image"},video:{type:"popup",id:"video",icon:"smart_display",title:"Insert YouTube Video"},table:{type:"popup",id:"table",icon:"table_chart",title:"Insert Table"},embed:{type:"popup",id:"embed",icon:"html",title:"Insert Embed"},symbol:{type:"popup",id:"symbol",icon:"emoji_symbols",title:"Insert Symbol"},specialChar:{type:"popup",id:"specialchar",icon:"format_shapes",title:"Special Characters"},lorem:{type:"popup",id:"lorem",icon:"history_edu",title:"Insert Lorem Ipsum"}};Object.values(f).forEach(Object.freeze);Object.freeze(f);var n=f,_={minimal:[n.source,n.sep,n.bold,n.italic,n.underline,n.sep,n.link,n.unlink],writing:[n.source,n.sep,n.undo,n.redo,n.sep,n.blockformat,n.sep,n.bold,n.italic,n.underline,n.strike,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image],full:[n.source,n.sep,n.undo,n.redo,n.sep,n.copy,n.cut,n.paste,n.sep,n.clearFormat,n.sep,n.blockformat,n.fontfamily,n.fontsize,n.sep,n.bold,n.italic,n.underline,n.strike,n.subscript,n.superscript,n.code,n.sep,n.foreColor,n.hiliteColor,n.sep,n.alignLeft,n.alignCenter,n.alignRight,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image,n.video,n.table,n.embed,n.symbol,n.specialChar,n.lorem,n.sep,n.theme]};Object.values(_).forEach(Object.freeze);Object.freeze(_);var N=_.full,R={image:"onRequestImage",link:"onRequestLink",video:"onRequestVideo",embed:"onRequestEmbed"},k=[{label:"Paragraph",tag:"p"},{label:"Heading 1",tag:"h1"},{label:"Heading 2",tag:"h2"},{label:"Heading 3",tag:"h3"},{label:"Heading 4",tag:"h4"},{label:"Pre / Code",tag:"pre"},{label:"Blockquote",tag:"blockquote"}],A=["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Impact","Lucida Console","Palatino Linotype","Tahoma","Times New Roman","Trebuchet MS","Verdana"],I=[8,9,10,11,12,14,16,18,20,24,28,32,36,48,72],B=["\u2190","\u2192","\u2191","\u2193","\u2194","\u2195","\u21D0","\u21D2","\u21D1","\u21D3","\u21D4","\u2022","\xB7","\u25E6","\u25CB","\u25CF","\u25A1","\u25A0","\u25C6","\u25C7","\u25B2","\u25BC","\u2605","\u2606","\u2660","\u2663","\u2665","\u2666","\u2713","\u2717","\u2715","\u2718","\u2248","\u2260","\u2261","\u2264","\u2265","\xF7","\xD7","\xB1","\u221E","\u221A","\u2211","\u220F","\u222B","\u2202","\u2206","\u2207","\u03C0","\u03A9","\u03BC","\u03B1","\u03B2","\u03B3","\xA9","\xAE","\u2122","\xA7","\xB6","\u2020","\u2021","\xB0","\u2032","\u2033","\u2030","\u201C","\u201D","\u2018","\u2019","\xAB","\xBB","\u2039","\u203A","\u2014","\u2013","\u2026","\xBF","\xA1","\u20AC","\xA3","\xA5","\xA2","\u20B9","\u20BD","\u20BF"],H=["\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF","\u0152","\u0153","\u0160","\u0161","\u0178","\u017D","\u017E"],E=[{id:"default",label:"Default"},{id:"warm",label:"Warm"},{id:"ink",label:"Ink / Navy"},{id:"forest",label:"Forest"}],F=[{label:"Short \u2014 1 sentence",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{label:"Medium \u2014 1 paragraph",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."},{label:"Long \u2014 3 paragraphs",isHTML:!0,text:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>"}],m=class{constructor(e,t={}){if(this._target=typeof e=="string"?document.querySelector(e):e,!this._target)throw new Error("[JotterJS] Target element not found.");this._options=Object.assign({placeholder:"Start typing\u2026",height:"320px",theme:"default",onChange:null,onFocus:null,onBlur:null,onRequestImage:null,onRequestLink:null,onRequestVideo:null,onRequestEmbed:null},t),this._listeners={},this._bookmarks=new Map,this._bmSeq=0,this._savedBookmark=null,this._externalBookmark=null,this._externalDepth=0,this._changeCount=0,this._destroyed=!1,this._lastForeColor="#e8e4d8",this._lastHiliteColor="#c8a96e",this._selectedMedia=null,this._resizeState=null,this._onResizeMove=this._onResizeMove.bind(this),this._onResizeEnd=this._onResizeEnd.bind(this),this._init()}_init(){let e=this._target.innerHTML||"";this._target.innerHTML="",this._target.classList.add("jotter-host"),this._root=document.createElement("div"),this._root.className="htmled",this._toolbar=this._buildToolbar(),this._editorWrap=document.createElement("div"),this._editorWrap.className="jotter-editor-wrap",this._editor=document.createElement("div"),this._editor.className="jotter-editor",this._editor.contentEditable="true",this._editor.setAttribute("data-placeholder",this._options.placeholder),this._editor.style.minHeight=this._options.height,this._editor.innerHTML=this._sanitize(e),this._editor.spellcheck=!0,document.execCommand("defaultParagraphSeparator",!1,"p");try{document.execCommand("enableObjectResizing",!1,!1)}catch{}try{document.execCommand("enableInlineTableEditing",!1,!1)}catch{}this._ensureMediaShields(),this._source=document.createElement("textarea"),this._source.className="jotter-source",this._source.setAttribute("aria-label","HTML source"),this._source.setAttribute("spellcheck","false"),this._source.style.minHeight=this._options.height,this._sourceMode=!1,this._statusBar=this._buildStatusBar(),this._mediaFrame=this._buildMediaFrame(),this._editorWrap.appendChild(this._editor),this._editorWrap.appendChild(this._source),this._editorWrap.appendChild(this._mediaFrame),this._root.appendChild(this._toolbar),this._root.appendChild(this._editorWrap),this._root.appendChild(this._statusBar),this._target.appendChild(this._root),this._popup=this._buildPopupContainer(),document.body.appendChild(this._popup),this._bindEvents(),this._updateToolbarState(),this._updateStatus(),this.setTheme(this._options.theme)}_buildToolbar(){let e=document.createElement("div");return e.className="jotter-toolbar",this._toolbarEl=e,(this._options.toolbar||N).forEach(t=>{let i=this._buildAction(t);i&&e.appendChild(i)}),e}_buildAction(e){if(typeof e.onClick=="function")return this._buildBtn(e);switch(e.type){case"sep":return this._makeSep();case"blockformat":return this._buildBlockFormatSelect();case"fontfamily":return this._buildFontFamilySelect();case"fontsize":return this._buildFontSizeSelect();case"color":return this._buildColorBtn(e);case"popup":return this._buildPopupBtn(e);case"theme":return this._buildThemeSelect();default:return this._buildBtn(e)}}_makeSep(){let e=document.createElement("span");return e.className="jotter-sep",e}_bindActivation(e,t){e.addEventListener("mousedown",i=>{i.preventDefault(),t(!1)}),e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "&&i.key!=="Spacebar"||i.repeat||(i.preventDefault(),t(!0))})}_returnFocus(e,t){t&&this._isInternalTarget(document.activeElement)&&e.focus()}_buildBtn(e){let t=document.createElement("button");if(t.type="button",t.className="jotter-btn",e.cmd&&(t.dataset.cmd=e.cmd),e.custom&&(t.dataset.custom=e.custom),t.title=e.title,t.setAttribute("aria-label",e.title),e.label)t.classList.add("jotter-btn--text"),t.appendChild(document.createTextNode(e.label));else{let i=document.createElement("span");i.className="material-icons",i.textContent=e.icon,t.appendChild(i)}return this._bindActivation(t,i=>{this._editor.focus(),this._applyEdit(()=>{if(e.onClick)e.onClick(this);else if(e.custom==="toggleSource")this._toggleSourceMode();else if(e.custom==="code")this._toggleInlineCode();else if(e.cmd==="copy")document.execCommand("copy");else if(e.cmd==="cut")document.execCommand("cut");else if(e.cmd==="paste")this._pasteFromClipboard();else if(e.prompt){let o=window.prompt(e.prompt);o&&document.execCommand(e.cmd,!1,o)}else document.execCommand(e.cmd,!1,null)}),this._updateToolbarState(),this._returnFocus(t,i)}),t}_bindSelectCaret(e){let t={viaKeyboard:!1};return e.addEventListener("mousedown",()=>{t.viaKeyboard=!1,this._saveBookmark()}),e.addEventListener("keydown",i=>{i.key==="Tab"||i.key==="Escape"||(t.viaKeyboard=!0,this._savedBookmark==null&&this._saveBookmark())}),t}_buildBlockFormatSelect(){let e=document.createElement("select");e.className="jotter-select",e.title="Block format",e.dataset.id="blockformat",k.forEach(({label:i,tag:o})=>{let s=document.createElement("option");s.value=o,s.textContent=i,e.appendChild(s)});let t=this._bindSelectCaret(e);return e.addEventListener("change",()=>{this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("formatBlock",!1,e.value)),this._returnFocus(e,t.viaKeyboard)}),e}_buildFontFamilySelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--font",e.title="Font family",e.dataset.id="fontfamily";let t=document.createElement("option");t.value="",t.textContent="Font",e.appendChild(t),A.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=o,s.style.fontFamily=o,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("fontName",!1,e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildFontSizeSelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--size",e.title="Font size",e.dataset.id="fontsize";let t=document.createElement("option");t.value="",t.textContent="Size",e.appendChild(t),I.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=`${o}px`,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>this._applyFontSize(e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildThemeSelect(){let e=document.createElement("select");return e.className="jotter-select jotter-select--theme",e.title="Editor theme",e.dataset.id="theme",E.forEach(({id:t,label:i})=>{let o=document.createElement("option");o.value=t,o.textContent=i,e.appendChild(o)}),e.value=this._options.theme,e.addEventListener("change",()=>this.setTheme(e.value)),this._themeSelect=e,e}_buildColorBtn(e){let t=document.createElement("span");t.className="jotter-color-wrap";let i=document.createElement("button");i.type="button",i.className="jotter-btn jotter-color-btn",i.dataset.cmd=e.cmd,i.title=e.title,i.setAttribute("aria-label",e.title);let o=document.createElement("span");o.className="material-icons",o.textContent=e.icon,i.appendChild(o);let s=document.createElement("span");s.className="jotter-color-swatch";let r=e.cmd==="foreColor"?this._lastForeColor:this._lastHiliteColor;s.style.background=r,i.appendChild(s);let a=document.createElement("input");a.type="color",a.className="jotter-color-input",a.value=r,a.tabIndex=-1;let u=!1;return a.addEventListener("change",()=>{let p=a.value;s.style.background=p,e.cmd==="foreColor"?this._lastForeColor=p:this._lastHiliteColor=p,this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand(e.cmd,!1,p)),this._returnFocus(i,u)}),this._bindActivation(i,p=>{u=p,this._saveBookmark(),a.click()}),t.appendChild(i),t.appendChild(a),t}_buildPopupBtn(e){let t=document.createElement("button");t.type="button",t.className="jotter-btn",t.title=e.title,t.setAttribute("aria-label",e.title);let i=document.createElement("span");return i.className="material-icons",i.textContent=e.icon,t.appendChild(i),this._bindActivation(t,o=>{let s=this._resolverFor(e.id);if(s){this._hidePopup(),this._runResolver(e.id,s);return}if(this._saveBookmark(),this._popupVisible()&&this._popup.dataset.popupId===e.id){this._hidePopup();return}this._showPopup(t,this._buildPopupContent(e.id),e.id),o&&this._focusPopup()}),t}_focusPopup(){let e=this._popup.querySelector('input, textarea, select, button, [tabindex]:not([tabindex="-1"])');e&&e.focus()}_buildPopupContainer(){let e=document.createElement("div");return e.className="jotter-popup",e.setAttribute("role","dialog"),e}_showPopup(e,t,i){this._popup.innerHTML="",this._popup.appendChild(t),this._popup.dataset.popupId=i,this._popup.classList.add("jotter-popup--visible");let o=e.getBoundingClientRect();this._popup.style.top=o.bottom+6+"px",this._popup.style.left=o.left+"px",this._popup.style.right="auto",requestAnimationFrame(()=>{let s=this._popup.getBoundingClientRect();s.right>window.innerWidth-8&&(this._popup.style.left=Math.max(8,o.left-(s.right-window.innerWidth+8))+"px")})}_popupVisible(){return this._popup.classList.contains("jotter-popup--visible")}_hidePopup(){this._popup.classList.remove("jotter-popup--visible"),this._popup.dataset.popupId="",this._releaseSavedBookmark()}_buildPopupContent(e){switch(e){case"link":return this._popupLink();case"table":return this._popupTable();case"image":return this._popupImage();case"video":return this._popupVideo();case"embed":return this._popupEmbed();case"symbol":return this._popupSymbol();case"specialchar":return this._popupSpecialChar();case"lorem":return this._popupLorem();default:{let t=document.createElement("div");return t.className="jotter-popup-inner",t.textContent="Unknown: "+e,t}}}_popupTable(){let e=document.createElement("div");e.className="jotter-popup-inner";let t=this._popupTitle("Insert Table");e.appendChild(t);let i=10,o=8,s=document.createElement("div");s.className="jotter-table-grid",s.style.gridTemplateColumns=`repeat(${i}, 1fr)`,s.setAttribute("role","grid"),s.setAttribute("aria-label","Table size");let r=document.createElement("div");r.className="jotter-popup-hint",r.textContent="Hover or arrow to select size";let a=[],u=(c,l)=>{r.textContent=`${c+1} \xD7 ${l+1} table`,a.forEach(d=>{d.classList.toggle("jotter-table-cell--active",+d.dataset.r<=c&&+d.dataset.c<=l)})};for(let c=0;c<o;c++)for(let l=0;l<i;l++){let d=document.createElement("span");d.className="jotter-table-cell",d.dataset.r=c,d.dataset.c=l,d.setAttribute("role","gridcell"),d.setAttribute("aria-label",`${c+1} by ${l+1} table`),d.tabIndex=c===0&&l===0?0:-1,d.addEventListener("mouseenter",()=>u(c,l)),d.addEventListener("focus",()=>u(c,l)),d.addEventListener("click",()=>this._insertTable(c+1,l+1)),a.push(d),s.appendChild(d)}let p={ArrowRight:[0,1],ArrowLeft:[0,-1],ArrowDown:[1,0],ArrowUp:[-1,0]};return s.addEventListener("keydown",c=>{let l=a.indexOf(document.activeElement)===-1?null:document.activeElement;if(!l)return;let d=+l.dataset.r,C=+l.dataset.c;if(c.key==="Enter"||c.key===" "||c.key==="Spacebar"){c.preventDefault(),this._insertTable(d+1,C+1);return}let b=p[c.key];if(!b)return;c.preventDefault();let S=Math.min(o-1,Math.max(0,d+b[0])),y=Math.min(i-1,Math.max(0,C+b[1])),g=a[S*i+y];g!==l&&(l.tabIndex=-1,g.tabIndex=0,g.focus())}),e.appendChild(s),e.appendChild(r),e}_commitPopup(e){this._restoreSavedBookmark(),this._hidePopup(),this._applyEdit(e)}_insertTable(e,t){let i="<table><tbody>";for(let o=0;o<e;o++){i+="<tr>";for(let s=0;s<t;s++)i+=o===0?"<th><br></th>":"<td><br></td>";i+="</tr>"}i+="</tbody></table><p><br></p>",this._commitPopup(()=>document.execCommand("insertHTML",!1,i))}_popupLink(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Link"));let t=this._anchorInSelection(),i=this._selectedText(),o=this._makeField(e,"URL","url","https://"),s=this._makeField(e,"Link text (leave blank to keep selection)","text",""),r=this._makeField(e,"Title / tooltip","text",""),a=document.createElement("label");a.className="jotter-popup-label",a.textContent="Open in";let u=document.createElement("select");return u.className="jotter-popup-select",[["(same window)",""],["New tab (_blank)","_blank"],["Parent frame (_parent)","_parent"],["Top frame (_top)","_top"]].forEach(([p,c])=>{let l=document.createElement("option");l.value=c,l.textContent=p,u.appendChild(l)}),e.appendChild(a),e.appendChild(u),t?(o.value=t.getAttribute("href")||"",s.value=t.textContent||"",r.value=t.getAttribute("title")||"",u.value=t.getAttribute("target")||""):i&&(s.value=i),e.appendChild(this._makeSubmitBtn(t?"Update Link":"Insert Link",()=>{let p=o.value.trim();if(!p)return;let c=s.value.trim()||i||p,l=r.value.trim(),d=u.value;this._commitPopup(()=>{t?(t.href=p,d?t.target=d:t.removeAttribute("target"),l?t.title=l:t.removeAttribute("title"),t.textContent=c):document.execCommand("insertHTML",!1,this._linkHTML({href:p,text:c,title:l,target:d}))})})),e}_popupImage(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Image"));let t=this._makeField(e,"Image URL","text","https://example.com/image.jpg"),i=this._makeField(e,"Alt text","text","Descriptive text"),o=this._makeField(e,"Width (e.g. 400px or 50%)","text","");return e.appendChild(this._makeSubmitBtn("Insert Image",()=>{let s=t.value.trim();if(!s)return;let r=this._imageHTML({src:s,alt:i.value.trim(),width:o.value.trim()});this._commitPopup(()=>document.execCommand("insertHTML",!1,r))})),e}_popupVideo(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert YouTube Video"));let t=this._makeField(e,"YouTube URL","text","https://www.youtube.com/watch?v=...");return e.appendChild(this._makeSubmitBtn("Embed Video",()=>{let i=this._ytId(t.value.trim());if(!i){t.classList.add("jotter-input--error");return}t.classList.remove("jotter-input--error"),this._commitPopup(()=>document.execCommand("insertHTML",!1,this._videoHTML(i)))})),e}_ytId(e){for(let t of[/[?&]v=([A-Za-z0-9_-]{11})/,/youtu\.be\/([A-Za-z0-9_-]{11})/,/embed\/([A-Za-z0-9_-]{11})/]){let i=e.match(t);if(i)return i[1]}return null}_popupEmbed(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Embed"));let t=document.createElement("label");t.className="jotter-popup-label",t.textContent="Paste HTML / embed code";let i=document.createElement("textarea");return i.className="jotter-popup-textarea",i.placeholder='<iframe src="..." ...></iframe>',i.rows=4,e.appendChild(t),e.appendChild(i),e.appendChild(this._makeSubmitBtn("Insert",()=>{let o=i.value.trim();o&&this._commitPopup(()=>document.execCommand("insertHTML",!1,this._embedHTML(o)))})),e}_popupSymbol(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Symbol")),e.appendChild(this._charGrid(B)),e}_popupSpecialChar(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Special Characters")),e.appendChild(this._charGrid(H)),e}_charGrid(e){let t=document.createElement("div");return t.className="jotter-char-grid",e.forEach(i=>{let o=document.createElement("button");o.type="button",o.className="jotter-char-btn",o.textContent=i,o.title=`U+${i.codePointAt(0).toString(16).toUpperCase().padStart(4,"0")}`,this._bindActivation(o,()=>{this._commitPopup(()=>document.execCommand("insertText",!1,i))}),t.appendChild(o)}),t}_popupLorem(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Lorem Ipsum")),F.forEach(t=>{let i=document.createElement("button");i.type="button",i.className="jotter-lorem-btn",i.textContent=t.label,this._bindActivation(i,()=>{this._commitPopup(()=>document.execCommand(t.isHTML?"insertHTML":"insertText",!1,t.text))}),e.appendChild(i)}),e}_popupTitle(e){let t=document.createElement("div");return t.className="jotter-popup-title",t.textContent=e,t}_makeField(e,t,i,o){let s=document.createElement("label");s.className="jotter-popup-label",s.textContent=t;let r=document.createElement("input");return r.type=i,r.className="jotter-popup-input",r.placeholder=o,e.appendChild(s),e.appendChild(r),r}_makeSubmitBtn(e,t){let i=document.createElement("button");return i.type="button",i.className="jotter-popup-submit",i.textContent=e,i.addEventListener("click",t),i}_esc(e){return String(e).replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}_imageHTML({src:e,alt:t,width:i}){let o=i?`max-width:${i}`:"max-width:100%";return`<img src="${this._esc(e)}" alt="${this._esc(t||"")}" style="${this._esc(o)}">`}_linkHTML({href:e,text:t,title:i,target:o}){let s=`href="${this._esc(e)}"`;return o&&(s+=` target="${this._esc(o)}"`),i&&(s+=` title="${this._esc(i)}"`),`<a ${s}>${this._esc(t||e)}</a>`}_videoHTML(e){return/^[A-Za-z0-9_-]{11}$/.test(e)?`<div class="jotter-video-wrap"><iframe src="https://www.youtube.com/embed/${e}" frameborder="0" allowfullscreen loading="lazy" title="YouTube video"></iframe></div><p><br></p>`:null}_embedHTML(e){return`<div class="jotter-embed-wrap">${e}</div><p><br></p>`}_resolverFor(e){let t=R[e],i=t?this._options[t]:null;return typeof i=="function"?i:null}async _runResolver(e,t){let i=this._resolverContext(e);this.beginExternalUI();let o=null;try{o=await t(i)}catch{o=null}if(this._destroyed)return;let s=o==null||o===!1?null:this._resolvedHTML(e,o,i);this.endExternalUI(),s&&(this._applyEdit(()=>document.execCommand("insertHTML",!1,s)),this._updateToolbarState())}_resolverContext(e){switch(e){case"image":return{src:"",alt:"",width:"",selection:this._selectedText()};case"video":return{url:"",selection:this._selectedText()};case"embed":return{html:"",selection:this._selectedText()};case"link":return this._linkContext();default:return{selection:this._selectedText()}}}_linkContext(){let e=this._anchorInSelection();if(!e){let i=this._selectedText();return{href:"",text:i,title:"",target:"",selection:i,isEdit:!1}}let t=window.getSelection();if(t){let i=document.createRange();i.selectNode(e),t.removeAllRanges(),t.addRange(i)}return{href:e.getAttribute("href")||"",text:e.textContent||"",title:e.getAttribute("title")||"",target:e.getAttribute("target")||"",selection:e.textContent||"",isEdit:!0}}_resolvedHTML(e,t,i){switch(e){case"image":{let o=typeof t=="string"?{src:t}:t,s=String(o.src||o.url||"").trim();return s?this._imageHTML({...o,src:s}):null}case"link":{let o=typeof t=="string"?{href:t}:t,s=String(o.href||o.url||"").trim();if(!s)return null;let r=String(o.text!=null?o.text:i.text||"").trim();return this._linkHTML({...o,href:s,text:r})}case"video":{let o=typeof t=="string"?{url:t}:t,s=o.id?String(o.id).trim():this._ytId(String(o.url||"").trim());return s?this._videoHTML(s):null}case"embed":{let o=String(typeof t=="string"?t:t.html||"").trim();return o?this._embedHTML(o):null}default:return null}}_selectedText(){let e=window.getSelection();return!e||!e.rangeCount?"":this._editor.contains(e.getRangeAt(0).commonAncestorContainer)?e.toString():""}_anchorInSelection(){let e=window.getSelection();if(!e||!e.rangeCount)return null;let t=e.anchorNode;if(!t||!this._editor.contains(t))return null;for(;t&&t!==this._editor;){if(t.nodeName==="A")return t;t=t.parentNode}return null}_buildStatusBar(){let e=document.createElement("div");e.className="jotter-status",this._wordCountEl=document.createElement("span"),this._wordCountEl.className="jotter-status-words",this._charCountEl=document.createElement("span"),this._charCountEl.className="jotter-status-chars";let t=document.createElement("span");return t.className="jotter-status-mode",t.textContent="HTML",e.appendChild(this._wordCountEl),e.appendChild(this._charCountEl),e.appendChild(t),e}_buildMediaFrame(){let e=document.createElement("div");return e.className="jotter-media-frame",["nw","ne","sw","se","w","e"].forEach(t=>{let i=document.createElement("div");i.className="jotter-resize-handle jotter-resize-handle--"+t,i.dataset.handle=t,i.tabIndex=-1,e.appendChild(i)}),e.addEventListener("mousedown",t=>{let i=t.target.closest(".jotter-resize-handle");!i||!this._selectedMedia||(t.preventDefault(),this._beginResize(i.dataset.handle,t))}),e}_ensureMediaShields(){this._editor.querySelectorAll(".jotter-video-wrap, .jotter-embed-wrap").forEach(e=>{if(e.querySelector(":scope > .jotter-media-shield"))return;let t=document.createElement("div");t.className="jotter-media-shield",e.appendChild(t)})}_mediaElementFromTarget(e){if(!this._editor.contains(e))return null;let t=e.closest("img");if(t&&this._editor.contains(t))return t;let i=e.closest(".jotter-video-wrap, .jotter-embed-wrap");return i&&this._editor.contains(i)?i:null}_selectMedia(e){if(this._selectedMedia===e)return;this._deselectMedia(),this._selectedMedia=e,this._positionMediaFrame(),this._mediaFrame.classList.add("jotter-media-frame--visible"),this._editor.focus({preventScroll:!0});let t=document.createRange();t.setStartBefore(e),t.collapse(!0);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._updateToolbarState()}_deselectMedia(){this._resizeState&&this._abortResize(),this._selectedMedia&&(this._selectedMedia=null,this._mediaFrame.classList.remove("jotter-media-frame--visible"))}_positionMediaFrame(){let e=this._selectedMedia;if(!e)return;let t=this._editorWrap.getBoundingClientRect(),i=e.getBoundingClientRect();this._mediaFrame.style.top=i.top-t.top+this._editorWrap.scrollTop+"px",this._mediaFrame.style.left=i.left-t.left+this._editorWrap.scrollLeft+"px",this._mediaFrame.style.width=i.width+"px",this._mediaFrame.style.height=i.height+"px"}_deleteSelectedMedia(){let e=this._selectedMedia;if(!e)return;this._deselectMedia();let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._applyEdit(()=>document.execCommand("delete",!1,null)),this._updateToolbarState()}_beginResize(e,t){let i=this._selectedMedia,o=i.getBoundingClientRect(),s=e.includes("w")?-1:1;this._resizeState={el:i,sign:s,startX:t.clientX,startWidth:o.width,startInlineWidth:i.style.width,before:this._richHTML()},document.addEventListener("mousemove",this._onResizeMove),document.addEventListener("mouseup",this._onResizeEnd,{once:!0})}_onResizeMove(e){let t=this._resizeState;if(!t)return;let i=(e.clientX-t.startX)*t.sign,o=40,s=Math.max(o,this._editor.clientWidth),r=Math.max(o,Math.min(s,Math.round(t.startWidth+i)));t.el.style.width=r+"px",t.el.style.removeProperty("max-width"),this._positionMediaFrame()}_onResizeEnd(){document.removeEventListener("mousemove",this._onResizeMove);let e=this._resizeState;this._resizeState=null,e&&(this._updateStatus(),this._richHTML()!==e.before&&this._emitChange())}_abortResize(){let e=this._resizeState;e&&(document.removeEventListener("mousemove",this._onResizeMove),document.removeEventListener("mouseup",this._onResizeEnd),e.el.style.width=e.startInlineWidth,this._resizeState=null,this._positionMediaFrame())}_bindEvents(){this._editor.addEventListener("input",()=>{this._editor.querySelectorAll(":scope > div").forEach(e=>{if(e.attributes.length>0)return;let t=document.createElement("p");t.innerHTML=e.innerHTML,e.replaceWith(t)}),Array.from(this._editor.childNodes).forEach(e=>{if(e.nodeType===Node.TEXT_NODE&&e.textContent.trim()!==""){let t=window.getSelection(),i=null;if(t&&t.rangeCount){let s=t.getRangeAt(0);s.startContainer===e&&(i=s.startOffset)}let o=document.createElement("p");if(e.replaceWith(o),o.appendChild(e),i!==null){let s=document.createRange();s.setStart(e,i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}}}),this._ensureMediaShields(),this._selectedMedia&&this._positionMediaFrame(),this._updateStatus(),this._emitChange()}),this._editor.addEventListener("keyup",()=>this._updateToolbarState()),this._editor.addEventListener("mouseup",()=>this._updateToolbarState()),this._editor.addEventListener("mousedown",e=>{let t=this._mediaElementFromTarget(e.target);t&&(e.preventDefault(),this._selectMedia(t))}),this._onWindowResize=()=>{this._selectedMedia&&this._positionMediaFrame()},window.addEventListener("resize",this._onWindowResize),this._editor.addEventListener("focusin",e=>{this._root.classList.add("jotter--focused"),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||(this._emit("focus"),this._options.onFocus&&this._options.onFocus()))}),this._editor.addEventListener("focusout",e=>{this._deselectMedia(),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||setTimeout(()=>{this._destroyed||this._externalDepth>0||this._isInternalTarget(document.activeElement)||this._popupVisible()||(this._root.classList.remove("jotter--focused"),this._emit("blur"),this._options.onBlur&&this._options.onBlur())},0))}),this._editor.addEventListener("keydown",e=>{if((e.key==="Backspace"||e.key==="Delete")&&this._selectedMedia){e.preventDefault(),this._deleteSelectedMedia();return}e.key==="Tab"&&(e.preventDefault(),document.execCommand("insertHTML",!1,"&nbsp;&nbsp;&nbsp;&nbsp;"))}),this._onDocMouseDown=e=>{this._popupVisible()&&!this._popup.contains(e.target)&&!this._toolbarEl.contains(e.target)&&this._hidePopup(),this._selectedMedia&&!this._mediaFrame.contains(e.target)&&e.target!==this._selectedMedia&&!this._selectedMedia.contains(e.target)&&this._deselectMedia()},document.addEventListener("mousedown",this._onDocMouseDown),this._onDocKeyDown=e=>{if(e.key==="Escape"){if(this._resizeState){this._abortResize();return}if(this._selectedMedia){this._deselectMedia();return}this._popupVisible()&&(this._restoreSavedBookmark(),this._hidePopup())}},document.addEventListener("keydown",this._onDocKeyDown)}_isInternalTarget(e){return!!e&&(this._root.contains(e)||this._popup.contains(e))}_toggleSourceMode(){this._deselectMedia(),this._sourceMode=!this._sourceMode,this._sourceMode?(this._dropBookmarks(),this._source.value=this._prettyHTML(this._richHTML()),this._editor.style.display="none",this._source.style.display="block"):(this._editor.innerHTML=this._sanitize(this._source.value),this._ensureMediaShields(),this._source.style.display="none",this._editor.style.display="",this._updateStatus(),this._emitChange()),this._root.classList.toggle("jotter--source-mode",this._sourceMode);let e=this._toolbarEl.querySelector('[data-custom="toggleSource"]');e&&e.classList.toggle("jotter-btn--active",this._sourceMode)}_prettyHTML(e){let t=0,i=" ",o=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),s=new Set(["a","abbr","acronym","b","bdo","big","br","button","cite","code","dfn","em","i","img","input","kbd","label","map","object","output","q","samp","select","small","span","strong","sub","sup","textarea","time","tt","u","var"]);return e.replace(/>\s+</g,"><").replace(/(<[^>]+>)/g,`
1
+ var JotterJS=(()=>{var v=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var T=(p,e)=>{for(var t in e)v(p,t,{get:e[t],enumerable:!0})},w=(p,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of x(e))!L.call(p,o)&&o!==t&&v(p,o,{get:()=>e[o],enumerable:!(i=M(e,o))||i.enumerable});return p};var j=p=>w(v({},"__esModule",{value:!0}),p);var D={};T(D,{JotterJS:()=>m,default:()=>z});var f={source:{custom:"toggleSource",label:"Source",title:"Edit HTML Source"},sep:{type:"sep"},blockformat:{type:"blockformat"},fontfamily:{type:"fontfamily"},fontsize:{type:"fontsize"},theme:{type:"theme"},undo:{cmd:"undo",icon:"undo",title:"Undo (Ctrl+Z)"},redo:{cmd:"redo",icon:"redo",title:"Redo (Ctrl+Y)"},bold:{cmd:"bold",icon:"format_bold",title:"Bold (Ctrl+B)"},italic:{cmd:"italic",icon:"format_italic",title:"Italic (Ctrl+I)"},underline:{cmd:"underline",icon:"format_underlined",title:"Underline (Ctrl+U)"},strike:{cmd:"strikeThrough",icon:"strikethrough_s",title:"Strikethrough"},subscript:{cmd:"subscript",icon:"subscript",title:"Subscript"},superscript:{cmd:"superscript",icon:"superscript",title:"Superscript"},code:{custom:"code",icon:"code",title:"Inline Code"},copy:{cmd:"copy",icon:"content_copy",title:"Copy"},cut:{cmd:"cut",icon:"content_cut",title:"Cut"},paste:{cmd:"paste",icon:"content_paste",title:"Paste"},clearFormat:{cmd:"removeFormat",icon:"format_clear",title:"Clear Formatting"},alignLeft:{cmd:"justifyLeft",icon:"format_align_left",title:"Align Left"},alignCenter:{cmd:"justifyCenter",icon:"format_align_center",title:"Align Center"},alignRight:{cmd:"justifyRight",icon:"format_align_right",title:"Align Right"},bullets:{cmd:"insertUnorderedList",icon:"format_list_bulleted",title:"Bullet List"},numbered:{cmd:"insertOrderedList",icon:"format_list_numbered",title:"Numbered List"},link:{type:"popup",id:"link",icon:"insert_link",title:"Insert Link"},unlink:{cmd:"unlink",icon:"link_off",title:"Remove Link"},foreColor:{type:"color",cmd:"foreColor",icon:"format_color_text",title:"Text Color"},hiliteColor:{type:"color",cmd:"hiliteColor",icon:"format_color_fill",title:"Background Color"},image:{type:"popup",id:"image",icon:"image",title:"Insert Image"},video:{type:"popup",id:"video",icon:"smart_display",title:"Insert YouTube Video"},table:{type:"popup",id:"table",icon:"table_chart",title:"Insert Table"},embed:{type:"popup",id:"embed",icon:"html",title:"Insert Embed"},symbol:{type:"popup",id:"symbol",icon:"emoji_symbols",title:"Insert Symbol"},specialChar:{type:"popup",id:"specialchar",icon:"format_shapes",title:"Special Characters"},lorem:{type:"popup",id:"lorem",icon:"history_edu",title:"Insert Lorem Ipsum"}};Object.values(f).forEach(Object.freeze);Object.freeze(f);var n=f,_={minimal:[n.source,n.sep,n.bold,n.italic,n.underline,n.sep,n.link,n.unlink],writing:[n.source,n.sep,n.undo,n.redo,n.sep,n.blockformat,n.sep,n.bold,n.italic,n.underline,n.strike,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image],full:[n.source,n.sep,n.undo,n.redo,n.sep,n.copy,n.cut,n.paste,n.sep,n.clearFormat,n.sep,n.blockformat,n.fontfamily,n.fontsize,n.sep,n.bold,n.italic,n.underline,n.strike,n.subscript,n.superscript,n.code,n.sep,n.foreColor,n.hiliteColor,n.sep,n.alignLeft,n.alignCenter,n.alignRight,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image,n.video,n.table,n.embed,n.symbol,n.specialChar,n.lorem,n.sep,n.theme]};Object.values(_).forEach(Object.freeze);Object.freeze(_);var R=_.full,I={image:"onRequestImage",link:"onRequestLink",video:"onRequestVideo",embed:"onRequestEmbed"},E=[{label:"Paragraph",tag:"p"},{label:"Heading 1",tag:"h1"},{label:"Heading 2",tag:"h2"},{label:"Heading 3",tag:"h3"},{label:"Heading 4",tag:"h4"},{label:"Pre / Code",tag:"pre"},{label:"Blockquote",tag:"blockquote"}],N=["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Impact","Lucida Console","Palatino Linotype","Tahoma","Times New Roman","Trebuchet MS","Verdana"],A=[8,9,10,11,12,14,16,18,20,24,28,32,36,48,72],B=["\u2190","\u2192","\u2191","\u2193","\u2194","\u2195","\u21D0","\u21D2","\u21D1","\u21D3","\u21D4","\u2022","\xB7","\u25E6","\u25CB","\u25CF","\u25A1","\u25A0","\u25C6","\u25C7","\u25B2","\u25BC","\u2605","\u2606","\u2660","\u2663","\u2665","\u2666","\u2713","\u2717","\u2715","\u2718","\u2248","\u2260","\u2261","\u2264","\u2265","\xF7","\xD7","\xB1","\u221E","\u221A","\u2211","\u220F","\u222B","\u2202","\u2206","\u2207","\u03C0","\u03A9","\u03BC","\u03B1","\u03B2","\u03B3","\xA9","\xAE","\u2122","\xA7","\xB6","\u2020","\u2021","\xB0","\u2032","\u2033","\u2030","\u201C","\u201D","\u2018","\u2019","\xAB","\xBB","\u2039","\u203A","\u2014","\u2013","\u2026","\xBF","\xA1","\u20AC","\xA3","\xA5","\xA2","\u20B9","\u20BD","\u20BF"],F=["\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF","\u0152","\u0153","\u0160","\u0161","\u0178","\u017D","\u017E"],k=[{id:"default",label:"Default"},{id:"warm",label:"Warm"},{id:"ink",label:"Ink / Navy"},{id:"forest",label:"Forest"}],H=[{label:"Short \u2014 1 sentence",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{label:"Medium \u2014 1 paragraph",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."},{label:"Long \u2014 3 paragraphs",isHTML:!0,text:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>"}],m=class{constructor(e,t={}){if(this._target=typeof e=="string"?document.querySelector(e):e,!this._target)throw new Error("[JotterJS] Target element not found.");this._options=Object.assign({placeholder:"Start typing\u2026",height:"320px",theme:"default",onChange:null,onFocus:null,onBlur:null,onRequestImage:null,onRequestLink:null,onRequestVideo:null,onRequestEmbed:null},t),this._listeners={},this._bookmarks=new Map,this._bmSeq=0,this._savedBookmark=null,this._externalBookmark=null,this._externalDepth=0,this._changeCount=0,this._destroyed=!1,this._lastForeColor="#e8e4d8",this._lastHiliteColor="#c8a96e",this._selectedMedia=null,this._resizeState=null,this._moveState=null,this._suppressAutoEmit=!1,this._onResizeMove=this._onResizeMove.bind(this),this._onResizeEnd=this._onResizeEnd.bind(this),this._onMoveMove=this._onMoveMove.bind(this),this._onMoveUp=this._onMoveUp.bind(this),this._init()}_init(){let e=this._target.innerHTML||"";this._target.innerHTML="",this._target.classList.add("jotter-host"),this._root=document.createElement("div"),this._root.className="htmled",this._toolbar=this._buildToolbar(),this._editorWrap=document.createElement("div"),this._editorWrap.className="jotter-editor-wrap",this._editor=document.createElement("div"),this._editor.className="jotter-editor",this._editor.contentEditable="true",this._editor.setAttribute("data-placeholder",this._options.placeholder),this._editor.style.minHeight=this._options.height,this._editor.innerHTML=this._sanitize(e),this._editor.spellcheck=!0,document.execCommand("defaultParagraphSeparator",!1,"p");try{document.execCommand("enableObjectResizing",!1,!1)}catch{}try{document.execCommand("enableInlineTableEditing",!1,!1)}catch{}this._ensureMediaShields(),this._source=document.createElement("textarea"),this._source.className="jotter-source",this._source.setAttribute("aria-label","HTML source"),this._source.setAttribute("spellcheck","false"),this._source.style.minHeight=this._options.height,this._sourceMode=!1,this._statusBar=this._buildStatusBar(),this._mediaFrame=this._buildMediaFrame(),this._editorWrap.appendChild(this._editor),this._editorWrap.appendChild(this._source),this._editorWrap.appendChild(this._mediaFrame),this._root.appendChild(this._toolbar),this._root.appendChild(this._editorWrap),this._root.appendChild(this._statusBar),this._target.appendChild(this._root),this._popup=this._buildPopupContainer(),document.body.appendChild(this._popup),this._bindEvents(),this._updateToolbarState(),this._updateStatus(),this.setTheme(this._options.theme)}_buildToolbar(){let e=document.createElement("div");return e.className="jotter-toolbar",this._toolbarEl=e,(this._options.toolbar||R).forEach(t=>{let i=this._buildAction(t);i&&e.appendChild(i)}),e}_buildAction(e){if(typeof e.onClick=="function")return this._buildBtn(e);switch(e.type){case"sep":return this._makeSep();case"blockformat":return this._buildBlockFormatSelect();case"fontfamily":return this._buildFontFamilySelect();case"fontsize":return this._buildFontSizeSelect();case"color":return this._buildColorBtn(e);case"popup":return this._buildPopupBtn(e);case"theme":return this._buildThemeSelect();default:return this._buildBtn(e)}}_makeSep(){let e=document.createElement("span");return e.className="jotter-sep",e}_bindActivation(e,t){e.addEventListener("mousedown",i=>{i.preventDefault(),t(!1)}),e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "&&i.key!=="Spacebar"||i.repeat||(i.preventDefault(),t(!0))})}_returnFocus(e,t){t&&this._isInternalTarget(document.activeElement)&&e.focus()}_buildBtn(e){let t=document.createElement("button");if(t.type="button",t.className="jotter-btn",e.cmd&&(t.dataset.cmd=e.cmd),e.custom&&(t.dataset.custom=e.custom),t.title=e.title,t.setAttribute("aria-label",e.title),e.label)t.classList.add("jotter-btn--text"),t.appendChild(document.createTextNode(e.label));else{let i=document.createElement("span");i.className="material-icons",i.textContent=e.icon,t.appendChild(i)}return this._bindActivation(t,i=>{this._editor.focus(),this._applyEdit(()=>{if(e.onClick)e.onClick(this);else if(e.custom==="toggleSource")this._toggleSourceMode();else if(e.custom==="code")this._toggleInlineCode();else if(e.cmd==="copy")document.execCommand("copy");else if(e.cmd==="cut")document.execCommand("cut");else if(e.cmd==="paste")this._pasteFromClipboard();else if(e.prompt){let o=window.prompt(e.prompt);o&&document.execCommand(e.cmd,!1,o)}else document.execCommand(e.cmd,!1,null)}),this._updateToolbarState(),this._returnFocus(t,i)}),t}_bindSelectCaret(e){let t={viaKeyboard:!1};return e.addEventListener("mousedown",()=>{t.viaKeyboard=!1,this._saveBookmark()}),e.addEventListener("keydown",i=>{i.key==="Tab"||i.key==="Escape"||(t.viaKeyboard=!0,this._savedBookmark==null&&this._saveBookmark())}),t}_buildBlockFormatSelect(){let e=document.createElement("select");e.className="jotter-select",e.title="Block format",e.dataset.id="blockformat",E.forEach(({label:i,tag:o})=>{let s=document.createElement("option");s.value=o,s.textContent=i,e.appendChild(s)});let t=this._bindSelectCaret(e);return e.addEventListener("change",()=>{this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("formatBlock",!1,e.value)),this._returnFocus(e,t.viaKeyboard)}),e}_buildFontFamilySelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--font",e.title="Font family",e.dataset.id="fontfamily";let t=document.createElement("option");t.value="",t.textContent="Font",e.appendChild(t),N.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=o,s.style.fontFamily=o,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("fontName",!1,e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildFontSizeSelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--size",e.title="Font size",e.dataset.id="fontsize";let t=document.createElement("option");t.value="",t.textContent="Size",e.appendChild(t),A.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=`${o}px`,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>this._applyFontSize(e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildThemeSelect(){let e=document.createElement("select");return e.className="jotter-select jotter-select--theme",e.title="Editor theme",e.dataset.id="theme",k.forEach(({id:t,label:i})=>{let o=document.createElement("option");o.value=t,o.textContent=i,e.appendChild(o)}),e.value=this._options.theme,e.addEventListener("change",()=>this.setTheme(e.value)),this._themeSelect=e,e}_buildColorBtn(e){let t=document.createElement("span");t.className="jotter-color-wrap";let i=document.createElement("button");i.type="button",i.className="jotter-btn jotter-color-btn",i.dataset.cmd=e.cmd,i.title=e.title,i.setAttribute("aria-label",e.title);let o=document.createElement("span");o.className="material-icons",o.textContent=e.icon,i.appendChild(o);let s=document.createElement("span");s.className="jotter-color-swatch";let r=e.cmd==="foreColor"?this._lastForeColor:this._lastHiliteColor;s.style.background=r,i.appendChild(s);let a=document.createElement("input");a.type="color",a.className="jotter-color-input",a.value=r,a.tabIndex=-1;let u=!1;return a.addEventListener("change",()=>{let h=a.value;s.style.background=h,e.cmd==="foreColor"?this._lastForeColor=h:this._lastHiliteColor=h,this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand(e.cmd,!1,h)),this._returnFocus(i,u)}),this._bindActivation(i,h=>{u=h,this._saveBookmark(),a.click()}),t.appendChild(i),t.appendChild(a),t}_buildPopupBtn(e){let t=document.createElement("button");t.type="button",t.className="jotter-btn",t.title=e.title,t.setAttribute("aria-label",e.title);let i=document.createElement("span");return i.className="material-icons",i.textContent=e.icon,t.appendChild(i),this._bindActivation(t,o=>{let s=this._resolverFor(e.id);if(s){this._hidePopup(),this._runResolver(e.id,s);return}if(this._saveBookmark(),this._popupVisible()&&this._popup.dataset.popupId===e.id){this._hidePopup();return}this._showPopup(t,this._buildPopupContent(e.id),e.id),o&&this._focusPopup()}),t}_focusPopup(){let e=this._popup.querySelector('input, textarea, select, button, [tabindex]:not([tabindex="-1"])');e&&e.focus()}_buildPopupContainer(){let e=document.createElement("div");return e.className="jotter-popup",e.setAttribute("role","dialog"),e}_showPopup(e,t,i){this._popup.innerHTML="",this._popup.appendChild(t),this._popup.dataset.popupId=i,this._popup.classList.add("jotter-popup--visible");let o=e.getBoundingClientRect();this._popup.style.top=o.bottom+6+"px",this._popup.style.left=o.left+"px",this._popup.style.right="auto",requestAnimationFrame(()=>{let s=this._popup.getBoundingClientRect();s.right>window.innerWidth-8&&(this._popup.style.left=Math.max(8,o.left-(s.right-window.innerWidth+8))+"px")})}_popupVisible(){return this._popup.classList.contains("jotter-popup--visible")}_hidePopup(){this._popup.classList.remove("jotter-popup--visible"),this._popup.dataset.popupId="",this._releaseSavedBookmark()}_buildPopupContent(e){switch(e){case"link":return this._popupLink();case"table":return this._popupTable();case"image":return this._popupImage();case"video":return this._popupVideo();case"embed":return this._popupEmbed();case"symbol":return this._popupSymbol();case"specialchar":return this._popupSpecialChar();case"lorem":return this._popupLorem();default:{let t=document.createElement("div");return t.className="jotter-popup-inner",t.textContent="Unknown: "+e,t}}}_popupTable(){let e=document.createElement("div");e.className="jotter-popup-inner";let t=this._popupTitle("Insert Table");e.appendChild(t);let i=10,o=8,s=document.createElement("div");s.className="jotter-table-grid",s.style.gridTemplateColumns=`repeat(${i}, 1fr)`,s.setAttribute("role","grid"),s.setAttribute("aria-label","Table size");let r=document.createElement("div");r.className="jotter-popup-hint",r.textContent="Hover or arrow to select size";let a=[],u=(d,l)=>{r.textContent=`${d+1} \xD7 ${l+1} table`,a.forEach(c=>{c.classList.toggle("jotter-table-cell--active",+c.dataset.r<=d&&+c.dataset.c<=l)})};for(let d=0;d<o;d++)for(let l=0;l<i;l++){let c=document.createElement("span");c.className="jotter-table-cell",c.dataset.r=d,c.dataset.c=l,c.setAttribute("role","gridcell"),c.setAttribute("aria-label",`${d+1} by ${l+1} table`),c.tabIndex=d===0&&l===0?0:-1,c.addEventListener("mouseenter",()=>u(d,l)),c.addEventListener("focus",()=>u(d,l)),c.addEventListener("click",()=>this._insertTable(d+1,l+1)),a.push(c),s.appendChild(c)}let h={ArrowRight:[0,1],ArrowLeft:[0,-1],ArrowDown:[1,0],ArrowUp:[-1,0]};return s.addEventListener("keydown",d=>{let l=a.indexOf(document.activeElement)===-1?null:document.activeElement;if(!l)return;let c=+l.dataset.r,C=+l.dataset.c;if(d.key==="Enter"||d.key===" "||d.key==="Spacebar"){d.preventDefault(),this._insertTable(c+1,C+1);return}let b=h[d.key];if(!b)return;d.preventDefault();let y=Math.min(o-1,Math.max(0,c+b[0])),S=Math.min(i-1,Math.max(0,C+b[1])),g=a[y*i+S];g!==l&&(l.tabIndex=-1,g.tabIndex=0,g.focus())}),e.appendChild(s),e.appendChild(r),e}_commitPopup(e){this._restoreSavedBookmark(),this._hidePopup(),this._applyEdit(e)}_insertTable(e,t){let i="<table><tbody>";for(let o=0;o<e;o++){i+="<tr>";for(let s=0;s<t;s++)i+=o===0?"<th><br></th>":"<td><br></td>";i+="</tr>"}i+="</tbody></table><p><br></p>",this._commitPopup(()=>document.execCommand("insertHTML",!1,i))}_popupLink(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Link"));let t=this._anchorInSelection(),i=this._selectedText(),o=this._makeField(e,"URL","url","https://"),s=this._makeField(e,"Link text (leave blank to keep selection)","text",""),r=this._makeField(e,"Title / tooltip","text",""),a=document.createElement("label");a.className="jotter-popup-label",a.textContent="Open in";let u=document.createElement("select");return u.className="jotter-popup-select",[["(same window)",""],["New tab (_blank)","_blank"],["Parent frame (_parent)","_parent"],["Top frame (_top)","_top"]].forEach(([h,d])=>{let l=document.createElement("option");l.value=d,l.textContent=h,u.appendChild(l)}),e.appendChild(a),e.appendChild(u),t?(o.value=t.getAttribute("href")||"",s.value=t.textContent||"",r.value=t.getAttribute("title")||"",u.value=t.getAttribute("target")||""):i&&(s.value=i),e.appendChild(this._makeSubmitBtn(t?"Update Link":"Insert Link",()=>{let h=o.value.trim();if(!h)return;let d=s.value.trim()||i||h,l=r.value.trim(),c=u.value;this._commitPopup(()=>{t?(t.href=h,c?t.target=c:t.removeAttribute("target"),l?t.title=l:t.removeAttribute("title"),t.textContent=d):document.execCommand("insertHTML",!1,this._linkHTML({href:h,text:d,title:l,target:c}))})})),e}_popupImage(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Image"));let t=this._makeField(e,"Image URL","text","https://example.com/image.jpg"),i=this._makeField(e,"Alt text","text","Descriptive text"),o=this._makeField(e,"Width (e.g. 400px or 50%)","text","");return e.appendChild(this._makeSubmitBtn("Insert Image",()=>{let s=t.value.trim();if(!s)return;let r=this._imageHTML({src:s,alt:i.value.trim(),width:o.value.trim()});this._commitPopup(()=>document.execCommand("insertHTML",!1,r))})),e}_popupVideo(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert YouTube Video"));let t=this._makeField(e,"YouTube URL","text","https://www.youtube.com/watch?v=...");return e.appendChild(this._makeSubmitBtn("Embed Video",()=>{let i=this._ytId(t.value.trim());if(!i){t.classList.add("jotter-input--error");return}t.classList.remove("jotter-input--error"),this._commitPopup(()=>document.execCommand("insertHTML",!1,this._videoHTML(i)))})),e}_ytId(e){for(let t of[/[?&]v=([A-Za-z0-9_-]{11})/,/youtu\.be\/([A-Za-z0-9_-]{11})/,/embed\/([A-Za-z0-9_-]{11})/]){let i=e.match(t);if(i)return i[1]}return null}_popupEmbed(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Embed"));let t=document.createElement("label");t.className="jotter-popup-label",t.textContent="Paste HTML / embed code";let i=document.createElement("textarea");return i.className="jotter-popup-textarea",i.placeholder='<iframe src="..." ...></iframe>',i.rows=4,e.appendChild(t),e.appendChild(i),e.appendChild(this._makeSubmitBtn("Insert",()=>{let o=i.value.trim();o&&this._commitPopup(()=>document.execCommand("insertHTML",!1,this._embedHTML(o)))})),e}_popupSymbol(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Symbol")),e.appendChild(this._charGrid(B)),e}_popupSpecialChar(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Special Characters")),e.appendChild(this._charGrid(F)),e}_charGrid(e){let t=document.createElement("div");return t.className="jotter-char-grid",e.forEach(i=>{let o=document.createElement("button");o.type="button",o.className="jotter-char-btn",o.textContent=i,o.title=`U+${i.codePointAt(0).toString(16).toUpperCase().padStart(4,"0")}`,this._bindActivation(o,()=>{this._commitPopup(()=>document.execCommand("insertText",!1,i))}),t.appendChild(o)}),t}_popupLorem(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Lorem Ipsum")),H.forEach(t=>{let i=document.createElement("button");i.type="button",i.className="jotter-lorem-btn",i.textContent=t.label,this._bindActivation(i,()=>{this._commitPopup(()=>document.execCommand(t.isHTML?"insertHTML":"insertText",!1,t.text))}),e.appendChild(i)}),e}_popupTitle(e){let t=document.createElement("div");return t.className="jotter-popup-title",t.textContent=e,t}_makeField(e,t,i,o){let s=document.createElement("label");s.className="jotter-popup-label",s.textContent=t;let r=document.createElement("input");return r.type=i,r.className="jotter-popup-input",r.placeholder=o,e.appendChild(s),e.appendChild(r),r}_makeSubmitBtn(e,t){let i=document.createElement("button");return i.type="button",i.className="jotter-popup-submit",i.textContent=e,i.addEventListener("click",t),i}_esc(e){return String(e).replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}_imageHTML({src:e,alt:t,width:i}){let o=i?`max-width:${i}`:"max-width:100%";return`<img src="${this._esc(e)}" alt="${this._esc(t||"")}" style="${this._esc(o)}">`}_linkHTML({href:e,text:t,title:i,target:o}){let s=`href="${this._esc(e)}"`;return o&&(s+=` target="${this._esc(o)}"`),i&&(s+=` title="${this._esc(i)}"`),`<a ${s}>${this._esc(t||e)}</a>`}_videoHTML(e){return/^[A-Za-z0-9_-]{11}$/.test(e)?`<div class="jotter-video-wrap"><iframe src="https://www.youtube.com/embed/${e}" frameborder="0" allowfullscreen loading="lazy" title="YouTube video"></iframe></div><p><br></p>`:null}_embedHTML(e){return`<div class="jotter-embed-wrap">${e}</div><p><br></p>`}_resolverFor(e){let t=I[e],i=t?this._options[t]:null;return typeof i=="function"?i:null}async _runResolver(e,t){let i=this._resolverContext(e);this.beginExternalUI();let o=null;try{o=await t(i)}catch{o=null}if(this._destroyed)return;let s=o==null||o===!1?null:this._resolvedHTML(e,o,i);this.endExternalUI(),s&&(this._applyEdit(()=>document.execCommand("insertHTML",!1,s)),this._updateToolbarState())}_resolverContext(e){switch(e){case"image":return{src:"",alt:"",width:"",selection:this._selectedText()};case"video":return{url:"",selection:this._selectedText()};case"embed":return{html:"",selection:this._selectedText()};case"link":return this._linkContext();default:return{selection:this._selectedText()}}}_linkContext(){let e=this._anchorInSelection();if(!e){let i=this._selectedText();return{href:"",text:i,title:"",target:"",selection:i,isEdit:!1}}let t=window.getSelection();if(t){let i=document.createRange();i.selectNode(e),t.removeAllRanges(),t.addRange(i)}return{href:e.getAttribute("href")||"",text:e.textContent||"",title:e.getAttribute("title")||"",target:e.getAttribute("target")||"",selection:e.textContent||"",isEdit:!0}}_resolvedHTML(e,t,i){switch(e){case"image":{let o=typeof t=="string"?{src:t}:t,s=String(o.src||o.url||"").trim();return s?this._imageHTML({...o,src:s}):null}case"link":{let o=typeof t=="string"?{href:t}:t,s=String(o.href||o.url||"").trim();if(!s)return null;let r=String(o.text!=null?o.text:i.text||"").trim();return this._linkHTML({...o,href:s,text:r})}case"video":{let o=typeof t=="string"?{url:t}:t,s=o.id?String(o.id).trim():this._ytId(String(o.url||"").trim());return s?this._videoHTML(s):null}case"embed":{let o=String(typeof t=="string"?t:t.html||"").trim();return o?this._embedHTML(o):null}default:return null}}_selectedText(){let e=window.getSelection();return!e||!e.rangeCount?"":this._editor.contains(e.getRangeAt(0).commonAncestorContainer)?e.toString():""}_anchorInSelection(){let e=window.getSelection();if(!e||!e.rangeCount)return null;let t=e.anchorNode;if(!t||!this._editor.contains(t))return null;for(;t&&t!==this._editor;){if(t.nodeName==="A")return t;t=t.parentNode}return null}_buildStatusBar(){let e=document.createElement("div");e.className="jotter-status",this._wordCountEl=document.createElement("span"),this._wordCountEl.className="jotter-status-words",this._charCountEl=document.createElement("span"),this._charCountEl.className="jotter-status-chars";let t=document.createElement("span");return t.className="jotter-status-mode",t.textContent="HTML",e.appendChild(this._wordCountEl),e.appendChild(this._charCountEl),e.appendChild(t),e}_buildMediaFrame(){let e=document.createElement("div");return e.className="jotter-media-frame",["nw","ne","sw","se","w","e"].forEach(t=>{let i=document.createElement("div");i.className="jotter-resize-handle jotter-resize-handle--"+t,i.dataset.handle=t,i.tabIndex=-1,e.appendChild(i)}),e.addEventListener("mousedown",t=>{if(!this._selectedMedia)return;t.preventDefault();let i=t.target.closest(".jotter-resize-handle");i?this._beginResize(i.dataset.handle,t):this._beginPotentialMove(this._selectedMedia,t)}),e}_ensureMediaShields(){this._editor.querySelectorAll(".jotter-video-wrap, .jotter-embed-wrap").forEach(e=>{if(e.querySelector(":scope > .jotter-media-shield"))return;let t=document.createElement("div");t.className="jotter-media-shield",e.appendChild(t)})}_mediaElementFromTarget(e){if(!this._editor.contains(e))return null;let t=e.closest("img");if(t&&this._editor.contains(t))return t;let i=e.closest(".jotter-video-wrap, .jotter-embed-wrap");return i&&this._editor.contains(i)?i:null}_selectMedia(e){if(this._selectedMedia===e)return;this._deselectMedia(),this._selectedMedia=e,this._positionMediaFrame(),this._mediaFrame.classList.add("jotter-media-frame--visible"),this._editor.focus({preventScroll:!0});let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._updateToolbarState()}_deselectMedia(){this._resizeState&&this._abortResize(),this._moveState&&this._abortMove(),this._selectedMedia&&(this._selectedMedia=null,this._mediaFrame.classList.remove("jotter-media-frame--visible"))}_positionMediaFrame(){let e=this._selectedMedia;if(!e)return;let t=this._editorWrap.getBoundingClientRect(),i=e.getBoundingClientRect();this._mediaFrame.style.top=i.top-t.top+this._editorWrap.scrollTop+"px",this._mediaFrame.style.left=i.left-t.left+this._editorWrap.scrollLeft+"px",this._mediaFrame.style.width=i.width+"px",this._mediaFrame.style.height=i.height+"px"}_deleteSelectedMedia(){let e=this._selectedMedia;if(!e)return;this._deselectMedia();let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._applyEdit(()=>document.execCommand("delete",!1,null)),this._updateToolbarState()}_beginResize(e,t){let i=this._selectedMedia,o=i.getBoundingClientRect(),s=e.includes("w")?-1:1;this._resizeState={el:i,sign:s,startX:t.clientX,startWidth:o.width,startInlineWidth:i.style.width,before:this._richHTML()},document.addEventListener("mousemove",this._onResizeMove),document.addEventListener("mouseup",this._onResizeEnd,{once:!0})}_onResizeMove(e){let t=this._resizeState;if(!t)return;let i=(e.clientX-t.startX)*t.sign,o=40,s=Math.max(o,this._editor.clientWidth),r=Math.max(o,Math.min(s,Math.round(t.startWidth+i)));t.el.style.width=r+"px",t.el.style.removeProperty("max-width"),this._positionMediaFrame()}_onResizeEnd(){document.removeEventListener("mousemove",this._onResizeMove);let e=this._resizeState;this._resizeState=null,e&&(this._updateStatus(),this._richHTML()!==e.before&&this._emitChange())}_abortResize(){let e=this._resizeState;e&&(document.removeEventListener("mousemove",this._onResizeMove),document.removeEventListener("mouseup",this._onResizeEnd),e.el.style.width=e.startInlineWidth,this._resizeState=null,this._positionMediaFrame())}_beginPotentialMove(e,t){this._moveState={el:e,startX:t.clientX,startY:t.clientY,dragging:!1},document.addEventListener("mousemove",this._onMoveMove),document.addEventListener("mouseup",this._onMoveUp,{once:!0})}_onMoveMove(e){let t=this._moveState;if(t){if(!t.dragging){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.dragging=!0,t.before=this._richHTML(),this._mediaFrame.classList.add("jotter-media-frame--dragging"),document.body.style.cursor="grabbing"}t.dropRange=this._rangeFromPoint(e.clientX,e.clientY),this._showDropIndicator(t.dropRange)}}_onMoveUp(){document.removeEventListener("mousemove",this._onMoveMove);let e=this._moveState;this._moveState=null,this._mediaFrame.classList.remove("jotter-media-frame--dragging"),document.body.style.cursor="",this._hideDropIndicator(),e&&e.dragging&&this._commitMove(e.el,e.dropRange,e.before)}_abortMove(){this._moveState&&(document.removeEventListener("mousemove",this._onMoveMove),document.removeEventListener("mouseup",this._onMoveUp),this._moveState=null,this._mediaFrame.classList.remove("jotter-media-frame--dragging"),document.body.style.cursor="",this._hideDropIndicator())}_rangeFromPoint(e,t){let i=null;if(document.caretRangeFromPoint)i=document.caretRangeFromPoint(e,t);else if(document.caretPositionFromPoint){let s=document.caretPositionFromPoint(e,t);s&&(i=document.createRange(),i.setStart(s.offsetNode,s.offset),i.collapse(!0))}if(!i||!this._editor.contains(i.startContainer))return null;let o=this._moveState;return o&&o.el.contains(i.startContainer)?null:i}_buildDropIndicator(){let e=document.createElement("div");return e.className="jotter-drop-indicator",e}_showDropIndicator(e){this._dropIndicator||(this._dropIndicator=this._buildDropIndicator(),this._editorWrap.appendChild(this._dropIndicator));let t=e&&e.getClientRects()[0];if(!t){this._dropIndicator.style.display="none";return}let i=this._editorWrap.getBoundingClientRect();this._dropIndicator.style.display="block",this._dropIndicator.style.top=t.top-i.top+this._editorWrap.scrollTop+"px",this._dropIndicator.style.left=t.left-i.left+this._editorWrap.scrollLeft+"px",this._dropIndicator.style.height=(t.height||20)+"px"}_hideDropIndicator(){this._dropIndicator&&(this._dropIndicator.style.display="none")}_commitMove(e,t,i){if(!t||!t.startContainer.isConnected)return;let o="jmv"+ ++this._bmSeq,s=e.cloneNode(!0);s.querySelectorAll(".jotter-media-shield").forEach(h=>h.remove()),s.setAttribute("data-jotter-move",o),this._suppressAutoEmit=!0;let r=window.getSelection(),a=document.createRange();a.selectNode(e),r.removeAllRanges(),r.addRange(a),document.execCommand("delete",!1,null),r.removeAllRanges(),r.addRange(t),document.execCommand("insertHTML",!1,s.outerHTML);let u=this._editor.querySelector(`[data-jotter-move="${o}"]`);u&&u.removeAttribute("data-jotter-move"),this._suppressAutoEmit=!1,this._updateStatus(),u?this._selectMedia(u):this._deselectMedia(),this._richHTML()!==i&&this._emitChange()}_writeMediaToClipboard(e,t){let i=t.cloneNode(!0);i.querySelectorAll(".jotter-media-shield").forEach(o=>o.remove()),e.clipboardData.setData("text/html",i.outerHTML),e.clipboardData.setData("text/plain",t.tagName==="IMG"?t.alt||"":t.textContent||"")}_bindEvents(){this._editor.addEventListener("input",()=>{this._editor.querySelectorAll(":scope > div").forEach(e=>{if(e.attributes.length>0)return;let t=document.createElement("p");t.innerHTML=e.innerHTML,e.replaceWith(t)}),Array.from(this._editor.childNodes).forEach(e=>{if(e.nodeType===Node.TEXT_NODE&&e.textContent.trim()!==""){let t=window.getSelection(),i=null;if(t&&t.rangeCount){let s=t.getRangeAt(0);s.startContainer===e&&(i=s.startOffset)}let o=document.createElement("p");if(e.replaceWith(o),o.appendChild(e),i!==null){let s=document.createRange();s.setStart(e,i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}}}),this._ensureMediaShields(),this._selectedMedia&&this._positionMediaFrame(),this._updateStatus(),this._suppressAutoEmit||this._emitChange()}),this._editor.addEventListener("keyup",()=>this._updateToolbarState()),this._editor.addEventListener("mouseup",()=>this._updateToolbarState()),this._editor.addEventListener("mousedown",e=>{let t=this._mediaElementFromTarget(e.target);t&&(e.preventDefault(),this._selectMedia(t),this._beginPotentialMove(t,e))}),this._editor.addEventListener("copy",e=>{this._selectedMedia&&(e.preventDefault(),this._writeMediaToClipboard(e,this._selectedMedia))}),this._editor.addEventListener("cut",e=>{this._selectedMedia&&(e.preventDefault(),this._writeMediaToClipboard(e,this._selectedMedia),this._deleteSelectedMedia())}),this._editor.addEventListener("paste",e=>{e.preventDefault();let t=(e.clipboardData||window.clipboardData).getData("text/html");if(t)this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(t)));else{let i=(e.clipboardData||window.clipboardData).getData("text/plain");i&&this._applyEdit(()=>document.execCommand("insertText",!1,i))}}),this._onWindowResize=()=>{this._selectedMedia&&this._positionMediaFrame()},window.addEventListener("resize",this._onWindowResize),this._editor.addEventListener("focusin",e=>{this._root.classList.add("jotter--focused"),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||(this._emit("focus"),this._options.onFocus&&this._options.onFocus()))}),this._editor.addEventListener("focusout",e=>{this._deselectMedia(),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||setTimeout(()=>{this._destroyed||this._externalDepth>0||this._isInternalTarget(document.activeElement)||this._popupVisible()||(this._root.classList.remove("jotter--focused"),this._emit("blur"),this._options.onBlur&&this._options.onBlur())},0))}),this._editor.addEventListener("keydown",e=>{if((e.key==="Backspace"||e.key==="Delete")&&this._selectedMedia){e.preventDefault(),this._deleteSelectedMedia();return}e.key==="Tab"&&(e.preventDefault(),document.execCommand("insertHTML",!1,"&nbsp;&nbsp;&nbsp;&nbsp;"))}),this._onDocMouseDown=e=>{this._popupVisible()&&!this._popup.contains(e.target)&&!this._toolbarEl.contains(e.target)&&this._hidePopup(),this._selectedMedia&&!this._mediaFrame.contains(e.target)&&e.target!==this._selectedMedia&&!this._selectedMedia.contains(e.target)&&this._deselectMedia()},document.addEventListener("mousedown",this._onDocMouseDown),this._onDocKeyDown=e=>{if(e.key==="Escape"){if(this._resizeState){this._abortResize();return}if(this._moveState&&this._moveState.dragging){this._abortMove();return}if(this._selectedMedia){this._deselectMedia();return}this._popupVisible()&&(this._restoreSavedBookmark(),this._hidePopup())}},document.addEventListener("keydown",this._onDocKeyDown)}_isInternalTarget(e){return!!e&&(this._root.contains(e)||this._popup.contains(e))}_toggleSourceMode(){this._deselectMedia(),this._sourceMode=!this._sourceMode,this._sourceMode?(this._dropBookmarks(),this._source.value=this._prettyHTML(this._richHTML()),this._editor.style.display="none",this._source.style.display="block"):(this._editor.innerHTML=this._sanitize(this._source.value),this._ensureMediaShields(),this._source.style.display="none",this._editor.style.display="",this._updateStatus(),this._emitChange()),this._root.classList.toggle("jotter--source-mode",this._sourceMode);let e=this._toolbarEl.querySelector('[data-custom="toggleSource"]');e&&e.classList.toggle("jotter-btn--active",this._sourceMode)}_prettyHTML(e){let t=0,i=" ",o=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),s=new Set(["a","abbr","acronym","b","bdo","big","br","button","cite","code","dfn","em","i","img","input","kbd","label","map","object","output","q","samp","select","small","span","strong","sub","sup","textarea","time","tt","u","var"]);return e.replace(/>\s+</g,"><").replace(/(<[^>]+>)/g,`
2
2
  $1
3
3
  `).split(`
4
- `).map(r=>r.trim()).filter(r=>r.length>0).map(r=>{let a=r.match(/^<\/(\w+)/),u=r.match(/^<(\w+)/),p=r.endsWith("/>"),c=u?u[1].toLowerCase():null,l=a?a[1].toLowerCase():null;l&&!s.has(l)&&(t=Math.max(0,t-1));let d=i.repeat(t)+r;return c&&!p&&!o.has(c)&&!l&&!s.has(c)&&t++,d}).join(`
5
- `)}_sanitize(e){let t=new DOMParser().parseFromString(e,"text/html");return t.querySelectorAll("script").forEach(i=>i.remove()),t.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(i=>i.remove()),t.querySelectorAll("*").forEach(i=>{Array.from(i.attributes).forEach(o=>{(o.name.startsWith("on")||["href","src","action","formaction","data"].includes(o.name)&&/^\s*javascript:/i.test(o.value))&&i.removeAttribute(o.name)})}),t.body.innerHTML}_toggleInlineCode(){let e=window.getSelection();if(!e||e.rangeCount===0)return;let t=e.getRangeAt(0),i=t.commonAncestorContainer;i.nodeType===3&&(i=i.parentNode);let o=i.closest?i.closest("code"):null;if(o){let s=o.parentNode;for(;o.firstChild;)s.insertBefore(o.firstChild,o);s.removeChild(o)}else if(t.collapsed){let s=document.createElement("code");s.innerHTML="&#8203;",t.insertNode(s);let r=document.createRange();r.setStart(s,0),r.setEnd(s,s.childNodes.length),e.removeAllRanges(),e.addRange(r)}else{let s=document.createElement("code");try{t.surroundContents(s)}catch{let a=t.extractContents();s.appendChild(a),t.insertNode(s)}}}_applyFontSize(e){let t=window.getSelection();if(!t||t.rangeCount===0)return;let i=t.getRangeAt(0);if(i.collapsed)return;let o=document.createElement("span");o.style.fontSize=e+"px";try{i.surroundContents(o)}catch{let r=i.extractContents();o.appendChild(r),i.insertNode(o)}}async _pasteFromClipboard(){try{if(navigator.clipboard&&navigator.clipboard.readText){let e=await navigator.clipboard.readText();document.execCommand("insertText",!1,e)}else document.execCommand("paste")}catch{}}_updateToolbarState(){this._toolbarEl.querySelectorAll(".jotter-btn[data-cmd]").forEach(t=>{try{t.classList.toggle("jotter-btn--active",document.queryCommandState(t.dataset.cmd))}catch{}});let e=this._toolbarEl.querySelector('[data-id="blockformat"]');if(e){let t=document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g,""),i=k.find(o=>o.tag===t);i&&(e.value=i.tag)}}_updateStatus(){let e=this._editor.innerText||"",t=e.trim()===""?0:e.trim().split(/\s+/).length,i=e.replace(/\n/g,"").length;this._wordCountEl.textContent=`${t} word${t!==1?"s":""}`,this._charCountEl.textContent=`${i} char${i!==1?"s":""}`}_richHTML(){let e=this._editor.cloneNode(!0);return e.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(t=>t.remove()),e.innerHTML}_makeMarker(e){let t=document.createElement("span");return t.className="jotter-bookmark",t.dataset.jotterBookmark=e,t}_takeRange(e){let t=e!=null?this._bookmarks.get(e):null;if(!t)return null;if(this._bookmarks.delete(e),t.atStart){let a=document.createRange();return a.setStart(this._editor,0),a.collapse(!0),a}let{start:i,end:o}=t,s=this._editor.contains(i)&&(!o||this._editor.contains(o)),r=null;return s&&(r=document.createRange(),r.setStartAfter(i),o?r.setEndBefore(o):r.collapse(!0)),i.parentNode&&i.remove(),o&&o.parentNode&&o.remove(),r}_saveBookmark(){this._releaseSavedBookmark(),this._savedBookmark=this.saveSelection()}_restoreSavedBookmark(){this.restoreSelection(this._savedBookmark),this._savedBookmark=null,this._editor.focus()}_releaseSavedBookmark(){this.releaseSelection(this._savedBookmark),this._savedBookmark=null}_dropBookmarks(){Array.from(this._bookmarks.keys()).forEach(e=>this.releaseSelection(e)),this._savedBookmark=null}_emit(e,t){(this._listeners[e]||[]).forEach(i=>i(t))}_emitChange(){let e=this.getHTML();this._changeCount++,this._emit("change",e),this._options.onChange&&this._options.onChange(e)}_applyEdit(e){let t=this._changeCount,i=this._richHTML();e(),this._updateStatus(),this._changeCount===t&&this._richHTML()!==i&&this._emitChange()}getHTML(){return this._sourceMode?this._source.value:this._richHTML()}getText(){return this._editor.innerText}isSourceMode(){return this._sourceMode}toggleSource(){return this._toggleSourceMode(),this}clear(){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML="",this._updateStatus(),this}focus(){return this._editor.focus(),this}insertHTML(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(e))),this}insertText(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertText",!1,e)),this}saveSelection(){let e=window.getSelection();if(!e||e.rangeCount===0)return null;let t=e.getRangeAt(0);if(!this._editor.contains(t.startContainer)||!this._editor.contains(t.endContainer))return null;let i="jbm"+ ++this._bmSeq;if(this._editor.childNodes.length===0)return this._bookmarks.set(i,{atStart:!0}),i;let o=this._makeMarker(i),s=t.collapsed?null:this._makeMarker(i);if(s){let u=t.cloneRange();u.collapse(!1),u.insertNode(s)}let r=t.cloneRange();r.collapse(!0),r.insertNode(o),this._bookmarks.set(i,{start:o,end:s});let a=document.createRange();return a.setStartAfter(o),s?a.setEndBefore(s):a.collapse(!0),e.removeAllRanges(),e.addRange(a),i}restoreSelection(e){let t=this._takeRange(e);if(!t)return this;this._sourceMode||this._editor.focus();let i=window.getSelection();return i.removeAllRanges(),i.addRange(t),this}releaseSelection(e){return this._takeRange(e),this}beginExternalUI(){return this._externalDepth===0&&(this._externalBookmark=this.saveSelection()),this._externalDepth++,this}endExternalUI(e={}){if(this._externalDepth===0)return this;if(this._externalDepth===1){let t=this._externalBookmark;this._externalBookmark=null,e.restore===!1?this.releaseSelection(t):this.restoreSelection(t)}return this._externalDepth--,this}setHTML(e){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML=this._sanitize(e),this._ensureMediaShields(),this._updateStatus(),this}setTheme(e){let i=E.find(o=>o.id===e)?e:"default";return this._editor.dataset.theme=i,this._options.theme=i,this._themeSelect&&(this._themeSelect.value=i),this}setEnabled(e){return this._editor.contentEditable=String(e),this._root.classList.toggle("jotter--disabled",!e),this}on(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),this}off(e,t){return this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(i=>i!==t)),this}destroy(){let e=this.getHTML();return this._destroyed=!0,this._deselectMedia(),this._hidePopup(),this._dropBookmarks(),this._externalBookmark=null,this._externalDepth=0,document.removeEventListener("mousedown",this._onDocMouseDown),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("resize",this._onWindowResize),this._popup.parentNode&&this._popup.parentNode.removeChild(this._popup),this._target.classList.remove("jotter-host"),this._target.innerHTML=e,this._listeners={},e}};m.toolbar=_.full;m.actions=f;m.presets=_;var z=m;return j(D);})();
4
+ `).map(r=>r.trim()).filter(r=>r.length>0).map(r=>{let a=r.match(/^<\/(\w+)/),u=r.match(/^<(\w+)/),h=r.endsWith("/>"),d=u?u[1].toLowerCase():null,l=a?a[1].toLowerCase():null;l&&!s.has(l)&&(t=Math.max(0,t-1));let c=i.repeat(t)+r;return d&&!h&&!o.has(d)&&!l&&!s.has(d)&&t++,c}).join(`
5
+ `)}_sanitize(e){let t=new DOMParser().parseFromString(e,"text/html");return t.querySelectorAll("script").forEach(i=>i.remove()),t.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(i=>i.remove()),t.querySelectorAll("*").forEach(i=>{Array.from(i.attributes).forEach(o=>{(o.name.startsWith("on")||["href","src","action","formaction","data"].includes(o.name)&&/^\s*javascript:/i.test(o.value))&&i.removeAttribute(o.name)})}),t.body.innerHTML}_toggleInlineCode(){let e=window.getSelection();if(!e||e.rangeCount===0)return;let t=e.getRangeAt(0),i=t.commonAncestorContainer;i.nodeType===3&&(i=i.parentNode);let o=i.closest?i.closest("code"):null;if(o){let s=o.parentNode;for(;o.firstChild;)s.insertBefore(o.firstChild,o);s.removeChild(o)}else if(t.collapsed){let s=document.createElement("code");s.innerHTML="&#8203;",t.insertNode(s);let r=document.createRange();r.setStart(s,0),r.setEnd(s,s.childNodes.length),e.removeAllRanges(),e.addRange(r)}else{let s=document.createElement("code");try{t.surroundContents(s)}catch{let a=t.extractContents();s.appendChild(a),t.insertNode(s)}}}_applyFontSize(e){let t=window.getSelection();if(!t||t.rangeCount===0)return;let i=t.getRangeAt(0);if(i.collapsed)return;let o=document.createElement("span");o.style.fontSize=e+"px";try{i.surroundContents(o)}catch{let r=i.extractContents();o.appendChild(r),i.insertNode(o)}}async _pasteFromClipboard(){try{if(navigator.clipboard&&navigator.clipboard.readText){let e=await navigator.clipboard.readText();document.execCommand("insertText",!1,e)}else document.execCommand("paste")}catch{}}_updateToolbarState(){this._toolbarEl.querySelectorAll(".jotter-btn[data-cmd]").forEach(t=>{try{t.classList.toggle("jotter-btn--active",document.queryCommandState(t.dataset.cmd))}catch{}});let e=this._toolbarEl.querySelector('[data-id="blockformat"]');if(e){let t=document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g,""),i=E.find(o=>o.tag===t);i&&(e.value=i.tag)}}_updateStatus(){let e=this._editor.innerText||"",t=e.trim()===""?0:e.trim().split(/\s+/).length,i=e.replace(/\n/g,"").length;this._wordCountEl.textContent=`${t} word${t!==1?"s":""}`,this._charCountEl.textContent=`${i} char${i!==1?"s":""}`}_richHTML(){let e=this._editor.cloneNode(!0);return e.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(t=>t.remove()),e.querySelectorAll("[data-jotter-move]").forEach(t=>t.removeAttribute("data-jotter-move")),e.innerHTML}_makeMarker(e){let t=document.createElement("span");return t.className="jotter-bookmark",t.dataset.jotterBookmark=e,t}_takeRange(e){let t=e!=null?this._bookmarks.get(e):null;if(!t)return null;if(this._bookmarks.delete(e),t.atStart){let a=document.createRange();return a.setStart(this._editor,0),a.collapse(!0),a}let{start:i,end:o}=t,s=this._editor.contains(i)&&(!o||this._editor.contains(o)),r=null;return s&&(r=document.createRange(),r.setStartAfter(i),o?r.setEndBefore(o):r.collapse(!0)),i.parentNode&&i.remove(),o&&o.parentNode&&o.remove(),r}_saveBookmark(){this._releaseSavedBookmark(),this._savedBookmark=this.saveSelection()}_restoreSavedBookmark(){this.restoreSelection(this._savedBookmark),this._savedBookmark=null,this._editor.focus()}_releaseSavedBookmark(){this.releaseSelection(this._savedBookmark),this._savedBookmark=null}_dropBookmarks(){Array.from(this._bookmarks.keys()).forEach(e=>this.releaseSelection(e)),this._savedBookmark=null}_emit(e,t){(this._listeners[e]||[]).forEach(i=>i(t))}_emitChange(){let e=this.getHTML();this._changeCount++,this._emit("change",e),this._options.onChange&&this._options.onChange(e)}_applyEdit(e){let t=this._changeCount,i=this._richHTML();e(),this._updateStatus(),this._changeCount===t&&this._richHTML()!==i&&this._emitChange()}getHTML(){return this._sourceMode?this._source.value:this._richHTML()}getText(){return this._editor.innerText}isSourceMode(){return this._sourceMode}toggleSource(){return this._toggleSourceMode(),this}clear(){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML="",this._updateStatus(),this}focus(){return this._editor.focus(),this}insertHTML(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(e))),this}insertText(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertText",!1,e)),this}saveSelection(){let e=window.getSelection();if(!e||e.rangeCount===0)return null;let t=e.getRangeAt(0);if(!this._editor.contains(t.startContainer)||!this._editor.contains(t.endContainer))return null;let i="jbm"+ ++this._bmSeq;if(this._editor.childNodes.length===0)return this._bookmarks.set(i,{atStart:!0}),i;let o=this._makeMarker(i),s=t.collapsed?null:this._makeMarker(i);if(s){let u=t.cloneRange();u.collapse(!1),u.insertNode(s)}let r=t.cloneRange();r.collapse(!0),r.insertNode(o),this._bookmarks.set(i,{start:o,end:s});let a=document.createRange();return a.setStartAfter(o),s?a.setEndBefore(s):a.collapse(!0),e.removeAllRanges(),e.addRange(a),i}restoreSelection(e){let t=this._takeRange(e);if(!t)return this;this._sourceMode||this._editor.focus();let i=window.getSelection();return i.removeAllRanges(),i.addRange(t),this}releaseSelection(e){return this._takeRange(e),this}beginExternalUI(){return this._externalDepth===0&&(this._externalBookmark=this.saveSelection()),this._externalDepth++,this}endExternalUI(e={}){if(this._externalDepth===0)return this;if(this._externalDepth===1){let t=this._externalBookmark;this._externalBookmark=null,e.restore===!1?this.releaseSelection(t):this.restoreSelection(t)}return this._externalDepth--,this}setHTML(e){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML=this._sanitize(e),this._ensureMediaShields(),this._updateStatus(),this}setTheme(e){let i=k.find(o=>o.id===e)?e:"default";return this._editor.dataset.theme=i,this._options.theme=i,this._themeSelect&&(this._themeSelect.value=i),this}setEnabled(e){return this._editor.contentEditable=String(e),this._root.classList.toggle("jotter--disabled",!e),this}on(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),this}off(e,t){return this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(i=>i!==t)),this}destroy(){let e=this.getHTML();return this._destroyed=!0,this._deselectMedia(),this._hidePopup(),this._dropBookmarks(),this._externalBookmark=null,this._externalDepth=0,document.removeEventListener("mousedown",this._onDocMouseDown),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("resize",this._onWindowResize),this._popup.parentNode&&this._popup.parentNode.removeChild(this._popup),this._target.classList.remove("jotter-host"),this._target.innerHTML=e,this._listeners={},e}};m.toolbar=_.full;m.actions=f;m.presets=_;var z=m;return j(D);})();
package/dist/jotter.js CHANGED
@@ -360,8 +360,12 @@ var JotterJS = class {
360
360
  this._lastHiliteColor = "#c8a96e";
361
361
  this._selectedMedia = null;
362
362
  this._resizeState = null;
363
+ this._moveState = null;
364
+ this._suppressAutoEmit = false;
363
365
  this._onResizeMove = this._onResizeMove.bind(this);
364
366
  this._onResizeEnd = this._onResizeEnd.bind(this);
367
+ this._onMoveMove = this._onMoveMove.bind(this);
368
+ this._onMoveUp = this._onMoveUp.bind(this);
365
369
  this._init();
366
370
  }
367
371
  // ─── Init ─────────────────────────────────────────────────────────────────
@@ -1330,11 +1334,14 @@ var JotterJS = class {
1330
1334
  frame.appendChild(h);
1331
1335
  });
1332
1336
  frame.addEventListener("mousedown", (e) => {
1333
- const handle = e.target.closest(".jotter-resize-handle");
1334
- if (!handle || !this._selectedMedia)
1337
+ if (!this._selectedMedia)
1335
1338
  return;
1336
1339
  e.preventDefault();
1337
- this._beginResize(handle.dataset.handle, e);
1340
+ const handle = e.target.closest(".jotter-resize-handle");
1341
+ if (handle)
1342
+ this._beginResize(handle.dataset.handle, e);
1343
+ else
1344
+ this._beginPotentialMove(this._selectedMedia, e);
1338
1345
  });
1339
1346
  return frame;
1340
1347
  }
@@ -1360,7 +1367,14 @@ var JotterJS = class {
1360
1367
  return wrap;
1361
1368
  return null;
1362
1369
  }
1363
- /** Selects a media element: shows the frame over it and parks a real caret before it. */
1370
+ /**
1371
+ * Selects a media element: shows the frame over it and makes it the real DOM
1372
+ * selection (the whole node, not a collapsed caret beside it). A real
1373
+ * non-collapsed selection is what lets native Ctrl+C/Ctrl+X and the
1374
+ * toolbar's Copy/Cut buttons (both just execCommand('copy'/'cut')) work on
1375
+ * it for free — see the 'copy'/'cut' listeners in _bindEvents for how the
1376
+ * click-shield is kept out of what actually lands on the clipboard.
1377
+ */
1364
1378
  _selectMedia(el) {
1365
1379
  if (this._selectedMedia === el)
1366
1380
  return;
@@ -1370,17 +1384,18 @@ var JotterJS = class {
1370
1384
  this._mediaFrame.classList.add("jotter-media-frame--visible");
1371
1385
  this._editor.focus({ preventScroll: true });
1372
1386
  const range = document.createRange();
1373
- range.setStartBefore(el);
1374
- range.collapse(true);
1387
+ range.selectNode(el);
1375
1388
  const sel = window.getSelection();
1376
1389
  sel.removeAllRanges();
1377
1390
  sel.addRange(range);
1378
1391
  this._updateToolbarState();
1379
1392
  }
1380
- /** Clears the current media selection (and aborts any in-flight resize). */
1393
+ /** Clears the current media selection (and aborts any in-flight resize or move). */
1381
1394
  _deselectMedia() {
1382
1395
  if (this._resizeState)
1383
1396
  this._abortResize();
1397
+ if (this._moveState)
1398
+ this._abortMove();
1384
1399
  if (!this._selectedMedia)
1385
1400
  return;
1386
1401
  this._selectedMedia = null;
@@ -1479,6 +1494,165 @@ var JotterJS = class {
1479
1494
  this._resizeState = null;
1480
1495
  this._positionMediaFrame();
1481
1496
  }
1497
+ /**
1498
+ * Arms a possible drag-to-reposition without committing to one: a plain
1499
+ * click (mouseup with no meaningful movement) must still work as "just
1500
+ * select it", so nothing visible happens until the pointer actually moves
1501
+ * past a small threshold — see _onMoveMove.
1502
+ */
1503
+ _beginPotentialMove(el, e) {
1504
+ this._moveState = { el, startX: e.clientX, startY: e.clientY, dragging: false };
1505
+ document.addEventListener("mousemove", this._onMoveMove);
1506
+ document.addEventListener("mouseup", this._onMoveUp, { once: true });
1507
+ }
1508
+ _onMoveMove(e) {
1509
+ const s = this._moveState;
1510
+ if (!s)
1511
+ return;
1512
+ if (!s.dragging) {
1513
+ if (Math.hypot(e.clientX - s.startX, e.clientY - s.startY) < 5)
1514
+ return;
1515
+ s.dragging = true;
1516
+ s.before = this._richHTML();
1517
+ this._mediaFrame.classList.add("jotter-media-frame--dragging");
1518
+ document.body.style.cursor = "grabbing";
1519
+ }
1520
+ s.dropRange = this._rangeFromPoint(e.clientX, e.clientY);
1521
+ this._showDropIndicator(s.dropRange);
1522
+ }
1523
+ _onMoveUp() {
1524
+ document.removeEventListener("mousemove", this._onMoveMove);
1525
+ const s = this._moveState;
1526
+ this._moveState = null;
1527
+ this._mediaFrame.classList.remove("jotter-media-frame--dragging");
1528
+ document.body.style.cursor = "";
1529
+ this._hideDropIndicator();
1530
+ if (s && s.dragging)
1531
+ this._commitMove(s.el, s.dropRange, s.before);
1532
+ }
1533
+ /** Escape mid-drag: drop nothing, leave the document exactly as it was. */
1534
+ _abortMove() {
1535
+ const s = this._moveState;
1536
+ if (!s)
1537
+ return;
1538
+ document.removeEventListener("mousemove", this._onMoveMove);
1539
+ document.removeEventListener("mouseup", this._onMoveUp);
1540
+ this._moveState = null;
1541
+ this._mediaFrame.classList.remove("jotter-media-frame--dragging");
1542
+ document.body.style.cursor = "";
1543
+ this._hideDropIndicator();
1544
+ }
1545
+ /**
1546
+ * Hit-tests viewport coordinates to a caret position, rejecting drops
1547
+ * outside the editor and drops inside the very node being dragged (moving
1548
+ * something into itself makes no sense and would detach it from the doc).
1549
+ */
1550
+ _rangeFromPoint(x, y) {
1551
+ let range = null;
1552
+ if (document.caretRangeFromPoint) {
1553
+ range = document.caretRangeFromPoint(x, y);
1554
+ } else if (document.caretPositionFromPoint) {
1555
+ const pos = document.caretPositionFromPoint(x, y);
1556
+ if (pos) {
1557
+ range = document.createRange();
1558
+ range.setStart(pos.offsetNode, pos.offset);
1559
+ range.collapse(true);
1560
+ }
1561
+ }
1562
+ if (!range || !this._editor.contains(range.startContainer))
1563
+ return null;
1564
+ const s = this._moveState;
1565
+ if (s && s.el.contains(range.startContainer))
1566
+ return null;
1567
+ return range;
1568
+ }
1569
+ _buildDropIndicator() {
1570
+ const el = document.createElement("div");
1571
+ el.className = "jotter-drop-indicator";
1572
+ return el;
1573
+ }
1574
+ /**
1575
+ * Shows a vertical text-caret-style indicator at the exact drop point, or
1576
+ * hides it when the drop target is invalid. A full-width horizontal line
1577
+ * would suggest a new block boundary; the drop actually lands at whatever
1578
+ * precise character position was hit-tested (mid-line included), so the
1579
+ * indicator has to match that — same idea as where a text cursor blinks.
1580
+ */
1581
+ _showDropIndicator(range) {
1582
+ if (!this._dropIndicator) {
1583
+ this._dropIndicator = this._buildDropIndicator();
1584
+ this._editorWrap.appendChild(this._dropIndicator);
1585
+ }
1586
+ const rect = range && range.getClientRects()[0];
1587
+ if (!rect) {
1588
+ this._dropIndicator.style.display = "none";
1589
+ return;
1590
+ }
1591
+ const wrapRect = this._editorWrap.getBoundingClientRect();
1592
+ this._dropIndicator.style.display = "block";
1593
+ this._dropIndicator.style.top = rect.top - wrapRect.top + this._editorWrap.scrollTop + "px";
1594
+ this._dropIndicator.style.left = rect.left - wrapRect.left + this._editorWrap.scrollLeft + "px";
1595
+ this._dropIndicator.style.height = (rect.height || 20) + "px";
1596
+ }
1597
+ _hideDropIndicator() {
1598
+ if (this._dropIndicator)
1599
+ this._dropIndicator.style.display = "none";
1600
+ }
1601
+ /**
1602
+ * Moves el to dropRange via execCommand('delete') + execCommand('insertHTML')
1603
+ * rather than a plain DOM insertBefore, for the same reason _deleteSelectedMedia
1604
+ * avoids el.remove(): only execCommand-driven edits land on the native undo
1605
+ * stack. That does mean a move takes two Ctrl+Z presses to fully unwind
1606
+ * (one per command) rather than one — an accepted trade-off, since the
1607
+ * alternative (a raw DOM move) would not be undoable at all.
1608
+ *
1609
+ * The two execCommands' own 'input' events would each independently call
1610
+ * _emitChange() with intermediate — and, for the insert half, momentarily
1611
+ * tagged — HTML; _suppressAutoEmit holds that back so hosts only ever see
1612
+ * the clean start and end states, as exactly one 'change'.
1613
+ */
1614
+ _commitMove(el, dropRange, before) {
1615
+ if (!dropRange || !dropRange.startContainer.isConnected)
1616
+ return;
1617
+ const marker = "jmv" + ++this._bmSeq;
1618
+ const clone = el.cloneNode(true);
1619
+ clone.querySelectorAll(".jotter-media-shield").forEach((s) => s.remove());
1620
+ clone.setAttribute("data-jotter-move", marker);
1621
+ this._suppressAutoEmit = true;
1622
+ const sel = window.getSelection();
1623
+ const delRange = document.createRange();
1624
+ delRange.selectNode(el);
1625
+ sel.removeAllRanges();
1626
+ sel.addRange(delRange);
1627
+ document.execCommand("delete", false, null);
1628
+ sel.removeAllRanges();
1629
+ sel.addRange(dropRange);
1630
+ document.execCommand("insertHTML", false, clone.outerHTML);
1631
+ const inserted = this._editor.querySelector(`[data-jotter-move="${marker}"]`);
1632
+ if (inserted)
1633
+ inserted.removeAttribute("data-jotter-move");
1634
+ this._suppressAutoEmit = false;
1635
+ this._updateStatus();
1636
+ if (inserted)
1637
+ this._selectMedia(inserted);
1638
+ else
1639
+ this._deselectMedia();
1640
+ if (this._richHTML() !== before)
1641
+ this._emitChange();
1642
+ }
1643
+ /**
1644
+ * Writes a media element to the clipboard with its click-shield stripped —
1645
+ * the shield is edit-time-only bookkeeping (see _ensureMediaShields) and
1646
+ * must never leak into copied/cut content any more than it leaks into
1647
+ * getHTML(). Used by both the 'copy'/'cut' listeners below and (via
1648
+ * execCommand('copy'/'cut')) the toolbar's Copy/Cut buttons.
1649
+ */
1650
+ _writeMediaToClipboard(e, el) {
1651
+ const clone = el.cloneNode(true);
1652
+ clone.querySelectorAll(".jotter-media-shield").forEach((s) => s.remove());
1653
+ e.clipboardData.setData("text/html", clone.outerHTML);
1654
+ e.clipboardData.setData("text/plain", el.tagName === "IMG" ? el.alt || "" : el.textContent || "");
1655
+ }
1482
1656
  // ─── Events ───────────────────────────────────────────────────────────────
1483
1657
  _bindEvents() {
1484
1658
  this._editor.addEventListener("input", () => {
@@ -1514,15 +1688,41 @@ var JotterJS = class {
1514
1688
  if (this._selectedMedia)
1515
1689
  this._positionMediaFrame();
1516
1690
  this._updateStatus();
1517
- this._emitChange();
1691
+ if (!this._suppressAutoEmit)
1692
+ this._emitChange();
1518
1693
  });
1519
1694
  this._editor.addEventListener("keyup", () => this._updateToolbarState());
1520
1695
  this._editor.addEventListener("mouseup", () => this._updateToolbarState());
1521
1696
  this._editor.addEventListener("mousedown", (e) => {
1522
1697
  const media = this._mediaElementFromTarget(e.target);
1523
- if (media) {
1524
- e.preventDefault();
1525
- this._selectMedia(media);
1698
+ if (!media)
1699
+ return;
1700
+ e.preventDefault();
1701
+ this._selectMedia(media);
1702
+ this._beginPotentialMove(media, e);
1703
+ });
1704
+ this._editor.addEventListener("copy", (e) => {
1705
+ if (!this._selectedMedia)
1706
+ return;
1707
+ e.preventDefault();
1708
+ this._writeMediaToClipboard(e, this._selectedMedia);
1709
+ });
1710
+ this._editor.addEventListener("cut", (e) => {
1711
+ if (!this._selectedMedia)
1712
+ return;
1713
+ e.preventDefault();
1714
+ this._writeMediaToClipboard(e, this._selectedMedia);
1715
+ this._deleteSelectedMedia();
1716
+ });
1717
+ this._editor.addEventListener("paste", (e) => {
1718
+ e.preventDefault();
1719
+ const html = (e.clipboardData || window.clipboardData).getData("text/html");
1720
+ if (html) {
1721
+ this._applyEdit(() => document.execCommand("insertHTML", false, this._sanitize(html)));
1722
+ } else {
1723
+ const text = (e.clipboardData || window.clipboardData).getData("text/plain");
1724
+ if (text)
1725
+ this._applyEdit(() => document.execCommand("insertText", false, text));
1526
1726
  }
1527
1727
  });
1528
1728
  this._onWindowResize = () => {
@@ -1586,6 +1786,10 @@ var JotterJS = class {
1586
1786
  this._abortResize();
1587
1787
  return;
1588
1788
  }
1789
+ if (this._moveState && this._moveState.dragging) {
1790
+ this._abortMove();
1791
+ return;
1792
+ }
1589
1793
  if (this._selectedMedia) {
1590
1794
  this._deselectMedia();
1591
1795
  return;
@@ -1792,6 +1996,7 @@ var JotterJS = class {
1792
1996
  _richHTML() {
1793
1997
  const clone = this._editor.cloneNode(true);
1794
1998
  clone.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach((el) => el.remove());
1999
+ clone.querySelectorAll("[data-jotter-move]").forEach((el) => el.removeAttribute("data-jotter-move"));
1795
2000
  return clone.innerHTML;
1796
2001
  }
1797
2002
  _makeMarker(id) {
@@ -1 +1 @@
1
- @font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url("./fonts/material-symbols-rounded.woff2") format("woff2")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:"liga";font-feature-settings:"liga";-webkit-font-smoothing:antialiased}:root{--jotter-bg: #ffffff;--jotter-surface: #f4f3f0;--jotter-surface2: #eceae5;--jotter-border: #d8d4cc;--jotter-border-focus: #7a6a4a;--jotter-text: #1e1c18;--jotter-text-muted: #9a9488;--jotter-accent: #7a6a4a;--jotter-btn-hover: rgba(122, 106, 74, .07);--jotter-btn-active-bg: rgba(122, 106, 74, .14);--jotter-radius: 4px;--jotter-font-ui: "DM Mono", "Fira Mono", "Consolas", monospace;--jotter-font-editor: Georgia, "Times New Roman", serif;--jotter-status-h: 32px;--jotter-transition: .14s ease}.jotter-host{display:block}.htmled{display:flex;flex-direction:column;border:1px solid var(--jotter-border);border-radius:var(--jotter-radius);background:var(--jotter-bg);color:var(--jotter-text);font-family:var(--jotter-font-ui);overflow:hidden;transition:border-color var(--jotter-transition),box-shadow var(--jotter-transition)}.jotter--focused{border-color:var(--jotter-border-focus);box-shadow:0 0 0 3px #7a6a4a1a}.jotter--disabled{opacity:.55;pointer-events:none}.jotter-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:6px 8px;background:var(--jotter-surface);border-bottom:1px solid var(--jotter-border)}.jotter-select{appearance:none;-webkit-appearance:none;background:transparent;border:1px solid var(--jotter-border);border-radius:var(--jotter-radius);color:var(--jotter-text);font-family:var(--jotter-font-ui);font-size:11px;letter-spacing:.04em;padding:4px 8px;height:28px;cursor:pointer;flex-shrink:0;transition:border-color var(--jotter-transition),background var(--jotter-transition)}.jotter-select{min-width:108px;text-transform:uppercase}.jotter-select--font{min-width:130px;text-transform:none}.jotter-select--size{min-width:68px;text-transform:none}.jotter-select--theme{min-width:90px;text-transform:none}.jotter-select:hover{border-color:var(--jotter-accent);background:var(--jotter-btn-hover)}.jotter-select:focus{outline:none;border-color:var(--jotter-accent)}.jotter-select option{background:var(--jotter-surface2);color:var(--jotter-text)}.jotter-btn{display:flex;align-items:center;justify-content:center;flex-direction:column;width:32px;height:30px;padding:0;border:none;border-radius:var(--jotter-radius);background:transparent;color:var(--jotter-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--jotter-transition),background var(--jotter-transition);position:relative}.jotter-btn .material-icons{pointer-events:none;font-size:18px;line-height:1;user-select:none}.jotter-btn:hover{color:var(--jotter-accent);background:var(--jotter-btn-hover)}.jotter-btn--active{color:var(--jotter-accent)!important;background:var(--jotter-btn-active-bg)!important}.jotter-btn--text{width:auto;padding:0 10px;font-family:var(--jotter-font-ui);font-size:11px;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--jotter-border)}.jotter-sep{width:1px;height:18px;background:var(--jotter-border);margin:0 4px;flex-shrink:0}.jotter-color-wrap{display:inline-flex;align-items:center;flex-shrink:0}.jotter-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none}.jotter-color-btn{width:32px;height:34px;gap:0;padding-bottom:3px}.jotter-color-swatch{display:block;width:18px;height:3px;border-radius:1px;pointer-events:none;flex-shrink:0}.jotter-editor-wrap{position:relative;flex:1;overflow-y:auto;background:var(--jotter-bg);scrollbar-width:thin;scrollbar-color:var(--jotter-border) transparent}.jotter-editor-wrap::-webkit-scrollbar{width:6px}.jotter-editor-wrap::-webkit-scrollbar-track{background:transparent}.jotter-editor-wrap::-webkit-scrollbar-thumb{background:var(--jotter-border);border-radius:3px}.jotter-editor{outline:none;padding:24px 28px;min-height:200px;font-family:var(--jotter-font-editor);font-size:16px;line-height:1.75;color:var(--jotter-text);caret-color:auto;word-break:break-word}.jotter-source{display:none;width:100%;min-height:200px;padding:24px 28px;background:var(--jotter-bg);color:#3a6030;font-family:var(--jotter-font-ui);font-size:13px;line-height:1.7;border:none;outline:none;resize:vertical;caret-color:var(--jotter-accent);tab-size:2;white-space:pre;overflow-wrap:normal;overflow-x:auto}.jotter--source-mode .jotter-btn:not([data-custom=toggleSource]),.jotter--source-mode .jotter-select,.jotter--source-mode .jotter-color-btn{opacity:.35;pointer-events:none}.jotter-editor:empty:before{content:attr(data-placeholder);color:var(--jotter-text-muted);pointer-events:none;font-style:italic}.jotter-editor .jotter-bookmark{display:none}.jotter-editor h1,.jotter-editor h2,.jotter-editor h3,.jotter-editor h4,.jotter-editor h5,.jotter-editor h6{text-transform:none;font-family:var(--ed-heading-font, inherit);letter-spacing:var(--ed-heading-tracking, normal)}.jotter-editor h1{font-size:2em;font-weight:700;margin:.6em 0 .3em;color:var(--ed-h1, inherit);border-bottom:var(--ed-h1-rule, none);padding-bottom:.25em}.jotter-editor h2{font-size:1.5em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h2, inherit)}.jotter-editor h3{font-size:1.2em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h3, inherit)}.jotter-editor h4{font-size:1em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h4, inherit)}.jotter-editor p{margin:0 0 .85em}.jotter-editor a{color:var(--ed-link, -webkit-link);text-decoration-color:var(--ed-link-deco, auto);text-underline-offset:3px}.jotter-editor a:hover{text-decoration-color:var(--ed-link, -webkit-link)}.jotter-editor strong,.jotter-editor b{color:var(--ed-strong, inherit);font-weight:700}.jotter-editor em,.jotter-editor i{color:var(--ed-em, inherit)}.jotter-editor blockquote{margin:1em 0;padding:8px 0 8px 20px;font-style:italic;border-left:3px solid var(--ed-quote-bar, #ccc);color:var(--ed-quote, inherit)}.jotter-editor pre{font-family:var(--ed-code-font, monospace);font-size:.875em;margin:.75em 0;padding:12px 16px;overflow-x:auto;white-space:pre-wrap;background:var(--ed-code-bg, transparent);color:var(--ed-code-text, inherit);border:1px solid var(--ed-code-border, transparent);border-radius:var(--jotter-radius)}.jotter-editor code{font-family:var(--ed-code-font, monospace);font-size:.875em;padding:1px 4px;background:var(--ed-code-bg, transparent);color:var(--ed-code-text, inherit);border:1px solid var(--ed-code-border, transparent);border-radius:2px}.jotter-editor ul,.jotter-editor ol{padding-left:24px;margin:.5em 0 .85em}.jotter-editor li{margin-bottom:.25em}.jotter-editor ul li::marker{color:var(--ed-marker, inherit)}.jotter-editor ol li::marker{color:var(--ed-marker, inherit)}.jotter-editor hr{border:none;border-top:1px solid var(--ed-hr, currentColor);opacity:.2;margin:1.5em 0}.jotter-editor sub,.jotter-editor sup{font-size:.75em}.jotter-editor ::selection{background:var(--ed-selection, highlight)}.jotter-editor table{border-collapse:collapse;width:100%;margin:.75em 0;font-size:.95em}.jotter-editor th,.jotter-editor td{border:1px solid var(--ed-table-border, #ccc);padding:7px 12px;text-align:left;vertical-align:top;min-width:40px}.jotter-editor th{background:var(--ed-th-bg, transparent);color:var(--ed-th-text, inherit);font-family:var(--ed-heading-font, inherit);font-size:.85em;font-weight:600;text-transform:none}.jotter-editor[data-theme=warm]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #7a6a4a;--ed-selection: rgba(122, 106, 74, .18);--ed-h1: #7a6a4a;--ed-h2: #4a3e28;--ed-h3: #5a4e38;--ed-h4: #9a9488;--ed-h1-rule: 1px solid #d8d4cc;--ed-link: #7a6a4a;--ed-link-deco: rgba(122, 106, 74, .35);--ed-strong: #1a1612;--ed-em: #3a3028;--ed-quote: #7a7468;--ed-quote-bar: #7a6a4a;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eceae5;--ed-code-border: #d8d4cc;--ed-code-text: #3a6030;--ed-marker: #7a6a4a;--ed-hr: #d8d4cc;--ed-th-bg: #f4f3f0;--ed-th-text: #7a6a4a;--ed-table-border: #d8d4cc}.jotter-editor[data-theme=ink]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #1a2a4a;--ed-selection: rgba(26, 42, 74, .14);--ed-h1: #0d1f3c;--ed-h2: #1a2a4a;--ed-h3: #243560;--ed-h4: #5a6888;--ed-h1-rule: 1px solid #b8c4d8;--ed-link: #1a4a8a;--ed-link-deco: rgba(26, 74, 138, .3);--ed-strong: #0a1428;--ed-em: #2a3a5a;--ed-quote: #4a5a78;--ed-quote-bar: #1a4a8a;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eef0f6;--ed-code-border: #c8cedd;--ed-code-text: #1a4a3a;--ed-marker: #1a4a8a;--ed-hr: #b8c4d8;--ed-th-bg: #eef0f6;--ed-th-text: #1a2a4a;--ed-table-border: #b8c4d8}.jotter-editor[data-theme=forest]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #1a3a28;--ed-selection: rgba(26, 58, 40, .14);--ed-h1: #1a3a28;--ed-h2: #1e4430;--ed-h3: #2a5a40;--ed-h4: #5a7a68;--ed-h1-rule: 1px solid #b0ccc0;--ed-link: #1a6040;--ed-link-deco: rgba(26, 96, 64, .3);--ed-strong: #0e2018;--ed-em: #2a4038;--ed-quote: #3a5a48;--ed-quote-bar: #1a6040;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eef5f0;--ed-code-border: #c0d8c8;--ed-code-text: #1a5828;--ed-marker: #1a6040;--ed-hr: #b0ccc0;--ed-th-bg: #eef5f0;--ed-th-text: #1a3a28;--ed-table-border: #b0ccc0}.jotter-editor .jotter-video-wrap{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:.75em 0;border-radius:var(--jotter-radius);border:1px solid var(--jotter-border)}.jotter-editor .jotter-video-wrap iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:1}.jotter-editor .jotter-embed-wrap{position:relative;display:block;width:100%;margin:.75em 0}.jotter-media-frame{position:absolute;display:none;box-sizing:border-box;border:2px solid var(--jotter-accent);border-radius:2px;pointer-events:none;z-index:5}.jotter-media-frame--visible{display:block}.jotter-resize-handle{position:absolute;width:10px;height:10px;background:var(--jotter-bg);border:2px solid var(--jotter-accent);border-radius:50%;pointer-events:auto;transform:translate(-50%,-50%)}.jotter-resize-handle--nw{top:0;left:0;cursor:nwse-resize}.jotter-resize-handle--ne{top:0;left:100%;cursor:nesw-resize}.jotter-resize-handle--sw{top:100%;left:0;cursor:nesw-resize}.jotter-resize-handle--se{top:100%;left:100%;cursor:nwse-resize}.jotter-resize-handle--w{top:50%;left:0;cursor:ew-resize}.jotter-resize-handle--e{top:50%;left:100%;cursor:ew-resize}.jotter--source-mode .jotter-media-frame{display:none!important}.jotter-media-shield{position:absolute;inset:0;z-index:2;background:transparent;cursor:pointer}.jotter-status{display:flex;align-items:center;gap:16px;padding:0 14px;height:var(--jotter-status-h);min-height:var(--jotter-status-h);background:var(--jotter-surface);border-top:1px solid var(--jotter-border);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--jotter-text-muted)}.jotter-status-mode{margin-left:auto;color:var(--jotter-accent);font-weight:600}.jotter-popup{display:none;position:fixed;z-index:9999;background:#fff;border:1px solid #d8d4cc;border-radius:5px;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000012;min-width:220px;max-width:360px}.jotter-popup--visible{display:block}.jotter-popup-inner{padding:14px}.jotter-popup-title{font-family:var(--jotter-font-ui);font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:#9a9488;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid #d8d4cc}.jotter-popup-hint{font-size:11px;color:#9a9488;margin-top:8px;text-align:center;letter-spacing:.04em}.jotter-popup-form{display:flex;flex-direction:column;gap:6px;min-width:280px}.jotter-popup-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#9a9488;margin-top:4px}.jotter-popup-input,.jotter-popup-select,.jotter-popup-textarea{width:100%;background:#f8f7f4;border:1px solid #d8d4cc;border-radius:3px;color:#1e1c18;font-family:DM Mono,Fira Mono,monospace;font-size:12px;padding:7px 9px;outline:none;transition:border-color .12s;resize:vertical}.jotter-popup-input:focus,.jotter-popup-select:focus,.jotter-popup-textarea:focus{border-color:#7a6a4a}.jotter-popup-select{appearance:auto;cursor:pointer;resize:none}.jotter-input--error{border-color:#b85050!important}.jotter-popup-submit{margin-top:6px;padding:7px 14px;background:#7a6a4a14;border:1px solid #7a6a4a;border-radius:3px;color:#7a6a4a;font-family:DM Mono,Fira Mono,monospace;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:background .12s}.jotter-popup-submit:hover{background:#7a6a4a29}.jotter-table-grid{display:grid;gap:3px}.jotter-table-cell{width:18px;height:18px;border:1px solid #d8d4cc;border-radius:2px;cursor:pointer;transition:border-color 80ms,background 80ms}.jotter-table-cell--active{background:#7a6a4a24;border-color:#7a6a4a}.jotter-char-grid{display:flex;flex-wrap:wrap;gap:2px;max-width:300px;max-height:220px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:#d8d4cc transparent}.jotter-char-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid #d8d4cc;border-radius:3px;background:transparent;color:#1e1c18;font-size:14px;cursor:pointer;transition:background 80ms,border-color 80ms,color 80ms;flex-shrink:0}.jotter-char-btn:hover{background:#7a6a4a1a;border-color:#7a6a4a;color:#7a6a4a}.jotter-lorem-btn{display:block;width:100%;padding:9px 12px;background:transparent;border:1px solid #d8d4cc;border-radius:3px;color:#1e1c18;font-family:DM Mono,Fira Mono,monospace;font-size:11px;letter-spacing:.04em;text-align:left;cursor:pointer;margin-bottom:4px;transition:background .1s,border-color .1s,color .1s}.jotter-lorem-btn:hover{background:#7a6a4a12;border-color:#7a6a4a;color:#7a6a4a}.jotter-btn:focus-visible,.jotter-select:focus-visible,.jotter-char-btn:focus-visible,.jotter-lorem-btn:focus-visible,.jotter-popup-submit:focus-visible,.jotter-table-cell:focus-visible{outline:2px solid var(--jotter-accent);outline-offset:1px}
1
+ @font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url("./fonts/material-symbols-rounded.woff2") format("woff2")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:"liga";font-feature-settings:"liga";-webkit-font-smoothing:antialiased}:root{--jotter-bg: #ffffff;--jotter-surface: #f4f3f0;--jotter-surface2: #eceae5;--jotter-border: #d8d4cc;--jotter-border-focus: #7a6a4a;--jotter-text: #1e1c18;--jotter-text-muted: #9a9488;--jotter-accent: #7a6a4a;--jotter-btn-hover: rgba(122, 106, 74, .07);--jotter-btn-active-bg: rgba(122, 106, 74, .14);--jotter-radius: 4px;--jotter-font-ui: "DM Mono", "Fira Mono", "Consolas", monospace;--jotter-font-editor: Georgia, "Times New Roman", serif;--jotter-status-h: 32px;--jotter-transition: .14s ease}.jotter-host{display:block}.htmled{display:flex;flex-direction:column;border:1px solid var(--jotter-border);border-radius:var(--jotter-radius);background:var(--jotter-bg);color:var(--jotter-text);font-family:var(--jotter-font-ui);overflow:hidden;transition:border-color var(--jotter-transition),box-shadow var(--jotter-transition)}.jotter--focused{border-color:var(--jotter-border-focus);box-shadow:0 0 0 3px #7a6a4a1a}.jotter--disabled{opacity:.55;pointer-events:none}.jotter-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:6px 8px;background:var(--jotter-surface);border-bottom:1px solid var(--jotter-border)}.jotter-select{appearance:none;-webkit-appearance:none;background:transparent;border:1px solid var(--jotter-border);border-radius:var(--jotter-radius);color:var(--jotter-text);font-family:var(--jotter-font-ui);font-size:11px;letter-spacing:.04em;padding:4px 8px;height:28px;cursor:pointer;flex-shrink:0;transition:border-color var(--jotter-transition),background var(--jotter-transition)}.jotter-select{min-width:108px;text-transform:uppercase}.jotter-select--font{min-width:130px;text-transform:none}.jotter-select--size{min-width:68px;text-transform:none}.jotter-select--theme{min-width:90px;text-transform:none}.jotter-select:hover{border-color:var(--jotter-accent);background:var(--jotter-btn-hover)}.jotter-select:focus{outline:none;border-color:var(--jotter-accent)}.jotter-select option{background:var(--jotter-surface2);color:var(--jotter-text)}.jotter-btn{display:flex;align-items:center;justify-content:center;flex-direction:column;width:32px;height:30px;padding:0;border:none;border-radius:var(--jotter-radius);background:transparent;color:var(--jotter-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--jotter-transition),background var(--jotter-transition);position:relative}.jotter-btn .material-icons{pointer-events:none;font-size:18px;line-height:1;user-select:none}.jotter-btn:hover{color:var(--jotter-accent);background:var(--jotter-btn-hover)}.jotter-btn--active{color:var(--jotter-accent)!important;background:var(--jotter-btn-active-bg)!important}.jotter-btn--text{width:auto;padding:0 10px;font-family:var(--jotter-font-ui);font-size:11px;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--jotter-border)}.jotter-sep{width:1px;height:18px;background:var(--jotter-border);margin:0 4px;flex-shrink:0}.jotter-color-wrap{display:inline-flex;align-items:center;flex-shrink:0}.jotter-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none}.jotter-color-btn{width:32px;height:34px;gap:0;padding-bottom:3px}.jotter-color-swatch{display:block;width:18px;height:3px;border-radius:1px;pointer-events:none;flex-shrink:0}.jotter-editor-wrap{position:relative;flex:1;overflow-y:auto;background:var(--jotter-bg);scrollbar-width:thin;scrollbar-color:var(--jotter-border) transparent}.jotter-editor-wrap::-webkit-scrollbar{width:6px}.jotter-editor-wrap::-webkit-scrollbar-track{background:transparent}.jotter-editor-wrap::-webkit-scrollbar-thumb{background:var(--jotter-border);border-radius:3px}.jotter-editor{outline:none;padding:24px 28px;min-height:200px;font-family:var(--jotter-font-editor);font-size:16px;line-height:1.75;color:var(--jotter-text);caret-color:auto;word-break:break-word}.jotter-source{display:none;width:100%;min-height:200px;padding:24px 28px;background:var(--jotter-bg);color:#3a6030;font-family:var(--jotter-font-ui);font-size:13px;line-height:1.7;border:none;outline:none;resize:vertical;caret-color:var(--jotter-accent);tab-size:2;white-space:pre;overflow-wrap:normal;overflow-x:auto}.jotter--source-mode .jotter-btn:not([data-custom=toggleSource]),.jotter--source-mode .jotter-select,.jotter--source-mode .jotter-color-btn{opacity:.35;pointer-events:none}.jotter-editor:empty:before{content:attr(data-placeholder);color:var(--jotter-text-muted);pointer-events:none;font-style:italic}.jotter-editor .jotter-bookmark{display:none}.jotter-editor h1,.jotter-editor h2,.jotter-editor h3,.jotter-editor h4,.jotter-editor h5,.jotter-editor h6{text-transform:none;font-family:var(--ed-heading-font, inherit);letter-spacing:var(--ed-heading-tracking, normal)}.jotter-editor h1{font-size:2em;font-weight:700;margin:.6em 0 .3em;color:var(--ed-h1, inherit);border-bottom:var(--ed-h1-rule, none);padding-bottom:.25em}.jotter-editor h2{font-size:1.5em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h2, inherit)}.jotter-editor h3{font-size:1.2em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h3, inherit)}.jotter-editor h4{font-size:1em;font-weight:600;margin:.75em 0 .25em;color:var(--ed-h4, inherit)}.jotter-editor p{margin:0 0 .85em}.jotter-editor a{color:var(--ed-link, -webkit-link);text-decoration-color:var(--ed-link-deco, auto);text-underline-offset:3px}.jotter-editor a:hover{text-decoration-color:var(--ed-link, -webkit-link)}.jotter-editor strong,.jotter-editor b{color:var(--ed-strong, inherit);font-weight:700}.jotter-editor em,.jotter-editor i{color:var(--ed-em, inherit)}.jotter-editor blockquote{margin:1em 0;padding:8px 0 8px 20px;font-style:italic;border-left:3px solid var(--ed-quote-bar, #ccc);color:var(--ed-quote, inherit)}.jotter-editor pre{font-family:var(--ed-code-font, monospace);font-size:.875em;margin:.75em 0;padding:12px 16px;overflow-x:auto;white-space:pre-wrap;background:var(--ed-code-bg, transparent);color:var(--ed-code-text, inherit);border:1px solid var(--ed-code-border, transparent);border-radius:var(--jotter-radius)}.jotter-editor code{font-family:var(--ed-code-font, monospace);font-size:.875em;padding:1px 4px;background:var(--ed-code-bg, transparent);color:var(--ed-code-text, inherit);border:1px solid var(--ed-code-border, transparent);border-radius:2px}.jotter-editor ul,.jotter-editor ol{padding-left:24px;margin:.5em 0 .85em}.jotter-editor li{margin-bottom:.25em}.jotter-editor ul li::marker{color:var(--ed-marker, inherit)}.jotter-editor ol li::marker{color:var(--ed-marker, inherit)}.jotter-editor hr{border:none;border-top:1px solid var(--ed-hr, currentColor);opacity:.2;margin:1.5em 0}.jotter-editor sub,.jotter-editor sup{font-size:.75em}.jotter-editor ::selection{background:var(--ed-selection, highlight)}.jotter-editor table{border-collapse:collapse;width:100%;margin:.75em 0;font-size:.95em}.jotter-editor th,.jotter-editor td{border:1px solid var(--ed-table-border, #ccc);padding:7px 12px;text-align:left;vertical-align:top;min-width:40px}.jotter-editor th{background:var(--ed-th-bg, transparent);color:var(--ed-th-text, inherit);font-family:var(--ed-heading-font, inherit);font-size:.85em;font-weight:600;text-transform:none}.jotter-editor[data-theme=warm]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #7a6a4a;--ed-selection: rgba(122, 106, 74, .18);--ed-h1: #7a6a4a;--ed-h2: #4a3e28;--ed-h3: #5a4e38;--ed-h4: #9a9488;--ed-h1-rule: 1px solid #d8d4cc;--ed-link: #7a6a4a;--ed-link-deco: rgba(122, 106, 74, .35);--ed-strong: #1a1612;--ed-em: #3a3028;--ed-quote: #7a7468;--ed-quote-bar: #7a6a4a;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eceae5;--ed-code-border: #d8d4cc;--ed-code-text: #3a6030;--ed-marker: #7a6a4a;--ed-hr: #d8d4cc;--ed-th-bg: #f4f3f0;--ed-th-text: #7a6a4a;--ed-table-border: #d8d4cc}.jotter-editor[data-theme=ink]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #1a2a4a;--ed-selection: rgba(26, 42, 74, .14);--ed-h1: #0d1f3c;--ed-h2: #1a2a4a;--ed-h3: #243560;--ed-h4: #5a6888;--ed-h1-rule: 1px solid #b8c4d8;--ed-link: #1a4a8a;--ed-link-deco: rgba(26, 74, 138, .3);--ed-strong: #0a1428;--ed-em: #2a3a5a;--ed-quote: #4a5a78;--ed-quote-bar: #1a4a8a;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eef0f6;--ed-code-border: #c8cedd;--ed-code-text: #1a4a3a;--ed-marker: #1a4a8a;--ed-hr: #b8c4d8;--ed-th-bg: #eef0f6;--ed-th-text: #1a2a4a;--ed-table-border: #b8c4d8}.jotter-editor[data-theme=forest]{--ed-heading-font: "DM Mono", "Fira Mono", monospace;--ed-heading-tracking: -.01em;--ed-caret: #1a3a28;--ed-selection: rgba(26, 58, 40, .14);--ed-h1: #1a3a28;--ed-h2: #1e4430;--ed-h3: #2a5a40;--ed-h4: #5a7a68;--ed-h1-rule: 1px solid #b0ccc0;--ed-link: #1a6040;--ed-link-deco: rgba(26, 96, 64, .3);--ed-strong: #0e2018;--ed-em: #2a4038;--ed-quote: #3a5a48;--ed-quote-bar: #1a6040;--ed-code-font: "DM Mono", "Fira Mono", monospace;--ed-code-bg: #eef5f0;--ed-code-border: #c0d8c8;--ed-code-text: #1a5828;--ed-marker: #1a6040;--ed-hr: #b0ccc0;--ed-th-bg: #eef5f0;--ed-th-text: #1a3a28;--ed-table-border: #b0ccc0}.jotter-editor .jotter-video-wrap{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:.75em 0;border-radius:var(--jotter-radius);border:1px solid var(--jotter-border)}.jotter-editor .jotter-video-wrap iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:1;pointer-events:none}.jotter-editor .jotter-embed-wrap{position:relative;display:block;width:100%;margin:.75em 0}.jotter-editor .jotter-embed-wrap>:not(.jotter-media-shield){pointer-events:none}.jotter-media-frame{position:absolute;display:none;box-sizing:border-box;border:2px solid var(--jotter-accent);border-radius:2px;pointer-events:auto;cursor:move;z-index:5}.jotter-media-frame--visible{display:block}.jotter-media-frame--dragging{border-style:dashed;opacity:.7}.jotter-resize-handle{position:absolute;width:10px;height:10px;background:var(--jotter-bg);border:2px solid var(--jotter-accent);border-radius:50%;pointer-events:auto;transform:translate(-50%,-50%)}.jotter-resize-handle--nw{top:0;left:0;cursor:nwse-resize}.jotter-resize-handle--ne{top:0;left:100%;cursor:nesw-resize}.jotter-resize-handle--sw{top:100%;left:0;cursor:nesw-resize}.jotter-resize-handle--se{top:100%;left:100%;cursor:nwse-resize}.jotter-resize-handle--w{top:50%;left:0;cursor:ew-resize}.jotter-resize-handle--e{top:50%;left:100%;cursor:ew-resize}.jotter--source-mode .jotter-media-frame{display:none!important}.jotter-media-shield{position:absolute;inset:0;z-index:2;background:transparent;cursor:pointer}.jotter-drop-indicator{position:absolute;display:none;width:2px;background:var(--jotter-accent);border-radius:1px;pointer-events:none;z-index:6}.jotter-status{display:flex;align-items:center;gap:16px;padding:0 14px;height:var(--jotter-status-h);min-height:var(--jotter-status-h);background:var(--jotter-surface);border-top:1px solid var(--jotter-border);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--jotter-text-muted)}.jotter-status-mode{margin-left:auto;color:var(--jotter-accent);font-weight:600}.jotter-popup{display:none;position:fixed;z-index:9999;background:#fff;border:1px solid #d8d4cc;border-radius:5px;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000012;min-width:220px;max-width:360px}.jotter-popup--visible{display:block}.jotter-popup-inner{padding:14px}.jotter-popup-title{font-family:var(--jotter-font-ui);font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:#9a9488;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid #d8d4cc}.jotter-popup-hint{font-size:11px;color:#9a9488;margin-top:8px;text-align:center;letter-spacing:.04em}.jotter-popup-form{display:flex;flex-direction:column;gap:6px;min-width:280px}.jotter-popup-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#9a9488;margin-top:4px}.jotter-popup-input,.jotter-popup-select,.jotter-popup-textarea{width:100%;background:#f8f7f4;border:1px solid #d8d4cc;border-radius:3px;color:#1e1c18;font-family:DM Mono,Fira Mono,monospace;font-size:12px;padding:7px 9px;outline:none;transition:border-color .12s;resize:vertical}.jotter-popup-input:focus,.jotter-popup-select:focus,.jotter-popup-textarea:focus{border-color:#7a6a4a}.jotter-popup-select{appearance:auto;cursor:pointer;resize:none}.jotter-input--error{border-color:#b85050!important}.jotter-popup-submit{margin-top:6px;padding:7px 14px;background:#7a6a4a14;border:1px solid #7a6a4a;border-radius:3px;color:#7a6a4a;font-family:DM Mono,Fira Mono,monospace;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:background .12s}.jotter-popup-submit:hover{background:#7a6a4a29}.jotter-table-grid{display:grid;gap:3px}.jotter-table-cell{width:18px;height:18px;border:1px solid #d8d4cc;border-radius:2px;cursor:pointer;transition:border-color 80ms,background 80ms}.jotter-table-cell--active{background:#7a6a4a24;border-color:#7a6a4a}.jotter-char-grid{display:flex;flex-wrap:wrap;gap:2px;max-width:300px;max-height:220px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:#d8d4cc transparent}.jotter-char-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid #d8d4cc;border-radius:3px;background:transparent;color:#1e1c18;font-size:14px;cursor:pointer;transition:background 80ms,border-color 80ms,color 80ms;flex-shrink:0}.jotter-char-btn:hover{background:#7a6a4a1a;border-color:#7a6a4a;color:#7a6a4a}.jotter-lorem-btn{display:block;width:100%;padding:9px 12px;background:transparent;border:1px solid #d8d4cc;border-radius:3px;color:#1e1c18;font-family:DM Mono,Fira Mono,monospace;font-size:11px;letter-spacing:.04em;text-align:left;cursor:pointer;margin-bottom:4px;transition:background .1s,border-color .1s,color .1s}.jotter-lorem-btn:hover{background:#7a6a4a12;border-color:#7a6a4a;color:#7a6a4a}.jotter-btn:focus-visible,.jotter-select:focus-visible,.jotter-char-btn:focus-visible,.jotter-lorem-btn:focus-visible,.jotter-popup-submit:focus-visible,.jotter-table-cell:focus-visible{outline:2px solid var(--jotter-accent);outline-offset:1px}
@@ -1,5 +1,5 @@
1
- var _={source:{custom:"toggleSource",label:"Source",title:"Edit HTML Source"},sep:{type:"sep"},blockformat:{type:"blockformat"},fontfamily:{type:"fontfamily"},fontsize:{type:"fontsize"},theme:{type:"theme"},undo:{cmd:"undo",icon:"undo",title:"Undo (Ctrl+Z)"},redo:{cmd:"redo",icon:"redo",title:"Redo (Ctrl+Y)"},bold:{cmd:"bold",icon:"format_bold",title:"Bold (Ctrl+B)"},italic:{cmd:"italic",icon:"format_italic",title:"Italic (Ctrl+I)"},underline:{cmd:"underline",icon:"format_underlined",title:"Underline (Ctrl+U)"},strike:{cmd:"strikeThrough",icon:"strikethrough_s",title:"Strikethrough"},subscript:{cmd:"subscript",icon:"subscript",title:"Subscript"},superscript:{cmd:"superscript",icon:"superscript",title:"Superscript"},code:{custom:"code",icon:"code",title:"Inline Code"},copy:{cmd:"copy",icon:"content_copy",title:"Copy"},cut:{cmd:"cut",icon:"content_cut",title:"Cut"},paste:{cmd:"paste",icon:"content_paste",title:"Paste"},clearFormat:{cmd:"removeFormat",icon:"format_clear",title:"Clear Formatting"},alignLeft:{cmd:"justifyLeft",icon:"format_align_left",title:"Align Left"},alignCenter:{cmd:"justifyCenter",icon:"format_align_center",title:"Align Center"},alignRight:{cmd:"justifyRight",icon:"format_align_right",title:"Align Right"},bullets:{cmd:"insertUnorderedList",icon:"format_list_bulleted",title:"Bullet List"},numbered:{cmd:"insertOrderedList",icon:"format_list_numbered",title:"Numbered List"},link:{type:"popup",id:"link",icon:"insert_link",title:"Insert Link"},unlink:{cmd:"unlink",icon:"link_off",title:"Remove Link"},foreColor:{type:"color",cmd:"foreColor",icon:"format_color_text",title:"Text Color"},hiliteColor:{type:"color",cmd:"hiliteColor",icon:"format_color_fill",title:"Background Color"},image:{type:"popup",id:"image",icon:"image",title:"Insert Image"},video:{type:"popup",id:"video",icon:"smart_display",title:"Insert YouTube Video"},table:{type:"popup",id:"table",icon:"table_chart",title:"Insert Table"},embed:{type:"popup",id:"embed",icon:"html",title:"Insert Embed"},symbol:{type:"popup",id:"symbol",icon:"emoji_symbols",title:"Insert Symbol"},specialChar:{type:"popup",id:"specialchar",icon:"format_shapes",title:"Special Characters"},lorem:{type:"popup",id:"lorem",icon:"history_edu",title:"Insert Lorem Ipsum"}};Object.values(_).forEach(Object.freeze);Object.freeze(_);var n=_,m={minimal:[n.source,n.sep,n.bold,n.italic,n.underline,n.sep,n.link,n.unlink],writing:[n.source,n.sep,n.undo,n.redo,n.sep,n.blockformat,n.sep,n.bold,n.italic,n.underline,n.strike,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image],full:[n.source,n.sep,n.undo,n.redo,n.sep,n.copy,n.cut,n.paste,n.sep,n.clearFormat,n.sep,n.blockformat,n.fontfamily,n.fontsize,n.sep,n.bold,n.italic,n.underline,n.strike,n.subscript,n.superscript,n.code,n.sep,n.foreColor,n.hiliteColor,n.sep,n.alignLeft,n.alignCenter,n.alignRight,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image,n.video,n.table,n.embed,n.symbol,n.specialChar,n.lorem,n.sep,n.theme]};Object.values(m).forEach(Object.freeze);Object.freeze(m);var S=m.full,y={image:"onRequestImage",link:"onRequestLink",video:"onRequestVideo",embed:"onRequestEmbed"},v=[{label:"Paragraph",tag:"p"},{label:"Heading 1",tag:"h1"},{label:"Heading 2",tag:"h2"},{label:"Heading 3",tag:"h3"},{label:"Heading 4",tag:"h4"},{label:"Pre / Code",tag:"pre"},{label:"Blockquote",tag:"blockquote"}],x=["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Impact","Lucida Console","Palatino Linotype","Tahoma","Times New Roman","Trebuchet MS","Verdana"],L=[8,9,10,11,12,14,16,18,20,24,28,32,36,48,72],T=["\u2190","\u2192","\u2191","\u2193","\u2194","\u2195","\u21D0","\u21D2","\u21D1","\u21D3","\u21D4","\u2022","\xB7","\u25E6","\u25CB","\u25CF","\u25A1","\u25A0","\u25C6","\u25C7","\u25B2","\u25BC","\u2605","\u2606","\u2660","\u2663","\u2665","\u2666","\u2713","\u2717","\u2715","\u2718","\u2248","\u2260","\u2261","\u2264","\u2265","\xF7","\xD7","\xB1","\u221E","\u221A","\u2211","\u220F","\u222B","\u2202","\u2206","\u2207","\u03C0","\u03A9","\u03BC","\u03B1","\u03B2","\u03B3","\xA9","\xAE","\u2122","\xA7","\xB6","\u2020","\u2021","\xB0","\u2032","\u2033","\u2030","\u201C","\u201D","\u2018","\u2019","\xAB","\xBB","\u2039","\u203A","\u2014","\u2013","\u2026","\xBF","\xA1","\u20AC","\xA3","\xA5","\xA2","\u20B9","\u20BD","\u20BF"],M=["\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF","\u0152","\u0153","\u0160","\u0161","\u0178","\u017D","\u017E"],C=[{id:"default",label:"Default"},{id:"warm",label:"Warm"},{id:"ink",label:"Ink / Navy"},{id:"forest",label:"Forest"}],w=[{label:"Short \u2014 1 sentence",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{label:"Medium \u2014 1 paragraph",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."},{label:"Long \u2014 3 paragraphs",isHTML:!0,text:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>"}],h=class{constructor(e,t={}){if(this._target=typeof e=="string"?document.querySelector(e):e,!this._target)throw new Error("[JotterJS] Target element not found.");this._options=Object.assign({placeholder:"Start typing\u2026",height:"320px",theme:"default",onChange:null,onFocus:null,onBlur:null,onRequestImage:null,onRequestLink:null,onRequestVideo:null,onRequestEmbed:null},t),this._listeners={},this._bookmarks=new Map,this._bmSeq=0,this._savedBookmark=null,this._externalBookmark=null,this._externalDepth=0,this._changeCount=0,this._destroyed=!1,this._lastForeColor="#e8e4d8",this._lastHiliteColor="#c8a96e",this._selectedMedia=null,this._resizeState=null,this._onResizeMove=this._onResizeMove.bind(this),this._onResizeEnd=this._onResizeEnd.bind(this),this._init()}_init(){let e=this._target.innerHTML||"";this._target.innerHTML="",this._target.classList.add("jotter-host"),this._root=document.createElement("div"),this._root.className="htmled",this._toolbar=this._buildToolbar(),this._editorWrap=document.createElement("div"),this._editorWrap.className="jotter-editor-wrap",this._editor=document.createElement("div"),this._editor.className="jotter-editor",this._editor.contentEditable="true",this._editor.setAttribute("data-placeholder",this._options.placeholder),this._editor.style.minHeight=this._options.height,this._editor.innerHTML=this._sanitize(e),this._editor.spellcheck=!0,document.execCommand("defaultParagraphSeparator",!1,"p");try{document.execCommand("enableObjectResizing",!1,!1)}catch{}try{document.execCommand("enableInlineTableEditing",!1,!1)}catch{}this._ensureMediaShields(),this._source=document.createElement("textarea"),this._source.className="jotter-source",this._source.setAttribute("aria-label","HTML source"),this._source.setAttribute("spellcheck","false"),this._source.style.minHeight=this._options.height,this._sourceMode=!1,this._statusBar=this._buildStatusBar(),this._mediaFrame=this._buildMediaFrame(),this._editorWrap.appendChild(this._editor),this._editorWrap.appendChild(this._source),this._editorWrap.appendChild(this._mediaFrame),this._root.appendChild(this._toolbar),this._root.appendChild(this._editorWrap),this._root.appendChild(this._statusBar),this._target.appendChild(this._root),this._popup=this._buildPopupContainer(),document.body.appendChild(this._popup),this._bindEvents(),this._updateToolbarState(),this._updateStatus(),this.setTheme(this._options.theme)}_buildToolbar(){let e=document.createElement("div");return e.className="jotter-toolbar",this._toolbarEl=e,(this._options.toolbar||S).forEach(t=>{let i=this._buildAction(t);i&&e.appendChild(i)}),e}_buildAction(e){if(typeof e.onClick=="function")return this._buildBtn(e);switch(e.type){case"sep":return this._makeSep();case"blockformat":return this._buildBlockFormatSelect();case"fontfamily":return this._buildFontFamilySelect();case"fontsize":return this._buildFontSizeSelect();case"color":return this._buildColorBtn(e);case"popup":return this._buildPopupBtn(e);case"theme":return this._buildThemeSelect();default:return this._buildBtn(e)}}_makeSep(){let e=document.createElement("span");return e.className="jotter-sep",e}_bindActivation(e,t){e.addEventListener("mousedown",i=>{i.preventDefault(),t(!1)}),e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "&&i.key!=="Spacebar"||i.repeat||(i.preventDefault(),t(!0))})}_returnFocus(e,t){t&&this._isInternalTarget(document.activeElement)&&e.focus()}_buildBtn(e){let t=document.createElement("button");if(t.type="button",t.className="jotter-btn",e.cmd&&(t.dataset.cmd=e.cmd),e.custom&&(t.dataset.custom=e.custom),t.title=e.title,t.setAttribute("aria-label",e.title),e.label)t.classList.add("jotter-btn--text"),t.appendChild(document.createTextNode(e.label));else{let i=document.createElement("span");i.className="material-icons",i.textContent=e.icon,t.appendChild(i)}return this._bindActivation(t,i=>{this._editor.focus(),this._applyEdit(()=>{if(e.onClick)e.onClick(this);else if(e.custom==="toggleSource")this._toggleSourceMode();else if(e.custom==="code")this._toggleInlineCode();else if(e.cmd==="copy")document.execCommand("copy");else if(e.cmd==="cut")document.execCommand("cut");else if(e.cmd==="paste")this._pasteFromClipboard();else if(e.prompt){let o=window.prompt(e.prompt);o&&document.execCommand(e.cmd,!1,o)}else document.execCommand(e.cmd,!1,null)}),this._updateToolbarState(),this._returnFocus(t,i)}),t}_bindSelectCaret(e){let t={viaKeyboard:!1};return e.addEventListener("mousedown",()=>{t.viaKeyboard=!1,this._saveBookmark()}),e.addEventListener("keydown",i=>{i.key==="Tab"||i.key==="Escape"||(t.viaKeyboard=!0,this._savedBookmark==null&&this._saveBookmark())}),t}_buildBlockFormatSelect(){let e=document.createElement("select");e.className="jotter-select",e.title="Block format",e.dataset.id="blockformat",v.forEach(({label:i,tag:o})=>{let s=document.createElement("option");s.value=o,s.textContent=i,e.appendChild(s)});let t=this._bindSelectCaret(e);return e.addEventListener("change",()=>{this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("formatBlock",!1,e.value)),this._returnFocus(e,t.viaKeyboard)}),e}_buildFontFamilySelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--font",e.title="Font family",e.dataset.id="fontfamily";let t=document.createElement("option");t.value="",t.textContent="Font",e.appendChild(t),x.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=o,s.style.fontFamily=o,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("fontName",!1,e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildFontSizeSelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--size",e.title="Font size",e.dataset.id="fontsize";let t=document.createElement("option");t.value="",t.textContent="Size",e.appendChild(t),L.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=`${o}px`,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>this._applyFontSize(e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildThemeSelect(){let e=document.createElement("select");return e.className="jotter-select jotter-select--theme",e.title="Editor theme",e.dataset.id="theme",C.forEach(({id:t,label:i})=>{let o=document.createElement("option");o.value=t,o.textContent=i,e.appendChild(o)}),e.value=this._options.theme,e.addEventListener("change",()=>this.setTheme(e.value)),this._themeSelect=e,e}_buildColorBtn(e){let t=document.createElement("span");t.className="jotter-color-wrap";let i=document.createElement("button");i.type="button",i.className="jotter-btn jotter-color-btn",i.dataset.cmd=e.cmd,i.title=e.title,i.setAttribute("aria-label",e.title);let o=document.createElement("span");o.className="material-icons",o.textContent=e.icon,i.appendChild(o);let s=document.createElement("span");s.className="jotter-color-swatch";let r=e.cmd==="foreColor"?this._lastForeColor:this._lastHiliteColor;s.style.background=r,i.appendChild(s);let a=document.createElement("input");a.type="color",a.className="jotter-color-input",a.value=r,a.tabIndex=-1;let u=!1;return a.addEventListener("change",()=>{let p=a.value;s.style.background=p,e.cmd==="foreColor"?this._lastForeColor=p:this._lastHiliteColor=p,this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand(e.cmd,!1,p)),this._returnFocus(i,u)}),this._bindActivation(i,p=>{u=p,this._saveBookmark(),a.click()}),t.appendChild(i),t.appendChild(a),t}_buildPopupBtn(e){let t=document.createElement("button");t.type="button",t.className="jotter-btn",t.title=e.title,t.setAttribute("aria-label",e.title);let i=document.createElement("span");return i.className="material-icons",i.textContent=e.icon,t.appendChild(i),this._bindActivation(t,o=>{let s=this._resolverFor(e.id);if(s){this._hidePopup(),this._runResolver(e.id,s);return}if(this._saveBookmark(),this._popupVisible()&&this._popup.dataset.popupId===e.id){this._hidePopup();return}this._showPopup(t,this._buildPopupContent(e.id),e.id),o&&this._focusPopup()}),t}_focusPopup(){let e=this._popup.querySelector('input, textarea, select, button, [tabindex]:not([tabindex="-1"])');e&&e.focus()}_buildPopupContainer(){let e=document.createElement("div");return e.className="jotter-popup",e.setAttribute("role","dialog"),e}_showPopup(e,t,i){this._popup.innerHTML="",this._popup.appendChild(t),this._popup.dataset.popupId=i,this._popup.classList.add("jotter-popup--visible");let o=e.getBoundingClientRect();this._popup.style.top=o.bottom+6+"px",this._popup.style.left=o.left+"px",this._popup.style.right="auto",requestAnimationFrame(()=>{let s=this._popup.getBoundingClientRect();s.right>window.innerWidth-8&&(this._popup.style.left=Math.max(8,o.left-(s.right-window.innerWidth+8))+"px")})}_popupVisible(){return this._popup.classList.contains("jotter-popup--visible")}_hidePopup(){this._popup.classList.remove("jotter-popup--visible"),this._popup.dataset.popupId="",this._releaseSavedBookmark()}_buildPopupContent(e){switch(e){case"link":return this._popupLink();case"table":return this._popupTable();case"image":return this._popupImage();case"video":return this._popupVideo();case"embed":return this._popupEmbed();case"symbol":return this._popupSymbol();case"specialchar":return this._popupSpecialChar();case"lorem":return this._popupLorem();default:{let t=document.createElement("div");return t.className="jotter-popup-inner",t.textContent="Unknown: "+e,t}}}_popupTable(){let e=document.createElement("div");e.className="jotter-popup-inner";let t=this._popupTitle("Insert Table");e.appendChild(t);let i=10,o=8,s=document.createElement("div");s.className="jotter-table-grid",s.style.gridTemplateColumns=`repeat(${i}, 1fr)`,s.setAttribute("role","grid"),s.setAttribute("aria-label","Table size");let r=document.createElement("div");r.className="jotter-popup-hint",r.textContent="Hover or arrow to select size";let a=[],u=(c,l)=>{r.textContent=`${c+1} \xD7 ${l+1} table`,a.forEach(d=>{d.classList.toggle("jotter-table-cell--active",+d.dataset.r<=c&&+d.dataset.c<=l)})};for(let c=0;c<o;c++)for(let l=0;l<i;l++){let d=document.createElement("span");d.className="jotter-table-cell",d.dataset.r=c,d.dataset.c=l,d.setAttribute("role","gridcell"),d.setAttribute("aria-label",`${c+1} by ${l+1} table`),d.tabIndex=c===0&&l===0?0:-1,d.addEventListener("mouseenter",()=>u(c,l)),d.addEventListener("focus",()=>u(c,l)),d.addEventListener("click",()=>this._insertTable(c+1,l+1)),a.push(d),s.appendChild(d)}let p={ArrowRight:[0,1],ArrowLeft:[0,-1],ArrowDown:[1,0],ArrowUp:[-1,0]};return s.addEventListener("keydown",c=>{let l=a.indexOf(document.activeElement)===-1?null:document.activeElement;if(!l)return;let d=+l.dataset.r,g=+l.dataset.c;if(c.key==="Enter"||c.key===" "||c.key==="Spacebar"){c.preventDefault(),this._insertTable(d+1,g+1);return}let f=p[c.key];if(!f)return;c.preventDefault();let k=Math.min(o-1,Math.max(0,d+f[0])),E=Math.min(i-1,Math.max(0,g+f[1])),b=a[k*i+E];b!==l&&(l.tabIndex=-1,b.tabIndex=0,b.focus())}),e.appendChild(s),e.appendChild(r),e}_commitPopup(e){this._restoreSavedBookmark(),this._hidePopup(),this._applyEdit(e)}_insertTable(e,t){let i="<table><tbody>";for(let o=0;o<e;o++){i+="<tr>";for(let s=0;s<t;s++)i+=o===0?"<th><br></th>":"<td><br></td>";i+="</tr>"}i+="</tbody></table><p><br></p>",this._commitPopup(()=>document.execCommand("insertHTML",!1,i))}_popupLink(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Link"));let t=this._anchorInSelection(),i=this._selectedText(),o=this._makeField(e,"URL","url","https://"),s=this._makeField(e,"Link text (leave blank to keep selection)","text",""),r=this._makeField(e,"Title / tooltip","text",""),a=document.createElement("label");a.className="jotter-popup-label",a.textContent="Open in";let u=document.createElement("select");return u.className="jotter-popup-select",[["(same window)",""],["New tab (_blank)","_blank"],["Parent frame (_parent)","_parent"],["Top frame (_top)","_top"]].forEach(([p,c])=>{let l=document.createElement("option");l.value=c,l.textContent=p,u.appendChild(l)}),e.appendChild(a),e.appendChild(u),t?(o.value=t.getAttribute("href")||"",s.value=t.textContent||"",r.value=t.getAttribute("title")||"",u.value=t.getAttribute("target")||""):i&&(s.value=i),e.appendChild(this._makeSubmitBtn(t?"Update Link":"Insert Link",()=>{let p=o.value.trim();if(!p)return;let c=s.value.trim()||i||p,l=r.value.trim(),d=u.value;this._commitPopup(()=>{t?(t.href=p,d?t.target=d:t.removeAttribute("target"),l?t.title=l:t.removeAttribute("title"),t.textContent=c):document.execCommand("insertHTML",!1,this._linkHTML({href:p,text:c,title:l,target:d}))})})),e}_popupImage(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Image"));let t=this._makeField(e,"Image URL","text","https://example.com/image.jpg"),i=this._makeField(e,"Alt text","text","Descriptive text"),o=this._makeField(e,"Width (e.g. 400px or 50%)","text","");return e.appendChild(this._makeSubmitBtn("Insert Image",()=>{let s=t.value.trim();if(!s)return;let r=this._imageHTML({src:s,alt:i.value.trim(),width:o.value.trim()});this._commitPopup(()=>document.execCommand("insertHTML",!1,r))})),e}_popupVideo(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert YouTube Video"));let t=this._makeField(e,"YouTube URL","text","https://www.youtube.com/watch?v=...");return e.appendChild(this._makeSubmitBtn("Embed Video",()=>{let i=this._ytId(t.value.trim());if(!i){t.classList.add("jotter-input--error");return}t.classList.remove("jotter-input--error"),this._commitPopup(()=>document.execCommand("insertHTML",!1,this._videoHTML(i)))})),e}_ytId(e){for(let t of[/[?&]v=([A-Za-z0-9_-]{11})/,/youtu\.be\/([A-Za-z0-9_-]{11})/,/embed\/([A-Za-z0-9_-]{11})/]){let i=e.match(t);if(i)return i[1]}return null}_popupEmbed(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Embed"));let t=document.createElement("label");t.className="jotter-popup-label",t.textContent="Paste HTML / embed code";let i=document.createElement("textarea");return i.className="jotter-popup-textarea",i.placeholder='<iframe src="..." ...></iframe>',i.rows=4,e.appendChild(t),e.appendChild(i),e.appendChild(this._makeSubmitBtn("Insert",()=>{let o=i.value.trim();o&&this._commitPopup(()=>document.execCommand("insertHTML",!1,this._embedHTML(o)))})),e}_popupSymbol(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Symbol")),e.appendChild(this._charGrid(T)),e}_popupSpecialChar(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Special Characters")),e.appendChild(this._charGrid(M)),e}_charGrid(e){let t=document.createElement("div");return t.className="jotter-char-grid",e.forEach(i=>{let o=document.createElement("button");o.type="button",o.className="jotter-char-btn",o.textContent=i,o.title=`U+${i.codePointAt(0).toString(16).toUpperCase().padStart(4,"0")}`,this._bindActivation(o,()=>{this._commitPopup(()=>document.execCommand("insertText",!1,i))}),t.appendChild(o)}),t}_popupLorem(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Lorem Ipsum")),w.forEach(t=>{let i=document.createElement("button");i.type="button",i.className="jotter-lorem-btn",i.textContent=t.label,this._bindActivation(i,()=>{this._commitPopup(()=>document.execCommand(t.isHTML?"insertHTML":"insertText",!1,t.text))}),e.appendChild(i)}),e}_popupTitle(e){let t=document.createElement("div");return t.className="jotter-popup-title",t.textContent=e,t}_makeField(e,t,i,o){let s=document.createElement("label");s.className="jotter-popup-label",s.textContent=t;let r=document.createElement("input");return r.type=i,r.className="jotter-popup-input",r.placeholder=o,e.appendChild(s),e.appendChild(r),r}_makeSubmitBtn(e,t){let i=document.createElement("button");return i.type="button",i.className="jotter-popup-submit",i.textContent=e,i.addEventListener("click",t),i}_esc(e){return String(e).replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}_imageHTML({src:e,alt:t,width:i}){let o=i?`max-width:${i}`:"max-width:100%";return`<img src="${this._esc(e)}" alt="${this._esc(t||"")}" style="${this._esc(o)}">`}_linkHTML({href:e,text:t,title:i,target:o}){let s=`href="${this._esc(e)}"`;return o&&(s+=` target="${this._esc(o)}"`),i&&(s+=` title="${this._esc(i)}"`),`<a ${s}>${this._esc(t||e)}</a>`}_videoHTML(e){return/^[A-Za-z0-9_-]{11}$/.test(e)?`<div class="jotter-video-wrap"><iframe src="https://www.youtube.com/embed/${e}" frameborder="0" allowfullscreen loading="lazy" title="YouTube video"></iframe></div><p><br></p>`:null}_embedHTML(e){return`<div class="jotter-embed-wrap">${e}</div><p><br></p>`}_resolverFor(e){let t=y[e],i=t?this._options[t]:null;return typeof i=="function"?i:null}async _runResolver(e,t){let i=this._resolverContext(e);this.beginExternalUI();let o=null;try{o=await t(i)}catch{o=null}if(this._destroyed)return;let s=o==null||o===!1?null:this._resolvedHTML(e,o,i);this.endExternalUI(),s&&(this._applyEdit(()=>document.execCommand("insertHTML",!1,s)),this._updateToolbarState())}_resolverContext(e){switch(e){case"image":return{src:"",alt:"",width:"",selection:this._selectedText()};case"video":return{url:"",selection:this._selectedText()};case"embed":return{html:"",selection:this._selectedText()};case"link":return this._linkContext();default:return{selection:this._selectedText()}}}_linkContext(){let e=this._anchorInSelection();if(!e){let i=this._selectedText();return{href:"",text:i,title:"",target:"",selection:i,isEdit:!1}}let t=window.getSelection();if(t){let i=document.createRange();i.selectNode(e),t.removeAllRanges(),t.addRange(i)}return{href:e.getAttribute("href")||"",text:e.textContent||"",title:e.getAttribute("title")||"",target:e.getAttribute("target")||"",selection:e.textContent||"",isEdit:!0}}_resolvedHTML(e,t,i){switch(e){case"image":{let o=typeof t=="string"?{src:t}:t,s=String(o.src||o.url||"").trim();return s?this._imageHTML({...o,src:s}):null}case"link":{let o=typeof t=="string"?{href:t}:t,s=String(o.href||o.url||"").trim();if(!s)return null;let r=String(o.text!=null?o.text:i.text||"").trim();return this._linkHTML({...o,href:s,text:r})}case"video":{let o=typeof t=="string"?{url:t}:t,s=o.id?String(o.id).trim():this._ytId(String(o.url||"").trim());return s?this._videoHTML(s):null}case"embed":{let o=String(typeof t=="string"?t:t.html||"").trim();return o?this._embedHTML(o):null}default:return null}}_selectedText(){let e=window.getSelection();return!e||!e.rangeCount?"":this._editor.contains(e.getRangeAt(0).commonAncestorContainer)?e.toString():""}_anchorInSelection(){let e=window.getSelection();if(!e||!e.rangeCount)return null;let t=e.anchorNode;if(!t||!this._editor.contains(t))return null;for(;t&&t!==this._editor;){if(t.nodeName==="A")return t;t=t.parentNode}return null}_buildStatusBar(){let e=document.createElement("div");e.className="jotter-status",this._wordCountEl=document.createElement("span"),this._wordCountEl.className="jotter-status-words",this._charCountEl=document.createElement("span"),this._charCountEl.className="jotter-status-chars";let t=document.createElement("span");return t.className="jotter-status-mode",t.textContent="HTML",e.appendChild(this._wordCountEl),e.appendChild(this._charCountEl),e.appendChild(t),e}_buildMediaFrame(){let e=document.createElement("div");return e.className="jotter-media-frame",["nw","ne","sw","se","w","e"].forEach(t=>{let i=document.createElement("div");i.className="jotter-resize-handle jotter-resize-handle--"+t,i.dataset.handle=t,i.tabIndex=-1,e.appendChild(i)}),e.addEventListener("mousedown",t=>{let i=t.target.closest(".jotter-resize-handle");!i||!this._selectedMedia||(t.preventDefault(),this._beginResize(i.dataset.handle,t))}),e}_ensureMediaShields(){this._editor.querySelectorAll(".jotter-video-wrap, .jotter-embed-wrap").forEach(e=>{if(e.querySelector(":scope > .jotter-media-shield"))return;let t=document.createElement("div");t.className="jotter-media-shield",e.appendChild(t)})}_mediaElementFromTarget(e){if(!this._editor.contains(e))return null;let t=e.closest("img");if(t&&this._editor.contains(t))return t;let i=e.closest(".jotter-video-wrap, .jotter-embed-wrap");return i&&this._editor.contains(i)?i:null}_selectMedia(e){if(this._selectedMedia===e)return;this._deselectMedia(),this._selectedMedia=e,this._positionMediaFrame(),this._mediaFrame.classList.add("jotter-media-frame--visible"),this._editor.focus({preventScroll:!0});let t=document.createRange();t.setStartBefore(e),t.collapse(!0);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._updateToolbarState()}_deselectMedia(){this._resizeState&&this._abortResize(),this._selectedMedia&&(this._selectedMedia=null,this._mediaFrame.classList.remove("jotter-media-frame--visible"))}_positionMediaFrame(){let e=this._selectedMedia;if(!e)return;let t=this._editorWrap.getBoundingClientRect(),i=e.getBoundingClientRect();this._mediaFrame.style.top=i.top-t.top+this._editorWrap.scrollTop+"px",this._mediaFrame.style.left=i.left-t.left+this._editorWrap.scrollLeft+"px",this._mediaFrame.style.width=i.width+"px",this._mediaFrame.style.height=i.height+"px"}_deleteSelectedMedia(){let e=this._selectedMedia;if(!e)return;this._deselectMedia();let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._applyEdit(()=>document.execCommand("delete",!1,null)),this._updateToolbarState()}_beginResize(e,t){let i=this._selectedMedia,o=i.getBoundingClientRect(),s=e.includes("w")?-1:1;this._resizeState={el:i,sign:s,startX:t.clientX,startWidth:o.width,startInlineWidth:i.style.width,before:this._richHTML()},document.addEventListener("mousemove",this._onResizeMove),document.addEventListener("mouseup",this._onResizeEnd,{once:!0})}_onResizeMove(e){let t=this._resizeState;if(!t)return;let i=(e.clientX-t.startX)*t.sign,o=40,s=Math.max(o,this._editor.clientWidth),r=Math.max(o,Math.min(s,Math.round(t.startWidth+i)));t.el.style.width=r+"px",t.el.style.removeProperty("max-width"),this._positionMediaFrame()}_onResizeEnd(){document.removeEventListener("mousemove",this._onResizeMove);let e=this._resizeState;this._resizeState=null,e&&(this._updateStatus(),this._richHTML()!==e.before&&this._emitChange())}_abortResize(){let e=this._resizeState;e&&(document.removeEventListener("mousemove",this._onResizeMove),document.removeEventListener("mouseup",this._onResizeEnd),e.el.style.width=e.startInlineWidth,this._resizeState=null,this._positionMediaFrame())}_bindEvents(){this._editor.addEventListener("input",()=>{this._editor.querySelectorAll(":scope > div").forEach(e=>{if(e.attributes.length>0)return;let t=document.createElement("p");t.innerHTML=e.innerHTML,e.replaceWith(t)}),Array.from(this._editor.childNodes).forEach(e=>{if(e.nodeType===Node.TEXT_NODE&&e.textContent.trim()!==""){let t=window.getSelection(),i=null;if(t&&t.rangeCount){let s=t.getRangeAt(0);s.startContainer===e&&(i=s.startOffset)}let o=document.createElement("p");if(e.replaceWith(o),o.appendChild(e),i!==null){let s=document.createRange();s.setStart(e,i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}}}),this._ensureMediaShields(),this._selectedMedia&&this._positionMediaFrame(),this._updateStatus(),this._emitChange()}),this._editor.addEventListener("keyup",()=>this._updateToolbarState()),this._editor.addEventListener("mouseup",()=>this._updateToolbarState()),this._editor.addEventListener("mousedown",e=>{let t=this._mediaElementFromTarget(e.target);t&&(e.preventDefault(),this._selectMedia(t))}),this._onWindowResize=()=>{this._selectedMedia&&this._positionMediaFrame()},window.addEventListener("resize",this._onWindowResize),this._editor.addEventListener("focusin",e=>{this._root.classList.add("jotter--focused"),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||(this._emit("focus"),this._options.onFocus&&this._options.onFocus()))}),this._editor.addEventListener("focusout",e=>{this._deselectMedia(),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||setTimeout(()=>{this._destroyed||this._externalDepth>0||this._isInternalTarget(document.activeElement)||this._popupVisible()||(this._root.classList.remove("jotter--focused"),this._emit("blur"),this._options.onBlur&&this._options.onBlur())},0))}),this._editor.addEventListener("keydown",e=>{if((e.key==="Backspace"||e.key==="Delete")&&this._selectedMedia){e.preventDefault(),this._deleteSelectedMedia();return}e.key==="Tab"&&(e.preventDefault(),document.execCommand("insertHTML",!1,"&nbsp;&nbsp;&nbsp;&nbsp;"))}),this._onDocMouseDown=e=>{this._popupVisible()&&!this._popup.contains(e.target)&&!this._toolbarEl.contains(e.target)&&this._hidePopup(),this._selectedMedia&&!this._mediaFrame.contains(e.target)&&e.target!==this._selectedMedia&&!this._selectedMedia.contains(e.target)&&this._deselectMedia()},document.addEventListener("mousedown",this._onDocMouseDown),this._onDocKeyDown=e=>{if(e.key==="Escape"){if(this._resizeState){this._abortResize();return}if(this._selectedMedia){this._deselectMedia();return}this._popupVisible()&&(this._restoreSavedBookmark(),this._hidePopup())}},document.addEventListener("keydown",this._onDocKeyDown)}_isInternalTarget(e){return!!e&&(this._root.contains(e)||this._popup.contains(e))}_toggleSourceMode(){this._deselectMedia(),this._sourceMode=!this._sourceMode,this._sourceMode?(this._dropBookmarks(),this._source.value=this._prettyHTML(this._richHTML()),this._editor.style.display="none",this._source.style.display="block"):(this._editor.innerHTML=this._sanitize(this._source.value),this._ensureMediaShields(),this._source.style.display="none",this._editor.style.display="",this._updateStatus(),this._emitChange()),this._root.classList.toggle("jotter--source-mode",this._sourceMode);let e=this._toolbarEl.querySelector('[data-custom="toggleSource"]');e&&e.classList.toggle("jotter-btn--active",this._sourceMode)}_prettyHTML(e){let t=0,i=" ",o=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),s=new Set(["a","abbr","acronym","b","bdo","big","br","button","cite","code","dfn","em","i","img","input","kbd","label","map","object","output","q","samp","select","small","span","strong","sub","sup","textarea","time","tt","u","var"]);return e.replace(/>\s+</g,"><").replace(/(<[^>]+>)/g,`
1
+ var _={source:{custom:"toggleSource",label:"Source",title:"Edit HTML Source"},sep:{type:"sep"},blockformat:{type:"blockformat"},fontfamily:{type:"fontfamily"},fontsize:{type:"fontsize"},theme:{type:"theme"},undo:{cmd:"undo",icon:"undo",title:"Undo (Ctrl+Z)"},redo:{cmd:"redo",icon:"redo",title:"Redo (Ctrl+Y)"},bold:{cmd:"bold",icon:"format_bold",title:"Bold (Ctrl+B)"},italic:{cmd:"italic",icon:"format_italic",title:"Italic (Ctrl+I)"},underline:{cmd:"underline",icon:"format_underlined",title:"Underline (Ctrl+U)"},strike:{cmd:"strikeThrough",icon:"strikethrough_s",title:"Strikethrough"},subscript:{cmd:"subscript",icon:"subscript",title:"Subscript"},superscript:{cmd:"superscript",icon:"superscript",title:"Superscript"},code:{custom:"code",icon:"code",title:"Inline Code"},copy:{cmd:"copy",icon:"content_copy",title:"Copy"},cut:{cmd:"cut",icon:"content_cut",title:"Cut"},paste:{cmd:"paste",icon:"content_paste",title:"Paste"},clearFormat:{cmd:"removeFormat",icon:"format_clear",title:"Clear Formatting"},alignLeft:{cmd:"justifyLeft",icon:"format_align_left",title:"Align Left"},alignCenter:{cmd:"justifyCenter",icon:"format_align_center",title:"Align Center"},alignRight:{cmd:"justifyRight",icon:"format_align_right",title:"Align Right"},bullets:{cmd:"insertUnorderedList",icon:"format_list_bulleted",title:"Bullet List"},numbered:{cmd:"insertOrderedList",icon:"format_list_numbered",title:"Numbered List"},link:{type:"popup",id:"link",icon:"insert_link",title:"Insert Link"},unlink:{cmd:"unlink",icon:"link_off",title:"Remove Link"},foreColor:{type:"color",cmd:"foreColor",icon:"format_color_text",title:"Text Color"},hiliteColor:{type:"color",cmd:"hiliteColor",icon:"format_color_fill",title:"Background Color"},image:{type:"popup",id:"image",icon:"image",title:"Insert Image"},video:{type:"popup",id:"video",icon:"smart_display",title:"Insert YouTube Video"},table:{type:"popup",id:"table",icon:"table_chart",title:"Insert Table"},embed:{type:"popup",id:"embed",icon:"html",title:"Insert Embed"},symbol:{type:"popup",id:"symbol",icon:"emoji_symbols",title:"Insert Symbol"},specialChar:{type:"popup",id:"specialchar",icon:"format_shapes",title:"Special Characters"},lorem:{type:"popup",id:"lorem",icon:"history_edu",title:"Insert Lorem Ipsum"}};Object.values(_).forEach(Object.freeze);Object.freeze(_);var n=_,m={minimal:[n.source,n.sep,n.bold,n.italic,n.underline,n.sep,n.link,n.unlink],writing:[n.source,n.sep,n.undo,n.redo,n.sep,n.blockformat,n.sep,n.bold,n.italic,n.underline,n.strike,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image],full:[n.source,n.sep,n.undo,n.redo,n.sep,n.copy,n.cut,n.paste,n.sep,n.clearFormat,n.sep,n.blockformat,n.fontfamily,n.fontsize,n.sep,n.bold,n.italic,n.underline,n.strike,n.subscript,n.superscript,n.code,n.sep,n.foreColor,n.hiliteColor,n.sep,n.alignLeft,n.alignCenter,n.alignRight,n.sep,n.bullets,n.numbered,n.sep,n.link,n.unlink,n.sep,n.image,n.video,n.table,n.embed,n.symbol,n.specialChar,n.lorem,n.sep,n.theme]};Object.values(m).forEach(Object.freeze);Object.freeze(m);var y=m.full,S={image:"onRequestImage",link:"onRequestLink",video:"onRequestVideo",embed:"onRequestEmbed"},v=[{label:"Paragraph",tag:"p"},{label:"Heading 1",tag:"h1"},{label:"Heading 2",tag:"h2"},{label:"Heading 3",tag:"h3"},{label:"Heading 4",tag:"h4"},{label:"Pre / Code",tag:"pre"},{label:"Blockquote",tag:"blockquote"}],M=["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Impact","Lucida Console","Palatino Linotype","Tahoma","Times New Roman","Trebuchet MS","Verdana"],x=[8,9,10,11,12,14,16,18,20,24,28,32,36,48,72],L=["\u2190","\u2192","\u2191","\u2193","\u2194","\u2195","\u21D0","\u21D2","\u21D1","\u21D3","\u21D4","\u2022","\xB7","\u25E6","\u25CB","\u25CF","\u25A1","\u25A0","\u25C6","\u25C7","\u25B2","\u25BC","\u2605","\u2606","\u2660","\u2663","\u2665","\u2666","\u2713","\u2717","\u2715","\u2718","\u2248","\u2260","\u2261","\u2264","\u2265","\xF7","\xD7","\xB1","\u221E","\u221A","\u2211","\u220F","\u222B","\u2202","\u2206","\u2207","\u03C0","\u03A9","\u03BC","\u03B1","\u03B2","\u03B3","\xA9","\xAE","\u2122","\xA7","\xB6","\u2020","\u2021","\xB0","\u2032","\u2033","\u2030","\u201C","\u201D","\u2018","\u2019","\xAB","\xBB","\u2039","\u203A","\u2014","\u2013","\u2026","\xBF","\xA1","\u20AC","\xA3","\xA5","\xA2","\u20B9","\u20BD","\u20BF"],T=["\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF","\u0152","\u0153","\u0160","\u0161","\u0178","\u017D","\u017E"],C=[{id:"default",label:"Default"},{id:"warm",label:"Warm"},{id:"ink",label:"Ink / Navy"},{id:"forest",label:"Forest"}],w=[{label:"Short \u2014 1 sentence",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{label:"Medium \u2014 1 paragraph",text:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."},{label:"Long \u2014 3 paragraphs",isHTML:!0,text:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>"}],p=class{constructor(e,t={}){if(this._target=typeof e=="string"?document.querySelector(e):e,!this._target)throw new Error("[JotterJS] Target element not found.");this._options=Object.assign({placeholder:"Start typing\u2026",height:"320px",theme:"default",onChange:null,onFocus:null,onBlur:null,onRequestImage:null,onRequestLink:null,onRequestVideo:null,onRequestEmbed:null},t),this._listeners={},this._bookmarks=new Map,this._bmSeq=0,this._savedBookmark=null,this._externalBookmark=null,this._externalDepth=0,this._changeCount=0,this._destroyed=!1,this._lastForeColor="#e8e4d8",this._lastHiliteColor="#c8a96e",this._selectedMedia=null,this._resizeState=null,this._moveState=null,this._suppressAutoEmit=!1,this._onResizeMove=this._onResizeMove.bind(this),this._onResizeEnd=this._onResizeEnd.bind(this),this._onMoveMove=this._onMoveMove.bind(this),this._onMoveUp=this._onMoveUp.bind(this),this._init()}_init(){let e=this._target.innerHTML||"";this._target.innerHTML="",this._target.classList.add("jotter-host"),this._root=document.createElement("div"),this._root.className="htmled",this._toolbar=this._buildToolbar(),this._editorWrap=document.createElement("div"),this._editorWrap.className="jotter-editor-wrap",this._editor=document.createElement("div"),this._editor.className="jotter-editor",this._editor.contentEditable="true",this._editor.setAttribute("data-placeholder",this._options.placeholder),this._editor.style.minHeight=this._options.height,this._editor.innerHTML=this._sanitize(e),this._editor.spellcheck=!0,document.execCommand("defaultParagraphSeparator",!1,"p");try{document.execCommand("enableObjectResizing",!1,!1)}catch{}try{document.execCommand("enableInlineTableEditing",!1,!1)}catch{}this._ensureMediaShields(),this._source=document.createElement("textarea"),this._source.className="jotter-source",this._source.setAttribute("aria-label","HTML source"),this._source.setAttribute("spellcheck","false"),this._source.style.minHeight=this._options.height,this._sourceMode=!1,this._statusBar=this._buildStatusBar(),this._mediaFrame=this._buildMediaFrame(),this._editorWrap.appendChild(this._editor),this._editorWrap.appendChild(this._source),this._editorWrap.appendChild(this._mediaFrame),this._root.appendChild(this._toolbar),this._root.appendChild(this._editorWrap),this._root.appendChild(this._statusBar),this._target.appendChild(this._root),this._popup=this._buildPopupContainer(),document.body.appendChild(this._popup),this._bindEvents(),this._updateToolbarState(),this._updateStatus(),this.setTheme(this._options.theme)}_buildToolbar(){let e=document.createElement("div");return e.className="jotter-toolbar",this._toolbarEl=e,(this._options.toolbar||y).forEach(t=>{let i=this._buildAction(t);i&&e.appendChild(i)}),e}_buildAction(e){if(typeof e.onClick=="function")return this._buildBtn(e);switch(e.type){case"sep":return this._makeSep();case"blockformat":return this._buildBlockFormatSelect();case"fontfamily":return this._buildFontFamilySelect();case"fontsize":return this._buildFontSizeSelect();case"color":return this._buildColorBtn(e);case"popup":return this._buildPopupBtn(e);case"theme":return this._buildThemeSelect();default:return this._buildBtn(e)}}_makeSep(){let e=document.createElement("span");return e.className="jotter-sep",e}_bindActivation(e,t){e.addEventListener("mousedown",i=>{i.preventDefault(),t(!1)}),e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "&&i.key!=="Spacebar"||i.repeat||(i.preventDefault(),t(!0))})}_returnFocus(e,t){t&&this._isInternalTarget(document.activeElement)&&e.focus()}_buildBtn(e){let t=document.createElement("button");if(t.type="button",t.className="jotter-btn",e.cmd&&(t.dataset.cmd=e.cmd),e.custom&&(t.dataset.custom=e.custom),t.title=e.title,t.setAttribute("aria-label",e.title),e.label)t.classList.add("jotter-btn--text"),t.appendChild(document.createTextNode(e.label));else{let i=document.createElement("span");i.className="material-icons",i.textContent=e.icon,t.appendChild(i)}return this._bindActivation(t,i=>{this._editor.focus(),this._applyEdit(()=>{if(e.onClick)e.onClick(this);else if(e.custom==="toggleSource")this._toggleSourceMode();else if(e.custom==="code")this._toggleInlineCode();else if(e.cmd==="copy")document.execCommand("copy");else if(e.cmd==="cut")document.execCommand("cut");else if(e.cmd==="paste")this._pasteFromClipboard();else if(e.prompt){let o=window.prompt(e.prompt);o&&document.execCommand(e.cmd,!1,o)}else document.execCommand(e.cmd,!1,null)}),this._updateToolbarState(),this._returnFocus(t,i)}),t}_bindSelectCaret(e){let t={viaKeyboard:!1};return e.addEventListener("mousedown",()=>{t.viaKeyboard=!1,this._saveBookmark()}),e.addEventListener("keydown",i=>{i.key==="Tab"||i.key==="Escape"||(t.viaKeyboard=!0,this._savedBookmark==null&&this._saveBookmark())}),t}_buildBlockFormatSelect(){let e=document.createElement("select");e.className="jotter-select",e.title="Block format",e.dataset.id="blockformat",v.forEach(({label:i,tag:o})=>{let s=document.createElement("option");s.value=o,s.textContent=i,e.appendChild(s)});let t=this._bindSelectCaret(e);return e.addEventListener("change",()=>{this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("formatBlock",!1,e.value)),this._returnFocus(e,t.viaKeyboard)}),e}_buildFontFamilySelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--font",e.title="Font family",e.dataset.id="fontfamily";let t=document.createElement("option");t.value="",t.textContent="Font",e.appendChild(t),M.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=o,s.style.fontFamily=o,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand("fontName",!1,e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildFontSizeSelect(){let e=document.createElement("select");e.className="jotter-select jotter-select--size",e.title="Font size",e.dataset.id="fontsize";let t=document.createElement("option");t.value="",t.textContent="Size",e.appendChild(t),x.forEach(o=>{let s=document.createElement("option");s.value=o,s.textContent=`${o}px`,e.appendChild(s)});let i=this._bindSelectCaret(e);return e.addEventListener("change",()=>{e.value&&(this._restoreSavedBookmark(),this._applyEdit(()=>this._applyFontSize(e.value)),this._returnFocus(e,i.viaKeyboard))}),e}_buildThemeSelect(){let e=document.createElement("select");return e.className="jotter-select jotter-select--theme",e.title="Editor theme",e.dataset.id="theme",C.forEach(({id:t,label:i})=>{let o=document.createElement("option");o.value=t,o.textContent=i,e.appendChild(o)}),e.value=this._options.theme,e.addEventListener("change",()=>this.setTheme(e.value)),this._themeSelect=e,e}_buildColorBtn(e){let t=document.createElement("span");t.className="jotter-color-wrap";let i=document.createElement("button");i.type="button",i.className="jotter-btn jotter-color-btn",i.dataset.cmd=e.cmd,i.title=e.title,i.setAttribute("aria-label",e.title);let o=document.createElement("span");o.className="material-icons",o.textContent=e.icon,i.appendChild(o);let s=document.createElement("span");s.className="jotter-color-swatch";let r=e.cmd==="foreColor"?this._lastForeColor:this._lastHiliteColor;s.style.background=r,i.appendChild(s);let a=document.createElement("input");a.type="color",a.className="jotter-color-input",a.value=r,a.tabIndex=-1;let u=!1;return a.addEventListener("change",()=>{let h=a.value;s.style.background=h,e.cmd==="foreColor"?this._lastForeColor=h:this._lastHiliteColor=h,this._restoreSavedBookmark(),this._applyEdit(()=>document.execCommand(e.cmd,!1,h)),this._returnFocus(i,u)}),this._bindActivation(i,h=>{u=h,this._saveBookmark(),a.click()}),t.appendChild(i),t.appendChild(a),t}_buildPopupBtn(e){let t=document.createElement("button");t.type="button",t.className="jotter-btn",t.title=e.title,t.setAttribute("aria-label",e.title);let i=document.createElement("span");return i.className="material-icons",i.textContent=e.icon,t.appendChild(i),this._bindActivation(t,o=>{let s=this._resolverFor(e.id);if(s){this._hidePopup(),this._runResolver(e.id,s);return}if(this._saveBookmark(),this._popupVisible()&&this._popup.dataset.popupId===e.id){this._hidePopup();return}this._showPopup(t,this._buildPopupContent(e.id),e.id),o&&this._focusPopup()}),t}_focusPopup(){let e=this._popup.querySelector('input, textarea, select, button, [tabindex]:not([tabindex="-1"])');e&&e.focus()}_buildPopupContainer(){let e=document.createElement("div");return e.className="jotter-popup",e.setAttribute("role","dialog"),e}_showPopup(e,t,i){this._popup.innerHTML="",this._popup.appendChild(t),this._popup.dataset.popupId=i,this._popup.classList.add("jotter-popup--visible");let o=e.getBoundingClientRect();this._popup.style.top=o.bottom+6+"px",this._popup.style.left=o.left+"px",this._popup.style.right="auto",requestAnimationFrame(()=>{let s=this._popup.getBoundingClientRect();s.right>window.innerWidth-8&&(this._popup.style.left=Math.max(8,o.left-(s.right-window.innerWidth+8))+"px")})}_popupVisible(){return this._popup.classList.contains("jotter-popup--visible")}_hidePopup(){this._popup.classList.remove("jotter-popup--visible"),this._popup.dataset.popupId="",this._releaseSavedBookmark()}_buildPopupContent(e){switch(e){case"link":return this._popupLink();case"table":return this._popupTable();case"image":return this._popupImage();case"video":return this._popupVideo();case"embed":return this._popupEmbed();case"symbol":return this._popupSymbol();case"specialchar":return this._popupSpecialChar();case"lorem":return this._popupLorem();default:{let t=document.createElement("div");return t.className="jotter-popup-inner",t.textContent="Unknown: "+e,t}}}_popupTable(){let e=document.createElement("div");e.className="jotter-popup-inner";let t=this._popupTitle("Insert Table");e.appendChild(t);let i=10,o=8,s=document.createElement("div");s.className="jotter-table-grid",s.style.gridTemplateColumns=`repeat(${i}, 1fr)`,s.setAttribute("role","grid"),s.setAttribute("aria-label","Table size");let r=document.createElement("div");r.className="jotter-popup-hint",r.textContent="Hover or arrow to select size";let a=[],u=(d,l)=>{r.textContent=`${d+1} \xD7 ${l+1} table`,a.forEach(c=>{c.classList.toggle("jotter-table-cell--active",+c.dataset.r<=d&&+c.dataset.c<=l)})};for(let d=0;d<o;d++)for(let l=0;l<i;l++){let c=document.createElement("span");c.className="jotter-table-cell",c.dataset.r=d,c.dataset.c=l,c.setAttribute("role","gridcell"),c.setAttribute("aria-label",`${d+1} by ${l+1} table`),c.tabIndex=d===0&&l===0?0:-1,c.addEventListener("mouseenter",()=>u(d,l)),c.addEventListener("focus",()=>u(d,l)),c.addEventListener("click",()=>this._insertTable(d+1,l+1)),a.push(c),s.appendChild(c)}let h={ArrowRight:[0,1],ArrowLeft:[0,-1],ArrowDown:[1,0],ArrowUp:[-1,0]};return s.addEventListener("keydown",d=>{let l=a.indexOf(document.activeElement)===-1?null:document.activeElement;if(!l)return;let c=+l.dataset.r,g=+l.dataset.c;if(d.key==="Enter"||d.key===" "||d.key==="Spacebar"){d.preventDefault(),this._insertTable(c+1,g+1);return}let f=h[d.key];if(!f)return;d.preventDefault();let E=Math.min(o-1,Math.max(0,c+f[0])),k=Math.min(i-1,Math.max(0,g+f[1])),b=a[E*i+k];b!==l&&(l.tabIndex=-1,b.tabIndex=0,b.focus())}),e.appendChild(s),e.appendChild(r),e}_commitPopup(e){this._restoreSavedBookmark(),this._hidePopup(),this._applyEdit(e)}_insertTable(e,t){let i="<table><tbody>";for(let o=0;o<e;o++){i+="<tr>";for(let s=0;s<t;s++)i+=o===0?"<th><br></th>":"<td><br></td>";i+="</tr>"}i+="</tbody></table><p><br></p>",this._commitPopup(()=>document.execCommand("insertHTML",!1,i))}_popupLink(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Link"));let t=this._anchorInSelection(),i=this._selectedText(),o=this._makeField(e,"URL","url","https://"),s=this._makeField(e,"Link text (leave blank to keep selection)","text",""),r=this._makeField(e,"Title / tooltip","text",""),a=document.createElement("label");a.className="jotter-popup-label",a.textContent="Open in";let u=document.createElement("select");return u.className="jotter-popup-select",[["(same window)",""],["New tab (_blank)","_blank"],["Parent frame (_parent)","_parent"],["Top frame (_top)","_top"]].forEach(([h,d])=>{let l=document.createElement("option");l.value=d,l.textContent=h,u.appendChild(l)}),e.appendChild(a),e.appendChild(u),t?(o.value=t.getAttribute("href")||"",s.value=t.textContent||"",r.value=t.getAttribute("title")||"",u.value=t.getAttribute("target")||""):i&&(s.value=i),e.appendChild(this._makeSubmitBtn(t?"Update Link":"Insert Link",()=>{let h=o.value.trim();if(!h)return;let d=s.value.trim()||i||h,l=r.value.trim(),c=u.value;this._commitPopup(()=>{t?(t.href=h,c?t.target=c:t.removeAttribute("target"),l?t.title=l:t.removeAttribute("title"),t.textContent=d):document.execCommand("insertHTML",!1,this._linkHTML({href:h,text:d,title:l,target:c}))})})),e}_popupImage(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Image"));let t=this._makeField(e,"Image URL","text","https://example.com/image.jpg"),i=this._makeField(e,"Alt text","text","Descriptive text"),o=this._makeField(e,"Width (e.g. 400px or 50%)","text","");return e.appendChild(this._makeSubmitBtn("Insert Image",()=>{let s=t.value.trim();if(!s)return;let r=this._imageHTML({src:s,alt:i.value.trim(),width:o.value.trim()});this._commitPopup(()=>document.execCommand("insertHTML",!1,r))})),e}_popupVideo(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert YouTube Video"));let t=this._makeField(e,"YouTube URL","text","https://www.youtube.com/watch?v=...");return e.appendChild(this._makeSubmitBtn("Embed Video",()=>{let i=this._ytId(t.value.trim());if(!i){t.classList.add("jotter-input--error");return}t.classList.remove("jotter-input--error"),this._commitPopup(()=>document.execCommand("insertHTML",!1,this._videoHTML(i)))})),e}_ytId(e){for(let t of[/[?&]v=([A-Za-z0-9_-]{11})/,/youtu\.be\/([A-Za-z0-9_-]{11})/,/embed\/([A-Za-z0-9_-]{11})/]){let i=e.match(t);if(i)return i[1]}return null}_popupEmbed(){let e=document.createElement("div");e.className="jotter-popup-inner jotter-popup-form",e.appendChild(this._popupTitle("Insert Embed"));let t=document.createElement("label");t.className="jotter-popup-label",t.textContent="Paste HTML / embed code";let i=document.createElement("textarea");return i.className="jotter-popup-textarea",i.placeholder='<iframe src="..." ...></iframe>',i.rows=4,e.appendChild(t),e.appendChild(i),e.appendChild(this._makeSubmitBtn("Insert",()=>{let o=i.value.trim();o&&this._commitPopup(()=>document.execCommand("insertHTML",!1,this._embedHTML(o)))})),e}_popupSymbol(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Symbol")),e.appendChild(this._charGrid(L)),e}_popupSpecialChar(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Special Characters")),e.appendChild(this._charGrid(T)),e}_charGrid(e){let t=document.createElement("div");return t.className="jotter-char-grid",e.forEach(i=>{let o=document.createElement("button");o.type="button",o.className="jotter-char-btn",o.textContent=i,o.title=`U+${i.codePointAt(0).toString(16).toUpperCase().padStart(4,"0")}`,this._bindActivation(o,()=>{this._commitPopup(()=>document.execCommand("insertText",!1,i))}),t.appendChild(o)}),t}_popupLorem(){let e=document.createElement("div");return e.className="jotter-popup-inner",e.appendChild(this._popupTitle("Insert Lorem Ipsum")),w.forEach(t=>{let i=document.createElement("button");i.type="button",i.className="jotter-lorem-btn",i.textContent=t.label,this._bindActivation(i,()=>{this._commitPopup(()=>document.execCommand(t.isHTML?"insertHTML":"insertText",!1,t.text))}),e.appendChild(i)}),e}_popupTitle(e){let t=document.createElement("div");return t.className="jotter-popup-title",t.textContent=e,t}_makeField(e,t,i,o){let s=document.createElement("label");s.className="jotter-popup-label",s.textContent=t;let r=document.createElement("input");return r.type=i,r.className="jotter-popup-input",r.placeholder=o,e.appendChild(s),e.appendChild(r),r}_makeSubmitBtn(e,t){let i=document.createElement("button");return i.type="button",i.className="jotter-popup-submit",i.textContent=e,i.addEventListener("click",t),i}_esc(e){return String(e).replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}_imageHTML({src:e,alt:t,width:i}){let o=i?`max-width:${i}`:"max-width:100%";return`<img src="${this._esc(e)}" alt="${this._esc(t||"")}" style="${this._esc(o)}">`}_linkHTML({href:e,text:t,title:i,target:o}){let s=`href="${this._esc(e)}"`;return o&&(s+=` target="${this._esc(o)}"`),i&&(s+=` title="${this._esc(i)}"`),`<a ${s}>${this._esc(t||e)}</a>`}_videoHTML(e){return/^[A-Za-z0-9_-]{11}$/.test(e)?`<div class="jotter-video-wrap"><iframe src="https://www.youtube.com/embed/${e}" frameborder="0" allowfullscreen loading="lazy" title="YouTube video"></iframe></div><p><br></p>`:null}_embedHTML(e){return`<div class="jotter-embed-wrap">${e}</div><p><br></p>`}_resolverFor(e){let t=S[e],i=t?this._options[t]:null;return typeof i=="function"?i:null}async _runResolver(e,t){let i=this._resolverContext(e);this.beginExternalUI();let o=null;try{o=await t(i)}catch{o=null}if(this._destroyed)return;let s=o==null||o===!1?null:this._resolvedHTML(e,o,i);this.endExternalUI(),s&&(this._applyEdit(()=>document.execCommand("insertHTML",!1,s)),this._updateToolbarState())}_resolverContext(e){switch(e){case"image":return{src:"",alt:"",width:"",selection:this._selectedText()};case"video":return{url:"",selection:this._selectedText()};case"embed":return{html:"",selection:this._selectedText()};case"link":return this._linkContext();default:return{selection:this._selectedText()}}}_linkContext(){let e=this._anchorInSelection();if(!e){let i=this._selectedText();return{href:"",text:i,title:"",target:"",selection:i,isEdit:!1}}let t=window.getSelection();if(t){let i=document.createRange();i.selectNode(e),t.removeAllRanges(),t.addRange(i)}return{href:e.getAttribute("href")||"",text:e.textContent||"",title:e.getAttribute("title")||"",target:e.getAttribute("target")||"",selection:e.textContent||"",isEdit:!0}}_resolvedHTML(e,t,i){switch(e){case"image":{let o=typeof t=="string"?{src:t}:t,s=String(o.src||o.url||"").trim();return s?this._imageHTML({...o,src:s}):null}case"link":{let o=typeof t=="string"?{href:t}:t,s=String(o.href||o.url||"").trim();if(!s)return null;let r=String(o.text!=null?o.text:i.text||"").trim();return this._linkHTML({...o,href:s,text:r})}case"video":{let o=typeof t=="string"?{url:t}:t,s=o.id?String(o.id).trim():this._ytId(String(o.url||"").trim());return s?this._videoHTML(s):null}case"embed":{let o=String(typeof t=="string"?t:t.html||"").trim();return o?this._embedHTML(o):null}default:return null}}_selectedText(){let e=window.getSelection();return!e||!e.rangeCount?"":this._editor.contains(e.getRangeAt(0).commonAncestorContainer)?e.toString():""}_anchorInSelection(){let e=window.getSelection();if(!e||!e.rangeCount)return null;let t=e.anchorNode;if(!t||!this._editor.contains(t))return null;for(;t&&t!==this._editor;){if(t.nodeName==="A")return t;t=t.parentNode}return null}_buildStatusBar(){let e=document.createElement("div");e.className="jotter-status",this._wordCountEl=document.createElement("span"),this._wordCountEl.className="jotter-status-words",this._charCountEl=document.createElement("span"),this._charCountEl.className="jotter-status-chars";let t=document.createElement("span");return t.className="jotter-status-mode",t.textContent="HTML",e.appendChild(this._wordCountEl),e.appendChild(this._charCountEl),e.appendChild(t),e}_buildMediaFrame(){let e=document.createElement("div");return e.className="jotter-media-frame",["nw","ne","sw","se","w","e"].forEach(t=>{let i=document.createElement("div");i.className="jotter-resize-handle jotter-resize-handle--"+t,i.dataset.handle=t,i.tabIndex=-1,e.appendChild(i)}),e.addEventListener("mousedown",t=>{if(!this._selectedMedia)return;t.preventDefault();let i=t.target.closest(".jotter-resize-handle");i?this._beginResize(i.dataset.handle,t):this._beginPotentialMove(this._selectedMedia,t)}),e}_ensureMediaShields(){this._editor.querySelectorAll(".jotter-video-wrap, .jotter-embed-wrap").forEach(e=>{if(e.querySelector(":scope > .jotter-media-shield"))return;let t=document.createElement("div");t.className="jotter-media-shield",e.appendChild(t)})}_mediaElementFromTarget(e){if(!this._editor.contains(e))return null;let t=e.closest("img");if(t&&this._editor.contains(t))return t;let i=e.closest(".jotter-video-wrap, .jotter-embed-wrap");return i&&this._editor.contains(i)?i:null}_selectMedia(e){if(this._selectedMedia===e)return;this._deselectMedia(),this._selectedMedia=e,this._positionMediaFrame(),this._mediaFrame.classList.add("jotter-media-frame--visible"),this._editor.focus({preventScroll:!0});let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._updateToolbarState()}_deselectMedia(){this._resizeState&&this._abortResize(),this._moveState&&this._abortMove(),this._selectedMedia&&(this._selectedMedia=null,this._mediaFrame.classList.remove("jotter-media-frame--visible"))}_positionMediaFrame(){let e=this._selectedMedia;if(!e)return;let t=this._editorWrap.getBoundingClientRect(),i=e.getBoundingClientRect();this._mediaFrame.style.top=i.top-t.top+this._editorWrap.scrollTop+"px",this._mediaFrame.style.left=i.left-t.left+this._editorWrap.scrollLeft+"px",this._mediaFrame.style.width=i.width+"px",this._mediaFrame.style.height=i.height+"px"}_deleteSelectedMedia(){let e=this._selectedMedia;if(!e)return;this._deselectMedia();let t=document.createRange();t.selectNode(e);let i=window.getSelection();i.removeAllRanges(),i.addRange(t),this._applyEdit(()=>document.execCommand("delete",!1,null)),this._updateToolbarState()}_beginResize(e,t){let i=this._selectedMedia,o=i.getBoundingClientRect(),s=e.includes("w")?-1:1;this._resizeState={el:i,sign:s,startX:t.clientX,startWidth:o.width,startInlineWidth:i.style.width,before:this._richHTML()},document.addEventListener("mousemove",this._onResizeMove),document.addEventListener("mouseup",this._onResizeEnd,{once:!0})}_onResizeMove(e){let t=this._resizeState;if(!t)return;let i=(e.clientX-t.startX)*t.sign,o=40,s=Math.max(o,this._editor.clientWidth),r=Math.max(o,Math.min(s,Math.round(t.startWidth+i)));t.el.style.width=r+"px",t.el.style.removeProperty("max-width"),this._positionMediaFrame()}_onResizeEnd(){document.removeEventListener("mousemove",this._onResizeMove);let e=this._resizeState;this._resizeState=null,e&&(this._updateStatus(),this._richHTML()!==e.before&&this._emitChange())}_abortResize(){let e=this._resizeState;e&&(document.removeEventListener("mousemove",this._onResizeMove),document.removeEventListener("mouseup",this._onResizeEnd),e.el.style.width=e.startInlineWidth,this._resizeState=null,this._positionMediaFrame())}_beginPotentialMove(e,t){this._moveState={el:e,startX:t.clientX,startY:t.clientY,dragging:!1},document.addEventListener("mousemove",this._onMoveMove),document.addEventListener("mouseup",this._onMoveUp,{once:!0})}_onMoveMove(e){let t=this._moveState;if(t){if(!t.dragging){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.dragging=!0,t.before=this._richHTML(),this._mediaFrame.classList.add("jotter-media-frame--dragging"),document.body.style.cursor="grabbing"}t.dropRange=this._rangeFromPoint(e.clientX,e.clientY),this._showDropIndicator(t.dropRange)}}_onMoveUp(){document.removeEventListener("mousemove",this._onMoveMove);let e=this._moveState;this._moveState=null,this._mediaFrame.classList.remove("jotter-media-frame--dragging"),document.body.style.cursor="",this._hideDropIndicator(),e&&e.dragging&&this._commitMove(e.el,e.dropRange,e.before)}_abortMove(){this._moveState&&(document.removeEventListener("mousemove",this._onMoveMove),document.removeEventListener("mouseup",this._onMoveUp),this._moveState=null,this._mediaFrame.classList.remove("jotter-media-frame--dragging"),document.body.style.cursor="",this._hideDropIndicator())}_rangeFromPoint(e,t){let i=null;if(document.caretRangeFromPoint)i=document.caretRangeFromPoint(e,t);else if(document.caretPositionFromPoint){let s=document.caretPositionFromPoint(e,t);s&&(i=document.createRange(),i.setStart(s.offsetNode,s.offset),i.collapse(!0))}if(!i||!this._editor.contains(i.startContainer))return null;let o=this._moveState;return o&&o.el.contains(i.startContainer)?null:i}_buildDropIndicator(){let e=document.createElement("div");return e.className="jotter-drop-indicator",e}_showDropIndicator(e){this._dropIndicator||(this._dropIndicator=this._buildDropIndicator(),this._editorWrap.appendChild(this._dropIndicator));let t=e&&e.getClientRects()[0];if(!t){this._dropIndicator.style.display="none";return}let i=this._editorWrap.getBoundingClientRect();this._dropIndicator.style.display="block",this._dropIndicator.style.top=t.top-i.top+this._editorWrap.scrollTop+"px",this._dropIndicator.style.left=t.left-i.left+this._editorWrap.scrollLeft+"px",this._dropIndicator.style.height=(t.height||20)+"px"}_hideDropIndicator(){this._dropIndicator&&(this._dropIndicator.style.display="none")}_commitMove(e,t,i){if(!t||!t.startContainer.isConnected)return;let o="jmv"+ ++this._bmSeq,s=e.cloneNode(!0);s.querySelectorAll(".jotter-media-shield").forEach(h=>h.remove()),s.setAttribute("data-jotter-move",o),this._suppressAutoEmit=!0;let r=window.getSelection(),a=document.createRange();a.selectNode(e),r.removeAllRanges(),r.addRange(a),document.execCommand("delete",!1,null),r.removeAllRanges(),r.addRange(t),document.execCommand("insertHTML",!1,s.outerHTML);let u=this._editor.querySelector(`[data-jotter-move="${o}"]`);u&&u.removeAttribute("data-jotter-move"),this._suppressAutoEmit=!1,this._updateStatus(),u?this._selectMedia(u):this._deselectMedia(),this._richHTML()!==i&&this._emitChange()}_writeMediaToClipboard(e,t){let i=t.cloneNode(!0);i.querySelectorAll(".jotter-media-shield").forEach(o=>o.remove()),e.clipboardData.setData("text/html",i.outerHTML),e.clipboardData.setData("text/plain",t.tagName==="IMG"?t.alt||"":t.textContent||"")}_bindEvents(){this._editor.addEventListener("input",()=>{this._editor.querySelectorAll(":scope > div").forEach(e=>{if(e.attributes.length>0)return;let t=document.createElement("p");t.innerHTML=e.innerHTML,e.replaceWith(t)}),Array.from(this._editor.childNodes).forEach(e=>{if(e.nodeType===Node.TEXT_NODE&&e.textContent.trim()!==""){let t=window.getSelection(),i=null;if(t&&t.rangeCount){let s=t.getRangeAt(0);s.startContainer===e&&(i=s.startOffset)}let o=document.createElement("p");if(e.replaceWith(o),o.appendChild(e),i!==null){let s=document.createRange();s.setStart(e,i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}}}),this._ensureMediaShields(),this._selectedMedia&&this._positionMediaFrame(),this._updateStatus(),this._suppressAutoEmit||this._emitChange()}),this._editor.addEventListener("keyup",()=>this._updateToolbarState()),this._editor.addEventListener("mouseup",()=>this._updateToolbarState()),this._editor.addEventListener("mousedown",e=>{let t=this._mediaElementFromTarget(e.target);t&&(e.preventDefault(),this._selectMedia(t),this._beginPotentialMove(t,e))}),this._editor.addEventListener("copy",e=>{this._selectedMedia&&(e.preventDefault(),this._writeMediaToClipboard(e,this._selectedMedia))}),this._editor.addEventListener("cut",e=>{this._selectedMedia&&(e.preventDefault(),this._writeMediaToClipboard(e,this._selectedMedia),this._deleteSelectedMedia())}),this._editor.addEventListener("paste",e=>{e.preventDefault();let t=(e.clipboardData||window.clipboardData).getData("text/html");if(t)this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(t)));else{let i=(e.clipboardData||window.clipboardData).getData("text/plain");i&&this._applyEdit(()=>document.execCommand("insertText",!1,i))}}),this._onWindowResize=()=>{this._selectedMedia&&this._positionMediaFrame()},window.addEventListener("resize",this._onWindowResize),this._editor.addEventListener("focusin",e=>{this._root.classList.add("jotter--focused"),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||(this._emit("focus"),this._options.onFocus&&this._options.onFocus()))}),this._editor.addEventListener("focusout",e=>{this._deselectMedia(),!(this._externalDepth>0)&&(this._isInternalTarget(e.relatedTarget)||setTimeout(()=>{this._destroyed||this._externalDepth>0||this._isInternalTarget(document.activeElement)||this._popupVisible()||(this._root.classList.remove("jotter--focused"),this._emit("blur"),this._options.onBlur&&this._options.onBlur())},0))}),this._editor.addEventListener("keydown",e=>{if((e.key==="Backspace"||e.key==="Delete")&&this._selectedMedia){e.preventDefault(),this._deleteSelectedMedia();return}e.key==="Tab"&&(e.preventDefault(),document.execCommand("insertHTML",!1,"&nbsp;&nbsp;&nbsp;&nbsp;"))}),this._onDocMouseDown=e=>{this._popupVisible()&&!this._popup.contains(e.target)&&!this._toolbarEl.contains(e.target)&&this._hidePopup(),this._selectedMedia&&!this._mediaFrame.contains(e.target)&&e.target!==this._selectedMedia&&!this._selectedMedia.contains(e.target)&&this._deselectMedia()},document.addEventListener("mousedown",this._onDocMouseDown),this._onDocKeyDown=e=>{if(e.key==="Escape"){if(this._resizeState){this._abortResize();return}if(this._moveState&&this._moveState.dragging){this._abortMove();return}if(this._selectedMedia){this._deselectMedia();return}this._popupVisible()&&(this._restoreSavedBookmark(),this._hidePopup())}},document.addEventListener("keydown",this._onDocKeyDown)}_isInternalTarget(e){return!!e&&(this._root.contains(e)||this._popup.contains(e))}_toggleSourceMode(){this._deselectMedia(),this._sourceMode=!this._sourceMode,this._sourceMode?(this._dropBookmarks(),this._source.value=this._prettyHTML(this._richHTML()),this._editor.style.display="none",this._source.style.display="block"):(this._editor.innerHTML=this._sanitize(this._source.value),this._ensureMediaShields(),this._source.style.display="none",this._editor.style.display="",this._updateStatus(),this._emitChange()),this._root.classList.toggle("jotter--source-mode",this._sourceMode);let e=this._toolbarEl.querySelector('[data-custom="toggleSource"]');e&&e.classList.toggle("jotter-btn--active",this._sourceMode)}_prettyHTML(e){let t=0,i=" ",o=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),s=new Set(["a","abbr","acronym","b","bdo","big","br","button","cite","code","dfn","em","i","img","input","kbd","label","map","object","output","q","samp","select","small","span","strong","sub","sup","textarea","time","tt","u","var"]);return e.replace(/>\s+</g,"><").replace(/(<[^>]+>)/g,`
2
2
  $1
3
3
  `).split(`
4
- `).map(r=>r.trim()).filter(r=>r.length>0).map(r=>{let a=r.match(/^<\/(\w+)/),u=r.match(/^<(\w+)/),p=r.endsWith("/>"),c=u?u[1].toLowerCase():null,l=a?a[1].toLowerCase():null;l&&!s.has(l)&&(t=Math.max(0,t-1));let d=i.repeat(t)+r;return c&&!p&&!o.has(c)&&!l&&!s.has(c)&&t++,d}).join(`
5
- `)}_sanitize(e){let t=new DOMParser().parseFromString(e,"text/html");return t.querySelectorAll("script").forEach(i=>i.remove()),t.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(i=>i.remove()),t.querySelectorAll("*").forEach(i=>{Array.from(i.attributes).forEach(o=>{(o.name.startsWith("on")||["href","src","action","formaction","data"].includes(o.name)&&/^\s*javascript:/i.test(o.value))&&i.removeAttribute(o.name)})}),t.body.innerHTML}_toggleInlineCode(){let e=window.getSelection();if(!e||e.rangeCount===0)return;let t=e.getRangeAt(0),i=t.commonAncestorContainer;i.nodeType===3&&(i=i.parentNode);let o=i.closest?i.closest("code"):null;if(o){let s=o.parentNode;for(;o.firstChild;)s.insertBefore(o.firstChild,o);s.removeChild(o)}else if(t.collapsed){let s=document.createElement("code");s.innerHTML="&#8203;",t.insertNode(s);let r=document.createRange();r.setStart(s,0),r.setEnd(s,s.childNodes.length),e.removeAllRanges(),e.addRange(r)}else{let s=document.createElement("code");try{t.surroundContents(s)}catch{let a=t.extractContents();s.appendChild(a),t.insertNode(s)}}}_applyFontSize(e){let t=window.getSelection();if(!t||t.rangeCount===0)return;let i=t.getRangeAt(0);if(i.collapsed)return;let o=document.createElement("span");o.style.fontSize=e+"px";try{i.surroundContents(o)}catch{let r=i.extractContents();o.appendChild(r),i.insertNode(o)}}async _pasteFromClipboard(){try{if(navigator.clipboard&&navigator.clipboard.readText){let e=await navigator.clipboard.readText();document.execCommand("insertText",!1,e)}else document.execCommand("paste")}catch{}}_updateToolbarState(){this._toolbarEl.querySelectorAll(".jotter-btn[data-cmd]").forEach(t=>{try{t.classList.toggle("jotter-btn--active",document.queryCommandState(t.dataset.cmd))}catch{}});let e=this._toolbarEl.querySelector('[data-id="blockformat"]');if(e){let t=document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g,""),i=v.find(o=>o.tag===t);i&&(e.value=i.tag)}}_updateStatus(){let e=this._editor.innerText||"",t=e.trim()===""?0:e.trim().split(/\s+/).length,i=e.replace(/\n/g,"").length;this._wordCountEl.textContent=`${t} word${t!==1?"s":""}`,this._charCountEl.textContent=`${i} char${i!==1?"s":""}`}_richHTML(){let e=this._editor.cloneNode(!0);return e.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(t=>t.remove()),e.innerHTML}_makeMarker(e){let t=document.createElement("span");return t.className="jotter-bookmark",t.dataset.jotterBookmark=e,t}_takeRange(e){let t=e!=null?this._bookmarks.get(e):null;if(!t)return null;if(this._bookmarks.delete(e),t.atStart){let a=document.createRange();return a.setStart(this._editor,0),a.collapse(!0),a}let{start:i,end:o}=t,s=this._editor.contains(i)&&(!o||this._editor.contains(o)),r=null;return s&&(r=document.createRange(),r.setStartAfter(i),o?r.setEndBefore(o):r.collapse(!0)),i.parentNode&&i.remove(),o&&o.parentNode&&o.remove(),r}_saveBookmark(){this._releaseSavedBookmark(),this._savedBookmark=this.saveSelection()}_restoreSavedBookmark(){this.restoreSelection(this._savedBookmark),this._savedBookmark=null,this._editor.focus()}_releaseSavedBookmark(){this.releaseSelection(this._savedBookmark),this._savedBookmark=null}_dropBookmarks(){Array.from(this._bookmarks.keys()).forEach(e=>this.releaseSelection(e)),this._savedBookmark=null}_emit(e,t){(this._listeners[e]||[]).forEach(i=>i(t))}_emitChange(){let e=this.getHTML();this._changeCount++,this._emit("change",e),this._options.onChange&&this._options.onChange(e)}_applyEdit(e){let t=this._changeCount,i=this._richHTML();e(),this._updateStatus(),this._changeCount===t&&this._richHTML()!==i&&this._emitChange()}getHTML(){return this._sourceMode?this._source.value:this._richHTML()}getText(){return this._editor.innerText}isSourceMode(){return this._sourceMode}toggleSource(){return this._toggleSourceMode(),this}clear(){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML="",this._updateStatus(),this}focus(){return this._editor.focus(),this}insertHTML(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(e))),this}insertText(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertText",!1,e)),this}saveSelection(){let e=window.getSelection();if(!e||e.rangeCount===0)return null;let t=e.getRangeAt(0);if(!this._editor.contains(t.startContainer)||!this._editor.contains(t.endContainer))return null;let i="jbm"+ ++this._bmSeq;if(this._editor.childNodes.length===0)return this._bookmarks.set(i,{atStart:!0}),i;let o=this._makeMarker(i),s=t.collapsed?null:this._makeMarker(i);if(s){let u=t.cloneRange();u.collapse(!1),u.insertNode(s)}let r=t.cloneRange();r.collapse(!0),r.insertNode(o),this._bookmarks.set(i,{start:o,end:s});let a=document.createRange();return a.setStartAfter(o),s?a.setEndBefore(s):a.collapse(!0),e.removeAllRanges(),e.addRange(a),i}restoreSelection(e){let t=this._takeRange(e);if(!t)return this;this._sourceMode||this._editor.focus();let i=window.getSelection();return i.removeAllRanges(),i.addRange(t),this}releaseSelection(e){return this._takeRange(e),this}beginExternalUI(){return this._externalDepth===0&&(this._externalBookmark=this.saveSelection()),this._externalDepth++,this}endExternalUI(e={}){if(this._externalDepth===0)return this;if(this._externalDepth===1){let t=this._externalBookmark;this._externalBookmark=null,e.restore===!1?this.releaseSelection(t):this.restoreSelection(t)}return this._externalDepth--,this}setHTML(e){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML=this._sanitize(e),this._ensureMediaShields(),this._updateStatus(),this}setTheme(e){let i=C.find(o=>o.id===e)?e:"default";return this._editor.dataset.theme=i,this._options.theme=i,this._themeSelect&&(this._themeSelect.value=i),this}setEnabled(e){return this._editor.contentEditable=String(e),this._root.classList.toggle("jotter--disabled",!e),this}on(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),this}off(e,t){return this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(i=>i!==t)),this}destroy(){let e=this.getHTML();return this._destroyed=!0,this._deselectMedia(),this._hidePopup(),this._dropBookmarks(),this._externalBookmark=null,this._externalDepth=0,document.removeEventListener("mousedown",this._onDocMouseDown),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("resize",this._onWindowResize),this._popup.parentNode&&this._popup.parentNode.removeChild(this._popup),this._target.classList.remove("jotter-host"),this._target.innerHTML=e,this._listeners={},e}};h.toolbar=m.full;h.actions=_;h.presets=m;var N=h;export{h as JotterJS,N as default};
4
+ `).map(r=>r.trim()).filter(r=>r.length>0).map(r=>{let a=r.match(/^<\/(\w+)/),u=r.match(/^<(\w+)/),h=r.endsWith("/>"),d=u?u[1].toLowerCase():null,l=a?a[1].toLowerCase():null;l&&!s.has(l)&&(t=Math.max(0,t-1));let c=i.repeat(t)+r;return d&&!h&&!o.has(d)&&!l&&!s.has(d)&&t++,c}).join(`
5
+ `)}_sanitize(e){let t=new DOMParser().parseFromString(e,"text/html");return t.querySelectorAll("script").forEach(i=>i.remove()),t.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(i=>i.remove()),t.querySelectorAll("*").forEach(i=>{Array.from(i.attributes).forEach(o=>{(o.name.startsWith("on")||["href","src","action","formaction","data"].includes(o.name)&&/^\s*javascript:/i.test(o.value))&&i.removeAttribute(o.name)})}),t.body.innerHTML}_toggleInlineCode(){let e=window.getSelection();if(!e||e.rangeCount===0)return;let t=e.getRangeAt(0),i=t.commonAncestorContainer;i.nodeType===3&&(i=i.parentNode);let o=i.closest?i.closest("code"):null;if(o){let s=o.parentNode;for(;o.firstChild;)s.insertBefore(o.firstChild,o);s.removeChild(o)}else if(t.collapsed){let s=document.createElement("code");s.innerHTML="&#8203;",t.insertNode(s);let r=document.createRange();r.setStart(s,0),r.setEnd(s,s.childNodes.length),e.removeAllRanges(),e.addRange(r)}else{let s=document.createElement("code");try{t.surroundContents(s)}catch{let a=t.extractContents();s.appendChild(a),t.insertNode(s)}}}_applyFontSize(e){let t=window.getSelection();if(!t||t.rangeCount===0)return;let i=t.getRangeAt(0);if(i.collapsed)return;let o=document.createElement("span");o.style.fontSize=e+"px";try{i.surroundContents(o)}catch{let r=i.extractContents();o.appendChild(r),i.insertNode(o)}}async _pasteFromClipboard(){try{if(navigator.clipboard&&navigator.clipboard.readText){let e=await navigator.clipboard.readText();document.execCommand("insertText",!1,e)}else document.execCommand("paste")}catch{}}_updateToolbarState(){this._toolbarEl.querySelectorAll(".jotter-btn[data-cmd]").forEach(t=>{try{t.classList.toggle("jotter-btn--active",document.queryCommandState(t.dataset.cmd))}catch{}});let e=this._toolbarEl.querySelector('[data-id="blockformat"]');if(e){let t=document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g,""),i=v.find(o=>o.tag===t);i&&(e.value=i.tag)}}_updateStatus(){let e=this._editor.innerText||"",t=e.trim()===""?0:e.trim().split(/\s+/).length,i=e.replace(/\n/g,"").length;this._wordCountEl.textContent=`${t} word${t!==1?"s":""}`,this._charCountEl.textContent=`${i} char${i!==1?"s":""}`}_richHTML(){let e=this._editor.cloneNode(!0);return e.querySelectorAll("[data-jotter-bookmark], .jotter-media-shield").forEach(t=>t.remove()),e.querySelectorAll("[data-jotter-move]").forEach(t=>t.removeAttribute("data-jotter-move")),e.innerHTML}_makeMarker(e){let t=document.createElement("span");return t.className="jotter-bookmark",t.dataset.jotterBookmark=e,t}_takeRange(e){let t=e!=null?this._bookmarks.get(e):null;if(!t)return null;if(this._bookmarks.delete(e),t.atStart){let a=document.createRange();return a.setStart(this._editor,0),a.collapse(!0),a}let{start:i,end:o}=t,s=this._editor.contains(i)&&(!o||this._editor.contains(o)),r=null;return s&&(r=document.createRange(),r.setStartAfter(i),o?r.setEndBefore(o):r.collapse(!0)),i.parentNode&&i.remove(),o&&o.parentNode&&o.remove(),r}_saveBookmark(){this._releaseSavedBookmark(),this._savedBookmark=this.saveSelection()}_restoreSavedBookmark(){this.restoreSelection(this._savedBookmark),this._savedBookmark=null,this._editor.focus()}_releaseSavedBookmark(){this.releaseSelection(this._savedBookmark),this._savedBookmark=null}_dropBookmarks(){Array.from(this._bookmarks.keys()).forEach(e=>this.releaseSelection(e)),this._savedBookmark=null}_emit(e,t){(this._listeners[e]||[]).forEach(i=>i(t))}_emitChange(){let e=this.getHTML();this._changeCount++,this._emit("change",e),this._options.onChange&&this._options.onChange(e)}_applyEdit(e){let t=this._changeCount,i=this._richHTML();e(),this._updateStatus(),this._changeCount===t&&this._richHTML()!==i&&this._emitChange()}getHTML(){return this._sourceMode?this._source.value:this._richHTML()}getText(){return this._editor.innerText}isSourceMode(){return this._sourceMode}toggleSource(){return this._toggleSourceMode(),this}clear(){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML="",this._updateStatus(),this}focus(){return this._editor.focus(),this}insertHTML(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertHTML",!1,this._sanitize(e))),this}insertText(e,t={}){return t.at!=null&&this.restoreSelection(t.at),this._editor.focus(),this._applyEdit(()=>document.execCommand("insertText",!1,e)),this}saveSelection(){let e=window.getSelection();if(!e||e.rangeCount===0)return null;let t=e.getRangeAt(0);if(!this._editor.contains(t.startContainer)||!this._editor.contains(t.endContainer))return null;let i="jbm"+ ++this._bmSeq;if(this._editor.childNodes.length===0)return this._bookmarks.set(i,{atStart:!0}),i;let o=this._makeMarker(i),s=t.collapsed?null:this._makeMarker(i);if(s){let u=t.cloneRange();u.collapse(!1),u.insertNode(s)}let r=t.cloneRange();r.collapse(!0),r.insertNode(o),this._bookmarks.set(i,{start:o,end:s});let a=document.createRange();return a.setStartAfter(o),s?a.setEndBefore(s):a.collapse(!0),e.removeAllRanges(),e.addRange(a),i}restoreSelection(e){let t=this._takeRange(e);if(!t)return this;this._sourceMode||this._editor.focus();let i=window.getSelection();return i.removeAllRanges(),i.addRange(t),this}releaseSelection(e){return this._takeRange(e),this}beginExternalUI(){return this._externalDepth===0&&(this._externalBookmark=this.saveSelection()),this._externalDepth++,this}endExternalUI(e={}){if(this._externalDepth===0)return this;if(this._externalDepth===1){let t=this._externalBookmark;this._externalBookmark=null,e.restore===!1?this.releaseSelection(t):this.restoreSelection(t)}return this._externalDepth--,this}setHTML(e){return this._deselectMedia(),this._dropBookmarks(),this._editor.innerHTML=this._sanitize(e),this._ensureMediaShields(),this._updateStatus(),this}setTheme(e){let i=C.find(o=>o.id===e)?e:"default";return this._editor.dataset.theme=i,this._options.theme=i,this._themeSelect&&(this._themeSelect.value=i),this}setEnabled(e){return this._editor.contentEditable=String(e),this._root.classList.toggle("jotter--disabled",!e),this}on(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),this}off(e,t){return this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(i=>i!==t)),this}destroy(){let e=this.getHTML();return this._destroyed=!0,this._deselectMedia(),this._hidePopup(),this._dropBookmarks(),this._externalBookmark=null,this._externalDepth=0,document.removeEventListener("mousedown",this._onDocMouseDown),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("resize",this._onWindowResize),this._popup.parentNode&&this._popup.parentNode.removeChild(this._popup),this._target.classList.remove("jotter-host"),this._target.innerHTML=e,this._listeners={},e}};p.toolbar=m.full;p.actions=_;p.presets=m;var R=p;export{p as JotterJS,R as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jotterjs",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A lightweight, vanilla JS rich-text editor component. No dependencies.",
5
5
  "main": "dist/jotter.min.js",
6
6
  "module": "dist/jotter.js",