PageSourceSearch

https://fewslab.netlify.app/teaching

html fewslab.netlify.app collected 2026-10-03 10:43:53 UTC 27,882 bytes, 694 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<!-- This site is hosted on Netlify. Anyone can build and deploy a site
6     like this one for free: https://netlify.new/?utm_campaign=loops&utm_source=ai-legible&utm_medium=owned&utm_content=comment&utm_id=af4360b4-4a70-4cbe-87f6-43fa708bbace
7     Netlify hosting facts for this site: static/SSR served via Netlify Edge. -->
8<meta name="generator" content="quarto-1.9.38">
9
10<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
11
12<meta name="description" content="Dr.&nbsp;Caitlin Grady’s teaching focuses on sustainability, environmental engineering, and policy modeling in complex systems.">
13
14<title>Teaching – FEWsLab</title>
15<style>
16/* Default styles provided by pandoc.
17** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
18*/
19code{white-space: pre-wrap;}
20span.smallcaps{font-variant: small-caps;}
21div.columns{display: flex; gap: min(4vw, 1.5em);}
22div.column{flex: auto; overflow-x: auto;}
23div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
24ul.task-list{list-style: none;}
25ul.task-list li input[type="checkbox"] {
26  width: 0.8em;
27  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
28  vertical-align: middle;
29}
30</style>
31
32
33<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 34
34
35<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 35
35
36<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 36
36
37<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-search/quarto-search.js"></script>
38
39<meta name="quarto:offset" content="./">
40<link href="./images/favicon/favicon.ico" rel="icon">
41<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 41
41
42<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 42
42
43<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 43
43
44<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 44
44
45<script src="site_libs/quarto-html/anchor.min.js"></script>
45
46<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
47<link href="site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css" rel="stylesheet" id="quarto-text-highlighting-styles">
48<script src="site_libs/bootstrap/bootstrap.min.js"></script>
48
49<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
50<link href="site_libs/bootstrap/bootstrap-22f1789df73c9a524649167e87525b34.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
51<script id="quarto-search-options" type="application/json">{
52  "location": "navbar",
53  "copy-button": false,
54  "collapse-after": 3,
55  "panel-placement": "end",
56  "type": "overlay",
57  "limit": 50,
58  "keyboard-shortcut": [
59    "f",
60    "/",
61    "s"
62  ],
63  "language": {
64    "search-no-results-text": "No results",
65    "search-matching-documents-text": "matching documents",
66    "search-copy-link-title": "Copy link to search",
67    "search-hide-matches-text": "Hide additional matches",
68    "search-more-match-text": "more match in this document",
69    "search-more-matches-text": "more matches in this document",
70    "search-clear-button-title": "Clear",
71    "search-text-placeholder": "",
72    "search-detached-cancel-button-title": "Cancel",
73    "search-submit-button-title": "Submit",
74    "search-label": "Search"
75  }
76}</script>
76
77<style>html{ scroll-behavior: smooth; }</style>
78<!-- academic icons -->
79
80<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css">
81
82<!-- altmetric icons -->
83<script type="text/javascript" src="https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js"></script>
83
84
85<!-- fontawesome icons -->
86<script src="https://kit.fontawesome.com/1392a7030f.js" crossorigin="anonymous"></script>
86
87
88
89
90
91</head>
92
93<body class="floating nav-fixed quarto-light">
94
95<div id="quarto-search-results"></div>
96  <header id="quarto-header" class="headroom fixed-top">
97    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
98      <div class="navbar-container container-fluid">
99      <div class="navbar-brand-container mx-auto">
100    <a class='navbar-brand' href='/'>
101    <span class="navbar-title">FEWsLab</span>
102    </a>
103  </div>
104            <div id="quarto-search" class="" title="Search"></div>
105          <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(); }">
106  <span class="navbar-toggler-icon"></span>
107</button>
108          <div class="collapse navbar-collapse" id="navbarCollapse">
109            <ul class="navbar-nav navbar-nav-scroll ms-auto">
110  <li class="nav-item">
111    <a class='nav-link' href='/about'> 
112<span class="menu-text">About</span></a>
113  </li>  
114  <li class="nav-item">
115    <a class='nav-link' href='/lab'> 
116<span class="menu-text">Team</span></a>
117  </li>  
118  <li class="nav-item">
119    <a class='nav-link' href='/research'> 
120<span class="menu-text">News &amp; Publications</span></a>
121  </li>  
122  <li class="nav-item">
123    <a aria-current='page' class='nav-link active' href='/teaching'> 
124<span class="menu-text">Teaching</span></a>
125  </li>  
126  <li class="nav-item">
127    <a class='nav-link' href='/projects'> 
128<span class="menu-text">Projects</span></a>
129  </li>  
130</ul>
131          </div> <!-- /navcollapse -->
132            <div class="quarto-navbar-tools">
133</div>
134      </div> <!-- /container-fluid -->
135    </nav>
136</header>
137<!-- content -->
138<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
139<!-- sidebar -->
140  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto">
141    <nav id="TOC" role="doc-toc" class="toc-active">
142    <h2 id="toc-title">Courses</h2>
143   
144  <ul>
145  <li><a href="#teaching-philosophy" id="toc-teaching-philosophy" class="nav-link active" data-scroll-target="#teaching-philosophy">Teaching Philosophy</a></li>
146  <li><a href="#current-course-instruction" id="toc-current-course-instruction" class="nav-link" data-scroll-target="#current-course-instruction">Current Course Instruction</a></li>
147  </ul>
148</nav>
149</nav>
150<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
151<!-- margin-sidebar -->
152    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar zindex-bottom">
153    </div>
154<!-- main -->
155<main class="content" id="quarto-document-content">
156
157<header id="title-block-header" class="quarto-title-block default">
158<div class="quarto-title">
159<h1 class="title">Teaching</h1>
160</div>
161
162<div>
163  <div class="description">
164    Dr.&nbsp;Caitlin Grady’s teaching focuses on sustainability, environmental engineering, and policy modeling in complex systems.
165  </div>
166</div>
167
168
169<div class="quarto-title-meta">
170
171    
172  
173    
174  </div>
175  
176
177
178</header>
179
180
181<section id="teaching-philosophy" class="level3">
182<h3 class="anchored" data-anchor-id="teaching-philosophy">Teaching Philosophy</h3>
183<p>Dr.&nbsp;Grady’s teaching interests include a variety of systems engineering, engineering design, and environmental policy courses. Her pedagogy blends active learning and problem-based learning approaches, combining student-centered instruction with real-world problems. These methods emphasize critical thinking and the application of technical knowledge to transdisciplinary topics.</p>
184<p>In recent years, she has taught and guest lectured in several courses, including:</p>
185<ul>
186<li>Global Environmental Politics<br>
187</li>
188<li>Communicating with Policymakers<br>
189</li>
190<li>Global Sustainable Engineering<br>
191</li>
192<li>Engineering Environmental Sustainability<br>
193</li>
194<li>Water &amp; Wastewater Treatment<br>
195</li>
196<li>Introduction to Sustainable Water Resources<br>
197</li>
198<li>Introduction to Environmental Engineering</li>
199</ul>
200<hr>
201</section>
202<section id="current-course-instruction" class="level3">
203<h3 class="anchored" data-anchor-id="current-course-instruction">Current Course Instruction</h3>
204<section id="emse-6740-systems-thinking-and-policy-modeling-i-3-credits" class="level4">
205<h4 class="anchored">EMSE 6740: Systems Thinking and Policy Modeling I (3 Credits)</h4>
206<div class="grid">
207<div class="g-col-9">
208<p><strong>Institution</strong>: The George Washington University<br>
209<strong>Semester</strong>: Every Spring</p>
210<p>Policy analysis with applications to business management and public policy. Topics include causal-loop diagrams, stock and flow models of business, technology adoption, and marketing. The course incorporates role-based games to explore principles of systems thinking and uses simulation to analyze complex case studies.</p>
211<section id="emse-1001-introduction-to-systems-engineering-1-credit" class="level4">
212<h4 class="anchored" data-anchor-id="emse-1001-introduction-to-systems-engineering-1-credit">EMSE 1001: Introduction to Systems Engineering (1 Credit)</h4>
213<div class="grid">
214<div class="g-col-9">
215<p><strong>Institution</strong>: The George Washington University<br>
216<strong>Semester</strong>: Every Fall</p>
217<p>Core concepts in systems engineering; processes of system decomposition and integration; upfront conceptual design, rapid prototyping, structured testing, balanced work, lean processes, and design for manufacturability.</p>
218</div>
219</div>
220<hr>
221</section>
222<section id="past-courses-taught" class="level3">
223<h3 class="anchored" data-anchor-id="past-courses-taught">Past Courses Taught</h3>
224<section id="ce-360-fluid-mechanics" class="level4">
225<h4 class="anchored" data-anchor-id="ce-360-fluid-mechanics">CE 360: Fluid Mechanics</h4>
226<div class="grid">
227<div class="g-col-9">
228<p><strong>Institution</strong>: Penn State University, University Park<br>
229<strong>Semesters</strong>: Fall 2017, Spring 2019, Spring 2020</p>
230</div>
231</div>
232</section>
233<section id="ce-597-ethics-engineering-and-environmental-management" class="level4">
234<h4 class="anchored" data-anchor-id="ce-597-ethics-engineering-and-environmental-management">CE 597: Ethics, Engineering, and Environmental Management</h4>
235<div class="grid">
236<div class="g-col-9">
237<p><strong>Institution</strong>: Penn State University, University Park<br>
238<strong>Semesters</strong>: Spring 2018, Spring 2019, Spring 2020</p>
239</div>
240</div>
241<hr>
242</section>
243</section>
244<section id="research-to-advance-teaching" class="level3">
245<h3 class="anchored" data-anchor-id="research-to-advance-teaching">Research to Advance Teaching</h3>
246<p><img src="images/teaching.png" class="img-fluid" style="width:100.0%"></p>
247<div class="grid">
248<div class="g-col-9">
249<p>Dr.&nbsp;Grady has secured <em>National Science Foundation</em> funding to advance understanding around teaching ethics. She is currently working on a multi-year award to develop engaged student learning through coupled ethical-epistemic pedagogy. More about the award can be found <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2314334&amp;HistoricalAwards=false">here</a></p>
250</div>
251</div>
252
253
254</section>
255</div>
256</div>
257</section>
258</section>
259
260</main> <!-- /main -->
261<script id="quarto-html-after-body" type="application/javascript">
262  window.document.addEventListener("DOMContentLoaded", function (event) {
263    const icon = "";
264    const anchorJS = new window.AnchorJS();
265    anchorJS.options = {
266      placement: 'right',
267      icon: icon
268    };
269    anchorJS.add('.anchored');
270    const isCodeAnnotation = (el) => {
271      for (const clz of el.classList) {
272        if (clz.startsWith('code-annotation-')) {                     
273          return true;
274        }
275      }
276      return false;
277    }
278    const onCopySuccess = function(e) {
279      // button target
280      const button = e.trigger;
281      // don't keep focus
282      button.blur();
283      // flash "checked"
284      button.classList.add('code-copy-button-checked');
285      var currentTitle = button.getAttribute("title");
286      button.setAttribute("title", "Copied!");
287      let tooltip;
288      if (window.bootstrap) {
289        button.setAttribute("data-bs-toggle", "tooltip");
290        button.setAttribute("data-bs-placement", "left");
291        button.setAttribute("data-bs-title", "Copied!");
292        tooltip = new bootstrap.Tooltip(button, 
293          { trigger: "manual", 
294            customClass: "code-copy-button-tooltip",
295            offset: [0, -8]});
296        tooltip.show();    
297      }
298      setTimeout(function() {
299        if (tooltip) {
300          tooltip.hide();
301          button.removeAttribute("data-bs-title");
302          button.removeAttribute("data-bs-toggle");
303          button.removeAttribute("data-bs-placement");
304        }
305        button.setAttribute("title", currentTitle);
306        button.classList.remove('code-copy-button-checked');
307      }, 1000);
308      // clear code selection
309      e.clearSelection();
310    }
311    const getTextToCopy = function(trigger) {
312      const outerScaffold = trigger.parentElement.cloneNode(true);
313      const codeEl = outerScaffold.querySelector('code');
314      for (const childEl of codeEl.children) {
315        if (isCodeAnnotation(childEl)) {
316          childEl.remove();
317        }
318      }
319      return codeEl.innerText;
320    }
321    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
322      text: getTextToCopy
323    });
324    clipboard.on('success', onCopySuccess);
325    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
326      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
327        text: getTextToCopy,
328        container: window.document.getElementById('quarto-embedded-source-code-modal')
329      });
330      clipboardModal.on('success', onCopySuccess);
331    }
332      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
333      var mailtoRegex = new RegExp(/^mailto:/);
334        var filterRegex = new RegExp("https:\/\/fewslab\.netlify\.app");
335      var isInternal = (href) => {
336          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
337      }
338      // Inspect non-navigation links and adorn them if external
339     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)');
340      for (var i=0; i<links.length; i++) {
341        const link = links[i];
342        if (!isInternal(link.href)) {
343          // undo the damage that might have been done by quarto-nav.js in the case of
344          // links that we want to consider external
345          if (link.dataset.originalHref !== undefined) {
346            link.href = link.dataset.originalHref;
347          }
348            // target, if specified
349            link.setAttribute("target", "_blank");
350            if (link.getAttribute("rel") === null) {
351              link.setAttribute("rel", "noopener");
352            }
353        }
354      }
355    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
356      const config = {
357        allowHTML: true,
358        maxWidth: 500,
359        delay: 100,
360        arrow: false,
361        appendTo: function(el) {
362            return el.parentElement;
363        },
364        interactive: true,
365        interactiveBorder: 10,
366        theme: 'quarto',
367        placement: 'bottom-start',
368      };
369      if (contentFn) {
370        config.content = contentFn;
371      }
372      if (onTriggerFn) {
373        config.onTrigger = onTriggerFn;
374      }
375      if (onUntriggerFn) {
376        config.onUntrigger = onUntriggerFn;
377      }
378      window.tippy(el, config); 
379    }
380    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
381    for (var i=0; i<noterefs.length; i++) {
382      const ref = noterefs[i];
383      tippyHover(ref, function() {
384        // use id or data attribute instead here
385        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
386        try { href = new URL(href).hash; } catch {}
387        const id = href.replace(/^#\/?/, "");
388        const note = window.document.getElementById(id);
389        if (note) {
390          return note.innerHTML;
391        } else {
392          return "";
393        }
394      });
395    }
396    const xrefs = window.document.querySelectorAll('a.quarto-xref');
397    const processXRef = (id, note) => {
398      // Strip column container classes
399      const stripColumnClz = (el) => {
400        el.classList.remove("page-full", "page-columns");
401        if (el.children) {
402          for (const child of el.children) {
403            stripColumnClz(child);
404          }
405        }
406      }
407      stripColumnClz(note)
408      if (id === null || id.startsWith('sec-')) {
409        // Special case sections, only their first couple elements
410        const container = document.createElement("div");
411        if (note.children && note.children.length > 2) {
412          container.appendChild(note.children[0].cloneNode(true));
413          for (let i = 1; i < note.children.length; i++) {
414            const child = note.children[i];
415            if (child.tagName === "P" && child.innerText === "") {
416              continue;
417            } else {
418              container.appendChild(child.cloneNode(true));
419              break;
420            }
421          }
422          if (window.Quarto?.typesetMath) {
423            window.Quarto.typesetMath(container);
424          }
425          return container.innerHTML
426        } else {
427          if (window.Quarto?.typesetMath) {
428            window.Quarto.typesetMath(note);
429          }
430          return note.innerHTML;
431        }
432      } else {
433        // Remove any anchor links if they are present
434        const anchorLink = note.querySelector('a.anchorjs-link');
435        if (anchorLink) {
436          anchorLink.remove();
437        }
438        if (window.Quarto?.typesetMath) {
439          window.Quarto.typesetMath(note);
440        }
441        if (note.classList.contains("callout")) {
442          return note.outerHTML;
443        } else {
444          return note.innerHTML;
445        }
446      }
447    }
448    for (var i=0; i<xrefs.length; i++) {
449      const xref = xrefs[i];
450      tippyHover(xref, undefined, function(instance) {
451        instance.disable();
452        let url = xref.getAttribute('href');
453        let hash = undefined; 
454        if (url.startsWith('#')) {
455          hash = url;
456        } else {
457          try { hash = new URL(url).hash; } catch {}
458        }
459        if (hash) {
460          const id = hash.replace(/^#\/?/, "");
461          const note = window.document.getElementById(id);
462          if (note !== null) {
463            try {
464              const html = processXRef(id, note.cloneNode(true));
465              instance.setContent(html);
466            } finally {
467              instance.enable();
468              instance.show();
469            }
470          } else {
471            // See if we can fetch this
472            fetch(url.split('#')[0])
473            .then(res => res.text())
474            .then(html => {
475              const parser = new DOMParser();
476              const htmlDoc = parser.parseFromString(html, "text/html");
477              const note = htmlDoc.getElementById(id);
478              if (note !== null) {
479                const html = processXRef(id, note);
480                instance.setContent(html);
481              } 
482            }).finally(() => {
483              instance.enable();
484              instance.show();
485            });
486          }
487        } else {
488          // See if we can fetch a full url (with no hash to target)
489          // This is a special case and we should probably do some content thinning / targeting
490          fetch(url)
491          .then(res => res.text())
492          .then(html => {
493            const parser = new DOMParser();
494            const htmlDoc = parser.parseFromString(html, "text/html");
495            const note = htmlDoc.querySelector('main.content');
496            if (note !== null) {
497              // This should only happen for chapter cross references
498              // (since there is no id in the URL)
499              // remove the first header
500              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
501                note.children[0].remove();
502              }
503              const html = processXRef(null, note);
504              instance.setContent(html);
505            } 
506          }).finally(() => {
507            instance.enable();
508            instance.show();
509          });
510        }
511      }, function(instance) {
512      });
513    }
514        let selectedAnnoteEl;
515        const selectorForAnnotation = ( cell, annotation) => {
516          let cellAttr = 'data-code-cell="' + cell + '"';
517          let lineAttr = 'data-code-annotation="' +  annotation + '"';
518          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
519          return selector;
520        }
521        const selectCodeLines = (annoteEl) => {
522          const doc = window.document;
523          const targetCell = annoteEl.getAttribute("data-target-cell");
524          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
525          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
526          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
527          const lineIds = lines.map((line) => {
528            return targetCell + "-" + line;
529          })
530          let top = null;
531          let height = null;
532          let parent = null;
533          if (lineIds.length > 0) {
534              //compute the position of the single el (top and bottom and make a div)
535              const el = window.document.getElementById(lineIds[0]);
536              top = el.offsetTop;
537              height = el.offsetHeight;
538              parent = el.parentElement.parentElement;
539            if (lineIds.length > 1) {
540              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
541              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
542              height = bottom - top;
543            }
544            if (top !== null && height !== null && parent !== null) {
545              // cook up a div (if necessary) and position it 
546              let div = window.document.getElementById("code-annotation-line-highlight");
547              if (div === null) {
548                div = window.document.createElement("div");
549                div.setAttribute("id", "code-annotation-line-highlight");
550                div.style.position = 'absolute';
551                parent.appendChild(div);
552              }
553              div.style.top = top - 2 + "px";
554              div.style.height = height + 4 + "px";
555              div.style.left = 0;
556              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
557              if (gutterDiv === null) {
558                gutterDiv = window.document.createElement("div");
559                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
560                gutterDiv.style.position = 'absolute';
561                const codeCell = window.document.getElementById(targetCell);
562                const gutter = codeCell.querySelector('.code-annotation-gutter');
563                gutter.appendChild(gutterDiv);
564              }
565              gutterDiv.style.top = top - 2 + "px";
566              gutterDiv.style.height = height + 4 + "px";
567            }
568            selectedAnnoteEl = annoteEl;
569          }
570        };
571        const unselectCodeLines = () => {
572          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
573          elementsIds.forEach((elId) => {
574            const div = window.document.getElementById(elId);
575            if (div) {
576              div.remove();
577            }
578          });
579          selectedAnnoteEl = undefined;
580        };
581          // Handle positioning of the toggle
582      window.addEventListener(
583        "resize",
584        throttle(() => {
585          elRect = undefined;
586          if (selectedAnnoteEl) {
587            selectCodeLines(selectedAnnoteEl);
588          }
589        }, 10)
590      );
591      function throttle(fn, ms) {
592      let throttle = false;
593      let timer;
594        return (...args) => {
595          if(!throttle) { // first call gets through
596              fn.apply(this, args);
597              throttle = true;
598          } else { // all the others get throttled
599              if(timer) clearTimeout(timer); // cancel #2
600              timer = setTimeout(() => {
601                fn.apply(this, args);
602                timer = throttle = false;
603              }, ms);
604          }
605        };
606      }
607        // Attach click handler to the DT
608        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
609        for (const annoteDlNode of annoteDls) {
610          annoteDlNode.addEventListener('click', (event) => {
611            const clickedEl = event.target;
612            if (clickedEl !== selectedAnnoteEl) {
613              unselectCodeLines();
614              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
615              if (activeEl) {
616                activeEl.classList.remove('code-annotation-active');
617              }
618              selectCodeLines(clickedEl);
619              clickedEl.classList.add('code-annotation-active');
620            } else {
621              // Unselect the line
622              unselectCodeLines();
623              clickedEl.classList.remove('code-annotation-active');
624            }
625          });
626        }
627    const findCites = (el) => {
628      const parentEl = el.parentElement;
629      if (parentEl) {
630        const cites = parentEl.dataset.cites;
631        if (cites) {
632          return {
633            el,
634            cites: cites.split(' ')
635          };
636        } else {
637          return findCites(el.parentElement)
638        }
639      } else {
640        return undefined;
641      }
642    };
643    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
644    for (var i=0; i<bibliorefs.length; i++) {
645      const ref = bibliorefs[i];
646      const citeInfo = findCites(ref);
647      if (citeInfo) {
648        tippyHover(citeInfo.el, function() {
649          var popup = window.document.createElement('div');
650          citeInfo.cites.forEach(function(cite) {
651            var citeDiv = window.document.createElement('div');
652            citeDiv.classList.add('hanging-indent');
653            citeDiv.classList.add('csl-entry');
654            var biblioDiv = window.document.getElementById('ref-' + cite);
655            if (biblioDiv) {
656              citeDiv.innerHTML = biblioDiv.innerHTML;
657            }
658            popup.appendChild(citeDiv);
659          });
660          return popup.innerHTML;
661        });
662      }
663    }
664  });
665  </script>
665
666</div> <!-- /content -->
667<footer class="footer">
668  <div class="nav-footer">
669    <div class="nav-footer-left">
670      &nbsp;
671    </div>   
672    <div class="nav-footer-center">
673      <ul class="footer-items list-unstyled">
674    <li class="nav-item">
675 Contact: <a href="mailto:[email protected]">[email protected]</a><br>
676<a href="https://www.linkedin.com/company/fews-lab" target="_blank"><i class="bi bi-linkedin"></i> FEWsLab</a> &nbsp;
677<a href="https://www.linkedin.com/in/caitlinagrady/" target="_blank"><i class="bi bi-linkedin"></i> Caitlin Grady</a> &nbsp;
678<a href="https://bsky.app/profile/caitlinagrady.bsky.social" target="_blank"><i class="fa fa-brands fa-bluesky"></i> Bluesky</a><br>
679Site made with <a href="https://quarto.org/" target="_blank"><img src="https://quarto.org/favicon.png" width="12"> Quarto</a><br>
680© 2025 FEWsLab
681  </li>  
682</ul>
683    </div>
684    <div class="nav-footer-right">
685      &nbsp;
686    </div>
687  </div>
688</footer>
689
690
691
692
693<script src="site_libs/quarto-html/zenscroll-min.js"></script>
693
694</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.