PageSourceSearch

https://mavrxlab.org/

html mavrxlab.org collected 2026-10-06 13:17:23 UTC 32,002 bytes, 831 lines download raw bytes

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>&nbsp;<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 &amp; 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.&nbsp;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.&nbsp;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.&nbsp;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.