From ece1e832a724b9993104a453c6b4116661adab10 Mon Sep 17 00:00:00 2001 From: yoannchb-pro <71560747+yoannchb-pro@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:02:21 -0500 Subject: [PATCH] implemented images support for gpt4 --- README.md | 1 + TODO.md | 3 --- assets/images.gif | Bin 0 -> 219082 bytes extension/MoodleGPT.js | 2 +- extension/MoodleGPT.js.map | 2 +- extension/popup/js/gptVersion.js | 11 ++++++++--- src/core/get-response.ts | 26 ++++++++++++++++---------- src/utils/version-support-images.ts | 6 +++--- test/fake-moodle/assets/cat1.jpg | Bin 0 -> 4666 bytes test/fake-moodle/assets/cat2.jpg | Bin 0 -> 22523 bytes test/fake-moodle/css/style.css | 4 ++++ test/fake-moodle/index.html | 17 ++++++++++++++++- 12 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 assets/images.gif create mode 100644 test/fake-moodle/assets/cat1.jpg create mode 100644 test/fake-moodle/assets/cat2.jpg diff --git a/README.md b/README.md index 61d5f81..5fe2fd7 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ Go to "Manage my extensions" on your browser, then click on "Load unpa - Infinite try: click as much as you want on the question (don't forget to reset the question). - Save history: allows you to create a conversation with ChatGPT by saving the previous question with its answer. However, note that it can consume a significant number of tokens. - Include images (only work with gpt-4): allows you to include the images from the question to be send to the chatgpt api. However, note that it can consume a significant number of tokens. +
![Images](./assets/images.gif) ## Internal Features diff --git a/TODO.md b/TODO.md index dcbbce3..8c87e9b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,5 @@ # TODO - Historic for questions (implemented but need testing) -- Image integration for gpt-4 (implemented but need testing) - - Better prompt (Fixe put in order question, Fixe calculation question) -- Support math equation from image stocked in the `data-mathml` attribute - Better webstore assets diff --git a/assets/images.gif b/assets/images.gif new file mode 100644 index 0000000000000000000000000000000000000000..7dd9c2406ee5493c539b47a9f4cc520dd93d4197 GIT binary patch literal 219082 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 emsEQ8PR^_WZoaOp#*W_3&K@Rrue!Madocument.title=n),3e3)}function n(e,n,t,o){return new(t||(t=Promise))((function(r,i){function s(e){try{c(o.next(e))}catch(e){i(e)}}function l(e){try{c(o.throw(e))}catch(e){i(e)}}function c(e){var n;e.done?r(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(s,l)}c((o=o.apply(e,n||[])).next())}))}function t(e,n){const t=e.length>n.length?e.length:n.length;return 0===t?1:(t-function(e,n){if(0===e.length)return n.length;if(0===n.length)return e.length;const t=[],o=e.replace(/\s+/,""),r=n.replace(/\s+/,"");for(let e=0;e<=o.length;++e){t.push([e]);for(let n=1;n<=r.length;++n)t[e][n]=0===e?n:Math.min(t[e-1][n]+1,t[e][n-1]+1,t[e-1][n-1]+(o[e-1]===r[n-1]?0:1))}return t[o.length][r.length]}(e,n))/t}function o(e,n){let o={element:null,similarity:0,value:null};for(const r of n){const n=t(r.value,e);if(1===n)return{element:r.element,value:r.value,similarity:n};n>o.similarity&&(o={element:r.element,value:r.value,similarity:n})}return o}"function"==typeof SuppressedError&&SuppressedError;class r{static question(e){console.log("%c[QUESTION]: %s","color: cyan",e)}static bestAnswer(e,n){console.log("%c[BEST ANSWER]: %s","color: green",`"${e}" with a similarity of ${function(e){return Math.round(100*e*100)/100+"%"}(n)}`)}static array(e){console.log("[CORRECTS] ",e)}static response(e){console.log("Original:\n"+e.response),console.log("Normalized:\n"+e.normalizedResponse)}}function i(e,n=!0){n&&(e=e.toLowerCase());return e.replace(/\n+/gi,"\n").replace(/(\n\s*\n)+/g,"\n").replace(/[ \t]+/gi," ").trim().replace(/^[a-z\d]\.\s/gi,"").replace(/\n[a-z\d]\.\s/gi,"\n")}var s,l;!function(e){e.SYSTEM="system",e.USER="user",e.ASSISTANT="assistant"}(s||(s={})),function(e){e.TEXT="text",e.IMAGE="image_url"}(l||(l={}));const c="\nAct as a quiz solver for the best notation with the following rules:\n- When asked for the result of an equation, provide only the result without any other information and skip the other rules.\n- If no answer(s) are given, answer the statement as usual without following the other rules, providing the most detailed, complete and precise explanation.\n- For 'put in order' questions, provide the position of the answer separated by a new line (e.g., '1\n3\n2') and ignore other rules.- Always reply in this format: '\n\n...'\n- Always reply in the format: '\n\n...'.\n- Retain only the correct answer(s).\n- Maintain the same order for the answers as in the text.\n- Retain all text from the answer with its description, content or definition.\n- Only provide answers that exactly match the given answer in the text.\n- The question always has the correct answer(s), so you should always provide an answer.\n- Always respond in the same language as the user's question.\n".trim(),a={url:null,system:{role:s.SYSTEM,content:c},history:[]};function u(e,t,o){return n(this,void 0,void 0,(function*(){const n=t.querySelectorAll("img");if(!e.includeImages||!function(e){const n=e.match(/gpt-(\d+)/);return!!(null==n?void 0:n[1])&&Number(n[1])>=4}(e.model)||0===n.length)return o;let r=[];const i=Array.from(n).map((e=>{return n=e,new Promise(((e,t)=>{const o=document.createElement("canvas"),r=o.getContext("2d");if(!r)return void e(null);const i=new Image;i.crossOrigin="Anonymous",i.onload=()=>{o.width=i.width,o.height=i.height,r.drawImage(i,0,0);const n=o.toDataURL("image/png");e(n)},i.onerror=e=>{t(e)},i.src=n.src}));var n})),s=(yield Promise.all(i)).filter((e=>null!==e));for(const e of s)r.push({type:l.IMAGE,content:e});return r.length>0?r.push({type:l.TEXT,content:o}):r=o,r}))}function f(e){const n=[],t=Array.from(e.querySelectorAll("tr")),o=[];t.map((e=>{const t=Array.from(e.querySelectorAll("td, th")).map(((e,n)=>{var t;const r=null===(t=e.textContent)||void 0===t?void 0:t.trim();return o[n]=Math.max(o[n]||0,(null==r?void 0:r.length)||0),null!=r?r:""}));n.push(t)}));const r=o.reduce(((e,n)=>e+n))+3*n[0].length+1,i="\n"+Array(r).fill("-").join("")+"\n",s=n.map((e=>"| "+e.map(((e,n)=>e.padEnd(o[n]," "))).join(" | ")+" |"));return s.shift()+i+s.join("\n")}function d(n,t){n.title&&e("Copied to clipboard"),navigator.clipboard.writeText(t.response)}function m(e,n,t){const o=n[0];if(1!==n.length||"true"!==o.getAttribute("contenteditable"))return!1;if(e.typing){let e=0;o.addEventListener("keydown",(function(n){if("Backspace"===n.key&&(e=t.response.length+1),e>t.response.length)return;n.preventDefault(),o.textContent=t.response.slice(0,++e),o.focus();const r=document.createRange();r.selectNodeContents(o),r.collapse(!1);const i=window.getSelection();null!==i&&(i.removeAllRanges(),i.addRange(r))}))}else o.textContent=t.response;return!0}function p(e,n,t){var o,r;const i=n[0];if(1!==n.length||"number"!==i.type)return!1;const s=null===(r=null===(o=t.normalizedResponse.match(/\d+([,.]\d+)?/gi))||void 0===o?void 0:o[0])||void 0===r?void 0:r.replace(",",".");if(void 0===s)return!1;if(e.typing){let e=0;i.addEventListener("keydown",(function(n){n.preventDefault(),"Backspace"===n.key&&(e=s.length+1),e>s.length||("."===s.slice(e,e+1)&&++e,i.value=s.slice(0,++e))}))}else i.value=s;return!0}function h(e,n,t){const s=null==n?void 0:n[0];if(!s||"radio"!==s.type)return!1;const l=Array.from(n).map((e=>{var n,t;return{element:e,value:i(null!==(t=null===(n=null==e?void 0:e.parentElement)||void 0===n?void 0:n.textContent)&&void 0!==t?t:"")}})).filter((e=>""!==e.value)),c=o(t.normalizedResponse,l);e.logs&&c.value&&r.bestAnswer(c.value,c.similarity);const a=c.element;return e.mouseover?a.addEventListener("mouseover",(()=>a.checked=!0),{once:!0}):a.checked=!0,!0}function g(e,n,t){const s=null==n?void 0:n[0];if(!s||"checkbox"!==s.type)return!1;const l=t.normalizedResponse.split("\n"),c=Array.from(n).map((e=>{var n,t;return{element:e,value:i(null!==(t=null===(n=null==e?void 0:e.parentElement)||void 0===n?void 0:n.textContent)&&void 0!==t?t:"")}})).filter((e=>""!==e.value));for(const n of l){const t=o(n,c);e.logs&&t.value&&r.bestAnswer(t.value,t.similarity);const i=t.element;e.mouseover?i.addEventListener("mouseover",(()=>i.checked=!0),{once:!0}):i.checked=!0}return!0}function v(e,n,t){if(0===n.length||"SELECT"!==n[0].tagName)return!1;const s=t.normalizedResponse.split("\n");e.logs&&r.array(s);for(let t=0;t{var n;return{element:e,value:i(null!==(n=e.textContent)&&void 0!==n?n:"")}})).filter((e=>""!==e.value)),a=o(s[t],c);e.logs&&a.value&&r.bestAnswer(a.value,a.similarity);const u=a.element,f=u.closest("select");null!==f&&(e.mouseover?f.addEventListener("click",(()=>u.selected=!0),{once:!0}):u.selected=!0)}return!0}function y(e,n,t){const o=n[0];if(1!==n.length||"TEXTAREA"!==o.tagName&&"text"!==o.type)return!1;if(e.typing){let e=0;o.addEventListener("keydown",(function(n){n.preventDefault(),"Backspace"===n.key&&(e=t.response.length+1),e>t.response.length||(o.value=t.response.slice(0,++e))}))}else o.value=t.response;return!0}function w(e){return n(this,void 0,void 0,(function*(){e.config.cursor&&(e.questionElement.style.cursor="wait");const t=function(e){let n=e.innerText;const t=e.querySelectorAll(".accesshide");for(const e of t)n=n.replace(e.innerText,"");const o=e.querySelectorAll(".qtext table");for(const e of o)n=n.replace(e.innerText,"\n"+f(e)+"\n");return i(n,!1)}(e.form),o=e.form.querySelectorAll(e.inputQuery),l=yield function(e,t,o){return n(this,void 0,void 0,(function*(){const n=location.hostname+location.pathname;e.history&&a.url===n||(a.url=n,a.history=[]);const r=new AbortController,l=setTimeout((()=>r.abort()),15e3),c=yield u(e,t,o),f={role:s.USER,content:c},d=yield fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},signal:e.timeout?r.signal:null,body:JSON.stringify({model:e.model,messages:[a.system,...a.history,f],temperature:.8,top_p:1,presence_penalty:1,stop:null})});clearTimeout(l);const m=(yield d.json()).choices[0].message.content;return e.history&&(a.history.push(f),a.history.push({role:s.ASSISTANT,content:m})),{question:o,response:m,normalizedResponse:i(m)}}))}(e.config,e.questionElement,t).catch((e=>({error:e}))),c="object"==typeof l&&"error"in l;if(e.config.cursor&&(e.questionElement.style.cursor=e.config.infinite||c?"pointer":"initial"),c)console.error(l.error);else switch(e.config.logs&&(r.question(t),r.response(l)),e.config.mode){case"clipboard":!function(e){e.config.infinite||e.removeListener(),d(e.config,e.gptAnswer)}({config:e.config,questionElement:e.questionElement,gptAnswer:l,removeListener:e.removeListener});break;case"question-to-answer":!function(e){const n=e.questionElement;e.removeListener();const t=n.textContent;n.textContent=e.gptAnswer.response,n.style.whiteSpace="pre-wrap";let o=!0;n.addEventListener("click",(function(){n.style.whiteSpace=o?"":"pre-warp",n.textContent=o?t:e.gptAnswer.response,o=!o}))}({gptAnswer:l,questionElement:e.questionElement,removeListener:e.removeListener});break;case"autocomplete":!function(e){e.config.infinite||e.removeListener();const n=[m,y,p,v,h,g];for(const t of n)if(t(e.config,e.inputList,e.gptAnswer))return;d(e.config,e.gptAnswer)}({config:e.config,gptAnswer:l,inputList:o,questionElement:e.questionElement,removeListener:e.removeListener})}}))}const A=[],E=[];function S(e){const n=E.findIndex((n=>n.element===e));if(-1!==n){const e=E.splice(n,1)[0];e.element.removeEventListener("click",e.fn)}}function x(n){if(E.length>0){for(const e of E)n.cursor&&(e.element.style.cursor="initial"),e.element.removeEventListener("click",e.fn);return n.title&&e("Removed"),void(E.length=0)}const t=["checkbox","radio","text","number"].map((e=>`input[type="${e}"]`)).join(",")+", textarea, select, [contenteditable]",o=document.querySelectorAll(".formulation");for(const e of o){const o=e.querySelector(".qtext");if(null===o)continue;n.cursor&&(o.style.cursor="pointer");const r=w.bind(null,{config:n,questionElement:o,form:e,inputQuery:t,removeListener:()=>S(o)});E.push({element:o,fn:r}),o.addEventListener("click",r)}n.title&&e("Injected")}chrome.storage.sync.get(["moodleGPT"]).then((function(e){const n=e.moodleGPT;if(!n)throw new Error("Please configure MoodleGPT into the extension");n.code?function(e){document.body.addEventListener("keydown",(function(n){A.push(n.key),A.length>e.code.length&&A.shift(),A.join("")===e.code&&(A.length=0,x(e))}))}(n):x(n)}))})); +!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";function e(e){const n=document.title;document.title=e,setTimeout((()=>document.title=n),3e3)}function n(e,n,t,o){return new(t||(t=Promise))((function(r,i){function s(e){try{c(o.next(e))}catch(e){i(e)}}function l(e){try{c(o.throw(e))}catch(e){i(e)}}function c(e){var n;e.done?r(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(s,l)}c((o=o.apply(e,n||[])).next())}))}function t(e,n){const t=e.length>n.length?e.length:n.length;return 0===t?1:(t-function(e,n){if(0===e.length)return n.length;if(0===n.length)return e.length;const t=[],o=e.replace(/\s+/,""),r=n.replace(/\s+/,"");for(let e=0;e<=o.length;++e){t.push([e]);for(let n=1;n<=r.length;++n)t[e][n]=0===e?n:Math.min(t[e-1][n]+1,t[e][n-1]+1,t[e-1][n-1]+(o[e-1]===r[n-1]?0:1))}return t[o.length][r.length]}(e,n))/t}function o(e,n){let o={element:null,similarity:0,value:null};for(const r of n){const n=t(r.value,e);if(1===n)return{element:r.element,value:r.value,similarity:n};n>o.similarity&&(o={element:r.element,value:r.value,similarity:n})}return o}"function"==typeof SuppressedError&&SuppressedError;class r{static question(e){console.log("%c[QUESTION]: %s","color: cyan",e)}static bestAnswer(e,n){console.log("%c[BEST ANSWER]: %s","color: green",`"${e}" with a similarity of ${function(e){return Math.round(100*e*100)/100+"%"}(n)}`)}static array(e){console.log("[CORRECTS] ",e)}static response(e){console.log("Original:\n"+e.response),console.log("Normalized:\n"+e.normalizedResponse)}}function i(e,n=!0){n&&(e=e.toLowerCase());return e.replace(/\n+/gi,"\n").replace(/(\n\s*\n)+/g,"\n").replace(/[ \t]+/gi," ").trim().replace(/^[a-z\d]\.\s/gi,"").replace(/\n[a-z\d]\.\s/gi,"\n")}function s(e){const n=e.match(/gpt-(\d+)/);return!!(null==n?void 0:n[1])&&Number(n[1])>=4}var l,c;!function(e){e.SYSTEM="system",e.USER="user",e.ASSISTANT="assistant"}(l||(l={})),function(e){e.TEXT="text",e.IMAGE="image_url"}(c||(c={}));const a="\nAct as a quiz solver for the best notation with the following rules:\n- When asked for the result of an equation, provide only the result without any other information and skip the other rules.\n- If no answer(s) are given, answer the statement as usual without following the other rules, providing the most detailed, complete and precise explanation.\n- For 'put in order' questions, provide the position of the answer separated by a new line (e.g., '1\n3\n2') and ignore other rules.- Always reply in this format: '\n\n...'\n- Always reply in the format: '\n\n...'.\n- Retain only the correct answer(s).\n- Maintain the same order for the answers as in the text.\n- Retain all text from the answer with its description, content or definition.\n- Only provide answers that exactly match the given answer in the text.\n- The question always has the correct answer(s), so you should always provide an answer.\n- Always respond in the same language as the user's question.\n".trim(),u={url:null,system:{role:l.SYSTEM,content:a},history:[]};function f(e,t,o){return n(this,void 0,void 0,(function*(){const n=t.querySelectorAll("img");if(e.includeImages&&s(e.model)&&0===n.length)return o;let r=[];const i=Array.from(n).map((e=>{return n=e,new Promise(((e,t)=>{const o=document.createElement("canvas"),r=o.getContext("2d");if(!r)return void e(null);const i=new Image;i.crossOrigin="Anonymous",i.onload=()=>{o.width=i.width,o.height=i.height,r.drawImage(i,0,0);const n=o.toDataURL("image/png");e(n)},i.onerror=e=>{t(e)},i.src=n.src}));var n})),l=(yield Promise.all(i)).filter((e=>null!==e));for(const e of l)r.push({type:c.IMAGE,image_url:{url:e}});return r.length>0?r.push({type:c.TEXT,text:o}):r=o,r}))}function d(e){const n=[],t=Array.from(e.querySelectorAll("tr")),o=[];t.map((e=>{const t=Array.from(e.querySelectorAll("td, th")).map(((e,n)=>{var t;const r=null===(t=e.textContent)||void 0===t?void 0:t.trim();return o[n]=Math.max(o[n]||0,(null==r?void 0:r.length)||0),null!=r?r:""}));n.push(t)}));const r=o.reduce(((e,n)=>e+n))+3*n[0].length+1,i="\n"+Array(r).fill("-").join("")+"\n",s=n.map((e=>"| "+e.map(((e,n)=>e.padEnd(o[n]," "))).join(" | ")+" |"));return s.shift()+i+s.join("\n")}function m(n,t){n.title&&e("Copied to clipboard"),navigator.clipboard.writeText(t.response)}function p(e,n,t){const o=n[0];if(1!==n.length||"true"!==o.getAttribute("contenteditable"))return!1;if(e.typing){let e=0;o.addEventListener("keydown",(function(n){if("Backspace"===n.key&&(e=t.response.length+1),e>t.response.length)return;n.preventDefault(),o.textContent=t.response.slice(0,++e),o.focus();const r=document.createRange();r.selectNodeContents(o),r.collapse(!1);const i=window.getSelection();null!==i&&(i.removeAllRanges(),i.addRange(r))}))}else o.textContent=t.response;return!0}function h(e,n,t){var o,r;const i=n[0];if(1!==n.length||"number"!==i.type)return!1;const s=null===(r=null===(o=t.normalizedResponse.match(/\d+([,.]\d+)?/gi))||void 0===o?void 0:o[0])||void 0===r?void 0:r.replace(",",".");if(void 0===s)return!1;if(e.typing){let e=0;i.addEventListener("keydown",(function(n){n.preventDefault(),"Backspace"===n.key&&(e=s.length+1),e>s.length||("."===s.slice(e,e+1)&&++e,i.value=s.slice(0,++e))}))}else i.value=s;return!0}function g(e,n,t){const s=null==n?void 0:n[0];if(!s||"radio"!==s.type)return!1;const l=Array.from(n).map((e=>{var n,t;return{element:e,value:i(null!==(t=null===(n=null==e?void 0:e.parentElement)||void 0===n?void 0:n.textContent)&&void 0!==t?t:"")}})).filter((e=>""!==e.value)),c=o(t.normalizedResponse,l);e.logs&&c.value&&r.bestAnswer(c.value,c.similarity);const a=c.element;return e.mouseover?a.addEventListener("mouseover",(()=>a.checked=!0),{once:!0}):a.checked=!0,!0}function v(e,n,t){const s=null==n?void 0:n[0];if(!s||"checkbox"!==s.type)return!1;const l=t.normalizedResponse.split("\n"),c=Array.from(n).map((e=>{var n,t;return{element:e,value:i(null!==(t=null===(n=null==e?void 0:e.parentElement)||void 0===n?void 0:n.textContent)&&void 0!==t?t:"")}})).filter((e=>""!==e.value));for(const n of l){const t=o(n,c);e.logs&&t.value&&r.bestAnswer(t.value,t.similarity);const i=t.element;e.mouseover?i.addEventListener("mouseover",(()=>i.checked=!0),{once:!0}):i.checked=!0}return!0}function y(e,n,t){if(0===n.length||"SELECT"!==n[0].tagName)return!1;const s=t.normalizedResponse.split("\n");e.logs&&r.array(s);for(let t=0;t{var n;return{element:e,value:i(null!==(n=e.textContent)&&void 0!==n?n:"")}})).filter((e=>""!==e.value)),a=o(s[t],c);e.logs&&a.value&&r.bestAnswer(a.value,a.similarity);const u=a.element,f=u.closest("select");null!==f&&(e.mouseover?f.addEventListener("click",(()=>u.selected=!0),{once:!0}):u.selected=!0)}return!0}function w(e,n,t){const o=n[0];if(1!==n.length||"TEXTAREA"!==o.tagName&&"text"!==o.type)return!1;if(e.typing){let e=0;o.addEventListener("keydown",(function(n){n.preventDefault(),"Backspace"===n.key&&(e=t.response.length+1),e>t.response.length||(o.value=t.response.slice(0,++e))}))}else o.value=t.response;return!0}function A(e){return n(this,void 0,void 0,(function*(){e.config.cursor&&(e.questionElement.style.cursor="wait");const t=function(e){let n=e.innerText;const t=e.querySelectorAll(".accesshide");for(const e of t)n=n.replace(e.innerText,"");const o=e.querySelectorAll(".qtext table");for(const e of o)n=n.replace(e.innerText,"\n"+d(e)+"\n");return i(n,!1)}(e.form),o=e.form.querySelectorAll(e.inputQuery),c=yield function(e,t,o){return n(this,void 0,void 0,(function*(){const n=location.hostname+location.pathname;e.history&&u.url===n||(u.url=n,u.history=[]);const r=new AbortController,c=setTimeout((()=>r.abort()),15e3),a=yield f(e,t,o),d={role:l.USER,content:a},m=yield fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},signal:e.timeout?r.signal:null,body:JSON.stringify(Object.assign({model:e.model,messages:[u.system,...u.history,d],temperature:.8,top_p:1,presence_penalty:1},s(e.model)?{max_tokens:1e3}:{stop:null}))});clearTimeout(c);const p=(yield m.json()).choices[0].message.content;return e.history&&(u.history.push(d),u.history.push({role:l.ASSISTANT,content:p})),{question:o,response:p,normalizedResponse:i(p)}}))}(e.config,e.questionElement,t).catch((e=>({error:e}))),a="object"==typeof c&&"error"in c;if(e.config.cursor&&(e.questionElement.style.cursor=e.config.infinite||a?"pointer":"initial"),a)console.error(c.error);else switch(e.config.logs&&(r.question(t),r.response(c)),e.config.mode){case"clipboard":!function(e){e.config.infinite||e.removeListener(),m(e.config,e.gptAnswer)}({config:e.config,questionElement:e.questionElement,gptAnswer:c,removeListener:e.removeListener});break;case"question-to-answer":!function(e){const n=e.questionElement;e.removeListener();const t=n.textContent;n.textContent=e.gptAnswer.response,n.style.whiteSpace="pre-wrap";let o=!0;n.addEventListener("click",(function(){n.style.whiteSpace=o?"":"pre-warp",n.textContent=o?t:e.gptAnswer.response,o=!o}))}({gptAnswer:c,questionElement:e.questionElement,removeListener:e.removeListener});break;case"autocomplete":!function(e){e.config.infinite||e.removeListener();const n=[p,w,h,y,g,v];for(const t of n)if(t(e.config,e.inputList,e.gptAnswer))return;m(e.config,e.gptAnswer)}({config:e.config,gptAnswer:c,inputList:o,questionElement:e.questionElement,removeListener:e.removeListener})}}))}const E=[],x=[];function S(e){const n=x.findIndex((n=>n.element===e));if(-1!==n){const e=x.splice(n,1)[0];e.element.removeEventListener("click",e.fn)}}function q(n){if(x.length>0){for(const e of x)n.cursor&&(e.element.style.cursor="initial"),e.element.removeEventListener("click",e.fn);return n.title&&e("Removed"),void(x.length=0)}const t=["checkbox","radio","text","number"].map((e=>`input[type="${e}"]`)).join(",")+", textarea, select, [contenteditable]",o=document.querySelectorAll(".formulation");for(const e of o){const o=e.querySelector(".qtext");if(null===o)continue;n.cursor&&(o.style.cursor="pointer");const r=A.bind(null,{config:n,questionElement:o,form:e,inputQuery:t,removeListener:()=>S(o)});x.push({element:o,fn:r}),o.addEventListener("click",r)}n.title&&e("Injected")}chrome.storage.sync.get(["moodleGPT"]).then((function(e){const n=e.moodleGPT;if(!n)throw new Error("Please configure MoodleGPT into the extension");n.code?function(e){document.body.addEventListener("keydown",(function(n){E.push(n.key),E.length>e.code.length&&E.shift(),E.join("")===e.code&&(E.length=0,q(e))}))}(n):q(n)}))})); //# sourceMappingURL=MoodleGPT.js.map diff --git a/extension/MoodleGPT.js.map b/extension/MoodleGPT.js.map index 1e7abaf..9fd19cf 100644 --- a/extension/MoodleGPT.js.map +++ b/extension/MoodleGPT.js.map @@ -1 +1 @@ -{"version":3,"file":"MoodleGPT.js","sources":["../src/utils/title-indications.ts","../node_modules/tslib/tslib.es6.js","../src/utils/pick-best-response.ts","../src/utils/logs.ts","../src/utils/normalize-text.ts","../src/core/get-response.ts","../src/utils/version-support-images.ts","../src/utils/image-to-base64.ts","../src/utils/html-table-to-string.ts","../src/core/questions/clipboard.ts","../src/core/questions/contenteditable.ts","../src/core/questions/number.ts","../src/core/questions/radio.ts","../src/core/questions/checkbox.ts","../src/core/questions/select.ts","../src/core/questions/textbox.ts","../src/core/reply.ts","../src/core/create-question.ts","../src/core/modes/clipboard.ts","../src/core/modes/question-to-answer.ts","../src/core/modes/autocomplete.ts","../src/core/code-listener.ts","../src/index.ts"],"sourcesContent":["/**\n * Show some informations into the document title and remove it after 3000ms\n * @param text\n */\nfunction titleIndications(text: string) {\n const backTitle = document.title;\n document.title = text;\n setTimeout(() => (document.title = backTitle), 3000);\n}\n\nexport default titleIndications;\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n function next() {\r\n while (env.stack.length) {\r\n var rec = env.stack.pop();\r\n try {\r\n var result = rec.dispose && rec.dispose.call(rec.value);\r\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n};\r\n","type BestResponse = {\n similarity: number;\n value: string | null;\n element: HTMLElement | null;\n};\n\ntype ResponsesBySimilarity = {\n similarity: number;\n value: string;\n element: HTMLElement;\n};\n\n/**\n * Calculate the levenshtein distance between two sentence\n * @param str1\n * @param str2\n * @returns\n */\nfunction levenshteinDistance(str1: string, str2: string) {\n if (str1.length === 0) return str2.length;\n if (str2.length === 0) return str1.length;\n\n const matrix: number[][] = [];\n const str1WithoutSpaces = str1.replace(/\\s+/, '');\n const str2WithoutSpaces = str2.replace(/\\s+/, '');\n\n for (let i = 0; i <= str1WithoutSpaces.length; ++i) {\n matrix.push([i]);\n for (let j = 1; j <= str2WithoutSpaces.length; ++j) {\n matrix[i][j] =\n i === 0\n ? j\n : Math.min(\n matrix[i - 1][j] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j - 1] + (str1WithoutSpaces[i - 1] === str2WithoutSpaces[j - 1] ? 0 : 1)\n );\n }\n }\n\n return matrix[str1WithoutSpaces.length][str2WithoutSpaces.length];\n}\n\n/**\n * Calculate the similarity between two sentences from 0 to 1 (best)\n * @param str1\n * @param str2\n * @returns\n */\nfunction sentenceSimilarity(str1: string, str2: string) {\n const longerLength = str1.length > str2.length ? str1.length : str2.length;\n if (longerLength === 0) return 1;\n return (longerLength - levenshteinDistance(str1, str2)) / longerLength;\n}\n\n/**\n * Pick the best sentence that correspond to the answer\n * @param arr\n * @param answer\n * @returns\n */\nexport function pickBestReponse(\n answer: string,\n arr: { element: HTMLElement; value: string }[]\n): BestResponse {\n let bestResponse: BestResponse = {\n element: null,\n similarity: 0,\n value: null\n };\n for (const obj of arr) {\n const similarity = sentenceSimilarity(obj.value, answer);\n if (similarity === 1) {\n return { element: obj.element, value: obj.value, similarity };\n }\n if (similarity > bestResponse.similarity) {\n bestResponse = { element: obj.element, value: obj.value, similarity };\n }\n }\n return bestResponse;\n}\n\n/**\n * Return the sentences sorted by score with a score superior or equal to what is asked\n * @param answer\n * @param arr\n * @param score\n * @returns\n */\nexport function pickResponsesWithSimilarityGreaterThan(\n answer: string,\n arr: { element: HTMLElement; value: string }[],\n score: number\n): ResponsesBySimilarity[] {\n const responses: ResponsesBySimilarity[] = [];\n for (const obj of arr) {\n const similarity = sentenceSimilarity(obj.value, answer);\n if (similarity >= score)\n responses.push({\n similarity,\n value: obj.value,\n element: obj.element\n });\n }\n return responses.sort((a, b) => a.similarity - b.similarity);\n}\n\n/**\n * Convert a number to a readable string pourcentage\n * @param similarity\n */\nexport function toPourcentage(similarity: number): string {\n return Math.round(similarity * 100 * 100) / 100 + '%';\n}\n","import GPTAnswer from '@typing/gptAnswer';\nimport { toPourcentage } from './pick-best-response';\n\nclass Logs {\n static question(text: string) {\n const css = 'color: cyan';\n console.log('%c[QUESTION]: %s', css, text);\n }\n\n static bestAnswer(answer: string, similarity: number) {\n const css = 'color: green';\n console.log(\n '%c[BEST ANSWER]: %s',\n css,\n `\"${answer}\" with a similarity of ${toPourcentage(similarity)}`\n );\n }\n\n static array(arr: unknown[]) {\n console.log('[CORRECTS] ', arr);\n }\n\n static response(gptAnswer: GPTAnswer) {\n console.log('Original:\\n' + gptAnswer.response);\n console.log('Normalized:\\n' + gptAnswer.normalizedResponse);\n }\n}\n\nexport default Logs;\n","/**\n * Normlize text\n * @param text\n */\nfunction normalizeText(text: string, toLowerCase: boolean = true) {\n if (toLowerCase) text = text.toLowerCase();\n\n const normalizedText = text\n .replace(/\\n+/gi, '\\n') //remove duplicate new lines\n .replace(/(\\n\\s*\\n)+/g, '\\n') //remove useless white space from textcontent\n .replace(/[ \\t]+/gi, ' ') //replace multiples space or tabs by a space\n .trim()\n // We remove the following content because sometimes ChatGPT will reply: \"answer d\"\n .replace(/^[a-z\\d]\\.\\s/gi, '') //a. text, b. text, c. text, 1. text, 2. text, 3.text\n .replace(/\\n[a-z\\d]\\.\\s/gi, '\\n'); //same but with new line\n\n return normalizedText;\n}\n\nexport default normalizeText;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport imageToBase64 from '@utils/image-to-base64';\nimport normalizeText from '@utils/normalize-text';\nimport isCurrentVersionSupportingImages from '@utils/version-support-images';\n\ntype Content =\n | string\n | Array<{\n type: CONTENT_TYPE;\n content: string;\n }>;\n\ntype History = {\n url: string | null;\n system: { role: ROLE; content: Content };\n history: { role: ROLE; content: Content }[];\n};\n\nenum ROLE {\n SYSTEM = 'system',\n USER = 'user',\n ASSISTANT = 'assistant'\n}\n\nenum CONTENT_TYPE {\n TEXT = 'text',\n IMAGE = 'image_url'\n}\n\nconst INSTRUCTION: string = `\nAct as a quiz solver for the best notation with the following rules:\n- When asked for the result of an equation, provide only the result without any other information and skip the other rules.\n- If no answer(s) are given, answer the statement as usual without following the other rules, providing the most detailed, complete and precise explanation.\n- For 'put in order' questions, provide the position of the answer separated by a new line (e.g., '1\\n3\\n2') and ignore other rules.- Always reply in this format: '\\n\\n...'\n- Always reply in the format: '\\n\\n...'.\n- Retain only the correct answer(s).\n- Maintain the same order for the answers as in the text.\n- Retain all text from the answer with its description, content or definition.\n- Only provide answers that exactly match the given answer in the text.\n- The question always has the correct answer(s), so you should always provide an answer.\n- Always respond in the same language as the user's question.\n`.trim();\n\nconst history: History = {\n url: null,\n system: {\n role: ROLE.SYSTEM,\n content: INSTRUCTION\n },\n history: []\n};\n\n/**\n * Get the content to send to ChatGPT API (it allows to includes images if supported)\n * @param config\n */\nasync function getContent(\n config: Config,\n questionElement: HTMLElement,\n question: string\n): Promise {\n const imagesElements = questionElement.querySelectorAll('img');\n\n if (\n !config.includeImages ||\n !isCurrentVersionSupportingImages(config.model) ||\n imagesElements.length === 0\n ) {\n return question;\n }\n\n let content: Content = [];\n\n const base64Images = Array.from(imagesElements).map(imgEl => imageToBase64(imgEl));\n const results = await Promise.all(base64Images);\n const filteredResults = results.filter(value => value !== null) as string[];\n\n for (const result of filteredResults) {\n content.push({\n type: CONTENT_TYPE.IMAGE,\n content: result\n });\n }\n\n if (content.length > 0) {\n content.push({\n type: CONTENT_TYPE.TEXT,\n content: question\n });\n } else {\n content = question;\n }\n\n return content;\n}\n\n/**\n * Get the response from chatGPT api\n * @param config\n * @param question\n * @returns\n */\nasync function getChatGPTResponse(\n config: Config,\n questionElement: HTMLElement,\n question: string\n): Promise {\n const URL = location.hostname + location.pathname;\n\n // We reset the history when we enter a new moodle quiz or when it's desactivate\n if (!config.history || history.url !== URL) {\n history.url = URL;\n history.history = [];\n }\n\n const controller = new AbortController();\n const timeoutControler = setTimeout(() => controller.abort(), 15 * 1000);\n\n const content = await getContent(config, questionElement, question);\n const message = { role: ROLE.USER, content };\n\n const req = await fetch('https://api.openai.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`\n },\n signal: config.timeout ? controller.signal : null,\n body: JSON.stringify({\n model: config.model,\n messages: [history.system, ...history.history, message],\n temperature: 0.8,\n top_p: 1.0,\n presence_penalty: 1.0,\n stop: null\n })\n });\n\n clearTimeout(timeoutControler);\n\n const rep = await req.json();\n const response = rep.choices[0].message.content;\n\n // Register the conversation\n if (config.history) {\n history.history.push(message);\n history.history.push({ role: ROLE.ASSISTANT, content: response });\n }\n\n return {\n question,\n response,\n normalizedResponse: normalizeText(response)\n };\n}\n\nexport default getChatGPTResponse;\n","/**\r\n * Check if the current ChatGPT version support image sending\r\n * @param version\r\n * @returns\r\n */\r\nfunction isCurrentVersionSupportingImages(version: string): boolean {\r\n const versionNumber = version.match(/gpt-(\\d+)/);\r\n if (!versionNumber?.[1]) {\r\n return false;\r\n }\r\n return Number(versionNumber[1]) >= 4;\r\n}\r\n\r\nexport default isCurrentVersionSupportingImages;\r\n","/**\r\n * Convert an image html element into a base64 image string\r\n * @param imageElement\r\n * @returns\r\n */\r\nfunction imageToBase64(imageElement: HTMLImageElement): Promise {\r\n return new Promise((resolve, reject) => {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n\r\n if (!ctx) {\r\n resolve(null);\r\n return;\r\n }\r\n\r\n const img = new Image();\r\n img.crossOrigin = 'Anonymous';\r\n img.onload = () => {\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n ctx.drawImage(img, 0, 0);\r\n\r\n const base64 = canvas.toDataURL('image/png');\r\n resolve(base64);\r\n };\r\n img.onerror = error => {\r\n reject(error);\r\n };\r\n\r\n img.src = imageElement.src;\r\n });\r\n}\r\n\r\nexport default imageToBase64;\r\n","/**\n * Convert table to representating string table\n * @param table\n * @returns\n */\nfunction htmlTableToString(table: HTMLTableElement) {\n const tab: string[][] = [];\n const lines = Array.from(table.querySelectorAll('tr'));\n const maxColumnsLength: number[] = [];\n lines.map(line => {\n const cells = Array.from(line.querySelectorAll('td, th'));\n const cellsContent = cells.map((cell, index) => {\n const content = cell.textContent?.trim();\n maxColumnsLength[index] = Math.max(maxColumnsLength[index] || 0, content?.length || 0);\n return content ?? '';\n });\n tab.push(cellsContent);\n });\n\n const lineSeparationSize = maxColumnsLength.reduce((a, b) => a + b) + tab[0].length * 3 + 1;\n const lineSeparation = '\\n' + Array(lineSeparationSize).fill('-').join('') + '\\n';\n\n const mappedTab = tab.map(line => {\n const mappedLine = line.map((content, index) =>\n content.padEnd(\n maxColumnsLength[index],\n '\\u00A0' // For no matching with \\s\n )\n );\n return '| ' + mappedLine.join(' | ') + ' |';\n });\n const head = mappedTab.shift();\n return head + lineSeparation + mappedTab.join('\\n');\n}\n\nexport default htmlTableToString;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport titleIndications from '@utils/title-indications';\n\n/**\n * Copy the response in the clipboard if we can automaticaly fill the question\n * @param config\n * @param gptAnswer\n */\nfunction handleClipboard(config: Config, gptAnswer: GPTAnswer) {\n if (config.title) titleIndications('Copied to clipboard');\n navigator.clipboard.writeText(gptAnswer.response);\n}\n\nexport default handleClipboard;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Hanlde contenteditable elements\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleContentEditable(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0];\n\n if (\n inputList.length !== 1 || // for now we don't handle many input for editable textcontent\n input.getAttribute('contenteditable') !== 'true'\n ) {\n return false;\n }\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: KeyboardEvent) {\n if (event.key === 'Backspace') index = gptAnswer.response.length + 1;\n if (index > gptAnswer.response.length) return;\n event.preventDefault();\n input.textContent = gptAnswer.response.slice(0, ++index);\n\n // Put the cursor at the end of the typed text\n input.focus();\n const range = document.createRange();\n range.selectNodeContents(input);\n range.collapse(false);\n const selection = window.getSelection();\n if (selection !== null) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n });\n } else {\n input.textContent = gptAnswer.response;\n }\n\n return true;\n}\n\nexport default handleContentEditable;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Handle number input\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleNumber(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0] as HTMLInputElement | HTMLTextAreaElement;\n\n if (\n inputList.length !== 1 || // for now we don't handle many input number\n input.type !== 'number'\n ) {\n return false;\n }\n\n const number = gptAnswer.normalizedResponse.match(/\\d+([,.]\\d+)?/gi)?.[0]?.replace(',', '.');\n\n if (number === undefined) return false;\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: Event) {\n event.preventDefault();\n if ((event).key === 'Backspace') index = number.length + 1;\n if (index > number.length) return;\n if (number.slice(index, index + 1) === '.') ++index;\n input.value = number.slice(0, ++index);\n });\n } else {\n input.value = number;\n }\n\n return true;\n}\n\nexport default handleNumber;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle input radio elements\n * @param config\n * @param inputList\n * @param gptAnswer\n */\nfunction handleRadio(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const firstInput = inputList?.[0] as HTMLInputElement;\n\n // Handle the case the input is not a radio\n if (!firstInput || firstInput.type !== 'radio') {\n return false;\n }\n\n const possibleAnswers = Array.from(inputList)\n .map(inp => ({\n element: inp,\n value: normalizeText(inp?.parentElement?.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n const bestAnswer = pickBestReponse(gptAnswer.normalizedResponse, possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctInput = bestAnswer.element as HTMLInputElement;\n if (config.mouseover) {\n correctInput.addEventListener('mouseover', () => (correctInput.checked = true), {\n once: true\n });\n } else {\n correctInput.checked = true;\n }\n\n return true;\n}\n\nexport default handleRadio;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle input checkbox elements\n * @param config\n * @param inputList\n * @param gptAnswer\n */\nfunction handleCheckbox(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const firstInput = inputList?.[0] as HTMLInputElement;\n\n // Handle the case the input is not a checkbox\n if (!firstInput || firstInput.type !== 'checkbox') {\n return false;\n }\n\n const corrects = gptAnswer.normalizedResponse.split('\\n');\n\n const possibleAnswers = Array.from(inputList)\n .map(inp => ({\n element: inp,\n value: normalizeText(inp?.parentElement?.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n for (const correct of corrects) {\n const bestAnswer = pickBestReponse(correct, possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctInput = bestAnswer.element as HTMLInputElement;\n if (config.mouseover) {\n correctInput.addEventListener('mouseover', () => (correctInput.checked = true), {\n once: true\n });\n } else {\n correctInput.checked = true;\n }\n }\n\n return true;\n}\n\nexport default handleCheckbox;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle select elements (and put in order select)\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleSelect(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n if (inputList.length === 0 || inputList[0].tagName !== 'SELECT') return false;\n\n const corrects = gptAnswer.normalizedResponse.split('\\n');\n\n if (config.logs) Logs.array(corrects);\n\n for (let i = 0; i < inputList.length; ++i) {\n if (!corrects[i]) break;\n\n const options = inputList[i].querySelectorAll('option');\n\n const possibleAnswers = Array.from(options)\n .map(opt => ({\n element: opt,\n value: normalizeText(opt.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n const bestAnswer = pickBestReponse(corrects[i], possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctOption = bestAnswer.element as HTMLOptionElement;\n const currentSelect = correctOption.closest('select');\n\n if (currentSelect === null) continue;\n\n if (config.mouseover) {\n currentSelect.addEventListener('click', () => (correctOption.selected = true), {\n once: true\n });\n } else {\n correctOption.selected = true;\n }\n }\n\n return true;\n}\n\nexport default handleSelect;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Handle textbox\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleTextbox(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0] as HTMLInputElement | HTMLTextAreaElement;\n\n if (\n inputList.length !== 1 || // for now we don't handle many input text\n (input.tagName !== 'TEXTAREA' && input.type !== 'text')\n ) {\n return false;\n }\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: Event) {\n event.preventDefault();\n if ((event).key === 'Backspace') {\n index = gptAnswer.response.length + 1;\n }\n if (index > gptAnswer.response.length) return;\n input.value = gptAnswer.response.slice(0, ++index);\n });\n } else {\n input.value = gptAnswer.response;\n }\n\n return true;\n}\n\nexport default handleTextbox;\n","import type Config from '@typing/config';\nimport Logs from '@utils/logs';\nimport getChatGPTResponse from './get-response';\nimport createAndNormalizeQuestion from './create-question';\nimport clipboardMode from './modes/clipboard';\nimport questionToAnswerMode from './modes/question-to-answer';\nimport autoCompleteMode from './modes/autocomplete';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n form: HTMLElement;\n inputQuery: string;\n removeListener: () => void;\n};\n\n/**\n * Reply to the question\n * @param props\n * @returns\n */\nasync function reply(props: Props): Promise {\n if (props.config.cursor) props.questionElement.style.cursor = 'wait';\n\n const question = createAndNormalizeQuestion(props.form);\n const inputList: NodeListOf = props.form.querySelectorAll(props.inputQuery);\n\n const gptAnswer = await getChatGPTResponse(props.config, props.questionElement, question).catch(\n error => ({\n error\n })\n );\n\n const haveError = typeof gptAnswer === 'object' && 'error' in gptAnswer;\n\n if (props.config.cursor) {\n props.questionElement.style.cursor = props.config.infinite || haveError ? 'pointer' : 'initial';\n }\n\n if (haveError) {\n console.error(gptAnswer.error);\n return;\n }\n\n if (props.config.logs) {\n Logs.question(question);\n Logs.response(gptAnswer);\n }\n\n switch (props.config.mode) {\n case 'clipboard':\n clipboardMode({\n config: props.config,\n questionElement: props.questionElement,\n gptAnswer,\n removeListener: props.removeListener\n });\n break;\n case 'question-to-answer':\n questionToAnswerMode({\n gptAnswer,\n questionElement: props.questionElement,\n removeListener: props.removeListener\n });\n break;\n case 'autocomplete':\n autoCompleteMode({\n config: props.config,\n gptAnswer,\n inputList,\n questionElement: props.questionElement,\n removeListener: props.removeListener\n });\n break;\n }\n}\n\nexport default reply;\n","import normalizeText from '@utils/normalize-text';\nimport htmlTableToString from '@utils/html-table-to-string';\n\n/**\n * Normalize the question as text and add sub informations\n * @param langage\n * @param question\n * @returns\n */\nfunction createAndNormalizeQuestion(questionContainer: HTMLElement) {\n let question = questionContainer.innerText;\n\n // We remove unnecessary information\n const accesshideElements: NodeListOf =\n questionContainer.querySelectorAll('.accesshide');\n for (const useless of accesshideElements) {\n question = question.replace(useless.innerText, '');\n }\n\n // Make tables more readable for chat-gpt\n const tables: NodeListOf = questionContainer.querySelectorAll('.qtext table');\n for (const table of tables) {\n question = question.replace(table.innerText, '\\n' + htmlTableToString(table) + '\\n');\n }\n\n return normalizeText(question, false);\n}\n\nexport default createAndNormalizeQuestion;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport handleClipboard from '@core/questions/clipboard';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Clipboard mode:\n * Simply copy the answer into the clipboard\n * @param props\n */\nfunction clipboardMode(props: Props) {\n if (!props.config.infinite) props.removeListener();\n handleClipboard(props.config, props.gptAnswer);\n}\n\nexport default clipboardMode;\n","import type GPTAnswer from '@typing/gptAnswer';\n\ntype Props = {\n questionElement: HTMLElement;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Question to answer mode:\n * Simply turn the question into the answer by clicking on it\n * @param props\n */\nfunction questionToAnswerMode(props: Props) {\n const questionElement = props.questionElement;\n\n props.removeListener();\n\n const questionBackup = questionElement.textContent;\n\n questionElement.textContent = props.gptAnswer.response;\n\n // Format the content\n questionElement.style.whiteSpace = 'pre-wrap';\n\n // To go back to the question / answer\n let contentIsResponse = true;\n questionElement.addEventListener('click', function () {\n questionElement.style.whiteSpace = contentIsResponse ? '' : 'pre-warp';\n questionElement.textContent = contentIsResponse ? questionBackup : props.gptAnswer.response;\n\n contentIsResponse = !contentIsResponse;\n });\n}\n\nexport default questionToAnswerMode;\n","import type GPTAnswer from '@typing/gptAnswer';\nimport type Config from '@typing/config';\nimport handleClipboard from '@core/questions/clipboard';\nimport handleContentEditable from '@core/questions/contenteditable';\nimport handleNumber from '@core/questions/number';\nimport handleRadio from '@core/questions/radio';\nimport handleCheckbox from '@core/questions/checkbox';\nimport handleSelect from '@core/questions/select';\nimport handleTextbox from '@core/questions/textbox';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n inputList: NodeListOf;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Autocomplete mode:\n * Autocomplete the question by checking the good answer\n * @param props\n * @returns\n */\nfunction autoCompleteMode(props: Props) {\n if (!props.config.infinite) props.removeListener();\n\n const handlers = [\n handleContentEditable,\n handleTextbox,\n handleNumber,\n handleSelect,\n handleRadio,\n handleCheckbox\n ];\n\n for (const handler of handlers) {\n if (handler(props.config, props.inputList, props.gptAnswer)) return;\n }\n\n // In the case we can't auto complete the question\n handleClipboard(props.config, props.gptAnswer);\n}\n\nexport default autoCompleteMode;\n","import type Config from '@typing/config';\nimport titleIndications from '@utils/title-indications';\nimport reply from './reply';\n\ntype Listener = {\n element: HTMLElement;\n fn: (this: HTMLElement, ev: MouseEvent) => void;\n};\n\nconst pressedKeys: string[] = [];\nconst listeners: Listener[] = [];\n\n/**\n * Create a listener on the keyboard to inject the code\n * @param config\n */\nfunction codeListener(config: Config) {\n document.body.addEventListener('keydown', function (event) {\n pressedKeys.push(event.key);\n if (pressedKeys.length > config.code!.length) pressedKeys.shift();\n if (pressedKeys.join('') === config.code) {\n pressedKeys.length = 0;\n setUpMoodleGpt(config);\n }\n });\n}\n\n/**\n * Remove the event listener on a specific question\n * @param element\n */\nfunction removeListener(element: HTMLElement) {\n const index = listeners.findIndex(listener => listener.element === element);\n if (index !== -1) {\n const listener = listeners.splice(index, 1)[0];\n listener.element.removeEventListener('click', listener.fn);\n }\n}\n\n/**\n * Setup moodleGPT into the page (remove/injection)\n * @param config\n * @returns\n */\nfunction setUpMoodleGpt(config: Config) {\n // Removing events if there are already declared\n if (listeners.length > 0) {\n for (const listener of listeners) {\n if (config.cursor) listener.element.style.cursor = 'initial';\n listener.element.removeEventListener('click', listener.fn);\n }\n if (config.title) titleIndications('Removed');\n listeners.length = 0;\n return;\n }\n\n // Query to find inputs and forms\n const inputTypeQuery = ['checkbox', 'radio', 'text', 'number']\n .map(e => `input[type=\"${e}\"]`)\n .join(',');\n const inputQuery = inputTypeQuery + ', textarea, select, [contenteditable]';\n const forms = document.querySelectorAll('.formulation');\n\n // For each form we inject a function on the queqtion\n for (const form of forms) {\n const questionElement: HTMLElement | null = form.querySelector('.qtext');\n\n if (questionElement === null) continue;\n\n if (config.cursor) questionElement.style.cursor = 'pointer';\n\n const injectionFunction = reply.bind(null, {\n config,\n questionElement,\n form: form as HTMLElement,\n inputQuery,\n removeListener: () => removeListener(questionElement)\n });\n\n listeners.push({ element: questionElement, fn: injectionFunction });\n questionElement.addEventListener('click', injectionFunction);\n }\n\n if (config.title) titleIndications('Injected');\n}\n\nexport { codeListener, removeListener, setUpMoodleGpt };\n","import type Config from '@typing/config';\nimport { codeListener, setUpMoodleGpt } from './core/code-listener';\n\nchrome.storage.sync.get(['moodleGPT']).then(function (storage) {\n const config: Config = storage.moodleGPT;\n\n if (!config) throw new Error('Please configure MoodleGPT into the extension');\n\n if (config.code) {\n codeListener(config);\n } else {\n setUpMoodleGpt(config);\n }\n});\n"],"names":["titleIndications","text","backTitle","document","title","setTimeout","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","sentenceSimilarity","str1","str2","longerLength","length","matrix","str1WithoutSpaces","replace","str2WithoutSpaces","i","push","j","Math","min","levenshteinDistance","pickBestReponse","answer","arr","bestResponse","element","similarity","obj","SuppressedError","Logs","question","console","log","bestAnswer","round","toPourcentage","array","response","gptAnswer","normalizedResponse","normalizeText","toLowerCase","trim","ROLE","CONTENT_TYPE","INSTRUCTION","history","url","system","role","SYSTEM","content","getContent","config","questionElement","imagesElements","querySelectorAll","includeImages","version","versionNumber","match","Number","isCurrentVersionSupportingImages","model","base64Images","Array","from","map","imgEl","imageToBase64","imageElement","canvas","createElement","ctx","getContext","img","Image","crossOrigin","onload","width","height","drawImage","base64","toDataURL","onerror","error","src","filteredResults","all","filter","type","IMAGE","TEXT","htmlTableToString","table","tab","lines","maxColumnsLength","line","cellsContent","cell","index","_a","textContent","max","lineSeparationSize","reduce","a","b","lineSeparation","fill","join","mappedTab","padEnd","shift","handleClipboard","navigator","clipboard","writeText","handleContentEditable","inputList","input","getAttribute","typing","addEventListener","event","key","preventDefault","slice","focus","range","createRange","selectNodeContents","collapse","selection","window","getSelection","removeAllRanges","addRange","handleNumber","number","_b","undefined","handleRadio","firstInput","possibleAnswers","inp","parentElement","logs","correctInput","mouseover","checked","once","handleCheckbox","corrects","split","correct","handleSelect","tagName","options","opt","correctOption","currentSelect","closest","selected","handleTextbox","reply","props","cursor","style","questionContainer","innerText","accesshideElements","useless","tables","createAndNormalizeQuestion","form","inputQuery","URL","location","hostname","pathname","controller","AbortController","timeoutControler","abort","message","USER","req","fetch","method","headers","Authorization","apiKey","signal","timeout","body","JSON","stringify","messages","temperature","top_p","presence_penalty","stop","clearTimeout","json","choices","ASSISTANT","getChatGPTResponse","catch","haveError","infinite","mode","removeListener","clipboardMode","questionBackup","whiteSpace","contentIsResponse","questionToAnswerMode","handlers","handler","autoCompleteMode","pressedKeys","listeners","findIndex","listener","splice","removeEventListener","fn","setUpMoodleGpt","forms","querySelector","injectionFunction","bind","chrome","storage","sync","get","moodleGPT","Error","code","codeListener"],"mappings":"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","x_google_ignoreList":[1]} \ No newline at end of file +{"version":3,"file":"MoodleGPT.js","sources":["../src/utils/title-indications.ts","../node_modules/tslib/tslib.es6.js","../src/utils/pick-best-response.ts","../src/utils/logs.ts","../src/utils/normalize-text.ts","../src/utils/version-support-images.ts","../src/core/get-response.ts","../src/utils/image-to-base64.ts","../src/utils/html-table-to-string.ts","../src/core/questions/clipboard.ts","../src/core/questions/contenteditable.ts","../src/core/questions/number.ts","../src/core/questions/radio.ts","../src/core/questions/checkbox.ts","../src/core/questions/select.ts","../src/core/questions/textbox.ts","../src/core/reply.ts","../src/core/create-question.ts","../src/core/modes/clipboard.ts","../src/core/modes/question-to-answer.ts","../src/core/modes/autocomplete.ts","../src/core/code-listener.ts","../src/index.ts"],"sourcesContent":["/**\n * Show some informations into the document title and remove it after 3000ms\n * @param text\n */\nfunction titleIndications(text: string) {\n const backTitle = document.title;\n document.title = text;\n setTimeout(() => (document.title = backTitle), 3000);\n}\n\nexport default titleIndications;\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n function next() {\r\n while (env.stack.length) {\r\n var rec = env.stack.pop();\r\n try {\r\n var result = rec.dispose && rec.dispose.call(rec.value);\r\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n};\r\n","type BestResponse = {\n similarity: number;\n value: string | null;\n element: HTMLElement | null;\n};\n\ntype ResponsesBySimilarity = {\n similarity: number;\n value: string;\n element: HTMLElement;\n};\n\n/**\n * Calculate the levenshtein distance between two sentence\n * @param str1\n * @param str2\n * @returns\n */\nfunction levenshteinDistance(str1: string, str2: string) {\n if (str1.length === 0) return str2.length;\n if (str2.length === 0) return str1.length;\n\n const matrix: number[][] = [];\n const str1WithoutSpaces = str1.replace(/\\s+/, '');\n const str2WithoutSpaces = str2.replace(/\\s+/, '');\n\n for (let i = 0; i <= str1WithoutSpaces.length; ++i) {\n matrix.push([i]);\n for (let j = 1; j <= str2WithoutSpaces.length; ++j) {\n matrix[i][j] =\n i === 0\n ? j\n : Math.min(\n matrix[i - 1][j] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j - 1] + (str1WithoutSpaces[i - 1] === str2WithoutSpaces[j - 1] ? 0 : 1)\n );\n }\n }\n\n return matrix[str1WithoutSpaces.length][str2WithoutSpaces.length];\n}\n\n/**\n * Calculate the similarity between two sentences from 0 to 1 (best)\n * @param str1\n * @param str2\n * @returns\n */\nfunction sentenceSimilarity(str1: string, str2: string) {\n const longerLength = str1.length > str2.length ? str1.length : str2.length;\n if (longerLength === 0) return 1;\n return (longerLength - levenshteinDistance(str1, str2)) / longerLength;\n}\n\n/**\n * Pick the best sentence that correspond to the answer\n * @param arr\n * @param answer\n * @returns\n */\nexport function pickBestReponse(\n answer: string,\n arr: { element: HTMLElement; value: string }[]\n): BestResponse {\n let bestResponse: BestResponse = {\n element: null,\n similarity: 0,\n value: null\n };\n for (const obj of arr) {\n const similarity = sentenceSimilarity(obj.value, answer);\n if (similarity === 1) {\n return { element: obj.element, value: obj.value, similarity };\n }\n if (similarity > bestResponse.similarity) {\n bestResponse = { element: obj.element, value: obj.value, similarity };\n }\n }\n return bestResponse;\n}\n\n/**\n * Return the sentences sorted by score with a score superior or equal to what is asked\n * @param answer\n * @param arr\n * @param score\n * @returns\n */\nexport function pickResponsesWithSimilarityGreaterThan(\n answer: string,\n arr: { element: HTMLElement; value: string }[],\n score: number\n): ResponsesBySimilarity[] {\n const responses: ResponsesBySimilarity[] = [];\n for (const obj of arr) {\n const similarity = sentenceSimilarity(obj.value, answer);\n if (similarity >= score)\n responses.push({\n similarity,\n value: obj.value,\n element: obj.element\n });\n }\n return responses.sort((a, b) => a.similarity - b.similarity);\n}\n\n/**\n * Convert a number to a readable string pourcentage\n * @param similarity\n */\nexport function toPourcentage(similarity: number): string {\n return Math.round(similarity * 100 * 100) / 100 + '%';\n}\n","import GPTAnswer from '@typing/gptAnswer';\nimport { toPourcentage } from './pick-best-response';\n\nclass Logs {\n static question(text: string) {\n const css = 'color: cyan';\n console.log('%c[QUESTION]: %s', css, text);\n }\n\n static bestAnswer(answer: string, similarity: number) {\n const css = 'color: green';\n console.log(\n '%c[BEST ANSWER]: %s',\n css,\n `\"${answer}\" with a similarity of ${toPourcentage(similarity)}`\n );\n }\n\n static array(arr: unknown[]) {\n console.log('[CORRECTS] ', arr);\n }\n\n static response(gptAnswer: GPTAnswer) {\n console.log('Original:\\n' + gptAnswer.response);\n console.log('Normalized:\\n' + gptAnswer.normalizedResponse);\n }\n}\n\nexport default Logs;\n","/**\n * Normlize text\n * @param text\n */\nfunction normalizeText(text: string, toLowerCase: boolean = true) {\n if (toLowerCase) text = text.toLowerCase();\n\n const normalizedText = text\n .replace(/\\n+/gi, '\\n') //remove duplicate new lines\n .replace(/(\\n\\s*\\n)+/g, '\\n') //remove useless white space from textcontent\n .replace(/[ \\t]+/gi, ' ') //replace multiples space or tabs by a space\n .trim()\n // We remove the following content because sometimes ChatGPT will reply: \"answer d\"\n .replace(/^[a-z\\d]\\.\\s/gi, '') //a. text, b. text, c. text, 1. text, 2. text, 3.text\n .replace(/\\n[a-z\\d]\\.\\s/gi, '\\n'); //same but with new line\n\n return normalizedText;\n}\n\nexport default normalizeText;\n","/**\r\n * Check if the current ChatGPT version is greater or equal to 4\r\n * @param version\r\n * @returns\r\n */\r\nfunction isGPTModelGreaterOrEqualTo4(version: string): boolean {\r\n const versionNumber = version.match(/gpt-(\\d+)/);\r\n if (!versionNumber?.[1]) {\r\n return false;\r\n }\r\n return Number(versionNumber[1]) >= 4;\r\n}\r\n\r\nexport default isGPTModelGreaterOrEqualTo4;\r\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport imageToBase64 from '@utils/image-to-base64';\nimport normalizeText from '@utils/normalize-text';\nimport isGPTModelGreaterOrEqualTo4 from '@utils/version-support-images';\n\ntype Content =\n | string\n | Array<\n | {\n type: CONTENT_TYPE.TEXT;\n text: string;\n }\n | {\n type: CONTENT_TYPE.IMAGE;\n image_url: { url: string };\n }\n >;\n\ntype History = {\n url: string | null;\n system: { role: ROLE; content: Content };\n history: { role: ROLE; content: Content }[];\n};\n\nenum ROLE {\n SYSTEM = 'system',\n USER = 'user',\n ASSISTANT = 'assistant'\n}\n\nenum CONTENT_TYPE {\n TEXT = 'text',\n IMAGE = 'image_url'\n}\n\nconst INSTRUCTION: string = `\nAct as a quiz solver for the best notation with the following rules:\n- When asked for the result of an equation, provide only the result without any other information and skip the other rules.\n- If no answer(s) are given, answer the statement as usual without following the other rules, providing the most detailed, complete and precise explanation.\n- For 'put in order' questions, provide the position of the answer separated by a new line (e.g., '1\\n3\\n2') and ignore other rules.- Always reply in this format: '\\n\\n...'\n- Always reply in the format: '\\n\\n...'.\n- Retain only the correct answer(s).\n- Maintain the same order for the answers as in the text.\n- Retain all text from the answer with its description, content or definition.\n- Only provide answers that exactly match the given answer in the text.\n- The question always has the correct answer(s), so you should always provide an answer.\n- Always respond in the same language as the user's question.\n`.trim();\n\nconst history: History = {\n url: null,\n system: {\n role: ROLE.SYSTEM,\n content: INSTRUCTION\n },\n history: []\n};\n\n/**\n * Get the content to send to ChatGPT API (it allows to includes images if supported)\n * @param config\n */\nasync function getContent(\n config: Config,\n questionElement: HTMLElement,\n question: string\n): Promise {\n const imagesElements = questionElement.querySelectorAll('img');\n\n if (\n config.includeImages &&\n isGPTModelGreaterOrEqualTo4(config.model) &&\n imagesElements.length === 0\n ) {\n return question;\n }\n\n let content: Content = [];\n\n const base64Images = Array.from(imagesElements).map(imgEl => imageToBase64(imgEl));\n const results = await Promise.all(base64Images);\n const filteredResults = results.filter(value => value !== null) as string[];\n\n for (const result of filteredResults) {\n content.push({\n type: CONTENT_TYPE.IMAGE,\n image_url: { url: result }\n });\n }\n\n if (content.length > 0) {\n content.push({\n type: CONTENT_TYPE.TEXT,\n text: question\n });\n } else {\n content = question;\n }\n\n return content;\n}\n\n/**\n * Get the response from chatGPT api\n * @param config\n * @param question\n * @returns\n */\nasync function getChatGPTResponse(\n config: Config,\n questionElement: HTMLElement,\n question: string\n): Promise {\n const URL = location.hostname + location.pathname;\n\n // We reset the history when we enter a new moodle quiz or when it's desactivate\n if (!config.history || history.url !== URL) {\n history.url = URL;\n history.history = [];\n }\n\n const controller = new AbortController();\n const timeoutControler = setTimeout(() => controller.abort(), 15 * 1000);\n\n const content = await getContent(config, questionElement, question);\n const message = { role: ROLE.USER, content };\n\n const req = await fetch('https://api.openai.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`\n },\n signal: config.timeout ? controller.signal : null,\n body: JSON.stringify({\n model: config.model,\n messages: [history.system, ...history.history, message],\n temperature: 0.8,\n top_p: 1.0,\n presence_penalty: 1.0,\n ...(isGPTModelGreaterOrEqualTo4(config.model) ? { max_tokens: 1000 } : { stop: null }) // look like that on 3.5 we can say stop do null but not on gpt >= 4\n })\n });\n\n clearTimeout(timeoutControler);\n\n const rep = await req.json();\n const response = rep.choices[0].message.content;\n\n // Register the conversation\n if (config.history) {\n history.history.push(message);\n history.history.push({ role: ROLE.ASSISTANT, content: response });\n }\n\n return {\n question,\n response,\n normalizedResponse: normalizeText(response)\n };\n}\n\nexport default getChatGPTResponse;\n","/**\r\n * Convert an image html element into a base64 image string\r\n * @param imageElement\r\n * @returns\r\n */\r\nfunction imageToBase64(imageElement: HTMLImageElement): Promise {\r\n return new Promise((resolve, reject) => {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n\r\n if (!ctx) {\r\n resolve(null);\r\n return;\r\n }\r\n\r\n const img = new Image();\r\n img.crossOrigin = 'Anonymous';\r\n img.onload = () => {\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n ctx.drawImage(img, 0, 0);\r\n\r\n const base64 = canvas.toDataURL('image/png');\r\n resolve(base64);\r\n };\r\n img.onerror = error => {\r\n reject(error);\r\n };\r\n\r\n img.src = imageElement.src;\r\n });\r\n}\r\n\r\nexport default imageToBase64;\r\n","/**\n * Convert table to representating string table\n * @param table\n * @returns\n */\nfunction htmlTableToString(table: HTMLTableElement) {\n const tab: string[][] = [];\n const lines = Array.from(table.querySelectorAll('tr'));\n const maxColumnsLength: number[] = [];\n lines.map(line => {\n const cells = Array.from(line.querySelectorAll('td, th'));\n const cellsContent = cells.map((cell, index) => {\n const content = cell.textContent?.trim();\n maxColumnsLength[index] = Math.max(maxColumnsLength[index] || 0, content?.length || 0);\n return content ?? '';\n });\n tab.push(cellsContent);\n });\n\n const lineSeparationSize = maxColumnsLength.reduce((a, b) => a + b) + tab[0].length * 3 + 1;\n const lineSeparation = '\\n' + Array(lineSeparationSize).fill('-').join('') + '\\n';\n\n const mappedTab = tab.map(line => {\n const mappedLine = line.map((content, index) =>\n content.padEnd(\n maxColumnsLength[index],\n '\\u00A0' // For no matching with \\s\n )\n );\n return '| ' + mappedLine.join(' | ') + ' |';\n });\n const head = mappedTab.shift();\n return head + lineSeparation + mappedTab.join('\\n');\n}\n\nexport default htmlTableToString;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport titleIndications from '@utils/title-indications';\n\n/**\n * Copy the response in the clipboard if we can automaticaly fill the question\n * @param config\n * @param gptAnswer\n */\nfunction handleClipboard(config: Config, gptAnswer: GPTAnswer) {\n if (config.title) titleIndications('Copied to clipboard');\n navigator.clipboard.writeText(gptAnswer.response);\n}\n\nexport default handleClipboard;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Hanlde contenteditable elements\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleContentEditable(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0];\n\n if (\n inputList.length !== 1 || // for now we don't handle many input for editable textcontent\n input.getAttribute('contenteditable') !== 'true'\n ) {\n return false;\n }\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: KeyboardEvent) {\n if (event.key === 'Backspace') index = gptAnswer.response.length + 1;\n if (index > gptAnswer.response.length) return;\n event.preventDefault();\n input.textContent = gptAnswer.response.slice(0, ++index);\n\n // Put the cursor at the end of the typed text\n input.focus();\n const range = document.createRange();\n range.selectNodeContents(input);\n range.collapse(false);\n const selection = window.getSelection();\n if (selection !== null) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n });\n } else {\n input.textContent = gptAnswer.response;\n }\n\n return true;\n}\n\nexport default handleContentEditable;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Handle number input\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleNumber(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0] as HTMLInputElement | HTMLTextAreaElement;\n\n if (\n inputList.length !== 1 || // for now we don't handle many input number\n input.type !== 'number'\n ) {\n return false;\n }\n\n const number = gptAnswer.normalizedResponse.match(/\\d+([,.]\\d+)?/gi)?.[0]?.replace(',', '.');\n\n if (number === undefined) return false;\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: Event) {\n event.preventDefault();\n if ((event).key === 'Backspace') index = number.length + 1;\n if (index > number.length) return;\n if (number.slice(index, index + 1) === '.') ++index;\n input.value = number.slice(0, ++index);\n });\n } else {\n input.value = number;\n }\n\n return true;\n}\n\nexport default handleNumber;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle input radio elements\n * @param config\n * @param inputList\n * @param gptAnswer\n */\nfunction handleRadio(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const firstInput = inputList?.[0] as HTMLInputElement;\n\n // Handle the case the input is not a radio\n if (!firstInput || firstInput.type !== 'radio') {\n return false;\n }\n\n const possibleAnswers = Array.from(inputList)\n .map(inp => ({\n element: inp,\n value: normalizeText(inp?.parentElement?.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n const bestAnswer = pickBestReponse(gptAnswer.normalizedResponse, possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctInput = bestAnswer.element as HTMLInputElement;\n if (config.mouseover) {\n correctInput.addEventListener('mouseover', () => (correctInput.checked = true), {\n once: true\n });\n } else {\n correctInput.checked = true;\n }\n\n return true;\n}\n\nexport default handleRadio;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle input checkbox elements\n * @param config\n * @param inputList\n * @param gptAnswer\n */\nfunction handleCheckbox(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const firstInput = inputList?.[0] as HTMLInputElement;\n\n // Handle the case the input is not a checkbox\n if (!firstInput || firstInput.type !== 'checkbox') {\n return false;\n }\n\n const corrects = gptAnswer.normalizedResponse.split('\\n');\n\n const possibleAnswers = Array.from(inputList)\n .map(inp => ({\n element: inp,\n value: normalizeText(inp?.parentElement?.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n for (const correct of corrects) {\n const bestAnswer = pickBestReponse(correct, possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctInput = bestAnswer.element as HTMLInputElement;\n if (config.mouseover) {\n correctInput.addEventListener('mouseover', () => (correctInput.checked = true), {\n once: true\n });\n } else {\n correctInput.checked = true;\n }\n }\n\n return true;\n}\n\nexport default handleCheckbox;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport Logs from '@utils/logs';\nimport normalizeText from '@utils/normalize-text';\nimport { pickBestReponse } from '@utils/pick-best-response';\n\n/**\n * Handle select elements (and put in order select)\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleSelect(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n if (inputList.length === 0 || inputList[0].tagName !== 'SELECT') return false;\n\n const corrects = gptAnswer.normalizedResponse.split('\\n');\n\n if (config.logs) Logs.array(corrects);\n\n for (let i = 0; i < inputList.length; ++i) {\n if (!corrects[i]) break;\n\n const options = inputList[i].querySelectorAll('option');\n\n const possibleAnswers = Array.from(options)\n .map(opt => ({\n element: opt,\n value: normalizeText(opt.textContent ?? '')\n }))\n .filter(obj => obj.value !== '');\n\n const bestAnswer = pickBestReponse(corrects[i], possibleAnswers);\n\n if (config.logs && bestAnswer.value) {\n Logs.bestAnswer(bestAnswer.value, bestAnswer.similarity);\n }\n\n const correctOption = bestAnswer.element as HTMLOptionElement;\n const currentSelect = correctOption.closest('select');\n\n if (currentSelect === null) continue;\n\n if (config.mouseover) {\n currentSelect.addEventListener('click', () => (correctOption.selected = true), {\n once: true\n });\n } else {\n correctOption.selected = true;\n }\n }\n\n return true;\n}\n\nexport default handleSelect;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\n\n/**\n * Handle textbox\n * @param config\n * @param inputList\n * @param gptAnswer\n * @returns\n */\nfunction handleTextbox(\n config: Config,\n inputList: NodeListOf,\n gptAnswer: GPTAnswer\n): boolean {\n const input = inputList[0] as HTMLInputElement | HTMLTextAreaElement;\n\n if (\n inputList.length !== 1 || // for now we don't handle many input text\n (input.tagName !== 'TEXTAREA' && input.type !== 'text')\n ) {\n return false;\n }\n\n if (config.typing) {\n let index = 0;\n input.addEventListener('keydown', function (event: Event) {\n event.preventDefault();\n if ((event).key === 'Backspace') {\n index = gptAnswer.response.length + 1;\n }\n if (index > gptAnswer.response.length) return;\n input.value = gptAnswer.response.slice(0, ++index);\n });\n } else {\n input.value = gptAnswer.response;\n }\n\n return true;\n}\n\nexport default handleTextbox;\n","import type Config from '@typing/config';\nimport Logs from '@utils/logs';\nimport getChatGPTResponse from './get-response';\nimport createAndNormalizeQuestion from './create-question';\nimport clipboardMode from './modes/clipboard';\nimport questionToAnswerMode from './modes/question-to-answer';\nimport autoCompleteMode from './modes/autocomplete';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n form: HTMLElement;\n inputQuery: string;\n removeListener: () => void;\n};\n\n/**\n * Reply to the question\n * @param props\n * @returns\n */\nasync function reply(props: Props): Promise {\n if (props.config.cursor) props.questionElement.style.cursor = 'wait';\n\n const question = createAndNormalizeQuestion(props.form);\n const inputList: NodeListOf = props.form.querySelectorAll(props.inputQuery);\n\n const gptAnswer = await getChatGPTResponse(props.config, props.questionElement, question).catch(\n error => ({\n error\n })\n );\n\n const haveError = typeof gptAnswer === 'object' && 'error' in gptAnswer;\n\n if (props.config.cursor) {\n props.questionElement.style.cursor = props.config.infinite || haveError ? 'pointer' : 'initial';\n }\n\n if (haveError) {\n console.error(gptAnswer.error);\n return;\n }\n\n if (props.config.logs) {\n Logs.question(question);\n Logs.response(gptAnswer);\n }\n\n switch (props.config.mode) {\n case 'clipboard':\n clipboardMode({\n config: props.config,\n questionElement: props.questionElement,\n gptAnswer,\n removeListener: props.removeListener\n });\n break;\n case 'question-to-answer':\n questionToAnswerMode({\n gptAnswer,\n questionElement: props.questionElement,\n removeListener: props.removeListener\n });\n break;\n case 'autocomplete':\n autoCompleteMode({\n config: props.config,\n gptAnswer,\n inputList,\n questionElement: props.questionElement,\n removeListener: props.removeListener\n });\n break;\n }\n}\n\nexport default reply;\n","import normalizeText from '@utils/normalize-text';\nimport htmlTableToString from '@utils/html-table-to-string';\n\n/**\n * Normalize the question as text and add sub informations\n * @param langage\n * @param question\n * @returns\n */\nfunction createAndNormalizeQuestion(questionContainer: HTMLElement) {\n let question = questionContainer.innerText;\n\n // We remove unnecessary information\n const accesshideElements: NodeListOf =\n questionContainer.querySelectorAll('.accesshide');\n for (const useless of accesshideElements) {\n question = question.replace(useless.innerText, '');\n }\n\n // Make tables more readable for chat-gpt\n const tables: NodeListOf = questionContainer.querySelectorAll('.qtext table');\n for (const table of tables) {\n question = question.replace(table.innerText, '\\n' + htmlTableToString(table) + '\\n');\n }\n\n return normalizeText(question, false);\n}\n\nexport default createAndNormalizeQuestion;\n","import type Config from '@typing/config';\nimport type GPTAnswer from '@typing/gptAnswer';\nimport handleClipboard from '@core/questions/clipboard';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Clipboard mode:\n * Simply copy the answer into the clipboard\n * @param props\n */\nfunction clipboardMode(props: Props) {\n if (!props.config.infinite) props.removeListener();\n handleClipboard(props.config, props.gptAnswer);\n}\n\nexport default clipboardMode;\n","import type GPTAnswer from '@typing/gptAnswer';\n\ntype Props = {\n questionElement: HTMLElement;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Question to answer mode:\n * Simply turn the question into the answer by clicking on it\n * @param props\n */\nfunction questionToAnswerMode(props: Props) {\n const questionElement = props.questionElement;\n\n props.removeListener();\n\n const questionBackup = questionElement.textContent;\n\n questionElement.textContent = props.gptAnswer.response;\n\n // Format the content\n questionElement.style.whiteSpace = 'pre-wrap';\n\n // To go back to the question / answer\n let contentIsResponse = true;\n questionElement.addEventListener('click', function () {\n questionElement.style.whiteSpace = contentIsResponse ? '' : 'pre-warp';\n questionElement.textContent = contentIsResponse ? questionBackup : props.gptAnswer.response;\n\n contentIsResponse = !contentIsResponse;\n });\n}\n\nexport default questionToAnswerMode;\n","import type GPTAnswer from '@typing/gptAnswer';\nimport type Config from '@typing/config';\nimport handleClipboard from '@core/questions/clipboard';\nimport handleContentEditable from '@core/questions/contenteditable';\nimport handleNumber from '@core/questions/number';\nimport handleRadio from '@core/questions/radio';\nimport handleCheckbox from '@core/questions/checkbox';\nimport handleSelect from '@core/questions/select';\nimport handleTextbox from '@core/questions/textbox';\n\ntype Props = {\n config: Config;\n questionElement: HTMLElement;\n inputList: NodeListOf;\n gptAnswer: GPTAnswer;\n removeListener: () => void;\n};\n\n/**\n * Autocomplete mode:\n * Autocomplete the question by checking the good answer\n * @param props\n * @returns\n */\nfunction autoCompleteMode(props: Props) {\n if (!props.config.infinite) props.removeListener();\n\n const handlers = [\n handleContentEditable,\n handleTextbox,\n handleNumber,\n handleSelect,\n handleRadio,\n handleCheckbox\n ];\n\n for (const handler of handlers) {\n if (handler(props.config, props.inputList, props.gptAnswer)) return;\n }\n\n // In the case we can't auto complete the question\n handleClipboard(props.config, props.gptAnswer);\n}\n\nexport default autoCompleteMode;\n","import type Config from '@typing/config';\nimport titleIndications from '@utils/title-indications';\nimport reply from './reply';\n\ntype Listener = {\n element: HTMLElement;\n fn: (this: HTMLElement, ev: MouseEvent) => void;\n};\n\nconst pressedKeys: string[] = [];\nconst listeners: Listener[] = [];\n\n/**\n * Create a listener on the keyboard to inject the code\n * @param config\n */\nfunction codeListener(config: Config) {\n document.body.addEventListener('keydown', function (event) {\n pressedKeys.push(event.key);\n if (pressedKeys.length > config.code!.length) pressedKeys.shift();\n if (pressedKeys.join('') === config.code) {\n pressedKeys.length = 0;\n setUpMoodleGpt(config);\n }\n });\n}\n\n/**\n * Remove the event listener on a specific question\n * @param element\n */\nfunction removeListener(element: HTMLElement) {\n const index = listeners.findIndex(listener => listener.element === element);\n if (index !== -1) {\n const listener = listeners.splice(index, 1)[0];\n listener.element.removeEventListener('click', listener.fn);\n }\n}\n\n/**\n * Setup moodleGPT into the page (remove/injection)\n * @param config\n * @returns\n */\nfunction setUpMoodleGpt(config: Config) {\n // Removing events if there are already declared\n if (listeners.length > 0) {\n for (const listener of listeners) {\n if (config.cursor) listener.element.style.cursor = 'initial';\n listener.element.removeEventListener('click', listener.fn);\n }\n if (config.title) titleIndications('Removed');\n listeners.length = 0;\n return;\n }\n\n // Query to find inputs and forms\n const inputTypeQuery = ['checkbox', 'radio', 'text', 'number']\n .map(e => `input[type=\"${e}\"]`)\n .join(',');\n const inputQuery = inputTypeQuery + ', textarea, select, [contenteditable]';\n const forms = document.querySelectorAll('.formulation');\n\n // For each form we inject a function on the queqtion\n for (const form of forms) {\n const questionElement: HTMLElement | null = form.querySelector('.qtext');\n\n if (questionElement === null) continue;\n\n if (config.cursor) questionElement.style.cursor = 'pointer';\n\n const injectionFunction = reply.bind(null, {\n config,\n questionElement,\n form: form as HTMLElement,\n inputQuery,\n removeListener: () => removeListener(questionElement)\n });\n\n listeners.push({ element: questionElement, fn: injectionFunction });\n questionElement.addEventListener('click', injectionFunction);\n }\n\n if (config.title) titleIndications('Injected');\n}\n\nexport { codeListener, removeListener, setUpMoodleGpt };\n","import type Config from '@typing/config';\nimport { codeListener, setUpMoodleGpt } from './core/code-listener';\n\nchrome.storage.sync.get(['moodleGPT']).then(function (storage) {\n const config: Config = storage.moodleGPT;\n\n if (!config) throw new Error('Please configure MoodleGPT into the extension');\n\n if (config.code) {\n codeListener(config);\n } else {\n setUpMoodleGpt(config);\n }\n});\n"],"names":["titleIndications","text","backTitle","document","title","setTimeout","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","sentenceSimilarity","str1","str2","longerLength","length","matrix","str1WithoutSpaces","replace","str2WithoutSpaces","i","push","j","Math","min","levenshteinDistance","pickBestReponse","answer","arr","bestResponse","element","similarity","obj","SuppressedError","Logs","question","console","log","bestAnswer","round","toPourcentage","array","response","gptAnswer","normalizedResponse","normalizeText","toLowerCase","trim","isGPTModelGreaterOrEqualTo4","version","versionNumber","match","Number","ROLE","CONTENT_TYPE","INSTRUCTION","history","url","system","role","SYSTEM","content","getContent","config","questionElement","imagesElements","querySelectorAll","includeImages","model","base64Images","Array","from","map","imgEl","imageToBase64","imageElement","canvas","createElement","ctx","getContext","img","Image","crossOrigin","onload","width","height","drawImage","base64","toDataURL","onerror","error","src","filteredResults","all","filter","type","IMAGE","image_url","TEXT","htmlTableToString","table","tab","lines","maxColumnsLength","line","cellsContent","cell","index","_a","textContent","max","lineSeparationSize","reduce","a","b","lineSeparation","fill","join","mappedTab","padEnd","shift","handleClipboard","navigator","clipboard","writeText","handleContentEditable","inputList","input","getAttribute","typing","addEventListener","event","key","preventDefault","slice","focus","range","createRange","selectNodeContents","collapse","selection","window","getSelection","removeAllRanges","addRange","handleNumber","number","_b","undefined","handleRadio","firstInput","possibleAnswers","inp","parentElement","logs","correctInput","mouseover","checked","once","handleCheckbox","corrects","split","correct","handleSelect","tagName","options","opt","correctOption","currentSelect","closest","selected","handleTextbox","reply","props","cursor","style","questionContainer","innerText","accesshideElements","useless","tables","createAndNormalizeQuestion","form","inputQuery","URL","location","hostname","pathname","controller","AbortController","timeoutControler","abort","message","USER","req","fetch","method","headers","Authorization","apiKey","signal","timeout","body","JSON","stringify","Object","assign","messages","temperature","top_p","presence_penalty","max_tokens","stop","clearTimeout","json","choices","ASSISTANT","getChatGPTResponse","catch","haveError","infinite","mode","removeListener","clipboardMode","questionBackup","whiteSpace","contentIsResponse","questionToAnswerMode","handlers","handler","autoCompleteMode","pressedKeys","listeners","findIndex","listener","splice","removeEventListener","fn","setUpMoodleGpt","forms","querySelector","injectionFunction","bind","chrome","storage","sync","get","moodleGPT","Error","code","codeListener"],"mappings":"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","x_google_ignoreList":[1]} \ No newline at end of file diff --git a/extension/popup/js/gptVersion.js b/extension/popup/js/gptVersion.js index cae27f1..00b1488 100644 --- a/extension/popup/js/gptVersion.js +++ b/extension/popup/js/gptVersion.js @@ -3,15 +3,20 @@ const modelInput = document.querySelector('#model'); const imagesIntegrationLine = document.querySelector('#includeImages-line'); -// Check if the gpt version is at least 4 to show the option 'Include images' -modelInput.addEventListener('input', function () { +/** + * Check if the gpt version is at least 4 to show the option 'Include images' + */ +function checkCanIncludeImages() { const version = modelInput.value; if (isCurrentVersionSupportingImages(version)) { imagesIntegrationLine.style.display = 'flex'; } else { imagesIntegrationLine.style.display = 'none'; } -}); +} + +checkCanIncludeImages(); +modelInput.addEventListener('input', checkCanIncludeImages); /** * Get the last ChatGPT version diff --git a/src/core/get-response.ts b/src/core/get-response.ts index 2828a9e..5b9fb63 100644 --- a/src/core/get-response.ts +++ b/src/core/get-response.ts @@ -2,14 +2,20 @@ import type Config from '@typing/config'; import type GPTAnswer from '@typing/gptAnswer'; import imageToBase64 from '@utils/image-to-base64'; import normalizeText from '@utils/normalize-text'; -import isCurrentVersionSupportingImages from '@utils/version-support-images'; +import isGPTModelGreaterOrEqualTo4 from '@utils/version-support-images'; type Content = | string - | Array<{ - type: CONTENT_TYPE; - content: string; - }>; + | Array< + | { + type: CONTENT_TYPE.TEXT; + text: string; + } + | { + type: CONTENT_TYPE.IMAGE; + image_url: { url: string }; + } + >; type History = { url: string | null; @@ -63,8 +69,8 @@ async function getContent( const imagesElements = questionElement.querySelectorAll('img'); if ( - !config.includeImages || - !isCurrentVersionSupportingImages(config.model) || + config.includeImages && + isGPTModelGreaterOrEqualTo4(config.model) && imagesElements.length === 0 ) { return question; @@ -79,14 +85,14 @@ async function getContent( for (const result of filteredResults) { content.push({ type: CONTENT_TYPE.IMAGE, - content: result + image_url: { url: result } }); } if (content.length > 0) { content.push({ type: CONTENT_TYPE.TEXT, - content: question + text: question }); } else { content = question; @@ -133,7 +139,7 @@ async function getChatGPTResponse( temperature: 0.8, top_p: 1.0, presence_penalty: 1.0, - stop: null + ...(isGPTModelGreaterOrEqualTo4(config.model) ? { max_tokens: 1000 } : { stop: null }) // look like that on 3.5 we can say stop do null but not on gpt >= 4 }) }); diff --git a/src/utils/version-support-images.ts b/src/utils/version-support-images.ts index 103cb69..98f1d0a 100644 --- a/src/utils/version-support-images.ts +++ b/src/utils/version-support-images.ts @@ -1,9 +1,9 @@ /** - * Check if the current ChatGPT version support image sending + * Check if the current ChatGPT version is greater or equal to 4 * @param version * @returns */ -function isCurrentVersionSupportingImages(version: string): boolean { +function isGPTModelGreaterOrEqualTo4(version: string): boolean { const versionNumber = version.match(/gpt-(\d+)/); if (!versionNumber?.[1]) { return false; @@ -11,4 +11,4 @@ function isCurrentVersionSupportingImages(version: string): boolean { return Number(versionNumber[1]) >= 4; } -export default isCurrentVersionSupportingImages; +export default isGPTModelGreaterOrEqualTo4; diff --git a/test/fake-moodle/assets/cat1.jpg b/test/fake-moodle/assets/cat1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70d140c43ad87f00cb74edef8628a993a72d14ed GIT binary patch literal 4666 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 b6XmZB0}1hRDs46;Wy*4T;n?KVtGWLHaYt$X literal 0 HcmV?d00001 diff --git a/test/fake-moodle/assets/cat2.jpg b/test/fake-moodle/assets/cat2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e771b425f36ff33d64340cabdb8f51af1ea1ec7b GIT binary patch literal 22523 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 TxYecbNmZ-3dF5$|zmxw5AF%G= literal 0 HcmV?d00001 diff --git a/test/fake-moodle/css/style.css b/test/fake-moodle/css/style.css index 3fe7434..29ded4f 100644 --- a/test/fake-moodle/css/style.css +++ b/test/fake-moodle/css/style.css @@ -65,3 +65,7 @@ textarea { white-space: pre-wrap; overflow-y: auto; } + +img { + height: 5rem; +} diff --git a/test/fake-moodle/index.html b/test/fake-moodle/index.html index 93abd99..3e2a34c 100644 --- a/test/fake-moodle/index.html +++ b/test/fake-moodle/index.html @@ -269,7 +269,7 @@ - +

@@ -281,5 +281,20 @@

+ + +
+

+ Warning ! Only work with gpt-4 and if "includes images" is activate +

+
+

Tell me what you see on thoses images

+ + +
+
+
+
+