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.8.26"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9 10<title>About â Dr. Franz Eder</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-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 34
34
35<script src="site_libs/quarto-html/axe/axe-check.js" type="module"></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>
37 38<link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> 39<link href="site_libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
40<script src="site_libs/bootstrap/bootstrap.min.js"></script>
40 41<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 42<link href="site_libs/bootstrap/bootstrap-dd357883b4fb0fe80695c2ba7470c529.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light"> 43<link href="site_libs/quarto-contrib/fontawesome6-1.2.0/all.min.css" rel="stylesheet"> 44<link href="site_libs/quarto-contrib/fontawesome6-1.2.0/latex-fontsize.css" rel="stylesheet">
45<script src="site_libs/quarto-contrib/iconify-2.1.0/iconify-icon.min.js"></script>
vendor: 1 bytes, line 45
45
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 async="" src="https://www.googletagmanager.com/gtag/js?id=347805153"></script>
73 74
75<script type="text/javascript"> 76 77window.dataLayer = window.dataLayer || []; 78function gtag(){dataLayer.push(arguments);} 79gtag('js', new Date()); 80gtag('config', '347805153', { 'anonymize_ip': true}); 81</script>
81 82<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin=""><link href="https://fonts.googleapis.com/css2?family=Lato&display=swap" rel="stylesheet"> 83 84 85<link rel="stylesheet" href="styles.css"> 86</head> 87 88<body class="nav-fixed quarto-light"> 89 90<div id="quarto-search-results"></div> 91 <header id="quarto-header" class="headroom fixed-top"> 92 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 93 <div class="navbar-container container-fluid"> 94 <div class="navbar-brand-container mx-auto"> 95 <a class="navbar-brand" href="./index.html"> 96 <span class="navbar-title">Dr. Franz Eder</span> 97 </a> 98 </div> 99 <div id="quarto-search" class="" title="Search"></div> 100 <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(); }"> 101 <span class="navbar-toggler-icon"></span> 102</button> 103 <div class="collapse navbar-collapse" id="navbarCollapse"> 104 <ul class="navbar-nav navbar-nav-scroll me-auto"> 105 <li class="nav-item"> 106 <a class="nav-link" href="./index.html"> 107<span class="menu-text">Home</span></a> 108 </li> 109 <li class="nav-item"> 110 <a class="nav-link active" href="./about.html" aria-current="page"> 111<span class="menu-text">About</span></a> 112 </li> 113 <li class="nav-item"> 114 <a class="nav-link" href="./research.html"> 115<span class="menu-text">Research</span></a> 116 </li> 117 <li class="nav-item"> 118 <a class="nav-link" href="./publications.html"> 119<span class="menu-text">Publications</span></a> 120 </li> 121 <li class="nav-item"> 122 <a class="nav-link" href="./teaching.html"> 123<span class="menu-text">Teaching</span></a> 124 </li> 125</ul> 126 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 127 <li class="nav-item"> 128 <a class="nav-link" href="mailto:[email protected]"> 129<span class="menu-text"><iconify-icon role="img" inline="" icon="clarity:email-line" style="font-size: 1.4em;" aria-label="Icon email-line from clarity Iconify.design set." title="eMail"></iconify-icon></span></a> 130 </li> 131 <li class="nav-item"> 132 <a class="nav-link" href="https://social.uibk.ac.at/@FranzEder"> 133<span class="menu-text"><iconify-icon role="img" inline="" icon="mdi:mastodon" style="font-size: 1.4em;" aria-label="Icon mastodon from mdi Iconify.design set." title="Mastodon"></iconify-icon></span></a> 134 </li> 135 <li class="nav-item"> 136 <a class="nav-link" href="https://bsky.app/profile/franzeder.bsky.social"> 137<span class="menu-text"><iconify-icon role="img" inline="" icon="ri:bluesky-line" style="font-size: 1.4em;" aria-label="Icon bluesky-line from ri Iconify.design set." title="Bluesky"></iconify-icon></span></a> 138 </li> 139 <li class="nav-item"> 140 <a class="nav-link" href="https://github.com/franzeder"> 141<span class="menu-text"><iconify-icon role="img" inline="" icon="fa6-brands:github" style="font-size: 1.4em;" aria-label="Icon github from fa6-brands Iconify.design set." title="github"></iconify-icon></span></a> 142 </li> 143 <li class="nav-item"> 144 <a class="nav-link" href="https://git.uibk.ac.at/c40298"> 145<span class="menu-text"><iconify-icon role="img" inline="" icon="fa-brands:gitlab" style="font-size: 1.4em;" aria-label="Icon gitlab from fa-brands Iconify.design set." title="gitlab"></iconify-icon></span></a> 146 </li> 147 <li class="nav-item"> 148 <a class="nav-link" href="https://scholar.google.com/citations?user=89MVg38AAAAJ"> 149<span class="menu-text"><iconify-icon role="img" inline="" icon="academicons:google-scholar" style="font-size: 1.4em;" aria-label="Icon google-scholar from academicons Iconify.design set." title="Google Scholar"></iconify-icon></span></a> 150 </li> 151 <li class="nav-item"> 152 <a class="nav-link" href="https://stackoverflow.com/users/2459401/feder80"> 153<span class="menu-text"><iconify-icon role="img" inline="" icon="mdi:stackoverflow" style="font-size: 1.4em;" aria-label="Icon stackoverflow from mdi Iconify.design set." title="Stackoverflow"></iconify-icon></span></a> 154 </li>
155 <li class="nav-item"> 156 <a class="nav-link" href="https://www.uibk.ac.at/politikwissenschaft/"> 157<span class="menu-text"><iconify-icon role="img" inline="" icon="la:university" style="font-size: 1.4em;" aria-label="Icon university from la Iconify.design set." title="University of Innsbruck"></iconify-icon></span></a> 158 </li> 159</ul> 160 </div> <!-- /navcollapse --> 161 <div class="quarto-navbar-tools"> 162</div> 163 </div> <!-- /container-fluid --> 164 </nav> 165</header> 166<!-- content --> 167<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 168<!-- sidebar --> 169<!-- margin-sidebar --> 170 <div id="quarto-margin-sidebar" class="sidebar margin-sidebar"> 171 <nav id="TOC" role="doc-toc" class="toc-active"> 172 <h2 id="toc-title">On this page</h2> 173 <ul> 174 <li><a href="#education" id="toc-education" class="nav-link active" data-scroll-target="#education">Education</a></li> 175 <li><a href="#experience" id="toc-experience" class="nav-link" data-scroll-target="#experience">Experience</a></li> 176 <li><a href="#grants-and-awards" id="toc-grants-and-awards" class="nav-link" data-scroll-target="#grants-and-awards">Grants and Awards</a></li> 177 <li><a href="#computational-skills" id="toc-computational-skills" class="nav-link" data-scroll-target="#computational-skills">Computational Skills</a></li> 178 <li><a href="#academic-services-and-leadership" id="toc-academic-services-and-leadership" class="nav-link" data-scroll-target="#academic-services-and-leadership">Academic Services and Leadership</a></li> 179 </ul> 180</nav> 181 </div> 182<!-- main --> 183<div class="quarto-about-solana column-body"> 184 <div class="about-entity"> 185 <div class="entity-contents"> 186 <header id="title-block-header" class="quarto-title-block default"> 187<div class="quarto-title"> 188<h1 class="title">About</h1> 189</div> 190<div class="quarto-title-meta"> 191 </div> 192</header> <div class="about-links"> 193 <a href="mailto:[email protected]" class="about-link" rel="" target=""> 194 <i class="bi bi-envelope-fill"></i> 195 <span class="about-link-text">email</span> 196 </a> 197 <a href="tel:004351250770112" class="about-link" rel="" target=""> 198 <i class="bi bi-telephone-fill"></i> 199 <span class="about-link-text">+43 512 507 70112</span> 200 </a> 201 <a href="https://universe.uibk.ac.at/s/q9S9Kxty2cMAESD" class="about-link" rel="" target=""> 202 <i class="bi bi-journal-text"></i> 203 <span class="about-link-text">CV</span> 204 </a> 205 <a href="https://universe.uibk.ac.at/s/tznqNWA5Y8nQd4a" class="about-link" rel="" target=""> 206 <i class="bi bi-image"></i> 207 <span class="about-link-text">press photo</span> 208 </a> 209</div> 210 <div class="about-contents"><main class="content" id="quarto-document-content"> 211 212<p><a href="https://goo.gl/maps/5KLHWqjvacY5H9hF6"><i class="fa-solid fa-map-location-dot" aria-label="map-location-dot"></i></a> UniversitätstraÃe 15, 6020 Innsbruck, Austria</p> 213<p>Associate Professor of International Relations, <a href="https://www.uibk.ac.at/politikwissenschaft/">Department of Political Science</a>, <a href="https://www.uibk.ac.at/">University of Innsbruck</a></p> 214<p>Dean of the <a href="https://www.uibk.ac.at/fakultaeten/social-and-political-sciences/">Innsbruck School of Social and Political Sciences</a></p> 215<p>Deputy Director of the <a href="https://www.foreignpolicylab.at/">Foreign Policy Lab</a> @ the University of Innsbruck</p> 216<section id="education" class="level2"> 217<h2 data-anchor-id="education">Education</h2> 218<p>Data Science Specialization | <strong>Johns Hopkins University</strong> & <a href="https://coursera.org/verify/specialization/BX8JL6C8VK7F"><strong>Coursera</strong></a> | July 2015 - June 2016</p> 219<p>Venia Docendi (Habilitation) in Political Science | <strong>University of Innsbruck</strong> | 2015</p> 220<p>Dr. phil. in Political Science | <strong>University of Innsbruck</strong> | Ocotber 2003 - June 2008</p> 221<p>Mag. phil. in Political Science | <strong>University of Vienna</strong> and Innsbruck | October 1999 - June 2003</p> 222</section> 223<section id="experience" class="level2"> 224<h2 data-anchor-id="experience">Experience</h2> 225<p>Dean | Innsbruck School of Social and Political Science, <strong>University of Innsbruck</strong> | March 2021 - present</p> 226<p>Dean of Studies | Innsbruck School of Social and Political Science, <strong>University of Innsbruck</strong> | March 2017 - February 2021</p> 227<p>Associate Professor of International Relations, Department of Political Science, <strong>University of Innsbruck</strong> | 2015 - present</p> 228<p>Assistant Professor of International Relations | Department of Political Science, <strong>University of Innsbruck</strong> | 2009-2015</p> 229<p>pre-doc | Department of Political Science, <strong>University of Innsbruck</strong> | April 2005 - 2009</p> 230<p>Visiting Research Fellow | <strong>Stiftung Wissenschaft und Politik</strong>, Berlin | January 2005 - March 2005</p> 231<p>Visiting Research Fellow | <strong>Deutsches Orient-Institut</strong>, Hamburg | October 2004 - December 2005</p> 232</section> 233<section id="grants-and-awards" class="level2"> 234<h2 data-anchor-id="grants-and-awards">Grants and Awards</h2> 235<p><strong>Principal Investigator</strong> | <a href="https://www.fwf.ac.at/forschungsradar/10.55776/PAT6423424">âInternational Intelligence Cooperation and Foreign Policyâ</a> funded by FWF, EUR 306,788 | 2025-2029</p> 236<p><strong>Co-author</strong> | <a href="https://www.fwf.ac.at/forschungsradar/10.55776/PAT8575123">âState Advocacy for Nuclear Disarmamentâ</a> funded by FWF, EUR 218,003 | 2025-2029</p> 237<p><strong>Collaborator</strong> | <a href="https://infra4nextgen.com/">
237âProviding research infrastructure services to support Next Generation EU â Infra4NextGenâ</a> funded by EU - Horizon Europe (HEU), EUR 56,750 | 2023-2026</p> 238<p><strong>Principal investigator</strong> | âContesting Counter-Terrorismâ funded by the Tyrolean Research Fund, EUR 10,000 | 2016 - 2017</p> 239<p><strong>Principal investigator</strong> | âAssessing the Effectiveness of online-searchâ funded by the Tyrolean Research Fund, EUR 13,000 | 2008 - 2009</p> 240</section> 241<section id="computational-skills" class="level2"> 242<h2 data-anchor-id="computational-skills">Computational Skills</h2> 243<p><strong>R</strong> | a software environment for statistical computing and graphics | <a href="https://www.r-project.org/">https://www.r-project.org/</a></p> 244<p><strong>RStudio</strong> | an open-source data science software | <a href="https://www.rstudio.com/">https://www.rstudio.com/</a></p> 245<p><strong>Quarto</strong> | an open-source scientific and technical publishing system for high-quality articles, reports, presen- tations, websites, blogs, and books in HTML, PDF, MS Word, ePub | <a href="https://quarto.org/">https://quarto.org/</a></p> 246<p><strong>GIT</strong> | a version control system | <a href="https://git.uibk.ac.at/c40298">https://git.uibk.ac.at/c40298</a></p> 247<p><strong>LATEX 2ε</strong> | a high-quality typesetting system for academic papers and books | <a href="https://www.latex-project.org">https://www.latex-project.org</a></p> 248</section> 249<section id="academic-services-and-leadership" class="level2"> 250<h2 data-anchor-id="academic-services-and-leadership">Academic Services and Leadership</h2> 251<p>Dean | School of Social and Political Sciences, University of Innsbruck | March 2021 - present</p> 252<p>Representative of the University of Innsbruck (observer) | âDigitize! Computational Social Sciences in der digitalen und sozialen Transformationâ | 2021 - present</p> 253<p>Representative of the University of Innsbruck | âAustrian Social Science Data Archiveâ (AUSSDA) | 2020 - present</p> 254<p>Working Group Member | Research Data Management at the University of Innsbruck | 2018 - 2021</p> 255<p>Working Group Member | âOpen Accessâ at the University of Innsbruck | 2018 - 2020</p> 256<p>Dean of Studies | School of Social and Political Sciences, University of Innsbruck | March 2017 - February 2021</p> 257<p>Board Member | Austrian Political Science Association (ÃGPW) | 2012 - 2015</p> 258<p>Member of the Editorial Board | Austrian Journal of Political Science (ÃZP) | 2012 - present</p> 259<p>Program Director | BA and MA Political Science, School of Social and Political Sciences, University of Innsbruck | 2009 - 2017</p> 260<p>Referee for multiple journals and institutions | New Political Economy, Cambridge Review of International Affairs, Politics and Governance, New Media & Society, African Security Review, Zeitschrift für AuÃen- und Sicherheitspolitik, Friedenswarte, Austrian Academy of Science, ÃGPW-Nachwuchspreise | 2008 - present</p> 261 262 263</section> 264</main></div> 265 </div> 266 <img src="img/Franz Eder 01 © Andreas Friedle.jpg" class="about-image 267 rounded " style="width: 15em;"> 268 </div> 269</div> 270 <!-- /main -->
271<script id="quarto-html-after-body" type="application/javascript"> 272 window.document.addEventListener("DOMContentLoaded", function (event) { 273 const isCodeAnnotation = (el) => { 274 for (const clz of el.classList) { 275 if (clz.startsWith('code-annotation-')) { 276 return true; 277 } 278 } 279 return false; 280 } 281 const onCopySuccess = function(e) { 282 // button target 283 const button = e.trigger; 284 // don't keep focus 285 button.blur(); 286 // flash "checked" 287 button.classList.add('code-copy-button-checked'); 288 var currentTitle = button.getAttribute("title"); 289 button.setAttribute("title", "Copied!"); 290 let tooltip; 291 if (window.bootstrap) { 292 button.setAttribute("data-bs-toggle", "tooltip"); 293 button.setAttribute("data-bs-placement", "left"); 294 button.setAttribute("data-bs-title", "Copied!"); 295 tooltip = new bootstrap.Tooltip(button, 296 { trigger: "manual", 297 customClass: "code-copy-button-tooltip", 298 offset: [0, -8]}); 299 tooltip.show(); 300 } 301 setTimeout(function() { 302 if (tooltip) { 303 tooltip.hide(); 304 button.removeAttribute("data-bs-title"); 305 button.removeAttribute("data-bs-toggle"); 306 button.removeAttribute("data-bs-placement"); 307 } 308 button.setAttribute("title", currentTitle); 309 button.classList.remove('code-copy-button-checked'); 310 }, 1000); 311 // clear code selection 312 e.clearSelection(); 313 } 314 const getTextToCopy = function(trigger) { 315 const outerScaffold = trigger.parentElement.cloneNode(true); 316 const codeEl = outerScaffold.querySelector('code'); 317 for (const childEl of codeEl.children) { 318 if (isCodeAnnotation(childEl)) { 319 childEl.remove(); 320 } 321 } 322 return codeEl.innerText; 323 } 324 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 325 text: getTextToCopy 326 }); 327 clipboard.on('success', onCopySuccess); 328 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 329 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 330 text: getTextToCopy, 331 container: window.document.getElementById('quarto-embedded-source-code-modal') 332 }); 333 clipboardModal.on('success', onCopySuccess); 334 } 335 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 336 var mailtoRegex = new RegExp(/^mailto:/); 337 var filterRegex = new RegExp('/' + window.location.host + '/'); 338 var isInternal = (href) => { 339 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 340 } 341 // Inspect non-navigation links and adorn them if external 342 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)'); 343 for (var i=0; i<links.length; i++) { 344 const link = links[i]; 345 if (!isInternal(link.href)) { 346 // undo the damage that might have been done by quarto-nav.js in the case of 347 // links that we want to consider external 348 if (link.dataset.originalHref !== undefined) { 349 link.href = link.dataset.originalHref; 350 } 351 // target, if specified 352 link.setAttribute("target", "_blank"); 353 if (link.getAttribute("rel") === null) { 354 link.setAttribute("rel", "noopener"); 355 } 356 // default icon 357 link.classList.add("external"); 358 } 359 } 360 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 361 const config = { 362 allowHTML: true, 363 maxWidth: 500, 364 delay: 100, 365 arrow: false, 366 appendTo: function(el) { 367 return el.parentElement; 368 }, 369 interactive: true, 370 interactiveBorder: 10, 371 theme: 'quarto', 372 placement: 'bottom-start', 373 }; 374 if (contentFn) { 375 config.content = contentFn; 376 } 377 if (onTriggerFn) { 378 config.onTrigger = onTriggerFn; 379 } 380 if (onUntriggerFn) { 381 config.onUntrigger = onUntriggerFn; 382 } 383 window.tippy(el, config); 384 } 385 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 386 for (var i=0; i<noterefs.length; i++) { 387 const ref = noterefs[i]; 388 tippyHover(ref, function() { 389 // use id or data attribute instead here 390 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 391 try { href = new URL(href).hash; } catch {} 392 const id = href.replace(/^#\/?/, ""); 393 const note = window.document.getElementById(id); 394 if (note) { 395 return note.innerHTML; 396 } else { 397 return ""; 398 } 399 }); 400 } 401 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 402 const processXRef = (id, note) => { 403 // Strip column container classes 404 const stripColumnClz = (el) => { 405 el.classList.remove("page-full", "page-columns"); 406 if (el.children) { 407 for (const child of el.children) {
408 stripColumnClz(child); 409 } 410 } 411 } 412 stripColumnClz(note) 413 if (id === null || id.startsWith('sec-')) { 414 // Special case sections, only their first couple elements 415 const container = document.createElement("div"); 416 if (note.children && note.children.length > 2) { 417 container.appendChild(note.children[0].cloneNode(true)); 418 for (let i = 1; i < note.children.length; i++) { 419 const child = note.children[i]; 420 if (child.tagName === "P" && child.innerText === "") { 421 continue; 422 } else { 423 container.appendChild(child.cloneNode(true)); 424 break; 425 } 426 } 427 if (window.Quarto?.typesetMath) { 428 window.Quarto.typesetMath(container); 429 } 430 return container.innerHTML 431 } else { 432 if (window.Quarto?.typesetMath) { 433 window.Quarto.typesetMath(note); 434 } 435 return note.innerHTML; 436 } 437 } else { 438 // Remove any anchor links if they are present 439 const anchorLink = note.querySelector('a.anchorjs-link'); 440 if (anchorLink) { 441 anchorLink.remove(); 442 } 443 if (window.Quarto?.typesetMath) { 444 window.Quarto.typesetMath(note); 445 } 446 if (note.classList.contains("callout")) { 447 return note.outerHTML; 448 } else { 449 return note.innerHTML; 450 } 451 } 452 } 453 for (var i=0; i<xrefs.length; i++) { 454 const xref = xrefs[i]; 455 tippyHover(xref, undefined, function(instance) { 456 instance.disable(); 457 let url = xref.getAttribute('href'); 458 let hash = undefined; 459 if (url.startsWith('#')) { 460 hash = url; 461 } else { 462 try { hash = new URL(url).hash; } catch {} 463 } 464 if (hash) { 465 const id = hash.replace(/^#\/?/, ""); 466 const note = window.document.getElementById(id); 467 if (note !== null) { 468 try { 469 const html = processXRef(id, note.cloneNode(true)); 470 instance.setContent(html); 471 } finally { 472 instance.enable(); 473 instance.show(); 474 } 475 } else { 476 // See if we can fetch this 477 fetch(url.split('#')[0]) 478 .then(res => res.text()) 479 .then(html => { 480 const parser = new DOMParser(); 481 const htmlDoc = parser.parseFromString(html, "text/html"); 482 const note = htmlDoc.getElementById(id); 483 if (note !== null) { 484 const html = processXRef(id, note); 485 instance.setContent(html); 486 } 487 }).finally(() => { 488 instance.enable(); 489 instance.show(); 490 }); 491 } 492 } else { 493 // See if we can fetch a full url (with no hash to target) 494 // This is a special case and we should probably do some content thinning / targeting 495 fetch(url) 496 .then(res => res.text()) 497 .then(html => { 498 const parser = new DOMParser(); 499 const htmlDoc = parser.parseFromString(html, "text/html"); 500 const note = htmlDoc.querySelector('main.content'); 501 if (note !== null) { 502 // This should only happen for chapter cross references 503 // (since there is no id in the URL) 504 // remove the first header 505 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 506 note.children[0].remove(); 507 } 508 const html = processXRef(null, note); 509 instance.setContent(html); 510 } 511 }).finally(() => { 512 instance.enable(); 513 instance.show(); 514 }); 515 } 516 }, function(instance) { 517 }); 518 } 519 let selectedAnnoteEl; 520 const selectorForAnnotation = ( cell, annotation) => { 521 let cellAttr = 'data-code-cell="' + cell + '"'; 522 let lineAttr = 'data-code-annotation="' + annotation + '"'; 523 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 524 return selector; 525 } 526 const selectCodeLines = (annoteEl) => { 527 const doc = window.document; 528 const targetCell = annoteEl.getAttribute("data-target-cell"); 529 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 530 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 531 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 532 const lineIds = lines.map((line) => { 533 return targetCell + "-" + line; 534 }) 535 let top = null; 536 let height = null; 537 let parent = null; 538 if (lineIds.length > 0) { 539 //compute the position of the single el (top and bottom and make a div) 540 const el = window.document.getElementById(lineIds[0]); 541 top = el.offsetTop; 542 height = el.offsetHeight; 543 parent = el.parentElement.parentElement; 544 if (lineIds.length > 1) { 545 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 546 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 547 height = bottom - top; 548 } 549 if (top !== null && height !== null && parent !== null) { 550 // cook up a div (if necessary) and position it 551 let div = window.document.getElementById("code-annotation-line-highlight"); 552 if (div === null) { 553 div = window.document.createElement("div"); 554 div.setAttribute("id", "code-annotation-line-highlight"); 555 div.style.position = 'absolute'; 556 parent.appendChild(div); 557 } 558 div.style.top = top - 2 + "px"; 559 div.style.height = height + 4 + "px"; 560 div.style.left = 0; 561 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 562 if (gutterDiv === null) { 563 gutterDiv = window.document.createElement("div"); 564 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 565 gutterDiv.style.position = 'absolute'; 566 const codeCell = window.document.getElementById(targetCell); 567 const gutter = codeCell.querySelector('.code-annotation-gutter'); 568 gutter.appendChild(gutterDiv); 569 } 570 gutterDiv.style.top = top - 2 + "px"; 571 gutterDiv.style.height = height + 4 + "px"; 572 } 573 selectedAnnoteEl = annoteEl; 574 } 575 }; 576 const unselectCodeLines = () => { 577 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 578 elementsIds.forEach((elId) => { 579 const div = window.document.getElementById(elId); 580 if (div) { 581 div.remove(); 582 } 583 }); 584 selectedAnnoteEl = undefined; 585 }; 586 // Handle positioning of the toggle 587 window.addEventListener( 588 "resize", 589 throttle(() => { 590 elRect = undefined; 591 if (selectedAnnoteEl) { 592 selectCodeLines(selectedAnnoteEl); 593 } 594 }, 10) 595 ); 596 function throttle(fn, ms) { 597 let throttle = false;
598 let timer; 599 return (...args) => { 600 if(!throttle) { // first call gets through 601 fn.apply(this, args); 602 throttle = true; 603 } else { // all the others get throttled 604 if(timer) clearTimeout(timer); // cancel #2 605 timer = setTimeout(() => { 606 fn.apply(this, args); 607 timer = throttle = false; 608 }, ms); 609 } 610 }; 611 } 612 // Attach click handler to the DT 613 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 614 for (const annoteDlNode of annoteDls) { 615 annoteDlNode.addEventListener('click', (event) => { 616 const clickedEl = event.target; 617 if (clickedEl !== selectedAnnoteEl) { 618 unselectCodeLines(); 619 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 620 if (activeEl) { 621 activeEl.classList.remove('code-annotation-active'); 622 } 623 selectCodeLines(clickedEl); 624 clickedEl.classList.add('code-annotation-active'); 625 } else { 626 // Unselect the line 627 unselectCodeLines(); 628 clickedEl.classList.remove('code-annotation-active'); 629 } 630 }); 631 } 632 const findCites = (el) => { 633 const parentEl = el.parentElement; 634 if (parentEl) { 635 const cites = parentEl.dataset.cites; 636 if (cites) { 637 return { 638 el, 639 cites: cites.split(' ') 640 }; 641 } else { 642 return findCites(el.parentElement) 643 } 644 } else { 645 return undefined; 646 } 647 }; 648 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 649 for (var i=0; i<bibliorefs.length; i++) { 650 const ref = bibliorefs[i]; 651 const citeInfo = findCites(ref); 652 if (citeInfo) { 653 tippyHover(citeInfo.el, function() { 654 var popup = window.document.createElement('div'); 655 citeInfo.cites.forEach(function(cite) { 656 var citeDiv = window.document.createElement('div'); 657 citeDiv.classList.add('hanging-indent'); 658 citeDiv.classList.add('csl-entry'); 659 var biblioDiv = window.document.getElementById('ref-' + cite); 660 if (biblioDiv) { 661 citeDiv.innerHTML = biblioDiv.innerHTML; 662 } 663 popup.appendChild(citeDiv); 664 }); 665 return popup.innerHTML; 666 }); 667 } 668 } 669 }); 670 </script>
670 671</div> <!-- /content --> 672 673 674 675 676</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.