PageSourceSearch

https://tnagler.github.io/index.html

html tnagler.github.io collected 2026-10-03 10:05:17 UTC 30,485 bytes, 804 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.5.57">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9<meta name="author" content="Thomas Nagler">
10<meta name="description" content="Personal Website">
11
12<title>Thomas Nagler</title>
13<style>
14code{white-space: pre-wrap;}
15span.smallcaps{font-variant: small-caps;}
16div.columns{display: flex; gap: min(4vw, 1.5em);}
17div.column{flex: auto; overflow-x: auto;}
18div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19ul.task-list{list-style: none;}
20ul.task-list li input[type="checkbox"] {
21  width: 0.8em;
22  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
23  vertical-align: middle;
24}
25</style>
26
27
28<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 28
28
29<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-html/quarto.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 32
32
33<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
33
34<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
35<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
36<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
37<script src="site_libs/bootstrap/bootstrap.min.js"></script>
37
38<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
39<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
40<link href="site_libs/bootstrap/bootstrap-dark.min.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
41<link href="site_libs/quarto-contrib/academicons-1.9.2/all.css" rel="stylesheet">
42<link href="site_libs/quarto-contrib/academicons-1.9.2/size.css" rel="stylesheet">
43<script id="quarto-search-options" type="application/json">{
44  "language": {
45    "search-no-results-text": "No results",
46    "search-matching-documents-text": "matching documents",
47    "search-copy-link-title": "Copy link to search",
48    "search-hide-matches-text": "Hide additional matches",
49    "search-more-match-text": "more match in this document",
50    "search-more-matches-text": "more matches in this document",
51    "search-clear-button-title": "Clear",
52    "search-text-placeholder": "",
53    "search-detached-cancel-button-title": "Cancel",
54    "search-submit-button-title": "Submit",
55    "search-label": "Search"
56  }
57}</script>
vendor: 1 bytes, line 57
57
58<script async="" src="https://www.googletagmanager.com/gtag/js?id="></script>
58
59
60<script type="text/javascript">
61
62window.dataLayer = window.dataLayer || [];
63function gtag(){dataLayer.push(arguments);}
64gtag('js', new Date());
65gtag('config', '', { 'anonymize_ip': true});
66</script>
66
67
68<!-- 
69Load Academicons v1: https://jpswalsh.github.io/academicons/
70-->
71<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css">
72
73<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
74
75
76<!---
77The following code are needed to show dimension citation and altmetrics.
78https://api.altmetric.com/embeds.html
79https://badge.dimensions.ai/
80--->
81
82<script type="text/javascript" src="https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js"></script>
82
83
84<script async="" src="https://badge.dimensions.ai/badge.js" charset="utf-8"></script>
84
85
86<script type="text/javascript" src="//cdn.plu.mx/widget-popup.js"></script>
86
87
88
89<link rel="stylesheet" href="styles.css">
90<meta property="og:title" content="Thomas Nagler">
91<meta property="og:description" content="Personal website of Thomas Nagler">
92<meta property="og:image" content="https://tnagler.com/files/images/avatar2.jpeg">
93<meta property="og:site_name" content="Thomas Nagler">
94<meta name="twitter:title" content="Thomas Nagler">
95<meta name="twitter:description" content="Personal website of Thomas Nagler">
96<meta name="twitter:image" content="https://tnagler.com/files/images/avatar2.jpeg">
97<meta name="twitter:card" content="summary_large_image">
98</head>
99
100<body class="nav-fixed">
101
102<div id="quarto-search-results"></div>
103  <header id="quarto-header" class="headroom fixed-top">
104    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
105      <div class="navbar-container container-fluid">
106      <div class="navbar-brand-container mx-auto">
107    <a class="navbar-brand" href="./index.html">
108    <span class="navbar-title">Thomas Nagler</span>
109    </a>
110  </div>
111          <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(); }">
112  <span class="navbar-toggler-icon"></span>
113</button>
114          <div class="collapse navbar-collapse" id="navbarCollapse">
115            <ul class="navbar-nav navbar-nav-scroll me-auto">
116  <li class="nav-item">
117    <a class="nav-link active" href="./index.html" aria-current="page"> 
118<span class="menu-text">About</span></a>
119  </li>  
120  <li class="nav-item">
121    <a class="nav-link" href="./publications.html"> 
122<span class="menu-text">Publications</span></a>
123  </li>  
124  <li class="nav-item">
125    <a class="nav-link" href="./software.html"> 
126<span class="menu-text">Software</span></a>
127  </li>  
128  <li class="nav-item">
129    <a class="nav-link" href="./teaching.html"> 
130<span class="menu-text">Teaching</span></a>
131  </li>  
132  <li class="nav-item">
133    <a class="nav-link" href="./people.html"> 
134<span class="menu-text">Team</span></a>
135  </li>  
136</ul>
137          </div> <!-- /navcollapse -->
138            <div class="quarto-navbar-tools">
139  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
140</div>
141      </div> <!-- /container-fluid -->
142    </nav>
143</header>
144<!-- content -->
145<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar">
146<!-- sidebar -->
147<!-- margin-sidebar -->
148    
149<!-- main -->
150<main class="content column-page" id="quarto-document-content">
151
152
153
154
155<div class="quarto-about-trestles column-page">
156  <div class="about-entity">
157    <img src="files/images/avatar2.jpeg" class="about-image
158  rectangle " style="width: 53%;">
159<header id="title-block-header" class="quarto-title-block default">
160<div class="quarto-title">
161<h1 class="title">Thomas Nagler</h1>
162</div>
163<div class="quarto-title-meta column-page">
164  </div>
165</header>
166    <div class="about-links">
167  <a href="mailto:[email protected]" class="about-link" rel="" target="">
168    <i class="bi bi-envelope"></i>
169     <span class="about-link-text"></span>
170  </a>
171  <a href="https://orcid.org/0000-0003-1855-0046" class="about-link" rel="" target="_blank">
172     <span class="about-link-text"><i class="ai  ai-orcid"></i></span>
173  </a>
174  <a href="https://github.com/tnagler" class="about-link" rel="" target="_blank">
175    <i class="bi bi-github"></i>
176     <span class="about-link-text"></span>
177  </a>
178  <a href="https://scholar.google.com/citations?user=tZR1rZoAAAAJ&amp;hl=en" class="about-link" rel="" target="_blank">
179     <span class="about-link-text"><i class="ai  ai-google-scholar"></i></span>
180  </a>
181</div>
182  </div>
183  <div class="about-contents"><div id="hero-heading">
184<p>I am Professor at the <a href="https://www.en.statistik.uni-muenchen.de/index.html">Department of Statistics</a>, <a href="https://www.lmu.de/">LMU Munich</a>, and a principal investigator at the <a href="https://mcml.ai/">Munich Center for Machine Learning (MCML)</a>.</p>
185<p>My main research areas are mathematical statistics and machine learning. I develop new methods, derive theoretical guarantees and scalable algorithms, and collaborate with domain experts to solve problems in diverse areas.</p>
186<section id="research-interests" class="level3">
187<h3 data-anchor-id="research-interests">Research interests</h3>
188<ul>
189<li>Statistical learning methods and theory</li>
190<li>High-dimensional dependence models</li>
191<li>Time series</li>
192<li>Statistical computing</li>
193</ul>
194</section>
195<section id="short-cv" class="level3">
196<h3 data-anchor-id="short-cv">Short CV</h3>
197<ul>
198<li>2022–: <em>Professor (W2)</em>, Department of Statistics, <a href="https://www.en.statistik.uni-muenchen.de/index.html">LMU Munich</a></li>
199<li>2021–2022: <em>Assistant professor</em>, DIAM, <a href="https://www.tudelft.nl/ewi/over-de-faculteit/afdelingen/applied-mathematics">TU Delft</a></li>
200<li>2019–2021: <em>Assistant professor</em>, Mathematical Institute, <a href="https://www.universiteitleiden.nl/en/science/mathematics">Leiden University</a></li>
201<li>2014–2018: <em>PhD Mathematical Statistics</em>, <a href="https://www.ma.tum.de/en">TU Munich</a></li>
202<li>2012–2014: <em>MSc Mathematical Finance</em>, <a href="https://www.ma.tum.de/en">TU Munich</a></li>
203<li>2009–2012: <em>BSc Mathematics</em>, <a href="https://www.ma.tum.de/en">TU Munich</a></li>
204</ul>
205</section>
206</div></div>
207</div>
208
209<center>
210<hr style="width:100%">
211</center>
212<section id="office" class="level4">
213<h4 data-anchor-id="office">Office</h4>
214<p>Room 311 (3rd floor)<br>
215Akademiestr. 7<br>
21680799 Munich, Germany</p>
217
218
219
220</section>
221
222</main> <!-- /main -->
223<script id="quarto-html-after-body" type="application/javascript">
224window.document.addEventListener("DOMContentLoaded", function (event) {
225  const toggleBodyColorMode = (bsSheetEl) => {
226    const mode = bsSheetEl.getAttribute("data-mode");
227    const bodyEl = window.document.querySelector("body");
228    if (mode === "dark") {
229      bodyEl.classList.add("quarto-dark");
230      bodyEl.classList.remove("quarto-light");
231    } else {
232      bodyEl.classList.add("quarto-light");
233      bodyEl.classList.remove("quarto-dark");
234    }
235  }
236  const toggleBodyColorPrimary = () => {
237    const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
238    if (bsSheetEl) {
239      toggleBodyColorMode(bsSheetEl);
240    }
241  }
242  toggleBodyColorPrimary();  
243  const disableStylesheet = (stylesheets) => {
244    for (let i=0; i < stylesheets.length; i++) {
245      const stylesheet = stylesheets[i];
246      stylesheet.rel = 'prefetch';
247    }
248  }
249  const enableStylesheet = (stylesheets) => {
250    for (let i=0; i < stylesheets.length; i++) {
251      const stylesheet = stylesheets[i];
252      stylesheet.rel = 'stylesheet';
253    }
254  }
255  const manageTransitions = (selector, allowTransitions) => {
256    const els = window.document.querySelectorAll(selector);
257    for (let i=0; i < els.length; i++) {
258      const el = els[i];
259      if (allowTransitions) {
260        el.classList.remove('notransition');
261      } else {
262        el.classList.add('notransition');
263      }
264    }
265  }
266  const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
267    const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
268    const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
269    let newTheme = '';
270    if(darkModeDefault) {
271      newTheme = isAlternate ? baseTheme : alternateTheme;
272    } else {
273      newTheme = isAlternate ? alternateTheme : baseTheme;
274    }
275    const changeGiscusTheme = () => {
276      // From: https://github.com/giscus/giscus/issues/336
277      const sendMessage = (message) => {
278        const iframe = document.querySelector('iframe.giscus-frame');
279        if (!iframe) return;
280        iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
281      }
282      sendMessage({
283        setConfig: {
284          theme: newTheme
285        }
286      });
287    }
288    const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
289    if (isGiscussLoaded) {
290      changeGiscusTheme();
291    }
292  }
293  const toggleColorMode = (alternate) => {
294    // Switch the stylesheets
295    const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
296    manageTransitions('#quarto-margin-sidebar .nav-link', false);
297    if (alternate) {
298      enableStylesheet(alternateStylesheets);
299      for (const sheetNode of alternateStylesheets) {
300        if (sheetNode.id === "quarto-bootstrap") {
301          toggleBodyColorMode(sheetNode);
302        }
303      }
304    } else {
305      disableStylesheet(alternateStylesheets);
306      toggleBodyColorPrimary();
307    }
308    manageTransitions('#quarto-margin-sidebar .nav-link', true);
309    // Switch the toggles
310    const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
311    for (let i=0; i < toggles.length; i++) {
312      const toggle = toggles[i];
313      if (toggle) {
314        if (alternate) {
315          toggle.classList.add("alternate");     
316        } else {
317          toggle.classList.remove("alternate");
318        }
319      }
320    }
321    // Hack to workaround the fact that safari doesn't
322    // properly recolor the scrollbar when toggling (#1455)
323    if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
324      manageTransitions("body", false);
325      window.scrollTo(0, 1);
326      setTimeout(() => {
327        window.scrollTo(0, 0);
328        manageTransitions("body", true);
329      }, 40);  
330    }
331  }
332  const isFileUrl = () => { 
333    return window.location.protocol === 'file:';
334  }
335  const hasAlternateSentinel = () => {  
336    let styleSentinel = getColorSchemeSentinel();
337    if (styleSentinel !== null) {
338      return styleSentinel === "alternate";
339    } else {
340      return false;
341    }
342  }
343  const setStyleSentinel = (alternate) => {
344    const value = alternate ? "alternate" : "default";
345    if (!isFileUrl()) {
346      window.localStorage.setItem("quarto-color-scheme", value);
347    } else {
348      localAlternateSentinel = value;
349    }
350  }
351  const getColorSchemeSentinel = () => {
352    if (!isFileUrl()) {
353      const storageValue = window.localStorage.getItem("quarto-color-scheme");
354      return storageValue != null ? storageValue : localAlternateSentinel;
355    } else {
356      return localAlternateSentinel;
357    }
358  }
359  const darkModeDefault = false;
360  let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
361  // Dark / light mode switch
362  window.quartoToggleColorScheme = () => {
363    // Read the current dark / light value 
364    let toAlternate = !hasAlternateSentinel();
365    toggleColorMode(toAlternate);
366    setStyleSentinel(toAlternate);
367    toggleGiscusIfUsed(toAlternate, darkModeDefault);
368  };
369  // Ensure there is a toggle, if there isn't float one in the top right
370  if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
371    const a = window.document.createElement('a');
372    a.classList.add('top-right');
373    a.classList.add('quarto-color-scheme-toggle');
374    a.href = "";
375    a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
376    const i = window.document.createElement("i");
377    i.classList.add('bi');
378    a.appendChild(i);
379    window.document.body.appendChild(a);
380  }
381  // Switch to dark mode if need be
382  if (hasAlternateSentinel()) {
383    toggleColorMode(true);
384  } else {
385    toggleColorMode(false);
386  }
387  const isCodeAnnotation = (el) => {
388    for (const clz of el.classList) {
389      if (clz.startsWith('code-annotation-')) {                     
390        return true;
391      }
392    }
393    return false;
394  }
395  const onCopySuccess = function(e) {
396    // button target
397    const button = e.trigger;
398    // don't keep focus
399    button.blur();
400    // flash "checked"
401    button.classList.add('code-copy-button-checked');
402    var currentTitle = button.getAttribute("title");
403    button.setAttribute("title", "Copied!");
404    let tooltip;
405    if (window.bootstrap) {
406      button.setAttribute("data-bs-toggle", "tooltip");
407      button.setAttribute("data-bs-placement", "left");
408      button.setAttribute("data-bs-title", "Copied!");
409      tooltip = new bootstrap.Tooltip(button, 
410        { trigger: "manual", 
411          customClass: "code-copy-button-tooltip",
412          offset: [0, -8]});
413      tooltip.show();    
414    }
415    setTimeout(function() {
416      if (tooltip) {
417        tooltip.hide();
418        button.removeAttribute("data-bs-title");
419        button.removeAttribute("data-bs-toggle");
420        button.removeAttribute("data-bs-placement");
421      }
422      button.setAttribute("title", currentTitle);
423      button.classList.remove('code-copy-button-checked');
424    }, 1000);
425    // clear code selection
426    e.clearSelection();
427  }
428  const getTextToCopy = function(trigger) {
429      const codeEl = trigger.previousElementSibling.cloneNode(true);
430      for (const childEl of codeEl.children) {
431        if (isCodeAnnotation(childEl)) {
432          childEl.remove();
433        }
434      }
435      return codeEl.innerText;
436  }
437  const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
438    text: getTextToCopy
439  });
440  clipboard.on('success', onCopySuccess);
441  if (window.document.getElementById('quarto-embedded-source-code-modal')) {
442    // For code content inside modals, clipBoardJS needs to be initialized with a container option
443    // TODO: Check when it could be a function (https://github.com/zenorocha/clipboard.js/issues/860)
444    const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
445      text: getTextToCopy,
446      container: window.document.getElementById('quarto-embedded-source-code-modal')
447    });
448    clipboardModal.on('success', onCopySuccess);
449  }
450    var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
451    var mailtoRegex = new RegExp(/^mailto:/);
452      var filterRegex = new RegExp("^(?:http:|https:)\/\/drganghe\.github\.io\/custom");
453    var isInternal = (href) => {
454        return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
455    }
456    // Inspect non-navigation links and adorn them if external
457 	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)');
458    for (var i=0; i<links.length; i++) {
459      const link = links[i];
460      if (!isInternal(link.href)) {
461        // undo the damage that might have been done by quarto-nav.js in the case of
462        // links that we want to consider external
463        if (link.dataset.originalHref !== undefined) {
464          link.href = link.dataset.originalHref;
465        }
466          // target, if specified
467          link.setAttribute("target", "_blank");
468          if (link.getAttribute("rel") === null) {
469            link.setAttribute("rel", "noopener");
470          }
471      }
472    }
473  function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
474    const config = {
475      allowHTML: true,
476      maxWidth: 500,
477      delay: 100,
478      arrow: false,
479      appendTo: function(el) {
480          return el.parentElement;
481      },
482      interactive: true,
483      interactiveBorder: 10,
484      theme: 'quarto',
485      placement: 'bottom-start',
486    };
487    if (contentFn) {
488      config.content = contentFn;
489    }
490    if (onTriggerFn) {
491      config.onTrigger = onTriggerFn;
492    }
493    if (onUntriggerFn) {
494      config.onUntrigger = onUntriggerFn;
495    }
496    window.tippy(el, config); 
497  }
498  const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
499  for (var i=0; i<noterefs.length; i++) {
500    const ref = noterefs[i];
501    tippyHover(ref, function() {
502      // use id or data attribute instead here
503      let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
504      try { href = new URL(href).hash; } catch {}
505      const id = href.replace(/^#\/?/, "");
506      const note = window.document.getElementById(id);
507      if (note) {
508        return note.innerHTML;
509      } else {
510        return "";
511      }
512    });
513  }
514  const xrefs = window.document.querySelectorAll('a.quarto-xref');
515  const processXRef = (id, note) => {
516    // Strip column container classes
517    const stripColumnClz = (el) => {
518      el.classList.remove("page-full", "page-columns");
519      if (el.children) {
520        for (const child of el.children) {
521          stripColumnClz(child);
522        }
523      }
524    }
525    stripColumnClz(note)
526    if (id === null || id.startsWith('sec-')) {
527      // Special case sections, only their first couple elements
528      const container = document.createElement("div");
529      if (note.children && note.children.length > 2) {
530        container.appendChild(note.children[0].cloneNode(true));
531        for (let i = 1; i < note.children.length; i++) {
532          const child = note.children[i];
533          if (child.tagName === "P" && child.innerText === "") {
534            continue;
535          } else {
536            container.appendChild(child.cloneNode(true));
537            break;
538          }
539        }
540        if (window.Quarto?.typesetMath) {
541          window.Quarto.typesetMath(container);
542        }
543        return container.innerHTML
544      } else {
545        if (window.Quarto?.typesetMath) {
546          window.Quarto.typesetMath(note);
547        }
548        return note.innerHTML;
549      }
550    } else {
551      // Remove any anchor links if they are present
552      const anchorLink = note.querySelector('a.anchorjs-link');
553      if (anchorLink) {
554        anchorLink.remove();
555      }
556      if (window.Quarto?.typesetMath) {
557        window.Quarto.typesetMath(note);
558      }
559      // TODO in 1.5, we should make sure this works without a callout special case
560      if (note.classList.contains("callout")) {
561        return note.outerHTML;
562      } else {
563        return note.innerHTML;
564      }
565    }
566  }
567  for (var i=0; i<xrefs.length; i++) {
568    const xref = xrefs[i];
569    tippyHover(xref, undefined, function(instance) {
570      instance.disable();
571      let url = xref.getAttribute('href');
572      let hash = undefined; 
573      if (url.startsWith('#')) {
574        hash = url;
575      } else {
576        try { hash = new URL(url).hash; } catch {}
577      }
578      if (hash) {
579        const id = hash.replace(/^#\/?/, "");
580        const note = window.document.getElementById(id);
581        if (note !== null) {
582          try {
583            const html = processXRef(id, note.cloneNode(true));
584            instance.setContent(html);
585          } finally {
586            instance.enable();
587            instance.show();
588          }
589        } else {
590          // See if we can fetch this
591          fetch(url.split('#')[0])
592          .then(res => res.text())
593          .then(html => {
594            const parser = new DOMParser();
595            const htmlDoc = parser.parseFromString(html, "text/html");
596            const note = htmlDoc.getElementById(id);
597            if (note !== null) {
598              const html = processXRef(id, note);
599              instance.setContent(html);
600            } 
601          }).finally(() => {
602            instance.enable();
603            instance.show();
604          });
605        }
606      } else {
607        // See if we can fetch a full url (with no hash to target)
608        // This is a special case and we should probably do some content thinning / targeting
609        fetch(url)
610        .then(res => res.text())
611        .then(html => {
612          const parser = new DOMParser();
613          const htmlDoc = parser.parseFromString(html, "text/html");
614          const note = htmlDoc.querySelector('main.content');
615          if (note !== null) {
616            // This should only happen for chapter cross references
617            // (since there is no id in the URL)
618            // remove the first header
619            if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
620              note.children[0].remove();
621            }
622            const html = processXRef(null, note);
623            instance.setContent(html);
624          } 
625        }).finally(() => {
626          instance.enable();
627          instance.show();
628        });
629      }
630    }, function(instance) {
631    });
632  }
633      let selectedAnnoteEl;
634      const selectorForAnnotation = ( cell, annotation) => {
635        let cellAttr = 'data-code-cell="' + cell + '"';
636        let lineAttr = 'data-code-annotation="' +  annotation + '"';
637        const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
638        return selector;
639      }
640      const selectCodeLines = (annoteEl) => {
641        const doc = window.document;
642        const targetCell = annoteEl.getAttribute("data-target-cell");
643        const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
644        const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
645        const lines = annoteSpan.getAttribute("data-code-lines").split(",");
646        const lineIds = lines.map((line) => {
647          return targetCell + "-" + line;
648        })
649        let top = null;
650        let height = null;
651        let parent = null;
652        if (lineIds.length > 0) {
653            //compute the position of the single el (top and bottom and make a div)
654            const el = window.document.getElementById(lineIds[0]);
655            top = el.offsetTop;
656            height = el.offsetHeight;
657            parent = el.parentElement.parentElement;
658          if (lineIds.length > 1) {
659            const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
660            const bottom = lastEl.offsetTop + lastEl.offsetHeight;
661            height = bottom - top;
662          }
663          if (top !== null && height !== null && parent !== null) {
664            // cook up a div (if necessary) and position it 
665            let div = window.document.getElementById("code-annotation-line-highlight");
666            if (div === null) {
667              div = window.document.createElement("div");
668              div.setAttribute("id", "code-annotation-line-highlight");
669              div.style.position = 'absolute';
670              parent.appendChild(div);
671            }
672            div.style.top = top - 2 + "px";
673            div.style.height = height + 4 + "px";
674            div.style.left = 0;
675            let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
676            if (gutterDiv === null) {
677              gutterDiv = window.document.createElement("div");
678              gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
679              gutterDiv.style.position = 'absolute';
680              const codeCell = window.document.getElementById(targetCell);
681              const gutter = codeCell.querySelector('.code-annotation-gutter');
682              gutter.appendChild(gutterDiv);
683            }
684            gutterDiv.style.top = top - 2 + "px";
685            gutterDiv.style.height = height + 4 + "px";
686          }
687          selectedAnnoteEl = annoteEl;
688        }
689      };
690      const unselectCodeLines = () => {
691        const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
692        elementsIds.forEach((elId) => {
693          const div = window.document.getElementById(elId);
694          if (div) {
695            div.remove();
696          }
697        });
698        selectedAnnoteEl = undefined;
699      };
700        // Handle positioning of the toggle
701    window.addEventListener(
702      "resize",
703      throttle(() => {
704        elRect = undefined;
705        if (selectedAnnoteEl) {
706          selectCodeLines(selectedAnnoteEl);
707        }
708      }, 10)
709    );
710    function throttle(fn, ms) {
711    let throttle = false;
712    let timer;
713      return (...args) => {
714        if(!throttle) { // first call gets through
715            fn.apply(this, args);
716            throttle = true;
717        } else { // all the others get throttled
718            if(timer) clearTimeout(timer); // cancel #2
719            timer = setTimeout(() => {
720              fn.apply(this, args);
721              timer = throttle = false;
722            }, ms);
723        }
724      };
725    }
726      // Attach click handler to the DT
727      const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
728      for (const annoteDlNode of annoteDls) {
729        annoteDlNode.addEventListener('click', (event) => {
730          const clickedEl = event.target;
731          if (clickedEl !== selectedAnnoteEl) {
732            unselectCodeLines();
733            const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
734            if (activeEl) {
735              activeEl.classList.remove('code-annotation-active');
736            }
737            selectCodeLines(clickedEl);
738            clickedEl.classList.add('code-annotation-active');
739          } else {
740            // Unselect the line
741            unselectCodeLines();
742            clickedEl.classList.remove('code-annotation-active');
743          }
744        });
745      }
746  const findCites = (el) => {
747    const parentEl = el.parentElement;
748    if (parentEl) {
749      const cites = parentEl.dataset.cites;
750      if (cites) {
751        return {
752          el,
753          cites: cites.split(' ')
754        };
755      } else {
756        return findCites(el.parentElement)
757      }
758    } else {
759      return undefined;
760    }
761  };
762  var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
763  for (var i=0; i<bibliorefs.length; i++) {
764    const ref = bibliorefs[i];
765    const citeInfo = findCites(ref);
766    if (citeInfo) {
767      tippyHover(citeInfo.el, function() {
768        var popup = window.document.createElement('div');
769        citeInfo.cites.forEach(function(cite) {
770          var citeDiv = window.document.createElement('div');
771          citeDiv.classList.add('hanging-indent');
772          citeDiv.classList.add('csl-entry');
773          var biblioDiv = window.document.getElementById('ref-' + cite);
774          if (biblioDiv) {
775            citeDiv.innerHTML = biblioDiv.innerHTML;
776          }
777          popup.appendChild(citeDiv);
778        });
779        return popup.innerHTML;
780      });
781    }
782  }
783});
784</script>
784
785</div> <!-- /content -->
786<footer class="footer">
787  <div class="nav-footer">
788    <div class="nav-footer-left">
789<a href="http://www.tnagler.com">Thomas Nagler</a> ©
790<script>document.write(new Date().getFullYear())</script>
790
791</div>   
792    <div class="nav-footer-center">
793      &nbsp;
794    </div>
795    <div class="nav-footer-right">
796      &nbsp;
797    </div>
798  </div>
799</footer>
800
801
802
803
804</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.