@citolab/qti-components 7.9.0 → 7.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cdn/index.js CHANGED
@@ -126,7 +126,7 @@ Make sure to test your application with a production build as repeat registratio
126
126
  rgb(0 0 0 / 0%) calc(50% + 1px)
127
127
  );
128
128
  }
129
- `;var ne=Symbol("configContext");var k=class extends v{constructor(){super();this.disabled=!1;this.readonly=!1;this._internals=this.attachInternals()}static{this.formAssociated=!0}get internals(){return this._internals}get isFullCorrectResponse(){return this._isFullCorrectResponse}set isFullCorrectResponse(e){this._isFullCorrectResponse=e,e&&(this.disabled=!0,this.setAttribute("response-identifier",this.responseIdentifier+"_cr"))}get correctResponse(){return this._correctResponse}set correctResponse(e){this._correctResponse=e}get correctness(){let e=this.responseVariable;return!e||e.correctResponse===null?null:e.correctResponse===e.value?"correct":"incorrect"}get isInline(){return!1}get responseVariable(){let e=this._context.variables.filter(i=>i.type==="response"),t=this.getAttribute("response-identifier");return e.find(i=>i.identifier===t)}toggleCorrectResponse(e){(this?.configContext?.correctResponseMode||"internal")==="full"?this.toggleFullCorrectResponse(e):this.toggleInternalCorrectResponse(e)}async toggleFullCorrectResponse(e){let t=this.nextSibling,i=t instanceof HTMLDivElement&&t?.classList.contains("full-correct-response"),s=this.responseVariable;if(!s)return;if(!e||this.correctness==="correct"){if(!i)return;this.parentElement?.removeChild(t)}if(i||this.correctness==="correct")return;let n=this.cloneNode(!0),a=document.createElement("div");a.classList.add("full-correct-response"),this.isInline?a.classList.add("full-correct-response-inline"):a.classList.add("full-correct-response-block"),a.role="full-correct-response",a.appendChild(n),n.isFullCorrectResponse=!0,this.parentElement?.insertBefore(a,this.nextSibling),await n.updateComplete,n.response=Array.isArray(s.correctResponse)?[...s.correctResponse]:s.correctResponse}toggleInternalCorrectResponse(e){let t=this.responseVariable;this.correctResponse=e?t?.correctResponse:t?.cardinality==="single"?"":[]}toggleCandidateCorrection(e){this.responseVariable&&(this._internals.states.delete("candidate-correct"),this._internals.states.delete("candidate-partially-correct"),this._internals.states.delete("candidate-incorrect"),e&&(this.correctness==="correct"&&this._internals.states.add("candidate-correct"),this.correctness==="partially-correct"&&this._internals.states.add("candidate-partially-correct"),this.correctness==="incorrect"&&this._internals.states.add("candidate-incorrect")))}get value(){return JSON.stringify(this.response)}set value(e){this.response=e?JSON.parse(e):null}reportValidity(){return this._internals.reportValidity()}reset(){this.response=null}connectedCallback(){super.connectedCallback(),!this.isFullCorrectResponse&&this.dispatchEvent(new CustomEvent("qti-register-interaction",{bubbles:!0,composed:!0,cancelable:!1,detail:{interactionElement:this,responseIdentifier:this.responseIdentifier}}))}saveResponse(e){this.dispatchEvent(new CustomEvent("qti-interaction-response",{bubbles:!0,composed:!0,cancelable:!1,detail:{responseIdentifier:this.responseIdentifier,response:Array.isArray(e)?[...e]:e}}))}};c([_({context:$,subscribe:!0})],k.prototype,"_context",2),c([_({context:ne,subscribe:!0})],k.prototype,"configContext",2),c([u({type:String,attribute:"response-identifier"})],k.prototype,"responseIdentifier",2),c([u({reflect:!0,type:Boolean})],k.prototype,"disabled",2),c([u({reflect:!0,type:Boolean})],k.prototype,"readonly",2),c([E()],k.prototype,"_isFullCorrectResponse",2),c([E()],k.prototype,"_correctResponse",2);var ut=class extends oe(k,"qti-simple-associable-choice",".dl","slot[name='qti-simple-associable-choice']"){constructor(){super();this._childrenMap=[];this._registerChoiceHandler=this._registerChoice.bind(this),this.addEventListener("register-qti-simple-associable-choice",this._registerChoiceHandler)}_registerChoice(e){let t=e.target;this._childrenMap.push(t)}render(){return h` <slot name="prompt"></slot>
129
+ `;var ne=Symbol("configContext");var k=class extends v{constructor(){super();this.disabled=!1;this.readonly=!1;this._internals=this.attachInternals()}static{this.formAssociated=!0}get internals(){return this._internals}get isFullCorrectResponse(){return this._isFullCorrectResponse}set isFullCorrectResponse(e){this._isFullCorrectResponse=e,e&&(this.disabled=!0,this.setAttribute("response-identifier",this.responseIdentifier+"_cr"))}get correctResponse(){return this._correctResponse}set correctResponse(e){this._correctResponse=e}get correctness(){let e=this.responseVariable;return!e||e.correctResponse===null?null:e.correctResponse===e.value?"correct":"incorrect"}get isInline(){return!1}get responseVariable(){let e=this._context.variables.filter(i=>i.type==="response"),t=this.getAttribute("response-identifier");return e.find(i=>i.identifier===t)}toggleCorrectResponse(e){(this?.configContext?.correctResponseMode||"internal")==="full"?this.toggleFullCorrectResponse(e):this.toggleInternalCorrectResponse(e)}async toggleFullCorrectResponse(e){let t=this.nextSibling,i=t instanceof HTMLDivElement&&t?.classList.contains("full-correct-response"),s=this.responseVariable;if(!s)return;if(!(e&&(this?.configContext?.fullCorrectResponseOnlyWhenIncorrect===!1||this.correctness!=="correct"))){if(!i)return;this.parentElement?.removeChild(t)}if(i)return;let a=this.cloneNode(!0),l=document.createElement("div");l.classList.add("full-correct-response"),this.isInline?l.classList.add("full-correct-response-inline"):l.classList.add("full-correct-response-block"),l.role="full-correct-response",l.appendChild(a),a.isFullCorrectResponse=!0,this.parentElement?.insertBefore(l,this.nextSibling),await a.updateComplete,a.response=Array.isArray(s.correctResponse)?[...s.correctResponse]:s.correctResponse}toggleInternalCorrectResponse(e){let t=this.responseVariable;this.correctResponse=e?t?.correctResponse:t?.cardinality==="single"?"":[]}toggleCandidateCorrection(e){this.responseVariable&&(this._internals.states.delete("candidate-correct"),this._internals.states.delete("candidate-partially-correct"),this._internals.states.delete("candidate-incorrect"),e&&(this.correctness==="correct"&&this._internals.states.add("candidate-correct"),this.correctness==="partially-correct"&&this._internals.states.add("candidate-partially-correct"),this.correctness==="incorrect"&&this._internals.states.add("candidate-incorrect")))}get value(){return JSON.stringify(this.response)}set value(e){this.response=e?JSON.parse(e):null}reportValidity(){return this._internals.reportValidity()}reset(){this.response=null}connectedCallback(){super.connectedCallback(),!this.isFullCorrectResponse&&this.dispatchEvent(new CustomEvent("qti-register-interaction",{bubbles:!0,composed:!0,cancelable:!1,detail:{interactionElement:this,responseIdentifier:this.responseIdentifier}}))}saveResponse(e){this.dispatchEvent(new CustomEvent("qti-interaction-response",{bubbles:!0,composed:!0,cancelable:!1,detail:{responseIdentifier:this.responseIdentifier,response:Array.isArray(e)?[...e]:e}}))}};c([_({context:$,subscribe:!0})],k.prototype,"_context",2),c([_({context:ne,subscribe:!0})],k.prototype,"configContext",2),c([u({type:String,attribute:"response-identifier"})],k.prototype,"responseIdentifier",2),c([u({reflect:!0,type:Boolean})],k.prototype,"disabled",2),c([u({reflect:!0,type:Boolean})],k.prototype,"readonly",2),c([E()],k.prototype,"_isFullCorrectResponse",2),c([E()],k.prototype,"_correctResponse",2);var ut=class extends oe(k,"qti-simple-associable-choice",".dl","slot[name='qti-simple-associable-choice']"){constructor(){super();this._childrenMap=[];this._registerChoiceHandler=this._registerChoice.bind(this),this.addEventListener("register-qti-simple-associable-choice",this._registerChoiceHandler)}_registerChoice(e){let t=e.target;this._childrenMap.push(t)}render(){return h` <slot name="prompt"></slot>
130
130
  <slot name="qti-simple-associable-choice"></slot>
131
131
  <div part="drop-container">
132
132
  ${this._childrenMap.length>0&&Array.from(Array(Math.ceil(this._childrenMap.length/2)).keys()).map((e,t)=>h`<div part="associables-container">
@@ -1382,7 +1382,7 @@ Make sure to test your application with a production build as repeat registratio
1382
1382
  bottom: 0;
1383
1383
  }
1384
1384
  }
1385
- `;var J=class extends k{constructor(){super(...arguments);this.inputRef=Ao();this.response=null;this._handleValueChange=()=>{this._internals.setFormValue(this.value),this.validate()}}get value(){return this.response||null}set value(e){this.response=e||null}get correctness(){let e=this.responseVariable;if(!e||e.value===null)return null;if(e.mapping){let t=e.mapping.mapEntries.reduce((i,s)=>Math.max(s.mappedValue,i),0);for(let i of e.mapping.mapEntries){let s=i.mapKey,n=e.value;if(i.caseSensitive||(s=s.toLowerCase(),n=n.toLowerCase()),s===n)return i.mappedValue===t?"correct":i.mappedValue<=(e.mapping.defaultValue||0)?"incorrect":"partially-correct"}}return e.correctResponse===e.value?"correct":"incorrect"}get isInline(){return!0}validate(){if(!this._input)return!1;if(this.patternMask&&this.dataPatternmaskMessage)this._internals.setValidity({}),this._input.setCustomValidity(""),this._input.checkValidity()||(this._internals.setValidity({customError:!0},this.dataPatternmaskMessage),this._input.setCustomValidity(this.dataPatternmaskMessage));else{let e=this._input.checkValidity();this._internals.setValidity(e?{}:{customError:!1})}return this.response!==""&&this._input.checkValidity()}toggleInternalCorrectResponse(e){let t=this.responseVariable;if(e&&t?.correctResponse){let i=t.correctResponse.toString();this._correctResponse=i}else this._correctResponse=null}render(){return h`
1385
+ `;var J=class extends k{constructor(){super(...arguments);this.inputRef=Ao();this.response=null;this._handleValueChange=()=>{this._internals.setFormValue(this.value),this.validate()}}get value(){return this.response||null}set value(e){this.response=e||null}get correctness(){let e=this.responseVariable;if(!e)return null;if(e.value===null)return"incorrect";if(e.mapping){let t=e.mapping.mapEntries.reduce((i,s)=>Math.max(s.mappedValue,i),0);for(let i of e.mapping.mapEntries){let s=i.mapKey,n=e.value;if(i.caseSensitive||(s=s.toLowerCase(),n=n.toLowerCase()),s===n)return i.mappedValue===t?"correct":i.mappedValue<=(e.mapping.defaultValue||0)?"incorrect":"partially-correct"}}return e.correctResponse===e.value?"correct":"incorrect"}get isInline(){return!0}validate(){if(!this._input)return!1;if(this.patternMask&&this.dataPatternmaskMessage)this._internals.setValidity({}),this._input.setCustomValidity(""),this._input.checkValidity()||(this._internals.setValidity({customError:!0},this.dataPatternmaskMessage),this._input.setCustomValidity(this.dataPatternmaskMessage));else{let e=this._input.checkValidity();this._internals.setValidity(e?{}:{customError:!1})}return this.response!==""&&this._input.checkValidity()}toggleInternalCorrectResponse(e){let t=this.responseVariable;if(e&&t?.correctResponse){let i=t.correctResponse.toString();this._correctResponse=i}else this._correctResponse=null}render(){return h`
1386
1386
  <input
1387
1387
  part="input"
1388
1388
  name="${this.responseIdentifier}"
@@ -1493,7 +1493,7 @@ Make sure to test your application with a production build as repeat registratio
1493
1493
  :host {
1494
1494
  display: none;
1495
1495
  }
1496
- `],c([u({type:String,attribute:"base-type"})],we.prototype,"baseType",2),c([u({type:String})],we.prototype,"identifier",2),c([u({type:String})],we.prototype,"cardinality",2),c([_({context:$,subscribe:!0}),E()],we.prototype,"itemContext",2),we=c([g("qti-response-declaration")],we);var Lo=(s=>(s.ITEM_NOT_FOUND="item-not-found",s.SECTION_NOT_FOUND="section-not-found",s.LOAD_ERROR="load-error",s.NETWORK_ERROR="network-error",s.TIMEOUT_ERROR="timeout-error",s))(Lo||{}),$o=o=>{class r extends o{constructor(...i){super(...i);this.navigate=null;this.cacheTransform=!1;this.requestTimeout=3e4;this.showLoadingIndicators=!0;this.postLoadTransformCallback=null;this._navigationInProgress=!1;this._activeRequests=[];this._lastError=null;this._lastNavigationRequestId=null;this._targetNavigation=null;this.addEventListener("qti-request-navigation",async({detail:s})=>{if(!s?.id)return;let n=`nav_${Date.now()}_${Math.random()}`;this._lastNavigationRequestId=n;try{if(this._navigationInProgress=!0,this._lastError=null,this._dispatchStatusEvent({loading:!0,type:s.type,id:s.id}),this._cancelActiveRequests(),this._targetNavigation={type:s.type,id:s.id},s.type==="item"?await this._navigateToItem(s.id):s.type==="section"&&await this._navigateToSection(s.id),this._lastNavigationRequestId!==n){console.log("Navigation was superseded by a newer request");return}}catch(a){if(this._lastNavigationRequestId===n){let l=this._normalizeError(a,s.type,s.id);this._lastError=l,this._dispatchErrorEvent(l),console.error(`Navigation error (${l.type}):`,l.message,l.details)}}finally{this._lastNavigationRequestId===n&&(this._navigationInProgress=!1,this._dispatchStatusEvent({loading:!1,type:s.type,id:s.id}))}}),this.addEventListener("qti-assessment-test-connected",s=>{this._testElement=s.detail,this._initializeNavigation()})}_initializeNavigation(){let i;this.navigate==="section"&&(i=this._testElement.querySelector("qti-assessment-section")?.identifier),this.navigate==="item"&&(i=this.sessionContext.navItemRefId??this._testElement.querySelector("qti-assessment-item-ref")?.identifier),i&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:this.navigate==="section"?"section":"item",id:i},bubbles:!0,composed:!0}))}navigateTo(i,s){s||(i==="section"&&(s=this._testElement?.querySelector("qti-assessment-section")?.identifier),i==="item"&&(s=this._testElement?.querySelector("qti-assessment-item-ref")?.identifier)),this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:i,id:s},bubbles:!0,composed:!0}))}async _navigateToItem(i){let s=this._testElement?.querySelector(`qti-assessment-item-ref[identifier="${i}"]`);if(!s)throw{type:"item-not-found",message:`Item with identifier "${i}" not found.`,itemId:i};let n=s.closest("qti-test-part")?.identifier,a=s.closest("qti-assessment-section")?.identifier;this.sessionContext={...this.sessionContext,navPartId:n,navSectionId:a,navItemRefId:i,navItemLoading:!0};try{await this._loadItems([i])}finally{this.sessionContext={...this.sessionContext,navItemLoading:!1}}}async _navigateToSection(i){let s=this._testElement?.querySelector(`qti-assessment-section[identifier="${i}"]`);if(!s)throw{type:"section-not-found",message:`Section with identifier "${i}" not found.`,sectionId:i};let n=s.closest("qti-test-part")?.identifier;this.sessionContext={...this.sessionContext,navPartId:n,navSectionId:i,navItemRefId:null,navItemLoading:!0};try{let a=this._getSectionItemIds(i);await this._loadItems(a)}finally{this.sessionContext={...this.sessionContext,navItemLoading:!1}}}_normalizeError(i,s,n){return i&&i.type&&Object.values(Lo).includes(i.type)?i:i instanceof DOMException&&i.name==="AbortError"?{type:"network-error",message:"Navigation was cancelled because a new navigation was requested.",details:i}:i.name==="TimeoutError"||i.message&&i.message.includes("timeout")?{type:"timeout-error",message:"Request timed out. Please check your network connection.",details:i}:i instanceof TypeError&&i.message.includes("network")?{type:"network-error",message:"A network error occurred. Please check your connection.",details:i}:{type:"load-error",message:`Failed to load ${s}: ${n}`,details:i,itemId:s==="item"?n:void 0,sectionId:s==="section"?n:void 0}}_dispatchErrorEvent(i){this.dispatchEvent(new CustomEvent("qti-navigation-error",{detail:i,bubbles:!0,composed:!0}))}_dispatchStatusEvent(i){this.showLoadingIndicators&&this.dispatchEvent(new CustomEvent("qti-navigation-status",{detail:i,bubbles:!0,composed:!0}))}_cancelActiveRequests(){this._activeRequests.length>0&&(console.info(`Cancelling ${this._activeRequests.length} pending requests`),this._activeRequests.forEach(i=>{i&&i.readyState!==4&&i.abort()}),this._activeRequests=[])}async _loadItems(i){if(!this._testElement||i.length===0)return;let s=i.map(l=>this._testElement.querySelector(`qti-assessment-item-ref[identifier="${l}"]`)),n=s.reduce((l,d,p)=>(d||l.push(i[p]),l),[]);if(n.length>0)throw{type:"item-not-found",message:`One or more items not found: ${n.join(", ")}`,details:{missingItems:n}};this._clearLoadedItems();let a=s.map(async l=>{if(!l)return null;let d=new Promise((p,m)=>{setTimeout(()=>{m({name:"TimeoutError",message:`Request for item ${l.identifier} timed out after ${this.requestTimeout}ms`})},this.requestTimeout)});try{let{promise:p,request:m}=Je(this.cacheTransform).load(l.href);m instanceof XMLHttpRequest&&this._activeRequests.push(m);let f=await Promise.race([p,d]),b=f;return this.postLoadTransformCallback&&(b=await this.postLoadTransformCallback(f,l)),{itemRef:l,doc:b.htmlDoc(),request:m}}catch(p){if(p instanceof DOMException&&p.name==="AbortError"||p&&p.name==="TimeoutError")return console.log(`Request for item ${l.identifier} was ${p.name==="TimeoutError"?"timed out":"aborted"}`),null;throw p.itemId=l.identifier,p}});try{let d=(await Promise.all(a)).filter(p=>p!==null);if(d.forEach(({itemRef:p,doc:m})=>{p&&m&&(p.xmlDoc=m)}),this._activeRequests=[],requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent("qti-test-loaded",{detail:d.map(({itemRef:p})=>({identifier:p?.identifier,element:p})),bubbles:!0,composed:!0}))}),d.length===0&&i.length>0)throw{type:"load-error",message:"All item requests failed to load",details:{itemIds:i}};return d}catch(l){throw console.error("Error loading items:",l),l}}_getSectionItemIds(i){if(!this._testElement?.querySelector(`qti-assessment-section[identifier="${i}"]`))throw{type:"section-not-found",message:`Section with identifier "${i}" not found.`,sectionId:i};return Array.from(this._testElement.querySelectorAll(`qti-assessment-section[identifier="${i}"] > qti-assessment-item-ref`)).map(n=>n.identifier)}_clearLoadedItems(){let i=this._testElement?.querySelectorAll("qti-assessment-test qti-assessment-item-ref");Array.from(i||[]).forEach(s=>{s.xmlDoc=null})}retryNavigation(){if(this._lastError){let i=this._lastError.itemId?"item":"section",s=this._lastError.itemId||this._lastError.sectionId;s&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:i,id:s},bubbles:!0,composed:!0}))}else this._targetNavigation&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:this._targetNavigation,bubbles:!0,composed:!0}))}}return c([u({type:String})],r.prototype,"navigate",2),c([u({type:Boolean,attribute:"cache-transform"})],r.prototype,"cacheTransform",2),c([u({type:Number})],r.prototype,"requestTimeout",2),c([u({type:Boolean})],r.prototype,"showLoadingIndicators",2),c([u({type:Function})],r.prototype,"postLoadTransformCallback",2),r};var Oo=o=>{class r extends o{constructor(...t){super(...t),this.sessionContext={...this.sessionContext,view:"candidate"},this.addEventListener("on-test-switch-view",i=>{this.sessionContext={...this.sessionContext,view:i.detail},this._updateElementView()}),this.addEventListener("qti-assessment-test-connected",()=>{this._updateElementView()}),this.addEventListener("qti-assessment-item-connected",i=>{this._updateElementView(),this._setCorrectResponseVisibility(i.detail)})}willUpdate(t){super.willUpdate(t),t.has("sessionContext")&&this._updateElementView()}_updateElementView(){if(this._testElement){Array.from(this._testElement.querySelectorAll("[view]")).forEach(n=>{n.classList.toggle("show",n.getAttribute("view")===this.sessionContext.view)});let s=this._testElement.querySelector(`qti-assessment-item-ref[identifier="${this.sessionContext.navItemRefId}"]`)?.assessmentItem;s&&s.showCorrectResponse(this.sessionContext.view==="scorer")}}_setCorrectResponseVisibility(t){t.showCorrectResponse(this.sessionContext.view==="scorer")}}return r};var ys={view:"candidate"},He=Symbol("testContext");var Ct=class extends v{constructor(){super();this.testContext=Ji;this.sessionContext=ys;this._updateItemInTestContext=e=>{let t=e._context,i=t.identifier,s=t.variables,n=this.testContext.items.find(a=>a?.identifier===i);if(!n){console.warn(`Item IDs between assessment.xml and item.xml should match: ${i} is not found!`);return}n.variables?.length===1?this._updateItemVariablesInTestContext(i,s):e.variables=[...n.variables||[]]};this.addEventListener("qti-assessment-test-connected",e=>{if(this.testContext=Ji,this.sessionContext=ys,this.testContext&&this.testContext.items.length>0)return;this._testElement=e.detail;let t=Array.from(this._testElement.querySelectorAll("qti-assessment-item-ref")).map(i=>({href:i.href,identifier:i.identifier,category:i.category,variables:[{identifier:"completionStatus",value:"not_attempted",type:"outcome"}]}));this.testContext={...this.testContext,items:t}}),this.addEventListener("qti-assessment-item-connected",e=>{let t=e.detail,i=t.closest("qti-assessment-item-ref")?.identifier;i&&(t.assessmentItemRefId=i),this._updateItemInTestContext(e.detail)}),this.addEventListener("qti-item-context-updated",e=>{this._updateItemVariablesInTestContext(e.detail.itemContext.identifier,e.detail.itemContext.variables)})}updateItemVariables(e,t){let i=this.testContext.items.find(n=>n.identifier===e);i&&(i.variables=i.variables.map(n=>{let a=t.find(l=>l.identifier===n.identifier);return a?{...n,...a}:n}));let s=this._testElement.querySelector(`qti-assessment-item-ref[identifier="${e}"]`);s&&s.assessmentItem&&s.assessmentItem&&(s.assessmentItem.variables=t)}_updateItemVariablesInTestContext(e,t){this.testContext={...this.testContext,items:this.testContext.items.map(i=>i.identifier!==e?i:{...i,variables:t.map(s=>{let n=i.variables.find(a=>a.identifier===s.identifier);return n?{...n,...s}:s})})},this.dispatchEvent(new CustomEvent("qti-test-context-updated",{detail:this.testContext,bubbles:!1,composed:!1}))}};c([u({attribute:!1,type:Object}),X({context:ue})],Ct.prototype,"testContext",2),c([u({attribute:!1,type:Object}),X({context:He})],Ct.prototype,"sessionContext",2);var Po=o=>{class r extends o{constructor(...t){super(...t),this.addEventListener("qti-register-variable",i=>{this.testContext={...this.testContext,testOutcomeVariables:[...this.testContext.testOutcomeVariables||[],i.detail.variable]},i.stopPropagation()}),this.addEventListener("qti-set-outcome-value",i=>{let{outcomeIdentifier:s,value:n}=i.detail;this.updateOutcomeVariable(s,n),i.stopPropagation()})}outcomeProcessing(){let t=this.querySelector("qti-outcome-processing");return t?(t?.process(),!0):!1}updateOutcomeVariable(t,i){let s=this.getOutcome(t);if(!s){console.warn(`Can not set qti-outcome-identifier: ${t}, it is not available`);return}this.testContext={...this.testContext,testOutcomeVariables:this.testContext.testOutcomeVariables?.map(n=>n.identifier!==t?n:{...n,value:s.cardinality==="single"?i:[...n.value,i]})}}getOutcome(t){return this.getVariable(t)}getVariable(t){return this.testContext.testOutcomeVariables?.find(i=>i.identifier===t)||null}}return r};var ai=class extends $o(Oo(Po(Ct))){async connectedCallback(){super.connectedCallback(),await this.updateComplete,this.dispatchEvent(new CustomEvent("qti-test-connected",{detail:this}))}render(){return h`<slot></slot>`}};ai=c([g("qti-test")],ai);var li=["this"],No=["+","-","!"],Vo=["=","+","-","*","/","%","^","==","!=",">","<",">=","<=","||","&&","??","&","===","!==","|","|>"],xs={"!":0,":":0,",":0,")":0,"]":0,"}":0,"|>":1,"?":2,"??":3,"||":4,"&&":5,"|":6,"^":7,"&":8,"!=":9,"==":9,"!==":9,"===":9,">=":10,">":10,"<=":10,"<":10,"+":11,"-":11,"%":12,"/":12,"*":12,"(":13,"[":13,".":13,"{":13},ci=13;var Ln=["==","!=","<=",">=","||","&&","??","|>"],$n=["===","!=="],A;(function(o){o[o.STRING=1]="STRING",o[o.IDENTIFIER=2]="IDENTIFIER",o[o.DOT=3]="DOT",o[o.COMMA=4]="COMMA",o[o.COLON=5]="COLON",o[o.INTEGER=6]="INTEGER",o[o.DECIMAL=7]="DECIMAL",o[o.OPERATOR=8]="OPERATOR",o[o.GROUPER=9]="GROUPER",o[o.KEYWORD=10]="KEYWORD",o[o.ARROW=11]="ARROW"})(A||(A={}));var fe=(o,r,e=0)=>({kind:o,value:r,precedence:e}),On=o=>o===9||o===10||o===13||o===32,Do=o=>o===95||o===36||(o&=-33,65<=o&&o<=90),Pn=o=>Do(o)||vr(o),Nn=o=>li.indexOf(o)!==-1,Vn=o=>o===34||o===39,vr=o=>48<=o&&o<=57,Dn=o=>o===43||o===45||o===42||o===47||o===33||o===38||o===37||o===60||o===61||o===62||o===63||o===94||o===124,Hn=o=>o===40||o===41||o===91||o===93||o===123||o===125,zn=o=>o.replace(/\\(.)/g,(r,e)=>{switch(e){case"n":return`
1496
+ `],c([u({type:String,attribute:"base-type"})],we.prototype,"baseType",2),c([u({type:String})],we.prototype,"identifier",2),c([u({type:String})],we.prototype,"cardinality",2),c([_({context:$,subscribe:!0}),E()],we.prototype,"itemContext",2),we=c([g("qti-response-declaration")],we);var Lo=(s=>(s.ITEM_NOT_FOUND="item-not-found",s.SECTION_NOT_FOUND="section-not-found",s.LOAD_ERROR="load-error",s.NETWORK_ERROR="network-error",s.TIMEOUT_ERROR="timeout-error",s))(Lo||{}),$o=o=>{class r extends o{constructor(...i){super(...i);this.navigate=null;this.cacheTransform=!1;this.requestTimeout=3e4;this.showLoadingIndicators=!0;this.postLoadTransformCallback=null;this._navigationInProgress=!1;this._activeRequests=[];this._lastError=null;this._lastNavigationRequestId=null;this._targetNavigation=null;this.addEventListener("qti-request-navigation",async({detail:s})=>{if(!s?.id)return;let n=`nav_${Date.now()}_${Math.random()}`;this._lastNavigationRequestId=n;try{if(this._navigationInProgress=!0,this._lastError=null,this._dispatchStatusEvent({loading:!0,type:s.type,id:s.id}),this._cancelActiveRequests(),this._targetNavigation={type:s.type,id:s.id},s.type==="item"?await this._navigateToItem(s.id):s.type==="section"&&await this._navigateToSection(s.id),this._lastNavigationRequestId!==n){console.log("Navigation was superseded by a newer request");return}}catch(a){if(this._lastNavigationRequestId===n){let l=this._normalizeError(a,s.type,s.id);this._lastError=l,this._dispatchErrorEvent(l),console.error(`Navigation error (${l.type}):`,l.message,l.details)}}finally{this._lastNavigationRequestId===n&&(this._navigationInProgress=!1,this._dispatchStatusEvent({loading:!1,type:s.type,id:s.id}))}}),this.addEventListener("qti-assessment-test-connected",s=>{this._testElement=s.detail,this._initializeNavigation()})}_initializeNavigation(){let i;this.navigate==="section"&&(i=this._testElement.querySelector("qti-assessment-section")?.identifier),this.navigate==="item"&&(i=this.sessionContext.navItemRefId??this._testElement.querySelector("qti-assessment-item-ref")?.identifier),i&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:this.navigate==="section"?"section":"item",id:i},bubbles:!0,composed:!0}))}navigateTo(i,s){s||(i==="section"&&(s=this._testElement?.querySelector("qti-assessment-section")?.identifier),i==="item"&&(s=this._testElement?.querySelector("qti-assessment-item-ref")?.identifier)),this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:i,id:s},bubbles:!0,composed:!0}))}async _navigateToItem(i){let s=this._testElement?.querySelector(`qti-assessment-item-ref[identifier="${i}"]`);if(!s)throw{type:"item-not-found",message:`Item with identifier "${i}" not found.`,itemId:i};let n=s.closest("qti-test-part")?.identifier,a=s.closest("qti-assessment-section")?.identifier;this.sessionContext={...this.sessionContext,navPartId:n,navSectionId:a,navItemRefId:i,navItemLoading:!0};try{await this._loadItems([i])}finally{this.sessionContext={...this.sessionContext,navItemLoading:!1}}}async _navigateToSection(i){let s=this._testElement?.querySelector(`qti-assessment-section[identifier="${i}"]`);if(!s)throw{type:"section-not-found",message:`Section with identifier "${i}" not found.`,sectionId:i};let n=s.closest("qti-test-part")?.identifier;this.sessionContext={...this.sessionContext,navPartId:n,navSectionId:i,navItemRefId:null,navItemLoading:!0};try{let a=this._getSectionItemIds(i);await this._loadItems(a)}finally{this.sessionContext={...this.sessionContext,navItemLoading:!1}}}_normalizeError(i,s,n){return i&&i.type&&Object.values(Lo).includes(i.type)?i:i instanceof DOMException&&i.name==="AbortError"?{type:"network-error",message:"Navigation was cancelled because a new navigation was requested.",details:i}:i.name==="TimeoutError"||i.message&&i.message.includes("timeout")?{type:"timeout-error",message:"Request timed out. Please check your network connection.",details:i}:i instanceof TypeError&&i.message.includes("network")?{type:"network-error",message:"A network error occurred. Please check your connection.",details:i}:{type:"load-error",message:`Failed to load ${s}: ${n}`,details:i,itemId:s==="item"?n:void 0,sectionId:s==="section"?n:void 0}}_dispatchErrorEvent(i){this.dispatchEvent(new CustomEvent("qti-navigation-error",{detail:i,bubbles:!0,composed:!0}))}_dispatchStatusEvent(i){this.showLoadingIndicators&&this.dispatchEvent(new CustomEvent("qti-navigation-status",{detail:i,bubbles:!0,composed:!0}))}_cancelActiveRequests(){this._activeRequests.length>0&&(console.info(`Cancelling ${this._activeRequests.length} pending requests`),this._activeRequests.forEach(i=>{i&&i.readyState!==4&&i.abort()}),this._activeRequests=[])}async _loadItems(i){if(!this._testElement||i.length===0)return;let s=i.map(l=>this._testElement.querySelector(`qti-assessment-item-ref[identifier="${l}"]`)),n=s.reduce((l,d,p)=>(d||l.push(i[p]),l),[]);if(n.length>0)throw{type:"item-not-found",message:`One or more items not found: ${n.join(", ")}`,details:{missingItems:n}};this._clearLoadedItems();let a=s.map(async l=>{if(!l)return null;let d=new Promise((p,m)=>{setTimeout(()=>{m({name:"TimeoutError",message:`Request for item ${l.identifier} timed out after ${this.requestTimeout}ms`})},this.requestTimeout)});try{let{promise:p,request:m}=Je(this.cacheTransform).load(l.href);m instanceof XMLHttpRequest&&this._activeRequests.push(m);let f=await Promise.race([p,d]),b=f;return this.postLoadTransformCallback&&(b=await this.postLoadTransformCallback(f,l)),{itemRef:l,doc:b.htmlDoc(),request:m}}catch(p){if(p instanceof DOMException&&p.name==="AbortError"||p&&p.name==="TimeoutError")return console.log(`Request for item ${l.identifier} was ${p.name==="TimeoutError"?"timed out":"aborted"}`),null;throw p.itemId=l.identifier,p}});try{let d=(await Promise.all(a)).filter(p=>p!==null);if(d.forEach(({itemRef:p,doc:m})=>{p&&m&&(p.xmlDoc=m)}),this._activeRequests=[],requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent("qti-test-loaded",{detail:d.map(({itemRef:p})=>({identifier:p?.identifier,element:p})),bubbles:!0,composed:!0}))}),d.length===0&&i.length>0)throw{type:"load-error",message:"All item requests failed to load",details:{itemIds:i}};return d}catch(l){throw console.error("Error loading items:",l),l}}_getSectionItemIds(i){if(!this._testElement?.querySelector(`qti-assessment-section[identifier="${i}"]`))throw{type:"section-not-found",message:`Section with identifier "${i}" not found.`,sectionId:i};return Array.from(this._testElement.querySelectorAll(`qti-assessment-section[identifier="${i}"] > qti-assessment-item-ref`)).map(n=>n.identifier)}_clearLoadedItems(){let i=this._testElement?.querySelectorAll("qti-assessment-test qti-assessment-item-ref");Array.from(i||[]).forEach(s=>{s.xmlDoc=null})}retryNavigation(){if(this._lastError){let i=this._lastError.itemId?"item":"section",s=this._lastError.itemId||this._lastError.sectionId;s&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:{type:i,id:s},bubbles:!0,composed:!0}))}else this._targetNavigation&&this.dispatchEvent(new CustomEvent("qti-request-navigation",{detail:this._targetNavigation,bubbles:!0,composed:!0}))}}return c([u({type:String})],r.prototype,"navigate",2),c([u({type:Boolean,attribute:"cache-transform"})],r.prototype,"cacheTransform",2),c([u({type:Number})],r.prototype,"requestTimeout",2),c([u({type:Boolean})],r.prototype,"showLoadingIndicators",2),c([u({type:Function})],r.prototype,"postLoadTransformCallback",2),r};var Oo=o=>{class r extends o{constructor(...t){super(...t),this.sessionContext={...this.sessionContext,view:"candidate"},this.addEventListener("on-test-switch-view",i=>{this.sessionContext={...this.sessionContext,view:i.detail},this._updateElementView()}),this.addEventListener("qti-assessment-test-connected",()=>{this._updateElementView()}),this.addEventListener("qti-assessment-item-connected",i=>{this._updateElementView(),this._setCorrectResponseVisibility(i.detail)})}willUpdate(t){super.willUpdate(t),t.has("sessionContext")&&this._updateElementView()}_updateElementView(){if(this._testElement){Array.from(this._testElement.querySelectorAll("[view]")).forEach(n=>{n.classList.toggle("show",n.getAttribute("view")===this.sessionContext.view)});let s=this._testElement.querySelector(`qti-assessment-item-ref[identifier="${this.sessionContext.navItemRefId}"]`)?.assessmentItem;s&&s.showCorrectResponse(this.sessionContext.view==="scorer")}}_setCorrectResponseVisibility(t){t.showCorrectResponse(this.sessionContext.view==="scorer")}}return r};var ys={view:"candidate"},He=Symbol("testContext");var Ct=class extends v{constructor(){super();this.testContext=Ji;this.sessionContext=ys;this._updateItemInTestContext=e=>{let t=e._context,i=t.identifier,s=t.variables,n=this.testContext.items.find(a=>a?.identifier===i);if(!n){console.warn(`Item IDs between assessment.xml and item.xml should match: ${i} is not found!`);return}if(n.variables?.length===1)this._updateItemVariablesInTestContext(i,s);else{let a=[...e.variables];for(let l of n.variables){let d=a.find(p=>p.identifier===l.identifier);d?d.value=l.value:a.push(l)}e.variables=a}};this.addEventListener("qti-assessment-test-connected",e=>{if(this.testContext=Ji,this.sessionContext=ys,this.testContext&&this.testContext.items.length>0)return;this._testElement=e.detail;let t=Array.from(this._testElement.querySelectorAll("qti-assessment-item-ref")).map(i=>({href:i.href,identifier:i.identifier,category:i.category,variables:[{identifier:"completionStatus",value:"not_attempted",type:"outcome"}]}));this.testContext={...this.testContext,items:t}}),this.addEventListener("qti-assessment-item-connected",e=>{let t=e.detail,i=t.closest("qti-assessment-item-ref")?.identifier;i&&(t.assessmentItemRefId=i),this._updateItemInTestContext(e.detail)}),this.addEventListener("qti-item-context-updated",e=>{this._updateItemVariablesInTestContext(e.detail.itemContext.identifier,e.detail.itemContext.variables)})}updateItemVariables(e,t){let i=this.testContext.items.find(n=>n.identifier===e);i&&(i.variables=i.variables.map(n=>{let a=t.find(l=>l.identifier===n.identifier);return a?{...n,...a}:n}));let s=this._testElement.querySelector(`qti-assessment-item-ref[identifier="${e}"]`);s&&s.assessmentItem&&(s.assessmentItem.variables=t)}_updateItemVariablesInTestContext(e,t){this.testContext={...this.testContext,items:this.testContext.items.map(i=>i.identifier!==e?i:{...i,variables:t.map(s=>{let n=i.variables.find(a=>a.identifier===s.identifier);return n?{...n,...s}:s})})},this.dispatchEvent(new CustomEvent("qti-test-context-updated",{detail:this.testContext,bubbles:!1,composed:!1}))}};c([u({attribute:!1,type:Object}),X({context:ue})],Ct.prototype,"testContext",2),c([u({attribute:!1,type:Object}),X({context:He})],Ct.prototype,"sessionContext",2);var Po=o=>{class r extends o{constructor(...t){super(...t),this.addEventListener("qti-register-variable",i=>{this.testContext={...this.testContext,testOutcomeVariables:[...this.testContext.testOutcomeVariables||[],i.detail.variable]},i.stopPropagation()}),this.addEventListener("qti-set-outcome-value",i=>{let{outcomeIdentifier:s,value:n}=i.detail;this.updateOutcomeVariable(s,n),i.stopPropagation()})}outcomeProcessing(){let t=this.querySelector("qti-outcome-processing");return t?(t?.process(),!0):!1}updateOutcomeVariable(t,i){let s=this.getOutcome(t);if(!s){console.warn(`Can not set qti-outcome-identifier: ${t}, it is not available`);return}this.testContext={...this.testContext,testOutcomeVariables:this.testContext.testOutcomeVariables?.map(n=>n.identifier!==t?n:{...n,value:s.cardinality==="single"?i:[...n.value,i]})}}getOutcome(t){return this.getVariable(t)}getVariable(t){return this.testContext.testOutcomeVariables?.find(i=>i.identifier===t)||null}}return r};var ai=class extends $o(Oo(Po(Ct))){async connectedCallback(){super.connectedCallback(),await this.updateComplete,this.dispatchEvent(new CustomEvent("qti-test-connected",{detail:this}))}render(){return h`<slot></slot>`}};ai=c([g("qti-test")],ai);var li=["this"],No=["+","-","!"],Vo=["=","+","-","*","/","%","^","==","!=",">","<",">=","<=","||","&&","??","&","===","!==","|","|>"],xs={"!":0,":":0,",":0,")":0,"]":0,"}":0,"|>":1,"?":2,"??":3,"||":4,"&&":5,"|":6,"^":7,"&":8,"!=":9,"==":9,"!==":9,"===":9,">=":10,">":10,"<=":10,"<":10,"+":11,"-":11,"%":12,"/":12,"*":12,"(":13,"[":13,".":13,"{":13},ci=13;var Ln=["==","!=","<=",">=","||","&&","??","|>"],$n=["===","!=="],A;(function(o){o[o.STRING=1]="STRING",o[o.IDENTIFIER=2]="IDENTIFIER",o[o.DOT=3]="DOT",o[o.COMMA=4]="COMMA",o[o.COLON=5]="COLON",o[o.INTEGER=6]="INTEGER",o[o.DECIMAL=7]="DECIMAL",o[o.OPERATOR=8]="OPERATOR",o[o.GROUPER=9]="GROUPER",o[o.KEYWORD=10]="KEYWORD",o[o.ARROW=11]="ARROW"})(A||(A={}));var fe=(o,r,e=0)=>({kind:o,value:r,precedence:e}),On=o=>o===9||o===10||o===13||o===32,Do=o=>o===95||o===36||(o&=-33,65<=o&&o<=90),Pn=o=>Do(o)||vr(o),Nn=o=>li.indexOf(o)!==-1,Vn=o=>o===34||o===39,vr=o=>48<=o&&o<=57,Dn=o=>o===43||o===45||o===42||o===47||o===33||o===38||o===37||o===60||o===61||o===62||o===63||o===94||o===124,Hn=o=>o===40||o===41||o===91||o===93||o===123||o===125,zn=o=>o.replace(/\\(.)/g,(r,e)=>{switch(e){case"n":return`
1497
1497
  `;case"r":return"\r";case"t":return" ";case"b":return"\b";case"f":return"\f";default:return e}}),di=class{#s;#n=-1;#i=0;#t;constructor(r){this.#s=r,this.#e()}nextToken(){for(;On(this.#t);)this.#e(!0);if(Vn(this.#t))return this.#l();if(Do(this.#t))return this.#d();if(vr(this.#t))return this.#p();if(this.#t===46)return this.#a();if(this.#t===44)return this.#u();if(this.#t===58)return this.#c();if(Dn(this.#t))return this.#h();if(Hn(this.#t))return this.#f();if(this.#e(),this.#t!==void 0)throw new Error(`Expected end of input, got ${this.#t}`)}#e(r){this.#n++,this.#n<this.#s.length?(this.#t=this.#s.charCodeAt(this.#n),r===!0&&(this.#i=this.#n)):this.#t=void 0}#r(r=0){let e=this.#s.substring(this.#i,this.#n+r);return r===0&&this.#o(),e}#o(){this.#i=this.#n}#l(){let r="unterminated string",e=this.#t;for(this.#e(!0);this.#t!==e;){if(this.#t===void 0)throw new Error(r);if(this.#t===92&&(this.#e(),this.#t===void 0))throw new Error(r);this.#e()}let t=fe(A.STRING,zn(this.#r()));return this.#e(),t}#d(){do this.#e();while(Pn(this.#t));let r=this.#r(),e=Nn(r)?A.KEYWORD:A.IDENTIFIER;return fe(e,r)}#p(){do this.#e();while(vr(this.#t));return this.#t===46?this.#a():fe(A.INTEGER,this.#r())}#a(){return this.#e(),vr(this.#t)?this.#m():(this.#o(),fe(A.DOT,".",ci))}#u(){return this.#e(!0),fe(A.COMMA,",")}#c(){return this.#e(!0),fe(A.COLON,":")}#m(){do this.#e();while(vr(this.#t));return fe(A.DECIMAL,this.#r())}#h(){this.#e();let r=this.#r(2);if($n.indexOf(r)!==-1)this.#e(),this.#e();else{if(r=this.#r(1),r==="=>")return this.#e(),fe(A.ARROW,r);Ln.indexOf(r)!==-1&&this.#e()}return r=this.#r(),fe(A.OPERATOR,r,xs[r])}#f(){let r=String.fromCharCode(this.#t),e=fe(A.GROUPER,r,xs[r]);return this.#e(!0),e}};var qs=(o,r)=>new yr(o,r).parse(),yr=class{#s;#n;#i;#t;#e;constructor(r,e){this.#n=new di(r),this.#i=e}parse(){return this.#r(),this.#o()}#r(r,e){if(!this._matches(r,e))throw new Error(`Expected kind ${r} (${e}), was ${this.#t?.kind} (${this.#t?.value})`);let t=this.#n.nextToken();this.#t=t,this.#s=t?.kind,this.#e=t?.value}_matches(r,e){return!(r&&this.#s!==r||e&&this.#e!==e)}#o(){if(!this.#t)return this.#i.empty();let r=this.#a();return r===void 0?void 0:this.#l(r,0)}#l(r,e){if(r===void 0)throw new Error("Expected left to be defined.");for(;this.#t;)if(this._matches(A.GROUPER,"(")){let t=this.#g();r=this.#i.invoke(r,void 0,t)}else if(this._matches(A.GROUPER,"[")){let t=this.#x();r=this.#i.index(r,t)}else if(this._matches(A.DOT)){this.#r();let t=this.#a();r=this.#d(r,t)}else{if(this._matches(A.KEYWORD))break;if(this._matches(A.OPERATOR)&&this.#t.precedence>=e)r=this.#e==="?"?this.#u(r):this.#p(r,this.#t);else break}return r}#d(r,e){if(e===void 0)throw new Error("expected identifier");if(e.type==="ID")return this.#i.getter(r,e.value);if(e.type==="Invoke"&&e.receiver.type==="ID"){let t=e.receiver;return this.#i.invoke(r,t.value,e.arguments)}else throw new Error(`expected identifier: ${e}`)}#p(r,e){if(Vo.indexOf(e.value)===-1)throw new Error(`unknown operator: ${e.value}`);this.#r();let t=this.#a();for(;(this.#s===A.OPERATOR||this.#s===A.DOT||this.#s===A.GROUPER)&&this.#t.precedence>e.precedence;)t=this.#l(t,this.#t.precedence);return this.#i.binary(r,e.value,t)}#a(){if(this._matches(A.OPERATOR)){let r=this.#e;if(this.#r(),r==="+"||r==="-"){if(this._matches(A.INTEGER))return this.#b(r);if(this._matches(A.DECIMAL))return this.#v(r)}if(No.indexOf(r)===-1)throw new Error(`unexpected token: ${r}`);let e=this.#l(this.#c(),ci);return this.#i.unary(r,e)}return this.#c()}#u(r){this.#r(A.OPERATOR,"?");let e=this.#o();this.#r(A.COLON);let t=this.#o();return this.#i.ternary(r,e,t)}#c(){switch(this.#s){case A.KEYWORD:let r=this.#e;if(r==="this")return this.#r(),this.#i.id(r);throw li.indexOf(r)!==-1?new Error(`unexpected keyword: ${r}`):new Error(`unrecognized keyword: ${r}`);case A.IDENTIFIER:return this.#f();case A.STRING:return this.#E();case A.INTEGER:return this.#b();case A.DECIMAL:return this.#v();case A.GROUPER:return this.#e==="("?this.#q():this.#e==="{"?this.#h():this.#e==="["?this.#m():void 0;case A.COLON:throw new Error('unexpected token ":"');default:return}}#m(){let r=[];do{if(this.#r(),this._matches(A.GROUPER,"]"))break;r.push(this.#o())}while(this._matches(A.COMMA));return this.#r(A.GROUPER,"]"),this.#i.list(r)}#h(){let r={};do{if(this.#r(),this._matches(A.GROUPER,"}"))break;let e=this.#e;(this._matches(A.STRING)||this._matches(A.IDENTIFIER))&&this.#r(),this.#r(A.COLON),r[e]=this.#o()}while(this._matches(A.COMMA));return this.#r(A.GROUPER,"}"),this.#i.map(r)}#f(){let r=this.#e;if(r==="true")return this.#r(),this.#i.literal(!0);if(r==="false")return this.#r(),this.#i.literal(!1);if(r==="null")return this.#r(),this.#i.literal(null);if(r==="undefined")return this.#r(),this.#i.literal(void 0);let e=this.#y(),t=this.#g();return t?this.#i.invoke(e,void 0,t):e}#y(){if(!this._matches(A.IDENTIFIER))throw new Error(`expected identifier: ${this.#e}`);let r=this.#e;return this.#r(),this.#i.id(r)}#g(){if(!this._matches(A.GROUPER,"("))return;let r=[];do{if(this.#r(),this._matches(A.GROUPER,")"))break;let e=this.#o();r.push(e)}while(this._matches(A.COMMA));return this.#r(A.GROUPER,")"),r}#x(){this.#r();let r=this.#o();return this.#r(A.GROUPER,"]"),r}#q(){let r=this.#g();if(this._matches(A.ARROW)){this.#r();let e=this.#o(),t=r?.map(i=>i.value)??[];return this.#i.arrowFunction(t,e)}else return this.#i.paren(r[0])}#E(){let r=this.#i.literal(this.#e);return this.#r(),r}#b(r=""){let e=this.#i.literal(parseInt(`${r}${this.#e}`,10));return this.#r(),e}#v(r=""){let e=this.#i.literal(parseFloat(`${r}${this.#e}`));return this.#r(),e}};var{hasOwn:Ho,fromEntries:Fn}=Object,Un={"+":(o,r)=>o+r,"-":(o,r)=>o-r,"*":(o,r)=>o*r,"/":(o,r)=>o/r,"%":(o,r)=>o%r,"==":(o,r)=>o==r,"!=":(o,r)=>o!=r,"===":(o,r)=>o===r,"!==":(o,r)=>o!==r,">":(o,r)=>o>r,">=":(o,r)=>o>=r,"<":(o,r)=>o<r,"<=":(o,r)=>o<=r,"||":(o,r)=>o||r,"&&":(o,r)=>o&&r,"??":(o,r)=>o??r,"|":(o,r)=>r(o),"|>":(o,r)=>r(o)},jn={"+":o=>o,"-":o=>-o,"!":o=>!o},pi=class{empty(){return{type:"Empty",evaluate(r){return r},getIds(r){return r}}}literal(r){return{type:"Literal",value:r,evaluate(e){return this.value},getIds(e){return e}}}id(r){return{type:"ID",value:r,evaluate(e){return this.value==="this"?e:e?.[this.value]},getIds(e){return e.push(this.value),e}}}unary(r,e){let t=jn[r];return{type:"Unary",operator:r,child:e,evaluate(i){return t(this.child.evaluate(i))},getIds(i){return this.child.getIds(i)}}}binary(r,e,t){let i=Un[e];return{type:"Binary",operator:e,left:r,right:t,evaluate(s){if(this.operator==="="){if(this.left.type!=="ID"&&this.left.type!=="Getter"&&this.left.type!=="Index")throw new Error(`Invalid assignment target: ${this.left}`);let n=this.right.evaluate(s),a,l;return this.left.type==="Getter"?(a=this.left.receiver.evaluate(s),l=this.left.name):this.left.type==="Index"?(a=this.left.receiver.evaluate(s),l=this.left.argument.evaluate(s)):this.left.type==="ID"&&(a=s,l=this.left.value),a===void 0?void 0:a[l]=n}return i(this.left.evaluate(s),this.right.evaluate(s))},getIds(s){return this.left.getIds(s),this.right.getIds(s),s}}}getter(r,e){return{type:"Getter",receiver:r,name:e,evaluate(t){return this.receiver.evaluate(t)?.[this.name]},getIds(t){return this.receiver.getIds(t),t}}}invoke(r,e,t){if(e!=null&&typeof e!="string")throw new Error("method not a string");return{type:"Invoke",receiver:r,method:e,arguments:t,evaluate(i){let s=this.receiver.evaluate(i),n=this.method?s:i?.this??i,a=this.method?s?.[e]:s,d=(this.arguments??[]).map(p=>p?.evaluate(i));return a?.apply?.(n,d)},getIds(i){return this.receiver.getIds(i),this.arguments?.forEach(s=>s?.getIds(i)),i}}}paren(r){return r}index(r,e){return{type:"Index",receiver:r,argument:e,evaluate(t){return this.receiver.evaluate(t)?.[this.argument.evaluate(t)]},getIds(t){return this.receiver.getIds(t),t}}}ternary(r,e,t){return{type:"Ternary",condition:r,trueExpr:e,falseExpr:t,evaluate(i){return this.condition.evaluate(i)?this.trueExpr.evaluate(i):this.falseExpr.evaluate(i)},getIds(i){return this.condition.getIds(i),this.trueExpr.getIds(i),this.falseExpr.getIds(i),i}}}map(r){return{type:"Map",entries:r,evaluate(e){let t={};if(r&&this.entries)for(let i in r){let s=this.entries[i];s&&(t[i]=s.evaluate(e))}return t},getIds(e){if(r&&this.entries)for(let t in r){let i=this.entries[t];i&&i.getIds(e)}return e}}}list(r){return{type:"List",items:r,evaluate(e){return this.items?.map(t=>t?.evaluate(e))},getIds(e){return this.items?.forEach(t=>t?.getIds(e)),e}}}arrowFunction(r,e){return{type:"ArrowFunction",params:r,body:e,evaluate(t){let i=this.params,s=this.body;return function(...n){let a=Fn(i.map((d,p)=>[d,n[p]])),l=new Proxy(t??{},{set(d,p,m){return Ho(a,p)&&(a[p]=m),d[p]=m},get(d,p){return Ho(a,p)?a[p]:d[p]}});return s.evaluate(l)}},getIds(t){return this.body.getIds(t).filter(i=>!this.params.includes(i))}}}};var Es=null,zo={boundAttributeSuffix:H.M,marker:H.P,markerMatch:H.A,HTML_RESULT:H.C,getTemplateHtml:H.L,overrideDirectiveResolve:(o,r)=>class extends o{_$AS(e,t){return r(this,t)}},patchDirectiveResolve:(o,r)=>{if(o.prototype._$AS.name!==r.name){Es??=o.prototype._$AS.name;for(let e=o.prototype;e!==Object.prototype;e=Object.getPrototypeOf(e))if(e.hasOwnProperty(Es))return void(e[Es]=r);throw Error("Internal error: It is possible that both dev mode and production mode Lit was mixed together during SSR. Please comment on the issue: https://github.com/lit/lit/issues/4527")}},setDirectiveClass(o,r){o._$litDirective$=r},getAttributePartCommittedValue:(o,r,e)=>{let t=P;return o.j=i=>t=i,o._$AI(r,o,e),t},connectedDisconnectable:o=>({...o,_$AU:!0}),resolveDirective:H.V,AttributePart:H.H,PropertyPart:H.B,BooleanAttributePart:H.N,EventPart:H.U,ElementPart:H.F,TemplateInstance:H.R,isIterable:H.D,ChildPart:H.I};var{AttributePart:Bn,PropertyPart:Wn,BooleanAttributePart:Xn,EventPart:Gn}=zo,ws=new pi,Cs=new Map,Fo=o=>o.replace(/-(-|\w)/g,(r,e)=>e.toUpperCase()),ui=(o,r)=>{let e=Cs.get(o);if(e===void 0){if(Cs.has(o))return;if(o=o.trim(),o.startsWith("{{")&&o.endsWith("}}")){let t=o.substring(2,o.length-2).trim();e=new yr(t,ws).parse(),Cs.set(o,e)}}return e?.evaluate(r)},Yn=(o,r,e,t)=>{let i=o.getAttribute("if");if(i!==null&&ui(i,r))return mi(o,r,e,t)},Uo=/(?<!\\){{(.*?)(?:(?<!\\)}})/g,jo=o=>/(?:\\{{)|(?:\\}})/g.test(o),xr=o=>o.replaceAll(/\\{{/g,"{{").replace(/\\}}/g,"}}"),Jn=(o,r,e,t)=>{let i=o.getAttribute("repeat");if(i!==null){let s=ui(i,r);if(!s[Symbol.iterator])return S;let n=qr(o),a=-1,l=[];for(let d of s){a++;let p=Object.create(r);p.item=d,p.index=a,p.this=r.this??r;let m=[];for(let b of n.parts){let y=b.update(p,e,t);b.type===1?m.push(...y):m.push(y)}let f={_$litType$:n,values:m};l.push(f)}return l}},Wo={if:Yn,repeat:Jn},Z=(o,r=Wo,e={},t)=>{let s=qr(o).renderers;if(t){let a=qr(t).renderers,l=s.super;l!==void 0?e={...s,...e,super:(d,p,m)=>(m={...a,...m,super:(f,b,y)=>mi(t,f,b,y)},l(d,p,m))}:(e={...a,...s,...e},o=t)}else e={...s,...e};return n=>mi(o,n,r,e)};var mi=(o,r,e=Wo,t={})=>{let i=qr(o),s=[];for(let a of i.parts){let l=a.update(r,e,t);a.type===1?s.push(...l):s.push(l)}return{_$litType$:i,values:s}},Bo=new Map,qr=o=>{let r=Bo.get(o);return r===void 0&&Bo.set(o,r=Kn(o)),r},Kn=o=>{let r={h:void 0,el:o.cloneNode(!0),parts:[],renderers:{}},e=document.createTreeWalker(r.el.content,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT|NodeFilter.SHOW_COMMENT),t=e.currentNode,i=-1,s=[];for(;(t=e.nextNode())!==null;)if(t.nodeType===Node.COMMENT_NODE)i++;else if(t.nodeType===Node.ELEMENT_NODE){i++;let n=t;if(n.tagName==="TEMPLATE"){let l=n.getAttribute("type"),d=n.getAttribute("name"),p=n.getAttribute("call");if(p!==null||l!==null||d!==null){n.parentNode.insertBefore(document.createComment(""),n),s.push(n);let m;if(p!==null){let f=p.trim(),b=f.startsWith("{{")&&f.endsWith("}}");m=(y,C,R)=>{let q=n.getAttribute("data"),T=q===null?void 0:ui(q,y);return(b?ui(f,y):R[p])?.(T,C,R)}}else l!==null?m=(f,b,y)=>{let C=b[l];return C?.(n,f,b,y)}:(d==="super"?r.renderers.super=(f,b,y)=>{let C=y.super,R=qr(n);return y={...y,...R.renderers},C(f,b,y)}:r.renderers[d]=(f,b,y)=>mi(n,f,b,y),m=(f,b,y)=>{let C=y[d];return C?.(f,b,y)});r.parts.push({type:2,index:i,update:m});continue}}let a=n.getAttributeNames();for(let l of a){let d=n.getAttribute(l),p=d.split(Uo);if(p.length===1){jo(d)&&n.setAttribute(l,xr(d));continue}n.removeAttribute(l);let m=l,f=Bn,b=l[0];b==="."?(m=Fo(l.substring(1)),f=Wn):b==="?"?(m=l.substring(1),f=Xn):b==="@"&&(m=Fo(l.substring(1)),f=Gn);let y=[xr(p[0])],C=[];for(let R=1;R<p.length;R+=2){let q=p[R];C.push(qs(q,ws)),y.push(xr(p[R+1]))}r.parts.push({type:1,index:i,name:m,strings:y,ctor:f,update:(R,q,T)=>C.map(M=>M.evaluate(R))})}}else if(t.nodeType===Node.TEXT_NODE){let n=t,a=n.textContent,l=a.split(Uo);l.length>1?n.textContent=xr(l[0]):jo(a)&&(n.textContent=xr(a));for(let d=1;d<l.length;d+=2){let p=l[d],m=qs(p,ws);r.parts.push({type:2,index:++i,update:(b,y)=>m.evaluate(b)});let f=new Text(l[d+1].replace("\\{{","{{"));n.parentNode.insertBefore(f,n.nextSibling),n.parentNode.insertBefore(document.createComment(""),n.nextSibling),n=f,e.currentNode=f}}for(let n of s)n.remove();return r};var Xo={fromAttribute(o){return o==="true"},toAttribute(o){return o?"true":"false"}},_e=class extends v{constructor(){super(...arguments);this.weigths=new Map}createRenderRoot(){return this}get assessmentItem(){return this.renderRoot?.querySelector("qti-assessment-item")}async connectedCallback(){super.connectedCallback();let e=this.getRootNode().host.closest("qti-test").querySelector("template[item-ref]");e&&(this.myTemplate=Z(e)),await this.updateComplete,this.dispatchEvent(new CustomEvent("qti-assessment-item-ref-connected",{bubbles:!0,composed:!0,detail:{identifier:this.identifier,href:this.href,category:this.category}}))}render(){return this.myTemplate?this.myTemplate({xmlDoc:this.xmlDoc}):this.xmlDoc}};c([u({type:String})],_e.prototype,"category",2),c([u({type:String})],_e.prototype,"identifier",2),c([u({type:Boolean,converter:Xo})],_e.prototype,"required",2),c([u({type:Boolean,converter:Xo})],_e.prototype,"fixed",2),c([u({type:String})],_e.prototype,"href",2),c([u({type:Object,attribute:!1})],_e.prototype,"xmlDoc",2);customElements.get("qti-assessment-item-ref")||customElements.define("qti-assessment-item-ref",_e);var _s={fromAttribute(o){return o==="true"},toAttribute(o){return o?"true":"false"}},Te=class extends v{constructor(){super(...arguments);this._title=""}get title(){return this._title}set title(e){this._title=e,this.removeAttribute("title"),this.setAttribute("data-title",e)}async connectedCallback(){this._title=this.getAttribute("title")||"",super.connectedCallback(),await this.updateComplete,this.dispatchEvent(new Event("qti-assessment-section-connected",{bubbles:!0,composed:!0}))}render(){return h`<slot name="qti-rubric-block"></slot><slot></slot>`}};c([u({type:String})],Te.prototype,"identifier",2),c([u({type:String})],Te.prototype,"required",2),c([u({type:Boolean,converter:_s})],Te.prototype,"fixed",2),c([u({type:Boolean,converter:_s})],Te.prototype,"visible",2),c([u({type:Boolean,converter:_s,attribute:"keep-together"})],Te.prototype,"keepTogether",2),c([_({context:ue,subscribe:!0})],Te.prototype,"_testContext",2);customElements.get("qti-assessment-section")||customElements.define("qti-assessment-section",Te);var et=class extends v{constructor(){super(...arguments);this._title=""}get title(){return this._title}set title(e){this._title=e,this.removeAttribute("title"),this.setAttribute("data-title",e)}async connectedCallback(){super.connectedCallback(),await this.updateComplete,this.dispatchEvent(new CustomEvent("qti-assessment-test-connected",{detail:this,bubbles:!0,composed:!0}))}render(){return h` <slot></slot>`}};c([u({type:String})],et.prototype,"identifier",2),c([u({type:String})],et.prototype,"title",1),c([_({context:ue,subscribe:!0})],et.prototype,"_testContext",2),et=c([g("qti-assessment-test")],et);var Ae=class extends v{constructor(){super(...arguments);this.identifier="";this.class="";this.navigationMode="nonlinear";this.submissionMode="individual";this._title=""}get title(){return this._title}set title(e){this._title=e,this.removeAttribute("title"),this.setAttribute("data-title",e)}async connectedCallback(){super.connectedCallback(),await this.updateComplete,this.dispatchEvent(new Event("qti-test-part-connected",{bubbles:!0,composed:!0}))}render(){return h` <slot></slot>`}};c([u({type:String})],Ae.prototype,"identifier",2),c([u({type:String})],Ae.prototype,"class",2),c([u({type:String,attribute:"navigation-mode"})],Ae.prototype,"navigationMode",2),c([u({type:String,attribute:"submission-mode"})],Ae.prototype,"submissionMode",2),Ae=c([g("qti-test-part")],Ae);customElements.get("qti-test-part")||customElements.define("qti-test-part",Ae);var Er=class extends Ze{render(){return h``}};Er.styles=x`
1498
1498
  :host {
1499
1499
  color: gray;
@@ -5432,7 +5432,7 @@ div.full-correct-response-inline {
5432
5432
  :host([disabled]) {
5433
5433
  ${Qo};
5434
5434
  }
5435
- `,c([_({context:kt,subscribe:!0})],re.prototype,"computedContext",2),c([u({type:Boolean,reflect:!0})],re.prototype,"shown",2),c([u({type:Boolean,reflect:!0})],re.prototype,"disabled",2),c([u({type:String})],re.prototype,"showCorrectText",2),c([u({type:String})],re.prototype,"hideCorrectText",2),c([u({type:String})],re.prototype,"noCorrectResponseText",2),re=c([g("item-show-correct-response")],re);var St=class extends v{constructor(){super();this.configContext={};this._onItemContextChanged=this._handleItemContextChanged.bind(this);this._onAssessmentItemConnected=this._handleAssessmentItemConnected.bind(this);this._onHandleShowCorrectResponse=this._handleShowCorrectResponse.bind(this);this._onHandleShowCandidateCorrection=this._handleShowCandidateCorrection.bind(this);this._onHandleSwitchCorrectResponseMode=this._handleSwitchCorrectResponseMode.bind(this);this.addEventListener("qti-item-context-updated",this._onItemContextChanged),this.addEventListener("qti-assessment-item-connected",this._onAssessmentItemConnected),this.addEventListener("item-show-correct-response",this._onHandleShowCorrectResponse),this.addEventListener("item-show-candidate-correction",this._onHandleShowCandidateCorrection),this.addEventListener("item-switch-correct-response-mode",this._onHandleSwitchCorrectResponseMode)}_handleItemContextChanged(e){this._updateItemVariablesInTestContext(e.detail.itemContext.identifier,e.detail?.itemContext?.variables||[])}_handleAssessmentItemConnected(e){let t=e.detail._context.variables;this._qtiAssessmentItem=e.detail,this.computedContext=this.computedContext?.identifier===this._qtiAssessmentItem.identifier?{...this.computedContext,title:this._qtiAssessmentItem.title}:{identifier:this._qtiAssessmentItem.identifier,title:this._qtiAssessmentItem.title,adaptive:this._qtiAssessmentItem.getAttribute("adaptive")?.toLowerCase()==="true"||!1,variables:t,correctResponseMode:"internal"},this._updateItemVariablesInTestContext(this._qtiAssessmentItem.identifier,t||[])}_handleShowCorrectResponse(e){this._qtiAssessmentItem&&this._qtiAssessmentItem.showCorrectResponse(e.detail)}_handleShowCandidateCorrection(e){this._qtiAssessmentItem&&this._qtiAssessmentItem.showCandidateCorrection(e.detail)}_handleSwitchCorrectResponseMode(e){this._handleShowCorrectResponse(new CustomEvent("item-show-correct-response",{detail:!1,bubbles:!0})),this.configContext={...this.configContext,correctResponseMode:e.detail}}_updateItemVariablesInTestContext(e,t){let i=t?.find(p=>p.identifier=="SCORE")?.value,s=parseFloat(i?.toString()),n=t?.find(p=>p.identifier==="completionStatus")?.value,a=s!==void 0&&!isNaN(s)&&s>0,l=s!==void 0&&!isNaN(s)&&s<=0,d=n==="completed";this.computedContext={...this.computedContext,identifier:e,correct:a,incorrect:l,completed:d,variables:t}}render(){return h`<slot></slot>`}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("qti-item-context-changed",this._onItemContextChanged),this.removeEventListener("qti-assessment-item-connected",this._onAssessmentItemConnected)}};c([E(),X({context:kt})],St.prototype,"computedContext",2),c([E(),X({context:ne})],St.prototype,"configContext",2),St=c([g("qti-item")],St);var en={name:"@citolab/qti-components",repository:{type:"git",url:"git+https://github.com/Citolab/qti-components.git"},description:"QTI webcomponents",author:{name:"Patrick de Klein"},contributors:[{name:"Sander Looise"},{name:"Marcel Hoekstra"}],license:"GPLv3",private:!1,engines:{node:">=22.0.0"},version:"7.9.0",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",sideEffects:!0,exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./exports/*":{import:"./dist/exports/*"},"./qti-components":{types:"./dist/qti-components/index.d.ts",import:"./dist/qti-components/index.js"},"./qti-item":{types:"./dist/qti-item/index.d.ts",import:"./dist/qti-item/index.js"},"./qti-test":{types:"./dist/qti-test/index.d.ts",import:"./dist/qti-test/index.js"},"./qti-loader":{types:"./dist/qti-loader/index.d.ts",import:"./dist/qti-loader/index.js"},"./qti-transformers":{types:"./dist/qti-transformers/index.d.ts",import:"./dist/qti-transformers/index.js"},"./customElements":"./custom-elements.json","./react":"./dist/qti-components-jsx.d.ts","./item.css":"./dist/item.css","./cdn/*":"./cdn/*","./package.json":"./package.json"},files:["dist","cdn","custom-elements.json"],scripts:{storybook:"run-p storybook:dev cem:watch",watch:'nodemon --watch src --ext ts,css --exec "run-s tsup cem css && yalc push"',"-----------------------cmds--":"-","pre-commit":"run-s lint stylelint madge","commit-msg":"commitlint --edit","build-storybook":"npm run cem && storybook build","-----------------------scripts--":"-",build:"run-p cem css tsup","storybook:dev":"storybook dev -p 6006",cem:"cem analyze","cem:watch":"cem analyze --watch",css:"postcss src/item.css -d dist -m",ci:"npm ci",tsup:"tsup",publint:"publint",lint:"eslint src/**/*.ts",stylelint:'stylelint "src/**/*.css"',test:"vitest run",attw:"attw --profile esm-only --pack --exclude-entrypoints ./item.css ./react",chromatic:"node chromatic-runner.cjs",clean:"rm -rf dist cdn",madge:"madge --circular --extensions ts src",commitlint:"commitlint --edit","-----------------------npm--":"-",prepare:"husky"},peerDependencies:{"@heximal/templates":"^0.1.5","@lit/context":"^1.1.3",lit:"^3.2.1"},devDependencies:{"@arethetypeswrong/cli":"^0.18.2","@chromatic-com/storybook":"^4.1.1","@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@custom-elements-manifest/analyzer":"^0.10.4","@eslint/js":"^9.29.0","@heximal/templates":"0.1.5","@lit/context":"^1.1.5","@open-wc/lit-helpers":"^0.7.0","@storybook/addon-a11y":"^9.1.5","@storybook/addon-docs":"^9.1.5","@storybook/addon-links":"^9.1.5","@storybook/addon-themes":"^9.1.5","@storybook/addon-vitest":"^9.1.5","@storybook/web-components-vite":"^9.1.5","@swc/core":"^1.12.1","@testing-library/dom":"^10.4.0","@types/dom-view-transitions":"^1.0.6","@types/node":"^24.0.3","@vitest/browser":"^3.2.4","@vitest/coverage-v8":"^3.2.4","@vitest/ui":"^3.2.4","@wc-toolkit/cem-inheritance":"^1.1.0","@wc-toolkit/cem-sorter":"^1.0.1","@wc-toolkit/cem-utilities":"^1.3.0","@wc-toolkit/changelog":"^1.0.1","@wc-toolkit/jsx-types":"^1.2.2","@wc-toolkit/storybook-helpers":"^9.0.0","@wc-toolkit/type-parser":"^1.1.0",autoprefixer:"^10.4.21",chromatic:"^13.0.0","custom-element-vs-code-integration":"^1.5.0","custom-elements-manifest-deprecator":"^1.2.0",dotenv:"^16.5.0",eslint:"^9.29.0","eslint-import-resolver-typescript":"^4.4.3","eslint-plugin-import":"^2.31.0","eslint-plugin-lit":"^2.1.1","eslint-plugin-lit-a11y":"^5.0.1","eslint-plugin-react":"^7.37.5","eslint-plugin-sort-imports-es6-autofix":"^0.6.0","eslint-plugin-storybook":"^9.1.5","eslint-plugin-wc":"^3.0.1","fast-xml-parser":"^5.2.5",globals:"^16.2.0",globby:"^14.1.0",husky:"^9.1.7",lit:"^3.3.0",madge:"^8.0.0",nodemon:"^3.1.10","npm-run-all":"^4.1.5","path-browserify":"^1.0.1","pkg-pr-new":"^0.0.51",playwright:"^1.53.0",postcss:"^8.5.6","postcss-class-apply":"^4.0.1","postcss-cli":"^11.0.1","postcss-import":"^16.1.1","postcss-nesting":"^13.0.2",prettier:"3.5.3","prettier-v2":"npm:prettier@2.8.8",publint:"^0.3.12","remark-gfm":"^4.0.1","shadow-dom-testing-library":"^1.12.0",storybook:"^9.1.5","storybook-addon-tag-badges":"^2.0.1",stylelint:"^16.20.0","stylelint-config-standard":"^38.0.0","stylelint-prettier":"^5.0.3",tsup:"^8.5.0",typescript:"^5.8.3","typescript-eslint":"^8.34.1",vite:"^6.3.5","vite-tsconfig-paths":"^5.1.4",vitest:"^3.2.4",yalc:"^1.0.0-pre.53"},optionalDependencies:{"@rollup/rollup-linux-x64-gnu":"^4.43.0"},customElements:"custom-elements.json",bugs:{url:"https://github.com/Citolab/qti-components/issues"},homepage:"https://github.com/Citolab/qti-components#readme",overrides:{storybook:"$storybook"}};console.info("%cC\xBFTO%cLab%c: qti-components v%c%s%c loaded",'font-family: "PT Sans", font-weight:bold; color:green; font-size: smaller;vertical-align: sub',"font-weight:bold; color:green","font-weight:unset","font-weight:bold; color:#2563eb",en.version,"font-weight:unset");export{Ji as INITIAL_TEST_CONTEXT,Re as ItemContainer,re as ItemShowCorrectResponse,Rt as PrintItemVariables,Jr as QtiAnd,G as QtiAssessmentItem,_e as QtiAssessmentItemRef,Te as QtiAssessmentSection,pt as QtiAssessmentStimulusRef,et as QtiAssessmentTest,Jt as QtiAssociableHotspot,ut as QtiAssociateInteraction,Kr as QtiBaseValue,mt as QtiChoiceInteraction,Br as QtiCompanionMaterialsInfo,Xi as QtiContainerSize,Gi as QtiContains,oi as QtiContentBody,Yi as QtiCorrect,ve as QtiCustomInteraction,Wt as QtiCustomOperator,qt as QtiDefault,vs as QtiDelete,$e as QtiEndAttemptInteraction,Qr as QtiEqual,Zr as QtiEqualRounded,U as QtiExtendedTextInteraction,Gt as QtiFeedbackBlock,Yt as QtiFeedbackInline,is as QtiFieldValue,gt as QtiGap,ht as QtiGapImg,Kt as QtiGapMatchInteraction,ft as QtiGapText,Zi as QtiGcd,ce as QtiGraphicAssociateInteraction,Zt as QtiGraphicGapMatchInteraction,Qt as QtiGraphicOrderInteraction,Qi as QtiGt,es as QtiGte,Qe as QtiHotspotChoice,er as QtiHotspotInteraction,rr as QtiHottext,tr as QtiHottextInteraction,br as QtiIndex,sr as QtiInlineChoice,ye as QtiInlineChoiceInteraction,rs as QtiIsNull,St as QtiItem,cr as QtiItemBody,ur as QtiLookupOutcomeValue,ss as QtiLt,os as QtiLte,ei as QtiMapResponse,ti as QtiMapResponsePoint,ns as QtiMatch,xe as QtiMatchInteraction,ri as QtiMathOperator,or as QtiMediaInteraction,as as QtiMember,Ze as QtiModalFeedback,ls as QtiMultiple,cs as QtiNot,ts as QtiNull,ds as QtiOr,qe as QtiOrderInteraction,ps as QtiOrdered,he as QtiOutcomeDeclaration,dr as QtiOutcomeProcessing,Fi as QtiOutcomeProcessingProcessor,z as QtiPortableCustomInteraction,Vi as QtiPositionObjectInteraction,nr as QtiPositionObjectStage,us as QtiPower,gr as QtiPrintedVariable,ms as QtiProduct,Gr as QtiPrompt,bs as QtiRandom,Et as QtiRandomInteger,Ui as QtiResponseCondition,we as QtiResponseDeclaration,mr as QtiResponseElse,Wi as QtiResponseElseIf,hr as QtiResponseIf,pr as QtiResponseProcessing,Ki as QtiRound,fr as QtiRoundTo,me as QtiRubricBlock,pe as QtiRule,de as QtiSelectPointInteraction,ji as QtiSetOutcomeValue,Bi as QtiSetOutcomeValueRule,Ve as QtiSimpleAssociableChoice,Ee as QtiSimpleChoice,Ce as QtiSliderInteraction,si as QtiStringMatch,ni as QtiStylesheet,ii as QtiSubtract,hs as QtiSum,fs as QtiSumExpression,ai as QtiTest,Er as QtiTestFeedback,Ae as QtiTestPart,J as QtiTextEntryInteraction,lr as QtiUploadInteraction,gs as QtiVariable,kr as TestCheckItem,ke as TestContainer,Cr as TestEndAttempt,wt as TestItemLink,Q as TestNavigation,ze as TestNext,wr as TestPagingButtonsStamp,Fe as TestPrev,Tr as TestPrintContext,_t as TestPrintVariables,it as TestScoringButtons,At as TestScoringFeedback,_r as TestSectionButtonsStamp,Tt as TestSectionLink,te as TestShowCorrectResponse,rt as TestStamp,W as TestView,Ar as TestViewToggle,Mn as qtiAndMixin,In as qtiSubtractMixin,ue as testContext};
5435
+ `,c([_({context:kt,subscribe:!0})],re.prototype,"computedContext",2),c([u({type:Boolean,reflect:!0})],re.prototype,"shown",2),c([u({type:Boolean,reflect:!0})],re.prototype,"disabled",2),c([u({type:String})],re.prototype,"showCorrectText",2),c([u({type:String})],re.prototype,"hideCorrectText",2),c([u({type:String})],re.prototype,"noCorrectResponseText",2),re=c([g("item-show-correct-response")],re);var St=class extends v{constructor(){super();this.configContext={};this._onItemContextChanged=this._handleItemContextChanged.bind(this);this._onAssessmentItemConnected=this._handleAssessmentItemConnected.bind(this);this._onHandleShowCorrectResponse=this._handleShowCorrectResponse.bind(this);this._onHandleShowCandidateCorrection=this._handleShowCandidateCorrection.bind(this);this._onHandleSwitchCorrectResponseMode=this._handleSwitchCorrectResponseMode.bind(this);this.addEventListener("qti-item-context-updated",this._onItemContextChanged),this.addEventListener("qti-assessment-item-connected",this._onAssessmentItemConnected),this.addEventListener("item-show-correct-response",this._onHandleShowCorrectResponse),this.addEventListener("item-show-candidate-correction",this._onHandleShowCandidateCorrection),this.addEventListener("item-switch-correct-response-mode",this._onHandleSwitchCorrectResponseMode)}_handleItemContextChanged(e){this._updateItemVariablesInTestContext(e.detail.itemContext.identifier,e.detail?.itemContext?.variables||[])}_handleAssessmentItemConnected(e){let t=e.detail._context.variables;this._qtiAssessmentItem=e.detail,this.computedContext=this.computedContext?.identifier===this._qtiAssessmentItem.identifier?{...this.computedContext,title:this._qtiAssessmentItem.title}:{identifier:this._qtiAssessmentItem.identifier,title:this._qtiAssessmentItem.title,adaptive:this._qtiAssessmentItem.getAttribute("adaptive")?.toLowerCase()==="true"||!1,variables:t,correctResponseMode:"internal"},this._updateItemVariablesInTestContext(this._qtiAssessmentItem.identifier,t||[])}_handleShowCorrectResponse(e){this._qtiAssessmentItem&&this._qtiAssessmentItem.showCorrectResponse(e.detail)}_handleShowCandidateCorrection(e){this._qtiAssessmentItem&&this._qtiAssessmentItem.showCandidateCorrection(e.detail)}_handleSwitchCorrectResponseMode(e){this._handleShowCorrectResponse(new CustomEvent("item-show-correct-response",{detail:!1,bubbles:!0})),this.configContext={...this.configContext,correctResponseMode:e.detail}}_updateItemVariablesInTestContext(e,t){let i=t?.find(p=>p.identifier=="SCORE")?.value,s=parseFloat(i?.toString()),n=t?.find(p=>p.identifier==="completionStatus")?.value,a=s!==void 0&&!isNaN(s)&&s>0,l=s!==void 0&&!isNaN(s)&&s<=0,d=n==="completed";this.computedContext={...this.computedContext,identifier:e,correct:a,incorrect:l,completed:d,variables:t}}render(){return h`<slot></slot>`}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("qti-item-context-changed",this._onItemContextChanged),this.removeEventListener("qti-assessment-item-connected",this._onAssessmentItemConnected)}};c([E(),X({context:kt})],St.prototype,"computedContext",2),c([E(),X({context:ne})],St.prototype,"configContext",2),St=c([g("qti-item")],St);var en={name:"@citolab/qti-components",repository:{type:"git",url:"git+https://github.com/Citolab/qti-components.git"},description:"QTI webcomponents",author:{name:"Patrick de Klein"},contributors:[{name:"Sander Looise"},{name:"Marcel Hoekstra"}],license:"GPLv3",private:!1,engines:{node:">=22.0.0"},version:"7.10.0",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",sideEffects:!0,exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./exports/*":{import:"./dist/exports/*"},"./qti-components":{types:"./dist/qti-components/index.d.ts",import:"./dist/qti-components/index.js"},"./qti-item":{types:"./dist/qti-item/index.d.ts",import:"./dist/qti-item/index.js"},"./qti-test":{types:"./dist/qti-test/index.d.ts",import:"./dist/qti-test/index.js"},"./qti-loader":{types:"./dist/qti-loader/index.d.ts",import:"./dist/qti-loader/index.js"},"./qti-transformers":{types:"./dist/qti-transformers/index.d.ts",import:"./dist/qti-transformers/index.js"},"./customElements":"./custom-elements.json","./react":"./dist/qti-components-jsx.d.ts","./item.css":"./dist/item.css","./cdn/*":"./cdn/*","./package.json":"./package.json"},files:["dist","cdn","custom-elements.json"],scripts:{storybook:"run-p storybook:dev cem:watch",watch:'nodemon --watch src --ext ts,css --exec "run-s tsup cem css && yalc push"',"-----------------------cmds--":"-","pre-commit":"run-s lint stylelint madge","commit-msg":"commitlint --edit","build-storybook":"npm run cem && storybook build","-----------------------scripts--":"-",build:"run-p cem css tsup","storybook:dev":"storybook dev -p 6006",cem:"cem analyze","cem:watch":"cem analyze --watch",css:"postcss src/item.css -d dist -m",ci:"npm ci",tsup:"tsup",publint:"publint",lint:"eslint src/**/*.ts",stylelint:'stylelint "src/**/*.css"',test:"vitest run",attw:"attw --profile esm-only --pack --exclude-entrypoints ./item.css ./react",chromatic:"node chromatic-runner.cjs",clean:"rm -rf dist cdn",madge:"madge --circular --extensions ts src",commitlint:"commitlint --edit","-----------------------npm--":"-",prepare:"husky"},peerDependencies:{"@heximal/templates":"^0.1.5","@lit/context":"^1.1.3",lit:"^3.2.1"},devDependencies:{"@arethetypeswrong/cli":"^0.18.2","@chromatic-com/storybook":"^4.1.1","@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@custom-elements-manifest/analyzer":"^0.10.4","@eslint/js":"^9.29.0","@heximal/templates":"0.1.5","@lit/context":"^1.1.5","@open-wc/lit-helpers":"^0.7.0","@storybook/addon-a11y":"^9.1.5","@storybook/addon-docs":"^9.1.5","@storybook/addon-links":"^9.1.5","@storybook/addon-themes":"^9.1.5","@storybook/addon-vitest":"^9.1.5","@storybook/web-components-vite":"^9.1.5","@swc/core":"^1.12.1","@testing-library/dom":"^10.4.0","@types/dom-view-transitions":"^1.0.6","@types/node":"^24.0.3","@vitest/browser":"^3.2.4","@vitest/coverage-v8":"^3.2.4","@vitest/ui":"^3.2.4","@wc-toolkit/cem-inheritance":"^1.1.0","@wc-toolkit/cem-sorter":"^1.0.1","@wc-toolkit/cem-utilities":"^1.3.0","@wc-toolkit/changelog":"^1.0.1","@wc-toolkit/jsx-types":"^1.2.2","@wc-toolkit/storybook-helpers":"^9.0.0","@wc-toolkit/type-parser":"^1.1.0",autoprefixer:"^10.4.21",chromatic:"^13.0.0","custom-element-vs-code-integration":"^1.5.0","custom-elements-manifest-deprecator":"^1.2.0",dotenv:"^16.5.0",eslint:"^9.29.0","eslint-import-resolver-typescript":"^4.4.3","eslint-plugin-import":"^2.31.0","eslint-plugin-lit":"^2.1.1","eslint-plugin-lit-a11y":"^5.0.1","eslint-plugin-react":"^7.37.5","eslint-plugin-sort-imports-es6-autofix":"^0.6.0","eslint-plugin-storybook":"^9.1.5","eslint-plugin-wc":"^3.0.1","fast-xml-parser":"^5.2.5",globals:"^16.2.0",globby:"^14.1.0",husky:"^9.1.7",lit:"^3.3.0",madge:"^8.0.0",nodemon:"^3.1.10","npm-run-all":"^4.1.5","path-browserify":"^1.0.1","pkg-pr-new":"^0.0.51",playwright:"^1.53.0",postcss:"^8.5.6","postcss-class-apply":"^4.0.1","postcss-cli":"^11.0.1","postcss-import":"^16.1.1","postcss-nesting":"^13.0.2",prettier:"3.5.3","prettier-v2":"npm:prettier@2.8.8",publint:"^0.3.12","remark-gfm":"^4.0.1","shadow-dom-testing-library":"^1.12.0",storybook:"^9.1.5","storybook-addon-tag-badges":"^2.0.1",stylelint:"^16.20.0","stylelint-config-standard":"^38.0.0","stylelint-prettier":"^5.0.3",tsup:"^8.5.0",typescript:"^5.8.3","typescript-eslint":"^8.34.1",vite:"^6.3.5","vite-tsconfig-paths":"^5.1.4",vitest:"^3.2.4",yalc:"^1.0.0-pre.53"},optionalDependencies:{"@rollup/rollup-linux-x64-gnu":"^4.43.0"},customElements:"custom-elements.json",bugs:{url:"https://github.com/Citolab/qti-components/issues"},homepage:"https://github.com/Citolab/qti-components#readme",overrides:{storybook:"$storybook"}};console.info("%cC\xBFTO%cLab%c: qti-components v%c%s%c loaded",'font-family: "PT Sans", font-weight:bold; color:green; font-size: smaller;vertical-align: sub',"font-weight:bold; color:green","font-weight:unset","font-weight:bold; color:#2563eb",en.version,"font-weight:unset");export{Ji as INITIAL_TEST_CONTEXT,Re as ItemContainer,re as ItemShowCorrectResponse,Rt as PrintItemVariables,Jr as QtiAnd,G as QtiAssessmentItem,_e as QtiAssessmentItemRef,Te as QtiAssessmentSection,pt as QtiAssessmentStimulusRef,et as QtiAssessmentTest,Jt as QtiAssociableHotspot,ut as QtiAssociateInteraction,Kr as QtiBaseValue,mt as QtiChoiceInteraction,Br as QtiCompanionMaterialsInfo,Xi as QtiContainerSize,Gi as QtiContains,oi as QtiContentBody,Yi as QtiCorrect,ve as QtiCustomInteraction,Wt as QtiCustomOperator,qt as QtiDefault,vs as QtiDelete,$e as QtiEndAttemptInteraction,Qr as QtiEqual,Zr as QtiEqualRounded,U as QtiExtendedTextInteraction,Gt as QtiFeedbackBlock,Yt as QtiFeedbackInline,is as QtiFieldValue,gt as QtiGap,ht as QtiGapImg,Kt as QtiGapMatchInteraction,ft as QtiGapText,Zi as QtiGcd,ce as QtiGraphicAssociateInteraction,Zt as QtiGraphicGapMatchInteraction,Qt as QtiGraphicOrderInteraction,Qi as QtiGt,es as QtiGte,Qe as QtiHotspotChoice,er as QtiHotspotInteraction,rr as QtiHottext,tr as QtiHottextInteraction,br as QtiIndex,sr as QtiInlineChoice,ye as QtiInlineChoiceInteraction,rs as QtiIsNull,St as QtiItem,cr as QtiItemBody,ur as QtiLookupOutcomeValue,ss as QtiLt,os as QtiLte,ei as QtiMapResponse,ti as QtiMapResponsePoint,ns as QtiMatch,xe as QtiMatchInteraction,ri as QtiMathOperator,or as QtiMediaInteraction,as as QtiMember,Ze as QtiModalFeedback,ls as QtiMultiple,cs as QtiNot,ts as QtiNull,ds as QtiOr,qe as QtiOrderInteraction,ps as QtiOrdered,he as QtiOutcomeDeclaration,dr as QtiOutcomeProcessing,Fi as QtiOutcomeProcessingProcessor,z as QtiPortableCustomInteraction,Vi as QtiPositionObjectInteraction,nr as QtiPositionObjectStage,us as QtiPower,gr as QtiPrintedVariable,ms as QtiProduct,Gr as QtiPrompt,bs as QtiRandom,Et as QtiRandomInteger,Ui as QtiResponseCondition,we as QtiResponseDeclaration,mr as QtiResponseElse,Wi as QtiResponseElseIf,hr as QtiResponseIf,pr as QtiResponseProcessing,Ki as QtiRound,fr as QtiRoundTo,me as QtiRubricBlock,pe as QtiRule,de as QtiSelectPointInteraction,ji as QtiSetOutcomeValue,Bi as QtiSetOutcomeValueRule,Ve as QtiSimpleAssociableChoice,Ee as QtiSimpleChoice,Ce as QtiSliderInteraction,si as QtiStringMatch,ni as QtiStylesheet,ii as QtiSubtract,hs as QtiSum,fs as QtiSumExpression,ai as QtiTest,Er as QtiTestFeedback,Ae as QtiTestPart,J as QtiTextEntryInteraction,lr as QtiUploadInteraction,gs as QtiVariable,kr as TestCheckItem,ke as TestContainer,Cr as TestEndAttempt,wt as TestItemLink,Q as TestNavigation,ze as TestNext,wr as TestPagingButtonsStamp,Fe as TestPrev,Tr as TestPrintContext,_t as TestPrintVariables,it as TestScoringButtons,At as TestScoringFeedback,_r as TestSectionButtonsStamp,Tt as TestSectionLink,te as TestShowCorrectResponse,rt as TestStamp,W as TestView,Ar as TestViewToggle,Mn as qtiAndMixin,In as qtiSubtractMixin,ue as testContext};
5436
5436
  /*! Bundled license information:
5437
5437
 
5438
5438
  @lit/context/lib/context-request-event.js:
@@ -23869,7 +23869,15 @@
23869
23869
  "type": {
23870
23870
  "text": "Story"
23871
23871
  },
23872
- "default": "{ render: args => { return html`<qti-item> <div style=\"display: flex; flex-direction: column; gap: 1rem; align-items: start\"> <item-container style=\"width: 400px; height: 350px; display: block;\" item-url=${args['item-url'] as string}> <template> <style> qti-assessment-item { padding: 1rem; display: block; aspect-ratio: 4 / 3; width: 800px; border: 2px solid blue; transform: scale(0.5); transform-origin: top left; } </style> </template> </item-container> <item-show-correct-response ${spread(args)}></item-show-correct-response> </div> </qti-item>`; }, play: async ({ canvasElement, step }) => { const item = document.querySelector('qti-item'); item.configContext = { correctResponseMode: 'full' }; const canvas = within(canvasElement); const showCorrectButton = await canvas.findByShadowText(/Show correct/i); await step('Click on the Show Correct button', async () => { await fireEvent.click(showCorrectButton); await step('Verify correct response state is applied', async () => { const fullCorrectResponse = await canvas.findByShadowRole('full-correct-response'); expect(fullCorrectResponse).toBeVisible(); const interaction = fullCorrectResponse.querySelector('qti-choice-interaction'); const choices = Array.from(interaction.querySelectorAll('qti-simple-choice')); await interaction.updateComplete; expect(choices[0].internals.states.has('--checked')).toBe(true); expect(choices[1].internals.states.has('--checked')).toBe(false); expect(choices[2].internals.states.has('--checked')).toBe(false); }); }); } }"
23872
+ "default": "{ render: args => { return html`<qti-item> <div style=\"display: flex; flex-direction: column; gap: 1rem; align-items: start\"> <item-container style=\"width: 400px; height: 350px; display: block;\" item-url=${args['item-url'] as string}> <template> <style> qti-assessment-item { padding: 1rem; display: block; aspect-ratio: 4 / 3; width: 800px; border: 2px solid blue; transform: scale(0.5); transform-origin: top left; } </style> </template> </item-container> <item-show-correct-response ${spread(args)}></item-show-correct-response> </div> </qti-item>`; }, play: async ({ canvasElement, step }) => { const item = document.querySelector('qti-item'); item.configContext = { correctResponseMode: 'full', fullCorrectResponseOnlyWhenIncorrect: false }; const canvas = within(canvasElement); const showCorrectButton = await canvas.findByShadowText(/Show correct/i); const choiceA: QtiSimpleChoice = await canvas.findByShadowText('You must stay with your luggage at all times.'); await step('Click on the Show Correct button', async () => { await choiceA.click(); await fireEvent.click(showCorrectButton); await step('Verify correct response state is applied', async () => { const fullCorrectResponse = await canvas.findByShadowRole('full-correct-response'); expect(fullCorrectResponse).toBeVisible(); const interaction = fullCorrectResponse.querySelector('qti-choice-interaction'); const choices = Array.from(interaction.querySelectorAll('qti-simple-choice')); await interaction.updateComplete; expect(choices[0].internals.states.has('--checked')).toBe(true); expect(choices[1].internals.states.has('--checked')).toBe(false); expect(choices[2].internals.states.has('--checked')).toBe(false); }); }); } }"
23873
+ },
23874
+ {
23875
+ "kind": "variable",
23876
+ "name": "ChoiceFullCorrectResponseOnlyWhenIncorrect",
23877
+ "type": {
23878
+ "text": "Story"
23879
+ },
23880
+ "default": "{ render: args => { return html`<qti-item> <div style=\"display: flex; flex-direction: column; gap: 1rem; align-items: start\"> <item-container style=\"width: 400px; height: 350px; display: block;\" item-url=${args['item-url'] as string}> <template> <style> qti-assessment-item { padding: 1rem; display: block; aspect-ratio: 4 / 3; width: 800px; border: 2px solid blue; transform: scale(0.5); transform-origin: top left; } </style> </template> </item-container> <item-show-correct-response ${spread(args)}></item-show-correct-response> </div> </qti-item>`; }, play: async ({ canvasElement, step }) => { const item = document.querySelector('qti-item'); item.configContext = { correctResponseMode: 'full', fullCorrectResponseOnlyWhenIncorrect: true }; const canvas = within(canvasElement); const showCorrectButton = await canvas.findByShadowText(/Show correct/i); const choiceA: QtiSimpleChoice = await canvas.findByShadowText('You must stay with your luggage at all times.'); await step('Click on the Show Correct button', async () => { await choiceA.click(); await fireEvent.click(showCorrectButton); await step('Verify correct full correct response is not visible', async () => { const fullCorrectResponse = await canvas.queryByShadowRole('full-correct-response'); expect(fullCorrectResponse).toBeNull(); }); }); } }"
23873
23881
  },
23874
23882
  {
23875
23883
  "kind": "variable",
@@ -23973,7 +23981,7 @@
23973
23981
  "type": {
23974
23982
  "text": "Story"
23975
23983
  },
23976
- "default": "{ args: { 'item-url': '/qti-item/example-choice-multiple-item.xml' // Set the new item URL here }, render: args => html` <qti-item> <div> <item-container style=\"display: block;width: 400px; height: 350px;\" item-url=${args['item-url'] as string}> <template> <style> qti-assessment-item { padding: 1rem; display: block; aspect-ratio: 4 / 3; width: 800px; border: 2px solid blue; transform: scale(0.5); transform-origin: top left; } </style> </template> </item-container> <item-show-correct-response ${spread(args)}></item-show-correct-response> </div> </qti-item>`, play: async ({ canvasElement, step }) => { const item = document.querySelector('qti-item'); item.configContext = { correctResponseMode: 'full' }; const canvas = within(canvasElement); const showCorrectButton = await canvas.findByShadowText(/Show correct/i); await step('Select the correct response mode full', async () => { await fireEvent.click(showCorrectButton); await step('Verify correct response full state is applied', async () => { const fullCorrectResponse = await canvas.findByShadowRole('full-correct-response'); expect(fullCorrectResponse).toBeVisible(); const interaction = fullCorrectResponse.querySelector('qti-choice-interaction'); const choices = Array.from(interaction.querySelectorAll('qti-simple-choice')); await interaction.updateComplete; expect(choices[0].internals.states.has('--checked')).toBe(true); expect(choices[1].internals.states.has('--checked')).toBe(true); expect(choices[2].internals.states.has('--checked')).toBe(false); }); }); } }"
23984
+ "default": "{ args: { 'item-url': '/qti-item/example-choice-multiple-item.xml' // Set the new item URL here }, render: args => html` <qti-item> <div> <item-container style=\"display: block;width: 400px; height: 350px;\" item-url=${args['item-url'] as string}> <template> <style> qti-assessment-item { padding: 1rem; display: block; aspect-ratio: 4 / 3; width: 800px; border: 2px solid blue; transform: scale(0.5); transform-origin: top left; } </style> </template> </item-container> <item-show-correct-response ${spread(args)}></item-show-correct-response> </div> </qti-item>`, play: async ({ canvasElement, step }) => { const item = document.querySelector('qti-item'); item.configContext = { correctResponseMode: 'full', }; const canvas = within(canvasElement); const showCorrectButton = await canvas.findByShadowText(/Show correct/i); await step('Select the correct response mode full', async () => { await fireEvent.click(showCorrectButton); await step('Verify correct response full state is applied', async () => { const fullCorrectResponse = await canvas.findByShadowRole('full-correct-response'); expect(fullCorrectResponse).toBeVisible(); const interaction = fullCorrectResponse.querySelector('qti-choice-interaction'); const choices = Array.from(interaction.querySelectorAll('qti-simple-choice')); await interaction.updateComplete; expect(choices[0].internals.states.has('--checked')).toBe(true); expect(choices[1].internals.states.has('--checked')).toBe(true); expect(choices[2].internals.states.has('--checked')).toBe(false); }); }); } }"
23977
23985
  },
23978
23986
  {
23979
23987
  "kind": "variable",
@@ -24041,6 +24049,14 @@
24041
24049
  "module": "src/lib/qti-item/components/item-show-correct-response.stories.ts"
24042
24050
  }
24043
24051
  },
24052
+ {
24053
+ "kind": "js",
24054
+ "name": "ChoiceFullCorrectResponseOnlyWhenIncorrect",
24055
+ "declaration": {
24056
+ "name": "ChoiceFullCorrectResponseOnlyWhenIncorrect",
24057
+ "module": "src/lib/qti-item/components/item-show-correct-response.stories.ts"
24058
+ }
24059
+ },
24044
24060
  {
24045
24061
  "kind": "js",
24046
24062
  "name": "ChoiceInternalCorrectResponse",
@@ -5,4 +5,4 @@ var configContext = createContext(Symbol("configContext"));
5
5
  export {
6
6
  configContext
7
7
  };
8
- //# sourceMappingURL=chunk-ERYHQVOT.js.map
8
+ //# sourceMappingURL=chunk-BHJSX3Q6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/exports/config.context.ts"],"sourcesContent":["import { createContext } from '@lit/context';\n\nexport type CorrectResponseMode = 'internal' | 'full';\n\nexport interface ConfigContext {\n infoItemCategory?: string;\n reportValidityAfterScoring?: boolean;\n disableAfterIfMaxChoicesReached?: boolean;\n correctResponseMode?: CorrectResponseMode;\n inlineChoicePrompt?: string;\n}\n\nexport const configContext = createContext<Readonly<ConfigContext>>(Symbol('configContext'));\n"],"mappings":";AAAA,SAAS,qBAAqB;AAYvB,IAAM,gBAAgB,cAAuC,OAAO,eAAe,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/exports/config.context.ts"],"sourcesContent":["import { createContext } from '@lit/context';\n\nexport type CorrectResponseMode = 'internal' | 'full';\n\nexport interface ConfigContext {\n infoItemCategory?: string;\n reportValidityAfterScoring?: boolean;\n disableAfterIfMaxChoicesReached?: boolean;\n correctResponseMode?: CorrectResponseMode;\n inlineChoicePrompt?: string;\n fullCorrectResponseOnlyWhenIncorrect?: boolean;\n}\n\nexport const configContext = createContext<Readonly<ConfigContext>>(Symbol('configContext'));\n"],"mappings":";AAAA,SAAS,qBAAqB;AAavB,IAAM,gBAAgB,cAAuC,OAAO,eAAe,CAAC;","names":[]}
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-4OGJBG35.js";
13
13
  import {
14
14
  configContext
15
- } from "./chunk-ERYHQVOT.js";
15
+ } from "./chunk-BHJSX3Q6.js";
16
16
  import {
17
17
  __decorateClass
18
18
  } from "./chunk-H2JE6IVU.js";
@@ -362,4 +362,4 @@ export {
362
362
  ItemShowCorrectResponse,
363
363
  QtiItem
364
364
  };
365
- //# sourceMappingURL=chunk-4QSZJYSB.js.map
365
+ //# sourceMappingURL=chunk-IHE5M7QU.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-NJNQOQUU.js";
4
4
  import {
5
5
  configContext
6
- } from "./chunk-ERYHQVOT.js";
6
+ } from "./chunk-BHJSX3Q6.js";
7
7
  import {
8
8
  __decorateClass
9
9
  } from "./chunk-H2JE6IVU.js";
@@ -75,7 +75,8 @@ var Interaction = class extends LitElement {
75
75
  if (!responseVariable) {
76
76
  return;
77
77
  }
78
- if (!show || this.correctness === "correct" /* Correct */) {
78
+ const showFullCorrectResponse = show && (this?.configContext?.fullCorrectResponseOnlyWhenIncorrect === false || this.correctness !== "correct" /* Correct */);
79
+ if (!showFullCorrectResponse) {
79
80
  if (!nextSiblingIsFullCorrectResponse) {
80
81
  return;
81
82
  }
@@ -84,9 +85,6 @@ var Interaction = class extends LitElement {
84
85
  if (nextSiblingIsFullCorrectResponse) {
85
86
  return;
86
87
  }
87
- if (this.correctness === "correct" /* Correct */) {
88
- return;
89
- }
90
88
  const clone = this.cloneNode(true);
91
89
  const containerDiv = document.createElement("div");
92
90
  containerDiv.classList.add("full-correct-response");
@@ -205,4 +203,4 @@ export {
205
203
  Correctness,
206
204
  Interaction
207
205
  };
208
- //# sourceMappingURL=chunk-HFAUM56X.js.map
206
+ //# sourceMappingURL=chunk-P4QBOVQ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/exports/interaction.ts"],"sourcesContent":["import { property, state } from 'lit/decorators.js';\nimport { LitElement } from 'lit';\nimport { consume } from '@lit/context';\n\nimport { configContext } from './config.context.ts';\nimport { itemContext } from './qti-assessment-item.context.ts';\n\nimport type { ConfigContext } from './config.context.ts';\nimport type { ResponseVariable } from './variables';\nimport type { IInteraction } from './interaction.interface';\nimport type { ItemContext } from './item.context.ts';\n\nexport enum Correctness {\n Correct = 'correct',\n PartiallyCorrect = 'partially-correct',\n Incorrect = 'incorrect'\n}\n\nexport abstract class Interaction extends LitElement implements IInteraction {\n @consume({ context: itemContext, subscribe: true })\n private _context: ItemContext;\n\n @consume({ context: configContext, subscribe: true })\n protected configContext: ConfigContext;\n\n static formAssociated = true;\n protected _internals: ElementInternals;\n\n get internals(): ElementInternals {\n return this._internals;\n }\n\n @property({ type: String, attribute: 'response-identifier' }) responseIdentifier;\n\n @property({ reflect: true, type: Boolean }) disabled = false;\n\n @property({ reflect: true, type: Boolean }) readonly = false;\n\n @state()\n protected _isFullCorrectResponse: boolean;\n\n get isFullCorrectResponse(): Readonly<boolean> {\n return this._isFullCorrectResponse;\n }\n\n set isFullCorrectResponse(val: Readonly<boolean>) {\n this._isFullCorrectResponse = val as boolean;\n if (val) {\n this.disabled = true;\n this.setAttribute('response-identifier', this.responseIdentifier + '_cr');\n }\n }\n\n /* PK: Correct response */\n @state()\n protected _correctResponse: string | string[];\n\n get correctResponse(): Readonly<string | string[]> {\n return this._correctResponse;\n }\n\n set correctResponse(val: Readonly<string | string[]>) {\n this._correctResponse = val as string | string[];\n }\n\n get correctness(): Readonly<Correctness | null> {\n const responseVariable = this.responseVariable;\n if (!responseVariable || responseVariable.correctResponse === null) return null;\n\n return responseVariable.correctResponse === responseVariable.value ? Correctness.Correct : Correctness.Incorrect;\n }\n\n get isInline(): boolean {\n return false;\n }\n\n get responseVariable(): ResponseVariable | undefined {\n // Get all response variables\n const responseVariables = this._context.variables.filter(v => v.type === 'response') as ResponseVariable[];\n\n // Get the response identifier for this interaction\n const responseIdentifier = this.getAttribute('response-identifier');\n\n // Return the matching response variable for this interaction\n return responseVariables.find(v => v.identifier === responseIdentifier);\n }\n\n public toggleCorrectResponse(show: boolean): void {\n const correctResponseMode = this?.configContext?.correctResponseMode || 'internal';\n\n if (correctResponseMode === 'full') {\n this.toggleFullCorrectResponse(show);\n } else {\n this.toggleInternalCorrectResponse(show);\n }\n }\n\n protected async toggleFullCorrectResponse(show: boolean): Promise<void> {\n const nextSibling = this.nextSibling;\n const nextSiblingIsFullCorrectResponse =\n nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains('full-correct-response');\n const responseVariable = this.responseVariable;\n\n if (!responseVariable) {\n return;\n }\n\n const showFullCorrectResponse = show && (this?.configContext?.fullCorrectResponseOnlyWhenIncorrect === false || this.correctness !== Correctness.Correct)\n\n if (!showFullCorrectResponse) {\n if (!nextSiblingIsFullCorrectResponse) {\n return;\n }\n // Remove cloned interaction\n this.parentElement?.removeChild(nextSibling);\n }\n\n if (nextSiblingIsFullCorrectResponse) {\n return; // Already exists\n }\n\n\n // Add a clone of interaction with the correct response\n const clone = this.cloneNode(true) as Interaction;\n\n const containerDiv = document.createElement('div');\n containerDiv.classList.add('full-correct-response');\n if (this.isInline) {\n containerDiv.classList.add('full-correct-response-inline');\n } else {\n containerDiv.classList.add('full-correct-response-block');\n }\n containerDiv.role = 'full-correct-response';\n containerDiv.appendChild(clone);\n\n clone.isFullCorrectResponse = true;\n\n this.parentElement?.insertBefore(containerDiv, this.nextSibling);\n await clone.updateComplete;\n\n clone.response = Array.isArray(responseVariable.correctResponse)\n ? ([...responseVariable.correctResponse] as string[])\n : (responseVariable.correctResponse as string);\n }\n\n protected toggleInternalCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n\n this.correctResponse = show\n ? responseVariable?.correctResponse\n : responseVariable?.cardinality === 'single'\n ? ''\n : [];\n }\n\n public toggleCandidateCorrection(show: boolean): void {\n const responseVariable = this.responseVariable;\n if (!responseVariable) return;\n\n this._internals.states.delete('candidate-correct');\n this._internals.states.delete('candidate-partially-correct');\n this._internals.states.delete('candidate-incorrect');\n\n if (!show) {\n return;\n }\n\n if (this.correctness === Correctness.Correct) {\n this._internals.states.add('candidate-correct');\n }\n if (this.correctness === Correctness.PartiallyCorrect) {\n this._internals.states.add('candidate-partially-correct');\n }\n if (this.correctness === Correctness.Incorrect) {\n this._internals.states.add('candidate-incorrect');\n }\n }\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n abstract validate(): boolean;\n\n get value(): string | null {\n return JSON.stringify(this.response);\n }\n\n set value(val: string | null) {\n this.response = val ? JSON.parse(val) : null;\n }\n\n abstract get response(): string | string[] | null;\n abstract set response(val: string | string[] | null);\n\n public reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n public reset(): void {\n this.response = null;\n }\n\n // attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n // super.attributeChangedCallback(name, _old, value);\n // // changing attributes in lit is not a thing, they are defined in the QTI XML and will never change\n // // except in storybook where we can change the value of the attribute\n // // this can make the internal state out of sync with the attribute\n // // so we reset the value to null to force the internal state to be reset\n // const attributeNamesToExclude = ['style', 'class'];\n // if (!attributeNamesToExclude.includes(name)) {\n // this.reset();\n // }\n // }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n\n if (this.isFullCorrectResponse) {\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent('qti-register-interaction', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n interactionElement: this,\n responseIdentifier: this.responseIdentifier\n }\n })\n );\n }\n\n public saveResponse(value: string | string[]): void {\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n responseIdentifier: this.responseIdentifier,\n response: Array.isArray(value) ? [...value] : value\n }\n })\n );\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,UAAU,aAAa;AAChC,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAUjB,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,sBAAmB;AACnB,EAAAA,aAAA,eAAY;AAHF,SAAAA;AAAA,GAAA;AAML,IAAe,cAAf,cAAmC,WAAmC;AAAA,EAgK3E,cAAc;AACZ,UAAM;AAjJoC,oBAAW;AAEX,oBAAW;AAgJrD,SAAK,aAAa,KAAK,gBAAgB;AAAA,EACzC;AAAA,EA5JA;AAAA,SAAO,iBAAiB;AAAA;AAAA,EAGxB,IAAI,YAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAWA,IAAI,wBAA2C;AAC7C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,sBAAsB,KAAwB;AAChD,SAAK,yBAAyB;AAC9B,QAAI,KAAK;AACP,WAAK,WAAW;AAChB,WAAK,aAAa,uBAAuB,KAAK,qBAAqB,KAAK;AAAA,IAC1E;AAAA,EACF;AAAA,EAMA,IAAI,kBAA+C;AACjD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,gBAAgB,KAAkC;AACpD,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,IAAI,cAA4C;AAC9C,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,oBAAoB,iBAAiB,oBAAoB,KAAM,QAAO;AAE3E,WAAO,iBAAiB,oBAAoB,iBAAiB,QAAQ,0BAAsB;AAAA,EAC7F;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,mBAAiD;AAEnD,UAAM,oBAAoB,KAAK,SAAS,UAAU,OAAO,OAAK,EAAE,SAAS,UAAU;AAGnF,UAAM,qBAAqB,KAAK,aAAa,qBAAqB;AAGlE,WAAO,kBAAkB,KAAK,OAAK,EAAE,eAAe,kBAAkB;AAAA,EACxE;AAAA,EAEO,sBAAsB,MAAqB;AAChD,UAAM,sBAAsB,MAAM,eAAe,uBAAuB;AAExE,QAAI,wBAAwB,QAAQ;AAClC,WAAK,0BAA0B,IAAI;AAAA,IACrC,OAAO;AACL,WAAK,8BAA8B,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAgB,0BAA0B,MAA8B;AACtE,UAAM,cAAc,KAAK;AACzB,UAAM,mCACJ,uBAAuB,kBAAkB,aAAa,UAAU,SAAS,uBAAuB;AAClG,UAAM,mBAAmB,KAAK;AAE9B,QAAI,CAAC,kBAAkB;AACrB;AAAA,IACF;AAEA,UAAM,0BAA0B,SAAS,MAAM,eAAe,yCAAyC,SAAS,KAAK,gBAAgB;AAErI,QAAI,CAAC,yBAAyB;AAC5B,UAAI,CAAC,kCAAkC;AACrC;AAAA,MACF;AAEA,WAAK,eAAe,YAAY,WAAW;AAAA,IAC7C;AAEA,QAAI,kCAAkC;AACpC;AAAA,IACF;AAIA,UAAM,QAAQ,KAAK,UAAU,IAAI;AAEjC,UAAM,eAAe,SAAS,cAAc,KAAK;AACjD,iBAAa,UAAU,IAAI,uBAAuB;AAClD,QAAI,KAAK,UAAU;AACjB,mBAAa,UAAU,IAAI,8BAA8B;AAAA,IAC3D,OAAO;AACL,mBAAa,UAAU,IAAI,6BAA6B;AAAA,IAC1D;AACA,iBAAa,OAAO;AACpB,iBAAa,YAAY,KAAK;AAE9B,UAAM,wBAAwB;AAE9B,SAAK,eAAe,aAAa,cAAc,KAAK,WAAW;AAC/D,UAAM,MAAM;AAEZ,UAAM,WAAW,MAAM,QAAQ,iBAAiB,eAAe,IAC1D,CAAC,GAAG,iBAAiB,eAAe,IACpC,iBAAiB;AAAA,EACxB;AAAA,EAEU,8BAA8B,MAAqB;AAC3D,UAAM,mBAAmB,KAAK;AAE9B,SAAK,kBAAkB,OACnB,kBAAkB,kBAClB,kBAAkB,gBAAgB,WAChC,KACA,CAAC;AAAA,EACT;AAAA,EAEO,0BAA0B,MAAqB;AACpD,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,iBAAkB;AAEvB,SAAK,WAAW,OAAO,OAAO,mBAAmB;AACjD,SAAK,WAAW,OAAO,OAAO,6BAA6B;AAC3D,SAAK,WAAW,OAAO,OAAO,qBAAqB;AAEnD,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB,yBAAqB;AAC5C,WAAK,WAAW,OAAO,IAAI,mBAAmB;AAAA,IAChD;AACA,QAAI,KAAK,gBAAgB,4CAA8B;AACrD,WAAK,WAAW,OAAO,IAAI,6BAA6B;AAAA,IAC1D;AACA,QAAI,KAAK,gBAAgB,6BAAuB;AAC9C,WAAK,WAAW,OAAO,IAAI,qBAAqB;AAAA,IAClD;AAAA,EACF;AAAA,EASA,IAAI,QAAuB;AACzB,WAAO,KAAK,UAAU,KAAK,QAAQ;AAAA,EACrC;AAAA,EAEA,IAAI,MAAM,KAAoB;AAC5B,SAAK,WAAW,MAAM,KAAK,MAAM,GAAG,IAAI;AAAA,EAC1C;AAAA,EAKO,iBAA0B;AAC/B,WAAO,KAAK,WAAW,eAAe;AAAA,EACxC;AAAA,EAEO,QAAc;AACnB,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcgB,oBAA0B;AACxC,UAAM,kBAAkB;AAExB,QAAI,KAAK,uBAAuB;AAC9B;AAAA,IACF;AAEA,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B;AAAA,QAC1C,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,UACN,oBAAoB;AAAA,UACpB,oBAAoB,KAAK;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEO,aAAa,OAAgC;AAClD,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B;AAAA,QAC1C,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,UACN,oBAAoB,KAAK;AAAA,UACzB,UAAU,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI;AAAA,QAChD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AArOU;AAAA,EADP,QAAQ,EAAE,SAAS,aAAa,WAAW,KAAK,CAAC;AAAA,GAD9B,YAEZ;AAGE;AAAA,EADT,QAAQ,EAAE,SAAS,eAAe,WAAW,KAAK,CAAC;AAAA,GAJhC,YAKV;AASoD;AAAA,EAA7D,SAAS,EAAE,MAAM,QAAQ,WAAW,sBAAsB,CAAC;AAAA,GAdxC,YAc0C;AAElB;AAAA,EAA3C,SAAS,EAAE,SAAS,MAAM,MAAM,QAAQ,CAAC;AAAA,GAhBtB,YAgBwB;AAEA;AAAA,EAA3C,SAAS,EAAE,SAAS,MAAM,MAAM,QAAQ,CAAC;AAAA,GAlBtB,YAkBwB;AAGlC;AAAA,EADT,MAAM;AAAA,GApBa,YAqBV;AAgBA;AAAA,EADT,MAAM;AAAA,GApCa,YAqCV;","names":["Correctness"]}
@@ -21,13 +21,13 @@ import {
21
21
  } from "./chunk-CJADUWEC.js";
22
22
  import {
23
23
  Interaction
24
- } from "./chunk-HFAUM56X.js";
24
+ } from "./chunk-P4QBOVQ2.js";
25
25
  import {
26
26
  itemContext
27
27
  } from "./chunk-NJNQOQUU.js";
28
28
  import {
29
29
  configContext
30
- } from "./chunk-ERYHQVOT.js";
30
+ } from "./chunk-BHJSX3Q6.js";
31
31
  import {
32
32
  itemContextVariables
33
33
  } from "./chunk-JQ6HWGRY.js";
@@ -6267,9 +6267,12 @@ var QtiTextEntryInteraction = class extends Interaction {
6267
6267
  }
6268
6268
  get correctness() {
6269
6269
  const responseVariable = this.responseVariable;
6270
- if (!responseVariable || responseVariable.value === null) {
6270
+ if (!responseVariable) {
6271
6271
  return null;
6272
6272
  }
6273
+ if (responseVariable.value === null) {
6274
+ return "incorrect" /* Incorrect */;
6275
+ }
6273
6276
  if (responseVariable.mapping) {
6274
6277
  const maxScore = responseVariable.mapping.mapEntries.reduce(
6275
6278
  (currentMax, mapEntry) => Math.max(mapEntry.mappedValue, currentMax),
@@ -8813,4 +8816,4 @@ export {
8813
8816
  QtiOutcomeDeclaration,
8814
8817
  QtiResponseDeclaration
8815
8818
  };
8816
- //# sourceMappingURL=chunk-7YO5JFT3.js.map
8819
+ //# sourceMappingURL=chunk-TWFYYDV7.js.map