@learnpack/learnpack 5.0.351 → 5.0.352

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -499,7 +499,7 @@ components:\r
499
499
  - Maintain professional, clean aesthetic appropriate for learning\r
500
500
  example: |\r
501
501
  ![Professional photograph of a modern developer workspace showing a dual-monitor setup with code editor on left screen and browser developer tools on right screen, mechanical keyboard in foreground, with natural lighting from window, clean desk organization, demonstrating a typical full-stack development environment with annotations highlighting the debugging workflow between IDE and browser](./.learn/assets/developer-workspace.png)\r
502
- `,V5=!1,ha="";function Yp(e,t){return e==="localStorage"||e==="scorm"||e==="creatorWeb"&&t!=="creator"}function Ah(e){return e==="localStorage"||e==="scorm"||e==="creatorWeb"}const tvt="https://ai.4geeks.com";function VCe(e){Array.isArray(e)||(e=[e]);const t=new URLSearchParams(window.location.search);let r={};return e.forEach(a=>r[a]=t.get(a)),e.length==1?r[e[0]]:r}const rvt=location.protocol+"//"+location.hostname+(location.port?":"+location.port:""),RC=function(){const e=window.location.pathname.endsWith("/config/index.html");let t=VCe("config");t&&t!==""&&(t=JSON.parse(atob(t)));let r=t?`${t.address}:${t.port}`:VCe("host")||rvt;return e&&(r=window.location.href.replace("/config/index.html","")),r};let Kp="localhost";const GCe=async()=>{var r;const e=RC();if(console.log("DETECTED HOST",e),window.location.pathname.endsWith("/config/index.html"))try{const n=await fetch(`${e}/.learn/config.json`);if(n.ok)return await n.json(),Kp="scorm",document.dispatchEvent(new CustomEvent("environment-change",{detail:{environment:"scorm"}})),console.log("The environment will be scorm"),"scorm"}catch(n){console.error("SCORM config fetch failed, falling back to legacy detection",n)}try{const n=Kr(),a=await fetch(`${e}/config?slug=${n}`),i=(r=a.headers.get("Content-Type"))==null?void 0:r.includes("application/json");if(a.ok&&i){let o="localhost";a.headers.get("X-Creator-Web")&&(o="creatorWeb"),console.log("The environment will be:",o),Kp=o;const l=new CustomEvent("environment-change",{detail:{environment:o}});return document.dispatchEvent(l),o}else throw Error("The response was unsuccessful")}catch{Kp="localStorage";try{const a=await fetch(`${e}/config.json`);if(!a.ok)throw new Error("config.json not found");await a.json(),console.log("The environment will be localStorage");const i=new CustomEvent("environment-change",{detail:{environment:"localStorage"}});return document.dispatchEvent(i),"localStorage"}catch{try{const i=await fetch(`${e}/.learn/config.json`);if(console.log("SCORM CONFIG PATH",i),!i.ok)throw new Error(".learn/config.json not found");await i.json(),Kp="scorm";const o=new CustomEvent("environment-change",{detail:{environment:"scorm"}});return console.log("The environment will be scorm"),document.dispatchEvent(o),"scorm"}catch(i){return console.error("Error fetching scorm config, impossible to detect environment",i),"localStorage"}}}};GCe();const ui="https://rigobot.herokuapp.com",QCe=2e4,nvt=2e3,avt=3,ivt=1e3,ovt=3,Lv="https://breathecode.herokuapp.com",svt=()=>{const e=document.querySelector(".sidebar-component");e&&(window.getComputedStyle(e).left==="0px"?(e.classList.remove("sidebar-appear"),e.classList.add("sidebar-disappear")):(e==null||e.classList.remove("sidebar-disappear"),e==null||e.classList.add("sidebar-appear")),e==null||e.offsetWidth)},lvt=async e=>await fetch(`${RC()}/exercise/${e}`),cvt=async(e,t)=>{const r=ui+"/v1/conversation/?purpose="+e,n={method:"POST",headers:{"Content-Type":"application/json",Authorization:"Token "+t}};return await(await fetch(r,n)).json()},WCe=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="block")},uvt=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="none")},dvt=()=>{const e=new URLSearchParams(window.location.search);let t={};for(const[r,n]of e.entries())t[r]=n;return t},BC=()=>dvt(),Rl=(e,t)=>{let r,n=null;const a=(...i)=>{n=i,clearTimeout(r),r=setTimeout(()=>{n=null,e(...i)},t)};return a.cancel=()=>{clearTimeout(r),n=null},a.flush=()=>{n!==null&&(clearTimeout(r),e(...n),n=null)},a},YCe=e=>e.replace(/\x1B[@-_][0-?]*[ -/]*[@-~]/g,""),KCe=(e,t,r)=>{const n=new RegExp(t,"g");return e.replace(n,r)},K1=e=>{const t=new URLSearchParams;Object.entries(e).forEach(([a,i])=>{i!=null&&i!==""&&t.set(a,String(i))});const r=t.toString(),n=r?`${window.location.pathname}?${r}${window.location.hash}`:`${window.location.pathname}${window.location.hash}`;window.history.replaceState(null,"",n)};function lce(e,t){return Math.random()*(t-e)+e}class OC extends Error{constructor(t){super(t),this.name="MissingRigobotAccountError"}}class XCe extends Error{constructor(t){super(t),this.name="TokenExpiredError"}}const cce=(e,t="ai-conversation-message")=>{const r=e.voids.find(n=>n.slug===t);return r?r.balance.unit:0},G5=async e=>{const r=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(n)).map(o=>o.toString(16).padStart(2,"0")).join("")};async function mh(e,t=2e3){const r=Date.now()-e;r<t&&await new Promise(n=>setTimeout(n,t-r))}const hvt=e=>{const t=new URL(window.location.href);t.searchParams.delete(e);const r=new URLSearchParams(t.hash.slice(1));r.delete(e),r.toString()?t.hash=`#${r.toString()}`:t.hash="",window.history.replaceState({},"",t.toString())},ZCe=e=>{Lle.dataLayer(e)},Yu=(e,t)=>`---
502
+ `,V5=!1,ha="";function Yp(e,t){return e==="localStorage"||e==="scorm"||e==="creatorWeb"&&t!=="creator"}function Ah(e){return e==="localStorage"||e==="scorm"||e==="creatorWeb"}const tvt="https://ai.4geeks.com";function VCe(e){Array.isArray(e)||(e=[e]);const t=new URLSearchParams(window.location.search);let r={};return e.forEach(a=>r[a]=t.get(a)),e.length==1?r[e[0]]:r}const rvt=location.protocol+"//"+location.hostname+(location.port?":"+location.port:""),RC=function(){const e=window.location.pathname.endsWith("/config/index.html");let t=VCe("config");t&&t!==""&&(t=JSON.parse(atob(t)));let r=t?`${t.address}:${t.port}`:VCe("host")||rvt;return e&&(r=window.location.href.replace("/config/index.html","")),r};let Kp="localhost";const GCe=async()=>{var r;const e=RC();if(console.log("DETECTED HOST",e),window.location.pathname.endsWith("/config/index.html"))try{const n=await fetch(`${e}/.learn/config.json`);if(n.ok)return await n.json(),Kp="scorm",document.dispatchEvent(new CustomEvent("environment-change",{detail:{environment:"scorm"}})),console.log("The environment will be scorm"),"scorm"}catch(n){console.error("SCORM config fetch failed, falling back to legacy detection",n)}try{const n=Kr(),a=await fetch(`${e}/config?slug=${n}`),i=(r=a.headers.get("Content-Type"))==null?void 0:r.includes("application/json");if(a.ok&&i){let o="localhost";a.headers.get("X-Creator-Web")&&(o="creatorWeb"),console.log("The environment will be:",o),Kp=o;const l=new CustomEvent("environment-change",{detail:{environment:o}});return document.dispatchEvent(l),o}else throw Error("The response was unsuccessful")}catch{Kp="localStorage";try{const a=await fetch(`${e}/config.json`);if(!a.ok)throw new Error("config.json not found");await a.json(),console.log("The environment will be localStorage");const i=new CustomEvent("environment-change",{detail:{environment:"localStorage"}});return document.dispatchEvent(i),"localStorage"}catch{try{const i=await fetch(`${e}/.learn/config.json`);if(console.log("SCORM CONFIG PATH",i),!i.ok)throw new Error(".learn/config.json not found");await i.json(),Kp="scorm";const o=new CustomEvent("environment-change",{detail:{environment:"scorm"}});return console.log("The environment will be scorm"),document.dispatchEvent(o),"scorm"}catch(i){return console.error("Error fetching scorm config, impossible to detect environment",i),"localStorage"}}}};GCe();const ui="https://rigobot.herokuapp.com",QCe=3e4,nvt=2e3,avt=3,ivt=1e3,ovt=3,Lv="https://breathecode.herokuapp.com",svt=()=>{const e=document.querySelector(".sidebar-component");e&&(window.getComputedStyle(e).left==="0px"?(e.classList.remove("sidebar-appear"),e.classList.add("sidebar-disappear")):(e==null||e.classList.remove("sidebar-disappear"),e==null||e.classList.add("sidebar-appear")),e==null||e.offsetWidth)},lvt=async e=>await fetch(`${RC()}/exercise/${e}`),cvt=async(e,t)=>{const r=ui+"/v1/conversation/?purpose="+e,n={method:"POST",headers:{"Content-Type":"application/json",Authorization:"Token "+t}};return await(await fetch(r,n)).json()},WCe=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="block")},uvt=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="none")},dvt=()=>{const e=new URLSearchParams(window.location.search);let t={};for(const[r,n]of e.entries())t[r]=n;return t},BC=()=>dvt(),Rl=(e,t)=>{let r,n=null;const a=(...i)=>{n=i,clearTimeout(r),r=setTimeout(()=>{n=null,e(...i)},t)};return a.cancel=()=>{clearTimeout(r),n=null},a.flush=()=>{n!==null&&(clearTimeout(r),e(...n),n=null)},a},YCe=e=>e.replace(/\x1B[@-_][0-?]*[ -/]*[@-~]/g,""),KCe=(e,t,r)=>{const n=new RegExp(t,"g");return e.replace(n,r)},K1=e=>{const t=new URLSearchParams;Object.entries(e).forEach(([a,i])=>{i!=null&&i!==""&&t.set(a,String(i))});const r=t.toString(),n=r?`${window.location.pathname}?${r}${window.location.hash}`:`${window.location.pathname}${window.location.hash}`;window.history.replaceState(null,"",n)};function lce(e,t){return Math.random()*(t-e)+e}class OC extends Error{constructor(t){super(t),this.name="MissingRigobotAccountError"}}class XCe extends Error{constructor(t){super(t),this.name="TokenExpiredError"}}const cce=(e,t="ai-conversation-message")=>{const r=e.voids.find(n=>n.slug===t);return r?r.balance.unit:0},G5=async e=>{const r=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(n)).map(o=>o.toString(16).padStart(2,"0")).join("")};async function mh(e,t=2e3){const r=Date.now()-e;r<t&&await new Promise(n=>setTimeout(n,t-r))}const hvt=e=>{const t=new URL(window.location.href);t.searchParams.delete(e);const r=new URLSearchParams(t.hash.slice(1));r.delete(e),r.toString()?t.hash=`#${r.toString()}`:t.hash="",window.history.replaceState({},"",t.toString())},ZCe=e=>{Lle.dataLayer(e)},Yu=(e,t)=>`---
503
503
  `+oCe(e)+`---
504
504
 
505
505
  `+t,fvt=e=>e==="us"?"en":"es",DC=e=>e==="en"||e==="us"?".md":`.${e}.md`,zo=(e,t="en")=>{try{const r=new Intl.DisplayNames([t],{type:"language"}),n=e==="us"?"en":e;return r.of(n)||e}catch{return e}},pvt=(e,t="")=>e.includes("?")||e.includes("#")?btoa(e+t):btoa(e+"?"+t),gvt="https://storage.googleapis.com/breathecode/learnpack",Bl=e=>{try{const t=Math.floor(Math.random()*2),r=new Audio(`${gvt}/sounds-${e}/${e==="success"?t:0}.mp3`);r.volume=.4,r.play()}catch(t){console.error("Error playing sound",t)}};function Q5(e){const t=/^---\s*[\s\S]*?\s*---\s*/;return e.replace(t,"").trimStart()}function FC(e){const t=parseFloat(e);if(Number.isNaN(t))return e;if(t===0)return"0";const r=t.toString().split(".");return r[0]=r[0].replace(/^0+(?=\d)/,""),r.join(".")}function PC(e,t="en"){var r,n,a,i;return e?typeof e=="string"?e.trim():((r=e[t])==null?void 0:r.trim())||((n=e.en)==null?void 0:n.trim())||((a=e.us)==null?void 0:a.trim())||((i=Object.values(e).find(o=>typeof o=="string"&&o.trim()))==null?void 0:i.trim())||"":""}function Avt(e){let t=e.split("-");t.shift();let r=t.join(" ");return r=r.charAt(0).toUpperCase()+r.slice(1),r}function $C(e,t,r,n){var s;const a=FC(e.split("-")[0]),i=((s=t==null?void 0:t[e])==null?void 0:s[r])||n,o=Avt(i);return{id:a,formattedTitle:o}}function Kr(){const e=window.location.pathname.split("/").filter(Boolean);return e[0]==="preview"&&e[1]?e[1]:e.pop()||null}function JCe(){return`teacherOnboardingClosed_${Kr()||"default"}`}const e9e=async(e,t)=>{console.log("Uploading blob to bucket",e,t);const r=new FormData;r.append("file",e,"preview.png"),r.append("destination",t);const n=await fetch("/upload-image-file",{method:"POST",body:r});if(!n.ok)throw console.error("Error uploading image to bucket",n),new Error("Failed to upload image");return await n.json()},mvt=async e=>{try{return(await Ur.get(`${V5?"http://localhost:3000":""}/check-preview-image/${e}`)).data}catch(t){return console.error("Error checking preview image",t),null}},W5=(e,t=!0)=>{let r=e.toString().normalize("NFD").replace(/[\u0300-\u036F]/g,"").toLowerCase().trim().replace(/[^\d\s._a-z-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-");return t&&(r=r.replace(/^-+|-+$/g,"")),r},yvt=async e=>{try{const t=`${ui}/v1/learnpack/check-slug-availability?slug=${encodeURIComponent(e)}`;return(await Ur.get(t)).data.available}catch(t){throw console.error("Error checking slug availability:",t),t}},t9e=async(e,{prompt:t,callbackUrl:r,context:n})=>{try{return(await Ur.post(`${ui}/v1/learnpack/tools/images`,{prompt:t,context:n,webhook_callback_url:r},{headers:{"Content-Type":"application/json",Authorization:"Token "+e}})).data}catch(a){return console.error("Error generating image:",a),null}};function vvt(e,t="",r=""){let n="Bug";t&&(n=`Bug in ${t}`);const a=`Lesson: ${e}
@@ -753,7 +753,7 @@ ${t}</body>`,n):(console.log("NO HTML TAG"),`
753
753
  `+e.slice(o+1):l+=e.slice(a),l.slice(1)}function V5t(e){for(var t="",r,n,a,i=0;i<e.length;i++){if(r=e.charCodeAt(i),r>=55296&&r<=56319&&(n=e.charCodeAt(i+1),n>=56320&&n<=57343)){t+=mEe((r-55296)*1024+n-56320+65536),i++;continue}a=Ho[r],t+=!a&&$v(r)?e[i]:a||mEe(r)}return t}function G5t(e,t,r){var n="",a=e.tag,i,o;for(i=0,o=r.length;i<o;i+=1)e0(e,t,r[i],!1,!1)&&(i!==0&&(n+=","+(e.condenseFlow?"":" ")),n+=e.dump);e.tag=a,e.dump="["+n+"]"}function Q5t(e,t,r,n){var a="",i=e.tag,o,s;for(o=0,s=r.length;o<s;o+=1)e0(e,t+1,r[o],!0,!0)&&((!n||o!==0)&&(a+=$ce(e,t)),e.dump&&iw===e.dump.charCodeAt(0)?a+="-":a+="- ",a+=e.dump);e.tag=i,e.dump=a||"[]"}function W5t(e,t,r){var n="",a=e.tag,i=Object.keys(r),o,s,l,u,d;for(o=0,s=i.length;o<s;o+=1)d="",o!==0&&(d+=", "),e.condenseFlow&&(d+='"'),l=i[o],u=r[l],e0(e,t,l,!1,!1)&&(e.dump.length>1024&&(d+="? "),d+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),e0(e,t,u,!1,!1)&&(d+=e.dump,n+=d));e.tag=a,e.dump="{"+n+"}"}function Y5t(e,t,r,n){var a="",i=e.tag,o=Object.keys(r),s,l,u,d,h,f;if(e.sortKeys===!0)o.sort();else if(typeof e.sortKeys=="function")o.sort(e.sortKeys);else if(e.sortKeys)throw new aw("sortKeys must be a boolean or a function");for(s=0,l=o.length;s<l;s+=1)f="",(!n||s!==0)&&(f+=$ce(e,t)),u=o[s],d=r[u],e0(e,t+1,u,!0,!0,!0)&&(h=e.tag!==null&&e.tag!=="?"||e.dump&&e.dump.length>1024,h&&(e.dump&&iw===e.dump.charCodeAt(0)?f+="?":f+="? "),f+=e.dump,h&&(f+=$ce(e,t)),e0(e,t+1,d,!0,h)&&(e.dump&&iw===e.dump.charCodeAt(0)?f+=":":f+=": ",f+=e.dump,a+=f));e.tag=i,e.dump=a||"{}"}function TEe(e,t,r){var n,a,i,o,s,l;for(a=r?e.explicitTypes:e.implicitTypes,i=0,o=a.length;i<o;i+=1)if(s=a[i],(s.instanceOf||s.predicate)&&(!s.instanceOf||typeof t=="object"&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=r?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,lEe.call(s.represent)==="[object Function]")n=s.represent(t,l);else if(cEe.call(s.represent,l))n=s.represent[l](t,l);else throw new aw("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');e.dump=n}return!0}return!1}function e0(e,t,r,n,a,i){e.tag=null,e.dump=r,TEe(e,r,!1)||TEe(e,r,!0);var o=lEe.call(e.dump);n&&(n=e.flowLevel<0||e.flowLevel>t);var s=o==="[object Object]"||o==="[object Array]",l,u;if(s&&(l=e.duplicates.indexOf(r),u=l!==-1),(e.tag!==null&&e.tag!=="?"||u||e.indent!==2&&t>0)&&(a=!1),u&&e.usedDuplicates[l])e.dump="*ref_"+l;else{if(s&&u&&!e.usedDuplicates[l]&&(e.usedDuplicates[l]=!0),o==="[object Object]")n&&Object.keys(e.dump).length!==0?(Y5t(e,t,e.dump,a),u&&(e.dump="&ref_"+l+e.dump)):(W5t(e,t,e.dump),u&&(e.dump="&ref_"+l+" "+e.dump));else if(o==="[object Array]"){var d=e.noArrayIndent&&t>0?t-1:t;n&&e.dump.length!==0?(Q5t(e,d,e.dump,a),u&&(e.dump="&ref_"+l+e.dump)):(G5t(e,d,e.dump),u&&(e.dump="&ref_"+l+" "+e.dump))}else if(o==="[object String]")e.tag!=="?"&&j5t(e,e.dump,t,i);else{if(e.skipInvalid)return!1;throw new aw("unacceptable kind of an object to dump "+o)}e.tag!==null&&e.tag!=="?"&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function K5t(e,t){var r=[],n=[],a,i;for(zce(e,r,n),a=0,i=n.length;a<i;a+=1)t.duplicates.push(r[n[a]]);t.usedDuplicates=new Array(i)}function zce(e,t,r){var n,a,i;if(e!==null&&typeof e=="object")if(a=t.indexOf(e),a!==-1)r.indexOf(a)===-1&&r.push(a);else if(t.push(e),Array.isArray(e))for(a=0,i=e.length;a<i;a+=1)zce(e[a],t,r);else for(n=Object.keys(e),a=0,i=n.length;a<i;a+=1)zce(e[n[a]],t,r)}function LEe(e,t){t=t||{};var r=new P5t(t);return r.noRefs||K5t(e,r),e0(r,0,e,!0,!0)?r.dump+`
754
754
  `:""}function X5t(e,t){return LEe(e,nw.extend({schema:v5t},t))}Pce.dump=LEe,Pce.safeDump=X5t;var s9=J5,NEe=Pce;function l9(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}Ha.Type=eo,Ha.Schema=Bv,Ha.FAILSAFE_SCHEMA=Rce,Ha.JSON_SCHEMA=P9e,Ha.CORE_SCHEMA=$9e,Ha.DEFAULT_SAFE_SCHEMA=rw,Ha.DEFAULT_FULL_SCHEMA=t9,Ha.load=s9.load,Ha.loadAll=s9.loadAll,Ha.safeLoad=s9.safeLoad,Ha.safeLoadAll=s9.safeLoadAll,Ha.dump=NEe.dump,Ha.safeDump=NEe.safeDump,Ha.YAMLException=tw,Ha.MINIMAL_SCHEMA=Rce,Ha.SAFE_SCHEMA=rw,Ha.DEFAULT_SCHEMA=t9,Ha.scan=l9("scan"),Ha.parse=l9("parse"),Ha.compose=l9("compose"),Ha.addConstructor=l9("addConstructor");var Z5t=Ha,J5t=Z5t,MEe=J5t,ewt="\\ufeff?",twt=typeof process<"u"?process.platform:"",rwt="^("+ewt+"(= yaml =|---)$([\\s\\S]*?)^(?:\\2|\\.\\.\\.)\\s*$"+(twt==="win32"?"\\r?":"")+"(?:\\n)?)",IEe=new RegExp(rwt,"m");Nce.exports=nwt,Nce.exports.test=owt;function nwt(e,t){e=e||"";var r={allowUnsafe:!1};t=t instanceof Object?{...r,...t}:r,t.allowUnsafe=!!t.allowUnsafe;var n=e.split(/(\r?\n)/);return n[0]&&/= yaml =|---/.test(n[0])?iwt(e,t.allowUnsafe):{attributes:{},body:e,bodyBegin:1}}function awt(e,t){for(var r=1,n=t.indexOf(`
755
755
  `),a=e.index+e[0].length;n!==-1;){if(n>=a)return r;r++,n=t.indexOf(`
756
- `,n+1)}return r}function iwt(e,t){var r=IEe.exec(e);if(!r)return{attributes:{},body:e,bodyBegin:1};var n=t?MEe.load:MEe.safeLoad,a=r[r.length-1].replace(/^\s+|\s+$/g,""),i=n(a)||{},o=e.replace(r[0],""),s=awt(r,e);return{attributes:i,body:o,bodyBegin:s,frontmatter:a}}function owt(e){return e=e||"",IEe.test(e)}var swt=Nce.exports;const REe=Ta(swt),lwt=1;class cwt{constructor(){mr(this,"name","engagement_indicator")}calculateStepIndicator(t,r){return r.status!=="skipped"&&r.status!=="unread"?Math.min(r.time_spent/3600*100,100):0}calculateGlobalIndicator(t,r){const n={total_time:.3,num_sessions:.2,completion_rate:.3,interactions:.2},a=Math.min(r.total_time_on_platform/36e3,1)*100,i=Math.min(r.num_sessions/5,1)*100,o=r.completion_rate,s=Math.min(r.total_interactions/100,1)*100;return(a*n.total_time+i*n.num_sessions+o*n.completion_rate+s*n.interactions)/100*100}}class uwt{constructor(){mr(this,"name","frustration_indicator")}calculateStepIndicator(t,r){return r.status==="completed"?Math.min((r.comp_struggles+r.test_struggles)/20*100,100):r.status==="attempted"?Math.min(r.time_spent/1800*100,100):r.status==="skipped"?25:0}calculateGlobalIndicator(t,r){const n={steps_not_completed:.3,time_on_incomplete:.2,avg_comp_struggles:.2,avg_test_struggles:.2,skipped_steps:.1},a=r.total_steps>0?r.steps_not_completed/r.total_steps*100:0,i=Math.min(r.time_on_incomplete/18e3,1)*100,o=Math.min(r.avg_comp_struggles/10,1)*100,s=Math.min(r.avg_test_struggles/10,1)*100,l=r.total_steps>0?r.skipped_steps/r.total_steps*100:0;return(a*n.steps_not_completed+i*n.time_on_incomplete+o*n.avg_comp_struggles+s*n.avg_test_struggles+l*n.skipped_steps)/100*100}}function BEe(e){var x,w,C,S,T,N,M,B,D,I,O,F,P,R,U,$;let t=0;e.sessions&&e.sessions.length>0&&(t=e.sessions.reduce((z,q)=>z+q,0));let r=t;!t&&e.completed_at&&e.opened_at&&(r=e.completed_at-e.opened_at,t=r);let n=e.completed_at?"completed":e.opened_at?"attempted":"unread";const a=((x=e.compilations)==null?void 0:x.filter(z=>z.exit_code!==0).length)||0,i=((w=e.compilations)==null?void 0:w.filter(z=>z.exit_code===0).length)||0,o=((C=e.tests)==null?void 0:C.filter(z=>z.exit_code!==0).length)||0,s=((S=e.tests)==null?void 0:S.filter(z=>z.exit_code===0).length)||0,l=((T=e.quiz_submissions)==null?void 0:T.filter(z=>z.status==="ERROR").length)||0,u=((N=e.quiz_submissions)==null?void 0:N.filter(z=>z.status==="SUCCESS").length)||0;let d=0,h=0;for(let z=((M=e.compilations)==null?void 0:M.length)-1;z>=0&&e.compilations[z].exit_code!==0;z--)d++;for(let z=((B=e.compilations)==null?void 0:B.length)-1;z>=0&&e.compilations[z].exit_code===0;z--)h++;let f=0,p=0;for(let z=((D=e.tests)==null?void 0:D.length)-1;z>=0&&e.tests[z].exit_code!==0;z--)f++;for(let z=((I=e.tests)==null?void 0:I.length)-1;z>=0&&e.tests[z].exit_code===0;z--)p++;let g=0,A=0;for(let z=((O=e.quiz_submissions)==null?void 0:O.length)-1;z>=0&&e.quiz_submissions[z].status==="ERROR";z--)g++;for(let z=((F=e.quiz_submissions)==null?void 0:F.length)-1;z>=0&&e.quiz_submissions[z].status==="SUCCESS";z--)A++;const m=e.is_testeable||e.testeable_elements&&e.testeable_elements.length>0,y=(((P=e.quiz_submissions)==null?void 0:P.length)||0)===0&&(((R=e.tests)==null?void 0:R.length)||0)===0&&(((U=e.compilations)==null?void 0:U.length)||0)===0,v=!!m&&y,b=(($=e.ai_interactions)==null?void 0:$.length)||0,_=a+o+l>0&&i+s+u===0;return{status:n,time_spent:r,total_duration:t,comp_struggles:a,comp_success:i,total_comp_attempts:i+a,test_struggles:o,test_success:s,total_test_attempts:s+o,quiz_struggles:l,quiz_success:u,total_quiz_attempts:u+l,streak_comp_struggles:d,streak_comp_success:h,streak_test_struggle:f,streak_test_success:p,streak_quiz_struggles:g,streak_quiz_success:A,user_skipped:v,total_ai_interactions:b,ai_used:b>0,is_abandoned:_}}function dwt(e){const t=e.length,r=e.map(BEe),n=r.filter(g=>g.status==="completed").length,a=r.filter(g=>g.status==="attempted").length,i=r.filter(g=>g.status==="skipped").length,o=r.filter(g=>g.status==="unread").length,s=t?n/t*100:0,l=e.reduce((g,A)=>{var m,y,v,b;return g+(((m=A.compilations)==null?void 0:m.length)||0)+(((y=A.tests)==null?void 0:y.length)||0)+(((v=A.quiz_submissions)==null?void 0:v.length)||0)+(((b=A.ai_interactions)==null?void 0:b.length)||0)},0),u=r.reduce((g,A)=>g+A.time_spent,0),d=a+i+o,h=t?r.reduce((g,A)=>g+A.comp_struggles,0)/t:0,f=t?r.reduce((g,A)=>g+A.test_struggles,0)/t:0;let p=0;for(const g of e){let A=0;for(const m of g.tests||[])m.exit_code===0?A++:A=0,p=Math.max(p,A)}return{total_time_on_platform:u,num_sessions:1,completion_rate:s,total_interactions:l,steps_not_completed:d,time_on_incomplete:u,avg_comp_struggles:h,avg_test_struggles:f,skipped_steps:i,total_steps:t,global_test_success_streak:p}}function Uv(e){const t=[new cwt,new uwt],r=e.steps.map(o=>BEe(o)),n=dwt(e.steps),a=e.steps.map((o,s)=>{const l=r[s],u={engagement_indicator:0,frustration_indicator:0};return t.forEach(d=>{u[d.name]=d.calculateStepIndicator(o,l)}),{slug:o.slug,metrics:l,indicators:u}}),i={engagement_indicator:0,frustration_indicator:0};return t.forEach(o=>{i[o.name]=o.calculateGlobalIndicator(a.map(s=>s.indicators[o.name]),n)}),{algo_version:lwt,global:{metrics:n,indicators:i},steps:a}}function hwt(e,t){var d,h,f,p;if(!e.testeable_elements)return;const r=e.testeable_elements.find(g=>g.hash===t);if(!r)return;const n=r.type==="quiz"?((d=e.quiz_submissions.find(g=>g.quiz_hash===t))==null?void 0:d.ended_at)||e.opened_at||0:((h=e.tests.shift())==null?void 0:h.started_at)||e.opened_at||0,a=r.type==="quiz"?((f=e.quiz_submissions.findLast(g=>g.quiz_hash===t))==null?void 0:f.ended_at)||e.completed_at||1:((p=e.tests.shift())==null?void 0:p.started_at)||e.completed_at||1,i=Number((a-n)/1e3),o=e.ai_interactions.filter(g=>g.started_at>=n&&g.ended_at<=a).length,s=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t).length:e.tests.length,l=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="ERROR").length:e.tests.filter(g=>g.exit_code!==1).length,u=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="SUCCESS").length:e.tests.filter(g=>g.exit_code===1).length;return{started_at:n,ended_at:a,resolution_time_seconds:i,n_ai_interactions:o,n_tries:s,n_fail:l,n_success:u}}const OEe={name:"learnpack-ai",private:!0,version:"5.0.399",scripts:{dev:"node src/utils/development.js --turn on && vite",build:"node src/utils/development.js --turn off && tsc && vite build && node src/utils/uploadLearnpack.js && node bin/publish.js && node src/utils/createVersionsFile.js ","dev-build":"node src/utils/development.js --turn on && tsc && vite build",lint:"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",preview:"vite preview",watch:"vite build --watch","compile-command":"tsc src/utils/development.ts && node src/utils/development.js --turn on"},dependencies:{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@monaco-editor/react":"^4.6.0","@radix-ui/react-tooltip":"^1.2.8",axios:"^1.7.7","class-variance-authority":"^0.7.1",clsx:"^2.1.1",dompurify:"^3.3.0","front-matter":"^4.0.2","highlight.js":"^11.11.1",html2canvas:"^1.4.1",i18next:"^23.10.1","js-yaml":"^4.1.0","lucide-react":"^0.545.0",mermaid:"^11.6.0",mitt:"^3.0.1","monaco-editor":"^0.50.0","prompt-sync":"^4.2.0","pusher-js":"7.6.0","radix-ui":"^1.4.3",react:"^18.2.0","react-dom":"^18.2.0","react-draggable":"^4.4.6","react-gtm-module":"^2.0.11","react-hot-toast":"^2.4.1","react-i18next":"^14.1.0","react-markdown":"^9.0.1","react-monaco-editor":"^0.56.1","react-router-dom":"^6.27.0","react-syntax-highlighter":"^15.6.1","rehype-katex":"^7.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.0","remark-math":"^6.0.0","socket.io":"^4.7.2","socket.io-client":"^4.7.2","tailwind-merge":"^3.3.1","tailwindcss-animate":"^1.0.7",uuid:"^10.0.0",zustand:"^4.4.1"},devDependencies:{"@aws-sdk/client-cloudfront":"^3.840.0","@aws-sdk/client-s3":"^3.709.0","@types/dompurify":"^3.0.5","@types/js-yaml":"^4.0.9","@types/markdown-it":"^14.1.2","@types/node":"^24.9.1","@types/react":"^18.2.15","@types/react-dom":"^18.2.7","@types/react-gtm-module":"^2.0.3","@types/react-syntax-highlighter":"^15.5.13","@types/remarkable":"^2.0.3","@types/uuid":"^10.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","@vitejs/plugin-react-swc":"^3.3.2",archiver:"^6.0.1",autoprefixer:"^10.4.21",dotenv:"^16.4.7",eslint:"^8.45.0","eslint-plugin-react-hooks":"^4.6.0","eslint-plugin-react-refresh":"^0.4.3",inquirer:"^9.2.12",postcss:"^8.5.6",tailwindcss:"^3.4.18",typescript:"^5.0.2",vite:"^4.5.13"}};function fwt(e){return{all:e=e||new Map,on:function(t,r){var n=e.get(t);n?n.push(r):e.set(t,[r])},off:function(t,r){var n=e.get(t);n&&(r?n.splice(n.indexOf(r)>>>0,1):e.set(t,[]))},emit:function(t,r){var n=e.get(t);n&&n.slice().map(function(a){a(r)}),(n=e.get("*"))&&n.slice().map(function(a){a(t,r)})}}}const zr=fwt(),Hce=async(e,t)=>{if(!t)throw new Error("Slug is required");const r=`${ui}/v1/learnpack/session/?slug=${t}`;try{return(await Ur.get(r,{headers:{Authorization:`Token ${e}`}})).data}catch(n){throw console.error("Error fetching session:",n),n}},jce=async(e,t,r,n,a)=>{const i=`${ui}/v1/learnpack/session/${a}/`,o={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.put(i,o,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(s){throw console.error("Error updating session:",s),s}},pwt=async(e,t,r,n)=>{const a=`${ui}/v1/learnpack/session/`,i={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.post(a,i,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(o){throw console.error("Error creating session:",o),o}};async function gwt(e){const t=`${Lv}/v1/payments/me/service/consumable?virtual=true`,r={Authorization:`Token ${e}`};try{return(await Ur.get(t,{headers:r})).data}catch(n){throw console.error("Error fetching consumables:",n),n}}async function Awt(e,t="ai-conversation-message"){const r=`${Lv}/v1/payments/me/service/${t}/consumptionsession`,n={Authorization:`Token ${e}`};try{const a=await Ur.put(r,{},{headers:n});return a.status>=200&&a.status<300?(console.log(a.data),console.log(`Successfully consumed ${t}`),!0):(console.error(`Request failed with status code: ${a.status}`),console.error(`Response: ${a.data}`),!1)}catch(a){return console.error(`Error consuming ${t}:`,a),!1}}function mwt(e){if(!Array.isArray(e))return[];const t=[];for(const r of e){const n=typeof r=="number"?r:Number(r);Number.isFinite(n)&&t.push(n)}return t}async function qce(e,t){var a;const r={id:null,assetIds:[]};if(!(e!=null&&e.trim())||!t)return r;const n=`${ui}/v1/learnpack/package/${encodeURIComponent(t)}/assets/`;try{const o=(await Ur.get(n,{headers:{Authorization:`Token ${e.trim()}`}})).data;return{id:(o==null?void 0:o.id)!=null?String(o.id):null,assetIds:mwt(o==null?void 0:o.asset_ids)}}catch(i){return Ur.isAxiosError(i)&&((a=i.response)==null?void 0:a.status)===404||console.warn("fetchLearnpackPackageInfo failed:",i),r}}const ywt=async(e,t)=>{var a;const r=`${ui}/v1/learnpack/package/${t}/`;console.log("Checking if package is author",r,e);const n={Authorization:`Token ${e}`};try{const i=await Ur.get(r,{headers:n});return{isAuthor:i.status===200,status:i.status}}catch(i){const o=((a=i==null?void 0:i.response)==null?void 0:a.status)||500;return console.error("Error fetching package:",i),{isAuthor:!1,status:o}}},vwt=async(e,t,r=ui)=>{const n=await Ur.get(`${r}/v1/prompting/completion/${t}/`,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}});return console.log("RigoBot completion response:",n.data),n.data};function bwt(e,t){if(t.length===0)return e;const r=e.includes("?")?"&":"?";return`${e}${r}asset_id=${t.join(",")}`}const wwt=async function(e,t,r,n){if(!e||!r){console.error("URL and token are required");return}r=r.trim();const a={"Content-Type":"application/json",Authorization:`Token ${r}`},i=bwt(e,n??[]);try{return(await Ur.post(i,t,{headers:a})).data}catch(o){throw console.error("Error while sending batch telemetry",o),Ur.isAxiosError(o)&&o.response&&(console.error("Response data:",o.response.data),console.error("Response status:",o.response.status),console.error("Response headers:",o.response.headers)),o}},kwt=async function(e,t){const r=`${ui}/v1/learnpack/telemetry`,n={"Content-Type":"application/json",Authorization:`Token ${t}`};try{return(await Ur.post(r,e,{headers:n})).data}catch(a){throw console.error("Error while sending batch telemetry",a),a}},xwt=5e3,_wt=6e4,Cwt=5*60*1e3;async function DEe(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return null;const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),xwt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryFromServer: non-OK response",d.status),null;const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?null:f}catch(d){return d.name==="AbortError"?console.warn("fetchTelemetryFromServer: timeout or aborted"):console.warn("fetchTelemetryFromServer: failed",d),null}finally{clearTimeout(l)}}async function Ewt(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return{status:"empty"};const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),_wt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryWithStatus: non-OK response",d.status),{status:"server_error",code:d.status};const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?{status:"empty"}:{status:"ok",data:f}}catch(d){return d.name==="AbortError"?(console.warn("fetchTelemetryWithStatus: timeout"),{status:"timeout"}):(console.warn("fetchTelemetryWithStatus: network error",d),{status:"timeout"})}finally{clearTimeout(l)}}function FEe(e){return!e||typeof e.last_interaction_at!="number"?0:e.last_interaction_at}function c9(){return Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,10)}function PEe(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{var o,s,l,u,d,h,f,p,g,A;const a=r.get(n.slug);if(!a)return n;const i={...n};if(!i.completed_at&&a.completed_at&&(i.completed_at=a.completed_at),!i.is_completed&&a.is_completed&&(i.is_completed=!0),!i.opened_at&&a.opened_at&&(i.opened_at=a.opened_at),(o=a.testeable_elements)!=null&&o.length){const m=new Map((i.testeable_elements??[]).map(v=>[v.hash,v])),y=[...i.testeable_elements??[]];for(const v of a.testeable_elements){const b=m.get(v.hash);if(!b)y.push(v);else if(v.is_completed&&!b.is_completed){const _=y.findIndex(x=>x.hash===v.hash);_!==-1&&(y[_]={...b,is_completed:!0,metrics:b.metrics??v.metrics})}}i.testeable_elements=y}if((s=a.quiz_submissions)!=null&&s.length){const m=new Set((i.quiz_submissions??[]).map(v=>v.quiz_hash)),y=a.quiz_submissions.filter(v=>!m.has(v.quiz_hash));y.length>0&&(i.quiz_submissions=[...i.quiz_submissions??[],...y])}return!((l=i.tests)!=null&&l.length)&&((u=a.tests)!=null&&u.length)&&(i.tests=[...a.tests]),!((d=i.compilations)!=null&&d.length)&&((h=a.compilations)!=null&&h.length)&&(i.compilations=[...a.compilations]),!((f=i.ai_interactions)!=null&&f.length)&&((p=a.ai_interactions)!=null&&p.length)&&(i.ai_interactions=[...a.ai_interactions]),!((g=i.sessions)!=null&&g.length)&&((A=a.sessions)!=null&&A.length)&&(i.sessions=[...a.sessions]),i})}function Swt(e,t,r,n,a,i){const o=!!e,s=t&&t.slug===n;if(o&&!s)return{telemetry:t0({...e},r,n,a,i),source:"server"};if(!o&&s)return{telemetry:t0({...t},r,n,a,i),source:"local"};if(o&&s){const u=FEe(e),d=FEe(t),[h,f,p]=d>u?[t,e,"local"]:[e,t,"server"],g=t0({...h},r,n,a,i);return g.steps=PEe(g.steps,f.steps??[]),{telemetry:g,source:p}}const l=Date.now();return{telemetry:t0({telemetry_id:c9(),slug:n,version:`${i}`,agent:a,tutorial_started_at:l,last_interaction_at:l,steps:r,workout_session:[{started_at:l}],fullname:"",cohort_id:null,academy_id:null},r,n,a,i),source:"new"}}function Twt(e,t,r){if(!e||!r)return;const n=r.trim();fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${n}`},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}const Lwt=async function(e,t,r){!e||!r||fetch(e,{method:"POST",body:JSON.stringify(t)}).then(n=>n).catch(n=>{console.log("Error while sending stream Telemetry",n)})},Nwt=async function(){try{return(await Ur.get(`${ha}/telemetry`)).data}catch(e){return console.error("Error while retrieving telemetry from CLI",e),null}},Mwt=async function(e){try{const t=await Ur.post(`${ha}/telemetry`,e);return console.debug("Saved telemetry in CLI",t.data),t.data}catch(t){return console.error("Error while saving telemetry in CLI",t),null}};function Vce(e){if(typeof e!="string")throw new TypeError("Input must be a string");return btoa(encodeURIComponent(e))}const Iwt=(e,t)=>{let r={...t};return typeof r.starting_at<"u"&&typeof r.started_at>"u"&&(r.started_at=r.starting_at,delete r.starting_at),typeof r.ending_at<"u"&&typeof r.ended_at>"u"&&(r.ended_at=r.ending_at,delete r.ending_at),typeof r.started_at>"u"&&e!=="open_step"&&(r.started_at=Date.now()),typeof r.ended_at>"u"&&e!=="open_step"&&(r.ended_at=Date.now()),r.source_code&&(r.source_code=Vce(r.source_code)),r.stdout&&(r.stdout=Vce(r.stdout)),r.stderr&&(r.stderr=Vce(r.stderr)),Object.prototype.hasOwnProperty.call(r,"exitCode")&&(r.exit_code=r.exitCode,r.exitCode=void 0),r},Rwt=["telemetry_id","user_id","fullname","slug","package_id","version","cohort_id","academy_id","agent","tutorial_started_at","last_interaction_at","steps","workout_session","global_metrics","global_indicators"];function $Ee(e){return e==null||typeof e=="string"&&e.trim()===""?null:typeof e=="number"&&!Number.isNaN(e)?String(e):typeof e=="string"?e:null}function Bwt(e,t){if(!Array.isArray(e))return[{started_at:t}];if(e.length===0)return[{started_at:t}];const r=e.filter(n=>!!n&&typeof n=="object"&&typeof n.started_at=="number");return r.length===0?[{started_at:t}]:r}function Owt(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{const a=r.get(n.slug);return a?{slug:n.slug,position:n.position,files:n.files,is_testeable:n.is_testeable,compilations:a.compilations??[],tests:a.tests??[],ai_interactions:a.ai_interactions??[],quiz_submissions:a.quiz_submissions??[],testeable_elements:a.testeable_elements??[],is_completed:a.is_completed??!1,completed_at:a.completed_at,opened_at:a.opened_at,sessions:a.sessions??[]}:n})}function t0(e,t,r,n,a){const i=e,o={};for(const g of Rwt)Object.prototype.hasOwnProperty.call(i,g)&&(o[g]=i[g]);const s=Date.now(),l=r,u=typeof o.version=="string"&&o.version.trim()!==""?o.version:`${a}`,d=typeof o.tutorial_started_at=="number"?o.tutorial_started_at:s,h=typeof o.last_interaction_at=="number"?o.last_interaction_at:s,f=Array.isArray(o.steps)&&o.steps.length>0?Owt(t,o.steps):t,p=Bwt(o.workout_session,s);return{telemetry_id:o.telemetry_id,user_id:o.user_id,fullname:o.fullname,slug:l,package_id:o.package_id,version:u,cohort_id:$Ee(o.cohort_id),academy_id:$Ee(o.academy_id),agent:typeof o.agent=="string"?o.agent:n,tutorial_started_at:d,last_interaction_at:h,steps:f,workout_session:p,global_metrics:o.global_metrics,global_indicators:o.global_indicators}}function UEe(e,t){e.telemetry_id||(e.telemetry_id=c9());const r=Uv(e),n=e.steps.map((a,i)=>{const o=e.telemetry_id||c9();return{...a,telemetry_id:o,metrics:r.steps[i].metrics,indicators:r.steps[i].indicators}});return{...e,steps:n,global_metrics:r.global.metrics,global_indicators:r.global.indicators,user_id:t}}const gr={current:null,urls:{},telemetryKey:"",packageAssetIds:[],listeners:{},agent:"cloud",prevStep:void 0,prevStepStartedAt:void 0,activeHashes:new Map,_lessonRenderedDebounce:null,user:{token:"",rigo_token:"",id:"",fullname:""},tutorialSlug:"",started:!1,reconciling:!1,version:`${OEe.version}`||"CLOUD:0.0.0",salute:e=>{console.log(e)},start:function(e,t,r,n,a,i){return this.activeHashes=new Map,this.packageAssetIds=[],this.telemetryKey=n,this.tutorialSlug=r,this.agent=e,this.user.id=a.user_id,this.user.token=a.token,this.user.rigo_token=a.rigo_token,this.user.fullname=a.fullname,this.current?Promise.resolve():e==="cloud"?(this.reconciling=!0,(async()=>{var s;let o=!1;try{const l=Hr.get(this.telemetryKey),u=String(l==null?void 0:l.user_id)===String(a==null?void 0:a.user_id),d=l&&l.slug===r&&u?l:null,h=!!((s=a.rigo_token)!=null&&s.trim()&&r),f=i!==void 0,[p,g]=await Promise.all([f?Promise.resolve(i):a.rigo_token&&a.user_id?DEe({userId:a.user_id,packageSlug:r,rigoToken:a.rigo_token}):Promise.resolve(null),h?qce(a.rigo_token,r):Promise.resolve({id:null,assetIds:[]})]);this.packageAssetIds=g.assetIds;const{telemetry:A,source:m}=Swt(p,d,t,r,e,this.version);if(this.current=A,this.current.user_id=a.user_id,this.current.fullname=a.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),g.id!=null&&this.mergePackageIdIfMissing(g.id),this.finishWorkoutSession(),this.save(),this.started=!0,!a.user_id){console.warn("No user ID found, impossible to submit telemetry at start");return}o=m==="local"}catch(l){throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(l),new Error(`There was a problem starting, reload LearnPack
756
+ `,n+1)}return r}function iwt(e,t){var r=IEe.exec(e);if(!r)return{attributes:{},body:e,bodyBegin:1};var n=t?MEe.load:MEe.safeLoad,a=r[r.length-1].replace(/^\s+|\s+$/g,""),i=n(a)||{},o=e.replace(r[0],""),s=awt(r,e);return{attributes:i,body:o,bodyBegin:s,frontmatter:a}}function owt(e){return e=e||"",IEe.test(e)}var swt=Nce.exports;const REe=Ta(swt),lwt=1;class cwt{constructor(){mr(this,"name","engagement_indicator")}calculateStepIndicator(t,r){return r.status!=="skipped"&&r.status!=="unread"?Math.min(r.time_spent/3600*100,100):0}calculateGlobalIndicator(t,r){const n={total_time:.3,num_sessions:.2,completion_rate:.3,interactions:.2},a=Math.min(r.total_time_on_platform/36e3,1)*100,i=Math.min(r.num_sessions/5,1)*100,o=r.completion_rate,s=Math.min(r.total_interactions/100,1)*100;return(a*n.total_time+i*n.num_sessions+o*n.completion_rate+s*n.interactions)/100*100}}class uwt{constructor(){mr(this,"name","frustration_indicator")}calculateStepIndicator(t,r){return r.status==="completed"?Math.min((r.comp_struggles+r.test_struggles)/20*100,100):r.status==="attempted"?Math.min(r.time_spent/1800*100,100):r.status==="skipped"?25:0}calculateGlobalIndicator(t,r){const n={steps_not_completed:.3,time_on_incomplete:.2,avg_comp_struggles:.2,avg_test_struggles:.2,skipped_steps:.1},a=r.total_steps>0?r.steps_not_completed/r.total_steps*100:0,i=Math.min(r.time_on_incomplete/18e3,1)*100,o=Math.min(r.avg_comp_struggles/10,1)*100,s=Math.min(r.avg_test_struggles/10,1)*100,l=r.total_steps>0?r.skipped_steps/r.total_steps*100:0;return(a*n.steps_not_completed+i*n.time_on_incomplete+o*n.avg_comp_struggles+s*n.avg_test_struggles+l*n.skipped_steps)/100*100}}function BEe(e){var x,w,C,S,T,N,M,B,D,I,O,F,P,R,U,$;let t=0;e.sessions&&e.sessions.length>0&&(t=e.sessions.reduce((z,q)=>z+q,0));let r=t;!t&&e.completed_at&&e.opened_at&&(r=e.completed_at-e.opened_at,t=r);let n=e.completed_at?"completed":e.opened_at?"attempted":"unread";const a=((x=e.compilations)==null?void 0:x.filter(z=>z.exit_code!==0).length)||0,i=((w=e.compilations)==null?void 0:w.filter(z=>z.exit_code===0).length)||0,o=((C=e.tests)==null?void 0:C.filter(z=>z.exit_code!==0).length)||0,s=((S=e.tests)==null?void 0:S.filter(z=>z.exit_code===0).length)||0,l=((T=e.quiz_submissions)==null?void 0:T.filter(z=>z.status==="ERROR").length)||0,u=((N=e.quiz_submissions)==null?void 0:N.filter(z=>z.status==="SUCCESS").length)||0;let d=0,h=0;for(let z=((M=e.compilations)==null?void 0:M.length)-1;z>=0&&e.compilations[z].exit_code!==0;z--)d++;for(let z=((B=e.compilations)==null?void 0:B.length)-1;z>=0&&e.compilations[z].exit_code===0;z--)h++;let f=0,p=0;for(let z=((D=e.tests)==null?void 0:D.length)-1;z>=0&&e.tests[z].exit_code!==0;z--)f++;for(let z=((I=e.tests)==null?void 0:I.length)-1;z>=0&&e.tests[z].exit_code===0;z--)p++;let g=0,A=0;for(let z=((O=e.quiz_submissions)==null?void 0:O.length)-1;z>=0&&e.quiz_submissions[z].status==="ERROR";z--)g++;for(let z=((F=e.quiz_submissions)==null?void 0:F.length)-1;z>=0&&e.quiz_submissions[z].status==="SUCCESS";z--)A++;const m=e.is_testeable||e.testeable_elements&&e.testeable_elements.length>0,y=(((P=e.quiz_submissions)==null?void 0:P.length)||0)===0&&(((R=e.tests)==null?void 0:R.length)||0)===0&&(((U=e.compilations)==null?void 0:U.length)||0)===0,v=!!m&&y,b=(($=e.ai_interactions)==null?void 0:$.length)||0,_=a+o+l>0&&i+s+u===0;return{status:n,time_spent:r,total_duration:t,comp_struggles:a,comp_success:i,total_comp_attempts:i+a,test_struggles:o,test_success:s,total_test_attempts:s+o,quiz_struggles:l,quiz_success:u,total_quiz_attempts:u+l,streak_comp_struggles:d,streak_comp_success:h,streak_test_struggle:f,streak_test_success:p,streak_quiz_struggles:g,streak_quiz_success:A,user_skipped:v,total_ai_interactions:b,ai_used:b>0,is_abandoned:_}}function dwt(e){const t=e.length,r=e.map(BEe),n=r.filter(g=>g.status==="completed").length,a=r.filter(g=>g.status==="attempted").length,i=r.filter(g=>g.status==="skipped").length,o=r.filter(g=>g.status==="unread").length,s=t?n/t*100:0,l=e.reduce((g,A)=>{var m,y,v,b;return g+(((m=A.compilations)==null?void 0:m.length)||0)+(((y=A.tests)==null?void 0:y.length)||0)+(((v=A.quiz_submissions)==null?void 0:v.length)||0)+(((b=A.ai_interactions)==null?void 0:b.length)||0)},0),u=r.reduce((g,A)=>g+A.time_spent,0),d=a+i+o,h=t?r.reduce((g,A)=>g+A.comp_struggles,0)/t:0,f=t?r.reduce((g,A)=>g+A.test_struggles,0)/t:0;let p=0;for(const g of e){let A=0;for(const m of g.tests||[])m.exit_code===0?A++:A=0,p=Math.max(p,A)}return{total_time_on_platform:u,num_sessions:1,completion_rate:s,total_interactions:l,steps_not_completed:d,time_on_incomplete:u,avg_comp_struggles:h,avg_test_struggles:f,skipped_steps:i,total_steps:t,global_test_success_streak:p}}function Uv(e){const t=[new cwt,new uwt],r=e.steps.map(o=>BEe(o)),n=dwt(e.steps),a=e.steps.map((o,s)=>{const l=r[s],u={engagement_indicator:0,frustration_indicator:0};return t.forEach(d=>{u[d.name]=d.calculateStepIndicator(o,l)}),{slug:o.slug,metrics:l,indicators:u}}),i={engagement_indicator:0,frustration_indicator:0};return t.forEach(o=>{i[o.name]=o.calculateGlobalIndicator(a.map(s=>s.indicators[o.name]),n)}),{algo_version:lwt,global:{metrics:n,indicators:i},steps:a}}function hwt(e,t){var d,h,f,p;if(!e.testeable_elements)return;const r=e.testeable_elements.find(g=>g.hash===t);if(!r)return;const n=r.type==="quiz"?((d=e.quiz_submissions.find(g=>g.quiz_hash===t))==null?void 0:d.ended_at)||e.opened_at||0:((h=e.tests.shift())==null?void 0:h.started_at)||e.opened_at||0,a=r.type==="quiz"?((f=e.quiz_submissions.findLast(g=>g.quiz_hash===t))==null?void 0:f.ended_at)||e.completed_at||1:((p=e.tests.shift())==null?void 0:p.started_at)||e.completed_at||1,i=Number((a-n)/1e3),o=e.ai_interactions.filter(g=>g.started_at>=n&&g.ended_at<=a).length,s=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t).length:e.tests.length,l=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="ERROR").length:e.tests.filter(g=>g.exit_code!==1).length,u=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="SUCCESS").length:e.tests.filter(g=>g.exit_code===1).length;return{started_at:n,ended_at:a,resolution_time_seconds:i,n_ai_interactions:o,n_tries:s,n_fail:l,n_success:u}}const OEe={name:"learnpack-ai",private:!0,version:"5.0.400",scripts:{dev:"node src/utils/development.js --turn on && vite",build:"node src/utils/development.js --turn off && tsc && vite build && node src/utils/uploadLearnpack.js && node bin/publish.js && node src/utils/createVersionsFile.js ","dev-build":"node src/utils/development.js --turn on && tsc && vite build",lint:"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",preview:"vite preview",watch:"vite build --watch","compile-command":"tsc src/utils/development.ts && node src/utils/development.js --turn on"},dependencies:{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@monaco-editor/react":"^4.6.0","@radix-ui/react-tooltip":"^1.2.8",axios:"^1.7.7","class-variance-authority":"^0.7.1",clsx:"^2.1.1",dompurify:"^3.3.0","front-matter":"^4.0.2","highlight.js":"^11.11.1",html2canvas:"^1.4.1",i18next:"^23.10.1","js-yaml":"^4.1.0","lucide-react":"^0.545.0",mermaid:"^11.6.0",mitt:"^3.0.1","monaco-editor":"^0.50.0","prompt-sync":"^4.2.0","pusher-js":"7.6.0","radix-ui":"^1.4.3",react:"^18.2.0","react-dom":"^18.2.0","react-draggable":"^4.4.6","react-gtm-module":"^2.0.11","react-hot-toast":"^2.4.1","react-i18next":"^14.1.0","react-markdown":"^9.0.1","react-monaco-editor":"^0.56.1","react-router-dom":"^6.27.0","react-syntax-highlighter":"^15.6.1","rehype-katex":"^7.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.0","remark-math":"^6.0.0","socket.io":"^4.7.2","socket.io-client":"^4.7.2","tailwind-merge":"^3.3.1","tailwindcss-animate":"^1.0.7",uuid:"^10.0.0",zustand:"^4.4.1"},devDependencies:{"@aws-sdk/client-cloudfront":"^3.840.0","@aws-sdk/client-s3":"^3.709.0","@types/dompurify":"^3.0.5","@types/js-yaml":"^4.0.9","@types/markdown-it":"^14.1.2","@types/node":"^24.9.1","@types/react":"^18.2.15","@types/react-dom":"^18.2.7","@types/react-gtm-module":"^2.0.3","@types/react-syntax-highlighter":"^15.5.13","@types/remarkable":"^2.0.3","@types/uuid":"^10.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","@vitejs/plugin-react-swc":"^3.3.2",archiver:"^6.0.1",autoprefixer:"^10.4.21",dotenv:"^16.4.7",eslint:"^8.45.0","eslint-plugin-react-hooks":"^4.6.0","eslint-plugin-react-refresh":"^0.4.3",inquirer:"^9.2.12",postcss:"^8.5.6",tailwindcss:"^3.4.18",typescript:"^5.0.2",vite:"^4.5.13"}};function fwt(e){return{all:e=e||new Map,on:function(t,r){var n=e.get(t);n?n.push(r):e.set(t,[r])},off:function(t,r){var n=e.get(t);n&&(r?n.splice(n.indexOf(r)>>>0,1):e.set(t,[]))},emit:function(t,r){var n=e.get(t);n&&n.slice().map(function(a){a(r)}),(n=e.get("*"))&&n.slice().map(function(a){a(t,r)})}}}const zr=fwt(),Hce=async(e,t)=>{if(!t)throw new Error("Slug is required");const r=`${ui}/v1/learnpack/session/?slug=${t}`;try{return(await Ur.get(r,{headers:{Authorization:`Token ${e}`}})).data}catch(n){throw console.error("Error fetching session:",n),n}},jce=async(e,t,r,n,a)=>{const i=`${ui}/v1/learnpack/session/${a}/`,o={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.put(i,o,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(s){throw console.error("Error updating session:",s),s}},pwt=async(e,t,r,n)=>{const a=`${ui}/v1/learnpack/session/`,i={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.post(a,i,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(o){throw console.error("Error creating session:",o),o}};async function gwt(e){const t=`${Lv}/v1/payments/me/service/consumable?virtual=true`,r={Authorization:`Token ${e}`};try{return(await Ur.get(t,{headers:r})).data}catch(n){throw console.error("Error fetching consumables:",n),n}}async function Awt(e,t="ai-conversation-message"){const r=`${Lv}/v1/payments/me/service/${t}/consumptionsession`,n={Authorization:`Token ${e}`};try{const a=await Ur.put(r,{},{headers:n});return a.status>=200&&a.status<300?(console.log(a.data),console.log(`Successfully consumed ${t}`),!0):(console.error(`Request failed with status code: ${a.status}`),console.error(`Response: ${a.data}`),!1)}catch(a){return console.error(`Error consuming ${t}:`,a),!1}}function mwt(e){if(!Array.isArray(e))return[];const t=[];for(const r of e){const n=typeof r=="number"?r:Number(r);Number.isFinite(n)&&t.push(n)}return t}async function qce(e,t){var a;const r={id:null,assetIds:[]};if(!(e!=null&&e.trim())||!t)return r;const n=`${ui}/v1/learnpack/package/${encodeURIComponent(t)}/assets/`;try{const o=(await Ur.get(n,{headers:{Authorization:`Token ${e.trim()}`}})).data;return{id:(o==null?void 0:o.id)!=null?String(o.id):null,assetIds:mwt(o==null?void 0:o.asset_ids)}}catch(i){return Ur.isAxiosError(i)&&((a=i.response)==null?void 0:a.status)===404||console.warn("fetchLearnpackPackageInfo failed:",i),r}}const ywt=async(e,t)=>{var a;const r=`${ui}/v1/learnpack/package/${t}/`;console.log("Checking if package is author",r,e);const n={Authorization:`Token ${e}`};try{const i=await Ur.get(r,{headers:n});return{isAuthor:i.status===200,status:i.status}}catch(i){const o=((a=i==null?void 0:i.response)==null?void 0:a.status)||500;return console.error("Error fetching package:",i),{isAuthor:!1,status:o}}},vwt=async(e,t,r=ui)=>{const n=await Ur.get(`${r}/v1/prompting/completion/${t}/`,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}});return console.log("RigoBot completion response:",n.data),n.data};function bwt(e,t){if(t.length===0)return e;const r=e.includes("?")?"&":"?";return`${e}${r}asset_id=${t.join(",")}`}const wwt=async function(e,t,r,n){if(!e||!r){console.error("URL and token are required");return}r=r.trim();const a={"Content-Type":"application/json",Authorization:`Token ${r}`},i=bwt(e,n??[]);try{return(await Ur.post(i,t,{headers:a})).data}catch(o){throw console.error("Error while sending batch telemetry",o),Ur.isAxiosError(o)&&o.response&&(console.error("Response data:",o.response.data),console.error("Response status:",o.response.status),console.error("Response headers:",o.response.headers)),o}},kwt=async function(e,t){const r=`${ui}/v1/learnpack/telemetry`,n={"Content-Type":"application/json",Authorization:`Token ${t}`};try{return(await Ur.post(r,e,{headers:n})).data}catch(a){throw console.error("Error while sending batch telemetry",a),a}},xwt=5e3,_wt=6e4,Cwt=5*60*1e3;async function DEe(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return null;const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),xwt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryFromServer: non-OK response",d.status),null;const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?null:f}catch(d){return d.name==="AbortError"?console.warn("fetchTelemetryFromServer: timeout or aborted"):console.warn("fetchTelemetryFromServer: failed",d),null}finally{clearTimeout(l)}}async function Ewt(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return{status:"empty"};const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),_wt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryWithStatus: non-OK response",d.status),{status:"server_error",code:d.status};const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?{status:"empty"}:{status:"ok",data:f}}catch(d){return d.name==="AbortError"?(console.warn("fetchTelemetryWithStatus: timeout"),{status:"timeout"}):(console.warn("fetchTelemetryWithStatus: network error",d),{status:"timeout"})}finally{clearTimeout(l)}}function FEe(e){return!e||typeof e.last_interaction_at!="number"?0:e.last_interaction_at}function c9(){return Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,10)}function PEe(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{var o,s,l,u,d,h,f,p,g,A;const a=r.get(n.slug);if(!a)return n;const i={...n};if(!i.completed_at&&a.completed_at&&(i.completed_at=a.completed_at),!i.is_completed&&a.is_completed&&(i.is_completed=!0),!i.opened_at&&a.opened_at&&(i.opened_at=a.opened_at),(o=a.testeable_elements)!=null&&o.length){const m=new Map((i.testeable_elements??[]).map(v=>[v.hash,v])),y=[...i.testeable_elements??[]];for(const v of a.testeable_elements){const b=m.get(v.hash);if(!b)y.push(v);else if(v.is_completed&&!b.is_completed){const _=y.findIndex(x=>x.hash===v.hash);_!==-1&&(y[_]={...b,is_completed:!0,metrics:b.metrics??v.metrics})}}i.testeable_elements=y}if((s=a.quiz_submissions)!=null&&s.length){const m=new Set((i.quiz_submissions??[]).map(v=>v.quiz_hash)),y=a.quiz_submissions.filter(v=>!m.has(v.quiz_hash));y.length>0&&(i.quiz_submissions=[...i.quiz_submissions??[],...y])}return!((l=i.tests)!=null&&l.length)&&((u=a.tests)!=null&&u.length)&&(i.tests=[...a.tests]),!((d=i.compilations)!=null&&d.length)&&((h=a.compilations)!=null&&h.length)&&(i.compilations=[...a.compilations]),!((f=i.ai_interactions)!=null&&f.length)&&((p=a.ai_interactions)!=null&&p.length)&&(i.ai_interactions=[...a.ai_interactions]),!((g=i.sessions)!=null&&g.length)&&((A=a.sessions)!=null&&A.length)&&(i.sessions=[...a.sessions]),i})}function Swt(e,t,r,n,a,i){const o=!!e,s=t&&t.slug===n;if(o&&!s)return{telemetry:t0({...e},r,n,a,i),source:"server"};if(!o&&s)return{telemetry:t0({...t},r,n,a,i),source:"local"};if(o&&s){const u=FEe(e),d=FEe(t),[h,f,p]=d>u?[t,e,"local"]:[e,t,"server"],g=t0({...h},r,n,a,i);return g.steps=PEe(g.steps,f.steps??[]),{telemetry:g,source:p}}const l=Date.now();return{telemetry:t0({telemetry_id:c9(),slug:n,version:`${i}`,agent:a,tutorial_started_at:l,last_interaction_at:l,steps:r,workout_session:[{started_at:l}],fullname:"",cohort_id:null,academy_id:null},r,n,a,i),source:"new"}}function Twt(e,t,r){if(!e||!r)return;const n=r.trim();fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${n}`},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}const Lwt=async function(e,t,r){!e||!r||fetch(e,{method:"POST",body:JSON.stringify(t)}).then(n=>n).catch(n=>{console.log("Error while sending stream Telemetry",n)})},Nwt=async function(){try{return(await Ur.get(`${ha}/telemetry`)).data}catch(e){return console.error("Error while retrieving telemetry from CLI",e),null}},Mwt=async function(e){try{const t=await Ur.post(`${ha}/telemetry`,e);return console.debug("Saved telemetry in CLI",t.data),t.data}catch(t){return console.error("Error while saving telemetry in CLI",t),null}};function Vce(e){if(typeof e!="string")throw new TypeError("Input must be a string");return btoa(encodeURIComponent(e))}const Iwt=(e,t)=>{let r={...t};return typeof r.starting_at<"u"&&typeof r.started_at>"u"&&(r.started_at=r.starting_at,delete r.starting_at),typeof r.ending_at<"u"&&typeof r.ended_at>"u"&&(r.ended_at=r.ending_at,delete r.ending_at),typeof r.started_at>"u"&&e!=="open_step"&&(r.started_at=Date.now()),typeof r.ended_at>"u"&&e!=="open_step"&&(r.ended_at=Date.now()),r.source_code&&(r.source_code=Vce(r.source_code)),r.stdout&&(r.stdout=Vce(r.stdout)),r.stderr&&(r.stderr=Vce(r.stderr)),Object.prototype.hasOwnProperty.call(r,"exitCode")&&(r.exit_code=r.exitCode,r.exitCode=void 0),r},Rwt=["telemetry_id","user_id","fullname","slug","package_id","version","cohort_id","academy_id","agent","tutorial_started_at","last_interaction_at","steps","workout_session","global_metrics","global_indicators"];function $Ee(e){return e==null||typeof e=="string"&&e.trim()===""?null:typeof e=="number"&&!Number.isNaN(e)?String(e):typeof e=="string"?e:null}function Bwt(e,t){if(!Array.isArray(e))return[{started_at:t}];if(e.length===0)return[{started_at:t}];const r=e.filter(n=>!!n&&typeof n=="object"&&typeof n.started_at=="number");return r.length===0?[{started_at:t}]:r}function Owt(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{const a=r.get(n.slug);return a?{slug:n.slug,position:n.position,files:n.files,is_testeable:n.is_testeable,compilations:a.compilations??[],tests:a.tests??[],ai_interactions:a.ai_interactions??[],quiz_submissions:a.quiz_submissions??[],testeable_elements:a.testeable_elements??[],is_completed:a.is_completed??!1,completed_at:a.completed_at,opened_at:a.opened_at,sessions:a.sessions??[]}:n})}function t0(e,t,r,n,a){const i=e,o={};for(const g of Rwt)Object.prototype.hasOwnProperty.call(i,g)&&(o[g]=i[g]);const s=Date.now(),l=r,u=typeof o.version=="string"&&o.version.trim()!==""?o.version:`${a}`,d=typeof o.tutorial_started_at=="number"?o.tutorial_started_at:s,h=typeof o.last_interaction_at=="number"?o.last_interaction_at:s,f=Array.isArray(o.steps)&&o.steps.length>0?Owt(t,o.steps):t,p=Bwt(o.workout_session,s);return{telemetry_id:o.telemetry_id,user_id:o.user_id,fullname:o.fullname,slug:l,package_id:o.package_id,version:u,cohort_id:$Ee(o.cohort_id),academy_id:$Ee(o.academy_id),agent:typeof o.agent=="string"?o.agent:n,tutorial_started_at:d,last_interaction_at:h,steps:f,workout_session:p,global_metrics:o.global_metrics,global_indicators:o.global_indicators}}function UEe(e,t){e.telemetry_id||(e.telemetry_id=c9());const r=Uv(e),n=e.steps.map((a,i)=>{const o=e.telemetry_id||c9();return{...a,telemetry_id:o,metrics:r.steps[i].metrics,indicators:r.steps[i].indicators}});return{...e,steps:n,global_metrics:r.global.metrics,global_indicators:r.global.indicators,user_id:t}}const gr={current:null,urls:{},telemetryKey:"",packageAssetIds:[],listeners:{},agent:"cloud",prevStep:void 0,prevStepStartedAt:void 0,activeHashes:new Map,_lessonRenderedDebounce:null,user:{token:"",rigo_token:"",id:"",fullname:""},tutorialSlug:"",started:!1,reconciling:!1,version:`${OEe.version}`||"CLOUD:0.0.0",salute:e=>{console.log(e)},start:function(e,t,r,n,a,i){return this.activeHashes=new Map,this.packageAssetIds=[],this.telemetryKey=n,this.tutorialSlug=r,this.agent=e,this.user.id=a.user_id,this.user.token=a.token,this.user.rigo_token=a.rigo_token,this.user.fullname=a.fullname,this.current?Promise.resolve():e==="cloud"?(this.reconciling=!0,(async()=>{var s;let o=!1;try{const l=Hr.get(this.telemetryKey),u=String(l==null?void 0:l.user_id)===String(a==null?void 0:a.user_id),d=l&&l.slug===r&&u?l:null,h=!!((s=a.rigo_token)!=null&&s.trim()&&r),f=i!==void 0,[p,g]=await Promise.all([f?Promise.resolve(i):a.rigo_token&&a.user_id?DEe({userId:a.user_id,packageSlug:r,rigoToken:a.rigo_token}):Promise.resolve(null),h?qce(a.rigo_token,r):Promise.resolve({id:null,assetIds:[]})]);this.packageAssetIds=g.assetIds;const{telemetry:A,source:m}=Swt(p,d,t,r,e,this.version);if(this.current=A,this.current.user_id=a.user_id,this.current.fullname=a.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),g.id!=null&&this.mergePackageIdIfMissing(g.id),this.finishWorkoutSession(),this.save(),this.started=!0,!a.user_id){console.warn("No user ID found, impossible to submit telemetry at start");return}o=m==="local"}catch(l){throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(l),new Error(`There was a problem starting, reload LearnPack
757
757
  Run
758
758
  $ learnpack start`)}finally{this.reconciling=!1}o&&a.user_id&&await this.submit()})()):this.retrieve().then(async o=>{var s;if(o?(this.current=t0(o,t,r,e,this.version),this.finishWorkoutSession()):(console.debug("No previous telemetry found, creating new one. Agent: ",e),this.current=t0({telemetry_id:c9(),slug:r,version:`${this.version}`,agent:e,tutorial_started_at:Date.now(),last_interaction_at:Date.now(),steps:t,workout_session:[{started_at:Date.now()}],fullname:this.user.fullname,cohort_id:null,academy_id:null},t,r,e,this.version)),this.current.user_id=this.user.id,this.current.fullname=this.user.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),this.save(),this.started=!0,!this.user.id){console.warn("No user ID found, impossible to submit telemetry at start");return}if((s=this.user.rigo_token)!=null&&s.trim()&&r){const l=await qce(this.user.rigo_token,r);this.packageAssetIds=l.assetIds,l.id!=null&&this.mergePackageIdIfMissing(l.id)}await this.submit()}).catch(o=>{throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(o),new Error(`There was a problem starting, reload LearnPack
759
759
  Run
package/src/ui/app.tar.gz CHANGED
Binary file
@@ -8,8 +8,6 @@ This directory contains utilities for exporting courses to different formats.
8
8
  - **ZIP**: Full course mirror from GCS (includes `.learn/package-manifest.json`)
9
9
  - **EPUB**: E-book format for offline reading (does not include `package-manifest.json`)
10
10
 
11
- `package-manifest.json` is regenerated on each ZIP/SCORM export with `publishedAt: null`. See [`docs/package-manifest.md`](../../../../docs/package-manifest.md) in the monorepo.
12
-
13
11
  ## Usage
14
12
 
15
13
  ### API Endpoints
@@ -22,6 +22,7 @@ export type PackageManifestLesson = {
22
22
  position: number;
23
23
  type: LessonType;
24
24
  title: Record<string, string>;
25
+ description: Record<string, string | null>;
25
26
  video: Record<string, string | null>;
26
27
  };
27
28
 
@@ -165,6 +166,19 @@ function resolveLessonTitle(
165
166
  return titles
166
167
  }
167
168
 
169
+ function resolveLessonDescriptions(
170
+ exercise: Exercise
171
+ ): Record<string, string | null> {
172
+ const description: Record<string, string | null> = {}
173
+
174
+ for (const lang of Object.keys(exercise.translations)) {
175
+ // TODO: add description content
176
+ description[lang] = null
177
+ }
178
+
179
+ return description
180
+ }
181
+
168
182
  function resolveLessonVideos(
169
183
  exercise: Exercise,
170
184
  readmeFrontmatters: Record<string, Record<string, ReadmeFrontmatter>>
@@ -226,6 +240,7 @@ export function buildPackageManifestFromSources(
226
240
  courseLang,
227
241
  readmeFrontmatters[exercise.slug] ?? {}
228
242
  ),
243
+ description: resolveLessonDescriptions(exercise),
229
244
  video: resolveLessonVideos(exercise, readmeFrontmatters),
230
245
  }
231
246
  })
@@ -263,6 +278,40 @@ async function downloadJsonFile<T>(
263
278
  }
264
279
  }
265
280
 
281
+ export function parseReadmeContent(content: string): ReadmeFrontmatter {
282
+ const parsed = frontMatter(content)
283
+ const attributes = parsed.attributes || {}
284
+ const h1 = extractReadmeH1(parsed.body || "")
285
+ const title = h1 ? normalizeReadmeTitle(h1) : null
286
+ return {
287
+ ...(attributes.tutorial ? { tutorial: attributes.tutorial } : {}),
288
+ ...(attributes.intro ? { intro: attributes.intro } : {}),
289
+ ...(title ? { title } : {}),
290
+ }
291
+ }
292
+
293
+ export function comparePackageManifests(
294
+ existing: PackageManifest | null,
295
+ next: PackageManifest
296
+ ): "created" | "updated" | "skipped" {
297
+ if (existing === null) {
298
+ return "created"
299
+ }
300
+
301
+ const { generatedAt: _existingGeneratedAt, ...existingRest } = existing
302
+ const { generatedAt: _nextGeneratedAt, ...nextRest } = next
303
+
304
+ if (JSON.stringify(existingRest) === JSON.stringify(nextRest)) {
305
+ return "skipped"
306
+ }
307
+
308
+ return "updated"
309
+ }
310
+
311
+ export function serializePackageManifest(manifest: PackageManifest): string {
312
+ return JSON.stringify(manifest, null, 2)
313
+ }
314
+
266
315
  async function readReadmeFrontmatter(
267
316
  bucket: Bucket,
268
317
  exerciseSlug: string,
@@ -275,18 +324,10 @@ async function readReadmeFrontmatter(
275
324
  }> {
276
325
  try {
277
326
  const [buf] = await bucket.file(readmePath).download()
278
- const parsed = frontMatter(buf.toString())
279
- const attributes = parsed.attributes || {}
280
- const h1 = extractReadmeH1(parsed.body || "")
281
- const title = h1 ? normalizeReadmeTitle(h1) : null
282
327
  return {
283
328
  exerciseSlug,
284
329
  lang,
285
- frontmatter: {
286
- tutorial: attributes.tutorial,
287
- intro: attributes.intro,
288
- ...(title ? { title } : {}),
289
- },
330
+ frontmatter: parseReadmeContent(buf.toString()),
290
331
  }
291
332
  } catch (error) {
292
333
  console.warn(
@@ -328,7 +369,7 @@ function writeManifestJson(
328
369
  manifest: PackageManifest,
329
370
  localDir?: string
330
371
  ): string {
331
- const json = JSON.stringify(manifest, null, 2)
372
+ const json = serializePackageManifest(manifest)
332
373
 
333
374
  if (localDir) {
334
375
  const learnDir = path.join(localDir, ".learn")