Click and drag between boxes to create connections.
\n
Use the tab key to navigate to a box and press Enter to select it. Focus then jumps to the other column; tab to the box you want to connect and press Enter. Press Escape to cancel a selection.
\n
Click on a connection line to remove it. You can also use the tab key to select lines. Press the delete key to remove a selected line.
\n
Click the "Check Me" button to check your connections, and save your work.
\n
Click the "Reset" button to clear all connections.
\n
',this.containerDiv.appendChild(this.helpModal),this.helpModal.querySelector(".help-close").addEventListener("click",(()=>this.hideHelp()))}showHelp(){this.helpModal.style.display="flex"}hideHelp(){this.helpModal.style.display="none"}shuffle(t){for(let e=t.length-1;e>0;e--){const n=Math.floor(Math.random()*(e+1));[t[e],t[n]]=[t[n],t[e]]}return t}renderBoxes(){this.boxData.left.forEach((({id:t,label:e})=>{const n=this.createBox(t,e,"drag");this.leftColumn.appendChild(n),this.allBoxes.push(n)})),this.boxData.right.forEach((({id:t,label:e})=>{const n=this.createBox(t,e,"drop");this.rightColumn.appendChild(n),this.allBoxes.push(n)}));const t=Array.from(this.workspace.querySelectorAll("img"));0===t.length&&this.boxesRenderedResolve();const e=t.map((t=>"function"==typeof t.decode?t.decode():t.complete&&0!==t.naturalWidth?Promise.resolve():new Promise((e=>{t.addEventListener("load",(()=>e())),t.addEventListener("error",(()=>e()))}))));Promise.all(e).then((()=>{this.boxesRenderedResolve()}))}createBox(t,e,n){const o=document.createElement("div");return o.className="box",o.dataset.id=t,o.dataset.role=n,o.innerHTML=e,o.tabIndex=0,o.setAttribute("role","button"),o.setAttribute("aria-label",`${"drag"===n?"Draggable":"Droppable"}: ${e}`),o}getCenter(t){const e=t.getBoundingClientRect(),n=this.workspace.getBoundingClientRect();return{x:e.left-n.left+e.width/2,y:e.top-n.top+e.height/2}}getRightBoxCenter(t){const e=t.getBoundingClientRect(),n=this.workspace.getBoundingClientRect();return{x:e.left-n.left+e.width,y:e.top-n.top+e.height/2}}getLeftBoxCenter(t){const e=t.getBoundingClientRect(),n=this.workspace.getBoundingClientRect();return{x:e.left-n.left,y:e.top-n.top+e.height/2}}getPortCenter(t){return"drop"===t.dataset.role?this.getLeftBoxCenter(t):this.getRightBoxCenter(t)}setLineEndpoints(t,e,n){const o=Math.max(30,Math.abs(n.x-e.x)/2),s=n.x>=e.x?1:-1;t.setAttribute("d",`M ${e.x} ${e.y} C ${e.x+s*o} ${e.y}, ${n.x-s*o} ${n.y}, ${n.x} ${n.y}`)}createLineElement(t,e){const n=document.createElementNS("http://www.w3.org/2000/svg","path");return this.setLineEndpoints(n,t,e),n.setAttribute("class","line"),n.setAttribute("tabindex","0"),n.setAttribute("focusable","true"),n.setAttribute("role","button"),n.setAttribute("aria-label","Connection line. Press Delete to remove."),n.addEventListener("click",(()=>{this.removeLine(n)})),n.addEventListener("keydown",(t=>{"Delete"!==t.key&&"Backspace"!==t.key||(t.preventDefault(),this.removeLine(n))})),n}removeLine(t){this.svg.removeChild(t);const e=this.connections.findIndex((e=>e.fromBox===t.fromBox&&e.toBox===t.toBox||e.fromBox===t.toBox&&e.toBox===t.fromBox));-1!==e&&this.connections.splice(e,1),this.updateConnectionModel()}isConnected(t,e){return this.connections.some((n=>n.fromBox===t&&n.toBox===e||n.fromBox===e&&n.toBox===t))}createPermanentLine(t,e){if(t.dataset.role===e.dataset.role)return this.flashInvalid(t,e),this.ariaLive&&(this.ariaLive.textContent="Connections must go between the left column and the right column."),!1;if("drop"===t.dataset.role&&([t,e]=[e,t]),this.isConnected(t,e))return!1;const n=this.getRightBoxCenter(t),o=this.getLeftBoxCenter(e),s=this.createLineElement(n,o);return s.fromBox=t,s.toBox=e,this.svg.appendChild(s),this.connections.push({fromBox:t,toBox:e,line:s}),this.updateConnectionModel(),this.isAnswered=!0,this.ariaLive&&(this.ariaLive.textContent=`Connected ${t.textContent} to ${e.textContent}`),!0}flashInvalid(...t){t.forEach((t=>{t.classList.add("invalid"),setTimeout((()=>t.classList.remove("invalid")),500)}))}updateConnectionModel(){if(this.allBoxes.forEach((t=>t.classList.remove("match-correct","match-incorrect"))),this.connList.innerHTML="Connections:",0===this.connections.length){const t=document.createElement("div");return t.className="conn-entry conn-empty",t.textContent="No connections yet. Drag between boxes to connect them.",void this.connList.appendChild(t)}this.connections.forEach((t=>{t.line&&t.line.classList.remove("correct","incorrect");const e=t.fromBox.textContent;let n=t.toBox.textContent;n||(n=t.toBox.querySelector("img").alt);const o=document.createElement("div");o.className="conn-entry",o.textContent=`${e} → ${n}`,this.connList.appendChild(o)}))}gradeConnections(){this.checkCurrentAnswer(),this.renderFeedback(),this.logCurrentAnswer(),this.setLocalStorage()}resetConnections(){this.connections.forEach((t=>{t.line&&t.line.parentNode===this.svg&&this.svg.removeChild(t.line)})),this.connections.length=0,this.updateConnectionModel(),this.ariaLive&&(this.ariaLive.textContent="All connections have been cleared."),this.logBookEvent({event:"matching_reset",div_id:this.divid,act:"reset all connections"})}attachEvents(){this.allBoxes.forEach((t=>{t.addEventListener("pointerdown",(e=>{e.preventDefault(),this.startBox=t;const n=this.getPortCenter(this.startBox);this.tempLine=this.createLineElement(n,n),this.tempLine.classList.add("temp"),this.svg.appendChild(this.tempLine),document.addEventListener("pointermove",this.updateTempLine),document.addEventListener("pointerup",this.finishConnection)})),t.addEventListener("keydown",(e=>{if("Enter"===e.key)if(e.preventDefault(),this.selectedBox){t!==this.selectedBox&&this.createPermanentLine(this.selectedBox,t),this.selectedBox.classList.remove("selected"),this.selectedBox=null;const e=this.allBoxes.indexOf(t),n=this.allBoxes[e+1];n?n.focus():this.allBoxes[0].focus()}else{this.selectedBox=t,t.classList.add("selected");const e=this.allBoxes.find((e=>e.dataset.role!==t.dataset.role));e&&e.focus(),this.ariaLive&&(this.ariaLive.textContent=`Selected ${t.textContent}. Tab to a box in the other column and press Enter to connect, or press Escape to cancel.`)}else if("Escape"===e.key&&this.selectedBox){e.preventDefault();const t=this.selectedBox;t.classList.remove("selected"),this.selectedBox=null,t.focus(),this.ariaLive&&(this.ariaLive.textContent="Selection cancelled.")}})),t.addEventListener("mouseenter",(()=>{this.connections.forEach((e=>{e.fromBox===t||e.toBox===t?(e.line.classList.add("highlighted"),e.line.classList.remove("faded")):(e.line.classList.add("faded"),e.line.classList.remove("highlighted"))}))})),t.addEventListener("mouseleave",(()=>{this.connections.forEach((t=>{t.line.classList.remove("highlighted","faded")}))}))})),window.addEventListener("resize",(()=>{this.connections.forEach((t=>{const e=this.getRightBoxCenter(t.fromBox),n=this.getLeftBoxCenter(t.toBox);this.setLineEndpoints(t.line,e,n)}))}))}updateTempLine=t=>{if(t.preventDefault(),!this.startBox||!this.tempLine)return;const e=this.getPortCenter(this.startBox),n=this.workspace.getBoundingClientRect(),o={x:t.clientX-n.left,y:t.clientY-n.top};this.setLineEndpoints(this.tempLine,e,o)};finishConnection=t=>{t.preventDefault(),this.tempLine&&(this.svg.removeChild(this.tempLine),this.tempLine=null);const e=t.clientX||t.changedTouches&&t.changedTouches[0].clientX,n=t.clientY||t.changedTouches&&t.changedTouches[0].clientY,o=document.elementFromPoint(e,n),s=this.allBoxes.find((t=>t.contains(o)&&t!==this.startBox));this.startBox&&s&&this.createPermanentLine(this.startBox,s)&&this.logBookEvent({event:"matching_connection",div_id:this.divid,act:`connected ${this.startBox.dataset.id} to ${s.dataset.id}`}),this.startBox=null,document.removeEventListener("pointermove",this.updateTempLine),document.removeEventListener("pointerup",this.finishConnection)}}document.addEventListener("runestone:login-complete",(()=>{document.querySelectorAll('[data-component="matching"]').forEach((t=>{if(!t.closest("[data-component=timedAssessment]")){let e={orig:t};window.componentMap[t.id]=new c(e)}}))})),void 0===window.component_factory&&(window.component_factory={}),window.component_factory.matching=function(t){return new c(t)}}}]);
//# sourceMappingURL=566.383db0dedccd8e8f.js.map