PageSourceSearch

https://calcwithdec.dev/about

html calcwithdec.dev collected 2026-09-25 21:01:43 UTC 25,936 bytes, 624 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.8.26">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9
10<title>About Dec 👋 – Calc with Dec 🧮 🤓</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-0df287d03f580c07ba6257b12f45a2a7.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
43<script id="quarto-search-options" type="application/json">{
44  "location": "navbar",
45  "copy-button": false,
46  "collapse-after": 3,
47  "panel-placement": "end",
48  "type": "overlay",
49  "limit": 50,
50  "keyboard-shortcut": [
51    "f",
52    "/",
53    "s"
54  ],
55  "show-item-context": false,
56  "language": {
57    "search-no-results-text": "No results",
58    "search-matching-documents-text": "matching documents",
59    "search-copy-link-title": "Copy link to search",
60    "search-hide-matches-text": "Hide additional matches",
61    "search-more-match-text": "more match in this document",
62    "search-more-matches-text": "more matches in this document",
63    "search-clear-button-title": "Clear",
64    "search-text-placeholder": "",
65    "search-detached-cancel-button-title": "Cancel",
66    "search-submit-button-title": "Submit",
67    "search-label": "Search"
68  }
69}</script>
69
70<link rel="stylesheet" href="./resources/cookieconsent-2.9.1/dist/cookieconsent.css" media="print" onload="this.media='all'">
71
72
73<link rel="stylesheet" href="styles.css">
74<meta name="twitter:title" content="About Dec 👋 – Calc with Dec 🧮 🤓">
75<meta name="twitter:description" content="">
76<meta name="twitter:image" content="https://calcwithdec.dev/me-2.jpeg">
77<meta name="twitter:card" content="summary_large_image">
78</head>
79
80<body class="nav-fixed fullcontent quarto-light">
81
82<div id="quarto-search-results"></div>
83  <header id="quarto-header" class="headroom fixed-top">
84    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
85      <div class="navbar-container container-fluid">
86      <div class="navbar-brand-container mx-auto">
87    <a class='navbar-brand' href='/'>
88    <span class="navbar-title">Calc with Dec 🧮 🤓</span>
89    </a>
90  </div>
91            <div id="quarto-search" class="" title="Search"></div>
92          <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(); }">
93  <span class="navbar-toggler-icon"></span>
94</button>
95          <div class="collapse navbar-collapse" id="navbarCollapse">
96            <ul class="navbar-nav navbar-nav-scroll ms-auto">
97  <li class="nav-item">
98    <a aria-current='page' class='nav-link active' href='/about'> 
99<span class="menu-text">About Dec 👋</span></a>
100  </li>  
101  <li class="nav-item">
102    <a class='nav-link' href='/'> 
103<span class="menu-text">Blog 📝</span></a>
104  </li>  
105  <li class="nav-item">
106    <a class='nav-link' href='/privacy'> 
107<span class="menu-text">Privacy</span></a>
108  </li>  
109  <li class="nav-item compact">
110    <a class="nav-link" href="https://linkedin.com/in/declann"> <i class="bi bi-linkedin" role="img">
111</i> 
112<span class="menu-text"></span></a>
113  </li>  
114  <li class="nav-item compact">
115    <a class="nav-link" href="https://youtube.com/@calcwithdec"> <i class="bi bi-youtube" role="img">
116</i> 
117<span class="menu-text"></span></a>
118  </li>  
119  <li class="nav-item compact">
120    <a class="nav-link" href="https://twitter.com/calculang"> <i class="bi bi-twitter" role="img">
121</i> 
122<span class="menu-text"></span></a>
123  </li>  
124  <li class="nav-item compact">
125    <a class="nav-link" href="https://fosstodon.org/@calculang" rel="me"> <i class="bi bi-mastodon" role="img">
126</i> 
127<span class="menu-text"></span></a>
128  </li>  
129</ul>
130          </div> <!-- /navcollapse -->
131            <div class="quarto-navbar-tools">
132</div>
133      </div> <!-- /container-fluid -->
134    </nav>
135</header>
136<!-- content -->
137<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
138<!-- sidebar -->
139<!-- margin-sidebar -->
140    
141<!-- main -->
142<div class="quarto-about-jolla">
143  <img src="me-2.jpeg" class="about-image
144  round " style="height: 15em; width: 15em;">
145 <header id="title-block-header" class="quarto-title-block default">
146<div class="quarto-title">
147<h1 class="title">About Dec 👋</h1>
148</div>
149<div class="quarto-title-meta">
150  </div>
151</header><main class="content" id="quarto-document-content">
152<p>I’m Declan. I’m a modeller - I work with numbers, mostly in actuarial departments 📊</p>
153<p>I also develop <a href="https://calculang.dev">calculang</a>, a language for calculations 🧮💬👩‍💻</p>
154<!--I made this website to share some thoughts about modelling ("calcs") and stuff.-->
155<p>Here I share <strong>visual and interactive explorations</strong> about models and numbers.</p>
156<p>For feedback or enquiries you can <a href="mailto:declann1990%20%5Bat%5D%20gmail%20%5Bdot%5D%20com">email me</a> or <a href="https://linkedin.com/in/declann">connect on LinkedIn</a> 🙂</p>
157<p><br></p>
158<div class="callout callout-style-default callout-tip callout-titled" style="text-align: left" title="Availability to work or consult">
159<div class="callout-header d-flex align-content-center">
160<div class="callout-icon-container">
161<i class="callout-icon"></i>
162</div>
163<div class="callout-title-container flex-fill">
164<span class="screen-reader-only">Tip</span>Availability to work or consult
165</div>
166</div>
167<div class="callout-body-container callout-body">
168<p>I’m available to work or consult on different types of projects: generally anything to do with numbers and analysis, with special interests including <strong>actuarial and financial modelling</strong>, <strong>communication and visualization</strong>, <strong>analytics and dashboards</strong>, plus programming and data work in any language, database or other environment.</p>
169<p>Besides extensive <strong>life actuarial</strong> reporting, modelling, and process improvement experience, I also have extensive experience with software, <strong>communicating between actuarial and IT departments</strong>, exploring <strong>software, visualization, analytics and database research</strong> (especially relating to <em>numbers</em>) and in making and contributing to <strong>technology decisions</strong>.</p>
170</div>
171</div>
172
173
174</main> 
175  <hr class="about-sep">
176   <div class="about-links">
177  <a href="https://linkedin.com/in/declann" class="about-link" rel="" target="">
178    <i class="bi bi-linkedin"></i>
179     <span class="about-link-text">Connect on LinkedIn</span>
180  </a>
181  <a href="https://youtube.com/@calcwithdec" class="about-link" rel="" target="">
182    <i class="bi bi-youtube"></i>
183     <span class="about-link-text"></span>
184  </a>
185  <a href="https://twitter.com/calculang" class="about-link" rel="" target="">
186    <i class="bi bi-twitter"></i>
187     <span class="about-link-text"><span class="citation" data-cites="calculang">@calculang</span></span>
188  </a>
189  <a href="https://fosstodon.org/@calculang" class="about-link" rel="" target="">
190    <i class="bi bi-mastodon"></i>
191     <span class="about-link-text"><span class="citation" data-cites="calculang">@calculang</span><span class="citation" data-cites="fosstodon.org">@fosstodon.org</span></span>
192  </a>
193  <a href="https://github.com/declann" class="about-link" rel="" target="">
194    <i class="bi bi-github"></i>
195     <span class="about-link-text"></span>
196  </a>
197  <a href="https://gitlab.com/declann" class="about-link" rel="" target="">
198    <i class="bi bi-git"></i>
199     <span class="about-link-text"></span>
200  </a>
201</div>
202</div>
203 <!-- /main -->
204<script id="quarto-html-after-body" type="application/javascript">
205  window.document.addEventListener("DOMContentLoaded", function (event) {
206    const isCodeAnnotation = (el) => {
207      for (const clz of el.classList) {
208        if (clz.startsWith('code-annotation-')) {                     
209          return true;
210        }
211      }
212      return false;
213    }
214    const onCopySuccess = function(e) {
215      // button target
216      const button = e.trigger;
217      // don't keep focus
218      button.blur();
219      // flash "checked"
220      button.classList.add('code-copy-button-checked');
221      var currentTitle = button.getAttribute("title");
222      button.setAttribute("title", "Copied!");
223      let tooltip;
224      if (window.bootstrap) {
225        button.setAttribute("data-bs-toggle", "tooltip");
226        button.setAttribute("data-bs-placement", "left");
227        button.setAttribute("data-bs-title", "Copied!");
228        tooltip = new bootstrap.Tooltip(button, 
229          { trigger: "manual", 
230            customClass: "code-copy-button-tooltip",
231            offset: [0, -8]});
232        tooltip.show();    
233      }
234      setTimeout(function() {
235        if (tooltip) {
236          tooltip.hide();
237          button.removeAttribute("data-bs-title");
238          button.removeAttribute("data-bs-toggle");
239          button.removeAttribute("data-bs-placement");
240        }
241        button.setAttribute("title", currentTitle);
242        button.classList.remove('code-copy-button-checked');
243      }, 1000);
244      // clear code selection
245      e.clearSelection();
246    }
247    const getTextToCopy = function(trigger) {
248      const outerScaffold = trigger.parentElement.cloneNode(true);
249      const codeEl = outerScaffold.querySelector('code');
250      for (const childEl of codeEl.children) {
251        if (isCodeAnnotation(childEl)) {
252          childEl.remove();
253        }
254      }
255      return codeEl.innerText;
256    }
257    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
258      text: getTextToCopy
259    });
260    clipboard.on('success', onCopySuccess);
261    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
262      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
263        text: getTextToCopy,
264        container: window.document.getElementById('quarto-embedded-source-code-modal')
265      });
266      clipboardModal.on('success', onCopySuccess);
267    }
268      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
269      var mailtoRegex = new RegExp(/^mailto:/);
270        var filterRegex = new RegExp("https:\/\/calcwithdec\.dev");
271      var isInternal = (href) => {
272          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
273      }
274      // Inspect non-navigation links and adorn them if external
275     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)');
276      for (var i=0; i<links.length; i++) {
277        const link = links[i];
278        if (!isInternal(link.href)) {
279          // undo the damage that might have been done by quarto-nav.js in the case of
280          // links that we want to consider external
281          if (link.dataset.originalHref !== undefined) {
282            link.href = link.dataset.originalHref;
283          }
284            // target, if specified
285            link.setAttribute("target", "_blank");
286            if (link.getAttribute("rel") === null) {
287              link.setAttribute("rel", "noopener");
288            }
289        }
290      }
291    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
292      const config = {
293        allowHTML: true,
294        maxWidth: 500,
295        delay: 100,
296        arrow: false,
297        appendTo: function(el) {
298            return el.parentElement;
299        },
300        interactive: true,
301        interactiveBorder: 10,
302        theme: 'quarto',
303        placement: 'bottom-start',
304      };
305      if (contentFn) {
306        config.content = contentFn;
307      }
308      if (onTriggerFn) {
309        config.onTrigger = onTriggerFn;
310      }
311      if (onUntriggerFn) {
312        config.onUntrigger = onUntriggerFn;
313      }
314      window.tippy(el, config); 
315    }
316    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
317    for (var i=0; i<noterefs.length; i++) {
318      const ref = noterefs[i];
319      tippyHover(ref, function() {
320        // use id or data attribute instead here
321        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
322        try { href = new URL(href).hash; } catch {}
323        const id = href.replace(/^#\/?/, "");
324        const note = window.document.getElementById(id);
325        if (note) {
326          return note.innerHTML;
327        } else {
328          return "";
329        }
330      });
331    }
332    const xrefs = window.document.querySelectorAll('a.quarto-xref');
333    const processXRef = (id, note) => {
334      // Strip column container classes
335      const stripColumnClz = (el) => {
336        el.classList.remove("page-full", "page-columns");
337        if (el.children) {
338          for (const child of el.children) {
339            stripColumnClz(child);
340          }
341        }
342      }
343      stripColumnClz(note)
344      if (id === null || id.startsWith('sec-')) {
345        // Special case sections, only their first couple elements
346        const container = document.createElement("div");
347        if (note.children && note.children.length > 2) {
348          container.appendChild(note.children[0].cloneNode(true));
349          for (let i = 1; i < note.children.length; i++) {
350            const child = note.children[i];
351            if (child.tagName === "P" && child.innerText === "") {
352              continue;
353            } else {
354              container.appendChild(child.cloneNode(true));
355              break;
356            }
357          }
358          if (window.Quarto?.typesetMath) {
359            window.Quarto.typesetMath(container);
360          }
361          return container.innerHTML
362        } else {
363          if (window.Quarto?.typesetMath) {
364            window.Quarto.typesetMath(note);
365          }
366          return note.innerHTML;
367        }
368      } else {
369        // Remove any anchor links if they are present
370        const anchorLink = note.querySelector('a.anchorjs-link');
371        if (anchorLink) {
372          anchorLink.remove();
373        }
374        if (window.Quarto?.typesetMath) {
375          window.Quarto.typesetMath(note);
376        }
377        if (note.classList.contains("callout")) {
378          return note.outerHTML;
379        } else {
380          return note.innerHTML;
381        }
382      }
383    }
384    for (var i=0; i<xrefs.length; i++) {
385      const xref = xrefs[i];
386      tippyHover(xref, undefined, function(instance) {
387        instance.disable();
388        let url = xref.getAttribute('href');
389        let hash = undefined; 
390        if (url.startsWith('#')) {
391          hash = url;
392        } else {
393          try { hash = new URL(url).hash; } catch {}
394        }
395        if (hash) {
396          const id = hash.replace(/^#\/?/, "");
397          const note = window.document.getElementById(id);
398          if (note !== null) {
399            try {
400              const html = processXRef(id, note.cloneNode(true));
401              instance.setContent(html);
402            } finally {
403              instance.enable();
404              instance.show();
405            }
406          } else {
407            // See if we can fetch this
408            fetch(url.split('#')[0])
409            .then(res => res.text())
410            .then(html => {
411              const parser = new DOMParser();
412              const htmlDoc = parser.parseFromString(html, "text/html");
413              const note = htmlDoc.getElementById(id);
414              if (note !== null) {
415                const html = processXRef(id, note);
416                instance.setContent(html);
417              } 
418            }).finally(() => {
419              instance.enable();
420              instance.show();
421            });
422          }
423        } else {
424          // See if we can fetch a full url (with no hash to target)
425          // This is a special case and we should probably do some content thinning / targeting
426          fetch(url)
427          .then(res => res.text())
428          .then(html => {
429            const parser = new DOMParser();
430            const htmlDoc = parser.parseFromString(html, "text/html");
431            const note = htmlDoc.querySelector('main.content');
432            if (note !== null) {
433              // This should only happen for chapter cross references
434              // (since there is no id in the URL)
435              // remove the first header
436              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
437                note.children[0].remove();
438              }
439              const html = processXRef(null, note);
440              instance.setContent(html);
441            } 
442          }).finally(() => {
443            instance.enable();
444            instance.show();
445          });
446        }
447      }, function(instance) {
448      });
449    }
450        let selectedAnnoteEl;
451        const selectorForAnnotation = ( cell, annotation) => {
452          let cellAttr = 'data-code-cell="' + cell + '"';
453          let lineAttr = 'data-code-annotation="' +  annotation + '"';
454          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
455          return selector;
456        }
457        const selectCodeLines = (annoteEl) => {
458          const doc = window.document;
459          const targetCell = annoteEl.getAttribute("data-target-cell");
460          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
461          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
462          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
463          const lineIds = lines.map((line) => {
464            return targetCell + "-" + line;
465          })
466          let top = null;
467          let height = null;
468          let parent = null;
469          if (lineIds.length > 0) {
470              //compute the position of the single el (top and bottom and make a div)
471              const el = window.document.getElementById(lineIds[0]);
472              top = el.offsetTop;
473              height = el.offsetHeight;
474              parent = el.parentElement.parentElement;
475            if (lineIds.length > 1) {
476              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
477              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
478              height = bottom - top;
479            }
480            if (top !== null && height !== null && parent !== null) {
481              // cook up a div (if necessary) and position it 
482              let div = window.document.getElementById("code-annotation-line-highlight");
483              if (div === null) {
484                div = window.document.createElement("div");
485                div.setAttribute("id", "code-annotation-line-highlight");
486                div.style.position = 'absolute';
487                parent.appendChild(div);
488              }
489              div.style.top = top - 2 + "px";
490              div.style.height = height + 4 + "px";
491              div.style.left = 0;
492              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
493              if (gutterDiv === null) {
494                gutterDiv = window.document.createElement("div");
495                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
496                gutterDiv.style.position = 'absolute';
497                const codeCell = window.document.getElementById(targetCell);
498                const gutter = codeCell.querySelector('.code-annotation-gutter');
499                gutter.appendChild(gutterDiv);
500              }
501              gutterDiv.style.top = top - 2 + "px";
502              gutterDiv.style.height = height + 4 + "px";
503            }
504            selectedAnnoteEl = annoteEl;
505          }
506        };
507        const unselectCodeLines = () => {
508          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
509          elementsIds.forEach((elId) => {
510            const div = window.document.getElementById(elId);
511            if (div) {
512              div.remove();
513            }
514          });
515          selectedAnnoteEl = undefined;
516        };
517          // Handle positioning of the toggle
518      window.addEventListener(
519        "resize",
520        throttle(() => {
521          elRect = undefined;
522          if (selectedAnnoteEl) {
523            selectCodeLines(selectedAnnoteEl);
524          }
525        }, 10)
526      );
527      function throttle(fn, ms) {
528      let throttle = false;
529      let timer;
530        return (...args) => {
531          if(!throttle) { // first call gets through
532              fn.apply(this, args);
533              throttle = true;
534          } else { // all the others get throttled
535              if(timer) clearTimeout(timer); // cancel #2
536              timer = setTimeout(() => {
537                fn.apply(this, args);
538                timer = throttle = false;
539              }, ms);
540          }
541        };
542      }
543        // Attach click handler to the DT
544        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
545        for (const annoteDlNode of annoteDls) {
546          annoteDlNode.addEventListener('click', (event) => {
547            const clickedEl = event.target;
548            if (clickedEl !== selectedAnnoteEl) {
549              unselectCodeLines();
550              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
551              if (activeEl) {
552                activeEl.classList.remove('code-annotation-active');
553              }
554              selectCodeLines(clickedEl);
555              clickedEl.classList.add('code-annotation-active');
556            } else {
557              // Unselect the line
558              unselectCodeLines();
559              clickedEl.classList.remove('code-annotation-active');
560            }
561          });
562        }
563    const findCites = (el) => {
564      const parentEl = el.parentElement;
565      if (parentEl) {
566        const cites = parentEl.dataset.cites;
567        if (cites) {
568          return {
569            el,
570            cites: cites.split(' ')
571          };
572        } else {
573          return findCites(el.parentElement)
574        }
575      } else {
576        return undefined;
577      }
578    };
579    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
580    for (var i=0; i<bibliorefs.length; i++) {
581      const ref = bibliorefs[i];
582      const citeInfo = findCites(ref);
583      if (citeInfo) {
584        tippyHover(citeInfo.el, function() {
585          var popup = window.document.createElement('div');
586          citeInfo.cites.forEach(function(cite) {
587            var citeDiv = window.document.createElement('div');
588            citeDiv.classList.add('hanging-indent');
589            citeDiv.classList.add('csl-entry');
590            var biblioDiv = window.document.getElementById('ref-' + cite);
591            if (biblioDiv) {
592              citeDiv.innerHTML = biblioDiv.innerHTML;
593            }
594            popup.appendChild(citeDiv);
595          });
596          return popup.innerHTML;
597        });
598      }
599    }
600  });
601  </script>
601
602</div> <!-- /content -->
603<footer class="footer">
604  <div class="nav-footer">
605    <div class="nav-footer-left">
606      &nbsp;
607    </div>   
608    <div class="nav-footer-center">
609<p><a type="button" data-cc="c-settings" class="cc-link">Cookies/analytics preferences</a></p>
610<div class="toc-actions"><ul><li><a href="https://gitlab.com/declann/calcwithdec.dev/edit/main/about.qmd" class="toc-action"><i class="bi bi-git"></i>Edit this page</a></li><li><a href="https://gitlab.com/declann/calcwithdec.dev/blob/main/about.qmd" class="toc-action"><i class="bi empty"></i>View source</a></li><li><a href="https://gitlab.com/declann/calcwithdec.dev/-/issues" class="toc-action"><i class="bi empty"></i>Report an issue</a></li></ul></div></div>
611    <div class="nav-footer-right">
612      &nbsp;
613    </div>
614  </div>
615</footer>
616<script defer="" src="./resources/cookieconsent-2.9.1/dist/cookieconsent.js"></script>
616 |
617<script defer="" src="./cookieconsent-init.js"></script>
vendor: 1 bytes, line 617
617
618<script defer="" type="text/plain" data-cookiecategory="analytics" data-domain="calcwithdec.dev" src="https://plausible.io/js/script.js"></script>
vendor: 1 bytes, line 618
618
619<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
619
620
621
622
623
624</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.