diff --git a/amd/build/autosaver.min.js b/amd/build/autosaver.min.js index c049ca37..13940655 100644 --- a/amd/build/autosaver.min.js +++ b/amd/build/autosaver.min.js @@ -1,3 +1,3 @@ -define("tiny_cursive/autosaver",["exports","core/ajax","core/modal_factory","core/str","core/modal_events","jquery","tiny_cursive/common","tiny_cursive/cursive_autosave","tiny_cursive/document_view"],(function(_exports,_ajax,_modal_factory,_str,_modal_events,_jquery,_common,_cursive_autosave,_document_view){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.register=void 0,_jquery=_interopRequireDefault(_jquery),_cursive_autosave=_interopRequireDefault(_cursive_autosave),_document_view=_interopRequireDefault(_document_view);_exports.register=(editor,interval,userId,hasApiKey,MODULES,Rubrics,submission,quizInfo,pasteSetting)=>{var isStudent=!(0,_jquery.default)("#body").hasClass("teacher_admin"),intervention=(0,_jquery.default)("#body").hasClass("intervention"),host=M.cfg.wwwroot,userid=userId,courseid=M.cfg.courseId,editorid=null==editor?void 0:editor.id,cmid=M.cfg.contextInstanceId,ed="",event="",filename="",questionid=0,quizSubmit=(0,_jquery.default)("#mod_quiz-next-nav");let assignSubmit=(0,_jquery.default)("#id_submitbutton");var syncInterval=interval?1e3*interval:1e4,lastCaretPos=1;let aiContents=[];var isFullScreen=!1,user=null;let ur=window.location.href,modulesInfo=function(ur,parm,MODULES){if(function(){localStorage.getItem("sbTitle")||Promise.all([(0,_str.get_string)("assignment","tiny_cursive"),(0,_str.get_string)("discussion","tiny_cursive"),(0,_str.get_string)("pluginname","mod_quiz"),(0,_str.get_string)("pluginname","mod_lesson"),(0,_str.get_string)("description","tiny_cursive")]).then((function(strings){return localStorage.setItem("sbTitle",JSON.stringify(strings))})).catch((error=>window.console.error(error)));localStorage.getItem("docSideBar")||Promise.all([(0,_str.get_string)("details","tiny_cursive"),(0,_str.get_string)("student_info","tiny_cursive"),(0,_str.get_string)("progress","tiny_cursive"),(0,_str.get_string)("description","tiny_cursive"),(0,_str.get_string)("replyingto","tiny_cursive"),(0,_str.get_string)("answeringto","tiny_cursive"),(0,_str.get_string)("importantdates","tiny_cursive"),(0,_str.get_string)("rubrics","tiny_cursive"),(0,_str.get_string)("submission_status","tiny_cursive"),(0,_str.get_string)("status","tiny_cursive"),(0,_str.get_string)("draft","tiny_cursive"),(0,_str.get_string)("draftnot","tiny_cursive"),(0,_str.get_string)("last_modified","tiny_cursive"),(0,_str.get_string)("gradings","tiny_cursive"),(0,_str.get_string)("gradenot","tiny_cursive"),(0,_str.get_string)("word_count","tiny_cursive"),(0,_str.get_string)("timeleft","tiny_cursive"),(0,_str.get_string)("nolimit","tiny_cursive"),(0,_str.get_string)("name","tiny_cursive"),(0,_str.get_string)("userename","tiny_cursive"),(0,_str.get_string)("course","tiny_cursive"),(0,_str.get_string)("opened","tiny_cursive"),(0,_str.get_string)("due","tiny_cursive"),(0,_str.get_string)("overdue","tiny_cursive"),(0,_str.get_string)("remaining","tiny_cursive"),(0,_str.get_string)("savechanges","tiny_cursive"),(0,_str.get_string)("subjectnot","tiny_cursive"),(0,_str.get_string)("remaining","tiny_cursive")]).then((function(strings){return localStorage.setItem("docSideBar",JSON.stringify(strings))})).catch((error=>window.console.error(error)))}(),!MODULES.some((module=>ur.includes(module))))return!1;resourceId=ur.includes("forum")&&!ur.includes("assign")?parm.searchParams.get("edit"):parm.searchParams.get("attempt");null===resourceId&&(resourceId=0);for(const module of MODULES)if(ur.includes(module)){modulename=module,"lesson"===module||"assign"===module?resourceId=cmid:"oublog"===module&&(resourceId=0);break}return{resourceId:resourceId,name:modulename}}(ur,new URL(ur),MODULES);var resourceId=modulesInfo.resourceId,modulename=modulesInfo.name,errorAlert=!0;let PASTE_SETTING=pasteSetting||"allow",shouldBlockPaste=!1,isPasteAllowed=!1;"assign"!==modulename&&(PASTE_SETTING="cite_source");const postOne=async(methodname,args)=>{try{const response=await(0,_ajax.call)([{methodname:methodname,args:args}])[0];return response&&setTimeout((()=>{_cursive_autosave.default.updateSavingState("saved")}),1e3),response}catch(error){throw _cursive_autosave.default.updateSavingState("offline"),window.console.error("Error in postOne:",error),error}};(0,_ajax.call)([{methodname:"core_user_get_users_by_field",args:{field:"id",values:[M.cfg.userId]}}])[0].done((response=>{user=response[0]})).fail((ex=>{window.console.error("Error fetching user data:",ex)})),assignSubmit.on("click",(async function(e){e.preventDefault(),filename?syncData().then((()=>{assignSubmit.off("click").click()})):assignSubmit.off("click").click(),localStorage.removeItem("lastCopyCutContent")})),quizSubmit.on("click",(async function(e){e.preventDefault(),filename?syncData().then((()=>{quizSubmit.off("click").click()})):quizSubmit.off("click").click(),localStorage.removeItem("lastCopyCutContent")}));const getModal=()=>{Promise.all([(0,_str.get_string)("tiny_cursive_srcurl","tiny_cursive"),(0,_str.get_string)("tiny_cursive_srcurl_des","tiny_cursive"),(0,_str.get_string)("tiny_cursive_placeholder","tiny_cursive")]).then((function(_ref){let[title,titledes,placeholder]=_ref;return(0,_modal_factory.create)({type:"SAVE_CANCEL",title:`
${title}
\n ${titledes}
`,body:``,removeOnClose:!0}).done((modal=>{modal.getRoot().addClass("tiny-cursive-modal"),modal.show();var lastEvent="";return modal.getRoot().on(_modal_events.save,(function(){var number=document.getElementById("inputUrl").value.trim();""===number||null==number?(editor.execCommand("Undo"),(0,_str.get_string)("pastewarning","tiny_cursive").then((str=>alert(str)))):editor.execCommand("Paste"),postOne("cursive_user_comments",{modulename:modulename,cmid:cmid,resourceid:resourceId,courseid:courseid,usercomment:number,timemodified:Date.now(),editorid:editorid||""}),lastEvent="save",modal.destroy()})),modal.getRoot().on(_modal_events.cancel,(function(){editor.execCommand("Undo"),lastEvent="cancel"})),modal.getRoot().on(_modal_events.hidden,(function(){"cancel"!=lastEvent&&"save"!=lastEvent&&editor.execCommand("Undo")})),modal}))})).catch((error=>window.console.error(error)))},sendKeyEvent=(events,editor)=>{if(ed=editor,event=events,filename=`${userid}_${resourceId}_${cmid}_${modulename}_attempt`,"quiz"===modulename&&(questionid=editorid.split(":")[1].split("_")[0],filename=`${userid}_${resourceId}_${cmid}_${questionid}_${modulename}_attempt`),localStorage.getItem(filename)){let data=JSON.parse(localStorage.getItem(filename));data.push({resourceId:resourceId,key:editor.key,keyCode:editor.keyCode,event:event,courseId:courseid,unixTimestamp:Date.now(),clientId:host,personId:userid,position:ed.caretPosition,rePosition:ed.rePosition,pastedContent:editor.pastedContent,aiContent:editor.aiContent}),localStorage.setItem(filename,JSON.stringify(data))}else{let data=[{resourceId:resourceId,key:editor.key,keyCode:editor.keyCode,event:event,courseId:courseid,unixTimestamp:Date.now(),clientId:host,personId:userid,position:ed.caretPosition,rePosition:ed.rePosition,pastedContent:editor.pastedContent,aiContent:editor.aiContent}];localStorage.setItem(filename,JSON.stringify(data))}};function constructMouseEvent(editor){let position=getCaretPosition(!1);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,editor.key=function(editor){switch(editor.button){case 0:return"left";case 1:return"middle";case 2:return"right"}return null}(editor),editor.keyCode=editor.button}function getCaretPosition(){let skip=arguments.length>0&&void 0!==arguments[0]&&arguments[0];try{if(!editor||!editor.selection)return{caretPosition:0,rePosition:0};const range=editor.selection.getRng(),body=editor.getBody(),preCaretRange=range.cloneRange();preCaretRange.selectNodeContents(body),preCaretRange.setEnd(range.endContainer,range.endOffset);const fragment=preCaretRange.cloneContents(),tempDiv=document.createElement("div");tempDiv.appendChild(fragment);let textBeforeCursor=tempDiv.innerText||"";const endContainer=range.endContainer;0===range.endOffset&&endContainer.nodeType===Node.ELEMENT_NODE&&editor.dom.isBlock(endContainer)&&endContainer.previousSibling&&(textBeforeCursor+="\n");const blockElements=tempDiv.querySelectorAll("p, div, h1, h2, h3, h4, h5, h6, li");let emptyBlockCount=0;blockElements.forEach((block=>{""===(block.innerText||block.textContent||"").trim()&&1===block.childNodes.length&&"BR"===block.childNodes[0].nodeName&&emptyBlockCount++})),emptyBlockCount>0&&(textBeforeCursor+="\n".repeat(emptyBlockCount));const absolutePosition=textBeforeCursor.length;if(skip)return{caretPosition:lastCaretPos,rePosition:absolutePosition};const storageKey=`${userid}_${resourceId}_${cmid}_position`;let storedPos=parseInt(sessionStorage.getItem(storageKey),10);return isNaN(storedPos)&&(storedPos=0),storedPos++,lastCaretPos=storedPos,sessionStorage.setItem(storageKey,storedPos),{caretPosition:storedPos,rePosition:absolutePosition}}catch(e){return window.console.warn("Error getting caret position:",e),{caretPosition:lastCaretPos||1,rePosition:0}}}async function syncData(){let data=localStorage.getItem(filename);if(data&&0!==data.length){localStorage.removeItem(filename);let originalText=editor.getContent({format:"text"});try{return _cursive_autosave.default.updateSavingState("saving"),await postOne("cursive_write_local_to_json",{key:ed.key,event:event,keyCode:ed.keyCode,resourceId:resourceId,cmid:cmid,modulename:modulename,editorid:editorid,json_data:data,originalText:originalText})}catch(error){window.console.error("Error submitting data:",error)}}}function customTooltip(){try{const tooltipText=async function(){const[buttonTitle,buttonDes]=await Promise.all([(0,_str.get_string)("cursive:state:active","tiny_cursive"),(0,_str.get_string)("cursive:state:active:des","tiny_cursive")]);return{buttonTitle:buttonTitle,buttonDes:buttonDes}}(),menubarDiv=document.querySelectorAll('div[role="menubar"].tox-menubar');let classArray=[];menubarDiv.length&&menubarDiv.forEach((function(element,index){let className="cursive-menu-"+(index+=1);element.classList.add(className),classArray.push(className)}));const cursiveIcon=document.createElement("img");cursiveIcon.src=hasApiKey?_common.iconUrl:_common.iconGrayUrl,cursiveIcon.setAttribute("class","tiny_cursive_StateButton"),cursiveIcon.style.display="inline-block",function(cursiveIcon,menubarDiv,classArray){if(!menubarDiv)return;for(let index in classArray){const rightWrapper=document.createElement("div"),imgWrapper=document.createElement("span"),iconClone=cursiveIcon.cloneNode(!0),targetMenu=document.querySelector("."+classArray[index]);let elementId="tiny_cursive_StateIcon"+index;rightWrapper.style.cssText="\n margin-left: auto;\n display: flex;\n align-items: center;\n ",imgWrapper.id=elementId,imgWrapper.style.marginLeft=".2rem",imgWrapper.appendChild(iconClone),rightWrapper.appendChild(imgWrapper);let moduleIds={resourceId:resourceId,cmid:cmid,modulename:modulename,questionid:questionid,userid:userid,courseid:courseid};if(!isFullScreen||"assign"!==modulename&&"forum"!==modulename&&"lesson"!==modulename)if(isFullScreen&&"quiz"===modulename){var _editor$container,_editor$container$chi,_editor$container$chi2,_editor$container$chi3,_editor$container2;let existingElement=null===(_editor$container=editor.container)||void 0===_editor$container||null===(_editor$container$chi=_editor$container.childNodes[1])||void 0===_editor$container$chi||null===(_editor$container$chi2=_editor$container$chi.childNodes[0])||void 0===_editor$container$chi2||null===(_editor$container$chi3=_editor$container$chi2.childNodes[0])||void 0===_editor$container$chi3?void 0:_editor$container$chi3.childNodes[7],newHeader=null===(_editor$container2=editor.container)||void 0===_editor$container2?void 0:_editor$container2.childNodes[0];existingElement&&existingElement.remove(),newHeader&&!newHeader.querySelector("span[id*=tiny_cursive_StateIcon]")&&(rightWrapper.style.marginTop="3px",document.querySelector("#tiny_cursive-fullpage-right-wrapper").prepend(rightWrapper)),_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}else{var _editor$container3,_editor$container3$ch,_editor$container3$ch2;let menubar=null==editor||null===(_editor$container3=editor.container)||void 0===_editor$container3||null===(_editor$container3$ch=_editor$container3.children[0])||void 0===_editor$container3$ch||null===(_editor$container3$ch2=_editor$container3$ch.childNodes[0])||void 0===_editor$container3$ch2?void 0:_editor$container3$ch2.childNodes[0];if(targetMenu&&!targetMenu.querySelector(`#${elementId}`)&&targetMenu.appendChild(rightWrapper),"quiz"===modulename&&menubar){let wrapper=menubar.querySelector('span[id*="tiny_cursive_StateIcon"]');wrapper&&(_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,null==wrapper?void 0:wrapper.parentElement,moduleIds,isFullScreen))}else _cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}else{let existsElement=document.querySelector('.tox-menubar[class*="cursive-menu-"] > div');existsElement&&existsElement.remove(),document.querySelector(`#${elementId}`)||(rightWrapper.style.marginTop="3px",document.querySelector("#tiny_cursive-fullpage-right-wrapper").prepend(rightWrapper)),_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}}}(cursiveIcon,menubarDiv,classArray);for(let index in classArray){const elementId="tiny_cursive_StateIcon"+index,tooltipId=`tiny_cursive_tooltip${index}`;tooltipText.then((text=>setTooltip(text,document.querySelector(`#${elementId}`),tooltipId))).catch((error=>window.console.error(error))),(0,_jquery.default)(`#${elementId}`).on("mouseenter",(function(){(0,_jquery.default)(this).css("position","relative"),(0,_jquery.default)(`#${tooltipId}`).css(_common.tooltipCss)})),(0,_jquery.default)(`#${elementId}`).on("mouseleave",(function(){(0,_jquery.default)(`#${tooltipId}`).css("display","none")}))}}catch(error){window.console.error("Error setting up custom tooltip:",error)}}function setTooltip(text,cursiveIcon,tooltipId){if(!document.querySelector(`#${tooltipId}`)&&cursiveIcon){const tooltipSpan=document.createElement("span"),description=document.createElement("span"),linebreak=document.createElement("br"),tooltipTitle=document.createElement("strong");tooltipSpan.style.display="none",tooltipTitle.textContent=text.buttonTitle,tooltipTitle.style.fontSize="16px",tooltipTitle.style.fontWeight="bold",description.textContent=text.buttonDes,description.style.fontSize="14px",tooltipSpan.id=tooltipId,tooltipSpan.classList.add("shadow"),tooltipSpan.appendChild(tooltipTitle),tooltipSpan.appendChild(linebreak),tooltipSpan.appendChild(description),cursiveIcon.appendChild(tooltipSpan)}}editor.on("keyUp",(editor=>{customTooltip();let position=getCaretPosition(!1);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,sendKeyEvent("keyUp",editor)})),editor.on("Paste",(async e=>{customTooltip();const pastedContent=(e.clipboardData||e.originalEvent.clipboardData).getData("text");if(!pastedContent)return;const trimmedPastedContent=pastedContent.trim(),lastCopyCutContent=localStorage.getItem("lastCopyCutContent"),isFromOwnEditor=lastCopyCutContent&&trimmedPastedContent===lastCopyCutContent;if(isStudent&&intervention){if("block"===PASTE_SETTING)return isFromOwnEditor?(shouldBlockPaste=!1,void(isPasteAllowed=!0)):(e.preventDefault(),shouldBlockPaste=!0,isPasteAllowed=!1,e.stopPropagation(),e.stopImmediatePropagation(),(0,_str.get_string)("paste_blocked","tiny_cursive").then((str=>editor.windowManager.alert(str))).catch((error=>window.console.error(error))),void setTimeout((()=>{isPasteAllowed=!0,shouldBlockPaste=!1}),100));if("cite_source"===PASTE_SETTING)return isFromOwnEditor||(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),getModal()),void(isPasteAllowed=!0)}isPasteAllowed=!0})),editor.on("Redo",(async e=>{customTooltip(),isStudent&&intervention&&getModal()})),editor.on("keyDown",(editor=>{customTooltip();if(("v"===editor.key||"V"===editor.key)&&(editor.ctrlKey||editor.metaKey)&&isStudent&&intervention&&"block"===PASTE_SETTING&&!isPasteAllowed)return void setTimeout((()=>{isPasteAllowed=!0}),100);let position=getCaretPosition();editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,sendKeyEvent("keyDown",editor)})),editor.on("Cut",(()=>{const selectedContent=editor.selection.getContent({format:"text"});localStorage.setItem("lastCopyCutContent",selectedContent.trim())})),editor.on("Copy",(()=>{const selectedContent=editor.selection.getContent({format:"text"});localStorage.setItem("lastCopyCutContent",selectedContent.trim())})),editor.on("mouseDown",(async editor=>{setTimeout((()=>{constructMouseEvent(editor),sendKeyEvent("mouseDown",editor)}),0)})),editor.on("mouseUp",(async editor=>{setTimeout((()=>{constructMouseEvent(editor),sendKeyEvent("mouseUp",editor)}),10)})),editor.on("init",(()=>{customTooltip(),localStorage.removeItem("lastCopyCutContent")})),editor.on("SetContent",(()=>{customTooltip()})),editor.on("FullscreenStateChanged",(e=>{let view=new _document_view.default(user,Rubrics,submission,modulename,editor,quizInfo);isFullScreen=e.state;try{e.state?view.fullPageMode():view.normalMode()}catch(error){errorAlert&&(errorAlert=!1,(0,_str.get_string)("fullmodeerror","tiny_cursive").then((str=>editor.windowManager.alert(str))).catch((error=>window.console.error(error)))),view.normalMode(),window.console.error("Error ResizeEditor event:",error)}})),editor.on("execcommand",(function(e){if("mceInsertContent"===e.command){const contentObj=e.value,isPaste=contentObj&&"object"==typeof contentObj&&!0===contentObj.paste;let insertedContent=contentObj.content||contentObj,tempDiv=document.createElement("div");tempDiv.innerHTML=insertedContent;let text=tempDiv.textContent||tempDiv.innerText||"",pastedText=tempDiv.textContent||tempDiv.innerText||"",position=getCaretPosition(!0);if(editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,isPaste){if(shouldBlockPaste)return shouldBlockPaste=!1,e.preventDefault(),void editor.undoManager.undo();const lastCopyCutContent=localStorage.getItem("lastCopyCutContent"),isFromOwnEditor=lastCopyCutContent&&pastedText.trim()===lastCopyCutContent;if(isStudent&&intervention&&"block"===PASTE_SETTING&&!isFromOwnEditor)return isPasteAllowed=!1,void editor.undoManager.undo();sendKeyEvent("Paste",{key:"v",keyCode:86,caretPosition:editor.caretPosition,rePosition:editor.rePosition,pastedContent:pastedText,srcElement:{baseURI:window.location.href}})}else aiContents.push(text),sendKeyEvent("aiInsert",{key:"ai",keyCode:0,caretPosition:editor.caretPosition,rePosition:editor.rePosition,aiContent:text,srcElement:{baseURI:window.location.href}})}})),editor.on("input",(function(e){let position=getCaretPosition(!0);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition;let aiContent=e.data;("insertReplacementText"===e.inputType||"insertText"===e.inputType&&aiContent&&aiContent.length>1)&&(aiContents.push(aiContent),e.key="ai",e.keyCode=0,e.caretPosition=position.caretPosition,e.rePosition=position.rePosition,e.aiContent=aiContent,sendKeyEvent("aiInsert",e))})),window.addEventListener("unload",(()=>{syncData()})),setInterval(syncData,syncInterval)}})); +define("tiny_cursive/autosaver",["exports","core/ajax","core/modal_factory","core/str","core/modal_events","jquery","tiny_cursive/common","tiny_cursive/cursive_autosave","tiny_cursive/document_view"],(function(_exports,_ajax,_modal_factory,_str,_modal_events,_jquery,_common,_cursive_autosave,_document_view){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.register=void 0,_jquery=_interopRequireDefault(_jquery),_cursive_autosave=_interopRequireDefault(_cursive_autosave),_document_view=_interopRequireDefault(_document_view);_exports.register=(editor,interval,userId,hasApiKey,MODULES,Rubrics,submission,quizInfo,pasteSetting)=>{var isStudent=!(0,_jquery.default)("#body").hasClass("teacher_admin"),intervention=(0,_jquery.default)("#body").hasClass("intervention"),host=M.cfg.wwwroot,userid=userId,courseid=M.cfg.courseId,editorid=null==editor?void 0:editor.id,cmid=M.cfg.contextInstanceId,ed="",event="",filename="",questionid=0,quizSubmit=(0,_jquery.default)("#mod_quiz-next-nav");let assignSubmit=(0,_jquery.default)("#id_submitbutton");var syncInterval=interval?1e3*interval:1e4,lastCaretPos=1;let aiContents=[];var isFullScreen=!1,user=null;let ur=window.location.href,modulesInfo=function(ur,parm,MODULES){if(function(){localStorage.getItem("sbTitle")||Promise.all([(0,_str.get_string)("assignment","tiny_cursive"),(0,_str.get_string)("discussion","tiny_cursive"),(0,_str.get_string)("pluginname","mod_quiz"),(0,_str.get_string)("pluginname","mod_lesson"),(0,_str.get_string)("description","tiny_cursive")]).then((function(strings){return localStorage.setItem("sbTitle",JSON.stringify(strings))})).catch((error=>window.console.error(error)));localStorage.getItem("docSideBar")||Promise.all([(0,_str.get_string)("details","tiny_cursive"),(0,_str.get_string)("student_info","tiny_cursive"),(0,_str.get_string)("progress","tiny_cursive"),(0,_str.get_string)("description","tiny_cursive"),(0,_str.get_string)("replyingto","tiny_cursive"),(0,_str.get_string)("answeringto","tiny_cursive"),(0,_str.get_string)("importantdates","tiny_cursive"),(0,_str.get_string)("rubrics","tiny_cursive"),(0,_str.get_string)("submission_status","tiny_cursive"),(0,_str.get_string)("status","tiny_cursive"),(0,_str.get_string)("draft","tiny_cursive"),(0,_str.get_string)("draftnot","tiny_cursive"),(0,_str.get_string)("last_modified","tiny_cursive"),(0,_str.get_string)("gradings","tiny_cursive"),(0,_str.get_string)("gradenot","tiny_cursive"),(0,_str.get_string)("word_count","tiny_cursive"),(0,_str.get_string)("timeleft","tiny_cursive"),(0,_str.get_string)("nolimit","tiny_cursive"),(0,_str.get_string)("name","tiny_cursive"),(0,_str.get_string)("userename","tiny_cursive"),(0,_str.get_string)("course","tiny_cursive"),(0,_str.get_string)("opened","tiny_cursive"),(0,_str.get_string)("due","tiny_cursive"),(0,_str.get_string)("overdue","tiny_cursive"),(0,_str.get_string)("remaining","tiny_cursive"),(0,_str.get_string)("savechanges","tiny_cursive"),(0,_str.get_string)("subjectnot","tiny_cursive"),(0,_str.get_string)("remaining","tiny_cursive")]).then((function(strings){return localStorage.setItem("docSideBar",JSON.stringify(strings))})).catch((error=>window.console.error(error)))}(),!MODULES.some((module=>ur.includes(module))))return!1;resourceId=ur.includes("forum")&&!ur.includes("assign")?parm.searchParams.get("edit"):parm.searchParams.get("attempt");null===resourceId&&(resourceId=0);for(const module of MODULES)if(ur.includes(module)){modulename=module,"lesson"===module||"assign"===module?resourceId=cmid:"oublog"===module&&(resourceId=0);break}return{resourceId:resourceId,name:modulename}}(ur,new URL(ur),MODULES);var resourceId=modulesInfo.resourceId,modulename=modulesInfo.name,errorAlert=!0;let PASTE_SETTING=pasteSetting||"allow",shouldBlockPaste=!1,isPasteAllowed=!1;"assign"!==modulename&&(PASTE_SETTING="cite_source");const postOne=async(methodname,args)=>{try{const response=await(0,_ajax.call)([{methodname:methodname,args:args}])[0];return response&&setTimeout((()=>{_cursive_autosave.default.updateSavingState("saved")}),1e3),response}catch(error){throw _cursive_autosave.default.updateSavingState("offline"),window.console.error("Error in postOne:",error),error}};(0,_ajax.call)([{methodname:"core_user_get_users_by_field",args:{field:"id",values:[userid]}}])[0].done((response=>{user=response[0]})).fail((ex=>{window.console.error("Error fetching user data:",ex)})),assignSubmit.on("click",(async function(e){e.preventDefault(),filename?syncData().then((()=>{assignSubmit.off("click").click()})):assignSubmit.off("click").click(),localStorage.removeItem("lastCopyCutContent")})),quizSubmit.on("click",(async function(e){e.preventDefault(),filename?syncData().then((()=>{quizSubmit.off("click").click()})):quizSubmit.off("click").click(),localStorage.removeItem("lastCopyCutContent")}));const getModal=()=>{Promise.all([(0,_str.get_string)("tiny_cursive_srcurl","tiny_cursive"),(0,_str.get_string)("tiny_cursive_srcurl_des","tiny_cursive"),(0,_str.get_string)("tiny_cursive_placeholder","tiny_cursive")]).then((function(_ref){let[title,titledes,placeholder]=_ref;return(0,_modal_factory.create)({type:"SAVE_CANCEL",title:`
${title}
\n ${titledes}
`,body:``,removeOnClose:!0}).done((modal=>{modal.getRoot().addClass("tiny-cursive-modal"),modal.show();var lastEvent="";return modal.getRoot().on(_modal_events.save,(function(){var number=document.getElementById("inputUrl").value.trim();""===number||null==number?(editor.execCommand("Undo"),(0,_str.get_string)("pastewarning","tiny_cursive").then((str=>alert(str)))):editor.execCommand("Paste"),postOne("cursive_user_comments",{modulename:modulename,cmid:cmid,resourceid:resourceId,courseid:courseid,usercomment:number,timemodified:Date.now(),editorid:editorid||""}),lastEvent="save",modal.destroy()})),modal.getRoot().on(_modal_events.cancel,(function(){editor.execCommand("Undo"),lastEvent="cancel"})),modal.getRoot().on(_modal_events.hidden,(function(){"cancel"!=lastEvent&&"save"!=lastEvent&&editor.execCommand("Undo")})),modal}))})).catch((error=>window.console.error(error)))},sendKeyEvent=(events,editor)=>{if(ed=editor,event=events,filename=`${userid}_${resourceId}_${cmid}_${modulename}_attempt`,"quiz"===modulename&&(questionid=editorid.split(":")[1].split("_")[0],filename=`${userid}_${resourceId}_${cmid}_${questionid}_${modulename}_attempt`),localStorage.getItem(filename)){let data=JSON.parse(localStorage.getItem(filename));data.push({resourceId:resourceId,key:editor.key,keyCode:editor.keyCode,event:event,courseId:courseid,unixTimestamp:Date.now(),clientId:host,personId:userid,position:ed.caretPosition,rePosition:ed.rePosition,pastedContent:editor.pastedContent,aiContent:editor.aiContent}),localStorage.setItem(filename,JSON.stringify(data))}else{let data=[{resourceId:resourceId,key:editor.key,keyCode:editor.keyCode,event:event,courseId:courseid,unixTimestamp:Date.now(),clientId:host,personId:userid,position:ed.caretPosition,rePosition:ed.rePosition,pastedContent:editor.pastedContent,aiContent:editor.aiContent}];localStorage.setItem(filename,JSON.stringify(data))}};function constructMouseEvent(editor){let position=getCaretPosition(!1);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,editor.key=function(editor){switch(editor.button){case 0:return"left";case 1:return"middle";case 2:return"right"}return null}(editor),editor.keyCode=editor.button}function getCaretPosition(){let skip=arguments.length>0&&void 0!==arguments[0]&&arguments[0];try{if(!editor||!editor.selection)return{caretPosition:0,rePosition:0};const range=editor.selection.getRng(),body=editor.getBody(),preCaretRange=range.cloneRange();preCaretRange.selectNodeContents(body),preCaretRange.setEnd(range.endContainer,range.endOffset);const fragment=preCaretRange.cloneContents(),tempDiv=document.createElement("div");tempDiv.appendChild(fragment);let textBeforeCursor=tempDiv.innerText||"";const endContainer=range.endContainer;0===range.endOffset&&endContainer.nodeType===Node.ELEMENT_NODE&&editor.dom.isBlock(endContainer)&&endContainer.previousSibling&&(textBeforeCursor+="\n");const blockElements=tempDiv.querySelectorAll("p, div, h1, h2, h3, h4, h5, h6, li");let emptyBlockCount=0;blockElements.forEach((block=>{""===(block.innerText||block.textContent||"").trim()&&1===block.childNodes.length&&"BR"===block.childNodes[0].nodeName&&emptyBlockCount++})),emptyBlockCount>0&&(textBeforeCursor+="\n".repeat(emptyBlockCount));const absolutePosition=textBeforeCursor.length;if(skip)return{caretPosition:lastCaretPos,rePosition:absolutePosition};const storageKey=`${userid}_${resourceId}_${cmid}_position`;let storedPos=parseInt(sessionStorage.getItem(storageKey),10);return isNaN(storedPos)&&(storedPos=0),storedPos++,lastCaretPos=storedPos,sessionStorage.setItem(storageKey,storedPos),{caretPosition:storedPos,rePosition:absolutePosition}}catch(e){return window.console.warn("Error getting caret position:",e),{caretPosition:lastCaretPos||1,rePosition:0}}}async function syncData(){let data=localStorage.getItem(filename);if(data&&0!==data.length){localStorage.removeItem(filename);let originalText=editor.getContent({format:"text"});try{return _cursive_autosave.default.updateSavingState("saving"),await postOne("cursive_write_local_to_json",{key:ed.key,event:event,keyCode:ed.keyCode,resourceId:resourceId,cmid:cmid,modulename:modulename,editorid:editorid,json_data:data,originalText:originalText})}catch(error){window.console.error("Error submitting data:",error)}}}function customTooltip(){try{const tooltipText=async function(){const[buttonTitle,buttonDes]=await Promise.all([(0,_str.get_string)("cursive:state:active","tiny_cursive"),(0,_str.get_string)("cursive:state:active:des","tiny_cursive")]);return{buttonTitle:buttonTitle,buttonDes:buttonDes}}(),menubarDiv=document.querySelectorAll('div[role="menubar"].tox-menubar');let classArray=[];menubarDiv.length&&menubarDiv.forEach((function(element,index){let className="cursive-menu-"+(index+=1);element.classList.add(className),classArray.push(className)}));const cursiveIcon=document.createElement("img");cursiveIcon.src=hasApiKey?_common.iconUrl:_common.iconGrayUrl,cursiveIcon.setAttribute("class","tiny_cursive_StateButton"),cursiveIcon.style.display="inline-block",function(cursiveIcon,menubarDiv,classArray){if(!menubarDiv)return;for(let index in classArray){const rightWrapper=document.createElement("div"),imgWrapper=document.createElement("span"),iconClone=cursiveIcon.cloneNode(!0),targetMenu=document.querySelector("."+classArray[index]);let elementId="tiny_cursive_StateIcon"+index;rightWrapper.style.cssText="\n margin-left: auto;\n display: flex;\n align-items: center;\n ",imgWrapper.id=elementId,imgWrapper.style.marginLeft=".2rem",imgWrapper.appendChild(iconClone),rightWrapper.appendChild(imgWrapper);let moduleIds={resourceId:resourceId,cmid:cmid,modulename:modulename,questionid:questionid,userid:userid,courseid:courseid};if(!isFullScreen||"assign"!==modulename&&"forum"!==modulename&&"lesson"!==modulename)if(isFullScreen&&"quiz"===modulename){var _editor$container,_editor$container$chi,_editor$container$chi2,_editor$container$chi3,_editor$container2;let existingElement=null===(_editor$container=editor.container)||void 0===_editor$container||null===(_editor$container$chi=_editor$container.childNodes[1])||void 0===_editor$container$chi||null===(_editor$container$chi2=_editor$container$chi.childNodes[0])||void 0===_editor$container$chi2||null===(_editor$container$chi3=_editor$container$chi2.childNodes[0])||void 0===_editor$container$chi3?void 0:_editor$container$chi3.childNodes[7],newHeader=null===(_editor$container2=editor.container)||void 0===_editor$container2?void 0:_editor$container2.childNodes[0];existingElement&&existingElement.remove(),newHeader&&!newHeader.querySelector("span[id*=tiny_cursive_StateIcon]")&&(rightWrapper.style.marginTop="3px",document.querySelector("#tiny_cursive-fullpage-right-wrapper").prepend(rightWrapper)),_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}else{var _editor$container3,_editor$container3$ch,_editor$container3$ch2;let menubar=null==editor||null===(_editor$container3=editor.container)||void 0===_editor$container3||null===(_editor$container3$ch=_editor$container3.children[0])||void 0===_editor$container3$ch||null===(_editor$container3$ch2=_editor$container3$ch.childNodes[0])||void 0===_editor$container3$ch2?void 0:_editor$container3$ch2.childNodes[0];if(targetMenu&&!targetMenu.querySelector(`#${elementId}`)&&targetMenu.appendChild(rightWrapper),"quiz"===modulename&&menubar){let wrapper=menubar.querySelector('span[id*="tiny_cursive_StateIcon"]');wrapper&&(_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,null==wrapper?void 0:wrapper.parentElement,moduleIds,isFullScreen))}else _cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}else{let existsElement=document.querySelector('.tox-menubar[class*="cursive-menu-"] > div');existsElement&&existsElement.remove(),document.querySelector(`#${elementId}`)||(rightWrapper.style.marginTop="3px",document.querySelector("#tiny_cursive-fullpage-right-wrapper").prepend(rightWrapper)),_cursive_autosave.default.destroyInstance(),_cursive_autosave.default.getInstance(editor,rightWrapper,moduleIds,isFullScreen)}}}(cursiveIcon,menubarDiv,classArray);for(let index in classArray){const elementId="tiny_cursive_StateIcon"+index,tooltipId=`tiny_cursive_tooltip${index}`;tooltipText.then((text=>setTooltip(text,document.querySelector(`#${elementId}`),tooltipId))).catch((error=>window.console.error(error))),(0,_jquery.default)(`#${elementId}`).on("mouseenter",(function(){(0,_jquery.default)(this).css("position","relative"),(0,_jquery.default)(`#${tooltipId}`).css(_common.tooltipCss)})),(0,_jquery.default)(`#${elementId}`).on("mouseleave",(function(){(0,_jquery.default)(`#${tooltipId}`).css("display","none")}))}}catch(error){window.console.error("Error setting up custom tooltip:",error)}}function setTooltip(text,cursiveIcon,tooltipId){if(!document.querySelector(`#${tooltipId}`)&&cursiveIcon){const tooltipSpan=document.createElement("span"),description=document.createElement("span"),linebreak=document.createElement("br"),tooltipTitle=document.createElement("strong");tooltipSpan.style.display="none",tooltipTitle.textContent=text.buttonTitle,tooltipTitle.style.fontSize="16px",tooltipTitle.style.fontWeight="bold",description.textContent=text.buttonDes,description.style.fontSize="14px",tooltipSpan.id=tooltipId,tooltipSpan.classList.add("shadow"),tooltipSpan.appendChild(tooltipTitle),tooltipSpan.appendChild(linebreak),tooltipSpan.appendChild(description),cursiveIcon.appendChild(tooltipSpan)}}editor.on("keyUp",(editor=>{customTooltip();let position=getCaretPosition(!1);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,sendKeyEvent("keyUp",editor)})),editor.on("Paste",(async e=>{customTooltip();const pastedContent=(e.clipboardData||e.originalEvent.clipboardData).getData("text");if(!pastedContent)return;const trimmedPastedContent=pastedContent.trim(),lastCopyCutContent=localStorage.getItem("lastCopyCutContent"),isFromOwnEditor=lastCopyCutContent&&trimmedPastedContent===lastCopyCutContent;if(isStudent&&intervention){if("block"===PASTE_SETTING)return isFromOwnEditor?(shouldBlockPaste=!1,void(isPasteAllowed=!0)):(e.preventDefault(),shouldBlockPaste=!0,isPasteAllowed=!1,e.stopPropagation(),e.stopImmediatePropagation(),(0,_str.get_string)("paste_blocked","tiny_cursive").then((str=>editor.windowManager.alert(str))).catch((error=>window.console.error(error))),void setTimeout((()=>{isPasteAllowed=!0,shouldBlockPaste=!1}),100));if("cite_source"===PASTE_SETTING)return isFromOwnEditor||(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),getModal()),void(isPasteAllowed=!0)}isPasteAllowed=!0})),editor.on("Redo",(async e=>{customTooltip(),isStudent&&intervention&&getModal()})),editor.on("keyDown",(editor=>{customTooltip();if(("v"===editor.key||"V"===editor.key)&&(editor.ctrlKey||editor.metaKey)&&isStudent&&intervention&&"block"===PASTE_SETTING&&!isPasteAllowed)return void setTimeout((()=>{isPasteAllowed=!0}),100);let position=getCaretPosition();editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,sendKeyEvent("keyDown",editor)})),editor.on("Cut",(()=>{const selectedContent=editor.selection.getContent({format:"text"});localStorage.setItem("lastCopyCutContent",selectedContent.trim())})),editor.on("Copy",(()=>{const selectedContent=editor.selection.getContent({format:"text"});localStorage.setItem("lastCopyCutContent",selectedContent.trim())})),editor.on("mouseDown",(async editor=>{setTimeout((()=>{constructMouseEvent(editor),sendKeyEvent("mouseDown",editor)}),0)})),editor.on("mouseUp",(async editor=>{setTimeout((()=>{constructMouseEvent(editor),sendKeyEvent("mouseUp",editor)}),10)})),editor.on("init",(()=>{customTooltip(),localStorage.removeItem("lastCopyCutContent")})),editor.on("SetContent",(()=>{customTooltip()})),editor.on("FullscreenStateChanged",(e=>{let view=new _document_view.default(user,Rubrics,submission,modulename,editor,quizInfo);isFullScreen=e.state;try{e.state?view.fullPageMode():view.normalMode()}catch(error){errorAlert&&(errorAlert=!1,(0,_str.get_string)("fullmodeerror","tiny_cursive").then((str=>editor.windowManager.alert(str))).catch((error=>window.console.error(error)))),view.normalMode(),window.console.error("Error ResizeEditor event:",error)}})),editor.on("execcommand",(function(e){if("mceInsertContent"===e.command){const contentObj=e.value,isPaste=contentObj&&"object"==typeof contentObj&&!0===contentObj.paste;let insertedContent=contentObj.content||contentObj,tempDiv=document.createElement("div");tempDiv.innerHTML=insertedContent;let text=tempDiv.textContent||tempDiv.innerText||"",pastedText=tempDiv.textContent||tempDiv.innerText||"",position=getCaretPosition(!0);if(editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition,isPaste){if(shouldBlockPaste)return shouldBlockPaste=!1,e.preventDefault(),void editor.undoManager.undo();const lastCopyCutContent=localStorage.getItem("lastCopyCutContent"),isFromOwnEditor=lastCopyCutContent&&pastedText.trim()===lastCopyCutContent;if(isStudent&&intervention&&"block"===PASTE_SETTING&&!isFromOwnEditor)return isPasteAllowed=!1,void editor.undoManager.undo();sendKeyEvent("Paste",{key:"v",keyCode:86,caretPosition:editor.caretPosition,rePosition:editor.rePosition,pastedContent:pastedText,srcElement:{baseURI:window.location.href}})}else aiContents.push(text),sendKeyEvent("aiInsert",{key:"ai",keyCode:0,caretPosition:editor.caretPosition,rePosition:editor.rePosition,aiContent:text,srcElement:{baseURI:window.location.href}})}})),editor.on("input",(function(e){let position=getCaretPosition(!0);editor.caretPosition=position.caretPosition,editor.rePosition=position.rePosition;let aiContent=e.data;("insertReplacementText"===e.inputType||"insertText"===e.inputType&&aiContent&&aiContent.length>1)&&(aiContents.push(aiContent),e.key="ai",e.keyCode=0,e.caretPosition=position.caretPosition,e.rePosition=position.rePosition,e.aiContent=aiContent,sendKeyEvent("aiInsert",e))})),window.addEventListener("unload",(()=>{syncData()})),setInterval(syncData,syncInterval)}})); //# sourceMappingURL=autosaver.min.js.map \ No newline at end of file diff --git a/amd/build/autosaver.min.js.map b/amd/build/autosaver.min.js.map index 31ebb527..3282341f 100644 --- a/amd/build/autosaver.min.js.map +++ b/amd/build/autosaver.min.js.map @@ -1 +1 @@ -{"version":3,"file":"autosaver.min.js","sources":["../src/autosaver.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * @module tiny_cursive/autosaver\n * @category TinyMCE Editor\n * @copyright CTI \n * @author Brain Station 23 \n */\n\nimport {call} from 'core/ajax';\nimport {create} from 'core/modal_factory';\nimport {get_string as getString} from 'core/str';\nimport {save, cancel, hidden} from 'core/modal_events';\nimport $ from 'jquery';\nimport {iconUrl, iconGrayUrl, tooltipCss} from 'tiny_cursive/common';\nimport Autosave from 'tiny_cursive/cursive_autosave';\nimport DocumentView from 'tiny_cursive/document_view';\nimport {call as getUser} from \"core/ajax\";\n\nexport const register = (editor, interval, userId, hasApiKey, MODULES, Rubrics, submission, quizInfo, pasteSetting) => {\n\n var isStudent = !($('#body').hasClass('teacher_admin'));\n var intervention = $('#body').hasClass('intervention');\n var host = M.cfg.wwwroot;\n var userid = userId;\n var courseid = M.cfg.courseId;\n var editorid = editor?.id;\n var cmid = M.cfg.contextInstanceId;\n var ed = \"\";\n var event = \"\";\n var filename = \"\";\n var questionid = 0;\n var quizSubmit = $('#mod_quiz-next-nav');\n let assignSubmit = $('#id_submitbutton');\n var syncInterval = interval ? interval * 1000 : 10000; // Default: Sync Every 10s.\n var lastCaretPos = 1;\n let aiContents = [];\n var isFullScreen = false;\n var user = null;\n let ur = window.location.href;\n let parm = new URL(ur);\n let modulesInfo = getModulesInfo(ur, parm, MODULES);\n var resourceId = modulesInfo.resourceId;\n var modulename = modulesInfo.name;\n var errorAlert = true;\n let PASTE_SETTING = pasteSetting || 'allow';\n let shouldBlockPaste = false;\n let isPasteAllowed = false;\n\n if (modulename !== 'assign') {\n PASTE_SETTING = 'cite_source';\n }\n const postOne = async(methodname, args) => {\n try {\n const response = await call([{\n methodname,\n args,\n }])[0];\n if (response) {\n setTimeout(() => {\n Autosave.updateSavingState('saved');\n }, 1000);\n }\n return response;\n } catch (error) {\n Autosave.updateSavingState('offline');\n window.console.error('Error in postOne:', error);\n throw error;\n }\n };\n\n getUser([{\n methodname: 'core_user_get_users_by_field',\n args: {field: 'id', values: [M.cfg.userId]},\n }])[0].done(response => {\n user = response[0];\n }).fail((ex) => {\n window.console.error('Error fetching user data:', ex);\n });\n\n assignSubmit.on('click', async function(e) {\n e.preventDefault();\n if (filename) {\n // eslint-disable-next-line\n syncData().then(() => {\n assignSubmit.off('click').click();\n });\n } else {\n assignSubmit.off('click').click();\n }\n localStorage.removeItem('lastCopyCutContent');\n });\n\n quizSubmit.on('click', async function(e) {\n e.preventDefault();\n if (filename) {\n // eslint-disable-next-line\n syncData().then(() => {\n quizSubmit.off('click').click();\n });\n } else {\n quizSubmit.off('click').click();\n }\n localStorage.removeItem('lastCopyCutContent');\n });\n\n const getModal = () => {\n\n Promise.all([\n getString('tiny_cursive_srcurl', 'tiny_cursive'),\n getString('tiny_cursive_srcurl_des', 'tiny_cursive'),\n getString('tiny_cursive_placeholder', 'tiny_cursive')\n ]).then(function([title, titledes, placeholder]) {\n\n return create({\n type: 'SAVE_CANCEL',\n title: `
${title}
\n ${titledes}
`,\n body: ``,\n removeOnClose: true,\n })\n .done(modal => {\n modal.getRoot().addClass('tiny-cursive-modal');\n modal.show();\n var lastEvent = '';\n\n modal.getRoot().on(save, function() {\n\n var number = document.getElementById(\"inputUrl\").value.trim();\n\n if (number === \"\" || number === null || number === undefined) {\n editor.execCommand('Undo');\n // eslint-disable-next-line\n getString('pastewarning', 'tiny_cursive').then(str => alert(str));\n } else {\n editor.execCommand('Paste');\n }\n\n postOne('cursive_user_comments', {\n modulename: modulename,\n cmid: cmid,\n resourceid: resourceId,\n courseid: courseid,\n usercomment: number,\n timemodified: Date.now(),\n editorid: editorid ? editorid : \"\"\n });\n\n lastEvent = 'save';\n modal.destroy();\n });\n modal.getRoot().on(cancel, function() {\n editor.execCommand('Undo');\n lastEvent = 'cancel';\n });\n\n modal.getRoot().on(hidden, function() {\n if (lastEvent != 'cancel' && lastEvent != 'save') {\n editor.execCommand('Undo');\n }\n });\n return modal;\n });\n }).catch(error => window.console.error(error));\n\n };\n\n const sendKeyEvent = (events, editor) => {\n ed = editor;\n event = events;\n\n filename = `${userid}_${resourceId}_${cmid}_${modulename}_attempt`;\n\n if (modulename === 'quiz') {\n questionid = editorid.split(':')[1].split('_')[0];\n filename = `${userid}_${resourceId}_${cmid}_${questionid}_${modulename}_attempt`;\n }\n\n if (localStorage.getItem(filename)) {\n let data = JSON.parse(localStorage.getItem(filename));\n data.push({\n resourceId: resourceId,\n key: editor.key,\n keyCode: editor.keyCode,\n event: event,\n courseId: courseid,\n unixTimestamp: Date.now(),\n clientId: host,\n personId: userid,\n position: ed.caretPosition,\n rePosition: ed.rePosition,\n pastedContent: editor.pastedContent,\n aiContent: editor.aiContent\n });\n localStorage.setItem(filename, JSON.stringify(data));\n } else {\n let data = [{\n resourceId: resourceId,\n key: editor.key,\n keyCode: editor.keyCode,\n event: event,\n courseId: courseid,\n unixTimestamp: Date.now(),\n clientId: host,\n personId: userid,\n position: ed.caretPosition,\n rePosition: ed.rePosition,\n pastedContent: editor.pastedContent,\n aiContent: editor.aiContent\n }];\n localStorage.setItem(filename, JSON.stringify(data));\n }\n };\n\n editor.on('keyUp', (editor) => {\n customTooltip();\n let position = getCaretPosition(false);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n sendKeyEvent(\"keyUp\", editor);\n });\n editor.on('Paste', async(e) => {\n customTooltip();\n const pastedContent = (e.clipboardData || e.originalEvent.clipboardData).getData('text');\n if (!pastedContent) {\n return;\n }\n // Trim both values for consistent comparison\n const trimmedPastedContent = pastedContent.trim();\n const lastCopyCutContent = localStorage.getItem('lastCopyCutContent');\n const isFromOwnEditor = lastCopyCutContent && trimmedPastedContent === lastCopyCutContent;\n\n if (isStudent && intervention) {\n\n if (PASTE_SETTING === 'block') {\n if (!isFromOwnEditor) {\n e.preventDefault();\n shouldBlockPaste = true;\n isPasteAllowed = false;\n e.stopPropagation();\n e.stopImmediatePropagation();\n getString('paste_blocked', 'tiny_cursive').then(str => {\n return editor.windowManager.alert(str);\n }).catch(error => window.console.error(error));\n setTimeout(() => {\n isPasteAllowed = true;\n shouldBlockPaste = false;\n }, 100);\n return;\n }\n shouldBlockPaste = false;\n isPasteAllowed = true;\n return;\n }\n if (PASTE_SETTING === 'cite_source') {\n if (!isFromOwnEditor) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n getModal(e);\n }\n isPasteAllowed = true;\n return;\n }\n }\n isPasteAllowed = true;\n });\n editor.on('Redo', async(e) => {\n customTooltip();\n if (isStudent && intervention) {\n getModal(e);\n }\n });\n editor.on('keyDown', (editor) => {\n customTooltip();\n const isPasteAttempt = (editor.key === 'v' || editor.key === 'V') &&\n (editor.ctrlKey || editor.metaKey);\n if (isPasteAttempt && isStudent && intervention && PASTE_SETTING === 'block' && !isPasteAllowed) {\n setTimeout(() => {\n isPasteAllowed = true;\n }, 100);\n return;\n }\n let position = getCaretPosition();\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n sendKeyEvent(\"keyDown\", editor);\n });\n editor.on('Cut', () => {\n const selectedContent = editor.selection.getContent({format: 'text'});\n localStorage.setItem('lastCopyCutContent', selectedContent.trim());\n });\n editor.on('Copy', () => {\n const selectedContent = editor.selection.getContent({format: 'text'});\n localStorage.setItem('lastCopyCutContent', selectedContent.trim());\n });\n editor.on('mouseDown', async(editor) => {\n setTimeout(() => {\n constructMouseEvent(editor);\n sendKeyEvent(\"mouseDown\", editor);\n }, 0);\n });\n editor.on('mouseUp', async(editor) => {\n setTimeout(() => {\n constructMouseEvent(editor);\n sendKeyEvent(\"mouseUp\", editor);\n }, 10);\n });\n editor.on('init', () => {\n customTooltip();\n localStorage.removeItem('lastCopyCutContent');\n });\n editor.on('SetContent', () => {\n customTooltip();\n });\n editor.on('FullscreenStateChanged', (e) => {\n let view = new DocumentView(user, Rubrics, submission, modulename, editor, quizInfo);\n isFullScreen = e.state;\n try {\n if (!e.state) {\n view.normalMode();\n } else {\n view.fullPageMode();\n }\n } catch (error) {\n if (errorAlert) {\n errorAlert = false;\n getString('fullmodeerror', 'tiny_cursive').then(str => {\n return editor.windowManager.alert(str);\n }).catch(error => window.console.error(error));\n }\n view.normalMode();\n window.console.error('Error ResizeEditor event:', error);\n }\n });\n\n editor.on('execcommand', function(e) {\n if (e.command === \"mceInsertContent\") {\n const contentObj = e.value;\n\n const isPaste = contentObj && typeof contentObj === 'object' && contentObj.paste === true;\n\n let insertedContent = contentObj.content || contentObj;\n let tempDiv = document.createElement('div');\n tempDiv.innerHTML = insertedContent;\n let text = tempDiv.textContent || tempDiv.innerText || '';\n let pastedText = tempDiv.textContent || tempDiv.innerText || '';\n\n let position = getCaretPosition(true);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n\n if (isPaste) {\n if (shouldBlockPaste) {\n shouldBlockPaste = false;\n e.preventDefault();\n editor.undoManager.undo();\n return;\n }\n const lastCopyCutContent = localStorage.getItem('lastCopyCutContent');\n const isFromOwnEditor = lastCopyCutContent && pastedText.trim() === lastCopyCutContent;\n\n if (isStudent && intervention && PASTE_SETTING === 'block' && !isFromOwnEditor) {\n isPasteAllowed = false;\n editor.undoManager.undo();\n return;\n }\n\n sendKeyEvent(\"Paste\", {\n key: \"v\",\n keyCode: 86,\n caretPosition: editor.caretPosition,\n rePosition: editor.rePosition,\n pastedContent: pastedText,\n srcElement: {baseURI: window.location.href}\n });\n } else {\n aiContents.push(text);\n\n sendKeyEvent(\"aiInsert\", {\n key: \"ai\",\n keyCode: 0,\n caretPosition: editor.caretPosition,\n rePosition: editor.rePosition,\n aiContent: text,\n srcElement: {baseURI: window.location.href}\n });\n }\n }\n });\n\n editor.on('input', function(e) {\n let position = getCaretPosition(true);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n let aiContent = e.data;\n\n if (e.inputType === 'insertReplacementText' || (e.inputType === 'insertText' && aiContent && aiContent.length > 1)) {\n\n aiContents.push(aiContent);\n\n e.key = \"ai\";\n e.keyCode = 0;\n e.caretPosition = position.caretPosition;\n e.rePosition = position.rePosition;\n e.aiContent = aiContent;\n\n sendKeyEvent(\"aiInsert\", e);\n }\n });\n\n\n /**\n * Constructs a mouse event object with caret position and button information\n * @param {Object} editor - The TinyMCE editor instance\n * @function constructMouseEvent\n * @description Sets caret position, reposition, key and keyCode properties on the editor object based on current mouse state\n */\n function constructMouseEvent(editor) {\n let position = getCaretPosition(false);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n editor.key = getMouseButton(editor);\n editor.keyCode = editor.button;\n }\n\n /**\n * Gets the string representation of a mouse button based on its numeric value\n * @param {Object} editor - The editor object containing button information\n * @returns {string} The string representation of the mouse button ('left', 'middle', or 'right')\n */\n function getMouseButton(editor) {\n\n switch (editor.button) {\n case 0:\n return 'left';\n case 1:\n return 'middle';\n case 2:\n return 'right';\n }\n return null;\n }\n\n /**\n * Gets the current caret position in the editor\n * @param {boolean} skip - If true, returns the last known caret position instead of calculating a new one\n * @returns {Object} Object containing:\n * - caretPosition: Sequential position number stored in session\n * - rePosition: Absolute character offset from start of content\n * @throws {Error} Logs warning to console if error occurs during calculation\n */\n function getCaretPosition(skip = false) {\n try {\n if (!editor || !editor.selection) {\n return {caretPosition: 0, rePosition: 0};\n }\n\n const range = editor.selection.getRng();\n const body = editor.getBody();\n\n // Create a range from start of document to current caret\n const preCaretRange = range.cloneRange();\n preCaretRange.selectNodeContents(body);\n preCaretRange.setEnd(range.endContainer, range.endOffset);\n\n const fragment = preCaretRange.cloneContents();\n const tempDiv = document.createElement('div');\n tempDiv.appendChild(fragment);\n let textBeforeCursor = tempDiv.innerText || '';\n\n const endContainer = range.endContainer;\n const endOffset = range.endOffset;\n\n if (endOffset === 0 &&\n endContainer.nodeType === Node.ELEMENT_NODE &&\n editor.dom.isBlock(endContainer) &&\n endContainer.previousSibling) {\n textBeforeCursor += '\\n';\n }\n const blockElements = tempDiv.querySelectorAll('p, div, h1, h2, h3, h4, h5, h6, li');\n let emptyBlockCount = 0;\n blockElements.forEach(block => {\n const text = block.innerText || block.textContent || '';\n if (text.trim() === '' && block.childNodes.length === 1 &&\n block.childNodes[0].nodeName === 'BR') {\n emptyBlockCount++;\n }\n });\n\n // Add newlines for empty blocks (these represent Enter presses that created empty lines)\n if (emptyBlockCount > 0) {\n textBeforeCursor += '\\n'.repeat(emptyBlockCount);\n }\n\n const absolutePosition = textBeforeCursor.length;\n\n if (skip) {\n return {\n caretPosition: lastCaretPos,\n rePosition: absolutePosition\n };\n }\n // Increment sequential caretPosition\n const storageKey = `${userid}_${resourceId}_${cmid}_position`;\n let storedPos = parseInt(sessionStorage.getItem(storageKey), 10);\n if (isNaN(storedPos)) {\n storedPos = 0;\n }\n storedPos++;\n lastCaretPos = storedPos;\n sessionStorage.setItem(storageKey, storedPos);\n\n return {\n caretPosition: storedPos,\n rePosition: absolutePosition\n };\n\n } catch (e) {\n window.console.warn('Error getting caret position:', e);\n return {caretPosition: lastCaretPos || 1, rePosition: 0};\n }\n }\n\n\n /**\n * Synchronizes data from localStorage to server\n * @async\n * @function SyncData\n * @description Retrieves stored keypress data from localStorage and sends it to server\n * @returns {Promise} Returns response from server if data exists and is successfully sent\n * @throws {Error} Logs error to console if data submission fails\n */\n async function syncData() {\n\n let data = localStorage.getItem(filename);\n\n if (!data || data.length === 0) {\n return;\n } else {\n localStorage.removeItem(filename);\n let originalText = editor.getContent({format: 'text'});\n try {\n Autosave.updateSavingState('saving');\n // eslint-disable-next-line\n return await postOne('cursive_write_local_to_json', {\n key: ed.key,\n event: event,\n keyCode: ed.keyCode,\n resourceId: resourceId,\n cmid: cmid,\n modulename: modulename,\n editorid: editorid,\n \"json_data\": data,\n originalText: originalText\n });\n } catch (error) {\n window.console.error('Error submitting data:', error);\n }\n }\n }\n /**\n * Sets up custom tooltip functionality for the Cursive icon\n * Initializes tooltip text, positions the icon in the menubar,\n * and sets up mouse event handlers for showing/hiding the tooltip\n * @function customTooltip\n */\n function customTooltip() {\n try {\n const tooltipText = getTooltipText();\n const menubarDiv = document.querySelectorAll('div[role=\"menubar\"].tox-menubar');\n let classArray = [];\n\n if (menubarDiv.length) {\n menubarDiv.forEach(function(element, index) {\n index += 1;\n let className = 'cursive-menu-' + index;\n element.classList.add(className);\n classArray.push(className);\n });\n }\n\n const cursiveIcon = document.createElement('img');\n cursiveIcon.src = hasApiKey ? iconUrl : iconGrayUrl;\n\n cursiveIcon.setAttribute('class', 'tiny_cursive_StateButton');\n cursiveIcon.style.display = 'inline-block';\n\n cursiveState(cursiveIcon, menubarDiv, classArray);\n\n for (let index in classArray) {\n const elementId = \"tiny_cursive_StateIcon\" + index;\n const tooltipId = `tiny_cursive_tooltip${index}`;\n\n tooltipText.then((text) => {\n return setTooltip(text, document.querySelector(`#${elementId}`), tooltipId);\n }).catch(error => window.console.error(error));\n\n $(`#${elementId}`).on('mouseenter', function() {\n $(this).css('position', 'relative');\n $(`#${tooltipId}`).css(tooltipCss);\n });\n\n $(`#${elementId}`).on('mouseleave', function() {\n $(`#${tooltipId}`).css('display', 'none');\n });\n }\n } catch (error) {\n window.console.error('Error setting up custom tooltip:', error);\n }\n }\n\n /**\n * Retrieves tooltip text strings from language files\n * @async\n * @function getTooltipText\n * @returns {Promise} Object containing buttonTitle and buttonDes strings\n */\n async function getTooltipText() {\n const [\n buttonTitle,\n buttonDes,\n ] = await Promise.all([\n getString('cursive:state:active', 'tiny_cursive'),\n getString('cursive:state:active:des', 'tiny_cursive'),\n ]);\n return {buttonTitle, buttonDes};\n }\n\n /**\n * Updates the Cursive icon state and positions it in the menubar\n * @param {HTMLElement} cursiveIcon - The Cursive icon element to modify\n * @param {HTMLElement} menubarDiv - The menubar div element\n * @param {Array} classArray - Array of class names for the menubar div elements\n */\n function cursiveState(cursiveIcon, menubarDiv, classArray) {\n if (!menubarDiv) {\n return;\n }\n\n for (let index in classArray) {\n const rightWrapper = document.createElement('div');\n const imgWrapper = document.createElement('span');\n const iconClone = cursiveIcon.cloneNode(true);\n const targetMenu = document.querySelector('.' + classArray[index]);\n let elementId = \"tiny_cursive_StateIcon\" + index;\n\n rightWrapper.style.cssText = `\n margin-left: auto;\n display: flex;\n align-items: center;\n `;\n\n imgWrapper.id = elementId;\n imgWrapper.style.marginLeft = '.2rem';\n imgWrapper.appendChild(iconClone);\n rightWrapper.appendChild(imgWrapper);\n\n let moduleIds = {\n resourceId: resourceId,\n cmid: cmid,\n modulename: modulename,\n questionid: questionid,\n userid: userid,\n courseid: courseid};\n // Document mode, other modules single editor instances\n if (isFullScreen && (modulename === 'assign' || modulename === 'forum'\n || modulename === 'lesson')) {\n let existsElement = document.querySelector('.tox-menubar[class*=\"cursive-menu-\"] > div');\n if (existsElement) {\n existsElement.remove();\n }\n\n if (!document.querySelector(`#${elementId}`)) {\n rightWrapper.style.marginTop = '3px';\n document.querySelector('#tiny_cursive-fullpage-right-wrapper').prepend(rightWrapper);\n }\n\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n } else if (isFullScreen && modulename === 'quiz') { // Document mode, quiz multiple editor instances\n let existingElement = editor.container?.childNodes[1]?.childNodes[0]?.childNodes[0]?.childNodes[7];\n let newHeader = editor.container?.childNodes[0];\n if (existingElement) {\n existingElement.remove();\n }\n\n if (newHeader && !newHeader.querySelector(`span[id*=tiny_cursive_StateIcon]`)) {\n rightWrapper.style.marginTop = '3px';\n document.querySelector('#tiny_cursive-fullpage-right-wrapper').prepend(rightWrapper);\n }\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n } else { // Regular view\n let menubar = editor?.container?.children[0]?.childNodes[0]?.childNodes[0];\n\n if (targetMenu && !targetMenu.querySelector(`#${elementId}`)) {\n targetMenu.appendChild(rightWrapper);\n }\n // Regular view, multiple editor instances\n if (modulename === 'quiz' && menubar) {\n let wrapper = menubar.querySelector('span[id*=\"tiny_cursive_StateIcon\"]');\n\n if (wrapper) {\n Autosave.destroyInstance();\n Autosave.getInstance(editor, wrapper?.parentElement, moduleIds, isFullScreen);\n }\n } else {\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n }\n }\n }\n }\n\n /**\n * Sets up tooltip content and styling for the Cursive icon\n * @param {Object} text - Object containing tooltip text strings\n * @param {string} text.buttonTitle - Title text for the tooltip\n * @param {string} text.buttonDes - Description text for the tooltip\n * @param {HTMLElement} cursiveIcon - The Cursive icon element to attach tooltip to\n * @param {string} tooltipId - ID for the tooltip element\n */\n function setTooltip(text, cursiveIcon, tooltipId) {\n\n if (document.querySelector(`#${tooltipId}`)) {\n return;\n }\n if (cursiveIcon) {\n\n const tooltipSpan = document.createElement('span');\n const description = document.createElement('span');\n const linebreak = document.createElement('br');\n const tooltipTitle = document.createElement('strong');\n\n tooltipSpan.style.display = 'none';\n tooltipTitle.textContent = text.buttonTitle;\n tooltipTitle.style.fontSize = '16px';\n tooltipTitle.style.fontWeight = 'bold';\n description.textContent = text.buttonDes;\n description.style.fontSize = '14px';\n\n tooltipSpan.id = tooltipId;\n tooltipSpan.classList.add(`shadow`);\n tooltipSpan.appendChild(tooltipTitle);\n tooltipSpan.appendChild(linebreak);\n tooltipSpan.appendChild(description);\n cursiveIcon.appendChild(tooltipSpan);\n }\n }\n\n /**\n * Extracts module information from URL parameters\n * @param {string} ur - The base URL to analyze\n * @param {URL} parm - URL object containing search parameters\n * @param {Array} MODULES - Array of valid module names to check against\n * @returns {Object|boolean} Object containing resourceId and module name if found, false if no valid module\n */\n function getModulesInfo(ur, parm, MODULES) {\n fetchStrings();\n if (!MODULES.some(module => ur.includes(module))) {\n return false;\n }\n\n if (ur.includes(\"forum\") && !ur.includes(\"assign\")) {\n resourceId = parm.searchParams.get('edit');\n } else {\n resourceId = parm.searchParams.get('attempt');\n }\n\n if (resourceId === null) {\n resourceId = 0;\n }\n\n for (const module of MODULES) {\n if (ur.includes(module)) {\n modulename = module;\n if (module === \"lesson\" || module === \"assign\") {\n resourceId = cmid;\n } else if (module === \"oublog\") {\n resourceId = 0;\n }\n break;\n }\n }\n\n return {resourceId: resourceId, name: modulename};\n }\n\n /**\n * Fetches and caches localized strings used in the UI\n * @function fetchStrings\n * @description Retrieves strings for sidebar titles and document sidebar elements if not already cached in localStorage\n * Uses Promise.all to fetch multiple strings in parallel for better performance\n * Stores the fetched strings in localStorage under 'sbTitle' and 'docSideBar' keys\n */\n function fetchStrings() {\n if (!localStorage.getItem('sbTitle')) {\n Promise.all([\n getString('assignment', 'tiny_cursive'),\n getString('discussion', 'tiny_cursive'),\n getString('pluginname', 'mod_quiz'),\n getString('pluginname', 'mod_lesson'),\n getString('description', 'tiny_cursive'),\n ]).then(function(strings) {\n return localStorage.setItem('sbTitle', JSON.stringify(strings));\n }).catch(error => window.console.error(error));\n }\n if (!localStorage.getItem('docSideBar')) {\n Promise.all([\n getString('details', 'tiny_cursive'),\n getString('student_info', 'tiny_cursive'),\n getString('progress', 'tiny_cursive'),\n getString('description', 'tiny_cursive'),\n getString('replyingto', 'tiny_cursive'),\n getString('answeringto', 'tiny_cursive'),\n getString('importantdates', 'tiny_cursive'),\n getString('rubrics', 'tiny_cursive'),\n getString('submission_status', 'tiny_cursive'),\n getString('status', 'tiny_cursive'),\n getString('draft', 'tiny_cursive'),\n getString('draftnot', 'tiny_cursive'),\n getString('last_modified', 'tiny_cursive'),\n getString('gradings', 'tiny_cursive'),\n getString('gradenot', 'tiny_cursive'),\n getString('word_count', 'tiny_cursive'),\n getString('timeleft', 'tiny_cursive'),\n getString('nolimit', 'tiny_cursive'),\n getString('name', 'tiny_cursive'),\n getString('userename', 'tiny_cursive'),\n getString('course', 'tiny_cursive'),\n getString('opened', 'tiny_cursive'),\n getString('due', 'tiny_cursive'),\n getString('overdue', 'tiny_cursive'),\n getString('remaining', 'tiny_cursive'),\n getString('savechanges', 'tiny_cursive'),\n getString('subjectnot', 'tiny_cursive'),\n getString('remaining', 'tiny_cursive'),\n ]).then(function(strings) {\n return localStorage.setItem('docSideBar', JSON.stringify(strings));\n }).catch(error => window.console.error(error));\n }\n\n }\n\n window.addEventListener('unload', () => {\n syncData();\n });\n\n setInterval(syncData, syncInterval);\n};\n"],"names":["editor","interval","userId","hasApiKey","MODULES","Rubrics","submission","quizInfo","pasteSetting","isStudent","hasClass","intervention","host","M","cfg","wwwroot","userid","courseid","courseId","editorid","id","cmid","contextInstanceId","ed","event","filename","questionid","quizSubmit","assignSubmit","syncInterval","lastCaretPos","aiContents","isFullScreen","user","ur","window","location","href","modulesInfo","parm","localStorage","getItem","Promise","all","then","strings","setItem","JSON","stringify","catch","error","console","fetchStrings","some","module","includes","resourceId","searchParams","get","modulename","name","getModulesInfo","URL","errorAlert","PASTE_SETTING","shouldBlockPaste","isPasteAllowed","postOne","async","methodname","args","response","setTimeout","updateSavingState","field","values","done","fail","ex","on","e","preventDefault","syncData","off","click","removeItem","getModal","title","titledes","placeholder","type","body","removeOnClose","modal","getRoot","addClass","show","lastEvent","save","number","document","getElementById","value","trim","execCommand","str","alert","resourceid","usercomment","timemodified","Date","now","destroy","cancel","hidden","sendKeyEvent","events","split","data","parse","push","key","keyCode","unixTimestamp","clientId","personId","position","caretPosition","rePosition","pastedContent","aiContent","constructMouseEvent","getCaretPosition","button","getMouseButton","skip","selection","range","getRng","getBody","preCaretRange","cloneRange","selectNodeContents","setEnd","endContainer","endOffset","fragment","cloneContents","tempDiv","createElement","appendChild","textBeforeCursor","innerText","nodeType","Node","ELEMENT_NODE","dom","isBlock","previousSibling","blockElements","querySelectorAll","emptyBlockCount","forEach","block","textContent","childNodes","length","nodeName","repeat","absolutePosition","storageKey","storedPos","parseInt","sessionStorage","isNaN","warn","originalText","getContent","format","customTooltip","tooltipText","buttonTitle","buttonDes","getTooltipText","menubarDiv","classArray","element","index","className","classList","add","cursiveIcon","src","iconUrl","iconGrayUrl","setAttribute","style","display","rightWrapper","imgWrapper","iconClone","cloneNode","targetMenu","querySelector","elementId","cssText","marginLeft","moduleIds","existingElement","container","_editor$container","_editor$container$chi","_editor$container$chi2","_editor$container$chi3","newHeader","_editor$container2","remove","marginTop","prepend","destroyInstance","getInstance","menubar","_editor$container3","children","_editor$container3$ch","_editor$container3$ch2","wrapper","parentElement","existsElement","cursiveState","tooltipId","text","setTooltip","this","css","tooltipCss","tooltipSpan","description","linebreak","tooltipTitle","fontSize","fontWeight","clipboardData","originalEvent","getData","trimmedPastedContent","lastCopyCutContent","isFromOwnEditor","stopPropagation","stopImmediatePropagation","windowManager","ctrlKey","metaKey","selectedContent","view","DocumentView","state","fullPageMode","normalMode","command","contentObj","isPaste","paste","insertedContent","content","innerHTML","pastedText","undoManager","undo","srcElement","baseURI","inputType","addEventListener","setInterval"],"mappings":"ooBAgCwB,CAACA,OAAQC,SAAUC,OAAQC,UAAWC,QAASC,QAASC,WAAYC,SAAUC,oBAE9FC,YAAc,mBAAE,SAASC,SAAS,iBAClCC,cAAe,mBAAE,SAASD,SAAS,gBACnCE,KAAOC,EAAEC,IAAIC,QACbC,OAASd,OACTe,SAAWJ,EAAEC,IAAII,SACjBC,SAAWnB,MAAAA,cAAAA,OAAQoB,GACnBC,KAAOR,EAAEC,IAAIQ,kBACbC,GAAK,GACLC,MAAQ,GACRC,SAAW,GACXC,WAAa,EACbC,YAAa,mBAAE,0BACfC,cAAe,mBAAE,wBACjBC,aAAe5B,SAAsB,IAAXA,SAAkB,IAC5C6B,aAAe,MACfC,WAAa,OACbC,cAAe,EACfC,KAAO,SACPC,GAAKC,OAAOC,SAASC,KAErBC,qBA6sBoBJ,GAAIK,KAAMnC,uBAuCzBoC,aAAaC,QAAQ,YACtBC,QAAQC,IAAI,EACR,mBAAU,aAAc,iBACxB,mBAAU,aAAc,iBACxB,mBAAU,aAAc,aACxB,mBAAU,aAAc,eACxB,mBAAU,cAAe,kBAC1BC,MAAK,SAASC,gBACNL,aAAaM,QAAQ,UAAWC,KAAKC,UAAUH,aACvDI,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,SAEtCV,aAAaC,QAAQ,eACtBC,QAAQC,IAAI,EACR,mBAAU,UAAW,iBACrB,mBAAU,eAAgB,iBAC1B,mBAAU,WAAY,iBACtB,mBAAU,cAAe,iBACzB,mBAAU,aAAc,iBACxB,mBAAU,cAAe,iBACzB,mBAAU,iBAAkB,iBAC5B,mBAAU,UAAW,iBACrB,mBAAU,oBAAqB,iBAC/B,mBAAU,SAAU,iBACpB,mBAAU,QAAS,iBACnB,mBAAU,WAAY,iBACtB,mBAAU,gBAAiB,iBAC3B,mBAAU,WAAY,iBACtB,mBAAU,WAAY,iBACtB,mBAAU,aAAc,iBACxB,mBAAU,WAAY,iBACtB,mBAAU,UAAW,iBACrB,mBAAU,OAAQ,iBAClB,mBAAU,YAAa,iBACvB,mBAAU,SAAU,iBACpB,mBAAU,SAAU,iBACpB,mBAAU,MAAO,iBACjB,mBAAU,UAAW,iBACrB,mBAAU,YAAa,iBACvB,mBAAU,cAAe,iBACzB,mBAAU,aAAc,iBACxB,mBAAU,YAAa,kBACxBC,MAAK,SAASC,gBACNL,aAAaM,QAAQ,aAAcC,KAAKC,UAAUH,aAC1DI,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,SAjF3CE,IACKhD,QAAQiD,MAAKC,QAAUpB,GAAGqB,SAASD,iBAC7B,EAIPE,WADAtB,GAAGqB,SAAS,WAAarB,GAAGqB,SAAS,UACxBhB,KAAKkB,aAAaC,IAAI,QAEtBnB,KAAKkB,aAAaC,IAAI,WAGpB,OAAfF,aACAA,WAAa,OAGZ,MAAMF,UAAUlD,WACb8B,GAAGqB,SAASD,QAAS,CACrBK,WAAaL,OACE,WAAXA,QAAkC,WAAXA,OACvBE,WAAanC,KACK,WAAXiC,SACPE,WAAa,eAMlB,CAACA,WAAYA,WAAYI,KAAMD,YAzuBxBE,CAAe3B,GADtB,IAAI4B,IAAI5B,IACwB9B,aACvCoD,WAAalB,YAAYkB,WACzBG,WAAarB,YAAYsB,KACzBG,YAAa,MACbC,cAAgBxD,cAAgB,QAChCyD,kBAAmB,EACnBC,gBAAiB,EAEF,WAAfP,aACAK,cAAgB,qBAEdG,QAAUC,MAAMC,WAAYC,kBAEpBC,eAAiB,cAAK,CAAC,CACzBF,WAAAA,WACAC,KAAAA,QACA,UACAC,UACAC,YAAW,+BACEC,kBAAkB,WAC5B,KAEAF,SACT,MAAOrB,uCACIuB,kBAAkB,WAC3BtC,OAAOgB,QAAQD,MAAM,oBAAqBA,OACpCA,uBAIN,CAAC,CACDmB,WAAY,+BACZC,KAAM,CAACI,MAAO,KAAMC,OAAQ,CAAC9D,EAAEC,IAAIZ,YACnC,GAAG0E,MAAKL,WACRtC,KAAOsC,SAAS,MACjBM,MAAMC,KACL3C,OAAOgB,QAAQD,MAAM,4BAA6B4B,OAG1DlD,aAAamD,GAAG,SAASX,eAAeY,GACpCA,EAAEC,iBACExD,SAEAyD,WAAWtC,MAAK,KACZhB,aAAauD,IAAI,SAASC,WAG9BxD,aAAauD,IAAI,SAASC,QAE9B5C,aAAa6C,WAAW,yBAG5B1D,WAAWoD,GAAG,SAASX,eAAeY,GAClCA,EAAEC,iBACExD,SAEAyD,WAAWtC,MAAK,KACZjB,WAAWwD,IAAI,SAASC,WAG5BzD,WAAWwD,IAAI,SAASC,QAE5B5C,aAAa6C,WAAW,+BAGtBC,SAAW,KAEb5C,QAAQC,IAAI,EACR,mBAAU,sBAAuB,iBACjC,mBAAU,0BAA2B,iBACrC,mBAAU,2BAA4B,kBACvCC,MAAK,mBAAU2C,MAAOC,SAAUC,yBAExB,yBAAO,CACVC,KAAM,cACNH,MAAQ,6CAA4CA,8EACJC,wBAChDG,KAAO,gFAA+EF,2BACtFG,eAAe,IAEdhB,MAAKiB,QACFA,MAAMC,UAAUC,SAAS,sBACzBF,MAAMG,WACFC,UAAY,UAEhBJ,MAAMC,UAAUf,GAAGmB,oBAAM,eAEjBC,OAASC,SAASC,eAAe,YAAYC,MAAMC,OAExC,KAAXJ,QAAAA,MAAiBA,QACjBnG,OAAOwG,YAAY,4BAET,eAAgB,gBAAgB5D,MAAK6D,KAAOC,MAAMD,QAE5DzG,OAAOwG,YAAY,SAGvBrC,QAAQ,wBAAyB,CAC7BR,WAAYA,WACZtC,KAAMA,KACNsF,WAAYnD,WACZvC,SAAUA,SACV2F,YAAaT,OACbU,aAAcC,KAAKC,MACnB5F,SAAUA,UAAsB,KAGpC8E,UAAY,OACZJ,MAAMmB,aAEVnB,MAAMC,UAAUf,GAAGkC,sBAAQ,WACvBjH,OAAOwG,YAAY,QACnBP,UAAY,YAGhBJ,MAAMC,UAAUf,GAAGmC,sBAAQ,WACN,UAAbjB,WAAsC,QAAbA,WACzBjG,OAAOwG,YAAY,WAGpBX,YAEhB5C,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,UAIrCiE,aAAe,CAACC,OAAQpH,aAC1BuB,GAAKvB,OACLwB,MAAQ4F,OAER3F,SAAY,GAAET,UAAUwC,cAAcnC,QAAQsC,qBAE3B,SAAfA,aACAjC,WAAaP,SAASkG,MAAM,KAAK,GAAGA,MAAM,KAAK,GAC/C5F,SAAY,GAAET,UAAUwC,cAAcnC,QAAQK,cAAciC,sBAG5DnB,aAAaC,QAAQhB,UAAW,KAC5B6F,KAAOvE,KAAKwE,MAAM/E,aAAaC,QAAQhB,WAC3C6F,KAAKE,KAAK,CACNhE,WAAYA,WACZiE,IAAKzH,OAAOyH,IACZC,QAAS1H,OAAO0H,QAChBlG,MAAOA,MACPN,SAAUD,SACV0G,cAAeb,KAAKC,MACpBa,SAAUhH,KACViH,SAAU7G,OACV8G,SAAUvG,GAAGwG,cACbC,WAAYzG,GAAGyG,WACfC,cAAejI,OAAOiI,cACtBC,UAAWlI,OAAOkI,YAEtB1F,aAAaM,QAAQrB,SAAUsB,KAAKC,UAAUsE,WAC3C,KACCA,KAAO,CAAC,CACR9D,WAAYA,WACZiE,IAAKzH,OAAOyH,IACZC,QAAS1H,OAAO0H,QAChBlG,MAAOA,MACPN,SAAUD,SACV0G,cAAeb,KAAKC,MACpBa,SAAUhH,KACViH,SAAU7G,OACV8G,SAAUvG,GAAGwG,cACbC,WAAYzG,GAAGyG,WACfC,cAAejI,OAAOiI,cACtBC,UAAWlI,OAAOkI,YAEtB1F,aAAaM,QAAQrB,SAAUsB,KAAKC,UAAUsE,kBAgN7Ca,oBAAoBnI,YACrB8H,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7BhI,OAAOyH,aASazH,eAEZA,OAAOqI,aACN,QACM,YACN,QACM,cACN,QACM,eAER,KAnBMC,CAAetI,QAC5BA,OAAO0H,QAAU1H,OAAOqI,gBA6BnBD,uBAAiBG,qEAEfvI,SAAWA,OAAOwI,gBACd,CAACT,cAAe,EAAGC,WAAY,SAGlCS,MAAQzI,OAAOwI,UAAUE,SACzB/C,KAAO3F,OAAO2I,UAGdC,cAAgBH,MAAMI,aAC5BD,cAAcE,mBAAmBnD,MACjCiD,cAAcG,OAAON,MAAMO,aAAcP,MAAMQ,iBAEzCC,SAAWN,cAAcO,gBACzBC,QAAUhD,SAASiD,cAAc,OACvCD,QAAQE,YAAYJ,cAChBK,iBAAmBH,QAAQI,WAAa,SAEtCR,aAAeP,MAAMO,aAGT,IAFAP,MAAMQ,WAGpBD,aAAaS,WAAaC,KAAKC,cAC/B3J,OAAO4J,IAAIC,QAAQb,eACnBA,aAAac,kBACbP,kBAAoB,YAElBQ,cAAgBX,QAAQY,iBAAiB,0CAC3CC,gBAAkB,EACtBF,cAAcG,SAAQC,QAEA,MADPA,MAAMX,WAAaW,MAAMC,aAAe,IAC5C7D,QAA6C,IAA5B4D,MAAME,WAAWC,QACN,OAAjCH,MAAME,WAAW,GAAGE,UACtBN,qBAKAA,gBAAkB,IACpBV,kBAAoB,KAAKiB,OAAOP,wBAG5BQ,iBAAmBlB,iBAAiBe,UAEtC/B,WACK,CACLR,cAAejG,aACfkG,WAAYyC,wBAIVC,WAAc,GAAE1J,UAAUwC,cAAcnC,oBAC1CsJ,UAAYC,SAASC,eAAepI,QAAQiI,YAAa,WACzDI,MAAMH,aACRA,UAAY,GAEdA,YACA7I,aAAe6I,UACfE,eAAe/H,QAAQ4H,WAAYC,WAE5B,CACL5C,cAAe4C,UACf3C,WAAYyC,kBAGd,MAAOzF,UACL7C,OAAOgB,QAAQ4H,KAAK,gCAAiC/F,GAC9C,CAAC+C,cAAejG,cAAgB,EAAGkG,WAAY,mBAa/C9C,eAEPoC,KAAO9E,aAAaC,QAAQhB,aAE3B6F,MAAwB,IAAhBA,KAAKgD,OAEX,CACH9H,aAAa6C,WAAW5D,cACpBuJ,aAAehL,OAAOiL,WAAW,CAACC,OAAQ,8CAEjCzG,kBAAkB,gBAEdN,QAAQ,8BAA+B,CAChDsD,IAAKlG,GAAGkG,IACRjG,MAAOA,MACPkG,QAASnG,GAAGmG,QACZlE,WAAYA,WACZnC,KAAMA,KACNsC,WAAYA,WACZxC,SAAUA,mBACGmG,KACb0D,aAAcA,eAEpB,MAAO9H,OACLf,OAAOgB,QAAQD,MAAM,yBAA0BA,kBAUlDiI,0BAEKC,mCAmDNC,YACAC,iBACM5I,QAAQC,IAAI,EAClB,mBAAU,uBAAwB,iBAClC,mBAAU,2BAA4B,wBAEnC,CAAC0I,YAAAA,YAAaC,UAAAA,WAzDGC,GACdC,WAAapF,SAAS4D,iBAAiB,uCACzCyB,WAAa,GAEbD,WAAWlB,QACXkB,WAAWtB,SAAQ,SAASwB,QAASC,WAE7BC,UAAY,iBADhBD,OAAS,GAETD,QAAQG,UAAUC,IAAIF,WACtBH,WAAWjE,KAAKoE,oBAIlBG,YAAc3F,SAASiD,cAAc,OAC3C0C,YAAYC,IAAM7L,UAAY8L,gBAAUC,oBAExCH,YAAYI,aAAa,QAAS,4BAClCJ,YAAYK,MAAMC,QAAU,wBAiDdN,YAAaP,WAAYC,gBACtCD,sBAIA,IAAIG,SAASF,WAAY,OACpBa,aAAelG,SAASiD,cAAc,OACtCkD,WAAanG,SAASiD,cAAc,QACpCmD,UAAYT,YAAYU,WAAU,GAClCC,WAAatG,SAASuG,cAAc,IAAMlB,WAAWE,YACvDiB,UAAY,yBAA2BjB,MAE3CW,aAAaF,MAAMS,QAAW,2JAM9BN,WAAWnL,GAAKwL,UAChBL,WAAWH,MAAMU,WAAa,QAC9BP,WAAWjD,YAAYkD,WACvBF,aAAahD,YAAYiD,gBAErBQ,UAAY,CACZvJ,WAAYA,WACZnC,KAAMA,KACNsC,WAAYA,WACZjC,WAAYA,WACZV,OAAQA,OACRC,SAAUA,cAEVe,cAAgC,WAAf2B,YAA0C,UAAfA,YAC1B,WAAfA,WAaA,GAAI3B,cAA+B,SAAf2B,WAAuB,kHAC1CqJ,0CAAkBhN,OAAOiN,sEAAPC,kBAAkB7C,WAAW,oEAA7B8C,sBAAiC9C,WAAW,qEAA5C+C,uBAAgD/C,WAAW,4CAA3DgD,uBAA+DhD,WAAW,GAC5FiD,qCAAYtN,OAAOiN,+CAAPM,mBAAkBlD,WAAW,GACzC2C,iBACAA,gBAAgBQ,SAGhBF,YAAcA,UAAUX,cAAe,sCACvCL,aAAaF,MAAMqB,UAAY,MAC/BrH,SAASuG,cAAc,wCAAwCe,QAAQpB,yCAElEqB,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,kBACnD,yEACC6L,QAAU7N,MAAAA,mCAAAA,OAAQiN,uEAARa,mBAAmBC,SAAS,oEAA5BC,sBAAgC3D,WAAW,4CAA3C4D,uBAA+C5D,WAAW,MAEpEqC,aAAeA,WAAWC,cAAe,IAAGC,cAC5CF,WAAWpD,YAAYgD,cAGR,SAAf3I,YAAyBkK,QAAS,KAC9BK,QAAUL,QAAQlB,cAAc,sCAEhCuB,oCACSP,4CACAC,YAAY5N,OAAQkO,MAAAA,eAAAA,QAASC,cAAepB,UAAW/K,8CAG3D2L,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,kBA1C7B,KACzBoM,cAAgBhI,SAASuG,cAAc,8CACvCyB,eACAA,cAAcZ,SAGbpH,SAASuG,cAAe,IAAGC,eAC5BN,aAAaF,MAAMqB,UAAY,MAC/BrH,SAASuG,cAAc,wCAAwCe,QAAQpB,yCAGlEqB,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,gBA3F1DqM,CAAatC,YAAaP,WAAYC,gBAEjC,IAAIE,SAASF,WAAY,OACpBmB,UAAY,yBAA2BjB,MACvC2C,UAAa,uBAAsB3C,QAEzCP,YAAYxI,MAAM2L,MACPC,WAAWD,KAAMnI,SAASuG,cAAe,IAAGC,aAAc0B,aAClErL,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,6BAEpC,IAAG0J,aAAa7H,GAAG,cAAc,+BAC9B0J,MAAMC,IAAI,WAAY,gCACrB,IAAGJ,aAAaI,IAAIC,2CAGxB,IAAG/B,aAAa7H,GAAG,cAAc,+BAC7B,IAAGuJ,aAAaI,IAAI,UAAW,YAG5C,MAAOxL,OACLf,OAAOgB,QAAQD,MAAM,mCAAoCA,iBAmHxDsL,WAAWD,KAAMxC,YAAauC,eAE/BlI,SAASuG,cAAe,IAAG2B,cAG3BvC,YAAa,OAEP6C,YAAcxI,SAASiD,cAAc,QACrCwF,YAAczI,SAASiD,cAAc,QACrCyF,UAAY1I,SAASiD,cAAc,MACnC0F,aAAe3I,SAASiD,cAAc,UAE5CuF,YAAYxC,MAAMC,QAAU,OAC5B0C,aAAa3E,YAAcmE,KAAKlD,YAChC0D,aAAa3C,MAAM4C,SAAW,OAC9BD,aAAa3C,MAAM6C,WAAa,OAChCJ,YAAYzE,YAAcmE,KAAKjD,UAC/BuD,YAAYzC,MAAM4C,SAAW,OAE7BJ,YAAYxN,GAAKkN,UACjBM,YAAY/C,UAAUC,IAAK,UAC3B8C,YAAYtF,YAAYyF,cACxBH,YAAYtF,YAAYwF,WACxBF,YAAYtF,YAAYuF,aACxB9C,YAAYzC,YAAYsF,cArhBhC5O,OAAO+E,GAAG,SAAU/E,SAChBmL,oBACIrD,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7Bb,aAAa,QAASnH,WAE1BA,OAAO+E,GAAG,SAASX,MAAAA,IACf+G,sBACMlD,eAAiBjD,EAAEkK,eAAiBlK,EAAEmK,cAAcD,eAAeE,QAAQ,YAC5EnH,2BAICoH,qBAAuBpH,cAAc1B,OACrC+I,mBAAqB9M,aAAaC,QAAQ,sBAC1C8M,gBAAkBD,oBAAsBD,uBAAyBC,sBAEnE7O,WAAaE,aAAc,IAEL,UAAlBqD,qBACKuL,iBAeLtL,kBAAmB,OACnBC,gBAAiB,KAfbc,EAAEC,iBACFhB,kBAAmB,EACnBC,gBAAiB,EACjBc,EAAEwK,kBACFxK,EAAEyK,+CACQ,gBAAiB,gBAAgB7M,MAAK6D,KACtCzG,OAAO0P,cAAchJ,MAAMD,OAClCxD,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,cACvCsB,YAAW,KACPN,gBAAiB,EACjBD,kBAAmB,IACpB,SAOW,gBAAlBD,qBACKuL,kBACDvK,EAAEC,iBACFD,EAAEwK,kBACFxK,EAAEyK,2BACFnK,iBAEJpB,gBAAiB,GAIzBA,gBAAiB,KAErBlE,OAAO+E,GAAG,QAAQX,MAAAA,IACd+G,gBACI1K,WAAaE,cACb2E,cAGRtF,OAAO+E,GAAG,WAAY/E,SAClBmL,oBACuC,MAAfnL,OAAOyH,KAA8B,MAAfzH,OAAOyH,OACpDzH,OAAO2P,SAAW3P,OAAO4P,UACJnP,WAAaE,cAAkC,UAAlBqD,gBAA8BE,2BAC7EM,YAAW,KACPN,gBAAiB,IAClB,SAGH4D,SAAWM,mBACfpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7Bb,aAAa,UAAWnH,WAE3BA,OAAO+E,GAAG,OAAO,WACR8K,gBAAkB7P,OAAOwI,UAAUyC,WAAW,CAACC,OAAQ,SAC7D1I,aAAaM,QAAQ,qBAAsB+M,gBAAgBtJ,WAE/DvG,OAAO+E,GAAG,QAAQ,WACR8K,gBAAkB7P,OAAOwI,UAAUyC,WAAW,CAACC,OAAQ,SAC7D1I,aAAaM,QAAQ,qBAAsB+M,gBAAgBtJ,WAE/DvG,OAAO+E,GAAG,aAAaX,MAAAA,SACnBI,YAAW,KACP2D,oBAAoBnI,QACpBmH,aAAa,YAAanH,UAC3B,MAEPA,OAAO+E,GAAG,WAAWX,MAAAA,SACjBI,YAAW,KACP2D,oBAAoBnI,QACpBmH,aAAa,UAAWnH,UACzB,OAEPA,OAAO+E,GAAG,QAAQ,KACdoG,gBACA3I,aAAa6C,WAAW,yBAE5BrF,OAAO+E,GAAG,cAAc,KACpBoG,mBAEJnL,OAAO+E,GAAG,0BAA2BC,QAC7B8K,KAAO,IAAIC,uBAAa9N,KAAM5B,QAASC,WAAYqD,WAAY3D,OAAQO,UAC3EyB,aAAegD,EAAEgL,UAERhL,EAAEgL,MAGHF,KAAKG,eAFLH,KAAKI,aAIX,MAAOhN,OACDa,aACAA,YAAa,sBACH,gBAAiB,gBAAgBnB,MAAK6D,KACrCzG,OAAO0P,cAAchJ,MAAMD,OACnCxD,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,UAE3C4M,KAAKI,aACL/N,OAAOgB,QAAQD,MAAM,4BAA6BA,WAI1DlD,OAAO+E,GAAG,eAAe,SAASC,MACZ,qBAAdA,EAAEmL,QAAgC,OAC5BC,WAAapL,EAAEsB,MAEf+J,QAAUD,YAAoC,iBAAfA,aAAgD,IAArBA,WAAWE,UAEvEC,gBAAkBH,WAAWI,SAAWJ,WACxChH,QAAUhD,SAASiD,cAAc,OACrCD,QAAQqH,UAAYF,oBAChBhC,KAAOnF,QAAQgB,aAAehB,QAAQI,WAAa,GACnDkH,WAAatH,QAAQgB,aAAehB,QAAQI,WAAa,GAEzD1B,SAAWM,kBAAiB,MAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAEzBqI,QAAS,IACLpM,wBACAA,kBAAmB,EACnBe,EAAEC,sBACFjF,OAAO2Q,YAAYC,aAGjBtB,mBAAqB9M,aAAaC,QAAQ,sBAC1C8M,gBAAkBD,oBAAsBoB,WAAWnK,SAAW+I,sBAEhE7O,WAAaE,cAAkC,UAAlBqD,gBAA8BuL,uBAC3DrL,gBAAiB,OACjBlE,OAAO2Q,YAAYC,OAIvBzJ,aAAa,QAAS,CAClBM,IAAK,IACLC,QAAS,GACTK,cAAe/H,OAAO+H,cACtBC,WAAYhI,OAAOgI,WACnBC,cAAeyI,WACfG,WAAY,CAACC,QAAS3O,OAAOC,SAASC,aAG1CN,WAAWyF,KAAK+G,MAEhBpH,aAAa,WAAY,CACrBM,IAAK,KACLC,QAAS,EACTK,cAAe/H,OAAO+H,cACtBC,WAAYhI,OAAOgI,WACnBE,UAAWqG,KACXsC,WAAY,CAACC,QAAS3O,OAAOC,SAASC,YAMtDrC,OAAO+E,GAAG,SAAS,SAASC,OACpB8C,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,eACzBE,UAAYlD,EAAEsC,MAEE,0BAAhBtC,EAAE+L,WAA0D,eAAhB/L,EAAE+L,WAA8B7I,WAAaA,UAAUoC,OAAS,KAE5GvI,WAAWyF,KAAKU,WAEhBlD,EAAEyC,IAAM,KACRzC,EAAE0C,QAAU,EACZ1C,EAAE+C,cAAgBD,SAASC,cAC3B/C,EAAEgD,WAAaF,SAASE,WACxBhD,EAAEkD,UAAYA,UAEdf,aAAa,WAAYnC,OAsbjC7C,OAAO6O,iBAAiB,UAAU,KAC9B9L,cAGJ+L,YAAY/L,SAAUrD"} \ No newline at end of file +{"version":3,"file":"autosaver.min.js","sources":["../src/autosaver.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * @module tiny_cursive/autosaver\n * @category TinyMCE Editor\n * @copyright CTI \n * @author Brain Station 23 \n */\n\nimport {call} from 'core/ajax';\nimport {create} from 'core/modal_factory';\nimport {get_string as getString} from 'core/str';\nimport {save, cancel, hidden} from 'core/modal_events';\nimport $ from 'jquery';\nimport {iconUrl, iconGrayUrl, tooltipCss} from 'tiny_cursive/common';\nimport Autosave from 'tiny_cursive/cursive_autosave';\nimport DocumentView from 'tiny_cursive/document_view';\nimport {call as getUser} from \"core/ajax\";\n\nexport const register = (editor, interval, userId, hasApiKey, MODULES, Rubrics, submission, quizInfo, pasteSetting) => {\n\n var isStudent = !($('#body').hasClass('teacher_admin'));\n var intervention = $('#body').hasClass('intervention');\n var host = M.cfg.wwwroot;\n var userid = userId;\n var courseid = M.cfg.courseId;\n var editorid = editor?.id;\n var cmid = M.cfg.contextInstanceId;\n var ed = \"\";\n var event = \"\";\n var filename = \"\";\n var questionid = 0;\n var quizSubmit = $('#mod_quiz-next-nav');\n let assignSubmit = $('#id_submitbutton');\n var syncInterval = interval ? interval * 1000 : 10000; // Default: Sync Every 10s.\n var lastCaretPos = 1;\n let aiContents = [];\n var isFullScreen = false;\n var user = null;\n let ur = window.location.href;\n let parm = new URL(ur);\n let modulesInfo = getModulesInfo(ur, parm, MODULES);\n var resourceId = modulesInfo.resourceId;\n var modulename = modulesInfo.name;\n var errorAlert = true;\n let PASTE_SETTING = pasteSetting || 'allow';\n let shouldBlockPaste = false;\n let isPasteAllowed = false;\n\n if (modulename !== 'assign') {\n PASTE_SETTING = 'cite_source';\n }\n const postOne = async(methodname, args) => {\n try {\n const response = await call([{\n methodname,\n args,\n }])[0];\n if (response) {\n setTimeout(() => {\n Autosave.updateSavingState('saved');\n }, 1000);\n }\n return response;\n } catch (error) {\n Autosave.updateSavingState('offline');\n window.console.error('Error in postOne:', error);\n throw error;\n }\n };\n\n getUser([{\n methodname: 'core_user_get_users_by_field',\n args: {field: 'id', values: [userid]},\n }])[0].done(response => {\n user = response[0];\n }).fail((ex) => {\n window.console.error('Error fetching user data:', ex);\n });\n\n assignSubmit.on('click', async function(e) {\n e.preventDefault();\n if (filename) {\n // eslint-disable-next-line\n syncData().then(() => {\n assignSubmit.off('click').click();\n });\n } else {\n assignSubmit.off('click').click();\n }\n localStorage.removeItem('lastCopyCutContent');\n });\n\n quizSubmit.on('click', async function(e) {\n e.preventDefault();\n if (filename) {\n // eslint-disable-next-line\n syncData().then(() => {\n quizSubmit.off('click').click();\n });\n } else {\n quizSubmit.off('click').click();\n }\n localStorage.removeItem('lastCopyCutContent');\n });\n\n const getModal = () => {\n\n Promise.all([\n getString('tiny_cursive_srcurl', 'tiny_cursive'),\n getString('tiny_cursive_srcurl_des', 'tiny_cursive'),\n getString('tiny_cursive_placeholder', 'tiny_cursive')\n ]).then(function([title, titledes, placeholder]) {\n\n return create({\n type: 'SAVE_CANCEL',\n title: `
${title}
\n ${titledes}
`,\n body: ``,\n removeOnClose: true,\n })\n .done(modal => {\n modal.getRoot().addClass('tiny-cursive-modal');\n modal.show();\n var lastEvent = '';\n\n modal.getRoot().on(save, function() {\n\n var number = document.getElementById(\"inputUrl\").value.trim();\n\n if (number === \"\" || number === null || number === undefined) {\n editor.execCommand('Undo');\n // eslint-disable-next-line\n getString('pastewarning', 'tiny_cursive').then(str => alert(str));\n } else {\n editor.execCommand('Paste');\n }\n\n postOne('cursive_user_comments', {\n modulename: modulename,\n cmid: cmid,\n resourceid: resourceId,\n courseid: courseid,\n usercomment: number,\n timemodified: Date.now(),\n editorid: editorid ? editorid : \"\"\n });\n\n lastEvent = 'save';\n modal.destroy();\n });\n modal.getRoot().on(cancel, function() {\n editor.execCommand('Undo');\n lastEvent = 'cancel';\n });\n\n modal.getRoot().on(hidden, function() {\n if (lastEvent != 'cancel' && lastEvent != 'save') {\n editor.execCommand('Undo');\n }\n });\n return modal;\n });\n }).catch(error => window.console.error(error));\n\n };\n\n const sendKeyEvent = (events, editor) => {\n ed = editor;\n event = events;\n\n filename = `${userid}_${resourceId}_${cmid}_${modulename}_attempt`;\n\n if (modulename === 'quiz') {\n questionid = editorid.split(':')[1].split('_')[0];\n filename = `${userid}_${resourceId}_${cmid}_${questionid}_${modulename}_attempt`;\n }\n\n if (localStorage.getItem(filename)) {\n let data = JSON.parse(localStorage.getItem(filename));\n data.push({\n resourceId: resourceId,\n key: editor.key,\n keyCode: editor.keyCode,\n event: event,\n courseId: courseid,\n unixTimestamp: Date.now(),\n clientId: host,\n personId: userid,\n position: ed.caretPosition,\n rePosition: ed.rePosition,\n pastedContent: editor.pastedContent,\n aiContent: editor.aiContent\n });\n localStorage.setItem(filename, JSON.stringify(data));\n } else {\n let data = [{\n resourceId: resourceId,\n key: editor.key,\n keyCode: editor.keyCode,\n event: event,\n courseId: courseid,\n unixTimestamp: Date.now(),\n clientId: host,\n personId: userid,\n position: ed.caretPosition,\n rePosition: ed.rePosition,\n pastedContent: editor.pastedContent,\n aiContent: editor.aiContent\n }];\n localStorage.setItem(filename, JSON.stringify(data));\n }\n };\n\n editor.on('keyUp', (editor) => {\n customTooltip();\n let position = getCaretPosition(false);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n sendKeyEvent(\"keyUp\", editor);\n });\n editor.on('Paste', async(e) => {\n customTooltip();\n const pastedContent = (e.clipboardData || e.originalEvent.clipboardData).getData('text');\n if (!pastedContent) {\n return;\n }\n // Trim both values for consistent comparison\n const trimmedPastedContent = pastedContent.trim();\n const lastCopyCutContent = localStorage.getItem('lastCopyCutContent');\n const isFromOwnEditor = lastCopyCutContent && trimmedPastedContent === lastCopyCutContent;\n\n if (isStudent && intervention) {\n\n if (PASTE_SETTING === 'block') {\n if (!isFromOwnEditor) {\n e.preventDefault();\n shouldBlockPaste = true;\n isPasteAllowed = false;\n e.stopPropagation();\n e.stopImmediatePropagation();\n getString('paste_blocked', 'tiny_cursive').then(str => {\n return editor.windowManager.alert(str);\n }).catch(error => window.console.error(error));\n setTimeout(() => {\n isPasteAllowed = true;\n shouldBlockPaste = false;\n }, 100);\n return;\n }\n shouldBlockPaste = false;\n isPasteAllowed = true;\n return;\n }\n if (PASTE_SETTING === 'cite_source') {\n if (!isFromOwnEditor) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n getModal(e);\n }\n isPasteAllowed = true;\n return;\n }\n }\n isPasteAllowed = true;\n });\n editor.on('Redo', async(e) => {\n customTooltip();\n if (isStudent && intervention) {\n getModal(e);\n }\n });\n editor.on('keyDown', (editor) => {\n customTooltip();\n const isPasteAttempt = (editor.key === 'v' || editor.key === 'V') &&\n (editor.ctrlKey || editor.metaKey);\n if (isPasteAttempt && isStudent && intervention && PASTE_SETTING === 'block' && !isPasteAllowed) {\n setTimeout(() => {\n isPasteAllowed = true;\n }, 100);\n return;\n }\n let position = getCaretPosition();\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n sendKeyEvent(\"keyDown\", editor);\n });\n editor.on('Cut', () => {\n const selectedContent = editor.selection.getContent({format: 'text'});\n localStorage.setItem('lastCopyCutContent', selectedContent.trim());\n });\n editor.on('Copy', () => {\n const selectedContent = editor.selection.getContent({format: 'text'});\n localStorage.setItem('lastCopyCutContent', selectedContent.trim());\n });\n editor.on('mouseDown', async(editor) => {\n setTimeout(() => {\n constructMouseEvent(editor);\n sendKeyEvent(\"mouseDown\", editor);\n }, 0);\n });\n editor.on('mouseUp', async(editor) => {\n setTimeout(() => {\n constructMouseEvent(editor);\n sendKeyEvent(\"mouseUp\", editor);\n }, 10);\n });\n editor.on('init', () => {\n customTooltip();\n localStorage.removeItem('lastCopyCutContent');\n });\n editor.on('SetContent', () => {\n customTooltip();\n });\n editor.on('FullscreenStateChanged', (e) => {\n let view = new DocumentView(user, Rubrics, submission, modulename, editor, quizInfo);\n isFullScreen = e.state;\n try {\n if (!e.state) {\n view.normalMode();\n } else {\n view.fullPageMode();\n }\n } catch (error) {\n if (errorAlert) {\n errorAlert = false;\n getString('fullmodeerror', 'tiny_cursive').then(str => {\n return editor.windowManager.alert(str);\n }).catch(error => window.console.error(error));\n }\n view.normalMode();\n window.console.error('Error ResizeEditor event:', error);\n }\n });\n\n editor.on('execcommand', function(e) {\n if (e.command === \"mceInsertContent\") {\n const contentObj = e.value;\n\n const isPaste = contentObj && typeof contentObj === 'object' && contentObj.paste === true;\n\n let insertedContent = contentObj.content || contentObj;\n let tempDiv = document.createElement('div');\n tempDiv.innerHTML = insertedContent;\n let text = tempDiv.textContent || tempDiv.innerText || '';\n let pastedText = tempDiv.textContent || tempDiv.innerText || '';\n\n let position = getCaretPosition(true);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n\n if (isPaste) {\n if (shouldBlockPaste) {\n shouldBlockPaste = false;\n e.preventDefault();\n editor.undoManager.undo();\n return;\n }\n const lastCopyCutContent = localStorage.getItem('lastCopyCutContent');\n const isFromOwnEditor = lastCopyCutContent && pastedText.trim() === lastCopyCutContent;\n\n if (isStudent && intervention && PASTE_SETTING === 'block' && !isFromOwnEditor) {\n isPasteAllowed = false;\n editor.undoManager.undo();\n return;\n }\n\n sendKeyEvent(\"Paste\", {\n key: \"v\",\n keyCode: 86,\n caretPosition: editor.caretPosition,\n rePosition: editor.rePosition,\n pastedContent: pastedText,\n srcElement: {baseURI: window.location.href}\n });\n } else {\n aiContents.push(text);\n\n sendKeyEvent(\"aiInsert\", {\n key: \"ai\",\n keyCode: 0,\n caretPosition: editor.caretPosition,\n rePosition: editor.rePosition,\n aiContent: text,\n srcElement: {baseURI: window.location.href}\n });\n }\n }\n });\n\n editor.on('input', function(e) {\n let position = getCaretPosition(true);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n let aiContent = e.data;\n\n if (e.inputType === 'insertReplacementText' || (e.inputType === 'insertText' && aiContent && aiContent.length > 1)) {\n\n aiContents.push(aiContent);\n\n e.key = \"ai\";\n e.keyCode = 0;\n e.caretPosition = position.caretPosition;\n e.rePosition = position.rePosition;\n e.aiContent = aiContent;\n\n sendKeyEvent(\"aiInsert\", e);\n }\n });\n\n\n /**\n * Constructs a mouse event object with caret position and button information\n * @param {Object} editor - The TinyMCE editor instance\n * @function constructMouseEvent\n * @description Sets caret position, reposition, key and keyCode properties on the editor object based on current mouse state\n */\n function constructMouseEvent(editor) {\n let position = getCaretPosition(false);\n editor.caretPosition = position.caretPosition;\n editor.rePosition = position.rePosition;\n editor.key = getMouseButton(editor);\n editor.keyCode = editor.button;\n }\n\n /**\n * Gets the string representation of a mouse button based on its numeric value\n * @param {Object} editor - The editor object containing button information\n * @returns {string} The string representation of the mouse button ('left', 'middle', or 'right')\n */\n function getMouseButton(editor) {\n\n switch (editor.button) {\n case 0:\n return 'left';\n case 1:\n return 'middle';\n case 2:\n return 'right';\n }\n return null;\n }\n\n /**\n * Gets the current caret position in the editor\n * @param {boolean} skip - If true, returns the last known caret position instead of calculating a new one\n * @returns {Object} Object containing:\n * - caretPosition: Sequential position number stored in session\n * - rePosition: Absolute character offset from start of content\n * @throws {Error} Logs warning to console if error occurs during calculation\n */\n function getCaretPosition(skip = false) {\n try {\n if (!editor || !editor.selection) {\n return {caretPosition: 0, rePosition: 0};\n }\n\n const range = editor.selection.getRng();\n const body = editor.getBody();\n\n // Create a range from start of document to current caret\n const preCaretRange = range.cloneRange();\n preCaretRange.selectNodeContents(body);\n preCaretRange.setEnd(range.endContainer, range.endOffset);\n\n const fragment = preCaretRange.cloneContents();\n const tempDiv = document.createElement('div');\n tempDiv.appendChild(fragment);\n let textBeforeCursor = tempDiv.innerText || '';\n\n const endContainer = range.endContainer;\n const endOffset = range.endOffset;\n\n if (endOffset === 0 &&\n endContainer.nodeType === Node.ELEMENT_NODE &&\n editor.dom.isBlock(endContainer) &&\n endContainer.previousSibling) {\n textBeforeCursor += '\\n';\n }\n const blockElements = tempDiv.querySelectorAll('p, div, h1, h2, h3, h4, h5, h6, li');\n let emptyBlockCount = 0;\n blockElements.forEach(block => {\n const text = block.innerText || block.textContent || '';\n if (text.trim() === '' && block.childNodes.length === 1 &&\n block.childNodes[0].nodeName === 'BR') {\n emptyBlockCount++;\n }\n });\n\n // Add newlines for empty blocks (these represent Enter presses that created empty lines)\n if (emptyBlockCount > 0) {\n textBeforeCursor += '\\n'.repeat(emptyBlockCount);\n }\n\n const absolutePosition = textBeforeCursor.length;\n\n if (skip) {\n return {\n caretPosition: lastCaretPos,\n rePosition: absolutePosition\n };\n }\n // Increment sequential caretPosition\n const storageKey = `${userid}_${resourceId}_${cmid}_position`;\n let storedPos = parseInt(sessionStorage.getItem(storageKey), 10);\n if (isNaN(storedPos)) {\n storedPos = 0;\n }\n storedPos++;\n lastCaretPos = storedPos;\n sessionStorage.setItem(storageKey, storedPos);\n\n return {\n caretPosition: storedPos,\n rePosition: absolutePosition\n };\n\n } catch (e) {\n window.console.warn('Error getting caret position:', e);\n return {caretPosition: lastCaretPos || 1, rePosition: 0};\n }\n }\n\n\n /**\n * Synchronizes data from localStorage to server\n * @async\n * @function SyncData\n * @description Retrieves stored keypress data from localStorage and sends it to server\n * @returns {Promise} Returns response from server if data exists and is successfully sent\n * @throws {Error} Logs error to console if data submission fails\n */\n async function syncData() {\n\n let data = localStorage.getItem(filename);\n\n if (!data || data.length === 0) {\n return;\n } else {\n localStorage.removeItem(filename);\n let originalText = editor.getContent({format: 'text'});\n try {\n Autosave.updateSavingState('saving');\n // eslint-disable-next-line\n return await postOne('cursive_write_local_to_json', {\n key: ed.key,\n event: event,\n keyCode: ed.keyCode,\n resourceId: resourceId,\n cmid: cmid,\n modulename: modulename,\n editorid: editorid,\n \"json_data\": data,\n originalText: originalText\n });\n } catch (error) {\n window.console.error('Error submitting data:', error);\n }\n }\n }\n /**\n * Sets up custom tooltip functionality for the Cursive icon\n * Initializes tooltip text, positions the icon in the menubar,\n * and sets up mouse event handlers for showing/hiding the tooltip\n * @function customTooltip\n */\n function customTooltip() {\n try {\n const tooltipText = getTooltipText();\n const menubarDiv = document.querySelectorAll('div[role=\"menubar\"].tox-menubar');\n let classArray = [];\n\n if (menubarDiv.length) {\n menubarDiv.forEach(function(element, index) {\n index += 1;\n let className = 'cursive-menu-' + index;\n element.classList.add(className);\n classArray.push(className);\n });\n }\n\n const cursiveIcon = document.createElement('img');\n cursiveIcon.src = hasApiKey ? iconUrl : iconGrayUrl;\n\n cursiveIcon.setAttribute('class', 'tiny_cursive_StateButton');\n cursiveIcon.style.display = 'inline-block';\n\n cursiveState(cursiveIcon, menubarDiv, classArray);\n\n for (let index in classArray) {\n const elementId = \"tiny_cursive_StateIcon\" + index;\n const tooltipId = `tiny_cursive_tooltip${index}`;\n\n tooltipText.then((text) => {\n return setTooltip(text, document.querySelector(`#${elementId}`), tooltipId);\n }).catch(error => window.console.error(error));\n\n $(`#${elementId}`).on('mouseenter', function() {\n $(this).css('position', 'relative');\n $(`#${tooltipId}`).css(tooltipCss);\n });\n\n $(`#${elementId}`).on('mouseleave', function() {\n $(`#${tooltipId}`).css('display', 'none');\n });\n }\n } catch (error) {\n window.console.error('Error setting up custom tooltip:', error);\n }\n }\n\n /**\n * Retrieves tooltip text strings from language files\n * @async\n * @function getTooltipText\n * @returns {Promise} Object containing buttonTitle and buttonDes strings\n */\n async function getTooltipText() {\n const [\n buttonTitle,\n buttonDes,\n ] = await Promise.all([\n getString('cursive:state:active', 'tiny_cursive'),\n getString('cursive:state:active:des', 'tiny_cursive'),\n ]);\n return {buttonTitle, buttonDes};\n }\n\n /**\n * Updates the Cursive icon state and positions it in the menubar\n * @param {HTMLElement} cursiveIcon - The Cursive icon element to modify\n * @param {HTMLElement} menubarDiv - The menubar div element\n * @param {Array} classArray - Array of class names for the menubar div elements\n */\n function cursiveState(cursiveIcon, menubarDiv, classArray) {\n if (!menubarDiv) {\n return;\n }\n\n for (let index in classArray) {\n const rightWrapper = document.createElement('div');\n const imgWrapper = document.createElement('span');\n const iconClone = cursiveIcon.cloneNode(true);\n const targetMenu = document.querySelector('.' + classArray[index]);\n let elementId = \"tiny_cursive_StateIcon\" + index;\n\n rightWrapper.style.cssText = `\n margin-left: auto;\n display: flex;\n align-items: center;\n `;\n\n imgWrapper.id = elementId;\n imgWrapper.style.marginLeft = '.2rem';\n imgWrapper.appendChild(iconClone);\n rightWrapper.appendChild(imgWrapper);\n\n let moduleIds = {\n resourceId: resourceId,\n cmid: cmid,\n modulename: modulename,\n questionid: questionid,\n userid: userid,\n courseid: courseid};\n // Document mode, other modules single editor instances\n if (isFullScreen && (modulename === 'assign' || modulename === 'forum'\n || modulename === 'lesson')) {\n let existsElement = document.querySelector('.tox-menubar[class*=\"cursive-menu-\"] > div');\n if (existsElement) {\n existsElement.remove();\n }\n\n if (!document.querySelector(`#${elementId}`)) {\n rightWrapper.style.marginTop = '3px';\n document.querySelector('#tiny_cursive-fullpage-right-wrapper').prepend(rightWrapper);\n }\n\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n } else if (isFullScreen && modulename === 'quiz') { // Document mode, quiz multiple editor instances\n let existingElement = editor.container?.childNodes[1]?.childNodes[0]?.childNodes[0]?.childNodes[7];\n let newHeader = editor.container?.childNodes[0];\n if (existingElement) {\n existingElement.remove();\n }\n\n if (newHeader && !newHeader.querySelector(`span[id*=tiny_cursive_StateIcon]`)) {\n rightWrapper.style.marginTop = '3px';\n document.querySelector('#tiny_cursive-fullpage-right-wrapper').prepend(rightWrapper);\n }\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n } else { // Regular view\n let menubar = editor?.container?.children[0]?.childNodes[0]?.childNodes[0];\n\n if (targetMenu && !targetMenu.querySelector(`#${elementId}`)) {\n targetMenu.appendChild(rightWrapper);\n }\n // Regular view, multiple editor instances\n if (modulename === 'quiz' && menubar) {\n let wrapper = menubar.querySelector('span[id*=\"tiny_cursive_StateIcon\"]');\n\n if (wrapper) {\n Autosave.destroyInstance();\n Autosave.getInstance(editor, wrapper?.parentElement, moduleIds, isFullScreen);\n }\n } else {\n Autosave.destroyInstance();\n Autosave.getInstance(editor, rightWrapper, moduleIds, isFullScreen);\n }\n }\n }\n }\n\n /**\n * Sets up tooltip content and styling for the Cursive icon\n * @param {Object} text - Object containing tooltip text strings\n * @param {string} text.buttonTitle - Title text for the tooltip\n * @param {string} text.buttonDes - Description text for the tooltip\n * @param {HTMLElement} cursiveIcon - The Cursive icon element to attach tooltip to\n * @param {string} tooltipId - ID for the tooltip element\n */\n function setTooltip(text, cursiveIcon, tooltipId) {\n\n if (document.querySelector(`#${tooltipId}`)) {\n return;\n }\n if (cursiveIcon) {\n\n const tooltipSpan = document.createElement('span');\n const description = document.createElement('span');\n const linebreak = document.createElement('br');\n const tooltipTitle = document.createElement('strong');\n\n tooltipSpan.style.display = 'none';\n tooltipTitle.textContent = text.buttonTitle;\n tooltipTitle.style.fontSize = '16px';\n tooltipTitle.style.fontWeight = 'bold';\n description.textContent = text.buttonDes;\n description.style.fontSize = '14px';\n\n tooltipSpan.id = tooltipId;\n tooltipSpan.classList.add(`shadow`);\n tooltipSpan.appendChild(tooltipTitle);\n tooltipSpan.appendChild(linebreak);\n tooltipSpan.appendChild(description);\n cursiveIcon.appendChild(tooltipSpan);\n }\n }\n\n /**\n * Extracts module information from URL parameters\n * @param {string} ur - The base URL to analyze\n * @param {URL} parm - URL object containing search parameters\n * @param {Array} MODULES - Array of valid module names to check against\n * @returns {Object|boolean} Object containing resourceId and module name if found, false if no valid module\n */\n function getModulesInfo(ur, parm, MODULES) {\n fetchStrings();\n if (!MODULES.some(module => ur.includes(module))) {\n return false;\n }\n\n if (ur.includes(\"forum\") && !ur.includes(\"assign\")) {\n resourceId = parm.searchParams.get('edit');\n } else {\n resourceId = parm.searchParams.get('attempt');\n }\n\n if (resourceId === null) {\n resourceId = 0;\n }\n\n for (const module of MODULES) {\n if (ur.includes(module)) {\n modulename = module;\n if (module === \"lesson\" || module === \"assign\") {\n resourceId = cmid;\n } else if (module === \"oublog\") {\n resourceId = 0;\n }\n break;\n }\n }\n\n return {resourceId: resourceId, name: modulename};\n }\n\n /**\n * Fetches and caches localized strings used in the UI\n * @function fetchStrings\n * @description Retrieves strings for sidebar titles and document sidebar elements if not already cached in localStorage\n * Uses Promise.all to fetch multiple strings in parallel for better performance\n * Stores the fetched strings in localStorage under 'sbTitle' and 'docSideBar' keys\n */\n function fetchStrings() {\n if (!localStorage.getItem('sbTitle')) {\n Promise.all([\n getString('assignment', 'tiny_cursive'),\n getString('discussion', 'tiny_cursive'),\n getString('pluginname', 'mod_quiz'),\n getString('pluginname', 'mod_lesson'),\n getString('description', 'tiny_cursive'),\n ]).then(function(strings) {\n return localStorage.setItem('sbTitle', JSON.stringify(strings));\n }).catch(error => window.console.error(error));\n }\n if (!localStorage.getItem('docSideBar')) {\n Promise.all([\n getString('details', 'tiny_cursive'),\n getString('student_info', 'tiny_cursive'),\n getString('progress', 'tiny_cursive'),\n getString('description', 'tiny_cursive'),\n getString('replyingto', 'tiny_cursive'),\n getString('answeringto', 'tiny_cursive'),\n getString('importantdates', 'tiny_cursive'),\n getString('rubrics', 'tiny_cursive'),\n getString('submission_status', 'tiny_cursive'),\n getString('status', 'tiny_cursive'),\n getString('draft', 'tiny_cursive'),\n getString('draftnot', 'tiny_cursive'),\n getString('last_modified', 'tiny_cursive'),\n getString('gradings', 'tiny_cursive'),\n getString('gradenot', 'tiny_cursive'),\n getString('word_count', 'tiny_cursive'),\n getString('timeleft', 'tiny_cursive'),\n getString('nolimit', 'tiny_cursive'),\n getString('name', 'tiny_cursive'),\n getString('userename', 'tiny_cursive'),\n getString('course', 'tiny_cursive'),\n getString('opened', 'tiny_cursive'),\n getString('due', 'tiny_cursive'),\n getString('overdue', 'tiny_cursive'),\n getString('remaining', 'tiny_cursive'),\n getString('savechanges', 'tiny_cursive'),\n getString('subjectnot', 'tiny_cursive'),\n getString('remaining', 'tiny_cursive'),\n ]).then(function(strings) {\n return localStorage.setItem('docSideBar', JSON.stringify(strings));\n }).catch(error => window.console.error(error));\n }\n\n }\n\n window.addEventListener('unload', () => {\n syncData();\n });\n\n setInterval(syncData, syncInterval);\n};\n"],"names":["editor","interval","userId","hasApiKey","MODULES","Rubrics","submission","quizInfo","pasteSetting","isStudent","hasClass","intervention","host","M","cfg","wwwroot","userid","courseid","courseId","editorid","id","cmid","contextInstanceId","ed","event","filename","questionid","quizSubmit","assignSubmit","syncInterval","lastCaretPos","aiContents","isFullScreen","user","ur","window","location","href","modulesInfo","parm","localStorage","getItem","Promise","all","then","strings","setItem","JSON","stringify","catch","error","console","fetchStrings","some","module","includes","resourceId","searchParams","get","modulename","name","getModulesInfo","URL","errorAlert","PASTE_SETTING","shouldBlockPaste","isPasteAllowed","postOne","async","methodname","args","response","setTimeout","updateSavingState","field","values","done","fail","ex","on","e","preventDefault","syncData","off","click","removeItem","getModal","title","titledes","placeholder","type","body","removeOnClose","modal","getRoot","addClass","show","lastEvent","save","number","document","getElementById","value","trim","execCommand","str","alert","resourceid","usercomment","timemodified","Date","now","destroy","cancel","hidden","sendKeyEvent","events","split","data","parse","push","key","keyCode","unixTimestamp","clientId","personId","position","caretPosition","rePosition","pastedContent","aiContent","constructMouseEvent","getCaretPosition","button","getMouseButton","skip","selection","range","getRng","getBody","preCaretRange","cloneRange","selectNodeContents","setEnd","endContainer","endOffset","fragment","cloneContents","tempDiv","createElement","appendChild","textBeforeCursor","innerText","nodeType","Node","ELEMENT_NODE","dom","isBlock","previousSibling","blockElements","querySelectorAll","emptyBlockCount","forEach","block","textContent","childNodes","length","nodeName","repeat","absolutePosition","storageKey","storedPos","parseInt","sessionStorage","isNaN","warn","originalText","getContent","format","customTooltip","tooltipText","buttonTitle","buttonDes","getTooltipText","menubarDiv","classArray","element","index","className","classList","add","cursiveIcon","src","iconUrl","iconGrayUrl","setAttribute","style","display","rightWrapper","imgWrapper","iconClone","cloneNode","targetMenu","querySelector","elementId","cssText","marginLeft","moduleIds","existingElement","container","_editor$container","_editor$container$chi","_editor$container$chi2","_editor$container$chi3","newHeader","_editor$container2","remove","marginTop","prepend","destroyInstance","getInstance","menubar","_editor$container3","children","_editor$container3$ch","_editor$container3$ch2","wrapper","parentElement","existsElement","cursiveState","tooltipId","text","setTooltip","this","css","tooltipCss","tooltipSpan","description","linebreak","tooltipTitle","fontSize","fontWeight","clipboardData","originalEvent","getData","trimmedPastedContent","lastCopyCutContent","isFromOwnEditor","stopPropagation","stopImmediatePropagation","windowManager","ctrlKey","metaKey","selectedContent","view","DocumentView","state","fullPageMode","normalMode","command","contentObj","isPaste","paste","insertedContent","content","innerHTML","pastedText","undoManager","undo","srcElement","baseURI","inputType","addEventListener","setInterval"],"mappings":"ooBAgCwB,CAACA,OAAQC,SAAUC,OAAQC,UAAWC,QAASC,QAASC,WAAYC,SAAUC,oBAE9FC,YAAc,mBAAE,SAASC,SAAS,iBAClCC,cAAe,mBAAE,SAASD,SAAS,gBACnCE,KAAOC,EAAEC,IAAIC,QACbC,OAASd,OACTe,SAAWJ,EAAEC,IAAII,SACjBC,SAAWnB,MAAAA,cAAAA,OAAQoB,GACnBC,KAAOR,EAAEC,IAAIQ,kBACbC,GAAK,GACLC,MAAQ,GACRC,SAAW,GACXC,WAAa,EACbC,YAAa,mBAAE,0BACfC,cAAe,mBAAE,wBACjBC,aAAe5B,SAAsB,IAAXA,SAAkB,IAC5C6B,aAAe,MACfC,WAAa,OACbC,cAAe,EACfC,KAAO,SACPC,GAAKC,OAAOC,SAASC,KAErBC,qBA6sBoBJ,GAAIK,KAAMnC,uBAuCzBoC,aAAaC,QAAQ,YACtBC,QAAQC,IAAI,EACR,mBAAU,aAAc,iBACxB,mBAAU,aAAc,iBACxB,mBAAU,aAAc,aACxB,mBAAU,aAAc,eACxB,mBAAU,cAAe,kBAC1BC,MAAK,SAASC,gBACNL,aAAaM,QAAQ,UAAWC,KAAKC,UAAUH,aACvDI,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,SAEtCV,aAAaC,QAAQ,eACtBC,QAAQC,IAAI,EACR,mBAAU,UAAW,iBACrB,mBAAU,eAAgB,iBAC1B,mBAAU,WAAY,iBACtB,mBAAU,cAAe,iBACzB,mBAAU,aAAc,iBACxB,mBAAU,cAAe,iBACzB,mBAAU,iBAAkB,iBAC5B,mBAAU,UAAW,iBACrB,mBAAU,oBAAqB,iBAC/B,mBAAU,SAAU,iBACpB,mBAAU,QAAS,iBACnB,mBAAU,WAAY,iBACtB,mBAAU,gBAAiB,iBAC3B,mBAAU,WAAY,iBACtB,mBAAU,WAAY,iBACtB,mBAAU,aAAc,iBACxB,mBAAU,WAAY,iBACtB,mBAAU,UAAW,iBACrB,mBAAU,OAAQ,iBAClB,mBAAU,YAAa,iBACvB,mBAAU,SAAU,iBACpB,mBAAU,SAAU,iBACpB,mBAAU,MAAO,iBACjB,mBAAU,UAAW,iBACrB,mBAAU,YAAa,iBACvB,mBAAU,cAAe,iBACzB,mBAAU,aAAc,iBACxB,mBAAU,YAAa,kBACxBC,MAAK,SAASC,gBACNL,aAAaM,QAAQ,aAAcC,KAAKC,UAAUH,aAC1DI,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,SAjF3CE,IACKhD,QAAQiD,MAAKC,QAAUpB,GAAGqB,SAASD,iBAC7B,EAIPE,WADAtB,GAAGqB,SAAS,WAAarB,GAAGqB,SAAS,UACxBhB,KAAKkB,aAAaC,IAAI,QAEtBnB,KAAKkB,aAAaC,IAAI,WAGpB,OAAfF,aACAA,WAAa,OAGZ,MAAMF,UAAUlD,WACb8B,GAAGqB,SAASD,QAAS,CACrBK,WAAaL,OACE,WAAXA,QAAkC,WAAXA,OACvBE,WAAanC,KACK,WAAXiC,SACPE,WAAa,eAMlB,CAACA,WAAYA,WAAYI,KAAMD,YAzuBxBE,CAAe3B,GADtB,IAAI4B,IAAI5B,IACwB9B,aACvCoD,WAAalB,YAAYkB,WACzBG,WAAarB,YAAYsB,KACzBG,YAAa,MACbC,cAAgBxD,cAAgB,QAChCyD,kBAAmB,EACnBC,gBAAiB,EAEF,WAAfP,aACAK,cAAgB,qBAEdG,QAAUC,MAAMC,WAAYC,kBAEpBC,eAAiB,cAAK,CAAC,CACzBF,WAAAA,WACAC,KAAAA,QACA,UACAC,UACAC,YAAW,+BACEC,kBAAkB,WAC5B,KAEAF,SACT,MAAOrB,uCACIuB,kBAAkB,WAC3BtC,OAAOgB,QAAQD,MAAM,oBAAqBA,OACpCA,uBAIN,CAAC,CACDmB,WAAY,+BACZC,KAAM,CAACI,MAAO,KAAMC,OAAQ,CAAC3D,YAC7B,GAAG4D,MAAKL,WACRtC,KAAOsC,SAAS,MACjBM,MAAMC,KACL3C,OAAOgB,QAAQD,MAAM,4BAA6B4B,OAG1DlD,aAAamD,GAAG,SAASX,eAAeY,GACpCA,EAAEC,iBACExD,SAEAyD,WAAWtC,MAAK,KACZhB,aAAauD,IAAI,SAASC,WAG9BxD,aAAauD,IAAI,SAASC,QAE9B5C,aAAa6C,WAAW,yBAG5B1D,WAAWoD,GAAG,SAASX,eAAeY,GAClCA,EAAEC,iBACExD,SAEAyD,WAAWtC,MAAK,KACZjB,WAAWwD,IAAI,SAASC,WAG5BzD,WAAWwD,IAAI,SAASC,QAE5B5C,aAAa6C,WAAW,+BAGtBC,SAAW,KAEb5C,QAAQC,IAAI,EACR,mBAAU,sBAAuB,iBACjC,mBAAU,0BAA2B,iBACrC,mBAAU,2BAA4B,kBACvCC,MAAK,mBAAU2C,MAAOC,SAAUC,yBAExB,yBAAO,CACVC,KAAM,cACNH,MAAQ,6CAA4CA,8EACJC,wBAChDG,KAAO,gFAA+EF,2BACtFG,eAAe,IAEdhB,MAAKiB,QACFA,MAAMC,UAAUC,SAAS,sBACzBF,MAAMG,WACFC,UAAY,UAEhBJ,MAAMC,UAAUf,GAAGmB,oBAAM,eAEjBC,OAASC,SAASC,eAAe,YAAYC,MAAMC,OAExC,KAAXJ,QAAAA,MAAiBA,QACjBnG,OAAOwG,YAAY,4BAET,eAAgB,gBAAgB5D,MAAK6D,KAAOC,MAAMD,QAE5DzG,OAAOwG,YAAY,SAGvBrC,QAAQ,wBAAyB,CAC7BR,WAAYA,WACZtC,KAAMA,KACNsF,WAAYnD,WACZvC,SAAUA,SACV2F,YAAaT,OACbU,aAAcC,KAAKC,MACnB5F,SAAUA,UAAsB,KAGpC8E,UAAY,OACZJ,MAAMmB,aAEVnB,MAAMC,UAAUf,GAAGkC,sBAAQ,WACvBjH,OAAOwG,YAAY,QACnBP,UAAY,YAGhBJ,MAAMC,UAAUf,GAAGmC,sBAAQ,WACN,UAAbjB,WAAsC,QAAbA,WACzBjG,OAAOwG,YAAY,WAGpBX,YAEhB5C,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,UAIrCiE,aAAe,CAACC,OAAQpH,aAC1BuB,GAAKvB,OACLwB,MAAQ4F,OAER3F,SAAY,GAAET,UAAUwC,cAAcnC,QAAQsC,qBAE3B,SAAfA,aACAjC,WAAaP,SAASkG,MAAM,KAAK,GAAGA,MAAM,KAAK,GAC/C5F,SAAY,GAAET,UAAUwC,cAAcnC,QAAQK,cAAciC,sBAG5DnB,aAAaC,QAAQhB,UAAW,KAC5B6F,KAAOvE,KAAKwE,MAAM/E,aAAaC,QAAQhB,WAC3C6F,KAAKE,KAAK,CACNhE,WAAYA,WACZiE,IAAKzH,OAAOyH,IACZC,QAAS1H,OAAO0H,QAChBlG,MAAOA,MACPN,SAAUD,SACV0G,cAAeb,KAAKC,MACpBa,SAAUhH,KACViH,SAAU7G,OACV8G,SAAUvG,GAAGwG,cACbC,WAAYzG,GAAGyG,WACfC,cAAejI,OAAOiI,cACtBC,UAAWlI,OAAOkI,YAEtB1F,aAAaM,QAAQrB,SAAUsB,KAAKC,UAAUsE,WAC3C,KACCA,KAAO,CAAC,CACR9D,WAAYA,WACZiE,IAAKzH,OAAOyH,IACZC,QAAS1H,OAAO0H,QAChBlG,MAAOA,MACPN,SAAUD,SACV0G,cAAeb,KAAKC,MACpBa,SAAUhH,KACViH,SAAU7G,OACV8G,SAAUvG,GAAGwG,cACbC,WAAYzG,GAAGyG,WACfC,cAAejI,OAAOiI,cACtBC,UAAWlI,OAAOkI,YAEtB1F,aAAaM,QAAQrB,SAAUsB,KAAKC,UAAUsE,kBAgN7Ca,oBAAoBnI,YACrB8H,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7BhI,OAAOyH,aASazH,eAEZA,OAAOqI,aACN,QACM,YACN,QACM,cACN,QACM,eAER,KAnBMC,CAAetI,QAC5BA,OAAO0H,QAAU1H,OAAOqI,gBA6BnBD,uBAAiBG,qEAEfvI,SAAWA,OAAOwI,gBACd,CAACT,cAAe,EAAGC,WAAY,SAGlCS,MAAQzI,OAAOwI,UAAUE,SACzB/C,KAAO3F,OAAO2I,UAGdC,cAAgBH,MAAMI,aAC5BD,cAAcE,mBAAmBnD,MACjCiD,cAAcG,OAAON,MAAMO,aAAcP,MAAMQ,iBAEzCC,SAAWN,cAAcO,gBACzBC,QAAUhD,SAASiD,cAAc,OACvCD,QAAQE,YAAYJ,cAChBK,iBAAmBH,QAAQI,WAAa,SAEtCR,aAAeP,MAAMO,aAGT,IAFAP,MAAMQ,WAGpBD,aAAaS,WAAaC,KAAKC,cAC/B3J,OAAO4J,IAAIC,QAAQb,eACnBA,aAAac,kBACbP,kBAAoB,YAElBQ,cAAgBX,QAAQY,iBAAiB,0CAC3CC,gBAAkB,EACtBF,cAAcG,SAAQC,QAEA,MADPA,MAAMX,WAAaW,MAAMC,aAAe,IAC5C7D,QAA6C,IAA5B4D,MAAME,WAAWC,QACN,OAAjCH,MAAME,WAAW,GAAGE,UACtBN,qBAKAA,gBAAkB,IACpBV,kBAAoB,KAAKiB,OAAOP,wBAG5BQ,iBAAmBlB,iBAAiBe,UAEtC/B,WACK,CACLR,cAAejG,aACfkG,WAAYyC,wBAIVC,WAAc,GAAE1J,UAAUwC,cAAcnC,oBAC1CsJ,UAAYC,SAASC,eAAepI,QAAQiI,YAAa,WACzDI,MAAMH,aACRA,UAAY,GAEdA,YACA7I,aAAe6I,UACfE,eAAe/H,QAAQ4H,WAAYC,WAE5B,CACL5C,cAAe4C,UACf3C,WAAYyC,kBAGd,MAAOzF,UACL7C,OAAOgB,QAAQ4H,KAAK,gCAAiC/F,GAC9C,CAAC+C,cAAejG,cAAgB,EAAGkG,WAAY,mBAa/C9C,eAEPoC,KAAO9E,aAAaC,QAAQhB,aAE3B6F,MAAwB,IAAhBA,KAAKgD,OAEX,CACH9H,aAAa6C,WAAW5D,cACpBuJ,aAAehL,OAAOiL,WAAW,CAACC,OAAQ,8CAEjCzG,kBAAkB,gBAEdN,QAAQ,8BAA+B,CAChDsD,IAAKlG,GAAGkG,IACRjG,MAAOA,MACPkG,QAASnG,GAAGmG,QACZlE,WAAYA,WACZnC,KAAMA,KACNsC,WAAYA,WACZxC,SAAUA,mBACGmG,KACb0D,aAAcA,eAEpB,MAAO9H,OACLf,OAAOgB,QAAQD,MAAM,yBAA0BA,kBAUlDiI,0BAEKC,mCAmDNC,YACAC,iBACM5I,QAAQC,IAAI,EAClB,mBAAU,uBAAwB,iBAClC,mBAAU,2BAA4B,wBAEnC,CAAC0I,YAAAA,YAAaC,UAAAA,WAzDGC,GACdC,WAAapF,SAAS4D,iBAAiB,uCACzCyB,WAAa,GAEbD,WAAWlB,QACXkB,WAAWtB,SAAQ,SAASwB,QAASC,WAE7BC,UAAY,iBADhBD,OAAS,GAETD,QAAQG,UAAUC,IAAIF,WACtBH,WAAWjE,KAAKoE,oBAIlBG,YAAc3F,SAASiD,cAAc,OAC3C0C,YAAYC,IAAM7L,UAAY8L,gBAAUC,oBAExCH,YAAYI,aAAa,QAAS,4BAClCJ,YAAYK,MAAMC,QAAU,wBAiDdN,YAAaP,WAAYC,gBACtCD,sBAIA,IAAIG,SAASF,WAAY,OACpBa,aAAelG,SAASiD,cAAc,OACtCkD,WAAanG,SAASiD,cAAc,QACpCmD,UAAYT,YAAYU,WAAU,GAClCC,WAAatG,SAASuG,cAAc,IAAMlB,WAAWE,YACvDiB,UAAY,yBAA2BjB,MAE3CW,aAAaF,MAAMS,QAAW,2JAM9BN,WAAWnL,GAAKwL,UAChBL,WAAWH,MAAMU,WAAa,QAC9BP,WAAWjD,YAAYkD,WACvBF,aAAahD,YAAYiD,gBAErBQ,UAAY,CACZvJ,WAAYA,WACZnC,KAAMA,KACNsC,WAAYA,WACZjC,WAAYA,WACZV,OAAQA,OACRC,SAAUA,cAEVe,cAAgC,WAAf2B,YAA0C,UAAfA,YAC1B,WAAfA,WAaA,GAAI3B,cAA+B,SAAf2B,WAAuB,kHAC1CqJ,0CAAkBhN,OAAOiN,sEAAPC,kBAAkB7C,WAAW,oEAA7B8C,sBAAiC9C,WAAW,qEAA5C+C,uBAAgD/C,WAAW,4CAA3DgD,uBAA+DhD,WAAW,GAC5FiD,qCAAYtN,OAAOiN,+CAAPM,mBAAkBlD,WAAW,GACzC2C,iBACAA,gBAAgBQ,SAGhBF,YAAcA,UAAUX,cAAe,sCACvCL,aAAaF,MAAMqB,UAAY,MAC/BrH,SAASuG,cAAc,wCAAwCe,QAAQpB,yCAElEqB,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,kBACnD,yEACC6L,QAAU7N,MAAAA,mCAAAA,OAAQiN,uEAARa,mBAAmBC,SAAS,oEAA5BC,sBAAgC3D,WAAW,4CAA3C4D,uBAA+C5D,WAAW,MAEpEqC,aAAeA,WAAWC,cAAe,IAAGC,cAC5CF,WAAWpD,YAAYgD,cAGR,SAAf3I,YAAyBkK,QAAS,KAC9BK,QAAUL,QAAQlB,cAAc,sCAEhCuB,oCACSP,4CACAC,YAAY5N,OAAQkO,MAAAA,eAAAA,QAASC,cAAepB,UAAW/K,8CAG3D2L,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,kBA1C7B,KACzBoM,cAAgBhI,SAASuG,cAAc,8CACvCyB,eACAA,cAAcZ,SAGbpH,SAASuG,cAAe,IAAGC,eAC5BN,aAAaF,MAAMqB,UAAY,MAC/BrH,SAASuG,cAAc,wCAAwCe,QAAQpB,yCAGlEqB,4CACAC,YAAY5N,OAAQsM,aAAcS,UAAW/K,gBA3F1DqM,CAAatC,YAAaP,WAAYC,gBAEjC,IAAIE,SAASF,WAAY,OACpBmB,UAAY,yBAA2BjB,MACvC2C,UAAa,uBAAsB3C,QAEzCP,YAAYxI,MAAM2L,MACPC,WAAWD,KAAMnI,SAASuG,cAAe,IAAGC,aAAc0B,aAClErL,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,6BAEpC,IAAG0J,aAAa7H,GAAG,cAAc,+BAC9B0J,MAAMC,IAAI,WAAY,gCACrB,IAAGJ,aAAaI,IAAIC,2CAGxB,IAAG/B,aAAa7H,GAAG,cAAc,+BAC7B,IAAGuJ,aAAaI,IAAI,UAAW,YAG5C,MAAOxL,OACLf,OAAOgB,QAAQD,MAAM,mCAAoCA,iBAmHxDsL,WAAWD,KAAMxC,YAAauC,eAE/BlI,SAASuG,cAAe,IAAG2B,cAG3BvC,YAAa,OAEP6C,YAAcxI,SAASiD,cAAc,QACrCwF,YAAczI,SAASiD,cAAc,QACrCyF,UAAY1I,SAASiD,cAAc,MACnC0F,aAAe3I,SAASiD,cAAc,UAE5CuF,YAAYxC,MAAMC,QAAU,OAC5B0C,aAAa3E,YAAcmE,KAAKlD,YAChC0D,aAAa3C,MAAM4C,SAAW,OAC9BD,aAAa3C,MAAM6C,WAAa,OAChCJ,YAAYzE,YAAcmE,KAAKjD,UAC/BuD,YAAYzC,MAAM4C,SAAW,OAE7BJ,YAAYxN,GAAKkN,UACjBM,YAAY/C,UAAUC,IAAK,UAC3B8C,YAAYtF,YAAYyF,cACxBH,YAAYtF,YAAYwF,WACxBF,YAAYtF,YAAYuF,aACxB9C,YAAYzC,YAAYsF,cArhBhC5O,OAAO+E,GAAG,SAAU/E,SAChBmL,oBACIrD,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7Bb,aAAa,QAASnH,WAE1BA,OAAO+E,GAAG,SAASX,MAAAA,IACf+G,sBACMlD,eAAiBjD,EAAEkK,eAAiBlK,EAAEmK,cAAcD,eAAeE,QAAQ,YAC5EnH,2BAICoH,qBAAuBpH,cAAc1B,OACrC+I,mBAAqB9M,aAAaC,QAAQ,sBAC1C8M,gBAAkBD,oBAAsBD,uBAAyBC,sBAEnE7O,WAAaE,aAAc,IAEL,UAAlBqD,qBACKuL,iBAeLtL,kBAAmB,OACnBC,gBAAiB,KAfbc,EAAEC,iBACFhB,kBAAmB,EACnBC,gBAAiB,EACjBc,EAAEwK,kBACFxK,EAAEyK,+CACQ,gBAAiB,gBAAgB7M,MAAK6D,KACtCzG,OAAO0P,cAAchJ,MAAMD,OAClCxD,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,cACvCsB,YAAW,KACPN,gBAAiB,EACjBD,kBAAmB,IACpB,SAOW,gBAAlBD,qBACKuL,kBACDvK,EAAEC,iBACFD,EAAEwK,kBACFxK,EAAEyK,2BACFnK,iBAEJpB,gBAAiB,GAIzBA,gBAAiB,KAErBlE,OAAO+E,GAAG,QAAQX,MAAAA,IACd+G,gBACI1K,WAAaE,cACb2E,cAGRtF,OAAO+E,GAAG,WAAY/E,SAClBmL,oBACuC,MAAfnL,OAAOyH,KAA8B,MAAfzH,OAAOyH,OACpDzH,OAAO2P,SAAW3P,OAAO4P,UACJnP,WAAaE,cAAkC,UAAlBqD,gBAA8BE,2BAC7EM,YAAW,KACPN,gBAAiB,IAClB,SAGH4D,SAAWM,mBACfpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAC7Bb,aAAa,UAAWnH,WAE3BA,OAAO+E,GAAG,OAAO,WACR8K,gBAAkB7P,OAAOwI,UAAUyC,WAAW,CAACC,OAAQ,SAC7D1I,aAAaM,QAAQ,qBAAsB+M,gBAAgBtJ,WAE/DvG,OAAO+E,GAAG,QAAQ,WACR8K,gBAAkB7P,OAAOwI,UAAUyC,WAAW,CAACC,OAAQ,SAC7D1I,aAAaM,QAAQ,qBAAsB+M,gBAAgBtJ,WAE/DvG,OAAO+E,GAAG,aAAaX,MAAAA,SACnBI,YAAW,KACP2D,oBAAoBnI,QACpBmH,aAAa,YAAanH,UAC3B,MAEPA,OAAO+E,GAAG,WAAWX,MAAAA,SACjBI,YAAW,KACP2D,oBAAoBnI,QACpBmH,aAAa,UAAWnH,UACzB,OAEPA,OAAO+E,GAAG,QAAQ,KACdoG,gBACA3I,aAAa6C,WAAW,yBAE5BrF,OAAO+E,GAAG,cAAc,KACpBoG,mBAEJnL,OAAO+E,GAAG,0BAA2BC,QAC7B8K,KAAO,IAAIC,uBAAa9N,KAAM5B,QAASC,WAAYqD,WAAY3D,OAAQO,UAC3EyB,aAAegD,EAAEgL,UAERhL,EAAEgL,MAGHF,KAAKG,eAFLH,KAAKI,aAIX,MAAOhN,OACDa,aACAA,YAAa,sBACH,gBAAiB,gBAAgBnB,MAAK6D,KACrCzG,OAAO0P,cAAchJ,MAAMD,OACnCxD,OAAMC,OAASf,OAAOgB,QAAQD,MAAMA,UAE3C4M,KAAKI,aACL/N,OAAOgB,QAAQD,MAAM,4BAA6BA,WAI1DlD,OAAO+E,GAAG,eAAe,SAASC,MACZ,qBAAdA,EAAEmL,QAAgC,OAC5BC,WAAapL,EAAEsB,MAEf+J,QAAUD,YAAoC,iBAAfA,aAAgD,IAArBA,WAAWE,UAEvEC,gBAAkBH,WAAWI,SAAWJ,WACxChH,QAAUhD,SAASiD,cAAc,OACrCD,QAAQqH,UAAYF,oBAChBhC,KAAOnF,QAAQgB,aAAehB,QAAQI,WAAa,GACnDkH,WAAatH,QAAQgB,aAAehB,QAAQI,WAAa,GAEzD1B,SAAWM,kBAAiB,MAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,WAEzBqI,QAAS,IACLpM,wBACAA,kBAAmB,EACnBe,EAAEC,sBACFjF,OAAO2Q,YAAYC,aAGjBtB,mBAAqB9M,aAAaC,QAAQ,sBAC1C8M,gBAAkBD,oBAAsBoB,WAAWnK,SAAW+I,sBAEhE7O,WAAaE,cAAkC,UAAlBqD,gBAA8BuL,uBAC3DrL,gBAAiB,OACjBlE,OAAO2Q,YAAYC,OAIvBzJ,aAAa,QAAS,CAClBM,IAAK,IACLC,QAAS,GACTK,cAAe/H,OAAO+H,cACtBC,WAAYhI,OAAOgI,WACnBC,cAAeyI,WACfG,WAAY,CAACC,QAAS3O,OAAOC,SAASC,aAG1CN,WAAWyF,KAAK+G,MAEhBpH,aAAa,WAAY,CACrBM,IAAK,KACLC,QAAS,EACTK,cAAe/H,OAAO+H,cACtBC,WAAYhI,OAAOgI,WACnBE,UAAWqG,KACXsC,WAAY,CAACC,QAAS3O,OAAOC,SAASC,YAMtDrC,OAAO+E,GAAG,SAAS,SAASC,OACpB8C,SAAWM,kBAAiB,GAChCpI,OAAO+H,cAAgBD,SAASC,cAChC/H,OAAOgI,WAAaF,SAASE,eACzBE,UAAYlD,EAAEsC,MAEE,0BAAhBtC,EAAE+L,WAA0D,eAAhB/L,EAAE+L,WAA8B7I,WAAaA,UAAUoC,OAAS,KAE5GvI,WAAWyF,KAAKU,WAEhBlD,EAAEyC,IAAM,KACRzC,EAAE0C,QAAU,EACZ1C,EAAE+C,cAAgBD,SAASC,cAC3B/C,EAAEgD,WAAaF,SAASE,WACxBhD,EAAEkD,UAAYA,UAEdf,aAAa,WAAYnC,OAsbjC7C,OAAO6O,iBAAiB,UAAU,KAC9B9L,cAGJ+L,YAAY/L,SAAUrD"} \ No newline at end of file diff --git a/amd/src/autosaver.js b/amd/src/autosaver.js index 788f3aec..a3948532 100644 --- a/amd/src/autosaver.js +++ b/amd/src/autosaver.js @@ -84,7 +84,7 @@ export const register = (editor, interval, userId, hasApiKey, MODULES, Rubrics, getUser([{ methodname: 'core_user_get_users_by_field', - args: {field: 'id', values: [M.cfg.userId]}, + args: {field: 'id', values: [userid]}, }])[0].done(response => { user = response[0]; }).fail((ex) => {