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 â Konstantinos Chousos</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-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-html/axe/axe-check.js" type="module"></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-93b8c9058bab3de7da2ef1d2980be073.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles"> 36<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark-b3861cce213c80ac26b579d77e21d477.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles"> 37<link href="site_libs/quarto-html/quarto-syntax-highlighting-93b8c9058bab3de7da2ef1d2980be073.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
38<script src="site_libs/bootstrap/bootstrap.min.js"></script>
38 39<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 40<link href="site_libs/bootstrap/bootstrap-c499bab53fbfaeaa32f2566e9f94890c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light"> 41<link href="site_libs/bootstrap/bootstrap-dark-829f4d663cc7c6a66af8ed91b3d72978.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark"> 42<link href="site_libs/bootstrap/bootstrap-c499bab53fbfaeaa32f2566e9f94890c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
43<script src="site_libs/quarto-contrib/iconify-2.1.0/iconify-icon.min.js"></script>
vendor: 1 bytes, line 43
43
44<script id="quarto-search-options" type="application/json">{ 45 "language": { 46 "search-no-results-text": "No results", 47 "search-matching-documents-text": "matching documents", 48 "search-copy-link-title": "Copy link to search", 49 "search-hide-matches-text": "Hide additional matches", 50 "search-more-match-text": "more match in this document", 51 "search-more-matches-text": "more matches in this document", 52 "search-clear-button-title": "Clear", 53 "search-text-placeholder": "", 54 "search-detached-cancel-button-title": "Cancel", 55 "search-submit-button-title": "Submit", 56 "search-label": "Search" 57 } 58}</script>
vendor: 1 bytes, line 58
58
59<script src="https://tinylytics.app/embed/bp9HPTzRCo35BgZSLJaf/min.js?kudos=â¤ï¸" defer=""></script>
59 60 61
61<script>window.backupDefine = window.define; window.define = undefined;</script>
61<script src="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.js"></script>
61 62
62<script>document.addEventListener("DOMContentLoaded", function () { 63 var mathElements = document.getElementsByClassName("math"); 64 var macros = []; 65 for (var i = 0; i < mathElements.length; i++) { 66 var texText = mathElements[i].firstChild; 67 if (mathElements[i].tagName == "SPAN") { 68 katex.render(texText.data, mathElements[i], { 69 displayMode: mathElements[i].classList.contains('display'), 70 throwOnError: false, 71 macros: macros, 72 fleqn: false 73 }); 74}}}); 75 </script>
75 76
76<script>window.define = window.backupDefine; window.backupDefine = undefined;</script>
76<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css"> 77
78<script type="text/javascript"> 79const typesetMath = (el) => { 80 if (window.MathJax) { 81 // MathJax Typeset 82 window.MathJax.typeset([el]); 83 } else if (window.katex) { 84 // KaTeX Render 85 var mathElements = el.getElementsByClassName("math"); 86 var macros = []; 87 for (var i = 0; i < mathElements.length; i++) { 88 var texText = mathElements[i].firstChild; 89 if (mathElements[i].tagName == "SPAN" && texText && texText.data) { 90 window.katex.render(texText.data, mathElements[i], { 91 displayMode: mathElements[i].classList.contains('display'), 92 throwOnError: false, 93 macros: macros, 94 fleqn: false 95 }); 96 } 97 } 98 } 99} 100window.Quarto = { 101 typesetMath 102}; 103</script>
103 104 105</head> 106 107<body class="nav-fixed fullcontent quarto-light">
107<script id="quarto-html-before-body" type="application/javascript"> 108 const toggleBodyColorMode = (bsSheetEl) => { 109 const mode = bsSheetEl.getAttribute("data-mode"); 110 const bodyEl = window.document.querySelector("body"); 111 if (mode === "dark") { 112 bodyEl.classList.add("quarto-dark"); 113 bodyEl.classList.remove("quarto-light"); 114 } else { 115 bodyEl.classList.add("quarto-light"); 116 bodyEl.classList.remove("quarto-dark"); 117 } 118 } 119 const toggleBodyColorPrimary = () => { 120 const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])"); 121 if (bsSheetEl) { 122 toggleBodyColorMode(bsSheetEl); 123 } 124 } 125 const setColorSchemeToggle = (alternate) => { 126 const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle'); 127 for (let i=0; i < toggles.length; i++) { 128 const toggle = toggles[i]; 129 if (toggle) { 130 if (alternate) { 131 toggle.classList.add("alternate"); 132 } else { 133 toggle.classList.remove("alternate"); 134 } 135 } 136 } 137 }; 138 const toggleColorMode = (alternate) => { 139 // Switch the stylesheets 140 const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)'); 141 const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate'); 142 manageTransitions('#quarto-margin-sidebar .nav-link', false); 143 if (alternate) { 144 // note: dark is layered on light, we don't disable primary! 145 enableStylesheet(alternateStylesheets); 146 for (const sheetNode of alternateStylesheets) { 147 if (sheetNode.id === "quarto-bootstrap") { 148 toggleBodyColorMode(sheetNode); 149 } 150 } 151 } else { 152 disableStylesheet(alternateStylesheets); 153 enableStylesheet(primaryStylesheets) 154 toggleBodyColorPrimary(); 155 } 156 manageTransitions('#quarto-margin-sidebar .nav-link', true); 157 // Switch the toggles 158 setColorSchemeToggle(alternate) 159 // Hack to workaround the fact that safari doesn't 160 // properly recolor the scrollbar when toggling (#1455) 161 if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) { 162 manageTransitions("body", false); 163 window.scrollTo(0, 1); 164 setTimeout(() => { 165 window.scrollTo(0, 0); 166 manageTransitions("body", true); 167 }, 40); 168 } 169 } 170 const disableStylesheet = (stylesheets) => { 171 for (let i=0; i < stylesheets.length; i++) { 172 const stylesheet = stylesheets[i]; 173 stylesheet.rel = 'disabled-stylesheet'; 174 } 175 } 176 const enableStylesheet = (stylesheets) => { 177 for (let i=0; i < stylesheets.length; i++) { 178 const stylesheet = stylesheets[i]; 179 if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check 180 stylesheet.rel = 'stylesheet'; 181 } 182 } 183 } 184 const manageTransitions = (selector, allowTransitions) => { 185 const els = window.document.querySelectorAll(selector); 186 for (let i=0; i < els.length; i++) { 187 const el = els[i]; 188 if (allowTransitions) { 189 el.classList.remove('notransition'); 190 } else { 191 el.classList.add('notransition'); 192 } 193 } 194 } 195 const isFileUrl = () => { 196 return window.location.protocol === 'file:'; 197 } 198 const hasAlternateSentinel = () => { 199 let styleSentinel = getColorSchemeSentinel(); 200 if (styleSentinel !== null) { 201 return styleSentinel === "alternate"; 202 } else { 203 return false; 204 } 205 } 206 const setStyleSentinel = (alternate) => { 207 const value = alternate ? "alternate" : "default"; 208 if (!isFileUrl()) { 209 window.localStorage.setItem("quarto-color-scheme", value); 210 } else { 211 localAlternateSentinel = value; 212 } 213 } 214 const getColorSchemeSentinel = () => { 215 if (!isFileUrl()) { 216 const storageValue = window.localStorage.getItem("quarto-color-scheme"); 217 return storageValue != null ? storageValue : localAlternateSentinel; 218 } else { 219 return localAlternateSentinel; 220 } 221 } 222 const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => { 223 const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light'; 224 const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark'; 225 let newTheme = ''; 226 if(authorPrefersDark) { 227 newTheme = isAlternate ? baseTheme : alternateTheme; 228 } else { 229 newTheme = isAlternate ? alternateTheme : baseTheme; 230 } 231 const changeGiscusTheme = () => { 232 // From: https://github.com/giscus/giscus/issues/336 233 const sendMessage = (message) => { 234 const iframe = document.querySelector('iframe.giscus-frame'); 235 if (!iframe) return; 236 iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app'); 237 } 238 sendMessage({ 239 setConfig: { 240 theme: newTheme 241 } 242 }); 243 } 244 const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null; 245 if (isGiscussLoaded) { 246 changeGiscusTheme(); 247 } 248 }; 249 const authorPrefersDark = false;
250 const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)'); 251 const darkModeDefault = queryPrefersDark.matches; 252 document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet'; 253 document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet'; 254 let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default'; 255 // Dark / light mode switch 256 window.quartoToggleColorScheme = () => { 257 // Read the current dark / light value 258 let toAlternate = !hasAlternateSentinel(); 259 toggleColorMode(toAlternate); 260 setStyleSentinel(toAlternate); 261 toggleGiscusIfUsed(toAlternate, darkModeDefault); 262 window.dispatchEvent(new Event('resize')); 263 }; 264 queryPrefersDark.addEventListener("change", e => { 265 if(window.localStorage.getItem("quarto-color-scheme") !== null) 266 return; 267 const alternate = e.matches 268 toggleColorMode(alternate); 269 localAlternateSentinel = e.matches ? 'alternate' : 'default'; // this is used alongside local storage! 270 toggleGiscusIfUsed(alternate, darkModeDefault); 271 }); 272 // Switch to dark mode if need be 273 if (hasAlternateSentinel()) { 274 toggleColorMode(true); 275 } else { 276 toggleColorMode(false); 277 } 278 </script>
278 279 280<div id="quarto-search-results"></div> 281 <header id="quarto-header" class="headroom fixed-top"> 282 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 283 <div class="navbar-container container-fluid"> 284 <div class="navbar-brand-container mx-auto"> 285 <a href="./index.html" class="navbar-brand navbar-brand-logo"> 286 <img src="././icons/favicon-32x32.png" alt="" class="navbar-logo light-content"> 287 <img src="././icons/favicon-32x32.png" alt="" class="navbar-logo dark-content"> 288 </a> 289 <a class="navbar-brand" href="./index.html"> 290 <span class="navbar-title">Konstantinos Chousos</span> 291 </a> 292 </div> 293 <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(); }"> 294 <span class="navbar-toggler-icon"></span> 295</button> 296 <div class="collapse navbar-collapse" id="navbarCollapse"> 297 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 298 <li class="nav-item"> 299 <a class="nav-link active" href="./about.html" aria-current="page"> 300<span class="menu-text">About</span></a> 301 </li> 302 <li class="nav-item"> 303 <a class="nav-link" href="./now.html"> 304<span class="menu-text">Now</span></a> 305 </li> 306 <li class="nav-item"> 307 <a class="nav-link" href="./research.html"> 308<span class="menu-text">Research</span></a> 309 </li> 310 <li class="nav-item"> 311 <a class="nav-link" href="./posts.html"> 312<span class="menu-text">Posts</span></a> 313 </li> 314 <li class="nav-item"> 315 <a class="nav-link" href="./resources.html"> 316<span class="menu-text">Resources</span></a> 317 </li> 318 <li class="nav-item"> 319 <a class="nav-link" href="./booklist.html"> 320<span class="menu-text">Reading</span></a> 321 </li> 322</ul> 323 </div> <!-- /navcollapse --> 324 <div class="quarto-navbar-tools"> 325 <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> 326</div> 327 </div> <!-- /container-fluid --> 328 </nav> 329</header> 330<!-- content --> 331<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 332<!-- sidebar --> 333<!-- margin-sidebar --> 334 335<!-- main --> 336<div class="quarto-about-solana column-body"> 337 <div class="about-entity"> 338 <div class="entity-contents"> 339 <header id="title-block-header" class="quarto-title-block default"> 340<div class="quarto-title"> 341<h1 class="title">About</h1> 342</div> 343<div class="quarto-title-meta"> 344 <div> 345 <div class="quarto-title-meta-heading">Modified</div> 346 <div class="quarto-title-meta-contents"> 347 <p class="date-modified">July 30, 2025</p> 348 </div> 349 </div> 350 </div> 351</header> 352 <div class="about-contents"><main class="content" id="quarto-document-content"> 353 354<p>Hello, welcome to my personal site!</p> 355<p>My name is Konstantinos Chousos. I am an AI/Security researcher, member of the <a href="https://ai.di.uoa.gr/">UoA AI team</a>.</p> 356<section id="about-me" class="level2"> 357<h2 data-anchor-id="about-me">About me</h2> 358<p>I recently finished my undergraduate studies at the <a href="https://www.di.uoa.gr/en">Department of Informatics and Telecommunications</a> of the <a href="https://en.uoa.gr/">University of Athens</a>. For the last semester I was working on my <a href="https://kchousos.github.io/BSc-Thesis/">thesis</a> under the guidance of prof. <a href="https://cgi.di.uoa.gr/~thanassis/">Thanassis Avgerinos</a>. I am also working on the <a href="https://recitals-project.eu/">RECITALS EU project</a>, as part of prof. <a href="https://cgi.di.uoa.gr/~koubarak/">Manolis Koubarakisâ</a> team.</p> 359<p>I am mainly interested in AI and its applications, software security and cryptography. Miscellaneous interests of mine include functional programming, typesetting/<span class="math inline">\LaTeX</span>, Linux systems, human-computer interaction and CS-adjacent mathematics.</p> 360<p>Aside from computer science, my second passion is music. I play classical guitar, in which I acquired a <a href="https://youtu.be/Ca1J-dLcY44?si=NhWsm8AFgrS_dYx4">diploma in January of 2023</a> from the national conservatory of Greece. I am also a member of the <a href="https://www.youtube.com/watch?v=QJvTAZme7-I">Vox Fortis choir</a>, with appearances in places such as the Athens Concert Hall and the Odeon of Herodes Atticus.</p> 361<p>Lastly, Iâm currently re-learning to draw, following the <a href="https://drawabox.com">DrawABox</a> course. Iâve been making progress and I look forward to improving my drawing skills furthermore. I used to draw a lot during primary school, and I was quite good at it too. So. Iâm excited to get back at it.</p> 362</section> 363<section id="about-this-site" class="level2"> 364<h2 data-anchor-id="about-this-site">About this site</h2> 365<section id="why-does-it-exist" class="level3"> 366<h3 data-anchor-id="why-does-it-exist">Why does it exist?</h3> 367<p>This site could be categorized as an <a href="https://www.urbandictionary.com/define.php?term=everything%2Fnothing"><em>e/n website</em></a>.</p> 368<blockquote class="blockquote"> 369<p>The websiteâs content means everything to the publisher, but it could mean nothing to the rest of the world.</p> 370</blockquote> 371<p>The content is/will be varied and will basically showcase whatever I find helpful and/or interesting, hoping that someone somewhere will find it useful.</p> 372</section> 373<section id="how-is-it-built" class="level3"> 374<h3 data-anchor-id="how-is-it-built">How is it built?</h3> 375<p>This site is generated by <a href="https://quarto.org/">Quarto</a>. The posts are written in <a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a>. <a href="https://pages.github.com/">Github-Pages</a> is used for hosting. You can find the source code of this site on my <a href="https://github.com/kchousos/kchousos.github.io">github</a>.</p> 376 377 378</section> 379</section> 380</main></div> 381 </div> 382 <img src="/static/headshot.png" class="about-image 383 rounded " style="width: 15em;"> 384 </div> 385</div> 386 <!-- /main -->
387<script id="quarto-html-after-body" type="application/javascript"> 388 window.document.addEventListener("DOMContentLoaded", function (event) { 389 // Ensure there is a toggle, if there isn't float one in the top right 390 if (window.document.querySelector('.quarto-color-scheme-toggle') === null) { 391 const a = window.document.createElement('a'); 392 a.classList.add('top-right'); 393 a.classList.add('quarto-color-scheme-toggle'); 394 a.href = ""; 395 a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; }; 396 const i = window.document.createElement("i"); 397 i.classList.add('bi'); 398 a.appendChild(i); 399 window.document.body.appendChild(a); 400 } 401 setColorSchemeToggle(hasAlternateSentinel()) 402 const isCodeAnnotation = (el) => { 403 for (const clz of el.classList) { 404 if (clz.startsWith('code-annotation-')) { 405 return true; 406 } 407 } 408 return false; 409 } 410 const onCopySuccess = function(e) { 411 // button target 412 const button = e.trigger; 413 // don't keep focus 414 button.blur(); 415 // flash "checked" 416 button.classList.add('code-copy-button-checked'); 417 var currentTitle = button.getAttribute("title"); 418 button.setAttribute("title", "Copied!"); 419 let tooltip; 420 if (window.bootstrap) { 421 button.setAttribute("data-bs-toggle", "tooltip"); 422 button.setAttribute("data-bs-placement", "left"); 423 button.setAttribute("data-bs-title", "Copied!"); 424 tooltip = new bootstrap.Tooltip(button, 425 { trigger: "manual", 426 customClass: "code-copy-button-tooltip", 427 offset: [0, -8]}); 428 tooltip.show(); 429 } 430 setTimeout(function() { 431 if (tooltip) { 432 tooltip.hide(); 433 button.removeAttribute("data-bs-title"); 434 button.removeAttribute("data-bs-toggle"); 435 button.removeAttribute("data-bs-placement"); 436 } 437 button.setAttribute("title", currentTitle); 438 button.classList.remove('code-copy-button-checked'); 439 }, 1000); 440 // clear code selection 441 e.clearSelection(); 442 } 443 const getTextToCopy = function(trigger) { 444 const outerScaffold = trigger.parentElement.cloneNode(true); 445 const codeEl = outerScaffold.querySelector('code'); 446 for (const childEl of codeEl.children) { 447 if (isCodeAnnotation(childEl)) { 448 childEl.remove(); 449 } 450 } 451 return codeEl.innerText; 452 } 453 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 454 text: getTextToCopy 455 }); 456 clipboard.on('success', onCopySuccess); 457 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 458 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 459 text: getTextToCopy, 460 container: window.document.getElementById('quarto-embedded-source-code-modal') 461 }); 462 clipboardModal.on('success', onCopySuccess); 463 } 464 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 465 var mailtoRegex = new RegExp(/^mailto:/); 466 var filterRegex = new RegExp("https:\/\/kchousos\.github\.io"); 467 var isInternal = (href) => { 468 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 469 } 470 // Inspect non-navigation links and adorn them if external 471 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)'); 472 for (var i=0; i<links.length; i++) { 473 const link = links[i]; 474 if (!isInternal(link.href)) { 475 // undo the damage that might have been done by quarto-nav.js in the case of 476 // links that we want to consider external 477 if (link.dataset.originalHref !== undefined) { 478 link.href = link.dataset.originalHref; 479 } 480 } 481 } 482 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 483 const config = { 484 allowHTML: true, 485 maxWidth: 500, 486 delay: 100,
487 arrow: false, 488 appendTo: function(el) { 489 return el.parentElement; 490 }, 491 interactive: true, 492 interactiveBorder: 10, 493 theme: 'quarto', 494 placement: 'bottom-start', 495 }; 496 if (contentFn) { 497 config.content = contentFn; 498 } 499 if (onTriggerFn) { 500 config.onTrigger = onTriggerFn; 501 } 502 if (onUntriggerFn) { 503 config.onUntrigger = onUntriggerFn; 504 } 505 window.tippy(el, config); 506 } 507 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 508 for (var i=0; i<noterefs.length; i++) { 509 const ref = noterefs[i]; 510 tippyHover(ref, function() { 511 // use id or data attribute instead here 512 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 513 try { href = new URL(href).hash; } catch {} 514 const id = href.replace(/^#\/?/, ""); 515 const note = window.document.getElementById(id); 516 if (note) { 517 return note.innerHTML; 518 } else { 519 return ""; 520 } 521 }); 522 } 523 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 524 const processXRef = (id, note) => { 525 // Strip column container classes 526 const stripColumnClz = (el) => { 527 el.classList.remove("page-full", "page-columns"); 528 if (el.children) { 529 for (const child of el.children) { 530 stripColumnClz(child); 531 } 532 } 533 } 534 stripColumnClz(note) 535 if (id === null || id.startsWith('sec-')) { 536 // Special case sections, only their first couple elements 537 const container = document.createElement("div"); 538 if (note.children && note.children.length > 2) { 539 container.appendChild(note.children[0].cloneNode(true)); 540 for (let i = 1; i < note.children.length; i++) { 541 const child = note.children[i]; 542 if (child.tagName === "P" && child.innerText === "") { 543 continue; 544 } else { 545 container.appendChild(child.cloneNode(true)); 546 break; 547 } 548 } 549 if (window.Quarto?.typesetMath) { 550 window.Quarto.typesetMath(container); 551 } 552 return container.innerHTML 553 } else { 554 if (window.Quarto?.typesetMath) { 555 window.Quarto.typesetMath(note); 556 } 557 return note.innerHTML; 558 } 559 } else { 560 // Remove any anchor links if they are present 561 const anchorLink = note.querySelector('a.anchorjs-link'); 562 if (anchorLink) { 563 anchorLink.remove(); 564 } 565 if (window.Quarto?.typesetMath) { 566 window.Quarto.typesetMath(note); 567 } 568 if (note.classList.contains("callout")) { 569 return note.outerHTML; 570 } else { 571 return note.innerHTML; 572 } 573 } 574 } 575 for (var i=0; i<xrefs.length; i++) { 576 const xref = xrefs[i]; 577 tippyHover(xref, undefined, function(instance) { 578 instance.disable(); 579 let url = xref.getAttribute('href'); 580 let hash = undefined; 581 if (url.startsWith('#')) { 582 hash = url; 583 } else { 584 try { hash = new URL(url).hash; } catch {} 585 } 586 if (hash) { 587 const id = hash.replace(/^#\/?/, ""); 588 const note = window.document.getElementById(id); 589 if (note !== null) { 590 try { 591 const html = processXRef(id, note.cloneNode(true)); 592 instance.setContent(html); 593 } finally { 594 instance.enable(); 595 instance.show(); 596 } 597 } else { 598 // See if we can fetch this 599 fetch(url.split('#')[0]) 600 .then(res => res.text()) 601 .then(html => { 602 const parser = new DOMParser(); 603 const htmlDoc = parser.parseFromString(html, "text/html"); 604 const note = htmlDoc.getElementById(id); 605 if (note !== null) { 606 const html = processXRef(id, note); 607 instance.setContent(html); 608 } 609 }).finally(() => { 610 instance.enable(); 611 instance.show(); 612 }); 613 } 614 } else { 615 // See if we can fetch a full url (with no hash to target)
616 // This is a special case and we should probably do some content thinning / targeting 617 fetch(url) 618 .then(res => res.text()) 619 .then(html => { 620 const parser = new DOMParser(); 621 const htmlDoc = parser.parseFromString(html, "text/html"); 622 const note = htmlDoc.querySelector('main.content'); 623 if (note !== null) { 624 // This should only happen for chapter cross references 625 // (since there is no id in the URL) 626 // remove the first header 627 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 628 note.children[0].remove(); 629 } 630 const html = processXRef(null, note); 631 instance.setContent(html); 632 } 633 }).finally(() => { 634 instance.enable(); 635 instance.show(); 636 }); 637 } 638 }, function(instance) { 639 }); 640 } 641 let selectedAnnoteEl; 642 const selectorForAnnotation = ( cell, annotation) => { 643 let cellAttr = 'data-code-cell="' + cell + '"'; 644 let lineAttr = 'data-code-annotation="' + annotation + '"'; 645 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 646 return selector; 647 } 648 const selectCodeLines = (annoteEl) => { 649 const doc = window.document; 650 const targetCell = annoteEl.getAttribute("data-target-cell"); 651 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 652 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 653 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 654 const lineIds = lines.map((line) => { 655 return targetCell + "-" + line; 656 }) 657 let top = null; 658 let height = null; 659 let parent = null; 660 if (lineIds.length > 0) { 661 //compute the position of the single el (top and bottom and make a div) 662 const el = window.document.getElementById(lineIds[0]); 663 top = el.offsetTop; 664 height = el.offsetHeight; 665 parent = el.parentElement.parentElement; 666 if (lineIds.length > 1) { 667 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 668 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 669 height = bottom - top; 670 } 671 if (top !== null && height !== null && parent !== null) { 672 // cook up a div (if necessary) and position it 673 let div = window.document.getElementById("code-annotation-line-highlight"); 674 if (div === null) { 675 div = window.document.createElement("div"); 676 div.setAttribute("id", "code-annotation-line-highlight"); 677 div.style.position = 'absolute'; 678 parent.appendChild(div); 679 } 680 div.style.top = top - 2 + "px"; 681 div.style.height = height + 4 + "px"; 682 div.style.left = 0; 683 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 684 if (gutterDiv === null) { 685 gutterDiv = window.document.createElement("div"); 686 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 687 gutterDiv.style.position = 'absolute'; 688 const codeCell = window.document.getElementById(targetCell); 689 const gutter = codeCell.querySelector('.code-annotation-gutter'); 690 gutter.appendChild(gutterDiv); 691 } 692 gutterDiv.style.top = top - 2 + "px"; 693 gutterDiv.style.height = height + 4 + "px"; 694 } 695 selectedAnnoteEl = annoteEl; 696 } 697 }; 698 const unselectCodeLines = () => { 699 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 700 elementsIds.forEach((elId) => { 701 const div = window.document.getElementById(elId); 702 if (div) { 703 div.remove(); 704 } 705 }); 706 selectedAnnoteEl = undefined; 707 }; 708 // Handle positioning of the toggle 709 window.addEventListener( 710 "resize", 711 throttle(() => { 712 elRect = undefined; 713 if (selectedAnnoteEl) { 714 selectCodeLines(selectedAnnoteEl); 715 } 716 }, 10) 717 ); 718 function throttle(fn, ms) { 719 let throttle = false;
720 let timer; 721 return (...args) => { 722 if(!throttle) { // first call gets through 723 fn.apply(this, args); 724 throttle = true; 725 } else { // all the others get throttled 726 if(timer) clearTimeout(timer); // cancel #2 727 timer = setTimeout(() => { 728 fn.apply(this, args); 729 timer = throttle = false; 730 }, ms); 731 } 732 }; 733 } 734 // Attach click handler to the DT 735 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 736 for (const annoteDlNode of annoteDls) { 737 annoteDlNode.addEventListener('click', (event) => { 738 const clickedEl = event.target; 739 if (clickedEl !== selectedAnnoteEl) { 740 unselectCodeLines(); 741 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 742 if (activeEl) { 743 activeEl.classList.remove('code-annotation-active'); 744 } 745 selectCodeLines(clickedEl); 746 clickedEl.classList.add('code-annotation-active'); 747 } else { 748 // Unselect the line 749 unselectCodeLines(); 750 clickedEl.classList.remove('code-annotation-active'); 751 } 752 }); 753 } 754 const findCites = (el) => { 755 const parentEl = el.parentElement; 756 if (parentEl) { 757 const cites = parentEl.dataset.cites; 758 if (cites) { 759 return { 760 el, 761 cites: cites.split(' ') 762 }; 763 } else { 764 return findCites(el.parentElement) 765 } 766 } else { 767 return undefined; 768 } 769 }; 770 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 771 for (var i=0; i<bibliorefs.length; i++) { 772 const ref = bibliorefs[i]; 773 const citeInfo = findCites(ref); 774 if (citeInfo) { 775 tippyHover(citeInfo.el, function() { 776 var popup = window.document.createElement('div'); 777 citeInfo.cites.forEach(function(cite) { 778 var citeDiv = window.document.createElement('div'); 779 citeDiv.classList.add('hanging-indent'); 780 citeDiv.classList.add('csl-entry'); 781 var biblioDiv = window.document.getElementById('ref-' + cite); 782 if (biblioDiv) { 783 citeDiv.innerHTML = biblioDiv.innerHTML; 784 } 785 popup.appendChild(citeDiv); 786 }); 787 return popup.innerHTML; 788 }); 789 } 790 } 791 }); 792 </script>
792 793</div> <!-- /content --> 794<footer class="footer"> 795 <div class="nav-footer"> 796 <div class="nav-footer-left"> 797 798 </div> 799 <div class="nav-footer-center"> 800 <ul class="footer-items list-unstyled"> 801 <li class="nav-item"> 802 <a class="nav-link" href="./copyright.html"> 803<p>© 2025 Konstantinos Chousos</p> 804</a> 805 </li> 806</ul> 807 </div> 808 <div class="nav-footer-right"> 809 <ul class="footer-items list-unstyled"> 810 <li class="nav-item"> 811 <a class="nav-link" href="https://github.com/kchousos"> 812<p><iconify-icon role="img" inline="" icon="fa6-brands:github" aria-label="Icon github from fa6-brands Iconify.design set." title="Icon github from fa6-brands Iconify.design set."></iconify-icon></p> 813</a> 814 </li> 815 <li class="nav-item"> 816 <a class="nav-link" href="https://orcid.org/0009-0008-6063-7915"> 817<p><iconify-icon role="img" inline="" icon="academicons:orcid" aria-label="Icon orcid from academicons Iconify.design set." title="Icon orcid from academicons Iconify.design set."></iconify-icon></p> 818</a> 819 </li> 820 <li class="nav-item"> 821 <a class="nav-link" href="https://www.linkedin.com/in/kchousos/"> 822<p><iconify-icon role="img" inline="" icon="fa6-brands:linkedin" aria-label="Icon linkedin from fa6-brands Iconify.design set." title="Icon linkedin from fa6-brands Iconify.design set."></iconify-icon></p> 823</a> 824 </li> 825 <li class="nav-item"> 826 <a class="nav-link" href="mailto:[email protected]"> 827<p><iconify-icon role="img" inline="" icon="material-symbols:mail" aria-label="Icon mail from material-symbols Iconify.design set." title="Icon mail from material-symbols Iconify.design set."></iconify-icon></p> 828</a> 829 </li> 830 <li class="nav-item"> 831 <a class="nav-link" href="./posts.xml"> 832<p><iconify-icon role="img" inline="" icon="material-symbols:rss-feed" aria-label="Icon rss-feed from material-symbols Iconify.design set." title="Icon rss-feed from material-symbols Iconify.design set."></iconify-icon></p> 833</a> 834 </li> 835</ul> 836 </div> 837 </div> 838</footer> 839 840 841 842 843</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.