1<!DOCTYPE html> 2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head> 3 4<meta charset="utf-8"> 5<meta name="generator" content="quarto-1.6.40"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9 10<title>MA{VR}X Lab</title> 11<style> 12code{white-space: pre-wrap;} 13span.smallcaps{font-variant: small-caps;} 14div.columns{display: flex; gap: min(4vw, 1.5em);} 15div.column{flex: auto; overflow-x: auto;} 16div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 17ul.task-list{list-style: none;} 18ul.task-list li input[type="checkbox"] { 19 width: 0.8em; 20 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 21 vertical-align: middle; 22} 23</style> 24 25
26<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 26
26
27<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 27
27
28<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 28
28
29<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-search/quarto-search.js"></script>
31 32<meta name="quarto:offset" content="./">
33<script src="site_libs/quarto-listing/list.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-listing/quarto-listing.js"></script>
vendor: 1 bytes, line 34
34
35<script src="site_libs/quarto-html/quarto.js"></script>
vendor: 1 bytes, line 35
35
36<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 36
36
37<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-html/anchor.min.js"></script>
38 39<link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> 40<link href="site_libs/quarto-html/quarto-syntax-highlighting-549806ee2085284f45b00abea8c6df48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
41<script src="site_libs/bootstrap/bootstrap.min.js"></script>
41 42<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 43<link href="site_libs/bootstrap/bootstrap-d83fba8907f73068b64e07941be842b2.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light"> 44<link href="site_libs/quarto-contrib/fontawesome6-0.1.0/all.css" rel="stylesheet"> 45<link href="site_libs/quarto-contrib/fontawesome6-0.1.0/latex-fontsize.css" rel="stylesheet">
46<script id="quarto-search-options" type="application/json">{ 47 "location": "navbar", 48 "copy-button": false, 49 "collapse-after": 3, 50 "panel-placement": "end", 51 "type": "overlay", 52 "limit": 50, 53 "keyboard-shortcut": [ 54 "f", 55 "/", 56 "s" 57 ], 58 "show-item-context": false, 59 "language": { 60 "search-no-results-text": "No results", 61 "search-matching-documents-text": "matching documents", 62 "search-copy-link-title": "Copy link to search", 63 "search-hide-matches-text": "Hide additional matches", 64 "search-more-match-text": "more match in this document", 65 "search-more-matches-text": "more matches in this document", 66 "search-clear-button-title": "Clear", 67 "search-text-placeholder": "", 68 "search-detached-cancel-button-title": "Cancel", 69 "search-submit-button-title": "Submit", 70 "search-label": "Search" 71 } 72}</script>
vendor: 1 bytes, line 72
72
73<script> 74 75 window.document.addEventListener("DOMContentLoaded", function (_event) { 76 const listingTargetEl = window.document.querySelector('#listing-news .list'); 77 if (!listingTargetEl) { 78 // No listing discovered, do not attach. 79 return; 80 } 81 82 const options = { 83 valueNames: ['listing-image','listing-date','listing-title','listing-description',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] },{ data: ['listing-file-modified-sort'] }], 84 page: 18, 85 pagination: { item: "<li class='page-item'><a class='page page-link' href='#'></a></li>" }, 86 searchColumns: ["listing-title","listing-author","listing-date","listing-image","listing-description"], 87 }; 88 89 window['quarto-listings'] = window['quarto-listings'] || {}; 90 window['quarto-listings']['listing-news'] = new List('listing-news', options); 91 92 if (window['quarto-listing-loaded']) { 93 window['quarto-listing-loaded'](); 94 } 95 }); 96 97 window.addEventListener('hashchange',() => { 98 if (window['quarto-listing-loaded']) { 99 window['quarto-listing-loaded'](); 100 } 101 }) 102 103 104 window.document.addEventListener("DOMContentLoaded", function (_event) { 105 const listingTargetEl = window.document.querySelector('#listing-projects .list'); 106 if (!listingTargetEl) { 107 // No listing discovered, do not attach. 108 return; 109 } 110 111 const options = { 112 valueNames: ['listing-image','listing-title','listing-description',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] },{ data: ['listing-file-modified-sort'] }], 113 114 searchColumns: ["listing-title","listing-author","listing-image","listing-description"], 115 }; 116 117 window['quarto-listings'] = window['quarto-listings'] || {}; 118 window['quarto-listings']['listing-projects'] = new List('listing-projects', options); 119 120 if (window['quarto-listing-loaded']) { 121 window['quarto-listing-loaded'](); 122 } 123 }); 124 125 window.addEventListener('hashchange',() => { 126 if (window['quarto-listing-loaded']) { 127 window['quarto-listing-loaded'](); 128 } 129 }) 130 </script>
130 131<!-- Proxima Nova reference. --> 132<link href="https://use.typekit.net/emv3zbo.css" rel="stylesheet" crossorigin="anonymous"> 133<!-- Arizona Bootstrap reference. --> 134<link rel="stylesheet" href="https://cdn.digital.arizona.edu/lib/arizona-bootstrap/2.0.19/css/arizona-bootstrap.min.css" crossorigin="anonymous"> 135 136
136<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
136 137
137<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
137 138
139<script type="text/javascript"> 140const typesetMath = (el) => { 141 if (window.MathJax) { 142 // MathJax Typeset 143 window.MathJax.typeset([el]); 144 } else if (window.katex) { 145 // KaTeX Render 146 var mathElements = el.getElementsByClassName("math"); 147 var macros = []; 148 for (var i = 0; i < mathElements.length; i++) { 149 var texText = mathElements[i].firstChild; 150 if (mathElements[i].tagName == "SPAN") { 151 window.katex.render(texText.data, mathElements[i], { 152 displayMode: mathElements[i].classList.contains('display'), 153 throwOnError: false, 154 macros: macros, 155 fleqn: false 156 }); 157 } 158 } 159 } 160} 161window.Quarto = { 162 typesetMath 163}; 164</script>
164 165 166<link rel="stylesheet" href="styles.css"> 167<link rel="alternate" type="application/rss+xml" title="MA{VR}X Lab" href="index.xml" data-external="1"><meta property="og:title" content="MA{VR}X Lab"> 168<meta property="og:description" content="Official site for the University of Arizonaâs MA{VR}X Lab"> 169<meta property="og:image" content="https://mavrxlab.org/news/2023-07-16-kti-c/featured.jpeg"> 170<meta property="og:site_name" content="MA{VR}X Lab"> 171</head> 172 173<body class="nav-fixed"> 174 175<div id="quarto-search-results"></div> 176 <header id="quarto-header" class="headroom fixed-top quarto-banner"> 177 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 178 <div class="navbar-container container-fluid"> 179 <div class="navbar-brand-container mx-auto"> 180 <a class='navbar-brand navbar-brand-logo' href='/'> 181 <img src="./assets/images/big-banner-white.png" alt="MA{VR}X Lab" class="navbar-logo"> 182 </a> 183 </div> 184 <div id="quarto-search" class="" title="Search"></div> 185 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> 186 <span class="navbar-toggler-icon"></span> 187</button> 188 <div class="collapse navbar-collapse" id="navbarCollapse"> 189 <ul class="navbar-nav navbar-nav-scroll me-auto"> 190 <li class="nav-item"> 191 <a aria-current='page' class='nav-link active' href='/'> 192<span class="menu-text">Home</span></a> 193 </li> 194 <li class="nav-item"> 195 <a class="nav-link" href="./about/"> 196<span class="menu-text">About</span></a> 197 </li> 198 <li class="nav-item"> 199 <a class='nav-link' href='/news'> 200<span class="menu-text">News</span></a> 201 </li> 202 <li class="nav-item"> 203 <a class='nav-link' href='/projects'> 204<span class="menu-text">Projects</span></a> 205 </li> 206 <li class="nav-item"> 207 <a class="nav-link" href="./team/"> 208<span class="menu-text">Team</span></a> 209 </li> 210 <li class="nav-item"> 211 <a class="nav-link" href="./resources/"> 212<span class="menu-text">Resources</span></a> 213 </li> 214</ul> 215 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 216 <li class="nav-item compact"> 217 <a class="nav-link" href="./index.xml"> <i class="bi bi-rss" role="img"> 218</i> 219<span class="menu-text"></span></a> 220 </li> 221</ul> 222 </div> <!-- /navcollapse --> 223 <div class="quarto-navbar-tools"> 224</div> 225 </div> <!-- /container-fluid --> 226 </nav> 227</header> 228<!-- content --> 229<header id="title-block-header" class="quarto-title-block"></header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar"> 230<!-- sidebar --> 231<!-- margin-sidebar --> 232 233<!-- main --> 234<main class="content quarto-banner-title-block column-page" id="quarto-document-content"> 235 236 237 238 239<p><img src="assets/images/big-banner.png" class="img-fluid"></p> 240<!--# Verifying lab on Mastodon --> 241<p> <a rel="me" href="https://hci.social/@mavrxlab"></a></p> 242<hr> 243<div> 244 245</div> 246<div class="quarto-layout-panel" data-layout-ncol="2"> 247<div class="quarto-layout-row"> 248<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;"> 249<p>The <strong>M</strong>ixed <strong>A</strong>ugmented <strong>V</strong>i<strong>R</strong>tual e<strong>X</strong>tended (Reality) Laboratory in the College of Applied Science & Technology is the University of Arizonaâs home for research, exploration, and development for alternative and extended reality media and training in southeastern Arizona.</p> 250</div> 251<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;"> 252<p>We take a very broad view of âextended realityâ to include everything from head-mounted displays, volumetric video, digital identity, and more.</p> 253</div> 254</div> 255</div> 256<section id="news" class="level2"> 257<h2 class="anchored" data-anchor-id="news">News</h2> 258<div id="listing-news" class="quarto-listing quarto-listing-container-grid"> 259<div class="list grid quarto-listing-cols-3"> 260<div class="g-col-1" data-index="0" data-categories="dGFsa3M=" data-listing-date-sort="1689811200000" data-listing-file-modified-sort="1738692796107" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="320"> 261<a class='quarto-grid-link' href='/news/2023-07-16-kti-c/'> 262<div class="quarto-grid-item card h-100 card-left"> 263<p class="card-img-top"> 264<img loading="lazy" src="./news/2023-07-16-kti-c/featured.jpeg" class="thumbnail-image card-img" style="height: 150px;"> 265</p> 266<div class="card-body post-contents"> 267<h5 class="no-anchor card-title listing-title"> 268Our Posthuman Learners: AI and the Future of Education 269</h5> 270<div class="card-text listing-description"> 271A talk given by Dr. Straight at the <em>2023 Keystones Together In Cyberspace</em> Summit. 272</div> 273<div class="card-attribution card-text-small end"> 274<div class="listing-date"> 275Jul 20, 2023 276</div> 277</div> 278</div> 279</div> 280</a> 281</div> 282<div class="g-col-1" data-index="1" data-categories="ZWQz" data-listing-date-sort="1680566400000" data-listing-file-modified-sort="1738692796107" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="6" data-listing-word-count-sort="1182"> 283<a class='quarto-grid-link' href='/news/2023-04-04-ed3-toolkit/'> 284<div class="quarto-grid-item card h-100 card-left"> 285<p class="card-img-top"> 286<img loading="lazy" src="./news/2023-04-04-ed3-toolkit/featured.jpeg" class="thumbnail-image card-img" style="height: 150px;"> 287</p> 288<div class="card-body post-contents"> 289<h5 class="no-anchor card-title listing-title"> 290The Ed3 Toolkit 291</h5> 292<div class="card-text listing-description"> 293The resources and guides to accompany the OLC Innovate â23 presentation by Dr. Straight. 294</div> 295<div class="card-attribution card-text-small end"> 296<div class="listing-date"> 297Apr 4, 2023 298</div> 299</div> 300</div> 301</div> 302</a> 303</div> 304<div class="g-col-1" data-index="2" data-categories="dGFsa3MlMkNlZDM=" data-listing-date-sort="1680134400000" data-listing-file-modified-sort="1738692796107" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="3" data-listing-word-count-sort="578"> 305<a class='quarto-grid-link' href='/news/2023-03-30-in23/'> 306<div class="quarto-grid-item card h-100 card-left"> 307<p class="card-img-top"> 308<img loading="lazy" src="./news/2023-03-30-in23/featured.jpeg" class="thumbnail-image card-img" style="height: 150px;"> 309</p> 310<div class="card-body post-contents"> 311<h5 class="no-anchor card-title listing-title">
312The State of Online Learning in Web3: How Educators Understand and Implement Ed3, Blockchain, and Metaversal Technologies 313</h5> 314<div class="card-text listing-description"> 315A talk given by Dr. Straight at the 2023 OLC Innovate conference. 316</div> 317<div class="card-attribution card-text-small end"> 318<div class="listing-date"> 319Mar 30, 2023 320</div> 321</div> 322</div> 323</div> 324</a> 325</div> 326</div> 327<div class="listing-no-matching d-none"> 328No matching items 329</div> 330</div> 331<p><a href='/news'>View all news <i class="fa-solid fa-arrow-right" aria-label="arrow-right"></i></a></p> 332</section> 333<section id="projects" class="level2"> 334<h2 class="anchored" data-anchor-id="projects">Projects</h2> 335<div id="listing-projects" class="quarto-listing quarto-listing-container-grid"> 336<div class="list grid quarto-listing-cols-3"> 337<div class="g-col-1" data-index="0" data-listing-file-modified-sort="1738692796139" data-listing-reading-time-sort="1" data-listing-word-count-sort="97"> 338<a class='quarto-grid-link' href='/projects/ed3/'> 339<div class="quarto-grid-item card h-100 card-left"> 340<p class="card-img-top"> 341<img loading="lazy" src="./projects/ed3/featured.jpeg" class="thumbnail-image card-img" style="height: 150px;"> 342</p> 343<div class="card-body post-contents"> 344<h5 class="no-anchor card-title listing-title"> 345Ed3: Web3 and Education 346</h5> 347<div class="card-text listing-description"> 348<p>This project focuses on so-called Web3 technologies and their influence on and use in education.</p> 349</div> 350</div> 351</div> 352</a> 353</div> 354<div class="g-col-1" data-index="1" data-listing-file-modified-sort="1738692796143" data-listing-reading-time-sort="1" data-listing-word-count-sort="33"> 355<a class='quarto-grid-link' href='/projects/parasocial/'> 356<div class="quarto-grid-item card h-100 card-left"> 357<p class="card-img-top"> 358<img loading="lazy" src="./projects/parasocial/featured.jpeg" class="thumbnail-image card-img" style="height: 150px;"> 359</p> 360<div class="card-body post-contents"> 361<h5 class="no-anchor card-title listing-title"> 362Extended Reality Parasocial Interaction 363</h5> 364<div class="card-text listing-description"> 365<p>A study undertaken to explore the nuanced parasocial interaction and relationships when in extended reality environments.</p> 366</div> 367</div> 368</div> 369</a> 370</div> 371</div> 372<div class="listing-no-matching d-none"> 373No matching items 374</div> 375</div> 376<p><a href='/projects'>View all projects <i class="fa-solid fa-arrow-right" aria-label="arrow-right"></i></a></p> 377 378 379 380</section> 381 382</main> <!-- /main -->
383<script id="quarto-html-after-body" type="application/javascript"> 384window.document.addEventListener("DOMContentLoaded", function (event) { 385 const toggleBodyColorMode = (bsSheetEl) => { 386 const mode = bsSheetEl.getAttribute("data-mode"); 387 const bodyEl = window.document.querySelector("body"); 388 if (mode === "dark") { 389 bodyEl.classList.add("quarto-dark"); 390 bodyEl.classList.remove("quarto-light"); 391 } else { 392 bodyEl.classList.add("quarto-light"); 393 bodyEl.classList.remove("quarto-dark"); 394 } 395 } 396 const toggleBodyColorPrimary = () => { 397 const bsSheetEl = window.document.querySelector("link#quarto-bootstrap"); 398 if (bsSheetEl) { 399 toggleBodyColorMode(bsSheetEl); 400 } 401 } 402 toggleBodyColorPrimary(); 403 const icon = "î§"; 404 const anchorJS = new window.AnchorJS(); 405 anchorJS.options = { 406 placement: 'right', 407 icon: icon 408 }; 409 anchorJS.add('.anchored'); 410 const isCodeAnnotation = (el) => { 411 for (const clz of el.classList) { 412 if (clz.startsWith('code-annotation-')) { 413 return true; 414 } 415 } 416 return false; 417 } 418 const onCopySuccess = function(e) { 419 // button target 420 const button = e.trigger; 421 // don't keep focus 422 button.blur(); 423 // flash "checked" 424 button.classList.add('code-copy-button-checked'); 425 var currentTitle = button.getAttribute("title"); 426 button.setAttribute("title", "Copied!"); 427 let tooltip; 428 if (window.bootstrap) { 429 button.setAttribute("data-bs-toggle", "tooltip"); 430 button.setAttribute("data-bs-placement", "left"); 431 button.setAttribute("data-bs-title", "Copied!"); 432 tooltip = new bootstrap.Tooltip(button, 433 { trigger: "manual", 434 customClass: "code-copy-button-tooltip", 435 offset: [0, -8]}); 436 tooltip.show(); 437 } 438 setTimeout(function() { 439 if (tooltip) { 440 tooltip.hide(); 441 button.removeAttribute("data-bs-title"); 442 button.removeAttribute("data-bs-toggle"); 443 button.removeAttribute("data-bs-placement"); 444 } 445 button.setAttribute("title", currentTitle); 446 button.classList.remove('code-copy-button-checked'); 447 }, 1000); 448 // clear code selection 449 e.clearSelection(); 450 } 451 const getTextToCopy = function(trigger) { 452 const codeEl = trigger.previousElementSibling.cloneNode(true); 453 for (const childEl of codeEl.children) { 454 if (isCodeAnnotation(childEl)) { 455 childEl.remove(); 456 } 457 } 458 return codeEl.innerText; 459 } 460 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 461 text: getTextToCopy 462 }); 463 clipboard.on('success', onCopySuccess); 464 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 465 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 466 text: getTextToCopy, 467 container: window.document.getElementById('quarto-embedded-source-code-modal') 468 }); 469 clipboardModal.on('success', onCopySuccess); 470 } 471 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 472 var mailtoRegex = new RegExp(/^mailto:/); 473 var filterRegex = new RegExp("https:\/\/mavrxlab\.org"); 474 var isInternal = (href) => { 475 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 476 } 477 // Inspect non-navigation links and adorn them if external 478 var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)'); 479 for (var i=0; i<links.length; i++) { 480 const link = links[i]; 481 if (!isInternal(link.href)) { 482 // undo the damage that might have been done by quarto-nav.js in the case of 483 // links that we want to consider external 484 if (link.dataset.originalHref !== undefined) { 485 link.href = link.dataset.originalHref; 486 } 487 } 488 } 489 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 490 const config = { 491 allowHTML: true, 492 maxWidth: 500, 493 delay: 100,
494 arrow: false, 495 appendTo: function(el) { 496 return el.parentElement; 497 }, 498 interactive: true, 499 interactiveBorder: 10, 500 theme: 'quarto', 501 placement: 'bottom-start', 502 }; 503 if (contentFn) { 504 config.content = contentFn; 505 } 506 if (onTriggerFn) { 507 config.onTrigger = onTriggerFn; 508 } 509 if (onUntriggerFn) { 510 config.onUntrigger = onUntriggerFn; 511 } 512 window.tippy(el, config); 513 } 514 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 515 for (var i=0; i<noterefs.length; i++) { 516 const ref = noterefs[i]; 517 tippyHover(ref, function() { 518 // use id or data attribute instead here 519 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 520 try { href = new URL(href).hash; } catch {} 521 const id = href.replace(/^#\/?/, ""); 522 const note = window.document.getElementById(id); 523 if (note) { 524 return note.innerHTML; 525 } else { 526 return ""; 527 } 528 }); 529 } 530 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 531 const processXRef = (id, note) => { 532 // Strip column container classes 533 const stripColumnClz = (el) => { 534 el.classList.remove("page-full", "page-columns"); 535 if (el.children) { 536 for (const child of el.children) { 537 stripColumnClz(child); 538 } 539 } 540 } 541 stripColumnClz(note) 542 if (id === null || id.startsWith('sec-')) { 543 // Special case sections, only their first couple elements 544 const container = document.createElement("div"); 545 if (note.children && note.children.length > 2) { 546 container.appendChild(note.children[0].cloneNode(true)); 547 for (let i = 1; i < note.children.length; i++) { 548 const child = note.children[i]; 549 if (child.tagName === "P" && child.innerText === "") { 550 continue; 551 } else { 552 container.appendChild(child.cloneNode(true)); 553 break; 554 } 555 } 556 if (window.Quarto?.typesetMath) { 557 window.Quarto.typesetMath(container); 558 } 559 return container.innerHTML 560 } else { 561 if (window.Quarto?.typesetMath) { 562 window.Quarto.typesetMath(note); 563 } 564 return note.innerHTML; 565 } 566 } else { 567 // Remove any anchor links if they are present 568 const anchorLink = note.querySelector('a.anchorjs-link'); 569 if (anchorLink) { 570 anchorLink.remove(); 571 } 572 if (window.Quarto?.typesetMath) { 573 window.Quarto.typesetMath(note); 574 } 575 if (note.classList.contains("callout")) { 576 return note.outerHTML; 577 } else { 578 return note.innerHTML; 579 } 580 } 581 } 582 for (var i=0; i<xrefs.length; i++) { 583 const xref = xrefs[i]; 584 tippyHover(xref, undefined, function(instance) { 585 instance.disable(); 586 let url = xref.getAttribute('href'); 587 let hash = undefined; 588 if (url.startsWith('#')) { 589 hash = url; 590 } else { 591 try { hash = new URL(url).hash; } catch {} 592 } 593 if (hash) { 594 const id = hash.replace(/^#\/?/, ""); 595 const note = window.document.getElementById(id); 596 if (note !== null) { 597 try { 598 const html = processXRef(id, note.cloneNode(true)); 599 instance.setContent(html); 600 } finally { 601 instance.enable(); 602 instance.show(); 603 } 604 } else { 605 // See if we can fetch this 606 fetch(url.split('#')[0]) 607 .then(res => res.text()) 608 .then(html => { 609 const parser = new DOMParser(); 610 const htmlDoc = parser.parseFromString(html, "text/html"); 611 const note = htmlDoc.getElementById(id); 612 if (note !== null) { 613 const html = processXRef(id, note); 614 instance.setContent(html); 615 } 616 }).finally(() => { 617 instance.enable(); 618 instance.show(); 619 }); 620 } 621 } else { 622 // See if we can fetch a full url (with no hash to target)
623 // This is a special case and we should probably do some content thinning / targeting 624 fetch(url) 625 .then(res => res.text()) 626 .then(html => { 627 const parser = new DOMParser(); 628 const htmlDoc = parser.parseFromString(html, "text/html"); 629 const note = htmlDoc.querySelector('main.content'); 630 if (note !== null) { 631 // This should only happen for chapter cross references 632 // (since there is no id in the URL) 633 // remove the first header 634 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 635 note.children[0].remove(); 636 } 637 const html = processXRef(null, note); 638 instance.setContent(html); 639 } 640 }).finally(() => { 641 instance.enable(); 642 instance.show(); 643 }); 644 } 645 }, function(instance) { 646 }); 647 } 648 let selectedAnnoteEl; 649 const selectorForAnnotation = ( cell, annotation) => { 650 let cellAttr = 'data-code-cell="' + cell + '"'; 651 let lineAttr = 'data-code-annotation="' + annotation + '"'; 652 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 653 return selector; 654 } 655 const selectCodeLines = (annoteEl) => { 656 const doc = window.document; 657 const targetCell = annoteEl.getAttribute("data-target-cell"); 658 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 659 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 660 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 661 const lineIds = lines.map((line) => { 662 return targetCell + "-" + line; 663 }) 664 let top = null; 665 let height = null; 666 let parent = null; 667 if (lineIds.length > 0) { 668 //compute the position of the single el (top and bottom and make a div) 669 const el = window.document.getElementById(lineIds[0]); 670 top = el.offsetTop; 671 height = el.offsetHeight; 672 parent = el.parentElement.parentElement; 673 if (lineIds.length > 1) { 674 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 675 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 676 height = bottom - top; 677 } 678 if (top !== null && height !== null && parent !== null) { 679 // cook up a div (if necessary) and position it 680 let div = window.document.getElementById("code-annotation-line-highlight"); 681 if (div === null) { 682 div = window.document.createElement("div"); 683 div.setAttribute("id", "code-annotation-line-highlight"); 684 div.style.position = 'absolute'; 685 parent.appendChild(div); 686 } 687 div.style.top = top - 2 + "px"; 688 div.style.height = height + 4 + "px"; 689 div.style.left = 0; 690 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 691 if (gutterDiv === null) { 692 gutterDiv = window.document.createElement("div"); 693 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 694 gutterDiv.style.position = 'absolute'; 695 const codeCell = window.document.getElementById(targetCell); 696 const gutter = codeCell.querySelector('.code-annotation-gutter'); 697 gutter.appendChild(gutterDiv); 698 } 699 gutterDiv.style.top = top - 2 + "px"; 700 gutterDiv.style.height = height + 4 + "px"; 701 } 702 selectedAnnoteEl = annoteEl; 703 } 704 }; 705 const unselectCodeLines = () => { 706 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 707 elementsIds.forEach((elId) => { 708 const div = window.document.getElementById(elId); 709 if (div) { 710 div.remove(); 711 } 712 }); 713 selectedAnnoteEl = undefined; 714 }; 715 // Handle positioning of the toggle 716 window.addEventListener( 717 "resize", 718 throttle(() => { 719 elRect = undefined; 720 if (selectedAnnoteEl) { 721 selectCodeLines(selectedAnnoteEl); 722 } 723 }, 10) 724 ); 725 function throttle(fn, ms) { 726 let throttle = false;
727 let timer; 728 return (...args) => { 729 if(!throttle) { // first call gets through 730 fn.apply(this, args); 731 throttle = true; 732 } else { // all the others get throttled 733 if(timer) clearTimeout(timer); // cancel #2 734 timer = setTimeout(() => { 735 fn.apply(this, args); 736 timer = throttle = false; 737 }, ms); 738 } 739 }; 740 } 741 // Attach click handler to the DT 742 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 743 for (const annoteDlNode of annoteDls) { 744 annoteDlNode.addEventListener('click', (event) => { 745 const clickedEl = event.target; 746 if (clickedEl !== selectedAnnoteEl) { 747 unselectCodeLines(); 748 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 749 if (activeEl) { 750 activeEl.classList.remove('code-annotation-active'); 751 } 752 selectCodeLines(clickedEl); 753 clickedEl.classList.add('code-annotation-active'); 754 } else { 755 // Unselect the line 756 unselectCodeLines(); 757 clickedEl.classList.remove('code-annotation-active'); 758 } 759 }); 760 } 761 const findCites = (el) => { 762 const parentEl = el.parentElement; 763 if (parentEl) { 764 const cites = parentEl.dataset.cites; 765 if (cites) { 766 return { 767 el, 768 cites: cites.split(' ') 769 }; 770 } else { 771 return findCites(el.parentElement) 772 } 773 } else { 774 return undefined; 775 } 776 }; 777 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 778 for (var i=0; i<bibliorefs.length; i++) { 779 const ref = bibliorefs[i]; 780 const citeInfo = findCites(ref); 781 if (citeInfo) { 782 tippyHover(citeInfo.el, function() { 783 var popup = window.document.createElement('div'); 784 citeInfo.cites.forEach(function(cite) { 785 var citeDiv = window.document.createElement('div'); 786 citeDiv.classList.add('hanging-indent'); 787 citeDiv.classList.add('csl-entry'); 788 var biblioDiv = window.document.getElementById('ref-' + cite); 789 if (biblioDiv) { 790 citeDiv.innerHTML = biblioDiv.innerHTML; 791 } 792 popup.appendChild(citeDiv); 793 }); 794 return popup.innerHTML; 795 }); 796 } 797 } 798}); 799</script>
799 800</div> <!-- /content --> 801<footer class="footer"> 802 <div class="nav-footer"> 803 <div class="nav-footer-left"> 804<p><i class="fa-regular fa-copyright" aria-label="copyright"></i> Ryan Straight, 2024<br> All content licensed under <i class="fa-brands fa-creative-commons" aria-label="creative-commons"></i> <i class="fa-brands fa-creative-commons-by" aria-label="creative-commons-by"></i> <i class="fa-brands fa-creative-commons-sa" aria-label="creative-commons-sa"></i> <i class="fa-brands fa-creative-commons-nc" aria-label="creative-commons-nc"></i> <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">(CC BY-NC-SA 4.0)</a></p> 805</div> 806 <div class="nav-footer-center"> 807 <ul class="footer-items list-unstyled"> 808 <li class="nav-item compact"> 809 <a class="nav-link" href="https://github.com/mavrxlab/"> 810 <i class="bi bi-github" role="img" aria-label="GitHub"> 811</i> 812 </a> 813 </li> 814 <li class="nav-item compact"> 815 <a class="nav-link" href="https://hci.social/@mavrxlab/"> 816 <i class="bi bi-mastodon" role="img" aria-label="Mastodon"> 817</i> 818 </a> 819 </li> 820</ul> 821 </div> 822 <div class="nav-footer-right"> 823<p>Made with <i class="fa-brands fa-r-project" aria-label="r-project"></i> and <a href="https://quarto.org/">Quarto</a><br> with much inspiration from <a href="https://github.com/andreashandel/andreashandelwebsite">Andreas Handel</a>.</p> 824</div> 825 </div> 826</footer> 827 828 829 830 831</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.